MPL11
 All Classes Namespaces Files Typedefs Macros Groups Pages
functional.hpp
Go to the documentation of this file.
1 
12 #ifndef BOOST_MPL11_FUNCTIONAL_HPP
13 #define BOOST_MPL11_FUNCTIONAL_HPP
14 
16 
21 
22 
23 namespace boost { namespace mpl11 {
25  // always
27  template <typename x>
28  struct always {
29  using type = always;
30 
31  template <typename ...>
32  using apply = x;
33  };
34 
36  // apply
38  template <typename f, typename ...x>
39  struct apply
40  : f::type::template apply<x...>
41  { };
42 
44  // flip
46  template <typename f>
47  struct flip {
48  using type = flip;
49 
50 #if defined(BOOST_MPL11_CLANG_FLIP_BUG)
51  template <typename x0, typename x1, typename ...xs>
52  struct apply : f::type::template apply<x1, x0, xs...> {};
53 #else
54  template <typename x0, typename x1, typename ...xs>
55  using apply = typename f::type::template apply<x1, x0, xs...>;
56 #endif
57  };
58 
60  // partial
62  template <typename f, typename ...x>
63  struct partial {
64  using type = partial;
65 
66  template <typename ...y>
67  using apply = typename f::type::template apply<x..., y...>;
68  };
69 
70  template <template <typename ...> class f, typename ...x>
71  struct partial<lift<f>, x...> {
72  using type = partial;
73 
74 #if defined(BOOST_MPL11_GCC_PACK_EXPANSION_BUG)
75  template <typename ...y>
76  struct apply : f<x..., y...> { };
77 #else
78  template <typename ...y>
79  using apply = f<x..., y...>;
80 #endif
81  };
82 
83  template <template <typename ...> class f, typename ...x>
84  struct partial<into<f>, x...> {
85  using type = partial;
86 
87  template <typename ...y>
88  struct apply {
89  using type = f<x..., y...>;
90  };
91  };
92 
94  // apply_curried
96  template <typename f, typename ...xs>
98  : detail::left_folds::variadic<apply, f, xs...>
99  { };
100 
102  // curry
104  template <detail::std_size_t n, typename f>
105  struct curry {
106 #if !defined(BOOST_MPL11_NO_ASSERTIONS)
107  static_assert(n > 0,
108  "Invalid usage of curry<n, f> with a zero-valued n.");
109 #endif
110 
111  using type = curry;
112 
113  template <typename x>
114  using apply = curry<n-1, partial<f, x>>;
115  };
116 
117  template <typename f>
118  struct curry<1, f> {
119  using type = curry;
120 
121  template <typename x>
122  using apply = typename f::type::template apply<x>;
123  };
124 
126  // uncurry
128  template <detail::std_size_t n, typename f>
129  struct uncurry {
130  using type = uncurry;
131 
132 #if defined(BOOST_MPL11_NO_ASSERTIONS)
133  template <typename ...xs>
134  using apply = apply_curried<f, xs...>;
135 #else
136  static_assert(n > 0,
137  "Invalid usage of uncurry<n, f> with a zero-valued n.");
138 
139  template <typename ...xs>
140  struct apply : apply_curried<f, xs...> {
141  static_assert(sizeof...(xs) <= n,
142  "Invalid usage of uncurry<n, f> with more than n arguments.");
143 
144  static_assert(sizeof...(xs) >= n,
145  "Invalid usage of uncurry<n, f> with less than n arguments.");
146  };
147 #endif
148  };
149 
150 
152  // lift
154  template <template <typename ...> class f>
155  struct lift {
156  using type = lift;
157 
158 #if defined(BOOST_MPL11_GCC_PACK_EXPANSION_BUG)
159  template <typename ...x>
160  struct apply : f<x...> { };
161 #else
162  template <typename ...x>
163  using apply = f<x...>;
164 #endif
165  };
166 
168  // into
170  template <template <typename ...> class tp>
171  struct into {
172  using type = into;
173 
174  template <typename ...x>
175  struct apply {
176  using type = tp<x...>;
177  };
178  };
179 
181  // fix
183  template <typename f>
184  struct fix
185  : partial<f, fix<f>>
186  { };
187 
189  // compose
191  namespace functional_detail {
192  template <bool has_zero_args>
193  struct compose_impl;
194 
195  template <>
196  struct compose_impl<true> {
197  template <typename f, typename g>
198  using apply = typename f::type::template apply<
199  typename g::type::template apply<>
200  >;
201  };
202 
203  template <>
204  struct compose_impl<false> {
205  template <typename f, typename g, typename x, typename ...xs>
206  using apply = typename f::type::template apply<
207  typename g::type::template apply<x>, xs...
208  >;
209  };
210  } // end namespace functional_detail
211 
212  template <typename f, typename ...fs>
213  struct compose {
214  using type = compose;
215 
216  template <typename ...xs>
217  using apply =
218  typename functional_detail::compose_impl<sizeof...(xs) == 0>::
219  template apply<f, compose<fs...>, xs...>;
220  };
221 
222  template <typename f>
223  struct compose<f> : f { };
224 
226  // argmap
228  template <typename f, typename g>
229  struct argmap {
230  using type = argmap;
231 
232  template <typename ...x>
233  using apply = typename f::type::template apply<
234  typename g::type::template apply<x>...
235  >;
236  };
237 
239  // on
241  template <typename f, typename ...fs>
242  struct on {
243  using type = on;
244 
245  template <typename ...x>
246  using apply = typename f::type::template apply<
247  typename fs::type::template apply<x>...
248  >;
249  };
250 
251  template <
252  template <typename ...> class f,
253  template <typename ...> class ...fs
254  >
255  struct on<lift<f>, lift<fs>...> {
256  using type = on;
257 
258  template <typename ...x>
259  using apply = f<fs<x>...>;
260  };
261 
263  // bind
265  template <typename f, typename ...fs>
266  struct bind {
267  using type = bind;
268 
269  template <typename ...x>
270  using apply = typename f::type::template apply<
271  typename fs::type::template apply<x...>...
272  >;
273  };
274 
275  template <
276  template <typename ...> class f,
277  template <typename ...> class ...fs
278  >
279  struct bind<lift<f>, lift<fs>...> {
280  using type = bind;
281 
282  template <typename ...x>
283  using apply = f<fs<x...>...>;
284  };
285 
286 
288  // arg
290  template <>
291  struct arg<0>;
292 
293  template <detail::std_size_t n>
294  struct arg {
295  using type = arg;
296 
297  template <typename ...an>
298  using apply = detail::at_index::best<n-1, an...>;
299  };
300 }} // end namespace boost::mpl11
301 
302 #endif // !BOOST_MPL11_FUNCTIONAL_HPP
Returns a specialization of the given template with the provided arguments.
Definition: functional.hpp:171
Forward declares the Functional module.
Returns a metafunction class computing the least fixed point of f.
Definition: functional.hpp:184
Returns a curried metafunction class.
Definition: functional.hpp:105
Lifts a metafunction.
Definition: functional.hpp:155
Invokes f with the result of invoking each fs... with the arguments.
Definition: functional.hpp:266
Manages configurable options of the library and defines utility macros.
Defines boost::mpl11::detail::std_size_t.
Invokes f with the result of invoking fs... on each corresponding argument.
Definition: functional.hpp:242
Returns a uncurried metafunction class.
Definition: functional.hpp:129
Returns the nth of its arguments.
Definition: functional.hpp:294
Returns a constant metafunction class returning x regardless of the arguments it is invoked with...
Definition: functional.hpp:28
Defines boost::mpl11::detail::left_folds::variadic.
Returns the composition of several metafunction classes.
Definition: functional.hpp:213
Returns a partially applied metafunction class.
Definition: functional.hpp:63
Recursive alias-based variadic left fold.
Definition: variadic_aliased.hpp:111
Returns a metafunction class invoking f with its two first arguments in reverse order.
Definition: functional.hpp:47
Invokes a metafunction class with the given arguments.
Definition: functional.hpp:39
Invokes f with the result of mapping g on each argument.
Definition: functional.hpp:229
Invokes a curried metafunction class with the given arguments.
Definition: functional.hpp:97
Defines boost::mpl11::detail::at_index::best.