// 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 union_struct.hpp
 * This header file contains the declaration of the described types in the IDL file.
 *
 * This file was generated by the tool fastddsgen.
 */

#ifndef FAST_DDS_GENERATED__UNION_STRUCT_HPP
#define FAST_DDS_GENERATED__UNION_STRUCT_HPP

#include <cstdint>
#include <functional>
#include <string>
#include <utility>
#include <fastcdr/cdr/fixed_size_string.hpp>
#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(UNION_STRUCT_SOURCE)
#define UNION_STRUCT_DllAPI __declspec( dllexport )
#else
#define UNION_STRUCT_DllAPI __declspec( dllimport )
#endif // UNION_STRUCT_SOURCE
#else
#define UNION_STRUCT_DllAPI
#endif  // EPROSIMA_USER_DLL_EXPORT
#else
#define UNION_STRUCT_DllAPI
#endif // _WIN32

/*!
 * @brief This class represents the union BasicUnion defined by the user in the IDL file.
 * @ingroup union_struct
 */
class BasicUnion
{
public:

    /*!
     * @brief Default constructor.
     */
    eProsima_user_DllExport BasicUnion()
    {
        selected_member_ = 0x00000002;
        member_destructor_ = nullptr;
        m_second = {0};

    }

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

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

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

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

        }
    }

    /*!
     * @brief Move constructor.
     * @param x Reference to the object BasicUnion that will be copied.
     */
    eProsima_user_DllExport BasicUnion(
            BasicUnion&& 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;

        }
    }

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

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

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

        }

        return *this;
    }

    /*!
     * @brief Move assignment.
     * @param x Reference to the object BasicUnion that will be copied.
     */
    eProsima_user_DllExport BasicUnion& operator =(
            BasicUnion&& 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;

        }

        return *this;
    }

    /*!
     * @brief Comparison operator.
     * @param x BasicUnion object to compare.
     */
    eProsima_user_DllExport bool operator ==(
            const BasicUnion& 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;

                    }
                }
            }
            else
            {
                ret_value = true;
            }
        }

        return ret_value;
    }

    /*!
     * @brief Comparison operator.
     * @param x BasicUnion object to compare.
     */
    eProsima_user_DllExport bool operator !=(
            const BasicUnion& 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(
            int16_t __d)
    {
        bool valid_discriminator = false;

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

                        case 1:
                        default:
                            if (0x00000002 == 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 int16_t _d() const
    {
        return m__d;
    }

    /*!
     * @brief This function copies the value in member first
     * @param _first New value to be copied in member first
     */
    eProsima_user_DllExport void first(
            const std::string& _first)
    {
        first_() = _first;
        m__d = 0;
    }

    /*!
     * @brief This function moves the value in member first
     * @param _first New value to be moved in member first
     */
    eProsima_user_DllExport void first(
            std::string&& _first)
    {
        first_() = _first;
        m__d = 0;
    }

    /*!
     * @brief This function returns a constant reference to member first
     * @return Constant 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 const std::string& 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 std::string& 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 = 32767;
    }

    /*!
     * @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;
    }



private:

            std::string& first_()
            {
                if (0x00000001 != selected_member_)
                {
                    if (member_destructor_)
                    {
                        member_destructor_();
                    }

                    selected_member_ = 0x00000001;
                    member_destructor_ = [&]()
                    {
                        m_first.~basic_string();
                    };
                    new(&m_first) std::string();

                }

                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;
            }


    int16_t m__d {32767};

    union
    {
        std::string m_first;
        int64_t m_second;
    };

    uint32_t selected_member_ {0x0FFFFFFFu};

    std::function<void()> member_destructor_;
};
/*!
 * @brief This class represents the union ComplexUnion defined by the user in the IDL file.
 * @ingroup union_struct
 */
class ComplexUnion
{
public:

    /*!
     * @brief Default constructor.
     */
    eProsima_user_DllExport ComplexUnion()
    {
        selected_member_ = 0x00000002;
        member_destructor_ = [&]()
        {
            m_fourth.~BasicUnion();
        };
        new(&m_fourth) BasicUnion();

    }

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

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

        switch (x.selected_member_)
        {
                        case 0x00000001:
                            third_() = x.m_third;
                            break;

                        case 0x00000002:
                            fourth_() = x.m_fourth;
                            break;

        }
    }

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

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

                        case 0x00000002:
                            fourth_() = std::move(x.m_fourth);
                            break;

        }
    }

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

        switch (x.selected_member_)
        {
                        case 0x00000001:
                            third_() = x.m_third;
                            break;

                        case 0x00000002:
                            fourth_() = x.m_fourth;
                            break;

        }

        return *this;
    }

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

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

                        case 0x00000002:
                            fourth_() = std::move(x.m_fourth);
                            break;

        }

        return *this;
    }

    /*!
     * @brief Comparison operator.
     * @param x ComplexUnion object to compare.
     */
    eProsima_user_DllExport bool operator ==(
            const ComplexUnion& 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_third == m_third);
                                                        break;

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

                    }
                }
            }
            else
            {
                ret_value = true;
            }
        }

        return ret_value;
    }

    /*!
     * @brief Comparison operator.
     * @param x ComplexUnion object to compare.
     */
    eProsima_user_DllExport bool operator !=(
            const ComplexUnion& 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(
            int32_t __d)
    {
        bool valid_discriminator = false;

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

                        default:
                            if (0x00000002 == 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 int32_t _d() const
    {
        return m__d;
    }

    /*!
     * @brief This function sets a value in member third
     * @param _third New value for member third
     */
    eProsima_user_DllExport void third(
            int32_t _third)
    {
        third_() = _third;
        m__d = 0;
    }

    /*!
     * @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 int32_t third() const
    {
        if (0x00000001 != 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 int32_t& third()
    {
        if (0x00000001 != selected_member_)
        {
            throw eprosima::fastcdr::exception::BadParamException("This member has not been selected");
        }

        return m_third;
    }


    /*!
     * @brief This function copies the value in member fourth
     * @param _fourth New value to be copied in member fourth
     */
    eProsima_user_DllExport void fourth(
            const BasicUnion& _fourth)
    {
        fourth_() = _fourth;
        m__d = 2147483647;
    }

    /*!
     * @brief This function moves the value in member fourth
     * @param _fourth New value to be moved in member fourth
     */
    eProsima_user_DllExport void fourth(
            BasicUnion&& _fourth)
    {
        fourth_() = _fourth;
        m__d = 2147483647;
    }

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

        return m_fourth;
    }

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

        return m_fourth;
    }



private:

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

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

                }

                return m_third;
            }

            BasicUnion& fourth_()
            {
                if (0x00000002 != selected_member_)
                {
                    if (member_destructor_)
                    {
                        member_destructor_();
                    }

                    selected_member_ = 0x00000002;
                    member_destructor_ = [&]()
                    {
                        m_fourth.~BasicUnion();
                    };
                    new(&m_fourth) BasicUnion();

                }

                return m_fourth;
            }


    int32_t m__d {2147483647};

    union
    {
        int32_t m_third;
        BasicUnion m_fourth;
    };

    uint32_t selected_member_ {0x0FFFFFFFu};

    std::function<void()> member_destructor_;
};
/*!
 * @brief This class represents the structure UnionStruct defined by the user in the IDL file.
 * @ingroup union_struct
 */
