xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/parallel/algo.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg // -*- C++ -*-
236ac495dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2007-2020 Free Software Foundation, Inc.
436ac495dSmrg //
536ac495dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
636ac495dSmrg // software; you can redistribute it and/or modify it under the terms
736ac495dSmrg // of the GNU General Public License as published by the Free Software
836ac495dSmrg // Foundation; either version 3, or (at your option) any later
936ac495dSmrg // version.
1036ac495dSmrg 
1136ac495dSmrg // This library is distributed in the hope that it will be useful, but
1236ac495dSmrg // WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1436ac495dSmrg // General Public License for more details.
1536ac495dSmrg 
1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg // 3.1, as published by the Free Software Foundation.
1936ac495dSmrg 
2036ac495dSmrg // You should have received a copy of the GNU General Public License and
2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2336ac495dSmrg // <http://www.gnu.org/licenses/>.
2436ac495dSmrg 
2536ac495dSmrg /** @file parallel/algo.h
2636ac495dSmrg  *  @brief Parallel STL function calls corresponding to the stl_algo.h header.
2736ac495dSmrg  *
2836ac495dSmrg  *  The functions defined here mainly do case switches and
2936ac495dSmrg  *  call the actual parallelized versions in other files.
3036ac495dSmrg  *  Inlining policy: Functions that basically only contain one function call,
3136ac495dSmrg  *  are declared inline.
3236ac495dSmrg  *  This file is a GNU parallel extension to the Standard C++ Library.
3336ac495dSmrg  */
3436ac495dSmrg 
3536ac495dSmrg // Written by Johannes Singler and Felix Putze.
3636ac495dSmrg 
3736ac495dSmrg #ifndef _GLIBCXX_PARALLEL_ALGO_H
3836ac495dSmrg #define _GLIBCXX_PARALLEL_ALGO_H 1
3936ac495dSmrg 
4036ac495dSmrg #include <parallel/algorithmfwd.h>
4136ac495dSmrg #include <bits/stl_algobase.h>
4236ac495dSmrg #include <bits/stl_algo.h>
4336ac495dSmrg #include <parallel/iterator.h>
4436ac495dSmrg #include <parallel/base.h>
4536ac495dSmrg #include <parallel/sort.h>
4636ac495dSmrg #include <parallel/workstealing.h>
4736ac495dSmrg #include <parallel/par_loop.h>
4836ac495dSmrg #include <parallel/omp_loop.h>
4936ac495dSmrg #include <parallel/omp_loop_static.h>
5036ac495dSmrg #include <parallel/for_each_selectors.h>
5136ac495dSmrg #include <parallel/for_each.h>
5236ac495dSmrg #include <parallel/find.h>
5336ac495dSmrg #include <parallel/find_selectors.h>
5436ac495dSmrg #include <parallel/search.h>
5536ac495dSmrg #include <parallel/random_shuffle.h>
5636ac495dSmrg #include <parallel/partition.h>
5736ac495dSmrg #include <parallel/merge.h>
5836ac495dSmrg #include <parallel/unique_copy.h>
5936ac495dSmrg #include <parallel/set_operations.h>
6036ac495dSmrg 
_GLIBCXX_VISIBILITY(default)6136ac495dSmrg namespace std _GLIBCXX_VISIBILITY(default)
6236ac495dSmrg {
6336ac495dSmrg namespace __parallel
6436ac495dSmrg {
6536ac495dSmrg   // Sequential fallback
6636ac495dSmrg   template<typename _IIter, typename _Function>
6736ac495dSmrg     inline _Function
6836ac495dSmrg     for_each(_IIter __begin, _IIter __end, _Function __f,
6936ac495dSmrg 	     __gnu_parallel::sequential_tag)
7036ac495dSmrg     { return _GLIBCXX_STD_A::for_each(__begin, __end, __f); }
7136ac495dSmrg 
7236ac495dSmrg   // Sequential fallback for input iterator case
7336ac495dSmrg   template<typename _IIter, typename _Function, typename _IteratorTag>
7436ac495dSmrg     inline _Function
7536ac495dSmrg     __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
7636ac495dSmrg 		      _IteratorTag)
7736ac495dSmrg     { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
7836ac495dSmrg 
7936ac495dSmrg   // Parallel algorithm for random access iterators
8036ac495dSmrg   template<typename _RAIter, typename _Function>
8136ac495dSmrg     _Function
8236ac495dSmrg     __for_each_switch(_RAIter __begin, _RAIter __end,
8336ac495dSmrg 		      _Function __f, random_access_iterator_tag,
8436ac495dSmrg 		      __gnu_parallel::_Parallelism __parallelism_tag)
8536ac495dSmrg     {
8636ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
8736ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
8836ac495dSmrg 	    >= __gnu_parallel::_Settings::get().for_each_minimal_n
8936ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
9036ac495dSmrg 	{
9136ac495dSmrg 	  bool __dummy;
9236ac495dSmrg 	  __gnu_parallel::__for_each_selector<_RAIter> __functionality;
9336ac495dSmrg 
9436ac495dSmrg 	  return __gnu_parallel::
9536ac495dSmrg 	    __for_each_template_random_access(
9636ac495dSmrg 	      __begin, __end, __f, __functionality,
9736ac495dSmrg 	      __gnu_parallel::_DummyReduct(), true, __dummy, -1,
9836ac495dSmrg 	      __parallelism_tag);
9936ac495dSmrg 	}
10036ac495dSmrg       else
10136ac495dSmrg 	return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
10236ac495dSmrg     }
10336ac495dSmrg 
10436ac495dSmrg   // Public interface
10536ac495dSmrg   template<typename _Iterator, typename _Function>
10636ac495dSmrg     inline _Function
10736ac495dSmrg     for_each(_Iterator __begin, _Iterator __end, _Function __f,
10836ac495dSmrg 	     __gnu_parallel::_Parallelism __parallelism_tag)
10936ac495dSmrg     {
11036ac495dSmrg       return __for_each_switch(__begin, __end, __f,
11136ac495dSmrg 			       std::__iterator_category(__begin),
11236ac495dSmrg 			       __parallelism_tag);
11336ac495dSmrg     }
11436ac495dSmrg 
11536ac495dSmrg   template<typename _Iterator, typename _Function>
11636ac495dSmrg     inline _Function
11736ac495dSmrg     for_each(_Iterator __begin, _Iterator __end, _Function __f)
11836ac495dSmrg     {
11936ac495dSmrg       return __for_each_switch(__begin, __end, __f,
12036ac495dSmrg 			       std::__iterator_category(__begin));
12136ac495dSmrg     }
12236ac495dSmrg 
12336ac495dSmrg   // Sequential fallback
12436ac495dSmrg   template<typename _IIter, typename _Tp>
12536ac495dSmrg     inline _IIter
12636ac495dSmrg     find(_IIter __begin, _IIter __end, const _Tp& __val,
12736ac495dSmrg 	 __gnu_parallel::sequential_tag)
12836ac495dSmrg     { return _GLIBCXX_STD_A::find(__begin, __end, __val); }
12936ac495dSmrg 
13036ac495dSmrg   // Sequential fallback for input iterator case
13136ac495dSmrg   template<typename _IIter, typename _Tp, typename _IteratorTag>
13236ac495dSmrg     inline _IIter
13336ac495dSmrg     __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
13436ac495dSmrg 		_IteratorTag)
13536ac495dSmrg     { return _GLIBCXX_STD_A::find(__begin, __end, __val); }
13636ac495dSmrg 
13736ac495dSmrg   // Parallel find for random access iterators
13836ac495dSmrg   template<typename _RAIter, typename _Tp>
13936ac495dSmrg     _RAIter
14036ac495dSmrg     __find_switch(_RAIter __begin, _RAIter __end,
14136ac495dSmrg 		const _Tp& __val, random_access_iterator_tag)
14236ac495dSmrg     {
14336ac495dSmrg       typedef iterator_traits<_RAIter> _TraitsType;
14436ac495dSmrg       typedef typename _TraitsType::value_type _ValueType;
14536ac495dSmrg 
14636ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(true))
14736ac495dSmrg 	{
14836ac495dSmrg 	  __gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType,
14936ac495dSmrg 							       const _Tp&>,
15036ac495dSmrg 				      _ValueType, const _Tp&, bool>
15136ac495dSmrg 	    __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
15236ac495dSmrg 	  return __gnu_parallel::__find_template(
15336ac495dSmrg 		   __begin, __end, __begin, __comp,
15436ac495dSmrg 		   __gnu_parallel::__find_if_selector()).first;
15536ac495dSmrg 	}
15636ac495dSmrg       else
15736ac495dSmrg 	return _GLIBCXX_STD_A::find(__begin, __end, __val);
15836ac495dSmrg     }
15936ac495dSmrg 
16036ac495dSmrg   // Public interface
16136ac495dSmrg   template<typename _IIter, typename _Tp>
16236ac495dSmrg     inline _IIter
16336ac495dSmrg     find(_IIter __begin, _IIter __end, const _Tp& __val)
16436ac495dSmrg     {
16536ac495dSmrg       return __find_switch(__begin, __end, __val,
16636ac495dSmrg 			   std::__iterator_category(__begin));
16736ac495dSmrg     }
16836ac495dSmrg 
16936ac495dSmrg   // Sequential fallback
17036ac495dSmrg   template<typename _IIter, typename _Predicate>
17136ac495dSmrg     inline _IIter
17236ac495dSmrg     find_if(_IIter __begin, _IIter __end, _Predicate __pred,
17336ac495dSmrg 	    __gnu_parallel::sequential_tag)
17436ac495dSmrg     { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
17536ac495dSmrg 
17636ac495dSmrg   // Sequential fallback for input iterator case
17736ac495dSmrg   template<typename _IIter, typename _Predicate, typename _IteratorTag>
17836ac495dSmrg     inline _IIter
17936ac495dSmrg     __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
18036ac495dSmrg 		   _IteratorTag)
18136ac495dSmrg     { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }
18236ac495dSmrg 
18336ac495dSmrg   // Parallel find_if for random access iterators
18436ac495dSmrg   template<typename _RAIter, typename _Predicate>
18536ac495dSmrg     _RAIter
18636ac495dSmrg     __find_if_switch(_RAIter __begin, _RAIter __end,
18736ac495dSmrg 		   _Predicate __pred, random_access_iterator_tag)
18836ac495dSmrg     {
18936ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(true))
19036ac495dSmrg 	return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
19136ac495dSmrg 					     __gnu_parallel::
19236ac495dSmrg 					     __find_if_selector()).first;
19336ac495dSmrg       else
19436ac495dSmrg 	return _GLIBCXX_STD_A::find_if(__begin, __end, __pred);
19536ac495dSmrg     }
19636ac495dSmrg 
19736ac495dSmrg   // Public interface
19836ac495dSmrg   template<typename _IIter, typename _Predicate>
19936ac495dSmrg     inline _IIter
20036ac495dSmrg     find_if(_IIter __begin, _IIter __end, _Predicate __pred)
20136ac495dSmrg     {
20236ac495dSmrg       return __find_if_switch(__begin, __end, __pred,
20336ac495dSmrg 			      std::__iterator_category(__begin));
20436ac495dSmrg     }
20536ac495dSmrg 
20636ac495dSmrg   // Sequential fallback
20736ac495dSmrg   template<typename _IIter, typename _FIterator>
20836ac495dSmrg     inline _IIter
20936ac495dSmrg     find_first_of(_IIter __begin1, _IIter __end1,
21036ac495dSmrg 		  _FIterator __begin2, _FIterator __end2,
21136ac495dSmrg 		  __gnu_parallel::sequential_tag)
21236ac495dSmrg     {
21336ac495dSmrg       return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2);
21436ac495dSmrg     }
21536ac495dSmrg 
21636ac495dSmrg   // Sequential fallback
21736ac495dSmrg   template<typename _IIter, typename _FIterator,
21836ac495dSmrg 	   typename _BinaryPredicate>
21936ac495dSmrg     inline _IIter
22036ac495dSmrg     find_first_of(_IIter __begin1, _IIter __end1,
22136ac495dSmrg 		  _FIterator __begin2, _FIterator __end2,
22236ac495dSmrg 		  _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
22336ac495dSmrg   { return _GLIBCXX_STD_A::find_first_of(
22436ac495dSmrg 	     __begin1, __end1, __begin2, __end2, __comp); }
22536ac495dSmrg 
22636ac495dSmrg   // Sequential fallback for input iterator type
22736ac495dSmrg   template<typename _IIter, typename _FIterator,
22836ac495dSmrg 	   typename _IteratorTag1, typename _IteratorTag2>
22936ac495dSmrg     inline _IIter
23036ac495dSmrg     __find_first_of_switch(_IIter __begin1, _IIter __end1,
23136ac495dSmrg 			   _FIterator __begin2, _FIterator __end2,
23236ac495dSmrg 			   _IteratorTag1, _IteratorTag2)
23336ac495dSmrg     { return find_first_of(__begin1, __end1, __begin2, __end2,
23436ac495dSmrg 			   __gnu_parallel::sequential_tag()); }
23536ac495dSmrg 
23636ac495dSmrg   // Parallel algorithm for random access iterators
23736ac495dSmrg   template<typename _RAIter, typename _FIterator,
23836ac495dSmrg 	   typename _BinaryPredicate, typename _IteratorTag>
23936ac495dSmrg     inline _RAIter
24036ac495dSmrg     __find_first_of_switch(_RAIter __begin1,
24136ac495dSmrg 			   _RAIter __end1,
24236ac495dSmrg 			   _FIterator __begin2, _FIterator __end2,
24336ac495dSmrg 			   _BinaryPredicate __comp, random_access_iterator_tag,
24436ac495dSmrg 			   _IteratorTag)
24536ac495dSmrg     {
24636ac495dSmrg       return __gnu_parallel::
24736ac495dSmrg 	__find_template(__begin1, __end1, __begin1, __comp,
24836ac495dSmrg 		      __gnu_parallel::__find_first_of_selector
24936ac495dSmrg 		      <_FIterator>(__begin2, __end2)).first;
25036ac495dSmrg     }
25136ac495dSmrg 
25236ac495dSmrg   // Sequential fallback for input iterator type
25336ac495dSmrg   template<typename _IIter, typename _FIterator,
25436ac495dSmrg 	   typename _BinaryPredicate, typename _IteratorTag1,
25536ac495dSmrg 	   typename _IteratorTag2>
25636ac495dSmrg     inline _IIter
25736ac495dSmrg     __find_first_of_switch(_IIter __begin1, _IIter __end1,
25836ac495dSmrg 			   _FIterator __begin2, _FIterator __end2,
25936ac495dSmrg 			   _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
26036ac495dSmrg     { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
26136ac495dSmrg 			   __gnu_parallel::sequential_tag()); }
26236ac495dSmrg 
26336ac495dSmrg   // Public interface
26436ac495dSmrg   template<typename _IIter, typename _FIterator,
26536ac495dSmrg 	   typename _BinaryPredicate>
26636ac495dSmrg     inline _IIter
26736ac495dSmrg     find_first_of(_IIter __begin1, _IIter __end1,
26836ac495dSmrg 		  _FIterator __begin2, _FIterator __end2,
26936ac495dSmrg 		  _BinaryPredicate __comp)
27036ac495dSmrg     {
27136ac495dSmrg       return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
27236ac495dSmrg 				    std::__iterator_category(__begin1),
27336ac495dSmrg 				    std::__iterator_category(__begin2));
27436ac495dSmrg     }
27536ac495dSmrg 
27636ac495dSmrg   // Public interface, insert default comparator
27736ac495dSmrg   template<typename _IIter, typename _FIterator>
27836ac495dSmrg     inline _IIter
27936ac495dSmrg     find_first_of(_IIter __begin1, _IIter __end1,
28036ac495dSmrg 		  _FIterator __begin2, _FIterator __end2)
28136ac495dSmrg     {
28236ac495dSmrg       typedef typename std::iterator_traits<_IIter>::value_type _IValueType;
28336ac495dSmrg       typedef typename std::iterator_traits<_FIterator>::value_type _FValueType;
28436ac495dSmrg 
28536ac495dSmrg       return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2,
28636ac495dSmrg 			 __gnu_parallel::_EqualTo<_IValueType, _FValueType>());
28736ac495dSmrg     }
28836ac495dSmrg 
28936ac495dSmrg   // Sequential fallback
29036ac495dSmrg   template<typename _IIter, typename _OutputIterator>
29136ac495dSmrg     inline _OutputIterator
29236ac495dSmrg     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
29336ac495dSmrg 		__gnu_parallel::sequential_tag)
29436ac495dSmrg     { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); }
29536ac495dSmrg 
29636ac495dSmrg   // Sequential fallback
29736ac495dSmrg   template<typename _IIter, typename _OutputIterator,
29836ac495dSmrg 	   typename _Predicate>
29936ac495dSmrg     inline _OutputIterator
30036ac495dSmrg     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
30136ac495dSmrg 		_Predicate __pred, __gnu_parallel::sequential_tag)
30236ac495dSmrg     { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); }
30336ac495dSmrg 
30436ac495dSmrg   // Sequential fallback for input iterator case
30536ac495dSmrg   template<typename _IIter, typename _OutputIterator,
30636ac495dSmrg 	   typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
30736ac495dSmrg     inline _OutputIterator
30836ac495dSmrg     __unique_copy_switch(_IIter __begin, _IIter __last,
30936ac495dSmrg 		       _OutputIterator __out, _Predicate __pred,
31036ac495dSmrg 		       _IteratorTag1, _IteratorTag2)
31136ac495dSmrg     { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); }
31236ac495dSmrg 
31336ac495dSmrg   // Parallel unique_copy for random access iterators
314*8feb0f0bSmrg   template<typename _RAIter, typename _RandomAccessOutputIterator,
31536ac495dSmrg 	   typename _Predicate>
316*8feb0f0bSmrg     _RandomAccessOutputIterator
31736ac495dSmrg     __unique_copy_switch(_RAIter __begin, _RAIter __last,
318*8feb0f0bSmrg 			 _RandomAccessOutputIterator __out, _Predicate __pred,
31936ac495dSmrg 			 random_access_iterator_tag, random_access_iterator_tag)
32036ac495dSmrg     {
32136ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
32236ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
32336ac495dSmrg 	    > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
32436ac495dSmrg 	return __gnu_parallel::__parallel_unique_copy(
32536ac495dSmrg 		 __begin, __last, __out, __pred);
32636ac495dSmrg       else
32736ac495dSmrg 	return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred);
32836ac495dSmrg     }
32936ac495dSmrg 
33036ac495dSmrg   // Public interface
33136ac495dSmrg   template<typename _IIter, typename _OutputIterator>
33236ac495dSmrg     inline _OutputIterator
33336ac495dSmrg     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
33436ac495dSmrg     {
33536ac495dSmrg       typedef typename std::iterator_traits<_IIter>::value_type _ValueType;
33636ac495dSmrg 
33736ac495dSmrg       return __unique_copy_switch(
33836ac495dSmrg 	       __begin1, __end1, __out, equal_to<_ValueType>(),
33936ac495dSmrg 	       std::__iterator_category(__begin1),
34036ac495dSmrg 	       std::__iterator_category(__out));
34136ac495dSmrg     }
34236ac495dSmrg 
34336ac495dSmrg   // Public interface
34436ac495dSmrg   template<typename _IIter, typename _OutputIterator, typename _Predicate>
34536ac495dSmrg     inline _OutputIterator
34636ac495dSmrg     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
34736ac495dSmrg 		_Predicate __pred)
34836ac495dSmrg     {
34936ac495dSmrg       return __unique_copy_switch(
35036ac495dSmrg 	       __begin1, __end1, __out, __pred,
35136ac495dSmrg 	       std::__iterator_category(__begin1),
35236ac495dSmrg 	       std::__iterator_category(__out));
35336ac495dSmrg     }
35436ac495dSmrg 
35536ac495dSmrg   // Sequential fallback
35636ac495dSmrg   template<typename _IIter1, typename _IIter2,
35736ac495dSmrg 	   typename _OutputIterator>
35836ac495dSmrg     inline _OutputIterator
35936ac495dSmrg     set_union(_IIter1 __begin1, _IIter1 __end1,
36036ac495dSmrg 	      _IIter2 __begin2, _IIter2 __end2,
36136ac495dSmrg 	      _OutputIterator __out, __gnu_parallel::sequential_tag)
36236ac495dSmrg     { return _GLIBCXX_STD_A::set_union(
36336ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out); }
36436ac495dSmrg 
36536ac495dSmrg   // Sequential fallback
36636ac495dSmrg   template<typename _IIter1, typename _IIter2,
36736ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
36836ac495dSmrg     inline _OutputIterator
36936ac495dSmrg     set_union(_IIter1 __begin1, _IIter1 __end1,
37036ac495dSmrg 	      _IIter2 __begin2, _IIter2 __end2,
37136ac495dSmrg 	      _OutputIterator __out, _Predicate __pred,
37236ac495dSmrg 	      __gnu_parallel::sequential_tag)
37336ac495dSmrg     { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
37436ac495dSmrg 				       __begin2, __end2, __out, __pred); }
37536ac495dSmrg 
37636ac495dSmrg   // Sequential fallback for input iterator case
37736ac495dSmrg   template<typename _IIter1, typename _IIter2, typename _Predicate,
37836ac495dSmrg 	   typename _OutputIterator, typename _IteratorTag1,
37936ac495dSmrg 	   typename _IteratorTag2, typename _IteratorTag3>
38036ac495dSmrg     inline _OutputIterator
38136ac495dSmrg     __set_union_switch(
38236ac495dSmrg       _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
38336ac495dSmrg       _OutputIterator __result, _Predicate __pred,
38436ac495dSmrg       _IteratorTag1, _IteratorTag2, _IteratorTag3)
38536ac495dSmrg     { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
38636ac495dSmrg 				       __begin2, __end2, __result, __pred); }
38736ac495dSmrg 
38836ac495dSmrg   // Parallel set_union for random access iterators
38936ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
39036ac495dSmrg 	   typename _Output_RAIter, typename _Predicate>
39136ac495dSmrg     _Output_RAIter
39236ac495dSmrg     __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
39336ac495dSmrg 		       _RAIter2 __begin2, _RAIter2 __end2,
39436ac495dSmrg 		       _Output_RAIter __result, _Predicate __pred,
39536ac495dSmrg 		       random_access_iterator_tag, random_access_iterator_tag,
39636ac495dSmrg 		       random_access_iterator_tag)
39736ac495dSmrg     {
39836ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
39936ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
40036ac495dSmrg 	    >= __gnu_parallel::_Settings::get().set_union_minimal_n
40136ac495dSmrg 	    || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
40236ac495dSmrg 	    >= __gnu_parallel::_Settings::get().set_union_minimal_n))
40336ac495dSmrg 	return __gnu_parallel::__parallel_set_union(
40436ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result, __pred);
40536ac495dSmrg       else
40636ac495dSmrg 	return _GLIBCXX_STD_A::set_union(__begin1, __end1,
40736ac495dSmrg 					 __begin2, __end2, __result, __pred);
40836ac495dSmrg     }
40936ac495dSmrg 
41036ac495dSmrg   // Public interface
41136ac495dSmrg   template<typename _IIter1, typename _IIter2,
41236ac495dSmrg 	   typename _OutputIterator>
41336ac495dSmrg     inline _OutputIterator
41436ac495dSmrg     set_union(_IIter1 __begin1, _IIter1 __end1,
41536ac495dSmrg 	      _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
41636ac495dSmrg     {
41736ac495dSmrg       typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
41836ac495dSmrg       typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
41936ac495dSmrg 
42036ac495dSmrg       return __set_union_switch(
42136ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out,
42236ac495dSmrg 	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
42336ac495dSmrg 	       std::__iterator_category(__begin1),
42436ac495dSmrg 	       std::__iterator_category(__begin2),
42536ac495dSmrg 	       std::__iterator_category(__out));
42636ac495dSmrg     }
42736ac495dSmrg 
42836ac495dSmrg   // Public interface
42936ac495dSmrg   template<typename _IIter1, typename _IIter2,
43036ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
43136ac495dSmrg     inline _OutputIterator
43236ac495dSmrg     set_union(_IIter1 __begin1, _IIter1 __end1,
43336ac495dSmrg 	      _IIter2 __begin2, _IIter2 __end2,
43436ac495dSmrg 	      _OutputIterator __out, _Predicate __pred)
43536ac495dSmrg     {
43636ac495dSmrg       return __set_union_switch(
43736ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out, __pred,
43836ac495dSmrg 	       std::__iterator_category(__begin1),
43936ac495dSmrg 	       std::__iterator_category(__begin2),
44036ac495dSmrg 	       std::__iterator_category(__out));
44136ac495dSmrg     }
44236ac495dSmrg 
44336ac495dSmrg   // Sequential fallback.
44436ac495dSmrg   template<typename _IIter1, typename _IIter2,
44536ac495dSmrg 	   typename _OutputIterator>
44636ac495dSmrg     inline _OutputIterator
44736ac495dSmrg     set_intersection(_IIter1 __begin1, _IIter1 __end1,
44836ac495dSmrg 		     _IIter2 __begin2, _IIter2 __end2,
44936ac495dSmrg 		     _OutputIterator __out, __gnu_parallel::sequential_tag)
45036ac495dSmrg     { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1,
45136ac495dSmrg 					      __begin2, __end2, __out); }
45236ac495dSmrg 
45336ac495dSmrg   // Sequential fallback.
45436ac495dSmrg   template<typename _IIter1, typename _IIter2,
45536ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
45636ac495dSmrg     inline _OutputIterator
45736ac495dSmrg     set_intersection(_IIter1 __begin1, _IIter1 __end1,
45836ac495dSmrg 		     _IIter2 __begin2, _IIter2 __end2,
45936ac495dSmrg 		     _OutputIterator __out, _Predicate __pred,
46036ac495dSmrg 		     __gnu_parallel::sequential_tag)
46136ac495dSmrg     { return _GLIBCXX_STD_A::set_intersection(
46236ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out, __pred); }
46336ac495dSmrg 
46436ac495dSmrg   // Sequential fallback for input iterator case
46536ac495dSmrg   template<typename _IIter1, typename _IIter2,
46636ac495dSmrg 	   typename _Predicate, typename _OutputIterator,
46736ac495dSmrg 	   typename _IteratorTag1, typename _IteratorTag2,
46836ac495dSmrg 	   typename _IteratorTag3>
46936ac495dSmrg     inline _OutputIterator
47036ac495dSmrg     __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
47136ac495dSmrg 			      _IIter2 __begin2, _IIter2 __end2,
47236ac495dSmrg 			      _OutputIterator __result, _Predicate __pred,
47336ac495dSmrg 			      _IteratorTag1, _IteratorTag2, _IteratorTag3)
47436ac495dSmrg     { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2,
47536ac495dSmrg 					      __end2, __result, __pred); }
47636ac495dSmrg 
47736ac495dSmrg   // Parallel set_intersection for random access iterators
47836ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
47936ac495dSmrg 	   typename _Output_RAIter, typename _Predicate>
48036ac495dSmrg     _Output_RAIter
48136ac495dSmrg     __set_intersection_switch(_RAIter1 __begin1,
48236ac495dSmrg 			      _RAIter1 __end1,
48336ac495dSmrg 			      _RAIter2 __begin2,
48436ac495dSmrg 			      _RAIter2 __end2,
48536ac495dSmrg 			      _Output_RAIter __result,
48636ac495dSmrg 			      _Predicate __pred,
48736ac495dSmrg 			      random_access_iterator_tag,
48836ac495dSmrg 			      random_access_iterator_tag,
48936ac495dSmrg 			      random_access_iterator_tag)
49036ac495dSmrg     {
49136ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
49236ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
49336ac495dSmrg 	    >= __gnu_parallel::_Settings::get().set_union_minimal_n
49436ac495dSmrg 	    || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
49536ac495dSmrg 	    >= __gnu_parallel::_Settings::get().set_union_minimal_n))
49636ac495dSmrg 	return __gnu_parallel::__parallel_set_intersection(
49736ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result, __pred);
49836ac495dSmrg       else
49936ac495dSmrg 	return _GLIBCXX_STD_A::set_intersection(
50036ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result, __pred);
50136ac495dSmrg     }
50236ac495dSmrg 
50336ac495dSmrg   // Public interface
50436ac495dSmrg   template<typename _IIter1, typename _IIter2,
50536ac495dSmrg 	   typename _OutputIterator>
50636ac495dSmrg     inline _OutputIterator
50736ac495dSmrg     set_intersection(_IIter1 __begin1, _IIter1 __end1,
50836ac495dSmrg 		     _IIter2 __begin2, _IIter2 __end2,
50936ac495dSmrg 		     _OutputIterator __out)
51036ac495dSmrg     {
51136ac495dSmrg       typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
51236ac495dSmrg       typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
51336ac495dSmrg 
51436ac495dSmrg       return __set_intersection_switch(
51536ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out,
51636ac495dSmrg 	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
51736ac495dSmrg 	       std::__iterator_category(__begin1),
51836ac495dSmrg 	       std::__iterator_category(__begin2),
51936ac495dSmrg 	       std::__iterator_category(__out));
52036ac495dSmrg     }
52136ac495dSmrg 
52236ac495dSmrg   template<typename _IIter1, typename _IIter2,
52336ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
52436ac495dSmrg     inline _OutputIterator
52536ac495dSmrg     set_intersection(_IIter1 __begin1, _IIter1 __end1,
52636ac495dSmrg 		     _IIter2 __begin2, _IIter2 __end2,
52736ac495dSmrg 		     _OutputIterator __out, _Predicate __pred)
52836ac495dSmrg     {
52936ac495dSmrg       return __set_intersection_switch(
53036ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out, __pred,
53136ac495dSmrg 	       std::__iterator_category(__begin1),
53236ac495dSmrg 	       std::__iterator_category(__begin2),
53336ac495dSmrg 	       std::__iterator_category(__out));
53436ac495dSmrg     }
53536ac495dSmrg 
53636ac495dSmrg   // Sequential fallback
53736ac495dSmrg   template<typename _IIter1, typename _IIter2,
53836ac495dSmrg 	   typename _OutputIterator>
53936ac495dSmrg     inline _OutputIterator
54036ac495dSmrg     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
54136ac495dSmrg 			     _IIter2 __begin2, _IIter2 __end2,
54236ac495dSmrg 			     _OutputIterator __out,
54336ac495dSmrg 			     __gnu_parallel::sequential_tag)
54436ac495dSmrg     { return _GLIBCXX_STD_A::set_symmetric_difference(
54536ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out); }
54636ac495dSmrg 
54736ac495dSmrg   // Sequential fallback
54836ac495dSmrg   template<typename _IIter1, typename _IIter2,
54936ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
55036ac495dSmrg     inline _OutputIterator
55136ac495dSmrg     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
55236ac495dSmrg 			     _IIter2 __begin2, _IIter2 __end2,
55336ac495dSmrg 			     _OutputIterator __out, _Predicate __pred,
55436ac495dSmrg 			     __gnu_parallel::sequential_tag)
55536ac495dSmrg     { return _GLIBCXX_STD_A::set_symmetric_difference(
55636ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out, __pred); }
55736ac495dSmrg 
55836ac495dSmrg   // Sequential fallback for input iterator case
55936ac495dSmrg   template<typename _IIter1, typename _IIter2,
56036ac495dSmrg 	   typename _Predicate, typename _OutputIterator,
56136ac495dSmrg 	   typename _IteratorTag1, typename _IteratorTag2,
56236ac495dSmrg 	   typename _IteratorTag3>
56336ac495dSmrg     inline _OutputIterator
56436ac495dSmrg     __set_symmetric_difference_switch(
56536ac495dSmrg 	_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
56636ac495dSmrg 	_OutputIterator __result, _Predicate __pred,
56736ac495dSmrg 	_IteratorTag1, _IteratorTag2, _IteratorTag3)
56836ac495dSmrg     { return _GLIBCXX_STD_A::set_symmetric_difference(
56936ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __result, __pred); }
57036ac495dSmrg 
57136ac495dSmrg   // Parallel set_symmetric_difference for random access iterators
57236ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
57336ac495dSmrg 	   typename _Output_RAIter, typename _Predicate>
57436ac495dSmrg     _Output_RAIter
57536ac495dSmrg     __set_symmetric_difference_switch(_RAIter1 __begin1,
57636ac495dSmrg 				      _RAIter1 __end1,
57736ac495dSmrg 				      _RAIter2 __begin2,
57836ac495dSmrg 				      _RAIter2 __end2,
57936ac495dSmrg 				      _Output_RAIter __result,
58036ac495dSmrg 				      _Predicate __pred,
58136ac495dSmrg 				      random_access_iterator_tag,
58236ac495dSmrg 				      random_access_iterator_tag,
58336ac495dSmrg 				      random_access_iterator_tag)
58436ac495dSmrg     {
58536ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
58636ac495dSmrg       static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
58736ac495dSmrg       >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
58836ac495dSmrg       || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
58936ac495dSmrg       >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
59036ac495dSmrg   return __gnu_parallel::__parallel_set_symmetric_difference(
59136ac495dSmrg 	   __begin1, __end1, __begin2, __end2, __result, __pred);
59236ac495dSmrg       else
59336ac495dSmrg 	return _GLIBCXX_STD_A::set_symmetric_difference(
59436ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result, __pred);
59536ac495dSmrg     }
59636ac495dSmrg 
59736ac495dSmrg   // Public interface.
59836ac495dSmrg   template<typename _IIter1, typename _IIter2,
59936ac495dSmrg 	   typename _OutputIterator>
60036ac495dSmrg     inline _OutputIterator
60136ac495dSmrg     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
60236ac495dSmrg 			     _IIter2 __begin2, _IIter2 __end2,
60336ac495dSmrg 			     _OutputIterator __out)
60436ac495dSmrg     {
60536ac495dSmrg       typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
60636ac495dSmrg       typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
60736ac495dSmrg 
60836ac495dSmrg       return __set_symmetric_difference_switch(
60936ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out,
61036ac495dSmrg 	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
61136ac495dSmrg 	       std::__iterator_category(__begin1),
61236ac495dSmrg 	       std::__iterator_category(__begin2),
61336ac495dSmrg 	       std::__iterator_category(__out));
61436ac495dSmrg     }
61536ac495dSmrg 
61636ac495dSmrg   // Public interface.
61736ac495dSmrg   template<typename _IIter1, typename _IIter2,
61836ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
61936ac495dSmrg     inline _OutputIterator
62036ac495dSmrg     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
62136ac495dSmrg 			     _IIter2 __begin2, _IIter2 __end2,
62236ac495dSmrg 			     _OutputIterator __out, _Predicate __pred)
62336ac495dSmrg     {
62436ac495dSmrg       return __set_symmetric_difference_switch(
62536ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out, __pred,
62636ac495dSmrg 	       std::__iterator_category(__begin1),
62736ac495dSmrg 	       std::__iterator_category(__begin2),
62836ac495dSmrg 	       std::__iterator_category(__out));
62936ac495dSmrg     }
63036ac495dSmrg 
63136ac495dSmrg   // Sequential fallback.
63236ac495dSmrg   template<typename _IIter1, typename _IIter2,
63336ac495dSmrg 	   typename _OutputIterator>
63436ac495dSmrg     inline _OutputIterator
63536ac495dSmrg     set_difference(_IIter1 __begin1, _IIter1 __end1,
63636ac495dSmrg 		   _IIter2 __begin2, _IIter2 __end2,
63736ac495dSmrg 		   _OutputIterator __out, __gnu_parallel::sequential_tag)
63836ac495dSmrg     { return _GLIBCXX_STD_A::set_difference(
63936ac495dSmrg 	       __begin1,__end1, __begin2, __end2, __out); }
64036ac495dSmrg 
64136ac495dSmrg   // Sequential fallback.
64236ac495dSmrg   template<typename _IIter1, typename _IIter2,
64336ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
64436ac495dSmrg     inline _OutputIterator
64536ac495dSmrg     set_difference(_IIter1 __begin1, _IIter1 __end1,
64636ac495dSmrg 		   _IIter2 __begin2, _IIter2 __end2,
64736ac495dSmrg 		   _OutputIterator __out, _Predicate __pred,
64836ac495dSmrg 		   __gnu_parallel::sequential_tag)
64936ac495dSmrg     { return _GLIBCXX_STD_A::set_difference(__begin1, __end1,
65036ac495dSmrg 					    __begin2, __end2, __out, __pred); }
65136ac495dSmrg 
65236ac495dSmrg   // Sequential fallback for input iterator case.
65336ac495dSmrg   template<typename _IIter1, typename _IIter2, typename _Predicate,
65436ac495dSmrg 	   typename _OutputIterator, typename _IteratorTag1,
65536ac495dSmrg 	   typename _IteratorTag2, typename _IteratorTag3>
65636ac495dSmrg     inline _OutputIterator
65736ac495dSmrg     __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
65836ac495dSmrg 			    _IIter2 __begin2, _IIter2 __end2,
65936ac495dSmrg 			    _OutputIterator __result, _Predicate __pred,
66036ac495dSmrg 			    _IteratorTag1, _IteratorTag2, _IteratorTag3)
66136ac495dSmrg     { return _GLIBCXX_STD_A::set_difference(
66236ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __result, __pred); }
66336ac495dSmrg 
66436ac495dSmrg   // Parallel set_difference for random access iterators
66536ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
66636ac495dSmrg 	   typename _Output_RAIter, typename _Predicate>
66736ac495dSmrg     _Output_RAIter
66836ac495dSmrg     __set_difference_switch(_RAIter1 __begin1,
66936ac495dSmrg 			    _RAIter1 __end1,
67036ac495dSmrg 			    _RAIter2 __begin2,
67136ac495dSmrg 			    _RAIter2 __end2,
67236ac495dSmrg 			    _Output_RAIter __result, _Predicate __pred,
67336ac495dSmrg 			    random_access_iterator_tag,
67436ac495dSmrg 			    random_access_iterator_tag,
67536ac495dSmrg 			    random_access_iterator_tag)
67636ac495dSmrg     {
67736ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
67836ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
67936ac495dSmrg 	    >= __gnu_parallel::_Settings::get().set_difference_minimal_n
68036ac495dSmrg 	    || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
68136ac495dSmrg 	    >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
68236ac495dSmrg 	return __gnu_parallel::__parallel_set_difference(
68336ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result, __pred);
68436ac495dSmrg       else
68536ac495dSmrg 	return _GLIBCXX_STD_A::set_difference(
68636ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result, __pred);
68736ac495dSmrg     }
68836ac495dSmrg 
68936ac495dSmrg   // Public interface
69036ac495dSmrg   template<typename _IIter1, typename _IIter2,
69136ac495dSmrg 	   typename _OutputIterator>
69236ac495dSmrg     inline _OutputIterator
69336ac495dSmrg     set_difference(_IIter1 __begin1, _IIter1 __end1,
69436ac495dSmrg 		   _IIter2 __begin2, _IIter2 __end2,
69536ac495dSmrg 		   _OutputIterator __out)
69636ac495dSmrg     {
69736ac495dSmrg       typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
69836ac495dSmrg       typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
69936ac495dSmrg 
70036ac495dSmrg       return __set_difference_switch(
70136ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out,
70236ac495dSmrg 	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
70336ac495dSmrg 	       std::__iterator_category(__begin1),
70436ac495dSmrg 	       std::__iterator_category(__begin2),
70536ac495dSmrg 	       std::__iterator_category(__out));
70636ac495dSmrg     }
70736ac495dSmrg 
70836ac495dSmrg   // Public interface
70936ac495dSmrg   template<typename _IIter1, typename _IIter2,
71036ac495dSmrg 	   typename _OutputIterator, typename _Predicate>
71136ac495dSmrg     inline _OutputIterator
71236ac495dSmrg     set_difference(_IIter1 __begin1, _IIter1 __end1,
71336ac495dSmrg 		   _IIter2 __begin2, _IIter2 __end2,
71436ac495dSmrg 		   _OutputIterator __out, _Predicate __pred)
71536ac495dSmrg     {
71636ac495dSmrg       return __set_difference_switch(
71736ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __out, __pred,
71836ac495dSmrg 	       std::__iterator_category(__begin1),
71936ac495dSmrg 	       std::__iterator_category(__begin2),
72036ac495dSmrg 	       std::__iterator_category(__out));
72136ac495dSmrg     }
72236ac495dSmrg 
72336ac495dSmrg   // Sequential fallback
72436ac495dSmrg   template<typename _FIterator>
72536ac495dSmrg     inline _FIterator
72636ac495dSmrg     adjacent_find(_FIterator __begin, _FIterator __end,
72736ac495dSmrg 		  __gnu_parallel::sequential_tag)
72836ac495dSmrg     { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); }
72936ac495dSmrg 
73036ac495dSmrg   // Sequential fallback
73136ac495dSmrg   template<typename _FIterator, typename _BinaryPredicate>
73236ac495dSmrg     inline _FIterator
73336ac495dSmrg     adjacent_find(_FIterator __begin, _FIterator __end,
73436ac495dSmrg 		  _BinaryPredicate __binary_pred,
73536ac495dSmrg 		  __gnu_parallel::sequential_tag)
73636ac495dSmrg     { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); }
73736ac495dSmrg 
73836ac495dSmrg   // Parallel algorithm for random access iterators
73936ac495dSmrg   template<typename _RAIter>
74036ac495dSmrg     _RAIter
74136ac495dSmrg     __adjacent_find_switch(_RAIter __begin, _RAIter __end,
74236ac495dSmrg 			   random_access_iterator_tag)
74336ac495dSmrg     {
74436ac495dSmrg       typedef iterator_traits<_RAIter> _TraitsType;
74536ac495dSmrg       typedef typename _TraitsType::value_type _ValueType;
74636ac495dSmrg 
74736ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(true))
74836ac495dSmrg 	{
74936ac495dSmrg 	  _RAIter __spot = __gnu_parallel::
75036ac495dSmrg 	      __find_template(
75136ac495dSmrg 		__begin, __end - 1, __begin, equal_to<_ValueType>(),
75236ac495dSmrg 		__gnu_parallel::__adjacent_find_selector())
75336ac495dSmrg 	    .first;
75436ac495dSmrg 	  if (__spot == (__end - 1))
75536ac495dSmrg 	    return __end;
75636ac495dSmrg 	  else
75736ac495dSmrg 	    return __spot;
75836ac495dSmrg 	}
75936ac495dSmrg       else
76036ac495dSmrg 	return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
76136ac495dSmrg     }
76236ac495dSmrg 
76336ac495dSmrg   // Sequential fallback for input iterator case
76436ac495dSmrg   template<typename _FIterator, typename _IteratorTag>
76536ac495dSmrg     inline _FIterator
76636ac495dSmrg     __adjacent_find_switch(_FIterator __begin, _FIterator __end,
76736ac495dSmrg 			   _IteratorTag)
76836ac495dSmrg     { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
76936ac495dSmrg 
77036ac495dSmrg   // Public interface
77136ac495dSmrg   template<typename _FIterator>
77236ac495dSmrg     inline _FIterator
77336ac495dSmrg     adjacent_find(_FIterator __begin, _FIterator __end)
77436ac495dSmrg     {
77536ac495dSmrg       return __adjacent_find_switch(__begin, __end,
77636ac495dSmrg 				    std::__iterator_category(__begin));
77736ac495dSmrg     }
77836ac495dSmrg 
77936ac495dSmrg   // Sequential fallback for input iterator case
78036ac495dSmrg   template<typename _FIterator, typename _BinaryPredicate,
78136ac495dSmrg 	   typename _IteratorTag>
78236ac495dSmrg     inline _FIterator
78336ac495dSmrg     __adjacent_find_switch(_FIterator __begin, _FIterator __end,
78436ac495dSmrg 			   _BinaryPredicate __pred, _IteratorTag)
78536ac495dSmrg     { return adjacent_find(__begin, __end, __pred,
78636ac495dSmrg 			   __gnu_parallel::sequential_tag()); }
78736ac495dSmrg 
78836ac495dSmrg   // Parallel algorithm for random access iterators
78936ac495dSmrg   template<typename _RAIter, typename _BinaryPredicate>
79036ac495dSmrg     _RAIter
79136ac495dSmrg     __adjacent_find_switch(_RAIter __begin, _RAIter __end,
79236ac495dSmrg 			   _BinaryPredicate __pred, random_access_iterator_tag)
79336ac495dSmrg     {
79436ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(true))
79536ac495dSmrg 	return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
79636ac495dSmrg 					     __gnu_parallel::
79736ac495dSmrg 					     __adjacent_find_selector()).first;
79836ac495dSmrg       else
79936ac495dSmrg 	return adjacent_find(__begin, __end, __pred,
80036ac495dSmrg 			     __gnu_parallel::sequential_tag());
80136ac495dSmrg     }
80236ac495dSmrg 
80336ac495dSmrg   // Public interface
80436ac495dSmrg   template<typename _FIterator, typename _BinaryPredicate>
80536ac495dSmrg     inline _FIterator
80636ac495dSmrg     adjacent_find(_FIterator __begin, _FIterator __end,
80736ac495dSmrg 		  _BinaryPredicate __pred)
80836ac495dSmrg     {
80936ac495dSmrg       return __adjacent_find_switch(__begin, __end, __pred,
81036ac495dSmrg 				    std::__iterator_category(__begin));
81136ac495dSmrg     }
81236ac495dSmrg 
81336ac495dSmrg   // Sequential fallback
81436ac495dSmrg   template<typename _IIter, typename _Tp>
81536ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
81636ac495dSmrg     count(_IIter __begin, _IIter __end, const _Tp& __value,
81736ac495dSmrg 	  __gnu_parallel::sequential_tag)
81836ac495dSmrg     { return _GLIBCXX_STD_A::count(__begin, __end, __value); }
81936ac495dSmrg 
82036ac495dSmrg   // Parallel code for random access iterators
82136ac495dSmrg   template<typename _RAIter, typename _Tp>
82236ac495dSmrg     typename iterator_traits<_RAIter>::difference_type
82336ac495dSmrg     __count_switch(_RAIter __begin, _RAIter __end,
82436ac495dSmrg 		   const _Tp& __value, random_access_iterator_tag,
82536ac495dSmrg 		   __gnu_parallel::_Parallelism __parallelism_tag)
82636ac495dSmrg     {
82736ac495dSmrg       typedef iterator_traits<_RAIter> _TraitsType;
82836ac495dSmrg       typedef typename _TraitsType::value_type _ValueType;
82936ac495dSmrg       typedef typename _TraitsType::difference_type _DifferenceType;
83036ac495dSmrg       typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
83136ac495dSmrg 
83236ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
83336ac495dSmrg 	    static_cast<_SequenceIndex>(__end - __begin)
83436ac495dSmrg 	    >= __gnu_parallel::_Settings::get().count_minimal_n
83536ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
83636ac495dSmrg 	{
83736ac495dSmrg 	  __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
83836ac495dSmrg 	    __functionality;
83936ac495dSmrg 	  _DifferenceType __res = 0;
84036ac495dSmrg 	  __gnu_parallel::
84136ac495dSmrg 	    __for_each_template_random_access(
84236ac495dSmrg 	      __begin, __end, __value, __functionality,
84336ac495dSmrg 	      std::plus<_SequenceIndex>(), __res, __res, -1,
84436ac495dSmrg 	      __parallelism_tag);
84536ac495dSmrg 	  return __res;
84636ac495dSmrg 	}
84736ac495dSmrg       else
84836ac495dSmrg 	return count(__begin, __end, __value,
84936ac495dSmrg 		     __gnu_parallel::sequential_tag());
85036ac495dSmrg     }
85136ac495dSmrg 
85236ac495dSmrg   // Sequential fallback for input iterator case.
85336ac495dSmrg   template<typename _IIter, typename _Tp, typename _IteratorTag>
85436ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
85536ac495dSmrg     __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
85636ac495dSmrg 		   _IteratorTag)
85736ac495dSmrg     { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
85836ac495dSmrg       }
85936ac495dSmrg 
86036ac495dSmrg   // Public interface.
86136ac495dSmrg   template<typename _IIter, typename _Tp>
86236ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
86336ac495dSmrg     count(_IIter __begin, _IIter __end, const _Tp& __value,
86436ac495dSmrg 	  __gnu_parallel::_Parallelism __parallelism_tag)
86536ac495dSmrg     {
86636ac495dSmrg       return __count_switch(__begin, __end, __value,
86736ac495dSmrg 			    std::__iterator_category(__begin),
86836ac495dSmrg 			    __parallelism_tag);
86936ac495dSmrg     }
87036ac495dSmrg 
87136ac495dSmrg   template<typename _IIter, typename _Tp>
87236ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
87336ac495dSmrg     count(_IIter __begin, _IIter __end, const _Tp& __value)
87436ac495dSmrg     {
87536ac495dSmrg       return __count_switch(__begin, __end, __value,
87636ac495dSmrg 			    std::__iterator_category(__begin));
87736ac495dSmrg     }
87836ac495dSmrg 
87936ac495dSmrg 
88036ac495dSmrg   // Sequential fallback.
88136ac495dSmrg   template<typename _IIter, typename _Predicate>
88236ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
88336ac495dSmrg     count_if(_IIter __begin, _IIter __end, _Predicate __pred,
88436ac495dSmrg 	     __gnu_parallel::sequential_tag)
88536ac495dSmrg     { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); }
88636ac495dSmrg 
88736ac495dSmrg   // Parallel count_if for random access iterators
88836ac495dSmrg   template<typename _RAIter, typename _Predicate>
88936ac495dSmrg     typename iterator_traits<_RAIter>::difference_type
89036ac495dSmrg     __count_if_switch(_RAIter __begin, _RAIter __end,
89136ac495dSmrg 		      _Predicate __pred, random_access_iterator_tag,
89236ac495dSmrg 		      __gnu_parallel::_Parallelism __parallelism_tag)
89336ac495dSmrg     {
89436ac495dSmrg       typedef iterator_traits<_RAIter> _TraitsType;
89536ac495dSmrg       typedef typename _TraitsType::value_type _ValueType;
89636ac495dSmrg       typedef typename _TraitsType::difference_type _DifferenceType;
89736ac495dSmrg       typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
89836ac495dSmrg 
89936ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
90036ac495dSmrg 	    static_cast<_SequenceIndex>(__end - __begin)
90136ac495dSmrg 	    >= __gnu_parallel::_Settings::get().count_minimal_n
90236ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
90336ac495dSmrg 	{
90436ac495dSmrg 	  _DifferenceType __res = 0;
90536ac495dSmrg 	  __gnu_parallel::
90636ac495dSmrg 	    __count_if_selector<_RAIter, _DifferenceType>
90736ac495dSmrg 	    __functionality;
90836ac495dSmrg 	  __gnu_parallel::
90936ac495dSmrg 	    __for_each_template_random_access(
91036ac495dSmrg 	      __begin, __end, __pred, __functionality,
91136ac495dSmrg 	      std::plus<_SequenceIndex>(), __res, __res, -1,
91236ac495dSmrg 	      __parallelism_tag);
91336ac495dSmrg 	  return __res;
91436ac495dSmrg 	}
91536ac495dSmrg       else
91636ac495dSmrg 	return count_if(__begin, __end, __pred,
91736ac495dSmrg 			__gnu_parallel::sequential_tag());
91836ac495dSmrg     }
91936ac495dSmrg 
92036ac495dSmrg   // Sequential fallback for input iterator case.
92136ac495dSmrg   template<typename _IIter, typename _Predicate, typename _IteratorTag>
92236ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
92336ac495dSmrg     __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
92436ac495dSmrg 		      _IteratorTag)
92536ac495dSmrg     { return count_if(__begin, __end, __pred,
92636ac495dSmrg 		      __gnu_parallel::sequential_tag()); }
92736ac495dSmrg 
92836ac495dSmrg   // Public interface.
92936ac495dSmrg   template<typename _IIter, typename _Predicate>
93036ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
93136ac495dSmrg     count_if(_IIter __begin, _IIter __end, _Predicate __pred,
93236ac495dSmrg 	     __gnu_parallel::_Parallelism __parallelism_tag)
93336ac495dSmrg     {
93436ac495dSmrg       return __count_if_switch(__begin, __end, __pred,
93536ac495dSmrg 			       std::__iterator_category(__begin),
93636ac495dSmrg 			       __parallelism_tag);
93736ac495dSmrg     }
93836ac495dSmrg 
93936ac495dSmrg   template<typename _IIter, typename _Predicate>
94036ac495dSmrg     inline typename iterator_traits<_IIter>::difference_type
94136ac495dSmrg     count_if(_IIter __begin, _IIter __end, _Predicate __pred)
94236ac495dSmrg     {
94336ac495dSmrg       return __count_if_switch(__begin, __end, __pred,
94436ac495dSmrg 			       std::__iterator_category(__begin));
94536ac495dSmrg     }
94636ac495dSmrg 
94736ac495dSmrg 
94836ac495dSmrg   // Sequential fallback.
94936ac495dSmrg   template<typename _FIterator1, typename _FIterator2>
95036ac495dSmrg     inline _FIterator1
95136ac495dSmrg     search(_FIterator1 __begin1, _FIterator1 __end1,
95236ac495dSmrg 	   _FIterator2 __begin2, _FIterator2 __end2,
95336ac495dSmrg 	   __gnu_parallel::sequential_tag)
95436ac495dSmrg     { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); }
95536ac495dSmrg 
95636ac495dSmrg   // Parallel algorithm for random access iterator
95736ac495dSmrg   template<typename _RAIter1, typename _RAIter2>
95836ac495dSmrg     _RAIter1
95936ac495dSmrg     __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
96036ac495dSmrg 		    _RAIter2 __begin2, _RAIter2 __end2,
96136ac495dSmrg 		    random_access_iterator_tag, random_access_iterator_tag)
96236ac495dSmrg     {
96336ac495dSmrg       typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1;
96436ac495dSmrg       typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2;
96536ac495dSmrg 
96636ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
96736ac495dSmrg 		static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
96836ac495dSmrg 	    >= __gnu_parallel::_Settings::get().search_minimal_n))
96936ac495dSmrg 	return __gnu_parallel::
97036ac495dSmrg 	  __search_template(
97136ac495dSmrg 	    __begin1, __end1, __begin2, __end2,
97236ac495dSmrg 	    __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
97336ac495dSmrg       else
97436ac495dSmrg 	return search(__begin1, __end1, __begin2, __end2,
97536ac495dSmrg 		      __gnu_parallel::sequential_tag());
97636ac495dSmrg     }
97736ac495dSmrg 
97836ac495dSmrg   // Sequential fallback for input iterator case
97936ac495dSmrg   template<typename _FIterator1, typename _FIterator2,
98036ac495dSmrg 	   typename _IteratorTag1, typename _IteratorTag2>
98136ac495dSmrg     inline _FIterator1
98236ac495dSmrg     __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
98336ac495dSmrg 		    _FIterator2 __begin2, _FIterator2 __end2,
98436ac495dSmrg 		    _IteratorTag1, _IteratorTag2)
98536ac495dSmrg     { return search(__begin1, __end1, __begin2, __end2,
98636ac495dSmrg 		    __gnu_parallel::sequential_tag()); }
98736ac495dSmrg 
98836ac495dSmrg   // Public interface.
98936ac495dSmrg   template<typename _FIterator1, typename _FIterator2>
99036ac495dSmrg     inline _FIterator1
99136ac495dSmrg     search(_FIterator1 __begin1, _FIterator1 __end1,
99236ac495dSmrg 	   _FIterator2 __begin2, _FIterator2 __end2)
99336ac495dSmrg     {
99436ac495dSmrg       return __search_switch(__begin1, __end1, __begin2, __end2,
99536ac495dSmrg 			     std::__iterator_category(__begin1),
99636ac495dSmrg 			     std::__iterator_category(__begin2));
99736ac495dSmrg     }
99836ac495dSmrg 
99936ac495dSmrg   // Public interface.
100036ac495dSmrg   template<typename _FIterator1, typename _FIterator2,
100136ac495dSmrg 	   typename _BinaryPredicate>
100236ac495dSmrg     inline _FIterator1
100336ac495dSmrg     search(_FIterator1 __begin1, _FIterator1 __end1,
100436ac495dSmrg 	   _FIterator2 __begin2, _FIterator2 __end2,
100536ac495dSmrg 	   _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
100636ac495dSmrg     { return _GLIBCXX_STD_A::search(
100736ac495dSmrg 			       __begin1, __end1, __begin2, __end2, __pred); }
100836ac495dSmrg 
100936ac495dSmrg   // Parallel algorithm for random access iterator.
101036ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
101136ac495dSmrg 	   typename _BinaryPredicate>
101236ac495dSmrg     _RAIter1
101336ac495dSmrg     __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
101436ac495dSmrg 		    _RAIter2 __begin2, _RAIter2 __end2,
101536ac495dSmrg 		    _BinaryPredicate __pred,
101636ac495dSmrg 		    random_access_iterator_tag, random_access_iterator_tag)
101736ac495dSmrg     {
101836ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
101936ac495dSmrg 		static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
102036ac495dSmrg 	    >= __gnu_parallel::_Settings::get().search_minimal_n))
102136ac495dSmrg 	return __gnu_parallel::__search_template(__begin1, __end1,
102236ac495dSmrg 					       __begin2, __end2, __pred);
102336ac495dSmrg       else
102436ac495dSmrg 	return search(__begin1, __end1, __begin2, __end2, __pred,
102536ac495dSmrg 		      __gnu_parallel::sequential_tag());
102636ac495dSmrg     }
102736ac495dSmrg 
102836ac495dSmrg   // Sequential fallback for input iterator case
102936ac495dSmrg   template<typename _FIterator1, typename _FIterator2,
103036ac495dSmrg 	   typename _BinaryPredicate, typename _IteratorTag1,
103136ac495dSmrg 	   typename _IteratorTag2>
103236ac495dSmrg     inline _FIterator1
103336ac495dSmrg     __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
103436ac495dSmrg 		    _FIterator2 __begin2, _FIterator2 __end2,
103536ac495dSmrg 		    _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
103636ac495dSmrg     { return search(__begin1, __end1, __begin2, __end2, __pred,
103736ac495dSmrg 		    __gnu_parallel::sequential_tag()); }
103836ac495dSmrg 
103936ac495dSmrg   // Public interface
104036ac495dSmrg   template<typename _FIterator1, typename _FIterator2,
104136ac495dSmrg 	   typename _BinaryPredicate>
104236ac495dSmrg     inline _FIterator1
104336ac495dSmrg     search(_FIterator1 __begin1, _FIterator1 __end1,
104436ac495dSmrg 	   _FIterator2 __begin2, _FIterator2 __end2,
104536ac495dSmrg 	   _BinaryPredicate  __pred)
104636ac495dSmrg     {
104736ac495dSmrg       return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
104836ac495dSmrg 			     std::__iterator_category(__begin1),
104936ac495dSmrg 			     std::__iterator_category(__begin2));
105036ac495dSmrg     }
105136ac495dSmrg 
105236ac495dSmrg   // Sequential fallback
105336ac495dSmrg   template<typename _FIterator, typename _Integer, typename _Tp>
105436ac495dSmrg     inline _FIterator
105536ac495dSmrg     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
105636ac495dSmrg 	     const _Tp& __val, __gnu_parallel::sequential_tag)
105736ac495dSmrg     { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); }
105836ac495dSmrg 
105936ac495dSmrg   // Sequential fallback
106036ac495dSmrg   template<typename _FIterator, typename _Integer, typename _Tp,
106136ac495dSmrg 	   typename _BinaryPredicate>
106236ac495dSmrg     inline _FIterator
106336ac495dSmrg     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
106436ac495dSmrg 	     const _Tp& __val, _BinaryPredicate __binary_pred,
106536ac495dSmrg 	     __gnu_parallel::sequential_tag)
106636ac495dSmrg     { return _GLIBCXX_STD_A::search_n(
106736ac495dSmrg 	       __begin, __end, __count, __val, __binary_pred); }
106836ac495dSmrg 
106936ac495dSmrg   // Public interface.
107036ac495dSmrg   template<typename _FIterator, typename _Integer, typename _Tp>
107136ac495dSmrg     inline _FIterator
107236ac495dSmrg     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
107336ac495dSmrg 	     const _Tp& __val)
107436ac495dSmrg     {
107536ac495dSmrg       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
107636ac495dSmrg       return __gnu_parallel::search_n(__begin, __end, __count, __val,
107736ac495dSmrg 		      __gnu_parallel::_EqualTo<_ValueType, _Tp>());
107836ac495dSmrg     }
107936ac495dSmrg 
108036ac495dSmrg   // Parallel algorithm for random access iterators.
108136ac495dSmrg   template<typename _RAIter, typename _Integer,
108236ac495dSmrg 	   typename _Tp, typename _BinaryPredicate>
108336ac495dSmrg     _RAIter
108436ac495dSmrg     __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
108536ac495dSmrg 		      const _Tp& __val, _BinaryPredicate __binary_pred,
108636ac495dSmrg 		      random_access_iterator_tag)
108736ac495dSmrg     {
108836ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
108936ac495dSmrg 		static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
109036ac495dSmrg 	    >= __gnu_parallel::_Settings::get().search_minimal_n))
109136ac495dSmrg 	{
109236ac495dSmrg 	  __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
109336ac495dSmrg 	  return __gnu_parallel::__search_template(
109436ac495dSmrg 		   __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
109536ac495dSmrg 	}
109636ac495dSmrg       else
109736ac495dSmrg 	return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
109836ac495dSmrg 					__binary_pred);
109936ac495dSmrg     }
110036ac495dSmrg 
110136ac495dSmrg   // Sequential fallback for input iterator case.
110236ac495dSmrg   template<typename _FIterator, typename _Integer, typename _Tp,
110336ac495dSmrg 	   typename _BinaryPredicate, typename _IteratorTag>
110436ac495dSmrg     inline _FIterator
110536ac495dSmrg     __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
110636ac495dSmrg 		      const _Tp& __val, _BinaryPredicate __binary_pred,
110736ac495dSmrg 		      _IteratorTag)
110836ac495dSmrg     { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
110936ac495dSmrg 				      __binary_pred); }
111036ac495dSmrg 
111136ac495dSmrg   // Public interface.
111236ac495dSmrg   template<typename _FIterator, typename _Integer, typename _Tp,
111336ac495dSmrg 	   typename _BinaryPredicate>
111436ac495dSmrg     inline _FIterator
111536ac495dSmrg     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
111636ac495dSmrg 	     const _Tp& __val, _BinaryPredicate __binary_pred)
111736ac495dSmrg     {
111836ac495dSmrg       return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
111936ac495dSmrg 			       std::__iterator_category(__begin));
112036ac495dSmrg     }
112136ac495dSmrg 
112236ac495dSmrg 
112336ac495dSmrg   // Sequential fallback.
112436ac495dSmrg   template<typename _IIter, typename _OutputIterator,
112536ac495dSmrg 	   typename _UnaryOperation>
112636ac495dSmrg     inline _OutputIterator
112736ac495dSmrg     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
112836ac495dSmrg 	      _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
112936ac495dSmrg     { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); }
113036ac495dSmrg 
113136ac495dSmrg   // Parallel unary transform for random access iterators.
113236ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
113336ac495dSmrg 	   typename _UnaryOperation>
113436ac495dSmrg     _RAIter2
113536ac495dSmrg     __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
113636ac495dSmrg 			_RAIter2 __result, _UnaryOperation __unary_op,
113736ac495dSmrg 			random_access_iterator_tag, random_access_iterator_tag,
113836ac495dSmrg 			__gnu_parallel::_Parallelism __parallelism_tag)
113936ac495dSmrg     {
114036ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
114136ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
114236ac495dSmrg 	    >= __gnu_parallel::_Settings::get().transform_minimal_n
114336ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
114436ac495dSmrg 	{
114536ac495dSmrg 	  bool __dummy = true;
114636ac495dSmrg 	  typedef __gnu_parallel::_IteratorPair<_RAIter1,
114736ac495dSmrg 	    _RAIter2, random_access_iterator_tag> _ItTrip;
114836ac495dSmrg 	  _ItTrip __begin_pair(__begin, __result),
114936ac495dSmrg 		  __end_pair(__end, __result + (__end - __begin));
115036ac495dSmrg 	  __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
115136ac495dSmrg 	  __gnu_parallel::
115236ac495dSmrg 	    __for_each_template_random_access(
115336ac495dSmrg 	      __begin_pair, __end_pair, __unary_op, __functionality,
115436ac495dSmrg 	      __gnu_parallel::_DummyReduct(),
115536ac495dSmrg 	      __dummy, __dummy, -1, __parallelism_tag);
115636ac495dSmrg 	  return __functionality._M_finish_iterator;
115736ac495dSmrg 	}
115836ac495dSmrg       else
115936ac495dSmrg 	return transform(__begin, __end, __result, __unary_op,
116036ac495dSmrg 			 __gnu_parallel::sequential_tag());
116136ac495dSmrg     }
116236ac495dSmrg 
116336ac495dSmrg   // Sequential fallback for input iterator case.
116436ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
116536ac495dSmrg 	   typename _UnaryOperation, typename _IteratorTag1,
116636ac495dSmrg 	   typename _IteratorTag2>
116736ac495dSmrg     inline _RAIter2
116836ac495dSmrg     __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
116936ac495dSmrg 			_RAIter2 __result, _UnaryOperation __unary_op,
117036ac495dSmrg 			_IteratorTag1, _IteratorTag2)
117136ac495dSmrg     { return transform(__begin, __end, __result, __unary_op,
117236ac495dSmrg 		       __gnu_parallel::sequential_tag()); }
117336ac495dSmrg 
117436ac495dSmrg   // Public interface.
117536ac495dSmrg   template<typename _IIter, typename _OutputIterator,
117636ac495dSmrg 	   typename _UnaryOperation>
117736ac495dSmrg     inline _OutputIterator
117836ac495dSmrg     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
117936ac495dSmrg 	      _UnaryOperation __unary_op,
118036ac495dSmrg 	      __gnu_parallel::_Parallelism __parallelism_tag)
118136ac495dSmrg     {
118236ac495dSmrg       return __transform1_switch(__begin, __end, __result, __unary_op,
118336ac495dSmrg 				 std::__iterator_category(__begin),
118436ac495dSmrg 				 std::__iterator_category(__result),
118536ac495dSmrg 				 __parallelism_tag);
118636ac495dSmrg     }
118736ac495dSmrg 
118836ac495dSmrg   template<typename _IIter, typename _OutputIterator,
118936ac495dSmrg 	   typename _UnaryOperation>
119036ac495dSmrg     inline _OutputIterator
119136ac495dSmrg     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
119236ac495dSmrg 	      _UnaryOperation __unary_op)
119336ac495dSmrg     {
119436ac495dSmrg       return __transform1_switch(__begin, __end, __result, __unary_op,
119536ac495dSmrg 				 std::__iterator_category(__begin),
119636ac495dSmrg 				 std::__iterator_category(__result));
119736ac495dSmrg     }
119836ac495dSmrg 
119936ac495dSmrg 
120036ac495dSmrg   // Sequential fallback
120136ac495dSmrg   template<typename _IIter1, typename _IIter2,
120236ac495dSmrg 	   typename _OutputIterator, typename _BinaryOperation>
120336ac495dSmrg     inline _OutputIterator
120436ac495dSmrg     transform(_IIter1 __begin1, _IIter1 __end1,
120536ac495dSmrg 	      _IIter2 __begin2, _OutputIterator __result,
120636ac495dSmrg 	      _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
120736ac495dSmrg     { return _GLIBCXX_STD_A::transform(__begin1, __end1,
120836ac495dSmrg 				       __begin2, __result, __binary_op); }
120936ac495dSmrg 
121036ac495dSmrg   // Parallel binary transform for random access iterators.
121136ac495dSmrg   template<typename _RAIter1, typename _RAIter2,
121236ac495dSmrg 	   typename _RAIter3, typename _BinaryOperation>
121336ac495dSmrg     _RAIter3
121436ac495dSmrg     __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
121536ac495dSmrg 			_RAIter2 __begin2,
121636ac495dSmrg 			_RAIter3 __result, _BinaryOperation __binary_op,
121736ac495dSmrg 			random_access_iterator_tag, random_access_iterator_tag,
121836ac495dSmrg 			random_access_iterator_tag,
121936ac495dSmrg 			__gnu_parallel::_Parallelism __parallelism_tag)
122036ac495dSmrg     {
122136ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
122236ac495dSmrg 	    (__end1 - __begin1) >=
122336ac495dSmrg 		__gnu_parallel::_Settings::get().transform_minimal_n
122436ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
122536ac495dSmrg 	{
122636ac495dSmrg 	  bool __dummy = true;
122736ac495dSmrg 	  typedef __gnu_parallel::_IteratorTriple<_RAIter1,
122836ac495dSmrg 	    _RAIter2, _RAIter3,
122936ac495dSmrg 	    random_access_iterator_tag> _ItTrip;
123036ac495dSmrg 	  _ItTrip __begin_triple(__begin1, __begin2, __result),
123136ac495dSmrg 	    __end_triple(__end1, __begin2 + (__end1 - __begin1),
123236ac495dSmrg 		       __result + (__end1 - __begin1));
123336ac495dSmrg 	  __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
123436ac495dSmrg 	  __gnu_parallel::
123536ac495dSmrg 	    __for_each_template_random_access(__begin_triple, __end_triple,
123636ac495dSmrg 					      __binary_op, __functionality,
123736ac495dSmrg 					      __gnu_parallel::_DummyReduct(),
123836ac495dSmrg 					      __dummy, __dummy, -1,
123936ac495dSmrg 					      __parallelism_tag);
124036ac495dSmrg 	  return __functionality._M_finish_iterator;
124136ac495dSmrg 	}
124236ac495dSmrg       else
124336ac495dSmrg 	return transform(__begin1, __end1, __begin2, __result, __binary_op,
124436ac495dSmrg 			 __gnu_parallel::sequential_tag());
124536ac495dSmrg     }
124636ac495dSmrg 
124736ac495dSmrg   // Sequential fallback for input iterator case.
124836ac495dSmrg   template<typename _IIter1, typename _IIter2,
124936ac495dSmrg 	   typename _OutputIterator, typename _BinaryOperation,
125036ac495dSmrg 	   typename _Tag1, typename _Tag2, typename _Tag3>
125136ac495dSmrg     inline _OutputIterator
125236ac495dSmrg     __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
125336ac495dSmrg 			_IIter2 __begin2, _OutputIterator __result,
125436ac495dSmrg 			_BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
125536ac495dSmrg     { return transform(__begin1, __end1, __begin2, __result, __binary_op,
125636ac495dSmrg 		       __gnu_parallel::sequential_tag()); }
125736ac495dSmrg 
125836ac495dSmrg   // Public interface.
125936ac495dSmrg   template<typename _IIter1, typename _IIter2,
126036ac495dSmrg 	   typename _OutputIterator, typename _BinaryOperation>
126136ac495dSmrg     inline _OutputIterator
126236ac495dSmrg     transform(_IIter1 __begin1, _IIter1 __end1,
126336ac495dSmrg 	      _IIter2 __begin2, _OutputIterator __result,
126436ac495dSmrg 	      _BinaryOperation __binary_op,
126536ac495dSmrg 	      __gnu_parallel::_Parallelism __parallelism_tag)
126636ac495dSmrg     {
126736ac495dSmrg       return __transform2_switch(
126836ac495dSmrg 	       __begin1, __end1, __begin2, __result, __binary_op,
126936ac495dSmrg 	       std::__iterator_category(__begin1),
127036ac495dSmrg 	       std::__iterator_category(__begin2),
127136ac495dSmrg 	       std::__iterator_category(__result),
127236ac495dSmrg 	       __parallelism_tag);
127336ac495dSmrg     }
127436ac495dSmrg 
127536ac495dSmrg   template<typename _IIter1, typename _IIter2,
127636ac495dSmrg 	   typename _OutputIterator, typename _BinaryOperation>
127736ac495dSmrg     inline _OutputIterator
127836ac495dSmrg     transform(_IIter1 __begin1, _IIter1 __end1,
127936ac495dSmrg 	      _IIter2 __begin2, _OutputIterator __result,
128036ac495dSmrg 	      _BinaryOperation __binary_op)
128136ac495dSmrg     {
128236ac495dSmrg       return __transform2_switch(
128336ac495dSmrg 	       __begin1, __end1, __begin2, __result, __binary_op,
128436ac495dSmrg 	       std::__iterator_category(__begin1),
128536ac495dSmrg 	       std::__iterator_category(__begin2),
128636ac495dSmrg 	       std::__iterator_category(__result));
128736ac495dSmrg     }
128836ac495dSmrg 
128936ac495dSmrg   // Sequential fallback
129036ac495dSmrg   template<typename _FIterator, typename _Tp>
129136ac495dSmrg     inline void
129236ac495dSmrg     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
129336ac495dSmrg 	    const _Tp& __new_value, __gnu_parallel::sequential_tag)
129436ac495dSmrg     { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); }
129536ac495dSmrg 
129636ac495dSmrg   // Sequential fallback for input iterator case
129736ac495dSmrg   template<typename _FIterator, typename _Tp, typename _IteratorTag>
129836ac495dSmrg     inline void
129936ac495dSmrg     __replace_switch(_FIterator __begin, _FIterator __end,
130036ac495dSmrg 		     const _Tp& __old_value, const _Tp& __new_value,
130136ac495dSmrg 		     _IteratorTag)
130236ac495dSmrg     { replace(__begin, __end, __old_value, __new_value,
130336ac495dSmrg 	      __gnu_parallel::sequential_tag()); }
130436ac495dSmrg 
130536ac495dSmrg   // Parallel replace for random access iterators
130636ac495dSmrg   template<typename _RAIter, typename _Tp>
130736ac495dSmrg     inline void
130836ac495dSmrg     __replace_switch(_RAIter __begin, _RAIter __end,
130936ac495dSmrg 		     const _Tp& __old_value, const _Tp& __new_value,
131036ac495dSmrg 		     random_access_iterator_tag,
131136ac495dSmrg 		     __gnu_parallel::_Parallelism __parallelism_tag)
131236ac495dSmrg     {
131336ac495dSmrg       // XXX parallel version is where?
131436ac495dSmrg       replace(__begin, __end, __old_value, __new_value,
131536ac495dSmrg 	      __gnu_parallel::sequential_tag());
131636ac495dSmrg     }
131736ac495dSmrg 
131836ac495dSmrg   // Public interface
131936ac495dSmrg   template<typename _FIterator, typename _Tp>
132036ac495dSmrg     inline void
132136ac495dSmrg     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
132236ac495dSmrg 	    const _Tp& __new_value,
132336ac495dSmrg 	    __gnu_parallel::_Parallelism __parallelism_tag)
132436ac495dSmrg     {
132536ac495dSmrg       __replace_switch(__begin, __end, __old_value, __new_value,
132636ac495dSmrg 		       std::__iterator_category(__begin),
132736ac495dSmrg 		       __parallelism_tag);
132836ac495dSmrg     }
132936ac495dSmrg 
133036ac495dSmrg   template<typename _FIterator, typename _Tp>
133136ac495dSmrg     inline void
133236ac495dSmrg     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
133336ac495dSmrg 	    const _Tp& __new_value)
133436ac495dSmrg     {
133536ac495dSmrg       __replace_switch(__begin, __end, __old_value, __new_value,
133636ac495dSmrg 		       std::__iterator_category(__begin));
133736ac495dSmrg     }
133836ac495dSmrg 
133936ac495dSmrg 
134036ac495dSmrg   // Sequential fallback
134136ac495dSmrg   template<typename _FIterator, typename _Predicate, typename _Tp>
134236ac495dSmrg     inline void
134336ac495dSmrg     replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
134436ac495dSmrg 	       const _Tp& __new_value, __gnu_parallel::sequential_tag)
134536ac495dSmrg     { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); }
134636ac495dSmrg 
134736ac495dSmrg   // Sequential fallback for input iterator case
134836ac495dSmrg   template<typename _FIterator, typename _Predicate, typename _Tp,
134936ac495dSmrg 	   typename _IteratorTag>
135036ac495dSmrg     inline void
135136ac495dSmrg     __replace_if_switch(_FIterator __begin, _FIterator __end,
135236ac495dSmrg 			_Predicate __pred, const _Tp& __new_value, _IteratorTag)
135336ac495dSmrg     { replace_if(__begin, __end, __pred, __new_value,
135436ac495dSmrg 		 __gnu_parallel::sequential_tag()); }
135536ac495dSmrg 
135636ac495dSmrg   // Parallel algorithm for random access iterators.
135736ac495dSmrg   template<typename _RAIter, typename _Predicate, typename _Tp>
135836ac495dSmrg     void
135936ac495dSmrg     __replace_if_switch(_RAIter __begin, _RAIter __end,
136036ac495dSmrg 			_Predicate __pred, const _Tp& __new_value,
136136ac495dSmrg 			random_access_iterator_tag,
136236ac495dSmrg 			__gnu_parallel::_Parallelism __parallelism_tag)
136336ac495dSmrg     {
136436ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
136536ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
136636ac495dSmrg 	    >= __gnu_parallel::_Settings::get().replace_minimal_n
136736ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
136836ac495dSmrg 	{
136936ac495dSmrg 	  bool __dummy;
137036ac495dSmrg 	  __gnu_parallel::
137136ac495dSmrg 	    __replace_if_selector<_RAIter, _Predicate, _Tp>
137236ac495dSmrg 	    __functionality(__new_value);
137336ac495dSmrg 	  __gnu_parallel::
137436ac495dSmrg 	    __for_each_template_random_access(
137536ac495dSmrg 	      __begin, __end, __pred, __functionality,
137636ac495dSmrg 	      __gnu_parallel::_DummyReduct(),
137736ac495dSmrg 	      true, __dummy, -1, __parallelism_tag);
137836ac495dSmrg 	}
137936ac495dSmrg       else
138036ac495dSmrg 	replace_if(__begin, __end, __pred, __new_value,
138136ac495dSmrg 		   __gnu_parallel::sequential_tag());
138236ac495dSmrg     }
138336ac495dSmrg 
138436ac495dSmrg   // Public interface.
138536ac495dSmrg   template<typename _FIterator, typename _Predicate, typename _Tp>
138636ac495dSmrg     inline void
138736ac495dSmrg     replace_if(_FIterator __begin, _FIterator __end,
138836ac495dSmrg 	       _Predicate __pred, const _Tp& __new_value,
138936ac495dSmrg 	       __gnu_parallel::_Parallelism __parallelism_tag)
139036ac495dSmrg     {
139136ac495dSmrg       __replace_if_switch(__begin, __end, __pred, __new_value,
139236ac495dSmrg 			  std::__iterator_category(__begin),
139336ac495dSmrg 			  __parallelism_tag);
139436ac495dSmrg     }
139536ac495dSmrg 
139636ac495dSmrg   template<typename _FIterator, typename _Predicate, typename _Tp>
139736ac495dSmrg     inline void
139836ac495dSmrg     replace_if(_FIterator __begin, _FIterator __end,
139936ac495dSmrg 	       _Predicate __pred, const _Tp& __new_value)
140036ac495dSmrg     {
140136ac495dSmrg       __replace_if_switch(__begin, __end, __pred, __new_value,
140236ac495dSmrg 			  std::__iterator_category(__begin));
140336ac495dSmrg     }
140436ac495dSmrg 
140536ac495dSmrg   // Sequential fallback
140636ac495dSmrg   template<typename _FIterator, typename _Generator>
140736ac495dSmrg     inline void
140836ac495dSmrg     generate(_FIterator __begin, _FIterator __end, _Generator __gen,
140936ac495dSmrg 	     __gnu_parallel::sequential_tag)
141036ac495dSmrg     { _GLIBCXX_STD_A::generate(__begin, __end, __gen); }
141136ac495dSmrg 
141236ac495dSmrg   // Sequential fallback for input iterator case.
141336ac495dSmrg   template<typename _FIterator, typename _Generator, typename _IteratorTag>
141436ac495dSmrg     inline void
141536ac495dSmrg     __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
141636ac495dSmrg 		      _IteratorTag)
141736ac495dSmrg     { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
141836ac495dSmrg 
141936ac495dSmrg   // Parallel algorithm for random access iterators.
142036ac495dSmrg   template<typename _RAIter, typename _Generator>
142136ac495dSmrg     void
142236ac495dSmrg     __generate_switch(_RAIter __begin, _RAIter __end,
142336ac495dSmrg 		      _Generator __gen, random_access_iterator_tag,
142436ac495dSmrg 		      __gnu_parallel::_Parallelism __parallelism_tag)
142536ac495dSmrg     {
142636ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
142736ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
142836ac495dSmrg 	    >= __gnu_parallel::_Settings::get().generate_minimal_n
142936ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
143036ac495dSmrg 	{
143136ac495dSmrg 	  bool __dummy;
143236ac495dSmrg 	  __gnu_parallel::__generate_selector<_RAIter>
143336ac495dSmrg 	    __functionality;
143436ac495dSmrg 	  __gnu_parallel::
143536ac495dSmrg 	    __for_each_template_random_access(
143636ac495dSmrg 	      __begin, __end, __gen, __functionality,
143736ac495dSmrg 	      __gnu_parallel::_DummyReduct(),
143836ac495dSmrg 	      true, __dummy, -1, __parallelism_tag);
143936ac495dSmrg 	}
144036ac495dSmrg       else
144136ac495dSmrg 	generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
144236ac495dSmrg     }
144336ac495dSmrg 
144436ac495dSmrg   // Public interface.
144536ac495dSmrg   template<typename _FIterator, typename _Generator>
144636ac495dSmrg     inline void
144736ac495dSmrg     generate(_FIterator __begin, _FIterator __end,
144836ac495dSmrg 	     _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
144936ac495dSmrg     {
145036ac495dSmrg       __generate_switch(__begin, __end, __gen,
145136ac495dSmrg 			std::__iterator_category(__begin),
145236ac495dSmrg 			__parallelism_tag);
145336ac495dSmrg     }
145436ac495dSmrg 
145536ac495dSmrg   template<typename _FIterator, typename _Generator>
145636ac495dSmrg     inline void
145736ac495dSmrg     generate(_FIterator __begin, _FIterator __end, _Generator __gen)
145836ac495dSmrg     {
145936ac495dSmrg       __generate_switch(__begin, __end, __gen,
146036ac495dSmrg 			std::__iterator_category(__begin));
146136ac495dSmrg     }
146236ac495dSmrg 
146336ac495dSmrg 
146436ac495dSmrg   // Sequential fallback.
146536ac495dSmrg   template<typename _OutputIterator, typename _Size, typename _Generator>
146636ac495dSmrg     inline _OutputIterator
146736ac495dSmrg     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
146836ac495dSmrg 	       __gnu_parallel::sequential_tag)
146936ac495dSmrg     { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); }
147036ac495dSmrg 
147136ac495dSmrg   // Sequential fallback for input iterator case.
147236ac495dSmrg   template<typename _OutputIterator, typename _Size, typename _Generator,
147336ac495dSmrg 	   typename _IteratorTag>
147436ac495dSmrg     inline _OutputIterator
147536ac495dSmrg     __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen,
147636ac495dSmrg 			_IteratorTag)
147736ac495dSmrg     { return generate_n(__begin, __n, __gen,
147836ac495dSmrg 			__gnu_parallel::sequential_tag()); }
147936ac495dSmrg 
148036ac495dSmrg   // Parallel algorithm for random access iterators.
148136ac495dSmrg   template<typename _RAIter, typename _Size, typename _Generator>
148236ac495dSmrg     inline _RAIter
148336ac495dSmrg     __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
148436ac495dSmrg 			random_access_iterator_tag,
148536ac495dSmrg 			__gnu_parallel::_Parallelism __parallelism_tag)
148636ac495dSmrg     {
148736ac495dSmrg       // XXX parallel version is where?
148836ac495dSmrg       return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
148936ac495dSmrg     }
149036ac495dSmrg 
149136ac495dSmrg   // Public interface.
149236ac495dSmrg   template<typename _OutputIterator, typename _Size, typename _Generator>
149336ac495dSmrg     inline _OutputIterator
149436ac495dSmrg     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
149536ac495dSmrg 	       __gnu_parallel::_Parallelism __parallelism_tag)
149636ac495dSmrg     {
149736ac495dSmrg       return __generate_n_switch(__begin, __n, __gen,
149836ac495dSmrg 				 std::__iterator_category(__begin),
149936ac495dSmrg 				 __parallelism_tag);
150036ac495dSmrg     }
150136ac495dSmrg 
150236ac495dSmrg   template<typename _OutputIterator, typename _Size, typename _Generator>
150336ac495dSmrg     inline _OutputIterator
150436ac495dSmrg     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
150536ac495dSmrg     {
150636ac495dSmrg       return __generate_n_switch(__begin, __n, __gen,
150736ac495dSmrg 				 std::__iterator_category(__begin));
150836ac495dSmrg     }
150936ac495dSmrg 
151036ac495dSmrg 
151136ac495dSmrg   // Sequential fallback.
151236ac495dSmrg   template<typename _RAIter>
151336ac495dSmrg     inline void
151436ac495dSmrg     random_shuffle(_RAIter __begin, _RAIter __end,
151536ac495dSmrg 		   __gnu_parallel::sequential_tag)
151636ac495dSmrg     { _GLIBCXX_STD_A::random_shuffle(__begin, __end); }
151736ac495dSmrg 
151836ac495dSmrg   // Sequential fallback.
151936ac495dSmrg   template<typename _RAIter, typename _RandomNumberGenerator>
152036ac495dSmrg     inline void
152136ac495dSmrg     random_shuffle(_RAIter __begin, _RAIter __end,
152236ac495dSmrg 		   _RandomNumberGenerator& __rand,
152336ac495dSmrg 		   __gnu_parallel::sequential_tag)
152436ac495dSmrg     { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); }
152536ac495dSmrg 
152636ac495dSmrg 
152736ac495dSmrg   /** @brief Functor wrapper for std::rand(). */
152836ac495dSmrg   template<typename _MustBeInt = int>
152936ac495dSmrg     struct _CRandNumber
153036ac495dSmrg     {
153136ac495dSmrg       int
153236ac495dSmrg       operator()(int __limit)
153336ac495dSmrg       { return rand() % __limit; }
153436ac495dSmrg     };
153536ac495dSmrg 
153636ac495dSmrg   // Fill in random number generator.
153736ac495dSmrg   template<typename _RAIter>
153836ac495dSmrg     inline void
153936ac495dSmrg     random_shuffle(_RAIter __begin, _RAIter __end)
154036ac495dSmrg     {
154136ac495dSmrg       _CRandNumber<> __r;
154236ac495dSmrg       // Parallelization still possible.
154336ac495dSmrg       __gnu_parallel::random_shuffle(__begin, __end, __r);
154436ac495dSmrg     }
154536ac495dSmrg 
154636ac495dSmrg   // Parallel algorithm for random access iterators.
154736ac495dSmrg   template<typename _RAIter, typename _RandomNumberGenerator>
154836ac495dSmrg     void
154936ac495dSmrg     random_shuffle(_RAIter __begin, _RAIter __end,
155036ac495dSmrg #if __cplusplus >= 201103L
155136ac495dSmrg 		   _RandomNumberGenerator&& __rand)
155236ac495dSmrg #else
155336ac495dSmrg 		   _RandomNumberGenerator& __rand)
155436ac495dSmrg #endif
155536ac495dSmrg     {
155636ac495dSmrg       if (__begin == __end)
155736ac495dSmrg 	return;
155836ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
155936ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
156036ac495dSmrg 	    >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
156136ac495dSmrg 	__gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
156236ac495dSmrg       else
156336ac495dSmrg 	__gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
156436ac495dSmrg     }
156536ac495dSmrg 
156636ac495dSmrg   // Sequential fallback.
156736ac495dSmrg   template<typename _FIterator, typename _Predicate>
156836ac495dSmrg     inline _FIterator
156936ac495dSmrg     partition(_FIterator __begin, _FIterator __end,
157036ac495dSmrg 	      _Predicate __pred, __gnu_parallel::sequential_tag)
157136ac495dSmrg     { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); }
157236ac495dSmrg 
157336ac495dSmrg   // Sequential fallback for input iterator case.
157436ac495dSmrg   template<typename _FIterator, typename _Predicate, typename _IteratorTag>
157536ac495dSmrg     inline _FIterator
157636ac495dSmrg     __partition_switch(_FIterator __begin, _FIterator __end,
157736ac495dSmrg 		       _Predicate __pred, _IteratorTag)
157836ac495dSmrg     { return partition(__begin, __end, __pred,
157936ac495dSmrg 		       __gnu_parallel::sequential_tag()); }
158036ac495dSmrg 
158136ac495dSmrg   // Parallel algorithm for random access iterators.
158236ac495dSmrg   template<typename _RAIter, typename _Predicate>
158336ac495dSmrg     _RAIter
158436ac495dSmrg     __partition_switch(_RAIter __begin, _RAIter __end,
158536ac495dSmrg 		       _Predicate __pred, random_access_iterator_tag)
158636ac495dSmrg     {
158736ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
158836ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
158936ac495dSmrg 	    >= __gnu_parallel::_Settings::get().partition_minimal_n))
159036ac495dSmrg 	{
159136ac495dSmrg 	  typedef typename std::iterator_traits<_RAIter>::
159236ac495dSmrg 	    difference_type _DifferenceType;
159336ac495dSmrg 	  _DifferenceType __middle = __gnu_parallel::
159436ac495dSmrg 	    __parallel_partition(__begin, __end, __pred,
159536ac495dSmrg 			       __gnu_parallel::__get_max_threads());
159636ac495dSmrg 	  return __begin + __middle;
159736ac495dSmrg 	}
159836ac495dSmrg       else
159936ac495dSmrg 	return partition(__begin, __end, __pred,
160036ac495dSmrg 			 __gnu_parallel::sequential_tag());
160136ac495dSmrg     }
160236ac495dSmrg 
160336ac495dSmrg   // Public interface.
160436ac495dSmrg   template<typename _FIterator, typename _Predicate>
160536ac495dSmrg     inline _FIterator
160636ac495dSmrg     partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
160736ac495dSmrg     {
160836ac495dSmrg       return __partition_switch(__begin, __end, __pred,
160936ac495dSmrg 				std::__iterator_category(__begin));
161036ac495dSmrg     }
161136ac495dSmrg 
161236ac495dSmrg   // sort interface
161336ac495dSmrg 
161436ac495dSmrg   // Sequential fallback
161536ac495dSmrg   template<typename _RAIter>
161636ac495dSmrg     inline void
161736ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
161836ac495dSmrg 	 __gnu_parallel::sequential_tag)
161936ac495dSmrg     { _GLIBCXX_STD_A::sort(__begin, __end); }
162036ac495dSmrg 
162136ac495dSmrg   // Sequential fallback
162236ac495dSmrg   template<typename _RAIter, typename _Compare>
162336ac495dSmrg     inline void
162436ac495dSmrg     sort(_RAIter __begin, _RAIter __end, _Compare __comp,
162536ac495dSmrg 	 __gnu_parallel::sequential_tag)
162636ac495dSmrg     { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end,
162736ac495dSmrg 							     __comp); }
162836ac495dSmrg 
162936ac495dSmrg   // Public interface
163036ac495dSmrg   template<typename _RAIter, typename _Compare,
163136ac495dSmrg 	   typename _Parallelism>
163236ac495dSmrg     void
163336ac495dSmrg     sort(_RAIter __begin, _RAIter __end, _Compare __comp,
163436ac495dSmrg 	 _Parallelism __parallelism)
163536ac495dSmrg   {
163636ac495dSmrg     typedef typename iterator_traits<_RAIter>::value_type _ValueType;
163736ac495dSmrg 
163836ac495dSmrg     if (__begin != __end)
163936ac495dSmrg       {
164036ac495dSmrg 	if (_GLIBCXX_PARALLEL_CONDITION(
164136ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
164236ac495dSmrg 	      __gnu_parallel::_Settings::get().sort_minimal_n))
164336ac495dSmrg 	  __gnu_parallel::__parallel_sort<false>(
164436ac495dSmrg 			    __begin, __end, __comp, __parallelism);
164536ac495dSmrg 	else
164636ac495dSmrg 	  sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
164736ac495dSmrg       }
164836ac495dSmrg   }
164936ac495dSmrg 
165036ac495dSmrg   // Public interface, insert default comparator
165136ac495dSmrg   template<typename _RAIter>
165236ac495dSmrg     inline void
165336ac495dSmrg     sort(_RAIter __begin, _RAIter __end)
165436ac495dSmrg     {
165536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
165636ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(),
165736ac495dSmrg 	   __gnu_parallel::default_parallel_tag());
165836ac495dSmrg     }
165936ac495dSmrg 
166036ac495dSmrg   // Public interface, insert default comparator
166136ac495dSmrg   template<typename _RAIter>
166236ac495dSmrg     inline void
166336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
166436ac495dSmrg 	 __gnu_parallel::default_parallel_tag __parallelism)
166536ac495dSmrg     {
166636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
166736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
166836ac495dSmrg     }
166936ac495dSmrg 
167036ac495dSmrg   // Public interface, insert default comparator
167136ac495dSmrg   template<typename _RAIter>
167236ac495dSmrg     inline void
167336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
167436ac495dSmrg 	 __gnu_parallel::parallel_tag __parallelism)
167536ac495dSmrg     {
167636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
167736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
167836ac495dSmrg     }
167936ac495dSmrg 
168036ac495dSmrg   // Public interface, insert default comparator
168136ac495dSmrg   template<typename _RAIter>
168236ac495dSmrg     inline void
168336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
168436ac495dSmrg 	 __gnu_parallel::multiway_mergesort_tag __parallelism)
168536ac495dSmrg     {
168636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
168736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
168836ac495dSmrg     }
168936ac495dSmrg 
169036ac495dSmrg   // Public interface, insert default comparator
169136ac495dSmrg   template<typename _RAIter>
169236ac495dSmrg     inline void
169336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
169436ac495dSmrg 	 __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
169536ac495dSmrg     {
169636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
169736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
169836ac495dSmrg     }
169936ac495dSmrg 
170036ac495dSmrg   // Public interface, insert default comparator
170136ac495dSmrg   template<typename _RAIter>
170236ac495dSmrg     inline void
170336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
170436ac495dSmrg 	 __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
170536ac495dSmrg     {
170636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
170736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
170836ac495dSmrg     }
170936ac495dSmrg 
171036ac495dSmrg   // Public interface, insert default comparator
171136ac495dSmrg   template<typename _RAIter>
171236ac495dSmrg     inline void
171336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
171436ac495dSmrg 	 __gnu_parallel::quicksort_tag __parallelism)
171536ac495dSmrg     {
171636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
171736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
171836ac495dSmrg     }
171936ac495dSmrg 
172036ac495dSmrg   // Public interface, insert default comparator
172136ac495dSmrg   template<typename _RAIter>
172236ac495dSmrg     inline void
172336ac495dSmrg     sort(_RAIter __begin, _RAIter __end,
172436ac495dSmrg 	 __gnu_parallel::balanced_quicksort_tag __parallelism)
172536ac495dSmrg     {
172636ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
172736ac495dSmrg       sort(__begin, __end, std::less<_ValueType>(), __parallelism);
172836ac495dSmrg     }
172936ac495dSmrg 
173036ac495dSmrg   // Public interface
173136ac495dSmrg   template<typename _RAIter, typename _Compare>
173236ac495dSmrg     void
173336ac495dSmrg     sort(_RAIter __begin, _RAIter __end, _Compare __comp)
173436ac495dSmrg     {
173536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
173636ac495dSmrg       sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
173736ac495dSmrg     }
173836ac495dSmrg 
173936ac495dSmrg   // stable_sort interface
174036ac495dSmrg 
174136ac495dSmrg 
174236ac495dSmrg   // Sequential fallback
174336ac495dSmrg   template<typename _RAIter>
174436ac495dSmrg     inline void
174536ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
174636ac495dSmrg 		__gnu_parallel::sequential_tag)
174736ac495dSmrg     { _GLIBCXX_STD_A::stable_sort(__begin, __end); }
174836ac495dSmrg 
174936ac495dSmrg   // Sequential fallback
175036ac495dSmrg   template<typename _RAIter, typename _Compare>
175136ac495dSmrg     inline void
175236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
175336ac495dSmrg 		_Compare __comp, __gnu_parallel::sequential_tag)
175436ac495dSmrg     { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); }
175536ac495dSmrg 
175636ac495dSmrg   // Public interface
175736ac495dSmrg   template<typename _RAIter, typename _Compare,
175836ac495dSmrg 	   typename _Parallelism>
175936ac495dSmrg     void
176036ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
176136ac495dSmrg 		_Compare __comp, _Parallelism __parallelism)
176236ac495dSmrg     {
176336ac495dSmrg       typedef iterator_traits<_RAIter> _TraitsType;
176436ac495dSmrg       typedef typename _TraitsType::value_type _ValueType;
176536ac495dSmrg 
176636ac495dSmrg       if (__begin != __end)
176736ac495dSmrg 	{
176836ac495dSmrg 	  if (_GLIBCXX_PARALLEL_CONDITION(
176936ac495dSmrg 		static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
177036ac495dSmrg 		__gnu_parallel::_Settings::get().sort_minimal_n))
177136ac495dSmrg 	    __gnu_parallel::__parallel_sort<true>(__begin, __end,
177236ac495dSmrg 						  __comp, __parallelism);
177336ac495dSmrg 	  else
177436ac495dSmrg 	    stable_sort(__begin, __end, __comp,
177536ac495dSmrg 			__gnu_parallel::sequential_tag());
177636ac495dSmrg 	}
177736ac495dSmrg     }
177836ac495dSmrg 
177936ac495dSmrg   // Public interface, insert default comparator
178036ac495dSmrg   template<typename _RAIter>
178136ac495dSmrg     inline void
178236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end)
178336ac495dSmrg     {
178436ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
178536ac495dSmrg       stable_sort(__begin, __end, std::less<_ValueType>(),
178636ac495dSmrg 		  __gnu_parallel::default_parallel_tag());
178736ac495dSmrg     }
178836ac495dSmrg 
178936ac495dSmrg   // Public interface, insert default comparator
179036ac495dSmrg   template<typename _RAIter>
179136ac495dSmrg     inline void
179236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
179336ac495dSmrg 		__gnu_parallel::default_parallel_tag __parallelism)
179436ac495dSmrg     {
179536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
179636ac495dSmrg       stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
179736ac495dSmrg     }
179836ac495dSmrg 
179936ac495dSmrg   // Public interface, insert default comparator
180036ac495dSmrg   template<typename _RAIter>
180136ac495dSmrg     inline void
180236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
180336ac495dSmrg 		__gnu_parallel::parallel_tag __parallelism)
180436ac495dSmrg     {
180536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
180636ac495dSmrg       stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
180736ac495dSmrg     }
180836ac495dSmrg 
180936ac495dSmrg   // Public interface, insert default comparator
181036ac495dSmrg   template<typename _RAIter>
181136ac495dSmrg     inline void
181236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
181336ac495dSmrg 		__gnu_parallel::multiway_mergesort_tag __parallelism)
181436ac495dSmrg     {
181536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
181636ac495dSmrg       stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
181736ac495dSmrg     }
181836ac495dSmrg 
181936ac495dSmrg   // Public interface, insert default comparator
182036ac495dSmrg   template<typename _RAIter>
182136ac495dSmrg     inline void
182236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
182336ac495dSmrg 		__gnu_parallel::quicksort_tag __parallelism)
182436ac495dSmrg     {
182536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
182636ac495dSmrg       stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
182736ac495dSmrg     }
182836ac495dSmrg 
182936ac495dSmrg   // Public interface, insert default comparator
183036ac495dSmrg   template<typename _RAIter>
183136ac495dSmrg     inline void
183236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end,
183336ac495dSmrg 		__gnu_parallel::balanced_quicksort_tag __parallelism)
183436ac495dSmrg     {
183536ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
183636ac495dSmrg       stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
183736ac495dSmrg     }
183836ac495dSmrg 
183936ac495dSmrg   // Public interface
184036ac495dSmrg   template<typename _RAIter, typename _Compare>
184136ac495dSmrg     void
184236ac495dSmrg     stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp)
184336ac495dSmrg     {
184436ac495dSmrg       stable_sort(
184536ac495dSmrg 	__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
184636ac495dSmrg     }
184736ac495dSmrg 
184836ac495dSmrg   // Sequential fallback
184936ac495dSmrg   template<typename _IIter1, typename _IIter2,
185036ac495dSmrg 	   typename _OutputIterator>
185136ac495dSmrg     inline _OutputIterator
185236ac495dSmrg     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
185336ac495dSmrg 	  _IIter2 __end2, _OutputIterator __result,
185436ac495dSmrg 	  __gnu_parallel::sequential_tag)
185536ac495dSmrg     { return _GLIBCXX_STD_A::merge(
185636ac495dSmrg 	       __begin1, __end1, __begin2, __end2, __result); }
185736ac495dSmrg 
185836ac495dSmrg   // Sequential fallback
185936ac495dSmrg   template<typename _IIter1, typename _IIter2,
186036ac495dSmrg 	   typename _OutputIterator, typename _Compare>
186136ac495dSmrg     inline _OutputIterator
186236ac495dSmrg     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
186336ac495dSmrg 	  _IIter2 __end2, _OutputIterator __result, _Compare __comp,
186436ac495dSmrg 	  __gnu_parallel::sequential_tag)
186536ac495dSmrg     { return _GLIBCXX_STD_A::merge(
186636ac495dSmrg 		__begin1, __end1, __begin2, __end2, __result, __comp); }
186736ac495dSmrg 
186836ac495dSmrg   // Sequential fallback for input iterator case
186936ac495dSmrg   template<typename _IIter1, typename _IIter2, typename _OutputIterator,
187036ac495dSmrg 	   typename _Compare, typename _IteratorTag1,
187136ac495dSmrg 	   typename _IteratorTag2, typename _IteratorTag3>
187236ac495dSmrg     inline _OutputIterator
187336ac495dSmrg     __merge_switch(_IIter1 __begin1, _IIter1 __end1,
187436ac495dSmrg 		   _IIter2 __begin2, _IIter2 __end2,
187536ac495dSmrg 		   _OutputIterator __result, _Compare __comp,
187636ac495dSmrg 		   _IteratorTag1, _IteratorTag2, _IteratorTag3)
187736ac495dSmrg      { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2,
187836ac495dSmrg 				    __result, __comp); }
187936ac495dSmrg 
188036ac495dSmrg   // Parallel algorithm for random access iterators
188136ac495dSmrg   template<typename _IIter1, typename _IIter2,
188236ac495dSmrg 	   typename _OutputIterator, typename _Compare>
188336ac495dSmrg     _OutputIterator
188436ac495dSmrg     __merge_switch(_IIter1 __begin1, _IIter1 __end1,
188536ac495dSmrg 		   _IIter2 __begin2, _IIter2 __end2,
188636ac495dSmrg 		   _OutputIterator __result, _Compare __comp,
188736ac495dSmrg 		   random_access_iterator_tag, random_access_iterator_tag,
188836ac495dSmrg 		   random_access_iterator_tag)
188936ac495dSmrg     {
189036ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
189136ac495dSmrg 	    (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
189236ac495dSmrg 	     >= __gnu_parallel::_Settings::get().merge_minimal_n
189336ac495dSmrg 	     || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
189436ac495dSmrg 	     >= __gnu_parallel::_Settings::get().merge_minimal_n)))
189536ac495dSmrg 	return __gnu_parallel::__parallel_merge_advance(
189636ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result,
189736ac495dSmrg 		 (__end1 - __begin1) + (__end2 - __begin2), __comp);
189836ac495dSmrg       else
189936ac495dSmrg 	return __gnu_parallel::__merge_advance(
190036ac495dSmrg 		 __begin1, __end1, __begin2, __end2, __result,
190136ac495dSmrg 		 (__end1 - __begin1) + (__end2 - __begin2), __comp);
190236ac495dSmrg   }
190336ac495dSmrg 
190436ac495dSmrg   // Public interface
190536ac495dSmrg   template<typename _IIter1, typename _IIter2,
190636ac495dSmrg 	   typename _OutputIterator, typename _Compare>
190736ac495dSmrg     inline _OutputIterator
190836ac495dSmrg     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
190936ac495dSmrg 	  _IIter2 __end2, _OutputIterator __result, _Compare __comp)
191036ac495dSmrg     {
191136ac495dSmrg       return __merge_switch(
191236ac495dSmrg 		__begin1, __end1, __begin2, __end2, __result, __comp,
191336ac495dSmrg 		std::__iterator_category(__begin1),
191436ac495dSmrg 		std::__iterator_category(__begin2),
191536ac495dSmrg 		std::__iterator_category(__result));
191636ac495dSmrg   }
191736ac495dSmrg 
191836ac495dSmrg   // Public interface, insert default comparator
191936ac495dSmrg   template<typename _IIter1, typename _IIter2,
192036ac495dSmrg 	   typename _OutputIterator>
192136ac495dSmrg     inline _OutputIterator
192236ac495dSmrg     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
192336ac495dSmrg 	  _IIter2 __end2, _OutputIterator __result)
192436ac495dSmrg     {
192536ac495dSmrg       typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
192636ac495dSmrg       typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;
192736ac495dSmrg 
192836ac495dSmrg       return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2,
192936ac495dSmrg 		__result, __gnu_parallel::_Less<_ValueType1, _ValueType2>());
193036ac495dSmrg     }
193136ac495dSmrg 
193236ac495dSmrg   // Sequential fallback
193336ac495dSmrg   template<typename _RAIter>
193436ac495dSmrg     inline void
193536ac495dSmrg     nth_element(_RAIter __begin, _RAIter __nth,
193636ac495dSmrg 		_RAIter __end, __gnu_parallel::sequential_tag)
193736ac495dSmrg     { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); }
193836ac495dSmrg 
193936ac495dSmrg   // Sequential fallback
194036ac495dSmrg   template<typename _RAIter, typename _Compare>
194136ac495dSmrg     inline void
194236ac495dSmrg     nth_element(_RAIter __begin, _RAIter __nth,
194336ac495dSmrg 		_RAIter __end, _Compare __comp,
194436ac495dSmrg 		__gnu_parallel::sequential_tag)
194536ac495dSmrg     { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); }
194636ac495dSmrg 
194736ac495dSmrg   // Public interface
194836ac495dSmrg   template<typename _RAIter, typename _Compare>
194936ac495dSmrg     inline void
195036ac495dSmrg     nth_element(_RAIter __begin, _RAIter __nth,
195136ac495dSmrg 		_RAIter __end, _Compare __comp)
195236ac495dSmrg     {
195336ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
195436ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
195536ac495dSmrg 	    >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
195636ac495dSmrg 	__gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
195736ac495dSmrg       else
195836ac495dSmrg 	nth_element(__begin, __nth, __end, __comp,
195936ac495dSmrg 		    __gnu_parallel::sequential_tag());
196036ac495dSmrg     }
196136ac495dSmrg 
196236ac495dSmrg   // Public interface, insert default comparator
196336ac495dSmrg   template<typename _RAIter>
196436ac495dSmrg     inline void
196536ac495dSmrg     nth_element(_RAIter __begin, _RAIter __nth,
196636ac495dSmrg 		_RAIter __end)
196736ac495dSmrg     {
196836ac495dSmrg       typedef typename iterator_traits<_RAIter>::value_type _ValueType;
196936ac495dSmrg       __gnu_parallel::nth_element(__begin, __nth, __end,
197036ac495dSmrg 				  std::less<_ValueType>());
197136ac495dSmrg     }
197236ac495dSmrg 
197336ac495dSmrg   // Sequential fallback
197436ac495dSmrg   template<typename _RAIter, typename _Compare>
197536ac495dSmrg     inline void
197636ac495dSmrg     partial_sort(_RAIter __begin, _RAIter __middle,
197736ac495dSmrg 		 _RAIter __end, _Compare __comp,
197836ac495dSmrg 		 __gnu_parallel::sequential_tag)
197936ac495dSmrg     { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); }
198036ac495dSmrg 
198136ac495dSmrg   // Sequential fallback
198236ac495dSmrg   template<typename _RAIter>
198336ac495dSmrg     inline void
198436ac495dSmrg     partial_sort(_RAIter __begin, _RAIter __middle,
198536ac495dSmrg 		 _RAIter __end, __gnu_parallel::sequential_tag)
198636ac495dSmrg     { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); }
198736ac495dSmrg 
198836ac495dSmrg   // Public interface, parallel algorithm for random access iterators
198936ac495dSmrg   template<typename _RAIter, typename _Compare>
199036ac495dSmrg     void
199136ac495dSmrg     partial_sort(_RAIter __begin, _RAIter __middle,
199236ac495dSmrg 		 _RAIter __end, _Compare __comp)
199336ac495dSmrg     {
199436ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
199536ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
199636ac495dSmrg 	    >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
199736ac495dSmrg 	__gnu_parallel::
199836ac495dSmrg 	  __parallel_partial_sort(__begin, __middle, __end, __comp);
199936ac495dSmrg       else
200036ac495dSmrg 	partial_sort(__begin, __middle, __end, __comp,
200136ac495dSmrg 		     __gnu_parallel::sequential_tag());
200236ac495dSmrg     }
200336ac495dSmrg 
200436ac495dSmrg   // Public interface, insert default comparator
200536ac495dSmrg   template<typename _RAIter>
200636ac495dSmrg     inline void
200736ac495dSmrg     partial_sort(_RAIter __begin, _RAIter __middle,
200836ac495dSmrg 		 _RAIter __end)
200936ac495dSmrg     {
201036ac495dSmrg       typedef iterator_traits<_RAIter> _TraitsType;
201136ac495dSmrg       typedef typename _TraitsType::value_type _ValueType;
201236ac495dSmrg       __gnu_parallel::partial_sort(__begin, __middle, __end,
201336ac495dSmrg 				   std::less<_ValueType>());
201436ac495dSmrg     }
201536ac495dSmrg 
201636ac495dSmrg   // Sequential fallback
201736ac495dSmrg   template<typename _FIterator>
201836ac495dSmrg     inline _FIterator
201936ac495dSmrg     max_element(_FIterator __begin, _FIterator __end,
202036ac495dSmrg 		__gnu_parallel::sequential_tag)
202136ac495dSmrg     { return _GLIBCXX_STD_A::max_element(__begin, __end); }
202236ac495dSmrg 
202336ac495dSmrg   // Sequential fallback
202436ac495dSmrg   template<typename _FIterator, typename _Compare>
202536ac495dSmrg     inline _FIterator
202636ac495dSmrg     max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
202736ac495dSmrg 		__gnu_parallel::sequential_tag)
202836ac495dSmrg     { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); }
202936ac495dSmrg 
203036ac495dSmrg   // Sequential fallback for input iterator case
203136ac495dSmrg   template<typename _FIterator, typename _Compare, typename _IteratorTag>
203236ac495dSmrg     inline _FIterator
203336ac495dSmrg     __max_element_switch(_FIterator __begin, _FIterator __end,
203436ac495dSmrg 		       _Compare __comp, _IteratorTag)
203536ac495dSmrg     { return max_element(__begin, __end, __comp,
203636ac495dSmrg 			 __gnu_parallel::sequential_tag()); }
203736ac495dSmrg 
203836ac495dSmrg   // Parallel algorithm for random access iterators
203936ac495dSmrg   template<typename _RAIter, typename _Compare>
204036ac495dSmrg     _RAIter
204136ac495dSmrg     __max_element_switch(_RAIter __begin, _RAIter __end,
204236ac495dSmrg 			 _Compare __comp, random_access_iterator_tag,
204336ac495dSmrg 			 __gnu_parallel::_Parallelism __parallelism_tag)
204436ac495dSmrg     {
204536ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
204636ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
204736ac495dSmrg 	    >= __gnu_parallel::_Settings::get().max_element_minimal_n
204836ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
204936ac495dSmrg 	{
205036ac495dSmrg 	  _RAIter __res(__begin);
205136ac495dSmrg 	  __gnu_parallel::__identity_selector<_RAIter>
205236ac495dSmrg 	    __functionality;
205336ac495dSmrg 	  __gnu_parallel::
205436ac495dSmrg 	    __for_each_template_random_access(
205536ac495dSmrg 	      __begin, __end, __gnu_parallel::_Nothing(), __functionality,
205636ac495dSmrg 	      __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
205736ac495dSmrg 	      __res, __res, -1, __parallelism_tag);
205836ac495dSmrg 	  return __res;
205936ac495dSmrg 	}
206036ac495dSmrg       else
206136ac495dSmrg 	return max_element(__begin, __end, __comp,
206236ac495dSmrg 			   __gnu_parallel::sequential_tag());
206336ac495dSmrg     }
206436ac495dSmrg 
206536ac495dSmrg   // Public interface, insert default comparator
206636ac495dSmrg   template<typename _FIterator>
206736ac495dSmrg     inline _FIterator
206836ac495dSmrg     max_element(_FIterator __begin, _FIterator __end,
206936ac495dSmrg 		__gnu_parallel::_Parallelism __parallelism_tag)
207036ac495dSmrg     {
207136ac495dSmrg       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
207236ac495dSmrg       return max_element(__begin, __end, std::less<_ValueType>(),
207336ac495dSmrg 			 __parallelism_tag);
207436ac495dSmrg     }
207536ac495dSmrg 
207636ac495dSmrg   template<typename _FIterator>
207736ac495dSmrg     inline _FIterator
207836ac495dSmrg     max_element(_FIterator __begin, _FIterator __end)
207936ac495dSmrg     {
208036ac495dSmrg       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
208136ac495dSmrg       return __gnu_parallel::max_element(__begin, __end,
208236ac495dSmrg 					 std::less<_ValueType>());
208336ac495dSmrg     }
208436ac495dSmrg 
208536ac495dSmrg   // Public interface
208636ac495dSmrg   template<typename _FIterator, typename _Compare>
208736ac495dSmrg     inline _FIterator
208836ac495dSmrg     max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
208936ac495dSmrg 		__gnu_parallel::_Parallelism __parallelism_tag)
209036ac495dSmrg     {
209136ac495dSmrg       return __max_element_switch(__begin, __end, __comp,
209236ac495dSmrg 				  std::__iterator_category(__begin),
209336ac495dSmrg 				  __parallelism_tag);
209436ac495dSmrg     }
209536ac495dSmrg 
209636ac495dSmrg   template<typename _FIterator, typename _Compare>
209736ac495dSmrg     inline _FIterator
209836ac495dSmrg     max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
209936ac495dSmrg     {
210036ac495dSmrg       return __max_element_switch(__begin, __end, __comp,
210136ac495dSmrg 				  std::__iterator_category(__begin));
210236ac495dSmrg     }
210336ac495dSmrg 
210436ac495dSmrg 
210536ac495dSmrg   // Sequential fallback
210636ac495dSmrg   template<typename _FIterator>
210736ac495dSmrg     inline _FIterator
210836ac495dSmrg     min_element(_FIterator __begin, _FIterator __end,
210936ac495dSmrg 		__gnu_parallel::sequential_tag)
211036ac495dSmrg     { return _GLIBCXX_STD_A::min_element(__begin, __end); }
211136ac495dSmrg 
211236ac495dSmrg   // Sequential fallback
211336ac495dSmrg   template<typename _FIterator, typename _Compare>
211436ac495dSmrg     inline _FIterator
211536ac495dSmrg     min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
211636ac495dSmrg 		__gnu_parallel::sequential_tag)
211736ac495dSmrg     { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); }
211836ac495dSmrg 
211936ac495dSmrg   // Sequential fallback for input iterator case
212036ac495dSmrg   template<typename _FIterator, typename _Compare, typename _IteratorTag>
212136ac495dSmrg     inline _FIterator
212236ac495dSmrg     __min_element_switch(_FIterator __begin, _FIterator __end,
212336ac495dSmrg 		       _Compare __comp, _IteratorTag)
212436ac495dSmrg     { return min_element(__begin, __end, __comp,
212536ac495dSmrg 			 __gnu_parallel::sequential_tag()); }
212636ac495dSmrg 
212736ac495dSmrg   // Parallel algorithm for random access iterators
212836ac495dSmrg   template<typename _RAIter, typename _Compare>
212936ac495dSmrg     _RAIter
213036ac495dSmrg     __min_element_switch(_RAIter __begin, _RAIter __end,
213136ac495dSmrg 			 _Compare __comp, random_access_iterator_tag,
213236ac495dSmrg 			 __gnu_parallel::_Parallelism __parallelism_tag)
213336ac495dSmrg     {
213436ac495dSmrg       if (_GLIBCXX_PARALLEL_CONDITION(
213536ac495dSmrg 	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
213636ac495dSmrg 	    >= __gnu_parallel::_Settings::get().min_element_minimal_n
213736ac495dSmrg 	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
213836ac495dSmrg 	{
213936ac495dSmrg 	  _RAIter __res(__begin);
214036ac495dSmrg 	  __gnu_parallel::__identity_selector<_RAIter>
214136ac495dSmrg 	    __functionality;
214236ac495dSmrg 	  __gnu_parallel::
214336ac495dSmrg 	    __for_each_template_random_access(
214436ac495dSmrg 	      __begin, __end, __gnu_parallel::_Nothing(), __functionality,
214536ac495dSmrg 	      __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
214636ac495dSmrg 	      __res, __res, -1, __parallelism_tag);
214736ac495dSmrg 	  return __res;
214836ac495dSmrg 	}
214936ac495dSmrg       else
215036ac495dSmrg 	return min_element(__begin, __end, __comp,
215136ac495dSmrg 			   __gnu_parallel::sequential_tag());
215236ac495dSmrg     }
215336ac495dSmrg 
215436ac495dSmrg   // Public interface, insert default comparator
215536ac495dSmrg   template<typename _FIterator>
215636ac495dSmrg     inline _FIterator
215736ac495dSmrg     min_element(_FIterator __begin, _FIterator __end,
215836ac495dSmrg 		__gnu_parallel::_Parallelism __parallelism_tag)
215936ac495dSmrg     {
216036ac495dSmrg       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
216136ac495dSmrg       return min_element(__begin, __end, std::less<_ValueType>(),
216236ac495dSmrg 			 __parallelism_tag);
216336ac495dSmrg     }
216436ac495dSmrg 
216536ac495dSmrg   template<typename _FIterator>
216636ac495dSmrg     inline _FIterator
216736ac495dSmrg     min_element(_FIterator __begin, _FIterator __end)
216836ac495dSmrg     {
216936ac495dSmrg       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
217036ac495dSmrg       return __gnu_parallel::min_element(__begin, __end,
217136ac495dSmrg 					 std::less<_ValueType>());
217236ac495dSmrg     }
217336ac495dSmrg 
217436ac495dSmrg   // Public interface
217536ac495dSmrg   template<typename _FIterator, typename _Compare>
217636ac495dSmrg     inline _FIterator
217736ac495dSmrg     min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
217836ac495dSmrg 		__gnu_parallel::_Parallelism __parallelism_tag)
217936ac495dSmrg     {
218036ac495dSmrg       return __min_element_switch(__begin, __end, __comp,
218136ac495dSmrg 				  std::__iterator_category(__begin),
218236ac495dSmrg 				  __parallelism_tag);
218336ac495dSmrg     }
218436ac495dSmrg 
218536ac495dSmrg   template<typename _FIterator, typename _Compare>
218636ac495dSmrg     inline _FIterator
218736ac495dSmrg     min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
218836ac495dSmrg     {
218936ac495dSmrg       return __min_element_switch(__begin, __end, __comp,
219036ac495dSmrg 				  std::__iterator_category(__begin));
219136ac495dSmrg     }
2192*8feb0f0bSmrg 
2193*8feb0f0bSmrg #if __cplusplus >= 201703L
2194*8feb0f0bSmrg   using _GLIBCXX_STD_A::for_each_n;
2195*8feb0f0bSmrg   using _GLIBCXX_STD_A::sample;
2196*8feb0f0bSmrg #endif
219736ac495dSmrg } // end namespace
219836ac495dSmrg } // end namespace
219936ac495dSmrg 
220036ac495dSmrg #endif /* _GLIBCXX_PARALLEL_ALGO_H */
2201