ROSE 0.11.145.147
metaprog.h
1#ifndef Rose_metaprog_h
2#define Rose_metaprog_h
3
4namespace Rose {
5
7namespace metaprog {
8
9namespace details {
10
11template <typename L, typename R, bool = L::value>
12struct and_t {
13 static constexpr bool value = false;
14};
15
16template <typename L, typename R>
17struct and_t<L,R,true> {
18 static constexpr bool value = R::value;
19};
20
21template <typename L>
22struct and_t<L,void,true> {
23 static constexpr bool value = true;
24};
25
26template <typename L, typename R, bool = L::value>
27struct or_t {
28 static constexpr bool value = true;
29};
30
31template <typename L, typename R>
32struct or_t<L,R,false> {
33 static constexpr bool value = R::value;
34};
35
36template <typename L>
37struct or_t<L,void,false> {
38 static constexpr bool value = false;
39};
40
41}
42
43template <typename L, typename R> struct and_t : details::and_t<L,R> {};
44template <typename L, typename R> struct or_t : details::or_t<L,R> {};
45
52template <typename... Elements>
53struct List;
54
55template <typename T>
56struct is_list_t {
57 static constexpr bool value = false;
58};
59
60template <typename... Ts>
61struct is_list_t<List<Ts...>> {
62 static constexpr bool value = true;
63};
64
65template <typename T> using enable_list = typename std::enable_if<is_list_t<T>::value>::type;
66template <typename T> using disable_list = typename std::enable_if<!is_list_t<T>::value>::type;
67
69template <typename... Elements>
71 template <typename L> using append_ravel = typename L::template prepend<Elements...>;
72 template <typename L> using prepend_ravel = typename L::template append<Elements...>;
73
74 template <typename... Es> using append = List<Elements..., Es...>;
75 template <typename... Es> using prepend = List<Es..., Elements...>;
76};
77
78template <typename... Elements>
79struct List : list_base_t<Elements...> {
89 template <typename Functor, typename... Args>
90 static inline void apply(Functor && functor, Args&&... args) {}
91
97 template <template <typename> class Functor>
98 using map_t = List<>;
99
105 template <template <typename,typename> class Reducer>
106 using reduce_t = void;
107
113 template <template <typename> class Functor>
115
121 template <template <typename> class Predicate>
122 using filter = List<>;
123
125 static constexpr size_t length{0};
126
132 template <size_t position>
133 using at = void;
134};
135
136namespace details {
137 template <size_t position, typename Element, typename... Elements>
138 struct list_at_t {
139 using type = typename List<Elements...>::template at<position-1>;
140 };
141
142 template <typename Element, typename... Elements>
143 struct list_at_t<0, Element, Elements...> {
144 using type = Element;
145 };
146
147 template <template <typename> class Predicate, bool, typename Element, typename... Elements>
149 using list = typename List<Elements...>::template filter<Predicate>;
150 };
151
152 template <template <typename> class Predicate, typename Element, typename... Elements>
153 struct list_filter_t<Predicate, true, Element, Elements...> {
154 using list = typename List<Elements...>::template filter<Predicate>::template prepend<Element>;
155 };
156}
157
158template <typename Element, typename... Elements>
159struct List<Element, Elements...> : list_base_t<Element, Elements...> {
160 template <typename Functor, typename... Args>
161 static inline void apply(Functor && functor, Args&&... args) {
162 functor.template operator()<Element>(std::forward<Args>(args)...);
163 List<Elements...>::template apply<Functor>(std::forward<Functor>(functor), std::forward<Args>(args)...);
164 }
165
166 template <template <typename> class Functor>
167 using map_t = typename List<Elements...>::template map_t<Functor>::template prepend< typename Functor<Element>::type >;
168
169 template <template <typename, typename> class Reducer>
170 using reduce_t = Reducer< Element, typename List<Elements...>::template reduce_t<Reducer> >;
171
172 template <template <typename> class Functor>
173 using map_ravel_t = typename List<Elements...>::template map_ravel_t<Functor>::template prepend_ravel<typename Functor<Element>::list>;
174
175 template <template <typename> class Predicate>
176 using filter = typename details::list_filter_t<Predicate, Predicate<Element>::value, Element, Elements...>::list;
177
178 static constexpr size_t length{ List<Elements...>::length + 1 };
179
180 template <size_t position>
181 using at = typename details::list_at_t<position, Element, Elements...>::type;
182};
183
192template <template<typename> class Predicate, template<typename> class Extract, template<typename> class Children>
194
200 template <typename RootTag>
203 using head = std::conditional_t<Predicate<RootTag>::value, List<typename Extract<RootTag>::type>, List<> >;
205 using tail = typename Children<RootTag>::list::template map_ravel_t<preorder_depthfirst_t>;
207 using list = typename head::template append_ravel<tail>;
208 };
209};
210
211namespace details {
212
213 template<typename... Ts> struct make_void { typedef void type;};
214 template<typename... Ts> using void_t = typename make_void<Ts...>::type;
215
216 template <typename T, typename = void>
217 struct is_iterable_t : std::false_type {};
218
219 template <typename T>
220 struct is_iterable_t<T, void_t<
221 decltype(std::begin(std::declval<T>())),
222 decltype(std::end(std::declval<T>()))
223 > > : std::true_type {};
224}
225
227template <class C> constexpr bool is_iterable = details::is_iterable_t<C>::value;
228
229}
230
231namespace mp = metaprog;
232
233}
234
235#endif /* Rose_metaprog_h */
constexpr bool is_iterable
Detect STL-like containers.
Definition metaprog.h:227
The ROSE library.
A template list implementing a apply pattern (functor return void but does not have to be pure)
Definition metaprog.h:79
static constexpr size_t length
Length of the list.
Definition metaprog.h:125
void at
Return the element at the given position (void if out-of-bound)
Definition metaprog.h:133
static void apply(Functor &&functor, Args &&... args)
Apply the given instance of Functor to each element of the list (in order)
Definition metaprog.h:90
void reduce_t
Reduce ...
Definition metaprog.h:106
helper base class for metaprogramming list
Definition metaprog.h:70
Traverse a tree (pre-order, depth-first) and build a list of values.
Definition metaprog.h:201
typename head::template append_ravel< tail > list
pseudo: return head+tail;
Definition metaprog.h:207
typename Children< RootTag >::list::template map_ravel_t< preorder_depthfirst_t > tail
pseudo: for (ChildTag: Children<RootTag>) tail += preorder_depthfirst_t<ChildTag>;
Definition metaprog.h:205
std::conditional_t< Predicate< RootTag >::value, List< typename Extract< RootTag >::type >, List<> > head
pseudo: head = Predicate<RootTag> ? List<Extract<RootTag>> : List<>;
Definition metaprog.h:203
Build traversals for meta-tree.
Definition metaprog.h:193