{#-
 # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 # Copyright (C) 2021  UAVCAN Development Team  <uavcan.org>
 # This software is distributed under the terms of the MIT License.
#}
    class VariantType final : public std::variant<
{%- for field in composite_type.fields_except_padding %}
        {{ field.doc | block_comment('cpp-doxygen', 8, 120) }}
        {{ field.data_type | declaration }}{% if not loop.last %},{% endif %}
{%- endfor %}
    >
    {
    public:

        static const constexpr std::size_t variant_npos = std::variant_npos;

        struct IndexOf final
        {
            IndexOf() = delete;
{%- for field in composite_type.fields_except_padding %}
            static constexpr const std::size_t {{ field.name | id }} = {{ loop.index0 }}U;
{%- endfor %}
        };
        static constexpr const std::size_t MAX_INDEX = {{ composite_type.fields_except_padding  | length }}U;

        template<size_t I, typename T>
        struct alternative;

        template<size_t I, typename... Types>
        struct alternative<I, std::variant<Types...>> final
        {
            using type = typename std::variant_alternative<I, std::variant<Types...>>::type;
        };

        template<size_t I, typename T>
        struct alternative<I, const T> final
        {
            using type = std::add_const_t<typename std::variant_alternative<I, T>::type>;
        };

        template<std::size_t I, class... Types>
        static constexpr typename alternative<I, std::variant<Types...>>::type* get_if(std::variant<Types...>* v) noexcept
        {
            return std::get_if<I, Types...>(v);
        }

        template<std::size_t I, class... Types>
        static constexpr const typename alternative<I, std::variant<Types...>>::type* get_if(const std::variant<Types...>* v) noexcept
        {
            return std::get_if<I, Types...>(v);
        }

    };

    VariantType union_value;
