MPL11
 All Classes Namespaces Files Typedefs Macros Groups Pages
list.hpp
Go to the documentation of this file.
1 
12 #ifndef BOOST_MPL11_LIST_HPP
13 #define BOOST_MPL11_LIST_HPP
14 
15 #include <boost/mpl11/fwd/list.hpp>
16 
17 #include <boost/mpl11/bool.hpp>
23 #include <boost/mpl11/functor.hpp>
24 #include <boost/mpl11/iterable.hpp>
25 
26 #include <boost/mpl11/core.hpp> //
27 #include <boost/mpl11/foldable.hpp> //
28 #include <boost/mpl11/functional.hpp> // required by fwd/list.hpp
29 #include <boost/mpl11/integer.hpp> //
30 #include <boost/mpl11/logical.hpp> //
31 
32 
33 namespace boost { namespace mpl11 {
34  template <typename ...xs>
35  struct list {
36  using type = list;
37  using mpl_datatype = List;
38  };
39 
40  template <typename x, typename xs>
41  struct cons {
42  using type = cons;
43  using mpl_datatype = List;
44  };
45 
46  template <>
47  struct Iterable<List> : instantiate<Iterable>::with<List> {
48  template <typename>
49  struct head_impl;
50 
51  template <typename x, typename xs>
52  struct head_impl<cons<x, xs>>
53  : x
54  { };
55 
56  template <typename x, typename ...xs>
57  struct head_impl<list<x, xs...>>
58  : x
59  { };
60 
61 
62  template <typename>
63  struct tail_impl;
64 
65  template <typename x, typename xs>
66  struct tail_impl<cons<x, xs>>
67  : xs
68  { };
69 
70  template <typename x, typename ...xs>
71  struct tail_impl<list<x, xs...>>
72  : list<xs...>
73  { };
74 
75 
76  template <typename n, typename self>
77  struct at_impl
78  : instantiate<mpl11::Iterable>::with<List>::at_impl<n, self>
79  { };
80 
81  template <typename n, typename ...xs>
82  struct at_impl<n, list<xs...>>
83  : detail::at_index::best<n::type::value, xs...>
84  { };
85 
86 
87  template <typename>
88  struct is_empty_impl : false_ { };
89  };
90 
91  template <>
92  struct Iterable<List>::is_empty_impl<list<>> : true_ { };
93 
94 
95  template <>
96  struct Functor<List> : instantiate<Functor>::with<List> {
97  template <typename f, typename xs>
98  struct fmap_impl;
99 
100  template <typename f, typename ...xs>
101  struct fmap_impl<f, list<xs...>> {
102  using type = list<typename f::type::template apply<xs>...>;
103  };
104 
105  template <typename f, typename x, typename xs>
106  struct fmap_impl<f, cons<x, xs>> {
107  using type = cons<
108  typename f::type::template apply<x>,
109  fmap<f, xs>
110  >;
111  };
112  };
113 
114  template <typename f, typename x>
115  struct iterate
116  : cons<x, iterate<f, typename f::type::template apply<x>>>
117  { };
118 
119  template <typename x>
120  struct repeat
121  : cons<x, repeat<x>>
122  { };
123 
124  namespace list_detail {
125  template <detail::std_size_t n, typename xs,
126  bool = n == 0 || is_empty<xs>::value>
127  struct take_impl
128  : list<>
129  { };
130 
131  template <detail::std_size_t n, typename xs>
132  struct take_impl<n, xs, false>
133  : cons<head<xs>, take_impl<n-1, tail<xs>>>
134  { };
135 
136  template <typename n, typename xs>
137  struct take_checks {
138  static_assert(n::type::value >= 0,
139  "Invalid usage of `take`: "
140  "The number of elements to take must be non-negative.");
141  };
142 
143  template <typename xs, typename from, typename to>
144  struct slice_checks {
145  private:
146  static constexpr auto start = from::type::value;
147  static constexpr auto stop = to::type::value;
148 
149  static_assert(start >= 0,
150  "Invalid usage of `slice`: The start index must be non-negative.");
151 
152  static_assert(start <= stop,
153  "Invalid usage of `slice`: "
154  "The start index must be less-than or equal to the stop index.");
155 
156  #if 0
157  using Length = if_c<sequence_traits<typename Iter::type>::is_finite,
158  length<Iter>,
159  Stop_
160  >;
161 
162  static_assert(Stop <= Length::value,
163  "Invalid usage of `slice`: "
164  "The stop index is out of the bounds of the iterable.");
165  #endif
166  };
167 
168  template <typename xs>
169  struct init_checks {
170  static_assert(!is_empty<xs>::value,
171  "Invalid usage of `init` on an empty list.");
172  };
173  } // end namespace list_detail
174 
175  template <typename n, typename xs>
176  struct take
177  : BOOST_MPL11_IF_ASSERTIONS(list_detail::take_checks<n, xs>,)
178  list_detail::take_impl<n::type::value, xs>
179  { };
180 
181  template <typename xs, typename from, typename to>
182  struct slice
183  : BOOST_MPL11_IF_ASSERTIONS(list_detail::slice_checks<xs, from, to>,)
184  take_c<to::type::value - from::type::value, drop<from, xs>>
185  { };
186 
187  template <typename xs>
188  struct init
189  : BOOST_MPL11_IF_ASSERTIONS(list_detail::init_checks<xs>,)
190  if_c<is_empty<tail<xs>>::value,
191  list<>,
192  cons<head<xs>, init<tail<xs>>>
193  >
194  { };
195 
196  namespace list_detail {
197  template <typename pred>
198  struct take_while_op {
199  using type = take_while_op;
200  template <typename x, typename xs>
201  using apply = if_c<
202  (bool)pred::type::template apply<x>::type::value,
203  cons<x, xs>,
204  list<>
205  >;
206  };
207 
208  template <typename pred>
209  struct filter_op {
210  using type = filter_op;
211  template <typename x, typename xs>
212  using apply = if_c<
213  (bool)pred::type::template apply<x>::type::value,
214  cons<x, xs>,
215  xs
216  >;
217  };
218  }
219 
220  template <typename f, typename state, typename xs>
221  struct scanl
222  : if_c<is_empty<xs>::value,
223  list<state>,
224  cons<
225  state,
226  scanl<f, apply<f, state, head<xs>>, tail<xs>>
227  >
228  >
229  { };
230 
231  template <typename f>
232  struct zip_with<f>
233  : list<>
234  { };
235 
236  template <typename f, typename xs>
237  struct zip_with<f, xs>
238  : fmap<f, xs>
239  { };
240 
241  template <typename f, typename ...lists>
242  struct zip_with
243  : if_<or_<is_empty<lists>...>,
244  list<>,
245  cons<
246  typename f::type::template apply<head<lists>...>,
247  zip_with<f, tail<lists>...>
248  >
249  >
250  { };
251 
252  template <typename ...xs>
253  struct concat
254  : foldr<lift<concat>, list<>, list<xs...>>
255  { };
256 
257  template <typename xs, typename ys>
258  struct concat<xs, ys>
259  : foldr<lift<cons>, ys, xs>
260  { };
261 
262  namespace list_detail {
263  template <
264  typename pred,
265  typename xs,
266  typename pivot = head<xs>,
267  typename rest = tail<xs>,
268  typename IsGreater = partial<pred, pivot>,
269  typename IsSmallerEq = compose<lift<not_>, IsGreater>,
270  typename SmallerEq = filter<IsSmallerEq, rest>,
271  typename Greater = filter<IsGreater, rest>
272  >
273  using sort_by_impl = concat<
274  sort_by<pred, SmallerEq>,
275  cons<pivot, sort_by<pred, Greater>>
276  >;
277  }
278 
279  template <typename pred, typename xs>
280  struct sort_by
281  : if_c<or_<is_empty<xs>, is_empty<tail<xs>>>::value,
282  xs,
283  list_detail::sort_by_impl<pred, xs>
284  >
285  { };
286 
287 #ifndef BOOST_MPL11_NO_REWRITE_RULES
288  template <typename f, typename state, typename ...xs>
289  struct foldl<f, state, list<xs...>>
290  : detail::left_folds::variadic<
291  f::type::template apply, state, xs...
292  >
293  { };
294 
295  template <typename f, typename state, typename ...xs>
296  struct foldr<f, state, list<xs...>>
297  : detail::right_folds::variadic<
298  f::type::template apply, state, xs...
299  >
300  { };
301 
302  // length/foldr
303  //
304  // length $ foldr (:) xs ys == length xs + length ys
305  template <typename ...xs, typename ys>
306  struct length<foldr<lift<cons>, list<xs...>, ys>>
307  : size_t<length<ys>::value + sizeof...(xs)>
308  { };
309 
310  // at/repeat
311  template <typename index, typename x>
312  struct at<index, repeat<x>> : x { };
313 #endif // end rewrite rules
314 }} // end namespace boost::mpl11
315 
316 #endif // !BOOST_MPL11_LIST_HPP
Defines the Integer datatype.
Defines the Iterable typeclass.
Manages configurable options of the library and defines utility macros.
Defines boost::mpl11::detail::std_size_t.
Defines boost::mpl11::detail::right_folds::variadic.
Defines the fmap method of the Functor typeclass.
Defines the Logical module.
Defines the Core module.
Defines boost::mpl11::detail::left_folds::variadic.
#define BOOST_MPL11_IF_ASSERTIONS(...)
Macro expanding to its argument(s) if BOOST_MPL11_NO_ASSERTIONS is not defined, and to nothing otherw...
Definition: config.hpp:72
Invokes a metafunction class with the given arguments.
Definition: functional.hpp:39
Forward declares the boost::mpl11::List datatype.
Forwards to boost/mpl11/integer.hpp.
Defines the methods of the Foldable typeclass.
Defines the Functional module.
Defines boost::mpl11::detail::at_index::best.