class UnionStruct
{
public:

    /*!
     * @brief Default constructor.
     */
    eProsima_user_DllExport UnionStruct()
    {
    }

    /*!
     * @brief Default destructor.
     */
    eProsima_user_DllExport ~UnionStruct()
    {
    }

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

    }

    /*!
     * @brief Move constructor.
     * @param x Reference to the object UnionStruct that will be copied.
     */
    eProsima_user_DllExport UnionStruct(
            UnionStruct&& x) noexcept
    {
        m_my_complex_union = std::move(x.m_my_complex_union);
    }

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

                    m_my_complex_union = x.m_my_complex_union;

        return *this;
    }

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

        m_my_complex_union = std::move(x.m_my_complex_union);
        return *this;
    }

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

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

    /*!
     * @brief This function copies the value in member my_complex_union
     * @param _my_complex_union New value to be copied in member my_complex_union
     */
    eProsima_user_DllExport void my_complex_union(
            const ComplexUnion& _my_complex_union)
    {
        m_my_complex_union = _my_complex_union;
    }

    /*!
     * @brief This function moves the value in member my_complex_union
     * @param _my_complex_union New value to be moved in member my_complex_union
     */
    eProsima_user_DllExport void my_complex_union(
            ComplexUnion&& _my_complex_union)
    {
        m_my_complex_union = std::move(_my_complex_union);
    }

    /*!
     * @brief This function returns a constant reference to member my_complex_union
     * @return Constant reference to member my_complex_union
     */
    eProsima_user_DllExport const ComplexUnion& my_complex_union() const
    {
        return m_my_complex_union;
    }

    /*!
     * @brief This function returns a reference to member my_complex_union
     * @return Reference to member my_complex_union
     */
    eProsima_user_DllExport ComplexUnion& my_complex_union()
    {
        return m_my_complex_union;
    }



private:

    ComplexUnion m_my_complex_union;

};

#endif // _FAST_DDS_GENERATED_UNION_STRUCT_HPP_


