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