Program Listing for File Reference.hpp

Return to documentation for file (/tmp/ws/src/fastrtps/include/dds/core/Reference.hpp)

/*
 * Copyright 2010, Object Management Group, Inc.
 * Copyright 2010, PrismTech, Corp.
 * Copyright 2010, Real-Time Innovations, Inc.
 * Copyright 2019, 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 OMG_DDS_CORE_REFERENCE_HPP_
#define OMG_DDS_CORE_REFERENCE_HPP_

#include <dds/core/types.hpp>
#include <dds/core/refmacros.hpp>
#include <dds/core/ref_traits.hpp> //used when macros of refmacros.hpp expand

namespace dds {
namespace core {

template<typename DELEGATE>
class Reference
{
public:

    DECLARE_TYPE_TRAITS(
        DELEGATE)


    explicit Reference(
            dds::core::null_type& n)
        : impl_(n)
    {
    }

    explicit Reference(
            const Reference& ref)
        : impl_(ref.impl_)
    {
    }

    Reference& operator = (
            const Reference& ref)
    {
        impl_ = ref.impl_;
        return *this;
    }

    template<typename D>
    explicit Reference(
            const Reference<D>& ref)
    {
        impl_ = std::dynamic_pointer_cast<DELEGATE_T>(ref.impl_);
        if (impl_ != ref.impl_)
        {
            throw
                IllegalOperationError(std::string("Attempted invalid cast: ") +
                        typeid(ref).name() + " to " + typeid(*this).name());
        }

    }

    explicit Reference(
            DELEGATE_T* p)
        : impl_(p)
    {
    }

    explicit Reference(
            const DELEGATE_REF_T& p)
        : impl_(p)
    {
    }

    ~Reference()
    {
    }

    operator DELEGATE_REF_T() const
    {
        return impl_;
    }
    template<typename R>
    bool operator ==(
            const R& ref) const
    {
        bool equal = false;
        if (this->is_nil() && ref.is_nil())
        {
            /* Both delegates are null. */
            equal = true;
        }
        else if (!this->is_nil() && !ref.is_nil())
        {
            /* Check delegates. */
            equal = (this->delegate() == ref.delegate());
        }
        return equal;
    }

    template<typename R>
    bool operator !=(
            const R& ref) const
    {
        // FRANAVA read something removing the this keyword.
        return !(*this == ref);
    }

    template<typename D>
    Reference& operator =(
            const Reference<D>& that)
    {
        //To implement
        static_assert((is_base_of<DELEGATE_T, D>::value), "value error");
        if (this != (Reference*)&that)
        {
            *this = Reference<DELEGATE_T>(that);
        }
        return *this;

    }

    template<typename R>
    Reference& operator =(
            const R& rhs)
    {
        static_assert(
            is_base_of< DELEGATE_T, typename R::DELEGATE_T>::value,
            "location: operator=()" );
        if (this != (Reference*)&rhs)
        {
            *this = Reference<DELEGATE_T>(rhs);
        }
        return *this;

    }

    Reference& operator =(
            const null_type nil)
    {
        this = nil;
        return this;
    }

    bool is_nil() const
    {
        return impl_.get() == 0;
    }

    bool operator ==(
            const null_type) const
    {
        return this->is_nil();
    }

    bool operator !=(
            const null_type) const
    {
        return !(this->is_nil());
    }

private:

    // -- disallow dynamic allocation for reference types
    void* operator new(
            size_t);

public:

    DELEGATE_REF_T& delegate()
    {
        return impl_;
    }

    const DELEGATE_REF_T& delegate() const
    {
        return impl_;
    }

    DELEGATE* operator ->()
    {
        return impl_.get();

    }

    const DELEGATE* operator ->() const
    {
        return impl_.get();
    }

    operator DELEGATE_REF_T& ()
    {
        return impl_;
    }

    operator const DELEGATE_REF_T& () const
    {
        return impl_;
    }
protected:

    Reference()
    {
    }

    void set_ref(
            DELEGATE_T* p)
    {
        impl_.reset(p);
    }

protected:

    DELEGATE_REF_T impl_;
};


} //namespace core
} //namespace dds


template<class D>
bool operator ==(
        dds::core::null_type,
        const dds::core::Reference<D>& r)
{
    return r.is_nil();
}

template<class D>
bool operator !=(
        dds::core::null_type,
        const dds::core::Reference<D>& r)
{
    return !r.is_nil();
}

#endif // OMG_DDS_CORE_REFERENCE_HPP_