// Copyright 2016 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.

/*!
 * @file extra_unions.hpp
 * This header file contains the declaration of the described types in the IDL file.
 *
 * This file was generated by the tool fastddsgen (version: 4.1.0).
 */

#ifndef FAST_DDS_GENERATED__EXTRA_UNIONS_HPP
#define FAST_DDS_GENERATED__EXTRA_UNIONS_HPP

#include <cstdint>
#include <functional>
#include <utility>
#include <fastcdr/exceptions/BadParamException.h>


#if defined(_WIN32)
#if defined(EPROSIMA_USER_DLL_EXPORT)
#define eProsima_user_DllExport __declspec( dllexport )
#else
#define eProsima_user_DllExport
#endif  // EPROSIMA_USER_DLL_EXPORT
#else
#define eProsima_user_DllExport
#endif  // _WIN32

#if defined(_WIN32)
#if defined(EPROSIMA_USER_DLL_EXPORT)
#if defined(EXTRA_UNIONS_SOURCE)
#define EXTRA_UNIONS_DllAPI __declspec( dllexport )
#else
#define EXTRA_UNIONS_DllAPI __declspec( dllimport )
#endif // EXTRA_UNIONS_SOURCE
#else
#define EXTRA_UNIONS_DllAPI
#endif  // EPROSIMA_USER_DLL_EXPORT
#else
#define EXTRA_UNIONS_DllAPI
#endif // _WIN32

namespace MyModule {

/*!
 * @brief This class represents the enumeration ScopedEnumHelper defined by the user in the IDL file.
 * @ingroup extra_unions
 */
enum class ScopedEnumHelper : int32_t
{
    ENUM_VALUE_1,
    ENUM_VALUE_2,
    ENUM_VALUE_3
};

} // namespace MyModule
/*!
 * @brief This class represents the union UnionScopedDiscriminator defined by the user in the IDL file.
 * @ingroup extra_unions
 */
class UnionScopedDiscriminator
{
public:

    /*!
     * @brief Default constructor.
     */
    eProsima_user_DllExport UnionScopedDiscriminator()
    {
        selected_member_ = 0x00000003;
        member_destructor_ = nullptr;
        m_third = {0};

    }

    /*!
     * @brief Default destructor.
     */
    eProsima_user_DllExport ~UnionScopedDiscriminator()
    {
        if (member_destructor_)
        {
            member_destructor_();
        }
    }

    /*!
     * @brief Copy constructor.
     * @param x Reference to the object UnionScopedDiscriminator that will be copied.
     */
    eProsima_user_DllExport UnionScopedDiscriminator(
            const UnionScopedDiscriminator& x)
    {
        m__d = x.m__d;

        switch (x.selected_member_)
        {
                        case 0x00000001:
                            first_() = x.m_first;
                            break;

                        case 0x00000002:
                            second_() = x.m_second;
                            break;

                        case 0x00000003:
                            third_() = x.m_third;
                            break;

        }
    }

    /*!
     * @brief Move constructor.
     * @param x Reference to the object UnionScopedDiscriminator that will be copied.
     */
    eProsima_user_DllExport UnionScopedDiscriminator(
            UnionScopedDiscriminator&& x) noexcept
    {
        m__d = x.m__d;

        switch (x.selected_member_)
        {
                        case 0x00000001:
                            first_() = std::move(x.m_first);
                            break;

                        case 0x00000002:
                            second_() = std::move(x.m_second);
                            break;

                        case 0x00000003:
                            third_() = std::move(x.m_third);
                            break;

        }
    }

    /*!
     * @brief Copy assignment.
     * @param x Reference to the object UnionScopedDiscriminator that will be copied.
     */
    eProsima_user_DllExport UnionScopedDiscriminator& operator =(
            const UnionScopedDiscriminator& x)
    {
        m__d = x.m__d;

        switch (x.selected_member_)
        {
                        case 0x00000001:
                            first_() = x.m_first;
                            break;

                        case 0x00000002:
                            second_() = x.m_second;
                            break;

                        case 0x00000003:
                            third_() = x.m_third;
                            break;

        }

        return *this;
    }

    /*!
     * @brief Move assignment.
     * @param x Reference to the object UnionScopedDiscriminator that will be copied.
     */
    eProsima_user_DllExport UnionScopedDiscriminator& operator =(
            UnionScopedDiscriminator&& x) noexcept
    {
        m__d = x.m__d;

        switch (x.selected_member_)
        {
                        case 0x00000001:
                            first_() = std::move(x.m_first);
                            break;

                        case 0x00000002:
                            second_() = std::move(x.m_second);
                            break;

                        case 0x00000003:
                            third_() = std::move(x.m_third);
                            break;

        }

        return *this;
    }

    /*!
     * @brief Comparison operator.
     * @param x UnionScopedDiscriminator object to compare.
     */
    eProsima_user_DllExport bool operator ==(
            const UnionScopedDiscriminator& x) const
    {
        bool ret_value {false};

        if (x.selected_member_ == selected_member_)
        {
            if (0x0FFFFFFFu != selected_member_)
            {
                if (x.m__d == m__d)
                {
                    switch (selected_member_)
                    {
                                                    case 0x00000001:
                                                        ret_value = (x.m_first == m_first);
                                                        break;

                                                    case 0x00000002:
                                                        ret_value = (x.m_second == m_second);
                                                        break;

                                                    case 0x00000003:
                                                        ret_value = (x.m_third == m_third);
                                                        break;

                    }
                }
            }
            else
            {
                ret_value = true;
            }
        }

        return ret_value;
    }

