/** @file {{iface_facet_any_hpp_fname}}
 *
 *  Generated automagically from ingredients:
 *  1. code generator:
 *       [{{genfacet}}]
 *     arguments:
 *       --input [{{genfacet_input}}]
 *  2. jinja2 template for abstract facet .hpp file:
 *       [{{ iface_facet_any_hpp_j2 }}]
 *  3. idl for facet methods
 *       [{{ idl_fname }}]
 **/

#pragma once

#include "{{abstract_facet_fname}}"
#include <xo/facet/obj.hpp>

namespace {{facet_ns1}} { namespace {{facet_ns2}} { class {{iface_facet_any}}; } }

namespace xo {
namespace facet {

template <>
struct FacetImplementation<{{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}},
                           DVariantPlaceholder>
{
    using ImplType = {{facet_ns1}}::{{facet_ns2}}::{{iface_facet_any}};
};

}
}

namespace {{facet_ns1}} {
namespace {{facet_ns2}} {

    /** @class {{iface_facet_any}}
     *  @brief {{abstract_facet}} implementation for empty variant instance
     **/
    class {{iface_facet_any}} : public {{abstract_facet}} {
    public:
        {% if using_dox %}
        /** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-type-traits **/
        ///@{
        {% endif %}

        /** integer identifying a type **/
        using typeseq = xo::facet::typeseq;
        {% for ty in types %}
        using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
        {% endfor %}

        {% if using_dox %}
        ///@}
        {% endif %}
        {% if using_dox %}
        /** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-methods **/
        ///@{
        {% endif %}

        const {{abstract_facet}} * iface() const { return std::launder(this); }

        // from {{abstract_facet}}

        // const methods
        typeseq _typeseq() const noexcept override { return s_typeseq; }
        {% for md in const_methods %}
        [[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); }
        {% endfor %}

        // nonconst methods
        {% for md in nonconst_methods %}
        [[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); }
        {% endfor %}

        {% if using_dox %}
        ///@}
        {% endif %}

    private:
        {% if using_dox %}
        /** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-any-private-methods **/
        ///@{
        {% endif %}

        [[noreturn]] static void _fatal();

        {% if using_dox %}
        ///@}
        {% endif %}

    public:
        {% if using_dox %}
        /** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-member-vars **/
        ///@{
        {% endif %}

        static typeseq s_typeseq;
        static bool _valid;

        {% if using_dox %}
        ///@}
        {% endif %}
    };

} /*namespace {{facet_ns2}} */
} /*namespace {{facet_ns1}} */

/* {{iface_facet_any_hpp_fname}} */
