struct context_null {};
-template <typename Tag, typename Tail = context_null>
+template <typename Tag, typename Tail = context_null>
struct context_cons
{
- Tag tag;
- Tail const& tail;
-};
-
-template <typename Tag>
-struct context_cons<Tag, context_null>
-{
- Tag tag;
- context_null tail;
+ typename std::remove_reference<Tag>::type const tag;
+ typename std::remove_reference<Tail>::type const tail;
};
template <typename NewTag, typename Tag, typename Tail>
-context_cons<NewTag, context_cons<Tag, Tail>>
-context_add_tag(NewTag tag, context_cons<Tag, Tail> const& context)
+constexpr context_cons<NewTag, context_cons<Tag, Tail>>
+context_add_tag(NewTag const& tag, context_cons<Tag, Tail> const& context)
{
return context_cons<NewTag, context_cons<Tag, Tail>>{tag, context};
}
template <typename NewTag>
-context_cons<NewTag, context_null>
-context_add_tag(NewTag tag, context_null context)
+constexpr context_cons<NewTag, context_null>
+context_add_tag(NewTag const& tag, context_null context)
{
return context_cons<NewTag, context_null>{tag, context};
}
+template <typename Tag, typename SameTag, typename Tail>
+constexpr context_cons<SameTag, Tail>
+context_replace_tag(Tag const& tag, context_cons<SameTag, Tail> const& context
+ , typename std::enable_if<std::is_same<Tag, SameTag>::value>::type* = nullptr)
+{
+ return {tag, context.tail};
+}
+
+template <typename Tag, typename OtherTag, typename Tail>
+constexpr context_cons<OtherTag, Tail>
+context_replace_tag(Tag const& tag, context_cons<OtherTag, Tail> const& context
+ , typename std::enable_if<!std::is_same<Tag, OtherTag>::value>::type* = nullptr)
+{
+ return {context.tag, context_replace_tag(tag, context.tail)};
+}
+
+template <typename Tag>
+constexpr context_null
+context_replace_tag(Tag const& tag, context_null const&)
+{
+ static_assert(std::is_same<Tag, context_null>::value, "Tag type not available in this generation context");
+ return tag;
+}
+
template <typename Tag, typename Context>
struct tag_check;
template <typename Tag, typename Tail>
struct tag_check<Tag, context_cons<OtherTag, Context>> : tag_check<Tag, Context> {};
template <typename Tag, typename SameTag, typename Tail>
-Tag const& context_find_tag(context_cons<SameTag, Tail> const& context
+constexpr Tag const& context_find_tag(context_cons<SameTag, Tail> const& context
, typename std::enable_if<std::is_same<Tag, SameTag>::value>::type* = nullptr)
{
return context.tag;
}
template <typename Tag, typename OtherTag, typename Tail>
-Tag const& context_find_tag(context_cons<OtherTag, Tail> const& context
+constexpr Tag const& context_find_tag(context_cons<OtherTag, Tail> const& context
, typename std::enable_if<!std::is_same<Tag, OtherTag>::value>::type* = nullptr)
{
return context_find_tag<Tag>(context.tail);
}
-template <typename Tag, typename OtherTag, typename Tail>
-Tag const& context_find_tag(context_null const&)
+template <typename Tag>
+constexpr Tag const& context_find_tag(context_null const& context)
{
- throw std::logic_error("Context for generation not available");
+ static_assert(std::is_same<Tag, context_null>::value, "Tag type not available in this generation context");
+ return context;
}
-
+
} } }
#endif
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 <typename OutputIterator, typename Context>
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 <>
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 = {};