MPL11
 All Classes Namespaces Files Typedefs Macros Groups Pages
iterable.hpp
Go to the documentation of this file.
1 
12 #ifndef BOOST_MPL11_ITERABLE_HPP
13 #define BOOST_MPL11_ITERABLE_HPP
14 
16 
17 #include <boost/mpl11/bool.hpp>
19 #include <boost/mpl11/core.hpp>
24 #include <boost/mpl11/foldable.hpp>
25 #include <boost/mpl11/functional.hpp> //
26 #include <boost/mpl11/integer.hpp> // required by fwd/iterable.hpp
27 #include <boost/mpl11/logical.hpp> //
29 
30 
31 namespace boost { namespace mpl11 {
32 namespace iterable_detail {
33  template <detail::std_size_t n, typename iter,
34  bool = n == 0 || is_empty<iter>::value>
35  struct drop_impl;
36 
37  template <detail::std_size_t n, typename iter>
38  struct drop_impl<n, iter, true> : iter { };
39 
40  template <detail::std_size_t n, typename iter>
41  struct drop_impl<n, iter, false>
42  : drop_impl<n-1, tail<iter>>
43  { };
44 
45  template <typename iter>
46  struct head_checks {
47  static_assert(!is_empty<iter>::value,
48  "Invalid usage of `head` on an empty iterable.");
49  };
50 
51  template <typename iter>
52  struct tail_checks {
53  static_assert(!is_empty<iter>::value,
54  "Invalid usage of `tail` on an empty iterable.");
55  };
56 
57  template <typename iter>
58  struct last_checks {
59  static_assert(!is_empty<iter>::value,
60  "Invalid usage of `last` on an empty iterable.");
61  };
62 
63  template <typename index, typename iter>
64  struct at_checks {
65  static_assert(index::type::value >= 0,
66  "Invalid usage of `at` with a negative index.");
67 
68 #if 0
69  using Length = if_c<sequence_traits<typename Iter::type>::is_finite,
70  length<Iter>,
71  size_t<index::type::value + 1>
72  >;
73 
74  static_assert(index::type::value < Length::value,
75  "Invalid usage of `at` with an out-of-bounds index.");
76 #endif
77  };
78 
79  template <typename n, typename iter>
80  struct drop_checks {
81  static_assert(n::type::value >= 0,
82  "Invalid usage of `drop`: "
83  "The number of elements to drop must be non-negative.");
84  };
85 
86  template <typename p>
87  struct drop_while_pred {
88  using type = drop_while_pred;
89  template <typename xs>
90  using apply = or_<
91  is_empty<xs>,
92  not_<typename p::type::template apply<head<xs>>>
93  >;
94  };
95 } // end namespace iterable_detail
96 
97 template <typename pred, typename iterable>
98 struct drop_while
99  : detail::left_folds::until<
100  iterable_detail::drop_while_pred<pred>::type::template apply
101  , bind<lift<tail>, arg<1>>::type::template apply
102  , iterable
103  , iterable
104  >
105 { };
106 
107 template <typename iter>
108 struct head :
109  BOOST_MPL11_IF_ASSERTIONS(iterable_detail::head_checks<iter>,)
110  Iterable<typename datatype<typename iter::type>::type>::
111  template head_impl<typename iter::type>
112 { };
113 
114 template <typename iter>
115 struct tail :
116  BOOST_MPL11_IF_ASSERTIONS(iterable_detail::tail_checks<iter>,)
117  Iterable<typename datatype<typename iter::type>::type>::
118  template tail_impl<typename iter::type>
119 { };
120 
121 template <typename iter>
122 struct last :
123  BOOST_MPL11_IF_ASSERTIONS(iterable_detail::last_checks<iter>,)
124  Iterable<typename datatype<typename iter::type>::type>::
125  template last_impl<typename iter::type>
126 { };
127 
128 template <typename index, typename iter>
129 struct at :
130  BOOST_MPL11_IF_ASSERTIONS(iterable_detail::at_checks<index, iter>,)
131  Iterable<typename datatype<typename iter::type>::type>::
132  template at_impl<index, typename iter::type>
133 { };
134 
135 template <typename n, typename iter>
136 struct drop :
137  BOOST_MPL11_IF_ASSERTIONS(iterable_detail::drop_checks<n, iter>,)
138  iterable_detail::drop_impl<n::type::value, iter>
139 { };
140 
141 template <typename iter>
142 struct is_empty :
143  Iterable<typename datatype<typename iter::type>::type>::
144  template is_empty_impl<typename iter::type>
145 { };
146 
147 template <typename iter>
148 struct length :
149  Iterable<typename datatype<typename iter::type>::type>::
150  template length_impl<typename iter::type>
151 { };
152 
153 template <typename Datatype, typename>
154 struct Iterable : false_ { };
155 
156 namespace iterable_detail {
158  struct plus_one {
159  using type = plus_one;
160  template <typename x, typename _>
161  using apply = succ<x>;
162  };
163 }
164 
165 template <>
166 struct instantiate<Iterable> {
167  template <typename Datatype>
168  struct with : true_ {
169  template <typename xs>
170  using last_impl = foldl<arg<2>, undefined, box<xs>>;
171 
172  template <typename index, typename xs, bool = index::type::value == 0>
173  struct at_impl
174  : head<box<xs>>
175  { };
176 
177  template <typename index, typename xs>
178  struct at_impl<index, xs, false>
179  : at_impl<
180  size_t<index::type::value - 1>,
181  typename tail<box<xs>>::type
182  >
183  { };
184 
185  template <typename xs>
186  using length_impl = foldl<iterable_detail::plus_one, int_<0>, box<xs>>;
187  };
188 };
189 
190 template <typename X, typename Y>
191 struct Orderable<X, Y, bool_<Iterable<X>::value && Iterable<Y>::value>>
192  : instantiate<Orderable>::template with<X, Y>
193 {
194  // xs is shorter than ys
195  template <typename xs, typename ys,
196  bool xs_done = is_empty<box<xs>>::value,
197  bool ys_done = is_empty<box<ys>>::value
198  >
199  struct less_impl
200  : bool_<xs_done && !ys_done>
201  { };
202 
203  // (head(xs) < head(ys)) or (head(xs) == head(ys) and compare the rest)
204  template <typename xs, typename ys>
205  struct less_impl<xs, ys, false, false>
206  : or_<
207  less<head<box<xs>>, head<box<ys>>>,
208  and_<
209  not_<less<head<box<ys>>, head<box<xs>>>>,
210  less_impl<
211  typename tail<box<xs>>::type,
212  typename tail<box<ys>>::type
213  >
214  >
215  >
216  { };
217 };
218 
219 template <typename X, typename Y>
220 struct Comparable<X, Y, bool_<Iterable<X>::value && Iterable<Y>::value>>
221  : instantiate<Comparable>::template with<X, Y>
222 {
223  template <typename xs, typename ys,
224  bool xs_done = is_empty<box<xs>>::value,
225  bool ys_done = is_empty<box<ys>>::value>
226  struct equal_impl
227  : bool_<xs_done && ys_done>
228  { };
229 
230  template <typename xs, typename ys>
231  struct equal_impl<xs, ys, false, false>
232  : and_<
233  equal<head<box<xs>>, head<box<ys>>>,
234  equal_impl<
235  typename tail<box<xs>>::type,
236  typename tail<box<ys>>::type
237  >
238  >
239  { };
240 };
241 
242 template <typename Datatype>
243 struct Foldable<Datatype, typename Iterable<Datatype>::type>
244  : instantiate<Foldable>::template with<Datatype>
245 {
246  template <typename f, typename state, typename iterable>
247  using foldl_impl = detail::left_folds::until<
248  is_empty, f::type::template apply, state, box<iterable>
249  >;
250 
251  template <typename f, typename iterable>
252  using foldl1_impl = detail::left_folds::until<
253  is_empty,
254  f::type::template apply,
255  head<box<iterable>>,
256  tail<box<iterable>>
257  >;
258 
259  template <typename f, typename state, typename iterable>
260  using foldr_impl = detail::right_folds::until<
261  is_empty, f::type::template apply, state, box<iterable>
262  >;
263 };
264 }} // end namespace boost::mpl11
265 
266 #endif // !BOOST_MPL11_ITERABLE_HPP
Boxes its argument.
Definition: core.hpp:46
Defines the Integer datatype.
Holds default methods of typeclasses.
Definition: core.hpp:37
Defines the Comparable typeclass.
Defines boost::mpl11::detail::left_folds::until.
Manages configurable options of the library and defines utility macros.
Defines boost::mpl11::detail::std_size_t.
Defines the Logical module.
Definition: iterable.hpp:158
Forward declares the Iterable typeclass.
Represents the bottom value of most functional programming languages.
Definition: core.hpp:87
Defines the Core module.
#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
Returns the first element of a non-empty iterable.
Definition: iterable.hpp:72
Defines boost::mpl11::detail::right_folds::until.
Invokes a metafunction class with the given arguments.
Definition: functional.hpp:39
Defines the Orderable typeclass.
Alias to bool_; provided for convenience.
Definition: integer.hpp:79
Left-associative fold of a structure using a binary operation.
Definition: foldable.hpp:62
Forwards to boost/mpl11/integer.hpp.
Defines the methods of the Foldable typeclass.
Returns the successor of the given object.
Definition: enumerable.hpp:22
Defines the Functional module.