]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/phoenix/stl/algorithm/querying.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / phoenix / stl / algorithm / querying.hpp
1 // Copyright 2005 Daniel Wallin. 
2 // Copyright 2005 Joel de Guzman.
3 // Copyright 2005 Dan Marsden. 
4 // Copyright 2008 Hartmut Kaiser. 
5 //
6 // Use, modification and distribution is subject to the Boost Software 
7 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // Modeled after range_ex, Copyright 2004 Eric Niebler
11
12 #ifndef BOOST_PHOENIX_ALGORITHM_QUERYING_HPP
13 #define BOOST_PHOENIX_ALGORITHM_QUERYING_HPP
14
15 #include <algorithm>
16
17 #include <boost/phoenix/core/limits.hpp>
18 #include <boost/phoenix/stl/algorithm/detail/has_find.hpp>
19 #include <boost/phoenix/stl/algorithm/detail/has_lower_bound.hpp>
20 #include <boost/phoenix/stl/algorithm/detail/has_upper_bound.hpp>
21 #include <boost/phoenix/stl/algorithm/detail/has_equal_range.hpp>
22
23 #include <boost/phoenix/stl/algorithm/detail/begin.hpp>
24 #include <boost/phoenix/stl/algorithm/detail/end.hpp>
25 #include <boost/phoenix/stl/algorithm/detail/decay_array.hpp>
26
27 #include <boost/phoenix/function/adapt_callable.hpp>
28
29 #include <boost/range/result_iterator.hpp>
30 #include <boost/range/difference_type.hpp>
31
32 namespace boost { namespace phoenix {
33     namespace impl
34     {
35         struct find
36         {
37             template <typename Sig>
38             struct result;
39
40             template <typename This, class R, class T>
41             struct result<This(R&, T const&)>
42                 : range_result_iterator<R>
43             {};
44
45             template<class R, class T>
46             typename range_result_iterator<R>::type
47             execute(R& r, T const& x, mpl::true_) const
48             {
49                 return r.find(x);
50             }
51
52             template<class R, class T>
53             typename range_result_iterator<R>::type
54             execute(R& r, T const& x, mpl::false_) const
55             {
56                 return std::find(detail::begin_(r), detail::end_(r), x);
57             }
58
59             template<class R, class T>
60             typename range_result_iterator<R>::type
61             operator()(R& r, T const& x) const
62             {
63                 return execute(r, x, has_find<R>());
64             }
65         };
66
67         struct find_if
68         {
69             template <typename Sig>
70             struct result;
71
72             template <typename This, class R, class P>
73             struct result<This(R&, P)>
74                 : range_result_iterator<R>
75             {};
76
77             template<class R, class P>
78             typename range_result_iterator<R>::type
79             operator()(R& r, P p) const
80             {
81                 return std::find_if(detail::begin_(r), detail::end_(r), p);
82             }
83         };
84
85         struct find_end
86         {
87             template <typename Sig>
88             struct result;
89
90             template<typename This, class R, class R2>
91             struct result<This(R&, R2&)>
92                 : range_result_iterator<R>
93             {};
94
95             template<typename This, class R, class R2, class P>
96             struct result<This(R&, R2&, P)>
97                 : range_result_iterator<R>
98             {};
99
100             template<class R, class R2>
101             typename range_result_iterator<R>::type
102             operator()(R& r, R2& r2) const
103             {
104                 return std::find_end(
105                     detail::begin_(r)
106                     , detail::end_(r)
107                     , detail::begin_(r2)
108                     , detail::end_(r2)
109                     );
110             }
111
112             template<class R, class R2, class P>
113             typename range_result_iterator<R>::type
114             operator()(R& r, R2& r2, P p) const
115             {
116                 return std::find_end(
117                     detail::begin_(r)
118                     , detail::end_(r)
119                     , detail::begin_(r2)
120                     , detail::end_(r2)
121                     , p
122                     );
123             }
124         };
125
126         struct find_first_of
127         {
128             template <typename Sig>
129             struct result;
130
131             template<typename This, class R, class R2>
132             struct result<This(R&, R2&)>
133                 : range_result_iterator<R>
134             {};
135
136             template<typename This, class R, class R2, class P>
137             struct result<This(R&, R2&, P)>
138                 : range_result_iterator<R>
139             {};
140
141             template<class R, class R2>
142             typename range_result_iterator<R>::type
143             operator()(R& r, R2& r2) const
144             {
145                 return std::find_first_of(
146                     detail::begin_(r)
147                     , detail::end_(r)
148                     , detail::begin_(r2)
149                     , detail::end_(r2)
150                     );
151             }
152
153             template<class R, class R2, class P>
154             typename range_result_iterator<R>::type
155             operator()(R& r, R2& r2, P p) const
156             {
157                 return std::find_first_of(
158                     detail::begin_(r)
159                     , detail::end_(r)
160                     , detail::begin_(r2)
161                     , detail::end_(r2)
162                     , p
163                     );
164             }
165         };
166
167         struct adjacent_find
168         {
169             template <typename Sig>
170             struct result;
171
172             template <typename This, class R>
173             struct result<This(R&)>
174                 : range_result_iterator<R>
175             {};
176
177             template <typename This, class R, class P>
178             struct result<This(R&, P)>
179                 : range_result_iterator<R>
180             {};
181
182             template<class R>
183             typename range_result_iterator<R>::type
184             operator()(R& r) const
185             {
186                 return std::adjacent_find(detail::begin_(r), detail::end_(r));
187             }
188
189             template<class R, class P>
190             typename range_result_iterator<R>::type
191             operator()(R& r, P p) const
192             {
193                 return std::adjacent_find(detail::begin_(r), detail::end_(r), p);
194             }
195         };
196
197         struct count
198         {
199             template <typename Sig>
200             struct result;
201
202             template <typename This, class R, class T>
203             struct result<This(R&, T const&)>
204                 : range_difference<R>
205             {};
206
207             template<class R, class T>
208             typename range_difference<R>::type
209             operator()(R& r, T const& x) const
210             {
211                 return std::count(detail::begin_(r), detail::end_(r), x);
212             }
213         };
214
215         struct count_if
216         {
217             template <typename Sig>
218             struct result;
219
220             template <typename This, class R, class P>
221             struct result<This(R&, P)>
222                 : range_difference<R>
223             {};
224
225             template<class R, class P>
226             typename range_difference<R>::type
227             operator()(R& r, P p) const
228             {
229                 return std::count_if(detail::begin_(r), detail::end_(r), p);
230             }
231         };
232
233         struct distance
234         {
235             template <typename Sig>
236             struct result;
237
238             template <typename This, class R>
239             struct result<This(R&)>
240                 : range_difference<R>
241             {};
242
243             template<class R>
244             typename range_difference<R>::type
245             operator()(R& r) const
246             {
247                 return std::distance(detail::begin_(r), detail::end_(r));
248             }
249         };
250
251         struct equal
252         {
253             typedef bool result_type;
254
255             template<class R, class I>
256             bool operator()(R& r, I i) const
257             {
258                 return std::equal(detail::begin_(r), detail::end_(r), i);
259             }
260
261             template<class R, class I, class P>
262             bool operator()(R& r, I i, P p) const
263             {
264                 return std::equal(detail::begin_(r), detail::end_(r), i, p);
265             }
266         };
267
268         struct search
269         {
270             template <typename Sig>
271             struct result;
272
273             template <typename This, class R, typename R2>
274             struct result<This(R&, R2&)>
275                 : range_result_iterator<R>
276             {};
277
278             template <typename This, class R, typename R2, class P>
279             struct result<This(R&, R2&, P)>
280                 : range_result_iterator<R>
281             {};
282
283             template<class R, class R2>
284             typename range_result_iterator<R>::type
285             operator()(R& r, R2& r2) const
286             {
287                 return std::search(
288                     detail::begin_(r)
289                     , detail::end_(r)
290                     , detail::begin_(r2)
291                     , detail::end_(r2)
292                     );
293             }
294
295             template<class R, class R2, class P>
296             typename range_result_iterator<R>::type
297             operator()(R& r, R2& r2, P p) const
298             {
299                 return std::search(
300                     detail::begin_(r)
301                     , detail::end_(r)
302                     , detail::begin_(r2)
303                     , detail::end_(r2)
304                     , p
305                     );
306             }
307         };
308
309         struct lower_bound 
310         {
311             template <typename Sig>
312             struct result;
313
314             template <typename This, class R, class T>
315             struct result<This(R&, T const&)>
316                 : range_result_iterator<R>
317             {};
318
319             template <typename This, class R, class T, class C>
320             struct result<This(R&, T const&, C)>
321                 : range_result_iterator<R>
322             {};
323
324             template<class R, class T>
325             typename range_result_iterator<R>::type
326             execute(R& r, T const& val, mpl::true_) const
327             {
328                 return r.lower_bound(val);
329             }
330
331             template<class R, class T>
332             typename range_result_iterator<R>::type
333             execute(R& r, T const& val, mpl::false_) const
334             {
335                 return std::lower_bound(detail::begin_(r), detail::end_(r), val);
336             }
337
338             template<class R, class T>
339             typename range_result_iterator<R>::type
340             operator()(R& r, T const& val) const
341             {
342                 return execute(r, val, has_lower_bound<R>());
343             }
344
345             template<class R, class T, class C>
346             typename range_result_iterator<R>::type
347             operator()(R& r, T const& val, C c) const
348             {
349                 return std::lower_bound(detail::begin_(r), detail::end_(r), val, c);
350             }
351         };
352
353         struct upper_bound 
354         {
355             template <typename Sig>
356             struct result;
357
358             template <typename This, class R, class T>
359             struct result<This(R&, T const&)>
360                 : range_result_iterator<R>
361             {};
362
363             template <typename This, class R, class T, class C>
364             struct result<This(R&, T const&, C)>
365                 : range_result_iterator<R>
366             {};
367
368             template<class R, class T>
369             typename range_result_iterator<R>::type
370             execute(R& r, T const& val, mpl::true_) const
371             {
372                 return r.upper_bound(val);
373             }
374
375             template<class R, class T>
376             typename range_result_iterator<R>::type
377             execute(R& r, T const& val, mpl::false_) const
378             {
379                 return std::upper_bound(detail::begin_(r), detail::end_(r), val);
380             }
381
382             template<class R, class T>
383             typename range_result_iterator<R>::type
384             operator()(R& r, T const& val) const
385             {
386                 return execute(r, val, has_upper_bound<R>());
387             }
388
389             template<class R, class T, class C>
390             typename range_result_iterator<R>::type
391             operator()(R& r, T const& val, C c) const
392             {
393                 return std::upper_bound(detail::begin_(r), detail::end_(r), val, c);
394             }
395         };
396
397         namespace result_of
398         {
399             template <typename R, typename T, typename C = void>
400             struct equal_range
401             {
402                 typedef std::pair<
403                     typename range_result_iterator<R>::type
404                     , typename range_result_iterator<R>::type
405                 > type;
406             };
407         }
408
409         struct equal_range 
410         {
411             template <typename Sig>
412             struct result;
413
414             template <typename This, class R, class T>
415             struct result<This(R&, T const&)>
416                 : result_of::equal_range<R,T>
417             {};
418
419             template <typename This, class R, class T, class C>
420             struct result<This(R&, T const&, C)>
421                 : result_of::equal_range<R,T, C>
422             {};
423
424             template<class R, class T>
425             typename result_of::equal_range<R, T>::type
426             execute(R& r, T const& val, mpl::true_) const
427             {
428                 return r.equal_range(val);
429             }
430
431             template<class R, class T>
432             typename result_of::equal_range<R, T>::type
433             execute(R& r, T const& val, mpl::false_) const
434             {
435                 return std::equal_range(detail::begin_(r), detail::end_(r), val);
436             }
437
438             template<class R, class T>
439             typename result_of::equal_range<R, T>::type
440             operator()(R& r, T const& val) const
441             {
442                 return execute(r, val, has_equal_range<R>());
443             }
444
445             template<class R, class T, class C>
446             typename result_of::equal_range<R, T, C>::type
447             operator()(R& r, T const& val, C c) const
448             {
449                 return std::equal_range(detail::begin_(r), detail::end_(r), val, c);
450             }
451         };
452
453         namespace result_of
454         {
455             template <typename R, typename I, typename P = void>
456             struct mismatch
457             {
458                 typedef std::pair<
459                     typename range_result_iterator<R>::type
460                     , typename detail::decay_array<I>::type
461                 > type;
462             };
463         }
464
465         struct mismatch
466         {
467             template <typename Sig>
468             struct result;
469
470             template<typename This, class R, class I>
471             struct result<This(R&, I)>
472                 : result_of::mismatch<R, I>
473             {};
474
475             template<typename This, class R, class I, class P>
476             struct result<This(R&, I, P)>
477                 : result_of::mismatch<R, I, P>
478             {};
479
480             template<class R, class I>
481             typename result_of::mismatch<R, I>::type
482             operator()(R& r, I i) const
483             {
484                 return std::mismatch(detail::begin_(r), detail::end_(r), i);
485             }
486
487             template<class R, class I, class P>
488             typename result_of::mismatch<R, I, P>::type
489             operator()(R& r, I i, P p) const
490             {
491                 return std::mismatch(detail::begin_(r), detail::end_(r), i, p);
492             }
493         };
494
495         struct binary_search 
496         {
497             typedef bool result_type;
498
499             template<class R, class T>
500             bool operator()(R& r, T const& val) const
501             {
502                 return std::binary_search(detail::begin_(r), detail::end_(r), val);
503             }
504
505             template<class R, class T, class C>
506             bool operator()(R& r, T const& val, C c) const
507             {
508                 return std::binary_search(detail::begin_(r), detail::end_(r), val, c);
509             }
510         };
511
512         struct includes 
513         {
514             typedef bool result_type;
515
516             template<class R1, class R2>
517             bool operator()(R1& r1, R2& r2) const
518             {
519                 return std::includes(
520                     detail::begin_(r1), detail::end_(r1)
521                     , detail::begin_(r2), detail::end_(r2)
522                     );
523             }
524
525             template<class R1, class R2, class C>
526             bool operator()(R1& r1, R2& r2, C c) const
527             {
528                 return std::includes(
529                     detail::begin_(r1), detail::end_(r1)
530                     , detail::begin_(r2), detail::end_(r2)
531                     , c
532                     );
533             }
534         };
535
536         struct min_element
537         {
538             template <typename Sig>
539             struct result;
540             
541             template <typename This, class R>
542             struct result<This(R&)>
543                 : range_result_iterator<R>
544             {};
545
546             template <typename This, class R, class P>
547             struct result<This(R&, P)>
548                 : range_result_iterator<R>
549             {};
550
551             template<class R>
552             typename range_result_iterator<R>::type
553             operator()(R& r) const
554             {
555                 return std::min_element(detail::begin_(r), detail::end_(r));
556             }
557         
558             template<class R, class P>
559             typename range_result_iterator<R>::type
560             operator()(R& r, P p) const
561             {
562                 return std::min_element(detail::begin_(r), detail::end_(r), p);
563             }
564         };
565
566         struct max_element
567         {
568             template <typename Sig>
569             struct result;
570
571             template <typename This, class R>
572             struct result<This(R&)>
573                 : range_result_iterator<R>
574             {};
575
576             template <typename This, class R, class P>
577             struct result<This(R&, P)>
578                 : range_result_iterator<R>
579             {};
580
581             template<class R>
582             typename range_result_iterator<R>::type
583             operator()(R& r) const
584             {
585                 return std::max_element(detail::begin_(r), detail::end_(r));
586             }
587         
588             template<class R, class P>
589             typename range_result_iterator<R>::type
590             operator()(R& r, P p) const
591             {
592                 return std::max_element(detail::begin_(r), detail::end_(r), p);
593             }
594         };
595
596         struct lexicographical_compare
597         {
598             typedef bool result_type;
599
600             template<class R1, class R2>
601             bool operator()(R1& r1, R2& r2) const
602             {
603                 return std::lexicographical_compare(
604                     detail::begin_(r1), detail::end_(r1)
605                     , detail::begin_(r2), detail::end_(r2)
606                     );
607             }
608         
609             template<class R1, class R2, class P>
610             bool operator()(R1& r1, R2& r2, P p) const
611             {
612                 return std::lexicographical_compare(
613                     detail::begin_(r1), detail::end_(r1)
614                     , detail::begin_(r2), detail::end_(r2)
615                     , p
616                     );
617             }
618         };
619
620     }
621
622     BOOST_PHOENIX_ADAPT_CALLABLE(find, impl::find, 2)
623     BOOST_PHOENIX_ADAPT_CALLABLE(find_if, impl::find_if, 2)
624     BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 2)
625     BOOST_PHOENIX_ADAPT_CALLABLE(find_end, impl::find_end, 3)
626     BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 2)
627     BOOST_PHOENIX_ADAPT_CALLABLE(find_first_of, impl::find_first_of, 3)
628     BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 1)
629     BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_find, impl::adjacent_find, 2)
630     BOOST_PHOENIX_ADAPT_CALLABLE(count, impl::count, 2)
631     BOOST_PHOENIX_ADAPT_CALLABLE(count_if, impl::count_if, 2)
632     BOOST_PHOENIX_ADAPT_CALLABLE(distance, impl::distance, 1)
633     BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 2)
634     BOOST_PHOENIX_ADAPT_CALLABLE(equal, impl::equal, 3)
635     BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 2)
636     BOOST_PHOENIX_ADAPT_CALLABLE(search, impl::search, 3)
637     BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 2)
638     BOOST_PHOENIX_ADAPT_CALLABLE(lower_bound, impl::lower_bound, 3)
639     BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 2)
640     BOOST_PHOENIX_ADAPT_CALLABLE(upper_bound, impl::upper_bound, 3)
641     BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 2)
642     BOOST_PHOENIX_ADAPT_CALLABLE(equal_range, impl::equal_range, 3)
643     BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 2)
644     BOOST_PHOENIX_ADAPT_CALLABLE(mismatch, impl::mismatch, 3)
645     BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 2)
646     BOOST_PHOENIX_ADAPT_CALLABLE(binary_search, impl::binary_search, 3)
647     BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 2)
648     BOOST_PHOENIX_ADAPT_CALLABLE(includes, impl::includes, 3)
649     BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 1)
650     BOOST_PHOENIX_ADAPT_CALLABLE(min_element, impl::min_element, 2)
651     BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 1)
652     BOOST_PHOENIX_ADAPT_CALLABLE(max_element, impl::max_element, 2)
653     BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 2)
654     BOOST_PHOENIX_ADAPT_CALLABLE(lexicographical_compare, impl::lexicographical_compare, 3)
655
656 }}
657
658 #endif