ROSE  0.11.145.0
metaprog.h
1 #ifndef Rose_metaprog_h
2 #define Rose_metaprog_h
3 
4 namespace Rose {
5 
7 namespace metaprog {
8 
9 namespace details {
10 
11 template <typename L, typename R, bool = L::value>
12 struct and_t {
13  static constexpr bool value = false;
14 };
15 
16 template <typename L, typename R>
17 struct and_t<L,R,true> {
18  static constexpr bool value = R::value;
19 };
20 
21 template <typename L>
22 struct and_t<L,void,true> {
23  static constexpr bool value = true;
24 };
25 
26 template <typename L, typename R, bool = L::value>
27 struct or_t {
28  static constexpr bool value = true;
29 };
30 
31 template <typename L, typename R>
32 struct or_t<L,R,false> {
33  static constexpr bool value = R::value;
34 };
35 
36 template <typename L>
37 struct or_t<L,void,false> {
38  static constexpr bool value = false;
39 };
40 
41 }
42 
43 template <typename L, typename R> struct and_t : details::and_t<L,R> {};
44 template <typename L, typename R> struct or_t : details::or_t<L,R> {};
45 
52 template <typename... Elements>
53 struct List;
54 
55 template <typename T>
56 struct is_list_t {
57  static constexpr bool value = false;
58 };
59 
60 template <typename... Ts>
61 struct is_list_t<List<Ts...>> {
62  static constexpr bool value = true;
63 };
64 
65 template <typename T> using enable_list = typename std::enable_if<is_list_t<T>::value>::type;
66 template <typename T> using disable_list = typename std::enable_if<!is_list_t<T>::value>::type;
67 
69 template <typename... Elements>
70 struct list_base_t {
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 
78 template <typename... Elements>
79 struct 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 
136 namespace 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>
148  struct list_filter_t {
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 
158 template <typename Element, typename... Elements>
159 struct 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 
192 template <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 
211 namespace 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 
227 template <class C> constexpr bool is_iterable = details::is_iterable_t<C>::value;
228 
229 }
230 
231 namespace mp = metaprog;
232 
233 }
234 
235 #endif /* Rose_metaprog_h */
constexpr bool is_iterable
Detect STL-like containers.
Definition: metaprog.h:227
typename head::template append_ravel< tail > list
pseudo: return head+tail;
Definition: metaprog.h:207
void reduce_t
Reduce ...
Definition: metaprog.h:106
static constexpr size_t length
Length of the list.
Definition: metaprog.h:125
Traverse a tree (pre-order, depth-first) and build a list of values.
Definition: metaprog.h:201
STL namespace.
Build traversals for meta-tree.
Definition: metaprog.h:193
Main namespace for the ROSE library.
A template list implementing a apply pattern (functor return void but does not have to be pure) ...
Definition: metaprog.h:53
helper base class for metaprogramming list
Definition: metaprog.h:70
std::conditional_t< Predicate< RootTag >::value, List< typename Extract< RootTag >::type >, List<> > head
pseudo: head = Predicate ? List> : List<>;
Definition: metaprog.h:203
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
typename Children< RootTag >::list::template map_ravel_t< preorder_depthfirst_t > tail
pseudo: for (ChildTag: Children) tail += preorder_depthfirst_t; ...
Definition: metaprog.h:205