#ifndef EOLIAN_CXX_CONTEXT_HH #define EOLIAN_CXX_CONTEXT_HH namespace efl { namespace eolian { namespace grammar { struct context_null {}; template struct context_cons { typename std::remove_reference::type const tag; typename std::remove_reference::type const tail; }; template constexpr context_cons> context_add_tag(NewTag const& tag, context_cons const& context) { return context_cons>{tag, context}; } template constexpr context_cons context_add_tag(NewTag const& tag, context_null context) { return context_cons{tag, context}; } template constexpr context_cons context_replace_tag(Tag const& tag, context_cons const& context , typename std::enable_if::value>::type* = nullptr) { return {tag, context.tail}; } template constexpr context_cons context_replace_tag(Tag const& tag, context_cons const& context , typename std::enable_if::value>::type* = nullptr) { return {context.tag, context_replace_tag(tag, context.tail)}; } template constexpr context_null context_replace_tag(Tag const& tag, context_null const&) { static_assert(std::is_same::value, "Tag type not available in this generation context"); return tag; } template struct tag_check; template struct tag_check> : std::true_type {}; template struct tag_check : std::false_type {}; template struct tag_check> : tag_check {}; template constexpr Tag const& context_find_tag(context_cons const& context , typename std::enable_if::value>::type* = nullptr) { return context.tag; } template constexpr Tag const& context_find_tag(context_cons const& context , typename std::enable_if::value>::type* = nullptr) { return context_find_tag(context.tail); } template constexpr Tag const& context_find_tag(context_null const& context) { static_assert(std::is_same::value, "Tag type not available in this generation context"); return context; } } } } #endif