1*e4b17023SJohn Marino // -*- C++ -*-
2*e4b17023SJohn Marino
3*e4b17023SJohn Marino // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4*e4b17023SJohn Marino //
5*e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free
6*e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the terms
7*e4b17023SJohn Marino // of the GNU General Public License as published by the Free Software
8*e4b17023SJohn Marino // Foundation; either version 3, or (at your option) any later
9*e4b17023SJohn Marino // version.
10*e4b17023SJohn Marino
11*e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, but
12*e4b17023SJohn Marino // WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*e4b17023SJohn Marino // General Public License for more details.
15*e4b17023SJohn Marino
16*e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino
20*e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23*e4b17023SJohn Marino // <http://www.gnu.org/licenses/>.
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino /** @file parallel/algobase.h
26*e4b17023SJohn Marino * @brief Parallel STL function calls corresponding to the
27*e4b17023SJohn Marino * stl_algobase.h header. The functions defined here mainly do case
28*e4b17023SJohn Marino * switches and call the actual parallelized versions in other files.
29*e4b17023SJohn Marino * Inlining policy: Functions that basically only contain one
30*e4b17023SJohn Marino * function call, are declared inline.
31*e4b17023SJohn Marino * This file is a GNU parallel extension to the Standard C++ Library.
32*e4b17023SJohn Marino */
33*e4b17023SJohn Marino
34*e4b17023SJohn Marino // Written by Johannes Singler and Felix Putze.
35*e4b17023SJohn Marino
36*e4b17023SJohn Marino #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H
37*e4b17023SJohn Marino #define _GLIBCXX_PARALLEL_ALGOBASE_H 1
38*e4b17023SJohn Marino
39*e4b17023SJohn Marino #include <bits/stl_algobase.h>
40*e4b17023SJohn Marino #include <parallel/base.h>
41*e4b17023SJohn Marino #include <parallel/algorithmfwd.h>
42*e4b17023SJohn Marino #include <parallel/find.h>
43*e4b17023SJohn Marino #include <parallel/find_selectors.h>
44*e4b17023SJohn Marino
_GLIBCXX_VISIBILITY(default)45*e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default)
46*e4b17023SJohn Marino {
47*e4b17023SJohn Marino namespace __parallel
48*e4b17023SJohn Marino {
49*e4b17023SJohn Marino // NB: equal and lexicographical_compare require mismatch.
50*e4b17023SJohn Marino
51*e4b17023SJohn Marino // Sequential fallback
52*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2>
53*e4b17023SJohn Marino inline pair<_IIter1, _IIter2>
54*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
55*e4b17023SJohn Marino __gnu_parallel::sequential_tag)
56*e4b17023SJohn Marino { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); }
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino // Sequential fallback
59*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate>
60*e4b17023SJohn Marino inline pair<_IIter1, _IIter2>
61*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
62*e4b17023SJohn Marino _Predicate __pred, __gnu_parallel::sequential_tag)
63*e4b17023SJohn Marino { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
64*e4b17023SJohn Marino
65*e4b17023SJohn Marino // Sequential fallback for input iterator case
66*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2,
67*e4b17023SJohn Marino typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
68*e4b17023SJohn Marino inline pair<_IIter1, _IIter2>
69*e4b17023SJohn Marino __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
70*e4b17023SJohn Marino _Predicate __pred, _IteratorTag1, _IteratorTag2)
71*e4b17023SJohn Marino { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino // Parallel mismatch for random access iterators
74*e4b17023SJohn Marino template<typename _RAIter1, typename _RAIter2, typename _Predicate>
75*e4b17023SJohn Marino pair<_RAIter1, _RAIter2>
76*e4b17023SJohn Marino __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
77*e4b17023SJohn Marino _RAIter2 __begin2, _Predicate __pred,
78*e4b17023SJohn Marino random_access_iterator_tag, random_access_iterator_tag)
79*e4b17023SJohn Marino {
80*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION(true))
81*e4b17023SJohn Marino {
82*e4b17023SJohn Marino _RAIter1 __res =
83*e4b17023SJohn Marino __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
84*e4b17023SJohn Marino __gnu_parallel::
85*e4b17023SJohn Marino __mismatch_selector()).first;
86*e4b17023SJohn Marino return make_pair(__res , __begin2 + (__res - __begin1));
87*e4b17023SJohn Marino }
88*e4b17023SJohn Marino else
89*e4b17023SJohn Marino return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred);
90*e4b17023SJohn Marino }
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino // Public interface
93*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2>
94*e4b17023SJohn Marino inline pair<_IIter1, _IIter2>
95*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
96*e4b17023SJohn Marino {
97*e4b17023SJohn Marino typedef std::iterator_traits<_IIter1> _Iterator1Traits;
98*e4b17023SJohn Marino typedef std::iterator_traits<_IIter2> _Iterator2Traits;
99*e4b17023SJohn Marino typedef typename _Iterator1Traits::value_type _ValueType1;
100*e4b17023SJohn Marino typedef typename _Iterator2Traits::value_type _ValueType2;
101*e4b17023SJohn Marino typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
102*e4b17023SJohn Marino typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
103*e4b17023SJohn Marino
104*e4b17023SJohn Marino typedef __gnu_parallel::_EqualTo<_ValueType1, _ValueType2> _EqualTo;
105*e4b17023SJohn Marino
106*e4b17023SJohn Marino return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(),
107*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2());
108*e4b17023SJohn Marino }
109*e4b17023SJohn Marino
110*e4b17023SJohn Marino // Public interface
111*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate>
112*e4b17023SJohn Marino inline pair<_IIter1, _IIter2>
113*e4b17023SJohn Marino mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
114*e4b17023SJohn Marino _Predicate __pred)
115*e4b17023SJohn Marino {
116*e4b17023SJohn Marino typedef std::iterator_traits<_IIter1> _Iterator1Traits;
117*e4b17023SJohn Marino typedef std::iterator_traits<_IIter2> _Iterator2Traits;
118*e4b17023SJohn Marino typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
119*e4b17023SJohn Marino typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
120*e4b17023SJohn Marino
121*e4b17023SJohn Marino return __mismatch_switch(__begin1, __end1, __begin2, __pred,
122*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2());
123*e4b17023SJohn Marino }
124*e4b17023SJohn Marino
125*e4b17023SJohn Marino // Sequential fallback
126*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2>
127*e4b17023SJohn Marino inline bool
128*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
129*e4b17023SJohn Marino __gnu_parallel::sequential_tag)
130*e4b17023SJohn Marino { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); }
131*e4b17023SJohn Marino
132*e4b17023SJohn Marino // Sequential fallback
133*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate>
134*e4b17023SJohn Marino inline bool
135*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
136*e4b17023SJohn Marino _Predicate __pred, __gnu_parallel::sequential_tag)
137*e4b17023SJohn Marino { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); }
138*e4b17023SJohn Marino
139*e4b17023SJohn Marino // Public interface
140*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2>
141*e4b17023SJohn Marino inline bool
142*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
143*e4b17023SJohn Marino {
144*e4b17023SJohn Marino return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first
145*e4b17023SJohn Marino == __end1;
146*e4b17023SJohn Marino }
147*e4b17023SJohn Marino
148*e4b17023SJohn Marino // Public interface
149*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate>
150*e4b17023SJohn Marino inline bool
151*e4b17023SJohn Marino equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
152*e4b17023SJohn Marino _Predicate __pred)
153*e4b17023SJohn Marino {
154*e4b17023SJohn Marino return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first
155*e4b17023SJohn Marino == __end1;
156*e4b17023SJohn Marino }
157*e4b17023SJohn Marino
158*e4b17023SJohn Marino // Sequential fallback
159*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2>
160*e4b17023SJohn Marino inline bool
161*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
162*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2,
163*e4b17023SJohn Marino __gnu_parallel::sequential_tag)
164*e4b17023SJohn Marino { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1,
165*e4b17023SJohn Marino __begin2, __end2); }
166*e4b17023SJohn Marino
167*e4b17023SJohn Marino // Sequential fallback
168*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate>
169*e4b17023SJohn Marino inline bool
170*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
171*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2,
172*e4b17023SJohn Marino _Predicate __pred, __gnu_parallel::sequential_tag)
173*e4b17023SJohn Marino { return _GLIBCXX_STD_A::lexicographical_compare(
174*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred); }
175*e4b17023SJohn Marino
176*e4b17023SJohn Marino // Sequential fallback for input iterator case
177*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2,
178*e4b17023SJohn Marino typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
179*e4b17023SJohn Marino inline bool
180*e4b17023SJohn Marino __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
181*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2,
182*e4b17023SJohn Marino _Predicate __pred,
183*e4b17023SJohn Marino _IteratorTag1, _IteratorTag2)
184*e4b17023SJohn Marino { return _GLIBCXX_STD_A::lexicographical_compare(
185*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred); }
186*e4b17023SJohn Marino
187*e4b17023SJohn Marino // Parallel lexicographical_compare for random access iterators
188*e4b17023SJohn Marino // Limitation: Both valuetypes must be the same
189*e4b17023SJohn Marino template<typename _RAIter1, typename _RAIter2, typename _Predicate>
190*e4b17023SJohn Marino bool
191*e4b17023SJohn Marino __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1,
192*e4b17023SJohn Marino _RAIter2 __begin2, _RAIter2 __end2,
193*e4b17023SJohn Marino _Predicate __pred,
194*e4b17023SJohn Marino random_access_iterator_tag,
195*e4b17023SJohn Marino random_access_iterator_tag)
196*e4b17023SJohn Marino {
197*e4b17023SJohn Marino if (_GLIBCXX_PARALLEL_CONDITION(true))
198*e4b17023SJohn Marino {
199*e4b17023SJohn Marino typedef iterator_traits<_RAIter1> _TraitsType1;
200*e4b17023SJohn Marino typedef typename _TraitsType1::value_type _ValueType1;
201*e4b17023SJohn Marino
202*e4b17023SJohn Marino typedef iterator_traits<_RAIter2> _TraitsType2;
203*e4b17023SJohn Marino typedef typename _TraitsType2::value_type _ValueType2;
204*e4b17023SJohn Marino
205*e4b17023SJohn Marino typedef __gnu_parallel::
206*e4b17023SJohn Marino _EqualFromLess<_ValueType1, _ValueType2, _Predicate>
207*e4b17023SJohn Marino _EqualFromLessCompare;
208*e4b17023SJohn Marino
209*e4b17023SJohn Marino // Longer sequence in first place.
210*e4b17023SJohn Marino if ((__end1 - __begin1) < (__end2 - __begin2))
211*e4b17023SJohn Marino {
212*e4b17023SJohn Marino typedef pair<_RAIter1, _RAIter2> _SpotType;
213*e4b17023SJohn Marino _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2,
214*e4b17023SJohn Marino _EqualFromLessCompare(__pred),
215*e4b17023SJohn Marino random_access_iterator_tag(),
216*e4b17023SJohn Marino random_access_iterator_tag());
217*e4b17023SJohn Marino
218*e4b17023SJohn Marino return (__mm.first == __end1)
219*e4b17023SJohn Marino || bool(__pred(*__mm.first, *__mm.second));
220*e4b17023SJohn Marino }
221*e4b17023SJohn Marino else
222*e4b17023SJohn Marino {
223*e4b17023SJohn Marino typedef pair<_RAIter2, _RAIter1> _SpotType;
224*e4b17023SJohn Marino _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1,
225*e4b17023SJohn Marino _EqualFromLessCompare(__pred),
226*e4b17023SJohn Marino random_access_iterator_tag(),
227*e4b17023SJohn Marino random_access_iterator_tag());
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino return (__mm.first != __end2)
230*e4b17023SJohn Marino && bool(__pred(*__mm.second, *__mm.first));
231*e4b17023SJohn Marino }
232*e4b17023SJohn Marino }
233*e4b17023SJohn Marino else
234*e4b17023SJohn Marino return _GLIBCXX_STD_A::lexicographical_compare(
235*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred);
236*e4b17023SJohn Marino }
237*e4b17023SJohn Marino
238*e4b17023SJohn Marino // Public interface
239*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2>
240*e4b17023SJohn Marino inline bool
241*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
242*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2)
243*e4b17023SJohn Marino {
244*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1;
245*e4b17023SJohn Marino typedef typename _TraitsType1::value_type _ValueType1;
246*e4b17023SJohn Marino typedef typename _TraitsType1::iterator_category _IteratorCategory1;
247*e4b17023SJohn Marino
248*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2;
249*e4b17023SJohn Marino typedef typename _TraitsType2::value_type _ValueType2;
250*e4b17023SJohn Marino typedef typename _TraitsType2::iterator_category _IteratorCategory2;
251*e4b17023SJohn Marino typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType;
252*e4b17023SJohn Marino
253*e4b17023SJohn Marino return __lexicographical_compare_switch(
254*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, _LessType(),
255*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2());
256*e4b17023SJohn Marino }
257*e4b17023SJohn Marino
258*e4b17023SJohn Marino // Public interface
259*e4b17023SJohn Marino template<typename _IIter1, typename _IIter2, typename _Predicate>
260*e4b17023SJohn Marino inline bool
261*e4b17023SJohn Marino lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
262*e4b17023SJohn Marino _IIter2 __begin2, _IIter2 __end2,
263*e4b17023SJohn Marino _Predicate __pred)
264*e4b17023SJohn Marino {
265*e4b17023SJohn Marino typedef iterator_traits<_IIter1> _TraitsType1;
266*e4b17023SJohn Marino typedef typename _TraitsType1::iterator_category _IteratorCategory1;
267*e4b17023SJohn Marino
268*e4b17023SJohn Marino typedef iterator_traits<_IIter2> _TraitsType2;
269*e4b17023SJohn Marino typedef typename _TraitsType2::iterator_category _IteratorCategory2;
270*e4b17023SJohn Marino
271*e4b17023SJohn Marino return __lexicographical_compare_switch(
272*e4b17023SJohn Marino __begin1, __end1, __begin2, __end2, __pred,
273*e4b17023SJohn Marino _IteratorCategory1(), _IteratorCategory2());
274*e4b17023SJohn Marino }
275*e4b17023SJohn Marino } // end namespace
276*e4b17023SJohn Marino } // end namespace
277*e4b17023SJohn Marino
278*e4b17023SJohn Marino #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */
279