    /*!
     * @brief Comparison operator.
     * @param x UnionScopedDiscriminator object to compare.
     */
    eProsima_user_DllExport bool operator !=(
            const UnionScopedDiscriminator& x) const
    {
        return !(*this == x);
    }

    /*!
     * @brief This function sets the discriminator value.
     * @param __d New value for the discriminator.
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the new value doesn't correspond to the selected union member.
     */
    eProsima_user_DllExport void _d(
            MyModule::ScopedEnumHelper __d)
    {
        bool valid_discriminator = false;

        switch (__d)
        {
                        case MyModule::ScopedEnumHelper::ENUM_VALUE_1:
                            if (0x00000001 == selected_member_)
                            {
                                valid_discriminator = true;
                            }
                            break;

                        case MyModule::ScopedEnumHelper::ENUM_VALUE_2:
                            if (0x00000002 == selected_member_)
                            {
                                valid_discriminator = true;
                            }
                            break;

                        default:
                            if (0x00000003 == selected_member_)
                            {
                                valid_discriminator = true;
                            }
                            break;

        }

        if (!valid_discriminator)
        {
            throw eprosima::fastcdr::exception::BadParamException("Discriminator doesn't correspond with the selected union member");
        }

        m__d = __d;
    }

    /*!
     * @brief This function returns the value of the discriminator.
     * @return Value of the discriminator
     */
    eProsima_user_DllExport MyModule::ScopedEnumHelper _d() const
    {
        return m__d;
    }

    /*!
     * @brief This function sets a value in member first
     * @param _first New value for member first
     */
    eProsima_user_DllExport void first(
            int32_t _first)
    {
        first_() = _first;
        m__d = MyModule::ScopedEnumHelper::ENUM_VALUE_1;
    }

    /*!
     * @brief This function returns the value of member first
     * @return Value of member first
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the requested union member is not the current selection.
     */
    eProsima_user_DllExport int32_t first() const
    {
        if (0x00000001 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_first;
    }

    /*!
     * @brief This function returns a reference to member first
     * @return Reference to member first
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the requested union member is not the current selection.
     */
    eProsima_user_DllExport int32_t& first()
    {
        if (0x00000001 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_first;
    }


    /*!
     * @brief This function sets a value in member second
     * @param _second New value for member second
     */
    eProsima_user_DllExport void second(
            int64_t _second)
    {
        second_() = _second;
        m__d = MyModule::ScopedEnumHelper::ENUM_VALUE_2;
    }

    /*!
     * @brief This function returns the value of member second
     * @return Value of member second
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the requested union member is not the current selection.
     */
    eProsima_user_DllExport int64_t second() const
    {
        if (0x00000002 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_second;
    }

    /*!
     * @brief This function returns a reference to member second
     * @return Reference to member second
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the requested union member is not the current selection.
     */
    eProsima_user_DllExport int64_t& second()
    {
        if (0x00000002 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_second;
    }


    /*!
     * @brief This function sets a value in member third
     * @param _third New value for member third
     */
    eProsima_user_DllExport void third(
            uint8_t _third)
    {
        third_() = _third;
        m__d = MyModule::ScopedEnumHelper::ENUM_VALUE_3;
    }

    /*!
     * @brief This function returns the value of member third
     * @return Value of member third
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the requested union member is not the current selection.
     */
    eProsima_user_DllExport uint8_t third() const
    {
        if (0x00000003 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_third;
    }

    /*!
     * @brief This function returns a reference to member third
     * @return Reference to member third
     * @exception eprosima::fastcdr::exception::BadParamException This exception is thrown if the requested union member is not the current selection.
     */
    eProsima_user_DllExport uint8_t& third()
    {
        if (0x00000003 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_third;
    }



private:

            int32_t& first_()
            {
                if (0x00000001 != selected_member_)
                {
                    if (member_destructor_)
                    {
                        member_destructor_();
                    }

                    selected_member_ = 0x00000001;
                    member_destructor_ = nullptr;
                    m_first = {0};

                }

                return m_first;
            }

            int64_t& second_()
            {
                if (0x00000002 != selected_member_)
                {
                    if (member_destructor_)
                    {
                        member_destructor_();
                    }

                    selected_member_ = 0x00000002;
                    member_destructor_ = nullptr;
                    m_second = {0};

                }

                return m_second;
            }

            uint8_t& third_()
            {
                if (0x00000003 != selected_member_)
                {
                    if (member_destructor_)
                    {
                        member_destructor_();
                    }

                    selected_member_ = 0x00000003;
                    member_destructor_ = nullptr;
                    m_third = {0};

                }

                return m_third;
            }


    MyModule::ScopedEnumHelper m__d {MyModule::ScopedEnumHelper::ENUM_VALUE_3};

    union
    {
        int32_t m_first;
        int64_t m_second;
        uint8_t m_third;
    };

    uint32_t selected_member_ {0x0FFFFFFFu};

    std::function<void()> member_destructor_;
};

#endif // _FAST_DDS_GENERATED_EXTRA_UNIONS_HPP_


