Program Listing for File external.hpp

Return to documentation for file (include/fastcdr/xcdr/external.hpp)

// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef _FASTCDR_XCDR_EXTERNAL_HPP_
#define _FASTCDR_XCDR_EXTERNAL_HPP_

#include <memory>

#include "../exceptions/LockedExternalAccessException.hpp"

namespace eprosima {
namespace fastcdr {

template<class T>
class external
{
public:

    using type = T;

    external() = default;

    external(
            T* pointer,
            bool locked = false) noexcept
        : pointer_ {pointer}
        , locked_ {locked}
    {
    }

    external(
            std::shared_ptr<T> pointer) noexcept
        : pointer_ {pointer}
    {
    }

    external(
            const external<T>& other) noexcept
        : locked_ {other.locked_}
    {
        if (locked_)
        {
            pointer_ = std::make_shared<T>(*other.pointer_);
        }
        else
        {
            pointer_ = other.pointer_;
        }
    }

    external<T>& operator =(
            const external<T>& other)
    {
        if (locked_)
        {
            throw exception::LockedExternalAccessException(
                      exception::LockedExternalAccessException::LOCKED_EXTERNAL_ACCESS_MESSAGE_DEFAULT);
        }

        if (!other.pointer_)
        {
            pointer_.reset();
        }
        else if (other.locked_)
        {
            if (!pointer_)
            {
                pointer_ = std::make_shared<T>(*other.pointer_);
            }
            else
            {
                *pointer_ = *other.pointer_;
            }
        }
        else
        {
            pointer_ = other.pointer_;
        }

        return *this;
    }

    ~external() = default;

    T& operator *() noexcept
    {
        return *pointer_;
    }

    const T& operator *() const noexcept
    {
        return *pointer_;
    }

    T* get() noexcept
    {
        return pointer_.get();
    }

    const T* get() const noexcept
    {
        return pointer_.get();
    }

    std::shared_ptr<T> get_shared_ptr() noexcept
    {
        return pointer_;
    }

    T* operator ->() noexcept
    {
        return pointer_.get();
    }

    const T* operator ->() const noexcept
    {
        return pointer_.get();
    }

    bool operator ==(
            const external<T>& other) const
    {
        return pointer_.get() == other.pointer_.get();
    }

    bool operator !=(
            const external<T>& other) const
    {
        return !(*this == other);
    }

    operator bool() const noexcept
    {
        return nullptr != pointer_.get();
    }

    bool is_locked() const noexcept
    {
        return locked_;
    }

    void lock() noexcept
    {
        locked_ = true;
    }

private:

    std::shared_ptr<T> pointer_;

    bool locked_ {false};

};

} // namespace fastcdr
} // namespace eprosima

#endif //_FASTCDR_XCDR_EXTERNAL_HPP_