]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/parallel/algobase.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / parallel / algobase.h
CommitLineData
6482a45c 1// -*- C++ -*-
2
f1717362 3// Copyright (C) 2007-2016 Free Software Foundation, Inc.
6482a45c 4//
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
6bc9506f 8// Foundation; either version 3, or (at your option) any later
6482a45c 9// version.
10
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.
15
6bc9506f 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.
19
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/>.
6482a45c 24
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.
32 */
33
34// Written by Johannes Singler and Felix Putze.
35
36#ifndef _GLIBCXX_PARALLEL_ALGOBASE_H
37#define _GLIBCXX_PARALLEL_ALGOBASE_H 1
38
6482a45c 39#include <bits/stl_algobase.h>
40#include <parallel/base.h>
c859a23c 41#include <parallel/algorithmfwd.h>
6482a45c 42#include <parallel/find.h>
43#include <parallel/find_selectors.h>
6482a45c 44
2948dd21 45namespace std _GLIBCXX_VISIBILITY(default)
6482a45c 46{
47namespace __parallel
48{
53bd33f6 49 // NB: equal and lexicographical_compare require mismatch.
6482a45c 50
51 // Sequential fallback
34475802 52 template<typename _IIter1, typename _IIter2>
53 inline pair<_IIter1, _IIter2>
54 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
84ec5566 55 __gnu_parallel::sequential_tag)
2948dd21 56 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); }
6482a45c 57
58 // Sequential fallback
84ec5566 59 template<typename _IIter1, typename _IIter2, typename _Predicate>
34475802 60 inline pair<_IIter1, _IIter2>
61 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
84ec5566 62 _Predicate __pred, __gnu_parallel::sequential_tag)
2948dd21 63 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
6482a45c 64
65 // Sequential fallback for input iterator case
34475802 66 template<typename _IIter1, typename _IIter2,
84ec5566 67 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
34475802 68 inline pair<_IIter1, _IIter2>
84ec5566 69 __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
70 _Predicate __pred, _IteratorTag1, _IteratorTag2)
2948dd21 71 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); }
6482a45c 72
73 // Parallel mismatch for random access iterators
84ec5566 74 template<typename _RAIter1, typename _RAIter2, typename _Predicate>
34475802 75 pair<_RAIter1, _RAIter2>
76 __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
84ec5566 77 _RAIter2 __begin2, _Predicate __pred,
78 random_access_iterator_tag, random_access_iterator_tag)
0be20f8a 79 {
80 if (_GLIBCXX_PARALLEL_CONDITION(true))
84ec5566 81 {
82 _RAIter1 __res =
83 __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
84 __gnu_parallel::
85 __mismatch_selector()).first;
86 return make_pair(__res , __begin2 + (__res - __begin1));
87 }
0be20f8a 88 else
2948dd21 89 return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred);
0be20f8a 90 }
6482a45c 91
92 // Public interface
34475802 93 template<typename _IIter1, typename _IIter2>
94 inline pair<_IIter1, _IIter2>
95 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
0be20f8a 96 {
ece877c5 97 typedef __gnu_parallel::_EqualTo<
98 typename std::iterator_traits<_IIter1>::value_type,
99 typename std::iterator_traits<_IIter2>::value_type> _EqualTo;
0be20f8a 100
30238171 101 return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(),
ece877c5 102 std::__iterator_category(__begin1),
103 std::__iterator_category(__begin2));
0be20f8a 104 }
6482a45c 105
106 // Public interface
84ec5566 107 template<typename _IIter1, typename _IIter2, typename _Predicate>
34475802 108 inline pair<_IIter1, _IIter2>
109 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
84ec5566 110 _Predicate __pred)
0be20f8a 111 {
84ec5566 112 return __mismatch_switch(__begin1, __end1, __begin2, __pred,
ece877c5 113 std::__iterator_category(__begin1),
114 std::__iterator_category(__begin2));
0be20f8a 115 }
6482a45c 116
d6afb235 117#if __cplusplus > 201103L
ece877c5 118 // Sequential fallback.
d6afb235 119 template<typename _InputIterator1, typename _InputIterator2>
120 inline pair<_InputIterator1, _InputIterator2>
121 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
ece877c5 122 _InputIterator2 __first2, _InputIterator2 __last2,
123 __gnu_parallel::sequential_tag)
d6afb235 124 { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); }
125
ece877c5 126 // Sequential fallback.
d6afb235 127 template<typename _InputIterator1, typename _InputIterator2,
128 typename _BinaryPredicate>
129 inline pair<_InputIterator1, _InputIterator2>
130 mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
131 _InputIterator2 __first2, _InputIterator2 __last2,
ece877c5 132 _BinaryPredicate __binary_pred,
133 __gnu_parallel::sequential_tag)
d6afb235 134 {
135 return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2,
136 __binary_pred);
137 }
ece877c5 138
139 // Sequential fallback for input iterator case
140 template<typename _IIter1, typename _IIter2,
141 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
142 inline pair<_IIter1, _IIter2>
143 __mismatch_switch(_IIter1 __begin1, _IIter1 __end1,
144 _IIter2 __begin2, _IIter2 __end2, _Predicate __pred,
145 _IteratorTag1, _IteratorTag2)
146 {
147 return _GLIBCXX_STD_A::mismatch(__begin1, __end1,
148 __begin2, __end2, __pred);
149 }
150
151 // Parallel mismatch for random access iterators
152 template<typename _RAIter1, typename _RAIter2, typename _Predicate>
153 pair<_RAIter1, _RAIter2>
154 __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
155 _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred,
156 random_access_iterator_tag, random_access_iterator_tag)
157 {
158 if (_GLIBCXX_PARALLEL_CONDITION(true))
159 {
160 if ((__end2 - __begin2) < (__end1 - __begin1))
161 __end1 = __begin1 + (__end2 - __begin2);
162
163 _RAIter1 __res =
164 __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
165 __gnu_parallel::
166 __mismatch_selector()).first;
167 return make_pair(__res , __begin2 + (__res - __begin1));
168 }
169 else
170 return _GLIBCXX_STD_A::mismatch(__begin1, __end1,
171 __begin2, __end2, __pred);
172 }
173
174 template<typename _IIter1, typename _IIter2>
175 inline pair<_IIter1, _IIter2>
176 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2)
177 {
178 typedef __gnu_parallel::_EqualTo<
179 typename std::iterator_traits<_IIter1>::value_type,
180 typename std::iterator_traits<_IIter2>::value_type> _EqualTo;
181
182 return __mismatch_switch(__begin1, __end1, __begin2, __end2, _EqualTo(),
183 std::__iterator_category(__begin1),
184 std::__iterator_category(__begin2));
185 }
186
187 template<typename _InputIterator1, typename _InputIterator2,
188 typename _BinaryPredicate>
189 inline pair<_InputIterator1, _InputIterator2>
190 mismatch(_InputIterator1 __begin1, _InputIterator1 __end1,
191 _InputIterator2 __begin2, _InputIterator2 __end2,
192 _BinaryPredicate __binary_pred)
193 {
194 return __mismatch_switch(__begin1, __end1, __begin2, __end2,
195 __binary_pred,
196 std::__iterator_category(__begin1),
197 std::__iterator_category(__begin2));
198 }
d6afb235 199#endif
200
53bd33f6 201 // Sequential fallback
34475802 202 template<typename _IIter1, typename _IIter2>
0be20f8a 203 inline bool
34475802 204 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
84ec5566 205 __gnu_parallel::sequential_tag)
2948dd21 206 { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); }
53bd33f6 207
208 // Sequential fallback
84ec5566 209 template<typename _IIter1, typename _IIter2, typename _Predicate>
0be20f8a 210 inline bool
34475802 211 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
84ec5566 212 _Predicate __pred, __gnu_parallel::sequential_tag)
2948dd21 213 { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); }
53bd33f6 214
215 // Public interface
34475802 216 template<typename _IIter1, typename _IIter2>
0be20f8a 217 inline bool
34475802 218 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
ab672a7f 219 {
49edb39c 220 return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first
221 == __end1;
ab672a7f 222 }
53bd33f6 223
224 // Public interface
84ec5566 225 template<typename _IIter1, typename _IIter2, typename _Predicate>
0be20f8a 226 inline bool
34475802 227 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
84ec5566 228 _Predicate __pred)
ab672a7f 229 {
49edb39c 230 return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first
231 == __end1;
ab672a7f 232 }
53bd33f6 233
d6afb235 234#if __cplusplus > 201103L
ece877c5 235 // Sequential fallback
236 template<typename _IIter1, typename _IIter2>
d6afb235 237 inline bool
ece877c5 238 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
239 __gnu_parallel::sequential_tag)
240 {
241 return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2);
242 }
d6afb235 243
ece877c5 244 // Sequential fallback
d6afb235 245 template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
246 inline bool
ece877c5 247 equal(_IIter1 __begin1, _IIter1 __end1,
248 _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred,
249 __gnu_parallel::sequential_tag)
d6afb235 250 {
ece877c5 251 return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2,
d6afb235 252 __binary_pred);
253 }
ece877c5 254
255 // Sequential fallback for input iterator case
256 template<typename _IIter1, typename _IIter2,
257 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
258 inline bool
259 __equal_switch(_IIter1 __begin1, _IIter1 __end1,
260 _IIter2 __begin2, _IIter2 __end2, _Predicate __pred,
261 _IteratorTag1, _IteratorTag2)
262 {
263 return _GLIBCXX_STD_A::equal(__begin1, __end1,
264 __begin2, __end2, __pred);
265 }
266
267 // Parallel equal for random access iterators
268 template<typename _RAIter1, typename _RAIter2, typename _Predicate>
269 inline bool
270 __equal_switch(_RAIter1 __begin1, _RAIter1 __end1,
271 _RAIter2 __begin2, _RAIter2 __end2, _Predicate __pred,
272 random_access_iterator_tag, random_access_iterator_tag)
273 {
274 if (_GLIBCXX_PARALLEL_CONDITION(true))
275 {
276 if (std::distance(__begin1, __end1)
277 != std::distance(__begin2, __end2))
278 return false;
279
280 return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __end2,
281 __pred).first == __end1;
282 }
283 else
284 return _GLIBCXX_STD_A::equal(__begin1, __end1,
285 __begin2, __end2, __pred);
286 }
287
288 template<typename _IIter1, typename _IIter2>
289 inline bool
290 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2)
291 {
292 typedef __gnu_parallel::_EqualTo<
293 typename std::iterator_traits<_IIter1>::value_type,
294 typename std::iterator_traits<_IIter2>::value_type> _EqualTo;
295
296 return __equal_switch(__begin1, __end1, __begin2, __end2, _EqualTo(),
297 std::__iterator_category(__begin1),
298 std::__iterator_category(__begin2));
299 }
300
301 template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
302 inline bool
303 equal(_IIter1 __begin1, _IIter1 __end1,
304 _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred)
305 {
306 return __equal_switch(__begin1, __end1, __begin2, __end2, __binary_pred,
307 std::__iterator_category(__begin1),
308 std::__iterator_category(__begin2));
309 }
d6afb235 310#endif
311
6482a45c 312 // Sequential fallback
34475802 313 template<typename _IIter1, typename _IIter2>
0be20f8a 314 inline bool
34475802 315 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
84ec5566 316 _IIter2 __begin2, _IIter2 __end2,
317 __gnu_parallel::sequential_tag)
2948dd21 318 { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1,
84ec5566 319 __begin2, __end2); }
6482a45c 320
321 // Sequential fallback
84ec5566 322 template<typename _IIter1, typename _IIter2, typename _Predicate>
0be20f8a 323 inline bool
34475802 324 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
84ec5566 325 _IIter2 __begin2, _IIter2 __end2,
326 _Predicate __pred, __gnu_parallel::sequential_tag)
2948dd21 327 { return _GLIBCXX_STD_A::lexicographical_compare(
84ec5566 328 __begin1, __end1, __begin2, __end2, __pred); }
6482a45c 329
330 // Sequential fallback for input iterator case
34475802 331 template<typename _IIter1, typename _IIter2,
84ec5566 332 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
0be20f8a 333 inline bool
84ec5566 334 __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
335 _IIter2 __begin2, _IIter2 __end2,
336 _Predicate __pred,
337 _IteratorTag1, _IteratorTag2)
2948dd21 338 { return _GLIBCXX_STD_A::lexicographical_compare(
84ec5566 339 __begin1, __end1, __begin2, __end2, __pred); }
6482a45c 340
341 // Parallel lexicographical_compare for random access iterators
342 // Limitation: Both valuetypes must be the same
84ec5566 343 template<typename _RAIter1, typename _RAIter2, typename _Predicate>
0be20f8a 344 bool
84ec5566 345 __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1,
346 _RAIter2 __begin2, _RAIter2 __end2,
347 _Predicate __pred,
348 random_access_iterator_tag,
349 random_access_iterator_tag)
0be20f8a 350 {
351 if (_GLIBCXX_PARALLEL_CONDITION(true))
84ec5566 352 {
353 typedef iterator_traits<_RAIter1> _TraitsType1;
354 typedef typename _TraitsType1::value_type _ValueType1;
355
356 typedef iterator_traits<_RAIter2> _TraitsType2;
357 typedef typename _TraitsType2::value_type _ValueType2;
358
359 typedef __gnu_parallel::
f69659cc 360 _EqualFromLess<_ValueType1, _ValueType2, _Predicate>
84ec5566 361 _EqualFromLessCompare;
362
363 // Longer sequence in first place.
364 if ((__end1 - __begin1) < (__end2 - __begin2))
365 {
366 typedef pair<_RAIter1, _RAIter2> _SpotType;
367 _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2,
368 _EqualFromLessCompare(__pred),
369 random_access_iterator_tag(),
370 random_access_iterator_tag());
371
372 return (__mm.first == __end1)
373 || bool(__pred(*__mm.first, *__mm.second));
374 }
375 else
376 {
377 typedef pair<_RAIter2, _RAIter1> _SpotType;
378 _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1,
379 _EqualFromLessCompare(__pred),
380 random_access_iterator_tag(),
381 random_access_iterator_tag());
382
383 return (__mm.first != __end2)
384 && bool(__pred(*__mm.second, *__mm.first));
385 }
386 }
0be20f8a 387 else
2948dd21 388 return _GLIBCXX_STD_A::lexicographical_compare(
84ec5566 389 __begin1, __end1, __begin2, __end2, __pred);
0be20f8a 390 }
6482a45c 391
392 // Public interface
34475802 393 template<typename _IIter1, typename _IIter2>
0be20f8a 394 inline bool
34475802 395 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
84ec5566 396 _IIter2 __begin2, _IIter2 __end2)
0be20f8a 397 {
34475802 398 typedef iterator_traits<_IIter1> _TraitsType1;
399 typedef typename _TraitsType1::value_type _ValueType1;
400 typedef typename _TraitsType1::iterator_category _IteratorCategory1;
401
402 typedef iterator_traits<_IIter2> _TraitsType2;
403 typedef typename _TraitsType2::value_type _ValueType2;
404 typedef typename _TraitsType2::iterator_category _IteratorCategory2;
405 typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType;
406
84ec5566 407 return __lexicographical_compare_switch(
408 __begin1, __end1, __begin2, __end2, _LessType(),
409 _IteratorCategory1(), _IteratorCategory2());
0be20f8a 410 }
6482a45c 411
412 // Public interface
84ec5566 413 template<typename _IIter1, typename _IIter2, typename _Predicate>
0be20f8a 414 inline bool
34475802 415 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
84ec5566 416 _IIter2 __begin2, _IIter2 __end2,
417 _Predicate __pred)
0be20f8a 418 {
34475802 419 typedef iterator_traits<_IIter1> _TraitsType1;
420 typedef typename _TraitsType1::iterator_category _IteratorCategory1;
0be20f8a 421
34475802 422 typedef iterator_traits<_IIter2> _TraitsType2;
423 typedef typename _TraitsType2::iterator_category _IteratorCategory2;
0be20f8a 424
84ec5566 425 return __lexicographical_compare_switch(
426 __begin1, __end1, __begin2, __end2, __pred,
427 _IteratorCategory1(), _IteratorCategory2());
0be20f8a 428 }
6482a45c 429} // end namespace
430} // end namespace
431
a8aa9db5 432#endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */