From dc1b0487b94552b6f8304c448ee11bebcc56f148 Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Fri, 22 Mar 2019 18:34:29 -0300 Subject: [PATCH] eolian_cxx: rework context code, also more flexible scope indentation generator Summary: Context management classes now store constant copies of the tags they are supposed to hold. So, they are immutable objects now. Functions that manipulate context create new object copies as needed. `constexpr` was added for class constructor and functions. Indentation generator now used four space by default. Also, the amount of desired spaces can now be specified at call site. Added helper methods to return 'indented' and 'unindented' version of a given indentation generator object. Test Plan: ninja test Reviewers: felipealmeida, lauromoura Reviewed By: lauromoura Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8467 --- src/lib/eolian_cxx/grammar/context.hpp | 58 +++++++++++++++++++----------- src/lib/eolian_cxx/grammar/indentation.hpp | 35 +++++++++++++----- 2 files changed, 65 insertions(+), 28 deletions(-) diff --git a/src/lib/eolian_cxx/grammar/context.hpp b/src/lib/eolian_cxx/grammar/context.hpp index e483920..6fb171a 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 897be03..347974f 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 {n, m}; + } + + operator scope_tab_generator() const { - return scope_tab_generator(n); + return {1}; } } const scope_tab = {}; -- 2.7.4