Import GCC-8 to a new vendor branch
[dragonfly.git] / contrib / gcc-8.0 / libstdc++-v3 / include / parallel / algobase.h
1 // -*- C++ -*-
2
3 // Copyright (C) 2007-2018 Free Software Foundation, Inc.
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
8 // Foundation; either version 3, or (at your option) any later
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
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/>.
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
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>
44
45 namespace std _GLIBCXX_VISIBILITY(default)
46 {
47 namespace __parallel
48 {
49   // NB: equal and lexicographical_compare require mismatch.
50
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); }
57
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); }
64
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); }
72
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)
79     {
80       if (_GLIBCXX_PARALLEL_CONDITION(true))
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         }
88       else
89         return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred);
90     }
91
92   // Public interface
93   template<typename _IIter1, typename _IIter2>
94     inline pair<_IIter1, _IIter2>
95     mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
96     {
97       typedef __gnu_parallel::_EqualTo<
98         typename std::iterator_traits<_IIter1>::value_type,
99         typename std::iterator_traits<_IIter2>::value_type> _EqualTo;
100
101       return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(),
102                                std::__iterator_category(__begin1),
103                                std::__iterator_category(__begin2));
104     }
105
106   // Public interface
107   template<typename _IIter1, typename _IIter2, typename _Predicate>
108     inline pair<_IIter1, _IIter2>
109     mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
110              _Predicate __pred)
111     {
112       return __mismatch_switch(__begin1, __end1, __begin2, __pred,
113                                std::__iterator_category(__begin1),
114                                std::__iterator_category(__begin2));
115     }
116
117 #if __cplusplus > 201103L
118   // Sequential fallback.
119   template<typename _InputIterator1, typename _InputIterator2>
120     inline pair<_InputIterator1, _InputIterator2>
121     mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
122              _InputIterator2 __first2, _InputIterator2 __last2,
123              __gnu_parallel::sequential_tag)
124     { return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2); }
125
126   // Sequential fallback.
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,
132              _BinaryPredicate __binary_pred,
133              __gnu_parallel::sequential_tag)
134     {
135       return _GLIBCXX_STD_A::mismatch(__first1, __last1, __first2, __last2,
136                                       __binary_pred);
137     }
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     }
199 #endif
200
201   // Sequential fallback
202   template<typename _IIter1, typename _IIter2>
203     inline bool
204     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
205           __gnu_parallel::sequential_tag)
206     { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); }
207
208   // Sequential fallback
209   template<typename _IIter1, typename _IIter2, typename _Predicate>
210     inline bool
211     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
212           _Predicate __pred, __gnu_parallel::sequential_tag)
213     { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); }
214
215   // Public interface
216   template<typename _IIter1, typename _IIter2>
217     inline bool
218     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
219     {
220       return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first
221               == __end1;
222     }
223
224   // Public interface
225   template<typename _IIter1, typename _IIter2, typename _Predicate>
226     inline bool
227     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
228           _Predicate __pred)
229     {
230       return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first
231               == __end1;
232     }
233
234 #if __cplusplus > 201103L
235   // Sequential fallback
236   template<typename _IIter1, typename _IIter2>
237     inline bool
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     }
243
244   // Sequential fallback
245   template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
246     inline bool
247     equal(_IIter1 __begin1, _IIter1 __end1,
248           _IIter2 __begin2, _IIter2 __end2, _BinaryPredicate __binary_pred,
249           __gnu_parallel::sequential_tag)
250     {
251       return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __end2,
252                                    __binary_pred);
253     }
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     }
310 #endif
311
312   // Sequential fallback
313   template<typename _IIter1, typename _IIter2>
314     inline bool
315     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 
316                             _IIter2 __begin2, _IIter2 __end2, 
317                             __gnu_parallel::sequential_tag)
318     { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1,
319                                                      __begin2, __end2); }
320
321   // Sequential fallback
322   template<typename _IIter1, typename _IIter2, typename _Predicate>
323     inline bool
324     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 
325                             _IIter2 __begin2, _IIter2 __end2, 
326                             _Predicate __pred, __gnu_parallel::sequential_tag)
327     { return _GLIBCXX_STD_A::lexicographical_compare(
328                __begin1, __end1, __begin2, __end2, __pred); }
329
330   // Sequential fallback for input iterator case
331   template<typename _IIter1, typename _IIter2,
332            typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
333     inline bool
334     __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
335                                      _IIter2 __begin2, _IIter2 __end2, 
336                                      _Predicate __pred,
337                                      _IteratorTag1, _IteratorTag2)
338     { return _GLIBCXX_STD_A::lexicographical_compare(
339                __begin1, __end1, __begin2, __end2, __pred); }
340
341   // Parallel lexicographical_compare for random access iterators
342   // Limitation: Both valuetypes must be the same
343   template<typename _RAIter1, typename _RAIter2, typename _Predicate>
344     bool
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)
350     {
351       if (_GLIBCXX_PARALLEL_CONDITION(true))
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::
360                   _EqualFromLess<_ValueType1, _ValueType2, _Predicate>
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         }
387       else
388         return _GLIBCXX_STD_A::lexicographical_compare(
389                  __begin1, __end1, __begin2, __end2, __pred);
390     }
391
392   // Public interface
393   template<typename _IIter1, typename _IIter2>
394     inline bool
395     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
396                             _IIter2 __begin2, _IIter2 __end2)
397     {
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
407       return __lexicographical_compare_switch(
408                __begin1, __end1, __begin2, __end2, _LessType(),
409                _IteratorCategory1(), _IteratorCategory2());
410     }
411
412   // Public interface
413   template<typename _IIter1, typename _IIter2, typename _Predicate>
414     inline bool
415     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
416                             _IIter2 __begin2, _IIter2 __end2,
417                             _Predicate __pred)
418     {
419       typedef iterator_traits<_IIter1> _TraitsType1;
420       typedef typename _TraitsType1::iterator_category _IteratorCategory1;
421
422       typedef iterator_traits<_IIter2> _TraitsType2;
423       typedef typename _TraitsType2::iterator_category _IteratorCategory2;
424
425       return __lexicographical_compare_switch(
426                __begin1, __end1, __begin2, __end2, __pred,
427                _IteratorCategory1(), _IteratorCategory2());
428     }
429 } // end namespace
430 } // end namespace
431
432 #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */