1 // Copyright 2005 Daniel Wallin.
2 // Copyright 2005 Joel de Guzman.
3 // Copyright 2005 Dan Marsden.
4 // Copyright 2015 John Fletcher.
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_TRANSFORMATION_HPP
13 #define BOOST_PHOENIX_ALGORITHM_TRANSFORMATION_HPP
14 
15 #include <algorithm>
16 #include <numeric>
17 
18 #include <boost/phoenix/core/limits.hpp>
19 #include <boost/phoenix/stl/algorithm/detail/has_sort.hpp>
20 #include <boost/phoenix/stl/algorithm/detail/has_remove.hpp>
21 #include <boost/phoenix/stl/algorithm/detail/has_remove_if.hpp>
22 #include <boost/phoenix/stl/algorithm/detail/has_unique.hpp>
23 #include <boost/phoenix/stl/algorithm/detail/has_reverse.hpp>
24 #include <boost/phoenix/stl/algorithm/detail/has_sort.hpp>
25 
26 #include <boost/phoenix/stl/algorithm/detail/begin.hpp>
27 #include <boost/phoenix/stl/algorithm/detail/end.hpp>
28 #include <boost/phoenix/stl/algorithm/detail/decay_array.hpp>
29 
30 #include <boost/phoenix/function/adapt_callable.hpp>
31 
32 //#include <boost/range/result_iterator.hpp> is deprecated
33 #include <boost/range/iterator.hpp>
34 #include <boost/range/difference_type.hpp>
35 
36 #include <boost/mpl/if.hpp>
37 
38 #include <boost/type_traits/is_void.hpp>
39 
40 namespace boost { namespace phoenix { namespace impl
41 {
42     struct swap
43     {
44         typedef void result_type;
45 
46         template <class A, class B>
operator ()boost::phoenix::impl::swap47         void operator()(A& a, B& b) const
48         {
49             using std::swap;
50             swap(a, b);
51         }
52     };
53 
54     struct copy
55     {
56         template <typename Sig>
57         struct result;
58 
59         template<typename This, class R, class I>
60         struct result<This(R&, I)>
61             : detail::decay_array<I>
62         {};
63 
64         template<class R, class I>
65         typename detail::decay_array<I>::type
operator ()boost::phoenix::impl::copy66         operator()(R& r, I i) const
67         {
68             return std::copy(detail::begin_(r), detail::end_(r), i);
69         }
70     };
71 
72     struct copy_backward
73     {
74         template <typename Sig>
75         struct result;
76 
77         template<typename This, class R, class I>
78         struct result<This(R&, I)>
79             : result<This(R&, I const &)>
80         {};
81 
82         template<typename This, class R, class I>
83         struct result<This(R&, I &)>
84         {
85             typedef I type;
86         };
87 
88         template<class R, class I>
operator ()boost::phoenix::impl::copy_backward89         I operator()(R& r, I & i) const
90         {
91             return std::copy_backward(detail::begin_(r), detail::end_(r), i);
92         }
93 
94         template<class R, class I>
operator ()boost::phoenix::impl::copy_backward95         I const operator()(R& r, I const & i) const
96         {
97             return std::copy_backward(detail::begin_(r), detail::end_(r), i);
98         }
99     };
100 
101     struct transform
102     {
103         template <typename Sig>
104         struct result;
105 
106         template<typename This, class R, class OutorI1, class ForOut>
107         struct result<This(R&, OutorI1, ForOut)>
108             : detail::decay_array<OutorI1>
109         {
110         };
111 
112         template<typename This, class R, class OutorI1, class ForOut, class BinF>
113         struct result<This(R&, OutorI1, ForOut, BinF)>
114             : detail::decay_array<ForOut>
115         {
116         };
117 
118         template<class R, class O, class F>
119         typename result<transform(R&,O,F)>::type
operator ()boost::phoenix::impl::transform120         operator()(R& r, O o, F f) const
121         {
122             return std::transform(detail::begin_(r), detail::end_(r), o, f);
123         }
124 
125         template<class R, class I, class O, class F>
126         typename result<transform(R&,I,O,F)>::type
operator ()boost::phoenix::impl::transform127         operator()(R& r, I i, O o, F f) const
128         {
129             return std::transform(detail::begin_(r), detail::end_(r), i, o, f);
130         }
131     };
132 
133     struct replace
134     {
135         typedef void result_type;
136 
137         template<class R, class T>
operator ()boost::phoenix::impl::replace138         void operator()(R& r, T const& what, T const& with) const
139         {
140             std::replace(detail::begin_(r), detail::end_(r), what, with);
141         }
142     };
143 
144     struct replace_if
145     {
146         typedef void result_type;
147 
148         template<class R, class P, class T>
operator ()boost::phoenix::impl::replace_if149         void operator()(R& r, P p, T const& with) const
150         {
151             std::replace_if(detail::begin_(r), detail::end_(r), p, with);
152         }
153     };
154 
155     struct replace_copy
156     {
157         template <typename Sig>
158         struct result;
159 
160         template<typename This, class R, class O, class T, class T2>
161         struct result<This(R&, O, T&, T2&)>
162             : detail::decay_array<O>
163         {};
164 
165         template<class R, class O, class T>
166         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::replace_copy167         operator()(R& r, O o, T const& what, T const& with) const
168         {
169             return std::replace_copy(detail::begin_(r), detail::end_(r), o, what, with);
170         }
171     };
172 
173     struct replace_copy_if
174     {
175         template <typename Sig>
176         struct result;
177 
178         template<typename This, class R, class O, class P, class T>
179         struct result<This(R&, O, P, T&)>
180             : detail::decay_array<O>
181         {};
182 
183         template<class R, class O, class P, class T>
184         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::replace_copy_if185         operator()(R& r, O o, P p, T const& with) const
186         {
187             return std::replace_copy_if(detail::begin_(r), detail::end_(r), o, p, with);
188         }
189     };
190 
191     struct fill
192     {
193         typedef void result_type;
194 
195         template<class R, class T>
operator ()boost::phoenix::impl::fill196         void operator()(R& r, T const& x) const
197         {
198             std::fill(detail::begin_(r), detail::end_(r), x);
199         }
200     };
201 
202     struct fill_n
203     {
204         typedef void result_type;
205 
206         template<class R, class N, class T>
operator ()boost::phoenix::impl::fill_n207         void operator()(R& r, N n, T const& x) const
208         {
209             std::fill_n(detail::begin_(r), n, x);
210         }
211     };
212 
213     struct generate
214     {
215         typedef void result_type;
216 
217         template<class R, class G>
operator ()boost::phoenix::impl::generate218         void operator()(R& r, G const & g) const
219         {
220             std::generate(detail::begin_(r), detail::end_(r), g);
221         }
222     };
223 
224     struct generate_n
225     {
226         typedef void result_type;
227 
228         template<class R, class N, class G>
operator ()boost::phoenix::impl::generate_n229         void operator()(R& r, N n, G g) const
230         {
231             std::generate_n(detail::begin_(r), n, g);
232         }
233     };
234 
235     struct remove
236     {
237         template <typename Sig>
238         struct result;
239 
240         template<typename This, class R, class T>
241         struct result<This(R&, T&)>
242             : range_iterator<R>
243         {
244         };
245 
246         template<class R, class T>
247         typename range_iterator<R>::type
executeboost::phoenix::impl::remove248         execute(R& r, T const& x, mpl::true_) const
249         {
250             r.remove(x);
251             return detail::end_(r);
252         }
253 
254         template<class R, class T>
255         typename range_iterator<R>::type
executeboost::phoenix::impl::remove256         execute(R& r, T const& x, mpl::false_) const
257         {
258             return std::remove(detail::begin_(r), detail::end_(r), x);
259         }
260 
261         template<class R, class T>
262         typename range_iterator<R>::type
operator ()boost::phoenix::impl::remove263         operator()(R& r, T const& x) const
264         {
265             return execute(r, x, has_remove<R>());
266         }
267     };
268 
269     struct remove_if
270     {
271         template <typename Sig>
272         struct result;
273 
274         template <typename This, class R, class P>
275         struct result<This(R&,P)>
276             : range_iterator<R>
277         {
278         };
279 
280         template<class R, class P>
281         typename range_iterator<R>::type
executeboost::phoenix::impl::remove_if282         execute(R& r, P p, mpl::true_) const
283         {
284             r.remove_if(p);
285             return detail::end_(r);
286         }
287 
288         template<class R, class P>
289         typename range_iterator<R>::type
executeboost::phoenix::impl::remove_if290         execute(R& r, P p, mpl::false_) const
291         {
292             return std::remove_if(detail::begin_(r), detail::end_(r), p);
293         }
294 
295         template<class R, class P>
296         typename range_iterator<R>::type
operator ()boost::phoenix::impl::remove_if297         operator()(R& r, P p) const
298         {
299             return execute(r, p, has_remove_if<R>());
300         }
301     };
302 
303     struct remove_copy
304     {
305         template <typename Sig>
306         struct result;
307 
308         template<typename This, class R, class O, class T>
309         struct result<This(R&, O, T)>
310             : detail::decay_array<O>
311         {};
312 
313         template<class R, class O, class T>
314         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::remove_copy315         operator()(R& r, O o, T const& x) const
316         {
317             return std::remove_copy(detail::begin_(r), detail::end_(r), o, x);
318         }
319     };
320 
321     struct remove_copy_if
322     {
323         template <typename Sig>
324         struct result;
325 
326         template<typename This, class R, class O, class P>
327         struct result<This(R&, O, P)>
328             : detail::decay_array<O>
329         {};
330 
331         template<class R, class O, class P>
332         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::remove_copy_if333         operator()(R& r, O o, P p) const
334         {
335             return std::remove_copy_if(detail::begin_(r), detail::end_(r), o, p);
336         }
337     };
338 
339     struct unique
340     {
341         template <typename Sig>
342         struct result;
343 
344         template<typename This, class R>
345         struct result<This(R&)>
346             : range_iterator<R>
347         {};
348 
349         template<typename This, class R, class P>
350         struct result<This(R&, P)>
351             : range_iterator<R>
352         {};
353 
354         template<class R>
355         typename range_iterator<R>::type
executeboost::phoenix::impl::unique356         execute(R& r, mpl::true_) const
357         {
358             r.unique();
359             return detail::end_(r);
360         }
361 
362         template<class R>
363         typename range_iterator<R>::type
executeboost::phoenix::impl::unique364         execute(R& r, mpl::false_) const
365         {
366             return std::unique(detail::begin_(r), detail::end_(r));
367         }
368 
369         template<class R>
370         typename range_iterator<R>::type
operator ()boost::phoenix::impl::unique371         operator()(R& r) const
372         {
373             return execute(r, has_unique<R>());
374         }
375 
376 
377         template<class R, class P>
378         typename range_iterator<R>::type
executeboost::phoenix::impl::unique379         execute(R& r, P p, mpl::true_) const
380         {
381             r.unique(p);
382             return detail::end_(r);
383         }
384 
385         template<class R, class P>
386         typename range_iterator<R>::type
executeboost::phoenix::impl::unique387         execute(R& r, P p, mpl::false_) const
388         {
389             return std::unique(detail::begin_(r), detail::end_(r), p);
390         }
391 
392         template<class R, class P>
393         typename range_iterator<R>::type
operator ()boost::phoenix::impl::unique394         operator()(R& r, P p) const
395         {
396             return execute(r, p, has_unique<R>());
397         }
398     };
399 
400     struct unique_copy
401     {
402         template <typename Sig>
403         struct result;
404 
405         template<typename This, class R, class O>
406         struct result<This(R&, O)>
407             : detail::decay_array<O>
408         {};
409 
410         template<typename This, class R, class O, class P>
411         struct result<This(R&, O, P)>
412             : detail::decay_array<O>
413         {};
414 
415         template<class R, class O>
operator ()boost::phoenix::impl::unique_copy416         typename detail::decay_array<O>::type operator()(R& r, O o) const
417         {
418             return std::unique_copy(
419                 detail::begin_(r)
420                 , detail::end_(r)
421                 , o
422                 );
423         }
424 
425         template<class R, class O, class P>
operator ()boost::phoenix::impl::unique_copy426         typename detail::decay_array<O>::type operator()(R& r, O o, P p) const
427         {
428             return std::unique_copy(
429                 detail::begin_(r)
430                 , detail::end_(r)
431                 , o
432                 , p
433                 );
434         }
435     };
436 
437     struct reverse
438     {
439         typedef void result_type;
440 
441         template<class R>
executeboost::phoenix::impl::reverse442         void execute(R& r, mpl::true_) const
443         {
444             r.reverse();
445         }
446 
447         template<class R>
executeboost::phoenix::impl::reverse448         void execute(R& r, mpl::false_) const
449         {
450             std::reverse(detail::begin_(r), detail::end_(r));
451         }
452 
453         template<class R>
operator ()boost::phoenix::impl::reverse454         void operator()(R& r) const
455         {
456             execute(r, has_reverse<R>());
457         }
458     };
459 
460     struct reverse_copy
461     {
462         template <typename Sig>
463         struct result;
464 
465         template<typename This, class R, class O>
466         struct result<This(R&, O)>
467             : detail::decay_array<O>
468         {};
469 
470         template<class R, class O>
operator ()boost::phoenix::impl::reverse_copy471         typename detail::decay_array<O>::type operator()(R& r, O o) const
472         {
473             return std::reverse_copy(
474                 detail::begin_(r)
475                 , detail::end_(r)
476                 , o
477                 );
478         }
479     };
480 
481     struct rotate
482     {
483         typedef void result_type;
484 
485         template<class R, class M>
operator ()boost::phoenix::impl::rotate486         void operator()(R& r, M m) const
487         {
488             std::rotate(
489                 detail::begin_(r)
490                 , m
491                 , detail::end_(r)
492                 );
493         }
494     };
495 
496     struct rotate_copy
497     {
498         template <typename Sig>
499         struct result;
500 
501         template<typename This, class R, class M, class O>
502         struct result<This(R&, M, O)>
503             : detail::decay_array<O>
504         {};
505 
506         template<class R, class M, class O>
operator ()boost::phoenix::impl::rotate_copy507         typename detail::decay_array<O>::type operator()(R& r, M m, O o) const
508         {
509             return std::rotate_copy(
510                 detail::begin_(r)
511                 , m
512                 , detail::end_(r)
513                 , o
514                 );
515         }
516     };
517 
518 #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE
519     struct random_shuffle
520     {
521         typedef void result_type;
522 
523         template<class R>
operator ()boost::phoenix::impl::random_shuffle524         void operator()(R& r) const
525         {
526             return std::random_shuffle(detail::begin_(r), detail::end_(r));
527         }
528 
529         template<class R, class G>
operator ()boost::phoenix::impl::random_shuffle530         void operator()(R& r, G g) const
531         {
532             return std::random_shuffle(detail::begin_(r), detail::end_(r), g);
533         }
534     };
535 #endif
536 
537     struct partition
538     {
539         template <typename Sig>
540         struct result;
541 
542         template <typename This, class R, class P>
543         struct result<This(R&, P)>
544             : range_iterator<R>
545         {};
546 
547         template<class R, class P>
548         typename range_iterator<R>::type
operator ()boost::phoenix::impl::partition549         operator()(R& r, P p) const
550         {
551             return std::partition(detail::begin_(r), detail::end_(r), p);
552         }
553     };
554 
555     struct stable_partition
556     {
557         template <typename Sig>
558         struct result;
559 
560         template <typename This, class R, class P>
561         struct result<This(R&, P)>
562             : range_iterator<R>
563         {};
564 
565         template<class R, class P>
566         typename range_iterator<R>::type
operator ()boost::phoenix::impl::stable_partition567         operator()(R& r, P p) const
568         {
569             return std::stable_partition(detail::begin_(r), detail::end_(r), p);
570         }
571     };
572 
573     struct sort
574     {
575         typedef void result_type;
576 
577         template<class R>
executeboost::phoenix::impl::sort578         void execute(R& r, mpl::true_) const
579         {
580             r.sort();
581         }
582 
583         template<class R>
executeboost::phoenix::impl::sort584         void execute(R& r, mpl::false_) const
585         {
586             std::sort(detail::begin_(r), detail::end_(r));
587         }
588 
589         template<class R>
operator ()boost::phoenix::impl::sort590         void operator()(R& r) const
591         {
592             execute(r, has_sort<R>());
593         }
594 
595         template<class R, class C>
executeboost::phoenix::impl::sort596         void execute(R& r, C c, mpl::true_) const
597         {
598             r.sort(c);
599         }
600 
601         template<class R, class C>
executeboost::phoenix::impl::sort602         void execute(R& r, C c, mpl::false_) const
603         {
604             std::sort(detail::begin_(r), detail::end_(r), c);
605         }
606 
607         template<class R, class C>
operator ()boost::phoenix::impl::sort608         void operator()(R& r, C c) const
609         {
610             execute(r, c, has_sort<R>());
611         }
612     };
613 
614     struct stable_sort
615     {
616         typedef void result_type;
617 
618         template<class R>
operator ()boost::phoenix::impl::stable_sort619         void operator()(R& r) const
620         {
621             std::stable_sort(detail::begin_(r), detail::end_(r));
622         }
623 
624         template<class R, class C>
operator ()boost::phoenix::impl::stable_sort625         void operator()(R& r, C c) const
626         {
627             std::stable_sort(detail::begin_(r), detail::end_(r), c);
628         }
629     };
630 
631     struct partial_sort
632     {
633         typedef void result_type;
634 
635         template<class R, class M>
operator ()boost::phoenix::impl::partial_sort636         void operator()(R& r, M m) const
637         {
638             std::partial_sort(detail::begin_(r), m, detail::end_(r));
639         }
640 
641         template<class R, class M, class C>
operator ()boost::phoenix::impl::partial_sort642         void operator()(R& r, M m, C c) const
643         {
644             std::partial_sort(detail::begin_(r), m, detail::end_(r), c);
645         }
646     };
647 
648     struct partial_sort_copy
649     {
650         template <typename Sig>
651         struct result;
652 
653         template <typename This, class R1, class R2>
654         struct result<This(R1&, R2&)>
655             : range_iterator<R2>
656         {};
657 
658         template <typename This, class R1, class R2, class C>
659         struct result<This(R1&, R2&, C)>
660             : range_iterator<R2>
661         {};
662 
663         template <class R1, class R2>
664         typename range_iterator<R2>::type
operator ()boost::phoenix::impl::partial_sort_copy665         operator()(R1& r1, R2& r2) const
666         {
667             return std::partial_sort_copy(
668                 detail::begin_(r1), detail::end_(r1)
669                 , detail::begin_(r2), detail::end_(r2)
670                 );
671         }
672 
673         template <class R1, class R2, class C>
674         typename range_iterator<R2>::type
operator ()boost::phoenix::impl::partial_sort_copy675         operator()(R1& r1, R2& r2, C c) const
676         {
677             return std::partial_sort_copy(
678                 detail::begin_(r1), detail::end_(r1)
679                 , detail::begin_(r2), detail::end_(r2)
680                 , c
681                 );
682         }
683     };
684 
685     struct nth_element
686     {
687         typedef void result_type;
688 
689         template<class R, class N>
operator ()boost::phoenix::impl::nth_element690         void operator()(R& r, N n) const
691         {
692             return std::nth_element(detail::begin_(r), n, detail::end_(r));
693         }
694 
695         template<class R, class N, class C>
operator ()boost::phoenix::impl::nth_element696         void operator()(R& r, N n, C c) const
697         {
698             return std::nth_element(detail::begin_(r), n, detail::end_(r), c);
699         }
700     };
701 
702     struct merge
703     {
704         template <typename Sig>
705         struct result;
706 
707         template<typename This, class R1, class R2, class O>
708         struct result<This(R1&, R2&, O)>
709             : detail::decay_array<O>
710         {};
711 
712         template<typename This, class R1, class R2, class O, class C>
713         struct result<This(R1&, R2&, O, C)>
714             : detail::decay_array<O>
715         {};
716 
717         template<class R1, class R2, class O>
operator ()boost::phoenix::impl::merge718         typename detail::decay_array<O>::type operator()(R1& r1, R2& r2, O o) const
719         {
720             return std::merge(
721                 detail::begin_(r1), detail::end_(r1)
722                 , detail::begin_(r2), detail::end_(r2)
723                 , o
724                 );
725         }
726 
727         template<class R1, class R2, class O, class C>
operator ()boost::phoenix::impl::merge728         typename detail::decay_array<O>::type operator()(R1& r1, R2& r2, O o, C c) const
729         {
730             return std::merge(
731                 detail::begin_(r1), detail::end_(r1)
732                 , detail::begin_(r2), detail::end_(r2)
733                 , o
734                 , c
735                 );
736         }
737     };
738 
739     struct inplace_merge
740     {
741         typedef void result_type;
742 
743         template<class R, class M>
operator ()boost::phoenix::impl::inplace_merge744         void operator()(R& r, M m) const
745         {
746             return std::inplace_merge(detail::begin_(r), m, detail::end_(r));
747         }
748 
749         template<class R, class M, class C>
operator ()boost::phoenix::impl::inplace_merge750         void operator()(R& r, M m, C c) const
751         {
752             return std::inplace_merge(detail::begin_(r), m, detail::end_(r), c);
753         }
754     };
755 
756     struct next_permutation
757     {
758         typedef bool result_type;
759 
760         template<class R>
operator ()boost::phoenix::impl::next_permutation761         bool operator()(R& r) const
762         {
763             return std::next_permutation(detail::begin_(r), detail::end_(r));
764         }
765 
766         template<class R, class C>
operator ()boost::phoenix::impl::next_permutation767         bool operator()(R& r, C c) const
768         {
769             return std::next_permutation(detail::begin_(r), detail::end_(r), c);
770         }
771     };
772 
773     struct prev_permutation
774     {
775         typedef bool result_type;
776 
777         template<class R>
operator ()boost::phoenix::impl::prev_permutation778         bool operator()(R& r) const
779         {
780             return std::prev_permutation(detail::begin_(r), detail::end_(r));
781         }
782 
783         template<class R, class C>
operator ()boost::phoenix::impl::prev_permutation784         bool operator()(R& r, C c) const
785         {
786             return std::prev_permutation(detail::begin_(r), detail::end_(r), c);
787         }
788     };
789 
790 
791     struct inner_product
792     {
793         template <typename Sig>
794         struct result;
795 
796         template <typename This, typename R, typename I, typename T>
797         struct result<This(R&, I, T)>
798             : result<This(R&, I const &, T)>
799         {};
800 
801         template <typename This, typename R, typename I, typename T>
802         struct result<This(R&, I, T &)>
803         {
804             typedef T type;
805         };
806 
807         template <typename This, typename R, typename I, typename T, typename C1, typename C2>
808         struct result<This(R&, I, T, C1, C2)>
809             : result<This(R&, I, T const &, C1, C2)>
810         {};
811 
812         template <typename This, typename R, typename I, typename T, typename C1, typename C2>
813         struct result<This(R&, I, T &, C1, C2)>
814         {
815             typedef T type;
816         };
817 
818         template <class R, class I, class T>
819         T
operator ()boost::phoenix::impl::inner_product820         operator()(R& r, I i, T t) const
821         {
822             return std::inner_product(
823                 detail::begin_(r), detail::end_(r), i, t);
824         }
825 
826         template <class R, class I, class T, class C1, class C2>
827         T
828         operator()(R& r, I i, T t, C1 c1, C2 c2) const
829         {
830             return std::inner_product(
831                 detail::begin_(r), detail::end_(r), i,
832                 t, c1, c2);
833         }
834     };
835 
836     struct partial_sum
837     {
838         template <typename Sig>
839         struct result;
840 
841         template <typename This, class R, class I>
842         struct result<This(R&, I)>
843             : detail::decay_array<I>
844         {};
845 
846         template <typename This, class R, class I, class C>
847         struct result<This(R&, I, C)>
848             : detail::decay_array<I>
849         {};
850 
851         template <class R, class I>
852         typename detail::decay_array<I>::type
operator ()boost::phoenix::impl::partial_sum853         operator()(R& r, I i) const
854         {
855             return std::partial_sum(
856                 detail::begin_(r), detail::end_(r), i);
857         }
858 
859         template <class R, class I, class C>
860         typename detail::decay_array<I>::type
operator ()boost::phoenix::impl::partial_sum861         operator()(R& r, I i, C c) const
862         {
863             return std::partial_sum(
864                 detail::begin_(r), detail::end_(r), i, c);
865         }
866     };
867 
868     struct adjacent_difference
869     {
870         template <typename Sig>
871         struct result;
872 
873         template <typename This, class R, class I>
874         struct result<This(R&, I)>
875             : detail::decay_array<I>
876         {};
877 
878         template <typename This,class R, class I, class C>
879         struct result<This(R&, I, C)>
880             : detail::decay_array<I>
881         {};
882 
883         template <class R, class I>
884         typename detail::decay_array<I>::type
operator ()boost::phoenix::impl::adjacent_difference885         operator()(R& r, I i) const
886         {
887             return std::adjacent_difference(
888                 detail::begin_(r), detail::end_(r), i);
889         }
890 
891         template <class R, class I, class C>
892         typename detail::decay_array<I>::type
operator ()boost::phoenix::impl::adjacent_difference893         operator()(R& r, I i, C c) const
894         {
895             return std::adjacent_difference(
896                 detail::begin_(r), detail::end_(r), i, c);
897         }
898     };
899 
900     struct push_heap
901     {
902         typedef void result_type;
903 
904         template <class R>
operator ()boost::phoenix::impl::push_heap905         void operator()(R& r) const
906         {
907             std::push_heap(detail::begin_(r), detail::end_(r));
908         }
909 
910         template <class R, class C>
operator ()boost::phoenix::impl::push_heap911         void operator()(R& r, C c) const
912         {
913             std::push_heap(detail::begin_(r), detail::end_(r), c);
914         }
915     };
916 
917     struct pop_heap
918     {
919         typedef void result_type;
920 
921         template <class R>
operator ()boost::phoenix::impl::pop_heap922         void operator()(R& r) const
923         {
924             std::pop_heap(detail::begin_(r), detail::end_(r));
925         }
926 
927         template <class R, class C>
operator ()boost::phoenix::impl::pop_heap928         void operator()(R& r, C c) const
929         {
930             std::pop_heap(detail::begin_(r), detail::end_(r), c);
931         }
932     };
933 
934     struct make_heap
935     {
936         typedef void result_type;
937 
938         template <class R>
operator ()boost::phoenix::impl::make_heap939         void operator()(R& r) const
940         {
941             std::make_heap(detail::begin_(r), detail::end_(r));
942         }
943 
944         template <class R, class C>
operator ()boost::phoenix::impl::make_heap945         void operator()(R& r, C c) const
946         {
947             std::make_heap(detail::begin_(r), detail::end_(r), c);
948         }
949     };
950 
951     struct sort_heap
952     {
953         typedef void result_type;
954 
955         template <class R>
operator ()boost::phoenix::impl::sort_heap956         void operator()(R& r) const
957         {
958             std::sort_heap(detail::begin_(r), detail::end_(r));
959         }
960 
961         template <class R, class C>
operator ()boost::phoenix::impl::sort_heap962         void operator()(R& r, C c) const
963         {
964             std::sort_heap(detail::begin_(r), detail::end_(r), c);
965         }
966     };
967 
968     struct set_union
969     {
970         template <typename Sig>
971         struct result;
972 
973         template <typename This, class R1, class R2, class O>
974         struct result<This(R1&, R2&, O)>
975             : detail::decay_array<O>
976         {};
977 
978         template <typename This, class R1, class R2, class O, typename C>
979         struct result<This(R1&, R2&, O, C)>
980             : detail::decay_array<O>
981         {};
982 
983         template <class R1, class R2, class O>
984         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_union985         operator()(R1& r1, R2& r2, O o) const
986         {
987             return std::set_union(
988                 detail::begin_(r1), detail::end_(r1)
989                 , detail::begin_(r2), detail::end_(r2)
990                 , o
991                 );
992         }
993 
994         template <class R1, class R2, class O, class C>
995         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_union996         operator()(R1& r1, R2& r2, O o, C c) const
997         {
998             return std::set_union(
999                 detail::begin_(r1), detail::end_(r1)
1000                 , detail::begin_(r2), detail::end_(r2)
1001                 , o
1002                 , c
1003                 );
1004         }
1005     };
1006 
1007     struct set_intersection
1008     {
1009         template <typename Sig>
1010         struct result;
1011 
1012         template <typename This, class R1, class R2, class O>
1013         struct result<This(R1&, R2&, O)>
1014             : detail::decay_array<O>
1015         {};
1016 
1017         template <typename This, class R1, class R2, class O, typename C>
1018         struct result<This(R1&, R2&, O, C)>
1019             : detail::decay_array<O>
1020         {};
1021 
1022         template <class R1, class R2, class O>
1023         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_intersection1024         operator()(R1& r1, R2& r2, O o) const
1025         {
1026             return std::set_intersection(
1027                 detail::begin_(r1), detail::end_(r1)
1028                 , detail::begin_(r2), detail::end_(r2)
1029                 , o
1030                 );
1031         }
1032 
1033         template <class R1, class R2, class O, class C>
1034         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_intersection1035         operator()(R1& r1, R2& r2, O o, C c) const
1036         {
1037             return std::set_intersection(
1038                 detail::begin_(r1), detail::end_(r1)
1039                 , detail::begin_(r2), detail::end_(r2)
1040                 , o
1041                 , c
1042                 );
1043         }
1044     };
1045 
1046     struct set_difference
1047     {
1048         template <typename Sig>
1049         struct result;
1050 
1051         template <typename This, class R1, class R2, class O>
1052         struct result<This(R1&, R2&, O)>
1053             : detail::decay_array<O>
1054         {};
1055 
1056         template <typename This, class R1, class R2, class O, class C>
1057         struct result<This(R1&, R2&, O, C)>
1058             : detail::decay_array<O>
1059         {};
1060 
1061         template <class R1, class R2, class O>
1062         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_difference1063         operator()(R1& r1, R2& r2, O o) const
1064         {
1065             return std::set_difference(
1066                 detail::begin_(r1), detail::end_(r1)
1067                 , detail::begin_(r2), detail::end_(r2)
1068                 , o
1069                 );
1070         }
1071 
1072         template <class R1, class R2, class O, class C>
1073         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_difference1074         operator()(R1& r1, R2& r2, O o, C c) const
1075         {
1076             return std::set_difference(
1077                 detail::begin_(r1), detail::end_(r1)
1078                 , detail::begin_(r2), detail::end_(r2)
1079                 , o
1080                 , c
1081                 );
1082         }
1083     };
1084 
1085     struct set_symmetric_difference
1086     {
1087         template <typename Sig>
1088         struct result;
1089 
1090         template <typename This, class R1, class R2, class O>
1091         struct result<This(R1&, R2, O)>
1092             : detail::decay_array<O>
1093         {};
1094 
1095         template <typename This, class R1, class R2, class O, class C>
1096         struct result<This(R1&, R2, O, C)>
1097             : detail::decay_array<O>
1098         {};
1099 
1100         template <class R1, class R2, class O>
1101         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_symmetric_difference1102         operator()(R1& r1, R2& r2, O o) const
1103         {
1104             return std::set_symmetric_difference(
1105                 detail::begin_(r1), detail::end_(r1)
1106                 , detail::begin_(r2), detail::end_(r2)
1107                 , o
1108                 );
1109         }
1110 
1111         template <class R1, class R2, class O, class C>
1112         typename detail::decay_array<O>::type
operator ()boost::phoenix::impl::set_symmetric_difference1113         operator()(R1& r1, R2& r2, O o, C c) const
1114         {
1115             return std::set_symmetric_difference(
1116                 detail::begin_(r1), detail::end_(r1)
1117                 , detail::begin_(r2), detail::end_(r2)
1118                 , o
1119                 , c
1120                 );
1121         }
1122     };
1123 
1124 }}} // boost::phoenix::impl
1125 
1126 namespace boost { namespace phoenix
1127 {
1128     BOOST_PHOENIX_ADAPT_CALLABLE(swap, impl::swap, 2)
1129     BOOST_PHOENIX_ADAPT_CALLABLE(copy, impl::copy, 2)
1130     BOOST_PHOENIX_ADAPT_CALLABLE(copy_backward, impl::copy_backward, 2)
1131     BOOST_PHOENIX_ADAPT_CALLABLE(transform, impl::transform, 3)
1132     BOOST_PHOENIX_ADAPT_CALLABLE(transform, impl::transform, 4)
1133     BOOST_PHOENIX_ADAPT_CALLABLE(replace, impl::replace, 3)
1134     BOOST_PHOENIX_ADAPT_CALLABLE(replace_if, impl::replace_if, 3)
1135     BOOST_PHOENIX_ADAPT_CALLABLE(replace_copy, impl::replace_copy, 4)
1136     BOOST_PHOENIX_ADAPT_CALLABLE(replace_copy_if, impl::replace_copy_if, 4)
1137     BOOST_PHOENIX_ADAPT_CALLABLE(fill, impl::fill, 2)
1138     BOOST_PHOENIX_ADAPT_CALLABLE(fill_n, impl::fill_n, 3)
1139     BOOST_PHOENIX_ADAPT_CALLABLE(generate, impl::generate, 2)
1140     BOOST_PHOENIX_ADAPT_CALLABLE(generate_n, impl::generate_n, 3)
1141     BOOST_PHOENIX_ADAPT_CALLABLE(remove, impl::remove, 2)
1142     BOOST_PHOENIX_ADAPT_CALLABLE(remove_if, impl::remove_if, 2)
1143     BOOST_PHOENIX_ADAPT_CALLABLE(remove_copy, impl::remove_copy, 3)
1144     BOOST_PHOENIX_ADAPT_CALLABLE(remove_copy_if, impl::remove_copy_if, 3)
1145     BOOST_PHOENIX_ADAPT_CALLABLE(unique, impl::unique, 1)
1146     BOOST_PHOENIX_ADAPT_CALLABLE(unique, impl::unique, 2)
1147     BOOST_PHOENIX_ADAPT_CALLABLE(unique_copy, impl::unique_copy, 2)
1148     BOOST_PHOENIX_ADAPT_CALLABLE(unique_copy, impl::unique_copy, 3)
1149     BOOST_PHOENIX_ADAPT_CALLABLE(reverse, impl::reverse, 1)
1150     BOOST_PHOENIX_ADAPT_CALLABLE(reverse_copy, impl::reverse_copy, 2)
1151     BOOST_PHOENIX_ADAPT_CALLABLE(rotate, impl::rotate, 2)
1152     BOOST_PHOENIX_ADAPT_CALLABLE(rotate_copy, impl::rotate_copy, 3)
1153 #ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE
1154     BOOST_PHOENIX_ADAPT_CALLABLE(random_shuffle, impl::random_shuffle, 1)
1155     BOOST_PHOENIX_ADAPT_CALLABLE(random_shuffle, impl::random_shuffle, 2)
1156 #endif
1157     BOOST_PHOENIX_ADAPT_CALLABLE(partition, impl::partition, 2)
1158     BOOST_PHOENIX_ADAPT_CALLABLE(stable_partition, impl::stable_partition, 2)
1159     BOOST_PHOENIX_ADAPT_CALLABLE(sort, impl::sort, 1)
1160     BOOST_PHOENIX_ADAPT_CALLABLE(sort, impl::sort, 2)
1161     BOOST_PHOENIX_ADAPT_CALLABLE(stable_sort, impl::stable_sort, 1)
1162     BOOST_PHOENIX_ADAPT_CALLABLE(stable_sort, impl::stable_sort, 2)
1163     BOOST_PHOENIX_ADAPT_CALLABLE(partial_sort, impl::partial_sort, 2)
1164     BOOST_PHOENIX_ADAPT_CALLABLE(partial_sort, impl::partial_sort, 3)
1165     BOOST_PHOENIX_ADAPT_CALLABLE(partial_sort_copy, impl::partial_sort_copy, 2)
1166     BOOST_PHOENIX_ADAPT_CALLABLE(partial_sort_copy, impl::partial_sort_copy, 3)
1167     BOOST_PHOENIX_ADAPT_CALLABLE(nth_element, impl::nth_element, 2)
1168     BOOST_PHOENIX_ADAPT_CALLABLE(nth_element, impl::nth_element, 3)
1169     BOOST_PHOENIX_ADAPT_CALLABLE(merge, impl::merge, 3)
1170     BOOST_PHOENIX_ADAPT_CALLABLE(merge, impl::merge, 4)
1171     BOOST_PHOENIX_ADAPT_CALLABLE(inplace_merge, impl::inplace_merge, 2)
1172     BOOST_PHOENIX_ADAPT_CALLABLE(inplace_merge, impl::inplace_merge, 3)
1173     BOOST_PHOENIX_ADAPT_CALLABLE(next_permutation, impl::next_permutation, 1)
1174     BOOST_PHOENIX_ADAPT_CALLABLE(next_permutation, impl::next_permutation, 2)
1175     BOOST_PHOENIX_ADAPT_CALLABLE(prev_permutation, impl::prev_permutation, 1)
1176     BOOST_PHOENIX_ADAPT_CALLABLE(prev_permutation, impl::prev_permutation, 2)
1177     BOOST_PHOENIX_ADAPT_CALLABLE(inner_product, impl::inner_product, 3)
1178     BOOST_PHOENIX_ADAPT_CALLABLE(inner_product, impl::inner_product, 5)
1179     BOOST_PHOENIX_ADAPT_CALLABLE(partial_sum, impl::partial_sum, 2)
1180     BOOST_PHOENIX_ADAPT_CALLABLE(partial_sum, impl::partial_sum, 3)
1181     BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_difference, impl::adjacent_difference, 2)
1182     BOOST_PHOENIX_ADAPT_CALLABLE(adjacent_difference, impl::adjacent_difference, 3)
1183     BOOST_PHOENIX_ADAPT_CALLABLE(push_heap, impl::push_heap, 1)
1184     BOOST_PHOENIX_ADAPT_CALLABLE(push_heap, impl::push_heap, 2)
1185     BOOST_PHOENIX_ADAPT_CALLABLE(pop_heap, impl::pop_heap, 1)
1186     BOOST_PHOENIX_ADAPT_CALLABLE(pop_heap, impl::pop_heap, 2)
1187     BOOST_PHOENIX_ADAPT_CALLABLE(make_heap, impl::make_heap, 1)
1188     BOOST_PHOENIX_ADAPT_CALLABLE(make_heap, impl::make_heap, 2)
1189     BOOST_PHOENIX_ADAPT_CALLABLE(sort_heap, impl::sort_heap, 1)
1190     BOOST_PHOENIX_ADAPT_CALLABLE(sort_heap, impl::sort_heap, 2)
1191     BOOST_PHOENIX_ADAPT_CALLABLE(set_union, impl::set_union, 3)
1192     BOOST_PHOENIX_ADAPT_CALLABLE(set_union, impl::set_union, 4)
1193     BOOST_PHOENIX_ADAPT_CALLABLE(set_intersection, impl::set_intersection, 3)
1194     BOOST_PHOENIX_ADAPT_CALLABLE(set_intersection, impl::set_intersection, 4)
1195     BOOST_PHOENIX_ADAPT_CALLABLE(set_difference, impl::set_difference, 3)
1196     BOOST_PHOENIX_ADAPT_CALLABLE(set_difference, impl::set_difference, 4)
1197     BOOST_PHOENIX_ADAPT_CALLABLE(set_symmetric_difference, impl::set_symmetric_difference, 3)
1198     BOOST_PHOENIX_ADAPT_CALLABLE(set_symmetric_difference, impl::set_symmetric_difference, 4)
1199 }}
1200 
1201 #endif
1202