diff --git a/src/lib/eolian_cxx/grammar/context.hpp b/src/lib/eolian_cxx/grammar/context.hpp index e4839200bc..6fb171ab66 100644 --- a/src/lib/eolian_cxx/grammar/context.hpp +++ b/src/lib/eolian_cxx/grammar/context.hpp @@ -5,33 +5,50 @@ namespace efl { namespace eolian { namespace grammar { struct context_null {}; -template +template struct context_cons { - Tag tag; - Tail const& tail; -}; - -template -struct context_cons -{ - Tag tag; - context_null tail; + typename std::remove_reference::type const tag; + typename std::remove_reference::type const tail; }; template -context_cons> -context_add_tag(NewTag tag, context_cons const& context) +constexpr context_cons> +context_add_tag(NewTag const& tag, context_cons const& context) { return context_cons>{tag, context}; } template -context_cons -context_add_tag(NewTag tag, context_null context) +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 @@ -42,25 +59,26 @@ template struct tag_check> : tag_check {}; template -Tag const& context_find_tag(context_cons const& context +constexpr Tag const& context_find_tag(context_cons const& context , typename std::enable_if::value>::type* = nullptr) { return context.tag; } template -Tag const& context_find_tag(context_cons const& context +constexpr Tag const& context_find_tag(context_cons const& context , typename std::enable_if::value>::type* = nullptr) { return context_find_tag(context.tail); } -template -Tag const& context_find_tag(context_null const&) +template +constexpr Tag const& context_find_tag(context_null const& context) { - throw std::logic_error("Context for generation not available"); + static_assert(std::is_same::value, "Tag type not available in this generation context"); + return context; } - + } } } #endif diff --git a/src/lib/eolian_cxx/grammar/indentation.hpp b/src/lib/eolian_cxx/grammar/indentation.hpp index 897be03c3b..347974fa01 100644 --- a/src/lib/eolian_cxx/grammar/indentation.hpp +++ b/src/lib/eolian_cxx/grammar/indentation.hpp @@ -8,22 +8,36 @@ namespace efl { namespace eolian { namespace grammar { struct scope_tab_generator { - scope_tab_generator(int n) - : n(n) {} - + constexpr scope_tab_generator(int n, int m = 4) + : n(n) + , m(m) + {} + constexpr scope_tab_generator(scope_tab_generator const&) = default; + scope_tab_generator& operator=(scope_tab_generator const&) = default; + template bool generate(OutputIterator sink, attributes::unused_type, Context const&) const { for(int i = 0; i != n; ++i) { - *sink++ = ' '; - *sink++ = ' '; - *sink++ = ' '; + for(int j = 0; j != m; ++j) + *sink++ = ' '; } return true; } + constexpr scope_tab_generator inc(int nplus = 1) const + { + return {n+nplus, m}; + } + + constexpr scope_tab_generator dec(int nminus = 1) const + { + return {n-nminus, m}; + } + int n; + int m; }; template <> @@ -33,9 +47,14 @@ struct is_generator : std::true_type {}; struct scope_tab_terminal { - scope_tab_generator operator()(int n) const + scope_tab_generator operator()(int n, int m = 4) const { - return scope_tab_generator(n); + return {n, m}; + } + + operator scope_tab_generator() const + { + return {1}; } } const scope_tab = {};