8
8
#ifndef INCLUDE_GUARD_LINQ_H
9
9
#define INCLUDE_GUARD_LINQ_H
10
10
11
- #include < utility>
12
- #include < boost/optional.hpp>
13
- #include < boost/preprocessor.hpp>
14
- #include < boost/preprocessor/facilities/is_empty.hpp>
15
- #include < boost/range.hpp>
16
- #include < boost/range/adaptor/filtered.hpp>
17
- #include < boost/range/adaptor/transformed.hpp>
18
- #include < boost/unordered_map.hpp>
19
- #include < boost/unordered_set.hpp>
20
- #include < numeric>
21
-
22
- //
23
- //
24
- // Some preprocessor utilites
25
- //
26
- //
27
-
28
- //
29
- // LINQ_RETURNS for auto return type deduction.
30
- //
31
- #define LINQ_RETURNS (...) -> decltype (__VA_ARGS__) { return (__VA_ARGS__); } static_assert(true , " " )
32
-
33
-
34
- #define LINQ_ERROR_RETURN_REQUIRES_NEEDS_AN_EXPRESSION (...) decltype(__VA_ARGS__)>::type { return __VA_ARGS__; }
35
- #define LINQ_RETURN_REQUIRES (...) -> typename boost::enable_if<__VA_ARGS__, LINQ_ERROR_RETURN_REQUIRES_NEEDS_AN_EXPRESSION
36
-
37
- //
38
- // LINQ_IS_PAREN is used to detect if the first token is a parenthesis.
39
- // It expands to 1 if it is, otherwise it expands to 0.
40
- //
41
- #define LINQ_IS_PAREN (x ) LINQ_IS_PAREN_CHECK(LINQ_IS_PAREN_PROBE x)
42
- #define LINQ_IS_PAREN_CHECK (...) LINQ_IS_PAREN_CHECK_N(__VA_ARGS__,0 )
43
- #define LINQ_IS_PAREN_PROBE (...) ~, 1 ,
44
- #ifndef _MSC_VER
45
- #define LINQ_IS_PAREN_CHECK_N (x, n, ...) n
46
- #else
47
- // MSVC workarounds
48
- #define LINQ_IS_PAREN_CHECK_RES (x ) x
49
- #define LINQ_IS_PAREN_CHECK_II (x, n, ...) n
50
- #define LINQ_IS_PAREN_CHECK_I (x ) LINQ_IS_PAREN_CHECK_RES(LINQ_IS_PAREN_CHECK_II x)
51
- #define LINQ_IS_PAREN_CHECK_N (...) LINQ_IS_PAREN_CHECK_I((__VA_ARGS__))
52
- #endif
53
-
54
- //
55
- // LINQ_IS_EMPTY will expands to 1 if the parameter is empty, otherwise
56
- // it expands to 0. This will work even if the parameter given is a set
57
- // of parenthesis.
58
- //
59
- #define LINQ_IS_EMPTY (x ) BOOST_PP_CAT(LINQ_IS_EMPTY_, LINQ_IS_PAREN(x))(x)
60
- #define LINQ_IS_EMPTY_0 (x ) BOOST_PP_IS_EMPTY(x)
61
- #define LINQ_IS_EMPTY_1 (x ) 0
62
-
63
- //
64
- // LINQ_HEAD retrieves the first element of a sequence.
65
- // Example:
66
- //
67
- // LINQ_HEAD((1)(2)(3)) // Expands to (1)
68
- //
69
- #define LINQ_HEAD (x ) LINQ_PICK_HEAD(LINQ_MARK x)
70
- #define LINQ_MARK (...) (__VA_ARGS__),
71
- #define LINQ_PICK_HEAD (...) LINQ_PICK_HEAD_I(__VA_ARGS__,)
72
- #ifndef _MSC_VER
73
- #define LINQ_PICK_HEAD_I (x, ...) x
74
- #else
75
- // MSVC workarounds
76
- #define LINQ_PICK_HEAD_III (x, ...) x
77
- #define LINQ_PICK_HEAD_II (x ) LINQ_PICK_HEAD_III x
78
- #define LINQ_PICK_HEAD_I (...) LINQ_PICK_HEAD_II((__VA_ARGS__))
79
- #endif
80
-
81
-
82
- //
83
- // LINQ_TAIL retrieves the tail of a sequence.
84
- // Example:
85
- //
86
- // LINQ_TAIL((1)(2)(3)) // Expands to (2)(3)
87
- //
88
- #define LINQ_TAIL (x ) LINQ_EAT x
89
- // Various utilities
90
- #define LINQ_EMPTY (...)
91
- #define LINQ_EAT (...)
92
- #define LINQ_REM (...) __VA_ARGS__
93
- #define LINQ_EXPAND (...) __VA_ARGS__
94
- #define LINQ_DEFER (...) __VA_ARGS__ LINQ_EMPTY ()
95
- #define LINQ_OBSTRUCT (...) __VA_ARGS__ LINQ_DEFER (LINQ_EMPTY)()
96
-
97
- #define LINQ_EVAL (...) LINQ_EVAL_A(LINQ_EVAL_A(LINQ_EVAL_A(__VA_ARGS__)))
98
- #define LINQ_EVAL_A (...) LINQ_EVAL_B(LINQ_EVAL_B(LINQ_EVAL_B(__VA_ARGS__)))
99
- #define LINQ_EVAL_B (...) LINQ_EVAL_C(LINQ_EVAL_C(LINQ_EVAL_C(__VA_ARGS__)))
100
- #define LINQ_EVAL_C (...) LINQ_EVAL_D(LINQ_EVAL_D(LINQ_EVAL_D(__VA_ARGS__)))
101
- #define LINQ_EVAL_D (...) LINQ_EVAL_E(LINQ_EVAL_E(LINQ_EVAL_E(__VA_ARGS__)))
102
- #define LINQ_EVAL_E (...) __VA_ARGS__
103
-
104
- //
105
- // LINQ_BACK gets the last element of a sequence
106
- //
107
- #define LINQ_BACK (seq ) BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), seq)
108
-
109
- //
110
- // LINQ_KEYWORD transforms the keyword. Keywords are generally defined
111
- // like this:
112
- //
113
- // //This defines a `my_keyword` macro
114
- // //NOTE: The space between the keyword and parenthesis is necessary
115
- // #define LINQ_KEYWORD_my_keyword (MY_KEYWORD_MACRO)
116
- //
117
- // Here is an example:
118
- //
119
- // LINQ_KEYWORD(my_keyword foo) // Expands to (MY_KEYWORD_MACRO) foo
120
- //
121
- #define LINQ_KEYWORD (x ) BOOST_PP_CAT(LINQ_KEYWORD_, x)
122
-
123
- //
124
- // LINQ_IS_KEYWORD will expand to 1 if the first token is a valid keyword
125
- //
126
- #define LINQ_IS_KEYWORD (x ) LINQ_IS_PAREN(LINQ_KEYWORD(x))
127
-
128
- //
129
- // LINQ_PLACE retrieves whats placed in parenthesis. In essence it does
130
- // this:
131
- //
132
- // LINQ_PLACE((1) foo) //Expands to 1
133
- //
134
- // But when its used in the contexts of keywords, it will retrieve whats
135
- // been defined inside the parenthesis of a keyword. Heres an example:
136
- //
137
- // //This defines a `my_keyword` macro
138
- // //NOTE: The space between the keyword and parenthesis is necessary
139
- // #define LINQ_KEYWORD_my_keyword (MY_KEYWORD_MACRO)
140
- // LINQ_PLACE(LINQ_KEYWORD(my_keyword foo)) // Expands to MY_KEYWORD_MACRO
141
- //
142
- #define LINQ_PLACE (x ) LINQ_EXPAND(LINQ_REM LINQ_PICK_HEAD (LINQ_MARK x))
143
-
144
- //
145
- // LINQ_TO_SEQ converts the keywords into a preprocessor sequence
146
- //
147
- #define LINQ_TO_SEQ (x ) LINQ_TO_SEQ_WHILE_M \
148
- ( \
149
- BOOST_PP_WHILE (LINQ_TO_SEQ_WHILE_P, LINQ_TO_SEQ_WHILE_O, (,x)) \
150
- )
151
-
152
- #define LINQ_TO_SEQ_WHILE_P (r, state ) LINQ_TO_SEQ_P state
153
- #define LINQ_TO_SEQ_WHILE_O (r, state ) LINQ_TO_SEQ_O state
154
- #define LINQ_TO_SEQ_WHILE_M (state ) LINQ_TO_SEQ_M state
155
-
156
- #define LINQ_TO_SEQ_P (prev, tail ) BOOST_PP_NOT(LINQ_IS_EMPTY(tail))
157
- #define LINQ_TO_SEQ_O (prev, tail ) \
158
- BOOST_PP_IF (LINQ_IS_PAREN(tail), \
159
- LINQ_TO_SEQ_PAREN, \
160
- LINQ_TO_SEQ_KEYWORD \
161
- )(prev, tail)
162
- #define LINQ_TO_SEQ_PAREN (prev, tail ) \
163
- (prev (LINQ_HEAD(tail)), LINQ_TAIL(tail))
164
-
165
- #define LINQ_TO_SEQ_KEYWORD (prev, tail ) \
166
- LINQ_TO_SEQ_REPLACE (prev, LINQ_KEYWORD(tail))
167
-
168
- #define LINQ_TO_SEQ_REPLACE (prev, tail ) \
169
- (prev LINQ_HEAD (tail), LINQ_TAIL(tail))
170
-
171
- #define LINQ_TO_SEQ_M (prev, tail ) prev
172
-
173
-
174
- //
175
- // LINQ_SEQ_TO_STRING convert a sequence back to a string of tokens
176
- //
177
- #define LINQ_SEQ_TO_STRING (seq ) BOOST_PP_SEQ_FOR_EACH(LINQ_SEQ_TO_STRING_EACH, ~, seq)
178
- #define LINQ_SEQ_TO_STRING_EACH (r, data, x ) x
179
-
180
- //
181
- // LINQ_SEQ_SPLIT
182
- //
183
- #define LINQ_SEQ_SPLIT (seq, pred, data ) LINQ_SEQ_SPLIT_FOLD_LEFT_M(BOOST_PP_SEQ_FOLD_LEFT(LINQ_SEQ_SPLIT_FOLD_LEFT_O, (pred, data,,), seq))
184
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_O (s, state, x ) LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE((s, x, LINQ_REM state))
185
- #ifndef _MSC_VER
186
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE (x ) LINQ_SEQ_SPLIT_OP x
187
- #else
188
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE (x ) LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE_I x
189
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE_I (...) LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE_II((__VA_ARGS__))
190
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_INVOKE_II (x ) LINQ_SEQ_SPLIT_OP x
191
- #endif
192
- #define LINQ_SEQ_SPLIT_OP (s, x, pred, data, seq, elem ) BOOST_PP_IF(pred(s, data, x), LINQ_SEQ_SPLIT_OP_TRUE, LINQ_SEQ_SPLIT_OP_FALSE)(x, pred, data, seq, elem)
193
- #define LINQ_SEQ_SPLIT_OP_TRUE (x, pred, data, seq, elem ) BOOST_PP_IIF(LINQ_IS_PAREN(elem), \
194
- (pred, data, seq(elem),),\
195
- (pred, data, seq,) )
196
- #define LINQ_SEQ_SPLIT_OP_FALSE (x, pred, data, seq, elem ) (pred, data, seq, elem (x))
197
- #ifndef _MSC_VER
198
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_M (x ) LINQ_SEQ_SPLIT_M x
199
- #else
200
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_M_X (x ) x
201
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_M_N (x ) LINQ_SEQ_SPLIT_FOLD_LEFT_M_X(LINQ_SEQ_SPLIT_FOLD_LEFT_M_X(LINQ_SEQ_SPLIT_FOLD_LEFT_M_X(LINQ_SEQ_SPLIT_FOLD_LEFT_M_X(x))))
202
- #define LINQ_SEQ_SPLIT_FOLD_LEFT_M (x ) LINQ_SEQ_SPLIT_FOLD_LEFT_M_N(LINQ_SEQ_SPLIT_M x)
203
- #endif
204
- #define LINQ_SEQ_SPLIT_M (pred, data, seq, elem ) seq BOOST_PP_IIF (LINQ_IS_PAREN(elem), (elem),)
205
-
206
- //
207
- // LINQ_SEQ_NEST
208
- //
209
- #define LINQ_SEQ_NEST (seq ) BOOST_PP_SEQ_FOLD_LEFT(LINQ_SEQ_NEST_OP, LINQ_BACK(seq) , BOOST_PP_SEQ_POP_BACK(seq))
210
- #define LINQ_SEQ_NEST_OP (s, state, x ) x(state)
211
-
212
- //
213
- // LINQ_SEQ_NEST_REVERSE
214
- //
215
- #define LINQ_SEQ_NEST_REVERSE (seq ) BOOST_PP_SEQ_FOLD_RIGHT(LINQ_SEQ_NEST_OP, LINQ_BACK(seq) , BOOST_PP_SEQ_POP_BACK(seq))
216
-
217
- //
218
- // LINQ_VARN_CAT
219
- //
220
- #define LINQ_VARN_CAT (n, tuple ) LINQ_EVAL(LINQ_VARN_CAT_D(n, tuple))
221
- #define LINQ_VARN_CAT_D (n, tuple ) LINQ_VARN_INVOKE((n, LINQ_REM tuple, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT, BOOST_PP_INTERCEPT))
222
- #define LINQ_VARN_CAT_ID () LINQ_VARN_CAT_D
223
-
224
- #ifndef _MSC_VER
225
- #define LINQ_VARN_INVOKE (data ) LINQ_VARN_PRIMITIVE_CAT data
226
- #else
227
- // MSVC Workarounds
228
- #define LINQ_VARN_INVOKE (data ) LINQ_VARN_INVOKE_I(data)
229
- #define LINQ_VARN_INVOKE_I (data ) LINQ_VARN_PRIMITIVE_CAT data
230
- #endif
231
- #define LINQ_VARN_PRIMITIVE_CAT (n, a, b, c, d, e, f, g, h, ...) LINQ_VARN_CAT_E(a, n) LINQ_VARN_CAT_E(b, n) LINQ_VARN_CAT_E(c, n) LINQ_VARN_CAT_E(d, n) LINQ_VARN_CAT_E(e, n) LINQ_VARN_CAT_E(f, n) LINQ_VARN_CAT_E(g, n) LINQ_VARN_CAT_E(h, n)
232
-
233
- #define LINQ_VARN_CAT_E (a, n ) BOOST_PP_IF(LINQ_IS_PAREN(a), LINQ_VARN_CAT_EACH_PAREN, LINQ_VARN_CAT_EACH_TOKEN)(a, n)
234
- #define LINQ_VARN_CAT_EACH_PAREN (a, n ) (LINQ_OBSTRUCT(LINQ_VARN_CAT_ID)()(n, a))
235
- #define LINQ_VARN_CAT_EACH_TOKEN (a, n ) a ## n
236
-
237
- //
238
- // LINQ_PARAMS
239
- //
240
- #define LINQ_PARAMS (n, ...) BOOST_PP_ENUM(n, LINQ_PARAMS_EACH, (__VA_ARGS__))
241
- #define LINQ_PARAMS_Z (z, n, ...) BOOST_PP_ENUM_ ## z(n, LINQ_PARAMS_EACH, (__VA_ARGS__))
242
- #define LINQ_PARAMS_EACH (z, n, data ) LINQ_VARN_CAT(n, data)
243
-
244
- //
245
- // LINQ_GEN
246
- //
247
- #define LINQ_GEN (n, ...) BOOST_PP_REPEAT(n, LINQ_GEN_EACH, (__VA_ARGS__))
248
- #define LINQ_GEN_Z (z, n, ...) BOOST_PP_REPEAT_ ## z(n, LINQ_GEN_EACH, (__VA_ARGS__))
249
- #define LINQ_GEN_EACH (z, n, data ) LINQ_VARN_CAT(n, data)
250
-
251
-
252
- //
253
- // LINQ_FORWARD_PARAMS
254
- //
255
- #define LINQ_FORWARD_PARAMS (n, type, var ) BOOST_PP_ENUM(n, LINQ_FORWARD_PARAMS_EACH, (type, var))
256
- #define LINQ_FORWARD_PARAMS_Z (z, n, type, var ) BOOST_PP_ENUM_ ## z(n, LINQ_FORWARD_PARAMS_EACH, (type, var))
257
- #define LINQ_FORWARD_PARAMS_EACH (z, n, data ) std::forward<BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2 , 0 , data),n)>(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2 , 1 , data),n))
258
-
259
-
260
- //
261
- //
262
- // Extensions
263
- //
264
- //
265
-
266
- namespace linq {
267
-
268
- // MSVC 2010 doesn't provide declval
269
- // We also return T&& instead std::add_rvalue_reference<T>
270
- // because MSVC has a buggy implementation of it.
271
- // So, this function will work in all cases except when T
272
- // is void(which should rarely happen).
273
- template <typename T>
274
- T&& declval(); // no definition required
275
-
276
- //
277
- // is_iterator type trait
278
- //
279
- namespace detail {
280
- BOOST_MPL_HAS_XXX_TRAIT_DEF (iterator_category)
281
- }
282
-
283
- template <class T , class Enabler = void >
284
- struct is_iterator
285
- : boost::mpl::false_
286
- {};
287
- template <class T >
288
- struct is_iterator <T, BOOST_DEDUCED_TYPENAME boost::enable_if<detail::has_iterator_category<T> >::type >
289
- : boost::mpl::true_
290
- {};
291
- template <class T >
292
- struct is_iterator <T, BOOST_DEDUCED_TYPENAME boost::enable_if<boost::is_pointer<T> >::type >
293
- : boost::mpl::true_
294
- {};
295
-
296
- //
297
- // is_range type trait
298
- //
299
- template <class T >
300
- struct is_range : boost::mpl::eval_if< boost::is_const<T>,
301
- boost::has_range_const_iterator<BOOST_DEDUCED_TYPENAME boost::remove_const<T>::type>,
302
- boost::mpl::and_<boost::has_range_iterator<T>, boost::has_range_const_iterator<T> >
303
- >::type
304
- {};
305
- template <class T , class U >
306
- struct is_range <std::pair<T, U> > : boost::mpl::and_<is_iterator<T>, is_iterator<U>, boost::is_same<T, U> >::type
307
- {};
308
-
309
- //
310
- // Range extension
311
- //
312
- #ifndef LINQ_LIMIT_EXTENSION
313
- #define LINQ_LIMIT_EXTENSION 4
314
- #endif
315
- namespace detail {
316
- struct na {};
317
-
318
- template <class F , BOOST_PP_ENUM_BINARY_PARAMS_Z(1 , LINQ_LIMIT_EXTENSION, class T , = na BOOST_PP_INTERCEPT) >
319
- struct pipe_closure {};
320
-
321
- #define LINQ_PIPE_CLOSURE_MEMBERS_OP (z, n, data ) T ## n x ## n;
322
- #define LINQ_PIPE_CLOSURE_CONSTRUCTOR_OP (z, n, data ) x ## n(std::forward<X ## n>(x ## n))
323
- #define LINQ_PIPE_CLOSURE (z, n, data ) \
324
- template <class F , BOOST_PP_ENUM_PARAMS_Z(z, n, T), BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_SUB(LINQ_LIMIT_EXTENSION,n), na BOOST_PP_INTERCEPT)> \
325
- struct pipe_closure \
326
- { \
327
- BOOST_PP_REPEAT_ ## z(n, LINQ_PIPE_CLOSURE_MEMBERS_OP, ~) \
328
- template <LINQ_PARAMS(n, class X )>\
329
- pipe_closure (LINQ_PARAMS(n, X, && BOOST_PP_INTERCEPT, x)) \
330
- : BOOST_PP_ENUM_ ## z(n, LINQ_PIPE_CLOSURE_CONSTRUCTOR_OP, ~) \
331
- {} \
332
- \
333
- template <class Range > \
334
- friend auto operator |(Range && r, pipe_closure p) LINQ_RETURN_REQUIRES(is_range<Range>) \
335
- (F()(std::forward<Range>(r), LINQ_FORWARD_PARAMS(n, T, x) )) \
336
- \
337
- };
338
- BOOST_PP_REPEAT_FROM_TO_1 (1 , LINQ_LIMIT_EXTENSION, LINQ_PIPE_CLOSURE, ~)
339
- }
340
- #define LINQ_RANGE_EXTENSION_OP (z, n, data ) \
341
- template <LINQ_PARAMS(n, class T )> \
342
- auto operator ()(LINQ_PARAMS(n, T, && x) ) const LINQ_RETURNS \
343
- ( \
344
- detail::pipe_closure<F, BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, T, && BOOST_PP_INTERCEPT)> \
345
- (LINQ_FORWARD_PARAMS_Z(z, n, T, x) ) \
346
- );
347
-
348
- template <class F >
349
- struct range_extension
350
- {
351
- BOOST_PP_REPEAT_1 (LINQ_LIMIT_EXTENSION, LINQ_RANGE_EXTENSION_OP, ~)
352
- template <class Range >
353
- friend auto operator |(Range && r, range_extension) LINQ_RETURN_REQUIRES(is_range<Range>)
354
- (F()(std::forward<Range>(r)))
355
-
356
- range_extension<F>& operator ()
357
- {
358
- return *this ;
359
- }
360
-
361
- const range_extension<F>& operator () const
362
- {
363
- return *this ;
364
- }
365
- };
366
-
367
- #define LINQ_EXT (name )
368
-
369
- //
370
- // set_filter_iterator
371
- //
372
- namespace detail {
373
- // TODO: Add support for an equality selector
374
- template <class Predicate , class Iterator >
375
- struct set_filter_iterator
376
- : boost::iterator_adaptor<set_filter_iterator<Predicate, Iterator, Iterator, boost::use_default, boost::forward_traversal_tag>
377
- {
378
-
379
- // Probably should be the initial base class so it can be
380
- // optimized away via EBO if it is an empty class.
381
- Predicate predicate;
382
- Iterator last;
383
- typedef boost::unordered_set<typename boost::iterator_value<Iterator>::type> set_t ;
384
- set_t set;
385
-
386
- typedef boost::iterator_adaptor<set_filter_iterator<Predicate, Iterator, Iterator, boost::use_default, boost::forward_traversal_tag> super_t ;
387
-
388
- set_filter_iterator () { }
389
-
390
- template <class Range >
391
- set_filter_iterator (Range && r, Predicate f, Iterator x, Iterator l = Iterator ())
392
- : super_t (x), predicate (f), last (l), set (boost::begin (r), boost::end (r))
393
- {
394
- satisfy_predicate ();
395
- }
396
-
397
- set_filter_iterator (Predicate f, Iterator x, Iterator l = Iterator ())
398
- : super_t (x), predicate (f), last (l)
399
- {
400
- satisfy_predicate ();
401
- }
402
-
403
- set_filter_iterator (Iterator x, Iterator l = Iterator ())
404
- : super_t (x), predicate (), last (l)
405
- {
406
- satisfy_predicate ();
407
- }
408
-
409
- // template<class OtherIterator>
410
- // set_filter_iterator(
411
- // set_filter_iterator<Predicate, OtherIterator> const& t
412
- // , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
413
- // )
414
- // : super_t(t.base()), predicate(t.predicate()), last(t.end()) {}
415
-
416
- Predicate predicate () const { return predicate; }
417
-
418
- Iterator end () const { return last; }
419
-
420
- void increment ()
421
- {
422
- ++(this ->base_reference ());
423
- satisfy_predicate ();
424
- }
425
-
426
- void satisfy_predicate ()
427
- {
428
- while (this ->base () != this ->last && !this ->predicate (*this ->base (), this ->set ))
429
- {
430
- ++(this ->base_reference ());
431
- }
432
- }
433
- };
434
-
435
- template <class Iterator , class Predicate >
436
- auto make_set_filter_iterator (Iterator it, Predicate p) LINQ_RETURNS
437
- (set_filter_iterator<Predicate, Iterator>(p, it));
438
-
439
- template <class Iterator , class Predicate >
440
- auto make_set_filter_iterator (Iterator it, Iterator last, Predicate p) LINQ_RETURNS
441
- (set_filter_iterator<Predicate, Iterator>(p, it, last));
442
-
443
- template <class Range , class Iterator , class Predicate >
444
- auto make_set_filter_iterator (Range && r, Iterator it, Iterator last, Predicate p) LINQ_RETURNS
445
- (set_filter_iterator<Predicate, Iterator>(r, p, it, last));
446
-
447
- template <class Range , class Predicate >
448
- auto make_set_filter_range (Range && r, Predicate p) LINQ_RETURNS
449
- (boost::make_iterator_range
450
- (
451
- make_set_filter_iterator (boost::begin(r), boost::end(r), p),
452
- make_set_filter_iterator(boost::end(r), p)
453
- ));
454
-
455
- template <class Set , class Range , class Predicate >
456
- auto make_set_filter_range (Set && s, Range && r, Predicate p) LINQ_RETURNS
457
- (boost::make_iterator_range
458
- (
459
- make_set_filter_iterator (s, boost::begin(r), boost::end(r), p),
460
- make_set_filter_iterator(boost::end(r), p)
461
- ));
462
-
463
- }
464
-
465
- //
466
- // always predicate
467
- //
468
- namespace detail {
469
-
470
- struct always
471
- {
472
- template <class T >
473
- bool operator ()(T) { return true ; }
474
- };
475
- }
476
-
477
- //
478
- // or_default
479
- //
480
- namespace detail {
481
-
482
- template <class Iterator , class Value >
483
- auto or_default (Iterator it, Iterator last, Value && v) LINQ_RETURNS
484
- ((it != last) ? *it : std::forward<Value>(v));
485
- }
486
-
487
-
488
- //
489
- // find
490
- //
491
- namespace detail {
492
-
493
- // TODO: Add overload for string
494
- template <class Range , class T >
495
- auto find (Range && r, T && x) LINQ_RETURNS(std::find(boost::begin(r), boost::end(r), std::forward<T>(x)));
496
-
497
- struct find_t
498
- {
499
- template <class Range , class T >
500
- auto operator ()(Range && r, T && x)
501
- LINQ_RETURNS(find(std::forward<Range>(r), std::forward<T>(x)));
502
- };
503
- }
504
- namespace {
505
- range_extension<detail::find_t > find = {};
506
- }
507
-
508
- //
509
- // select
510
- //
511
- namespace detail {
512
- struct select_t
513
- {
514
- // TODO: make it work for empty and single ranges
515
-
516
- template <class F , class It >
517
- static auto make_transform_iterator (F f, It it) LINQ_RETURNS(boost::transform_iterator<F, It>(it, f));
518
-
519
- template <class Range , class Selector >
520
- auto operator ()(Range && r, Selector selector)
521
- LINQ_RETURNS(boost::make_iterator_range(make_transform_iterator(selector, boost::begin(r)), make_transform_iterator(selector, boost::end(r))) );
522
-
523
- };
524
- }
525
- namespace {
526
- range_extension<detail::select_t > select = {};
527
- }
528
-
529
-
530
- //
531
- // aggregate
532
- //
533
- namespace detail {
534
- struct aggregate_t
535
- {
536
- // TODO: make it work for empty and single ranges
537
- template <class Range , class Reducer >
538
- auto operator ()(Range && r, Reducer reducer) LINQ_RETURNS(std::accumulate(++boost::begin(r), boost::end(r), *boost::begin(r)));
539
-
540
- template <class Range , class Seed , class Reducer >
541
- auto operator ()(Range && r, Seed && s, Reducer reducer) LINQ_RETURNS(std::accumulate(boost::begin(r), boost::end(r), s, reducer));
542
-
543
- template <class Range , class Seed , class Reducer >
544
- auto operator ()(Range && r, Seed && s, Reducer reducer, Selector sel) LINQ_RETURNS(sel(std::accumulate(boost::begin(r), boost::end(r), s, reducer)));
545
- };
546
- }
547
- namespace {
548
- range_extension<detail::aggregate_t > aggregate = {};
549
- }
550
-
551
- //
552
- // all
553
- //
554
- namespace detail {
555
- struct all_t
556
- {
557
- template <class Range , class Pred >
558
- auto operator ()(Range && r, Pred p) LINQ_RETURNS(std::all_of(boost::begin(r), boost::end(r), pred));
559
- };
560
- }
561
- namespace {
562
- range_extension<detail::all_t > all = {};
563
- }
564
-
565
- //
566
- // any
567
- //
568
- namespace detail {
569
- struct any_t
570
- {
571
- template <class Range , class Pred >
572
- auto operator ()(Range && r) LINQ_RETURNS(!boost::empty(r))
573
-
574
- template<class Range, class Pred>
575
- auto operator()(Range && r, Pred p) LINQ_RETURNS(std::any_of(boost::begin(r), boost::end(r), pred));
576
- };
577
- }
578
- namespace {
579
- range_extension<detail::any_t > any = {};
580
- }
581
-
582
- //
583
- // average
584
- //
585
- // TODO
586
-
587
- //
588
- // concat
589
- //
590
- namespace detail {
591
- struct concat_t
592
- {
593
- template <class Range1 , class Range2 >
594
- auto operator ()(Range1 && r1, Range2 && r2) LINQ_RETURNS(boost::join(r1, r2));
595
- };
596
- }
597
- namespace {
598
- range_extension<detail::concat_t > concat = {};
599
- }
600
-
601
- //
602
- // contains
603
- //
604
- namespace detail {
605
- struct contains_t
606
- {
607
- template <class Range , class T >
608
- auto operator ()(Range && r, T && x) LINQ_RETURNS(return (r | linq::find(x) != boost::end(r)));
609
- };
610
- }
611
- namespace {
612
- range_extension<detail::contains_t > contains = {};
613
- }
614
-
615
-
616
- //
617
- // count
618
- //
619
- namespace detail {
620
- struct count_t
621
- {
622
- // TODO: add overload for random access ranges
623
- template <class Range >
624
- long operator ()(Range && r)
625
- {
626
- return std::count_if (boost::begin (r), boost::end (r), [](decltype (*boost::begin (r))) {return true ;});
627
- }
628
-
629
- template <class Range , class Pred >
630
- long operator ()(Range && r, Pred p)
631
- {
632
- return std::count_if (boost::begin (r), boost::end (r), p);
633
- }
634
- };
635
- }
636
- namespace {
637
- range_extension<detail::count_t > count = {};
638
- }
639
-
640
- //
641
- // default_if_empty
642
- //
643
- namespace detail {
644
-
645
- template <class Iterator , class Value =typename boost::iterator_value<Iterator>::type>
646
- struct default_if_empty_iterator
647
- : boost::iterator_facade<default_if_empty_iterator, Value, boost::forward_traversal_tag>
648
- {
649
- const bool empty;
650
- Iterator it;
651
- Value* ref;
652
- boost::optional<Value> v;
653
-
654
- default_if_empty_iterator (bool empty, Iterator it, Value x)
655
- : empty(empty), it(it), v(not empty, x)
656
- {}
657
-
658
- // TODO: Assign operator
659
-
660
- void increment ()
661
- {
662
- if (not empty) it++;
663
- else v = boost::optional<Value>();
664
- }
665
-
666
- bool equal (const default_if_empty_iterator<Iterator>& other) const
667
- {
668
- return
669
- (
670
- it == other.it and
671
- (not (v xor other.v ))
672
- );
673
- }
674
-
675
- typename boost::iteraror_reference<Iterator>::type deref () const
676
- {
677
- if (not empty) return *it;
678
- else return *v;
679
- }
680
- };
681
-
682
- template <class Iterator , class Value >
683
- auto make_default_if_empty_iterator (bool empty, Iterator && it, Value && v) LINQ_RETURNS
684
- (default_if_empty_iterator<Iterator>(empty, it, v));
685
-
686
- template <class Range , class Value >
687
- auto make_default_if_empty_range (bool empty, Range && r, Value && v) LINQ_RETURNS
688
- (boost::make_iterator_range
689
- (
690
- make_default_if_empty_iterator (empty, boost::begin(r), v),
691
- make_default_if_empty_iterator(empty, boost::end(r), v)
692
- ));
693
-
694
- struct default_if_empty_t
695
- {
696
- template <class Range , class T >
697
- auto operator ()(Range && r, T && x) LINQ_RETURNS
698
- (make_default_if_empty_range(boost::empty(r), r, x));
699
-
700
- template <class Range , class T >
701
- auto operator ()(Range && r) LINQ_RETURNS
702
- (make_default_if_empty_range(boost::empty(r), r, typename boost::range_value<Range>::type()));
703
- };
704
- }
705
- namespace {
706
- range_extension<detail::default_if_empty_t > default_if_empty = {};
707
- }
708
-
709
- //
710
- // distinct
711
- //
712
- namespace detail {
713
- struct distinct_t
714
- {
715
- struct predicate
716
- {
717
- template <class T , class Set >
718
- bool operator ()(const T& x, Set& s) const
719
- {
720
- if (s.find (x) != s.end ())
721
- {
722
- s.insert (x);
723
- return true ;
724
- }
725
- else
726
- {
727
- return false ;
728
- }
729
- }
730
- };
731
- // TODO: Add support for an equality selector
732
- template <class Range >
733
- auto operator ()(Range && r) const LINQ_RETURNS(make_set_filter_range(r, p));
734
- };
735
- }
736
- namespace {
737
- range_extension<detail::distinct_t > distinct = {};
738
- }
739
-
740
- //
741
- // element_at
742
- //
743
- namespace detail {
744
- struct element_at_t
745
- {
746
- template <class Iterator >
747
- static Iterator advance_it (Iterator it, std::size_t n)
748
- {
749
- std::advance (it, n);
750
- return it;
751
- }
752
- // TODO: Throw when its out of range
753
- // TODO: Add overload to provide a fallback value when its out of range
754
- template <class Range >
755
- auto operator ()(Range && r) const LINQ_RETURNS(*(advance_it(boost::begin(r))));
756
- };
757
- }
758
- namespace {
759
- range_extension<detail::element_at_t > element_at = {};
760
- }
761
-
762
- //
763
- // empty_range
764
- //
765
-
766
- //
767
- // except
768
- //
769
- namespace detail {
770
- struct except_t
771
- {
772
- struct predicate
773
- {
774
-
775
- template <class T , class Set >
776
- bool operator ()(const T& x, Set & s) const
777
- {
778
- if (s.find (x) == s.end ())
779
- {
780
- s.insert (x);
781
- return true ;
782
- }
783
- else return false ;
784
- }
785
- };
786
- // TODO: Add support for an equality selector
787
- template <class Range1 , class Range2 >
788
- auto operator ()(Range1 && r1, Range2 && r2) LINQ_RETURNS
789
- (make_set_filter_range(r2, r1, predicate()));
790
-
791
- };
792
- }
793
- namespace {
794
- range_extension<detail::except_t > except = {};
795
- }
796
-
797
-
798
- //
799
- // first
800
- //
801
- namespace detail {
802
- struct first_t
803
- {
804
- template <class Iterator , class Predicate , class Value >
805
- static boost::iterator_value<Iterator>::type first_it (Iterator first, Iterator last, Predicate p, Value && v)
806
- {
807
- auto it = std::find_if (first, last, p);
808
- if (it == last) return v;
809
- else return *it;
810
- }
811
-
812
- template <class Range , class Predicate , class Value >
813
- auto operator ()(Range && r, Predicate p, Value && v) LINQ_RETURNS
814
- (first_it(boost::begin(r), boost::end(r), p, std::forward<Value>(v)));
815
-
816
- template <class Range >
817
- auto operator ()(Range && r) LINQ_RETURNS(*(boost::begin(r)));
818
-
819
- };
820
- }
821
- namespace {
822
- range_extension<detail::first_t > first = {};
823
- }
824
-
825
- //
826
- // first_or_default
827
- //
828
- namespace detail {
829
- struct first_or_default_t
830
- {
831
- template <class Range >
832
- auto operator ()(Range && r) LINQ_RETURNS(r | linq::first(always(), typename boost::range_value<Range>::type()));
833
-
834
- template <class Range , class Predicate >
835
- auto operator ()(Range && r, Predicate p) LINQ_RETURNS(r | linq::first(p, typename boost::range_value<Range>::type()));
836
- };
837
- }
838
- namespace {
839
- range_extension<detail::first_or_default_t > first_or_default = {};
840
- }
841
-
842
- //
843
- // group_by
844
- //
845
- namespace detail {
846
- struct group_by_t
847
- {
848
-
849
- template <class Range >
850
- static auto make_map (Range && r) LINQ_RETURNS
851
- (std::multimap<decltype(boost::begin(r)->first), boost::begin(r)->second>(boost::begin(r), boost::end(r)));
852
-
853
- template <class Range , class Compare >
854
- static auto make_map (Range && r, Compare c) LINQ_RETURNS
855
- (std::multimap<decltype(boost::begin(r)->first), boost::begin(r)->second, Compare>(boost::begin(r), boost::end(r), c));
856
-
857
- struct identity_selector
858
- {
859
- template <class T >
860
- auto operator ()(T&& x) LINQ_RETURNS(std::forward<T>(x));
861
- };
862
-
863
- template <class KeySelector , class ElementSelector = identity_selector>
864
- struct map_selector
865
- {
866
- KeySelector key_selector;
867
- ElementSelector element_selector;
868
-
869
- map_selector (KeySelector ks, ElementSelector es = ElementSelector()) : key_selector(ks), element_selector(es)
870
- {}
871
-
872
- template <class T >
873
- auto operator ()(T && x) LINQ_RETURNS(std::make_pair(key_selector(x), element_selector(x)));
874
- };
875
-
876
- template <class KeySelector >
877
- static auto make_map_selector (KeySelector ks) LINQ_RETURNS(map_selector<KeySelector>(ks));
878
-
879
- template <class KeySelector , class ElementSelector >
880
- static auto make_map_selector (KeySelector ks, ElementSelector es) LINQ_RETURNS(map_selector<KeySelector>(ks, es));
881
-
882
- template <class Range , class KeySelector >
883
- auto operator ()(Range && r, KeySelector ks) LINQ_RETURNS
884
- (make_map(r | linq::select(make_map_selector(ks))));
885
-
886
- // TODO: Custom comparer overloads can't be supported right now,
887
- // because we can't detect the difference between a comparer and
888
- // a selector in msvc
889
-
890
- // template<class Range, class KeySelector, class KeyCompare>
891
- // auto operator()(Range && r, KeySelector ks, KeyCompare kc) LINQ_RETURNS
892
- // (make_map(r | linq::select(make_map_selector(ks)), kc));
893
-
894
- template <class Range , class KeySelector , class ElementSelector >
895
- auto operator ()(Range && r, KeySelector ks, ElementSelector es) LINQ_RETURNS
896
- (make_map(r | linq::select(make_map_selector(ks, es))));
897
-
898
- // template<class Range, class KeySelector, class ElementSelector, class KeyCompare>
899
- // auto operator()(Range && r, KeySelector ks,ElementSelector es, KeyCompare kc) LINQ_RETURNS
900
- // (make_map(r | linq::select(make_map_selector(ks, es)), kc));
901
- };
902
- }
903
- namespace {
904
- range_extension<detail::group_by_t > group_by = {};
905
- }
906
-
907
- //
908
- // group_join
909
- //
910
- namespace detail {
911
-
912
- template <class InnerKeySelector >
913
- struct join_inner_selector
914
- {
915
- InnerKeySelector is;
916
-
917
- join_inner_selector (InnerKeySelector is) : is(is)
918
- {}
919
-
920
- template <class T >
921
- auto operator ()(T && x) LINQ_RETURNS(std::make_pair(is(std::forward<T>(x), std::forward<T>(x)));
922
- };
923
-
924
- template <class InnerKeySelector >
925
- auto make_join_inner_selector (InnerKeySelector is) LINQ_RETURNS(join_inner_selector<InnerKeySelector>(is));
926
-
927
- template <class Value , class OuterKeySelector , class ResultKeySelector >
928
- struct join_selector
929
- {
930
- typedef decltype (linq::declval<OuterKeySelector>()(linq::declval<Value>())) key_t;
931
- boost::unordered_map<key_t , Value> inner_lookup;
932
- ResultKeySelector rs;
933
- OuterKeySelector os;
934
-
935
- template <class Range >
936
- join_selector (Range && r, OuterKeySelector os, ResultKeySelector rs)
937
- : inner_lookup(boost::begin(r), boost::end(r)), rs(rs), os(os)
938
- {}
939
-
940
- template <class Key >
941
- auto create_pair (Key && x) LINQ_RETURNS
942
- (
943
- std::make_pair (std::forward<T>(x), inner_lookup.equal_range(std::forward<T>(x)) | boost::adaptors::map_values)
944
- );
945
-
946
- template <class T >
947
- auto operator ()(T && x) LINQ_RETURNS
948
- (
949
- rs
950
- (
951
- create_pair (os(std::forward<T>(x)))
952
- )
953
- );
954
- };
955
-
956
- template <class Range , class OuterKeySelector , class ResultKeySelector >
957
- static auto make_join_selector (Range && r, OuterKeySelector os, ResultKeySelector rs) LINQ_RETURNS
958
- (join_selector<typename boost::range_value<R>, OuterKeySelector, ResultKeySelector >
959
- (
960
- r, os, rs
961
- ));
962
-
963
- struct group_join_t
964
- {
965
- template <class Outer , class Inner , class OuterKeySelector , class InnerKeySelector , class ResultSelector >
966
- auto operator ()(Outer && outer, Inner && inner, OuterKeySelector outer_key_selector, InnerKeySelector inner_key_selector, ResultSelector result_selector) LINQ_RETURNS
967
- (
968
- outer | linq::select
969
- (
970
- make_join_selector (inner | linq::select(make_join_inner_selector(is)), outer_key_selector, result_selector)
971
- )
972
- );
973
- };
974
- }
975
- namespace {
976
- range_extension<detail::group_join_t > group_join = {};
977
- }
978
-
979
- //
980
- // intersect
981
- //
982
- namespace detail {
983
- struct intersect_t
984
- {
985
- struct predicate
986
- {
987
-
988
- template <class T , class Set >
989
- bool operator ()(const T& x, Set & s) const
990
- {
991
- auto it = s.find (x);
992
- if (it != s.end ())
993
- {
994
- s.erase (it);
995
- return true ;
996
- }
997
- else return false ;
998
- }
999
- };
1000
- // TODO: Add support for an equality selector
1001
- template <class Range1 , class Range2 >
1002
- auto operator ()(Range1 && r1, Range2 && r2) LINQ_RETURNS
1003
- (make_set_filter_range(r2, r1, predicate()));
1004
- };
1005
- }
1006
- namespace {
1007
- range_extension<detail::intersect_t > intersect = {};
1008
- }
1009
-
1010
- //
1011
- // join
1012
- //
1013
-
1014
- //
1015
- // last
1016
- //
1017
-
1018
- //
1019
- // last_or_default
1020
- //
1021
-
1022
- //
1023
- // max
1024
- //
1025
-
1026
- //
1027
- // min
1028
- //
1029
-
1030
- //
1031
- // order_by
1032
- //
1033
-
1034
- //
1035
- // reverse
1036
- //
1037
-
1038
- //
1039
- // select_many
1040
- //
1041
-
1042
- //
1043
- // sequence_equal
1044
- //
1045
-
1046
- //
1047
- // single
1048
- //
1049
-
1050
- //
1051
- // single_or_default
1052
- //
1053
-
1054
- //
1055
- // skip
1056
- //
1057
-
1058
- //
1059
- // skip_while
1060
- //
1061
-
1062
- //
1063
- // sum
1064
- //
1065
-
1066
- //
1067
- // take
1068
- //
1069
-
1070
- //
1071
- // take_while
1072
- //
1073
-
1074
- //
1075
- // to_container
1076
- //
1077
- namespace detail {
1078
- struct to_container_t
1079
- {
1080
-
1081
- template <class Range >
1082
- struct converter
1083
- {
1084
- Range r;
1085
-
1086
- template <class R >
1087
- converter (R && x) : r(std::forward<R&&>(x))
1088
- {}
1089
-
1090
- template <class C >
1091
- operator C () const
1092
- {
1093
- return C (boost::begin (r), boost::end (r));
1094
- }
1095
- };
1096
-
1097
- template <class Range >
1098
- auto operator ()(Range && r) LINQ_RETURNS
1099
- (converter<Range&&>(std::forward<Range>(r)));
1100
- };
1101
- }
1102
- namespace {
1103
- range_extension<detail::to_container_t > to_container = {};
1104
- }
1105
-
1106
- //
1107
- // to_string
1108
- //
1109
-
1110
- //
1111
- // union
1112
- //
1113
-
1114
- //
1115
- // where
1116
- //
1117
-
1118
- //
1119
- // zip
1120
- //
1121
-
1122
- // Lambdas aren't very nice, so we use this wrapper to make them play nicer. This
1123
- // will make the function_object default constructible, even if it doesn't have a
1124
- // default constructor. This helpful since these function objects are being used
1125
- // inside of iterators.
1126
- template <class Fun >
1127
- struct function_object
1128
- {
1129
- boost::optional<Fun> f;
1130
-
1131
- function_object ()
1132
- {}
1133
- function_object (Fun f): f(f)
1134
- {}
1135
-
1136
- function_object (const function_object & rhs) : f(rhs.f)
1137
- {}
1138
-
1139
- // Assignment operator is just a copy construction, which does not provide
1140
- // the strong exception guarentee.
1141
- function_object& operator =(const function_object& rhs)
1142
- {
1143
- if (this != &rhs)
1144
- {
1145
- this ->~function_object ();
1146
- new (this ) function_object (rhs);
1147
- }
1148
- return *this ;
1149
- }
1150
-
1151
- template <class F >
1152
- struct result
1153
- {};
1154
-
1155
- template <class F , class T >
1156
- struct result <F(T)>
1157
- {
1158
- typedef decltype (linq::declval<Fun>()(linq::declval<T>())) type;
1159
- };
1160
-
1161
- template <class T >
1162
- auto operator ()(T && x) const LINQ_RETURNS((*f)(std::forward<T>(x)));
1163
-
1164
- template <class T >
1165
- auto operator ()(T && x) LINQ_RETURNS((*f)(std::forward<T>(x)));
1166
- };
1167
-
1168
- template <class F >
1169
- function_object<F> make_function_object (F f)
1170
- {
1171
- return function_object<F>(f);
1172
- }
1173
-
1174
-
1175
- // bind_iterator
1176
- template <class OuterIterator , class Selector , class SelectorRange = typename std::result_of<Selector(typename boost::iterator_reference<OuterIterator>::type)>::type>
1177
- struct bind_iterator
1178
- : boost::iterator_facade
1179
- <
1180
- bind_iterator<OuterIterator, Selector, SelectorRange>,
1181
- typename boost::range_value<SelectorRange >::type,
1182
- boost::forward_traversal_tag,
1183
- typename boost::range_reference<SelectorRange >::type
1184
- >
1185
- {
1186
- typedef typename boost::range_iterator<SelectorRange >::type InnerIteraror;
1187
-
1188
- Selector selector;
1189
- OuterIterator iterator;
1190
- InnerIteraror inner_first;
1191
- InnerIteraror inner_last;
1192
- OuterIterator last;
1193
-
1194
- bind_iterator (Selector selector, OuterIterator iterator, OuterIterator last) : selector (selector), iterator (iterator), last (last)
1195
- {
1196
- this ->select ();
1197
- }
1198
-
1199
- void select ()
1200
- {
1201
- for (;iterator!=last;iterator++)
1202
- {
1203
- if (inner_first==inner_last)
1204
- {
1205
- auto && r = selector (*iterator);
1206
- inner_first = boost::begin (r);
1207
- inner_last = boost::end (r);
1208
- }
1209
- else inner_first++;
1210
- for (;inner_first!=inner_last;inner_first++)
1211
- return ;
1212
- }
1213
- }
1214
-
1215
- void increment ()
1216
- {
1217
- this ->select ();
1218
- }
1219
-
1220
- bool equal (const bind_iterator& other) const
1221
- {
1222
- return this ->iterator == other.iterator ;
1223
- }
1224
-
1225
- typename boost::range_reference<SelectorRange >::type dereference () const
1226
- {
1227
- return *inner_first;
1228
- }
1229
-
1230
- };
1231
-
1232
- template <class Iterator , class Selector >
1233
- bind_iterator<Iterator, Selector> make_bind_iterator (Selector selector, Iterator iterator, Iterator last)
1234
- {
1235
- return bind_iterator<Iterator, Selector>(selector, iterator, last);
1236
- }
1237
-
1238
- template <class Range , class Selector >
1239
- auto bind_range (Range && r, Selector s) LINQ_RETURNS
1240
- (
1241
- boost::make_iterator_range
1242
- (
1243
- make_bind_iterator (s, boost::begin(r), boost::end(r)),
1244
- make_bind_iterator(s, boost::end(r), boost::end(r))
1245
- )
1246
- );
1247
-
1248
- // Bound range adaptor
1249
- namespace detail {
1250
- template <class Selector >
1251
- struct bound_t
1252
- {
1253
- Selector s;
1254
- bound_t (Selector s) : s(s)
1255
- {
1256
- }
1257
-
1258
- template <class Range >
1259
- friend auto operator |(Range && r, const bound_t self) -> decltype (linq::bind_range(std::forward<Range>(r), linq::declval<Selector>()))
1260
- {
1261
- return linq::bind_range (std::forward<Range>(r), self.s );
1262
- }
1263
-
1264
- };
1265
- }
1266
-
1267
- template <class Selector >
1268
- detail::bound_t <Selector> bound (Selector s)
1269
- {
1270
- return detail::bound_t <Selector>(s);
1271
- }
1272
-
1273
-
1274
-
1275
- namespace detail {
1276
-
1277
- // These are used to avoid using parenthessis with lambdas, since it
1278
- // could perhaps result in a pathological case for the preprocessor.
1279
- struct where_t
1280
- {
1281
- template <class Pred >
1282
- auto operator +(Pred p) LINQ_RETURNS(boost::adaptors::filtered(linq::make_function_object(p)));
1283
- };
1284
-
1285
- struct select_t
1286
- {
1287
- template <class Tran >
1288
- auto operator +(Tran t) LINQ_RETURNS(boost::adaptors::transformed(linq::make_function_object(t)));
1289
- };
1290
-
1291
- struct select_many_t
1292
- {
1293
- template <class Sel >
1294
- auto operator +(Sel s) LINQ_RETURNS(linq::bound(make_function_object(s)));
1295
- };
1296
- }
1297
-
1298
- detail::select_many_t select_many = {};
1299
- detail::select_t select = {};
1300
- detail::where_t where = {};
1301
-
1302
- }
1303
-
1304
- // Helps in defining lambdas in two steps. It also dedcues the type held
1305
- // by the container.
1306
- #define LINQ_LAMBDA_BLOCK (...) { return (__VA_ARGS__); }
1307
- #define LINQ_LAMBDA_HEADER (var, col ) [&](decltype( *(boost::begin(col)) ) var)
1308
-
1309
- // These macros help in defining the clauses. So instead of writing this:
1310
- //
1311
- // auto r = numbers | boost::adaptors::filtered([](int i) { return i > 2});
1312
- //
1313
- // This can be written:
1314
- //
1315
- // auto r = numbers | LINQ_WHERE(i, numbers)(i > 2);
1316
- //
1317
- #define LINQ_WHERE (var, col ) linq::where + LINQ_LAMBDA_HEADER(var, col) LINQ_LAMBDA_BLOCK
1318
- #define LINQ_SELECT (var, col ) linq::select + LINQ_LAMBDA_HEADER(var, col) LINQ_LAMBDA_BLOCK
1319
- #define LINQ_SELECT_MANY (var, col ) linq::select_many + LINQ_LAMBDA_HEADER(var, col) LINQ_LAMBDA_BLOCK
1320
-
1321
- //
1322
- // Keywords used by linq
1323
- //
1324
- #define LINQ_KEYWORD_from ()
1325
- #define LINQ_KEYWORD_select (LINQ_SELECT)
1326
- #define LINQ_KEYWORD_where (LINQ_WHERE)
1327
-
1328
- //
1329
- // Process the sequence
1330
- //
1331
-
1332
- // Expands the parameter, for another preprocessor scan
1333
- #define LINQ_X (...) __VA_ARGS__
1334
-
1335
- #define LINQ_PROCESS_PAREN (data, x ) x
1336
- #ifndef _MSC_VER
1337
- #define LINQ_PROCESS_KEYWORD (data, x ) | x data
1338
- #else
1339
- // MSVC Workarounds
1340
- #define LINQ_PROCESS_KEYWORD_RES (x ) x
1341
- #define LINQ_PROCESS_KEYWORD (data, x ) | LINQ_PROCESS_KEYWORD_RES(x data)
1342
- #endif
1343
-
1344
- #define LINQ_COL (var, col ) col
1345
-
1346
- // Process the select, where clauses
1347
- #define LINQ_SELECT_WHERE (seq ) LINQ_SELECT_WHERE_TRANSFORM(BOOST_PP_SEQ_ELEM(0 , seq) ,BOOST_PP_SEQ_REST_N(1 , seq))
1348
- #define LINQ_SELECT_WHERE_TRANSFORM (data, seq ) LINQ_COL data LINQ_SEQ_TO_STRING (BOOST_PP_SEQ_TRANSFORM(LINQ_SELECT_WHERE_O, data, seq))
1349
- #define LINQ_SELECT_WHERE_O (s, data, x ) BOOST_PP_IF(LINQ_IS_PAREN(x), LINQ_PROCESS_PAREN, LINQ_PROCESS_KEYWORD)(data, x)
1350
-
1351
- // Process from clauses
1352
- // ()((x, col))()((y, x.col))(LINQ_SELECT)((x))
1353
- // SPLIT
1354
- // ( ((x, col)) ) ( ((y, x.col))(LINQ_SELECT)((x)) )
1355
- // TRANSFORM
1356
- // (SELECT_MANY(x, col))((y, x.col)(LINQ_SELECT)(x))
1357
- // NEST
1358
- #define LINQ_FROM (seq ) LINQ_FROM_CHECK(LINQ_SEQ_SPLIT(seq, LINQ_FROM_P, data))
1359
- #define LINQ_FROM_CHECK (seq ) BOOST_PP_IF(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), LINQ_FROM_MULTI, LINQ_FROM_SINGLE)(seq)
1360
- #define LINQ_FROM_MULTI (seq ) LINQ_SEQ_NEST(LINQ_FROM_TRANSFORM(seq))
1361
- #define LINQ_FROM_SINGLE (seq ) LINQ_SELECT_WHERE(BOOST_PP_SEQ_HEAD(seq))
1362
-
1363
-
1364
- #define LINQ_FROM_TRANSFORM (seq ) BOOST_PP_SEQ_TRANSFORM(LINQ_FROM_OP, data, BOOST_PP_SEQ_POP_BACK(seq)) (LINQ_SELECT_WHERE(LINQ_BACK(seq)))
1365
-
1366
- #define LINQ_FROM_P (s, data, x ) LINQ_IS_EMPTY(x)
1367
- #ifndef _MSC_VER
1368
- #define LINQ_FROM_OP (s, data, x ) LINQ_PROCESS_FROM LINQ_REM x
1369
- #else
1370
- // MSVC Workarounds
1371
- #define LINQ_FROM_OP (s, data, x ) LINQ_FROM_OP_INVOKE(LINQ_REM x)
1372
- #define LINQ_FROM_OP_INVOKE_X (x ) x
1373
- #define LINQ_FROM_OP_INVOKE (x ) LINQ_FROM_OP_INVOKE_X(LINQ_PROCESS_FROM x)
1374
- #endif
1375
- #define LINQ_PROCESS_FROM (var, col ) col | LINQ_SELECT_MANY(var, col)
1376
-
1377
- // Transforms the sequence
1378
- #define LINQ_TRANSFORM (seq ) LINQ_X(LINQ_FROM(seq))
1379
- // And finally the LINQ macro
1380
- #define LINQ (x ) LINQ_TRANSFORM(LINQ_TO_SEQ(x))
11
+ #include <linq/extensions.h>
12
+ #include <linq/query.h>
1381
13
1382
14
#endif
0 commit comments