algo.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 3, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file parallel/algo.h
00026  *  @brief Parallel STL function calls corresponding to the stl_algo.h header.
00027  *
00028  *  The functions defined here mainly do case switches and
00029  *  call the actual parallelized versions in other files.
00030  *  Inlining policy: Functions that basically only contain one function call,
00031  *  are declared inline.
00032  *  This file is a GNU parallel extension to the Standard C++ Library.
00033  */
00034 
00035 // Written by Johannes Singler and Felix Putze.
00036 
00037 #ifndef _GLIBCXX_PARALLEL_ALGO_H
00038 #define _GLIBCXX_PARALLEL_ALGO_H 1
00039 
00040 #include <parallel/algorithmfwd.h>
00041 #include <bits/stl_algobase.h>
00042 #include <bits/stl_algo.h>
00043 #include <parallel/iterator.h>
00044 #include <parallel/base.h>
00045 #include <parallel/sort.h>
00046 #include <parallel/workstealing.h>
00047 #include <parallel/par_loop.h>
00048 #include <parallel/omp_loop.h>
00049 #include <parallel/omp_loop_static.h>
00050 #include <parallel/for_each_selectors.h>
00051 #include <parallel/for_each.h>
00052 #include <parallel/find.h>
00053 #include <parallel/find_selectors.h>
00054 #include <parallel/search.h>
00055 #include <parallel/random_shuffle.h>
00056 #include <parallel/partition.h>
00057 #include <parallel/merge.h>
00058 #include <parallel/unique_copy.h>
00059 #include <parallel/set_operations.h>
00060 
00061 namespace std
00062 {
00063 namespace __parallel
00064 {
00065   // Sequential fallback
00066   template<typename _IIter, typename _Function>
00067     inline _Function
00068     for_each(_IIter __begin, _IIter __end, _Function __f, 
00069              __gnu_parallel::sequential_tag)
00070     { return _GLIBCXX_STD_P::for_each(__begin, __end, __f); }
00071 
00072 
00073   // Sequential fallback for input iterator case
00074   template<typename _IIter, typename _Function, typename _IteratorTag>
00075     inline _Function
00076     __for_each_switch(_IIter __begin, _IIter __end, _Function __f, 
00077                     _IteratorTag)
00078     { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }
00079 
00080   // Parallel algorithm for random access iterators
00081   template<typename _RAIter, typename _Function>
00082     _Function
00083     __for_each_switch(_RAIter __begin, _RAIter __end, 
00084                     _Function __f, random_access_iterator_tag, 
00085                     __gnu_parallel::_Parallelism __parallelism_tag
00086                     = __gnu_parallel::parallel_balanced)
00087     {
00088       if (_GLIBCXX_PARALLEL_CONDITION(
00089             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
00090             >= __gnu_parallel::_Settings::get().for_each_minimal_n
00091             && __gnu_parallel::__is_parallel(__parallelism_tag)))
00092         {
00093           bool __dummy;
00094     __gnu_parallel::__for_each_selector<_RAIter> __functionality;
00095 
00096           return __gnu_parallel::
00097             __for_each_template_random_access(
00098               __begin, __end, __f, __functionality,
00099               __gnu_parallel::_DummyReduct(), true, __dummy, -1,
00100               __parallelism_tag);
00101         }
00102       else
00103         return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
00104     }
00105 
00106   // Public interface
00107   template<typename _Iterator, typename _Function>
00108     inline _Function
00109     for_each(_Iterator __begin, _Iterator __end, _Function __f, 
00110              __gnu_parallel::_Parallelism __parallelism_tag)
00111     {
00112       typedef std::iterator_traits<_Iterator> _IteratorTraits;
00113       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
00114       return __for_each_switch(__begin, __end, __f, _IteratorCategory(), 
00115                              __parallelism_tag);
00116     }
00117 
00118   template<typename _Iterator, typename _Function>
00119     inline _Function
00120     for_each(_Iterator __begin, _Iterator __end, _Function __f) 
00121     {
00122       typedef std::iterator_traits<_Iterator> _IteratorTraits;
00123       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
00124       return __for_each_switch(__begin, __end, __f, _IteratorCategory());
00125     }
00126 
00127 
00128   // Sequential fallback
00129   template<typename _IIter, typename _Tp>
00130     inline _IIter
00131     find(_IIter __begin, _IIter __end, const _Tp& __val, 
00132          __gnu_parallel::sequential_tag)
00133     { return _GLIBCXX_STD_P::find(__begin, __end, __val); }
00134 
00135   // Sequential fallback for input iterator case
00136   template<typename _IIter, typename _Tp, typename _IteratorTag>
00137     inline _IIter
00138     __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
00139                 _IteratorTag)
00140     { return _GLIBCXX_STD_P::find(__begin, __end, __val); }
00141 
00142   // Parallel find for random access iterators
00143   template<typename _RAIter, typename _Tp>
00144     _RAIter
00145     __find_switch(_RAIter __begin, _RAIter __end,
00146                 const _Tp& __val, random_access_iterator_tag)
00147     {
00148       typedef iterator_traits<_RAIter> _TraitsType;
00149       typedef typename _TraitsType::value_type _ValueType;
00150 
00151       if (_GLIBCXX_PARALLEL_CONDITION(true))
00152         {
00153           binder2nd<__gnu_parallel::_EqualTo<_ValueType, const _Tp&> >
00154             __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
00155           return __gnu_parallel::__find_template(
00156                    __begin, __end, __begin, __comp,
00157                    __gnu_parallel::__find_if_selector()).first;
00158         }
00159       else
00160         return _GLIBCXX_STD_P::find(__begin, __end, __val);
00161     }
00162 
00163   // Public interface
00164   template<typename _IIter, typename _Tp>
00165     inline _IIter
00166     find(_IIter __begin, _IIter __end, const _Tp& __val)
00167     {
00168       typedef std::iterator_traits<_IIter> _IteratorTraits;
00169       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
00170       return __find_switch(__begin, __end, __val, _IteratorCategory());
00171     }
00172 
00173   // Sequential fallback
00174   template<typename _IIter, typename _Predicate>
00175     inline _IIter
00176     find_if(_IIter __begin, _IIter __end, _Predicate __pred, 
00177             __gnu_parallel::sequential_tag)
00178     { return _GLIBCXX_STD_P::find_if(__begin, __end, __pred); }
00179 
00180   // Sequential fallback for input iterator case
00181   template<typename _IIter, typename _Predicate, typename _IteratorTag>
00182     inline _IIter
00183     __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, 
00184                    _IteratorTag)
00185     { return _GLIBCXX_STD_P::find_if(__begin, __end, __pred); }
00186 
00187   // Parallel find_if for random access iterators
00188   template<typename _RAIter, typename _Predicate>
00189     _RAIter
00190     __find_if_switch(_RAIter __begin, _RAIter __end, 
00191                    _Predicate __pred, random_access_iterator_tag)
00192     {
00193       if (_GLIBCXX_PARALLEL_CONDITION(true))
00194         return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
00195                                              __gnu_parallel::
00196                                              __find_if_selector()).first;
00197       else
00198         return _GLIBCXX_STD_P::find_if(__begin, __end, __pred);
00199     }
00200 
00201   // Public interface
00202   template<typename _IIter, typename _Predicate>
00203     inline _IIter
00204     find_if(_IIter __begin, _IIter __end, _Predicate __pred)
00205     {
00206       typedef std::iterator_traits<_IIter> _IteratorTraits;
00207       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
00208       return __find_if_switch(__begin, __end, __pred, _IteratorCategory());
00209     }
00210 
00211   // Sequential fallback
00212   template<typename _IIter, typename _FIterator>
00213     inline _IIter
00214     find_first_of(_IIter __begin1, _IIter __end1, 
00215                   _FIterator __begin2, _FIterator __end2, 
00216                   __gnu_parallel::sequential_tag)
00217     { return _GLIBCXX_STD_P::find_first_of(__begin1, __end1, __begin2, __end2);
00218       }
00219 
00220   // Sequential fallback
00221   template<typename _IIter, typename _FIterator,
00222            typename _BinaryPredicate>
00223     inline _IIter
00224     find_first_of(_IIter __begin1, _IIter __end1,
00225                   _FIterator __begin2, _FIterator __end2,
00226                   _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
00227   { return _GLIBCXX_STD_P::find_first_of(
00228              __begin1, __end1, __begin2, __end2, __comp); }
00229 
00230   // Sequential fallback for input iterator type
00231   template<typename _IIter, typename _FIterator,
00232            typename _IteratorTag1, typename _IteratorTag2>
00233     inline _IIter
00234     __find_first_of_switch(_IIter __begin1, _IIter __end1,
00235                          _FIterator __begin2, _FIterator __end2, 
00236                          _IteratorTag1, _IteratorTag2)
00237     { return find_first_of(__begin1, __end1, __begin2, __end2, 
00238                            __gnu_parallel::sequential_tag()); }
00239 
00240   // Parallel algorithm for random access iterators
00241   template<typename _RAIter, typename _FIterator,
00242            typename _BinaryPredicate, typename _IteratorTag>
00243     inline _RAIter
00244     __find_first_of_switch(_RAIter __begin1,
00245                          _RAIter __end1,
00246                          _FIterator __begin2, _FIterator __end2, 
00247                          _BinaryPredicate __comp, random_access_iterator_tag, 
00248                          _IteratorTag)
00249     {
00250       return __gnu_parallel::
00251         __find_template(__begin1, __end1, __begin1, __comp,
00252                       __gnu_parallel::__find_first_of_selector
00253                       <_FIterator>(__begin2, __end2)).first;
00254     }
00255 
00256   // Sequential fallback for input iterator type
00257   template<typename _IIter, typename _FIterator,
00258            typename _BinaryPredicate, typename _IteratorTag1,
00259            typename _IteratorTag2>
00260     inline _IIter
00261     __find_first_of_switch(_IIter __begin1, _IIter __end1,
00262                          _FIterator __begin2, _FIterator __end2, 
00263                          _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
00264     { return find_first_of(__begin1, __end1, __begin2, __end2, __comp, 
00265                            __gnu_parallel::sequential_tag()); }
00266 
00267   // Public interface
00268   template<typename _IIter, typename _FIterator,
00269            typename _BinaryPredicate>
00270     inline _IIter
00271     find_first_of(_IIter __begin1, _IIter __end1,
00272                   _FIterator __begin2, _FIterator __end2, 
00273                   _BinaryPredicate __comp)
00274     {
00275       typedef std::iterator_traits<_IIter> _IIterTraits;
00276       typedef std::iterator_traits<_FIterator> iteratorf_traits;
00277       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
00278       typedef typename iteratorf_traits::iterator_category iteratorf_category;
00279 
00280       return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
00281                                   _IIteratorCategory(), iteratorf_category());
00282     }
00283 
00284   // Public interface, insert default comparator
00285   template<typename _IIter, typename _FIterator>
00286     inline _IIter
00287     find_first_of(_IIter __begin1, _IIter __end1, 
00288                   _FIterator __begin2, _FIterator __end2)
00289     {
00290       typedef std::iterator_traits<_IIter> _IIterTraits;
00291       typedef std::iterator_traits<_FIterator> iteratorf_traits;
00292       typedef typename _IIterTraits::value_type _IValueType;
00293       typedef typename iteratorf_traits::value_type _FValueType;
00294 
00295       return find_first_of(__begin1, __end1, __begin2, __end2, __gnu_parallel::
00296                            _EqualTo<_IValueType, _FValueType>());
00297     }
00298 
00299   // Sequential fallback
00300   template<typename _IIter, typename _OutputIterator>
00301     inline _OutputIterator
00302     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
00303                 __gnu_parallel::sequential_tag)
00304     { return _GLIBCXX_STD_P::unique_copy(__begin1, __end1, __out); }
00305 
00306   // Sequential fallback
00307   template<typename _IIter, typename _OutputIterator,
00308            typename _Predicate>
00309     inline _OutputIterator
00310     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
00311                 _Predicate __pred, __gnu_parallel::sequential_tag)
00312     { return _GLIBCXX_STD_P::unique_copy(__begin1, __end1, __out, __pred); }
00313 
00314   // Sequential fallback for input iterator case
00315   template<typename _IIter, typename _OutputIterator,
00316            typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
00317     inline _OutputIterator
00318     __unique_copy_switch(_IIter __begin, _IIter __last, 
00319                        _OutputIterator __out, _Predicate __pred, 
00320                        _IteratorTag1, _IteratorTag2)
00321     { return _GLIBCXX_STD_P::unique_copy(__begin, __last, __out, __pred); }
00322 
00323   // Parallel unique_copy for random access iterators
00324   template<typename _RAIter, typename RandomAccessOutputIterator,
00325            typename _Predicate>
00326     RandomAccessOutputIterator
00327     __unique_copy_switch(_RAIter __begin, _RAIter __last, 
00328                        RandomAccessOutputIterator __out, _Predicate __pred, 
00329                        random_access_iterator_tag, random_access_iterator_tag)
00330     {
00331       if (_GLIBCXX_PARALLEL_CONDITION(
00332             static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
00333             > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
00334         return __gnu_parallel::__parallel_unique_copy(
00335                  __begin, __last, __out, __pred);
00336       else
00337         return _GLIBCXX_STD_P::unique_copy(__begin, __last, __out, __pred);
00338     }
00339 
00340   // Public interface
00341   template<typename _IIter, typename _OutputIterator>
00342     inline _OutputIterator
00343     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
00344     {
00345       typedef std::iterator_traits<_IIter> _IIterTraits;
00346       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00347       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
00348       typedef typename _IIterTraits::value_type _ValueType;
00349       typedef typename _OIterTraits::iterator_category _OIterCategory;
00350 
00351       return __unique_copy_switch(
00352                __begin1, __end1, __out, equal_to<_ValueType>(),
00353                _IIteratorCategory(), _OIterCategory());
00354     }
00355 
00356   // Public interface
00357   template<typename _IIter, typename _OutputIterator, typename _Predicate>
00358     inline _OutputIterator
00359     unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
00360                 _Predicate __pred)
00361     {
00362       typedef std::iterator_traits<_IIter> _IIterTraits;
00363       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00364       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
00365       typedef typename _OIterTraits::iterator_category _OIterCategory;
00366 
00367       return __unique_copy_switch(
00368                __begin1, __end1, __out, __pred,
00369                _IIteratorCategory(), _OIterCategory());
00370     }
00371 
00372   // Sequential fallback
00373   template<typename _IIter1, typename _IIter2,
00374            typename _OutputIterator>
00375     inline _OutputIterator
00376     set_union(_IIter1 __begin1, _IIter1 __end1,
00377               _IIter2 __begin2, _IIter2 __end2,
00378               _OutputIterator __out, __gnu_parallel::sequential_tag)
00379     { return _GLIBCXX_STD_P::set_union(
00380                __begin1, __end1, __begin2, __end2, __out); }
00381 
00382   // Sequential fallback
00383   template<typename _IIter1, typename _IIter2,
00384            typename _OutputIterator, typename _Predicate>
00385     inline _OutputIterator
00386     set_union(_IIter1 __begin1, _IIter1 __end1,
00387               _IIter2 __begin2, _IIter2 __end2,
00388               _OutputIterator __out, _Predicate __pred,
00389               __gnu_parallel::sequential_tag)
00390     { return _GLIBCXX_STD_P::set_union(__begin1, __end1,
00391                                        __begin2, __end2, __out, __pred); }
00392 
00393   // Sequential fallback for input iterator case
00394   template<typename _IIter1, typename _IIter2, typename _Predicate,
00395            typename _OutputIterator, typename _IteratorTag1,
00396            typename _IteratorTag2, typename _IteratorTag3>
00397     inline _OutputIterator
00398     __set_union_switch(
00399       _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
00400       _OutputIterator __result, _Predicate __pred,
00401       _IteratorTag1, _IteratorTag2, _IteratorTag3)
00402     { return _GLIBCXX_STD_P::set_union(__begin1, __end1,
00403                                        __begin2, __end2, __result, __pred); }
00404 
00405   // Parallel set_union for random access iterators
00406   template<typename _RAIter1, typename _RAIter2,
00407            typename _Output_RAIter, typename _Predicate>
00408     _Output_RAIter
00409     __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1, 
00410                      _RAIter2 __begin2, _RAIter2 __end2, 
00411                      _Output_RAIter __result, _Predicate __pred,
00412                      random_access_iterator_tag, random_access_iterator_tag, 
00413                      random_access_iterator_tag)
00414     {
00415       if (_GLIBCXX_PARALLEL_CONDITION(
00416             static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
00417             >= __gnu_parallel::_Settings::get().set_union_minimal_n
00418             || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
00419             >= __gnu_parallel::_Settings::get().set_union_minimal_n))
00420         return __gnu_parallel::__parallel_set_union(
00421                  __begin1, __end1, __begin2, __end2, __result, __pred);
00422       else
00423         return _GLIBCXX_STD_P::set_union(__begin1, __end1,
00424                                          __begin2, __end2, __result, __pred);
00425     }
00426 
00427   // Public interface
00428   template<typename _IIter1, typename _IIter2,
00429            typename _OutputIterator>
00430     inline _OutputIterator 
00431     set_union(_IIter1 __begin1, _IIter1 __end1,
00432               _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
00433     {
00434       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00435       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00436       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00437       typedef typename _IIterTraits1::iterator_category
00438         _IIterCategory1;
00439       typedef typename _IIterTraits2::iterator_category
00440         _IIterCategory2;
00441       typedef typename _OIterTraits::iterator_category _OIterCategory;
00442       typedef typename _IIterTraits1::value_type _ValueType1;
00443       typedef typename _IIterTraits2::value_type _ValueType2;
00444 
00445       return __set_union_switch(
00446                __begin1, __end1, __begin2, __end2, __out,
00447                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
00448                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00449     }
00450 
00451   // Public interface
00452   template<typename _IIter1, typename _IIter2,
00453            typename _OutputIterator, typename _Predicate>
00454     inline _OutputIterator 
00455     set_union(_IIter1 __begin1, _IIter1 __end1,
00456               _IIter2 __begin2, _IIter2 __end2,
00457               _OutputIterator __out, _Predicate __pred)
00458     {
00459       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00460       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00461       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00462       typedef typename _IIterTraits1::iterator_category
00463         _IIterCategory1;
00464       typedef typename _IIterTraits2::iterator_category
00465         _IIterCategory2;
00466       typedef typename _OIterTraits::iterator_category _OIterCategory;
00467 
00468       return __set_union_switch(
00469                __begin1, __end1, __begin2, __end2, __out, __pred,
00470                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00471     }
00472 
00473   // Sequential fallback.
00474   template<typename _IIter1, typename _IIter2,
00475            typename _OutputIterator>
00476     inline _OutputIterator
00477     set_intersection(_IIter1 __begin1, _IIter1 __end1,
00478                      _IIter2 __begin2, _IIter2 __end2,
00479                      _OutputIterator __out, __gnu_parallel::sequential_tag)
00480     { return _GLIBCXX_STD_P::set_intersection(__begin1, __end1,
00481                                               __begin2, __end2, __out); }
00482 
00483   // Sequential fallback.
00484   template<typename _IIter1, typename _IIter2,
00485            typename _OutputIterator, typename _Predicate>
00486     inline _OutputIterator
00487     set_intersection(_IIter1 __begin1, _IIter1 __end1,
00488                      _IIter2 __begin2, _IIter2 __end2,
00489                      _OutputIterator __out, _Predicate __pred, 
00490                      __gnu_parallel::sequential_tag)
00491     { return _GLIBCXX_STD_P::set_intersection(
00492                __begin1, __end1, __begin2, __end2, __out, __pred); }
00493 
00494   // Sequential fallback for input iterator case
00495   template<typename _IIter1, typename _IIter2,
00496            typename _Predicate, typename _OutputIterator,
00497            typename _IteratorTag1, typename _IteratorTag2,
00498            typename _IteratorTag3>
00499     inline _OutputIterator 
00500     __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
00501                               _IIter2 __begin2, _IIter2 __end2,
00502                               _OutputIterator __result, _Predicate __pred,
00503                               _IteratorTag1, _IteratorTag2, _IteratorTag3)
00504     { return _GLIBCXX_STD_P::set_intersection(__begin1, __end1, __begin2,
00505                                               __end2, __result, __pred); }
00506 
00507   // Parallel set_intersection for random access iterators
00508   template<typename _RAIter1, typename _RAIter2,
00509            typename _Output_RAIter, typename _Predicate>
00510     _Output_RAIter
00511     __set_intersection_switch(_RAIter1 __begin1,
00512                             _RAIter1 __end1,
00513                             _RAIter2 __begin2,
00514                             _RAIter2 __end2,
00515                             _Output_RAIter __result,
00516                             _Predicate __pred,
00517                             random_access_iterator_tag,
00518                             random_access_iterator_tag,
00519                             random_access_iterator_tag)
00520     {
00521       if (_GLIBCXX_PARALLEL_CONDITION(
00522             static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
00523             >= __gnu_parallel::_Settings::get().set_union_minimal_n
00524             || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
00525             >= __gnu_parallel::_Settings::get().set_union_minimal_n))
00526         return __gnu_parallel::__parallel_set_intersection(
00527                  __begin1, __end1, __begin2, __end2, __result, __pred);
00528       else
00529         return _GLIBCXX_STD_P::set_intersection(
00530                  __begin1, __end1, __begin2, __end2, __result, __pred);
00531     }
00532 
00533   // Public interface
00534   template<typename _IIter1, typename _IIter2,
00535            typename _OutputIterator>
00536     inline _OutputIterator 
00537     set_intersection(_IIter1 __begin1, _IIter1 __end1, 
00538                      _IIter2 __begin2, _IIter2 __end2, 
00539                      _OutputIterator __out)
00540     {
00541       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00542       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00543       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00544       typedef typename _IIterTraits1::iterator_category
00545         _IIterCategory1;
00546       typedef typename _IIterTraits2::iterator_category
00547         _IIterCategory2;
00548       typedef typename _OIterTraits::iterator_category _OIterCategory;
00549       typedef typename _IIterTraits1::value_type _ValueType1;
00550       typedef typename _IIterTraits2::value_type _ValueType2;
00551 
00552       return __set_intersection_switch(
00553                __begin1, __end1, __begin2, __end2, __out,
00554                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
00555                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00556     }
00557 
00558   template<typename _IIter1, typename _IIter2,
00559            typename _OutputIterator, typename _Predicate>
00560     inline _OutputIterator 
00561     set_intersection(_IIter1 __begin1, _IIter1 __end1,
00562                      _IIter2 __begin2, _IIter2 __end2,
00563                      _OutputIterator __out, _Predicate __pred)
00564     {
00565       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00566       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00567       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00568       typedef typename _IIterTraits1::iterator_category
00569         _IIterCategory1;
00570       typedef typename _IIterTraits2::iterator_category
00571         _IIterCategory2;
00572       typedef typename _OIterTraits::iterator_category _OIterCategory;
00573 
00574       return __set_intersection_switch(
00575                __begin1, __end1, __begin2, __end2, __out, __pred,
00576                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00577     }
00578 
00579   // Sequential fallback
00580   template<typename _IIter1, typename _IIter2,
00581            typename _OutputIterator>
00582     inline _OutputIterator
00583     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
00584                              _IIter2 __begin2, _IIter2 __end2,
00585                              _OutputIterator __out,
00586                              __gnu_parallel::sequential_tag)
00587     { return _GLIBCXX_STD_P::set_symmetric_difference(
00588                __begin1, __end1, __begin2, __end2, __out); }
00589 
00590   // Sequential fallback
00591   template<typename _IIter1, typename _IIter2,
00592            typename _OutputIterator, typename _Predicate>
00593     inline _OutputIterator
00594     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
00595                              _IIter2 __begin2, _IIter2 __end2,
00596                              _OutputIterator __out, _Predicate __pred,
00597                              __gnu_parallel::sequential_tag)
00598     { return _GLIBCXX_STD_P::set_symmetric_difference(
00599                __begin1, __end1, __begin2, __end2, __out, __pred); }
00600 
00601   // Sequential fallback for input iterator case
00602   template<typename _IIter1, typename _IIter2,
00603            typename _Predicate, typename _OutputIterator,
00604            typename _IteratorTag1, typename _IteratorTag2,
00605            typename _IteratorTag3>
00606     inline _OutputIterator 
00607     __set_symmetric_difference_switch(
00608       _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
00609       _OutputIterator __result, _Predicate __pred,
00610       _IteratorTag1, _IteratorTag2, _IteratorTag3)
00611     { return _GLIBCXX_STD_P::set_symmetric_difference(
00612                __begin1, __end1, __begin2, __end2, __result, __pred); }
00613 
00614   // Parallel set_symmetric_difference for random access iterators
00615   template<typename _RAIter1, typename _RAIter2,
00616            typename _Output_RAIter, typename _Predicate>
00617     _Output_RAIter
00618     __set_symmetric_difference_switch(_RAIter1 __begin1,
00619                                     _RAIter1 __end1,
00620                                     _RAIter2 __begin2,
00621                                     _RAIter2 __end2,
00622                                     _Output_RAIter __result,
00623                                     _Predicate __pred,
00624                                     random_access_iterator_tag,
00625                                     random_access_iterator_tag,
00626                                     random_access_iterator_tag)
00627     {
00628       if (_GLIBCXX_PARALLEL_CONDITION(
00629       static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
00630       >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
00631       || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
00632       >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
00633   return __gnu_parallel::__parallel_set_symmetric_difference(
00634            __begin1, __end1, __begin2, __end2, __result, __pred);
00635       else
00636         return _GLIBCXX_STD_P::set_symmetric_difference(
00637                  __begin1, __end1, __begin2, __end2, __result, __pred);
00638     }
00639 
00640   // Public interface.
00641   template<typename _IIter1, typename _IIter2,
00642            typename _OutputIterator>
00643     inline _OutputIterator 
00644     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
00645                              _IIter2 __begin2, _IIter2 __end2,
00646                              _OutputIterator __out)
00647     {
00648       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00649       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00650       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00651       typedef typename _IIterTraits1::iterator_category
00652         _IIterCategory1;
00653       typedef typename _IIterTraits2::iterator_category
00654         _IIterCategory2;
00655       typedef typename _OIterTraits::iterator_category _OIterCategory;
00656       typedef typename _IIterTraits1::value_type _ValueType1;
00657       typedef typename _IIterTraits2::value_type _ValueType2;
00658 
00659       return __set_symmetric_difference_switch(
00660                __begin1, __end1, __begin2, __end2, __out,
00661                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
00662                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00663     }
00664 
00665   // Public interface.
00666   template<typename _IIter1, typename _IIter2,
00667            typename _OutputIterator, typename _Predicate>
00668     inline _OutputIterator 
00669     set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
00670                              _IIter2 __begin2, _IIter2 __end2,
00671                              _OutputIterator __out, _Predicate __pred)
00672     {
00673       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00674       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00675       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00676       typedef typename _IIterTraits1::iterator_category
00677         _IIterCategory1;
00678       typedef typename _IIterTraits2::iterator_category
00679         _IIterCategory2;
00680       typedef typename _OIterTraits::iterator_category _OIterCategory;
00681 
00682       return __set_symmetric_difference_switch(
00683                __begin1, __end1, __begin2, __end2, __out, __pred,
00684                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00685     }
00686 
00687   // Sequential fallback.
00688   template<typename _IIter1, typename _IIter2,
00689            typename _OutputIterator>
00690     inline _OutputIterator
00691     set_difference(_IIter1 __begin1, _IIter1 __end1, 
00692                    _IIter2 __begin2, _IIter2 __end2, 
00693                    _OutputIterator __out, __gnu_parallel::sequential_tag)
00694     { return _GLIBCXX_STD_P::set_difference(
00695                __begin1,__end1, __begin2, __end2, __out); }
00696 
00697   // Sequential fallback.
00698   template<typename _IIter1, typename _IIter2,
00699            typename _OutputIterator, typename _Predicate>
00700     inline _OutputIterator
00701     set_difference(_IIter1 __begin1, _IIter1 __end1, 
00702                    _IIter2 __begin2, _IIter2 __end2, 
00703                    _OutputIterator __out, _Predicate __pred, 
00704                    __gnu_parallel::sequential_tag)
00705     { return _GLIBCXX_STD_P::set_difference(__begin1, __end1,
00706                                             __begin2, __end2, __out, __pred); }
00707 
00708   // Sequential fallback for input iterator case.
00709   template<typename _IIter1, typename _IIter2, typename _Predicate,
00710            typename _OutputIterator, typename _IteratorTag1,
00711            typename _IteratorTag2, typename _IteratorTag3>
00712     inline _OutputIterator
00713     __set_difference_switch(_IIter1 __begin1, _IIter1 __end1, 
00714                           _IIter2 __begin2, _IIter2 __end2, 
00715                           _OutputIterator __result, _Predicate __pred, 
00716                           _IteratorTag1, _IteratorTag2, _IteratorTag3)
00717     { return _GLIBCXX_STD_P::set_difference(
00718                __begin1, __end1, __begin2, __end2, __result, __pred); }
00719 
00720   // Parallel set_difference for random access iterators
00721   template<typename _RAIter1, typename _RAIter2,
00722            typename _Output_RAIter, typename _Predicate>
00723     _Output_RAIter
00724     __set_difference_switch(_RAIter1 __begin1,
00725                           _RAIter1 __end1,
00726                           _RAIter2 __begin2,
00727                           _RAIter2 __end2,
00728                           _Output_RAIter __result, _Predicate __pred,
00729                           random_access_iterator_tag,
00730                           random_access_iterator_tag,
00731                           random_access_iterator_tag)
00732     {
00733       if (_GLIBCXX_PARALLEL_CONDITION(
00734             static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
00735             >= __gnu_parallel::_Settings::get().set_difference_minimal_n
00736             || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
00737             >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
00738         return __gnu_parallel::__parallel_set_difference(
00739                  __begin1, __end1, __begin2, __end2, __result, __pred);
00740       else
00741         return _GLIBCXX_STD_P::set_difference(
00742                  __begin1, __end1, __begin2, __end2, __result, __pred);
00743     }
00744 
00745   // Public interface
00746   template<typename _IIter1, typename _IIter2,
00747            typename _OutputIterator>
00748     inline _OutputIterator
00749     set_difference(_IIter1 __begin1, _IIter1 __end1, 
00750                    _IIter2 __begin2, _IIter2 __end2, 
00751                    _OutputIterator __out)
00752     {
00753       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00754       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00755       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00756       typedef typename _IIterTraits1::iterator_category
00757         _IIterCategory1;
00758       typedef typename _IIterTraits2::iterator_category
00759         _IIterCategory2;
00760       typedef typename _OIterTraits::iterator_category _OIterCategory;
00761       typedef typename _IIterTraits1::value_type _ValueType1;
00762       typedef typename _IIterTraits2::value_type _ValueType2;
00763 
00764       return __set_difference_switch(
00765                __begin1, __end1, __begin2, __end2, __out,
00766                __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
00767                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00768     }
00769 
00770   // Public interface
00771   template<typename _IIter1, typename _IIter2,
00772            typename _OutputIterator, typename _Predicate>
00773     inline _OutputIterator
00774     set_difference(_IIter1 __begin1, _IIter1 __end1, 
00775                    _IIter2 __begin2, _IIter2 __end2, 
00776                    _OutputIterator __out, _Predicate __pred)
00777     {
00778       typedef std::iterator_traits<_IIter1> _IIterTraits1;
00779       typedef std::iterator_traits<_IIter2> _IIterTraits2;
00780       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
00781       typedef typename _IIterTraits1::iterator_category
00782         _IIterCategory1;
00783       typedef typename _IIterTraits2::iterator_category
00784         _IIterCategory2;
00785       typedef typename _OIterTraits::iterator_category _OIterCategory;
00786 
00787       return __set_difference_switch(
00788                __begin1, __end1, __begin2, __end2, __out, __pred,
00789                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
00790     }
00791 
00792   // Sequential fallback
00793   template<typename _FIterator>
00794     inline _FIterator
00795     adjacent_find(_FIterator __begin, _FIterator __end, 
00796                   __gnu_parallel::sequential_tag)
00797     { return _GLIBCXX_STD_P::adjacent_find(__begin, __end); }
00798 
00799   // Sequential fallback
00800   template<typename _FIterator, typename _BinaryPredicate>
00801     inline _FIterator
00802     adjacent_find(_FIterator __begin, _FIterator __end, 
00803                   _BinaryPredicate __binary_pred,
00804                   __gnu_parallel::sequential_tag)
00805     { return _GLIBCXX_STD_P::adjacent_find(__begin, __end, __binary_pred); }
00806 
00807   // Parallel algorithm for random access iterators
00808   template<typename _RAIter>
00809     _RAIter
00810     __adjacent_find_switch(_RAIter __begin, _RAIter __end, 
00811                          random_access_iterator_tag)
00812     {
00813       typedef iterator_traits<_RAIter> _TraitsType;
00814       typedef typename _TraitsType::value_type _ValueType;
00815 
00816       if (_GLIBCXX_PARALLEL_CONDITION(true))
00817         {
00818           _RAIter __spot = __gnu_parallel::
00819               __find_template(
00820                 __begin, __end - 1, __begin, equal_to<_ValueType>(),
00821                 __gnu_parallel::__adjacent_find_selector())
00822             .first;
00823           if (__spot == (__end - 1))
00824             return __end;
00825           else
00826             return __spot;
00827         }
00828       else
00829         return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
00830     }
00831 
00832   // Sequential fallback for input iterator case
00833   template<typename _FIterator, typename _IteratorTag>
00834     inline _FIterator
00835     __adjacent_find_switch(_FIterator __begin, _FIterator __end,
00836                          _IteratorTag)
00837     { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }
00838 
00839   // Public interface
00840   template<typename _FIterator>
00841     inline _FIterator
00842     adjacent_find(_FIterator __begin, _FIterator __end)
00843     {
00844       typedef iterator_traits<_FIterator> _TraitsType;
00845       typedef typename _TraitsType::iterator_category _IteratorCategory;
00846       return __adjacent_find_switch(__begin, __end, _IteratorCategory());
00847     }
00848 
00849   // Sequential fallback for input iterator case
00850   template<typename _FIterator, typename _BinaryPredicate,
00851            typename _IteratorTag>
00852     inline _FIterator
00853     __adjacent_find_switch(_FIterator __begin, _FIterator __end, 
00854                          _BinaryPredicate __pred, _IteratorTag)
00855     { return adjacent_find(__begin, __end, __pred,
00856                            __gnu_parallel::sequential_tag()); }
00857 
00858   // Parallel algorithm for random access iterators
00859   template<typename _RAIter, typename _BinaryPredicate>
00860     _RAIter
00861     __adjacent_find_switch(_RAIter __begin, _RAIter __end, 
00862                          _BinaryPredicate __pred, random_access_iterator_tag)
00863     {
00864       if (_GLIBCXX_PARALLEL_CONDITION(true))
00865         return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
00866                                              __gnu_parallel::
00867                                              __adjacent_find_selector()).first;
00868       else
00869         return adjacent_find(__begin, __end, __pred,
00870                              __gnu_parallel::sequential_tag());
00871     }
00872 
00873   // Public interface
00874   template<typename _FIterator, typename _BinaryPredicate>
00875     inline _FIterator
00876     adjacent_find(_FIterator __begin, _FIterator __end, 
00877                   _BinaryPredicate __pred)
00878     {
00879       typedef iterator_traits<_FIterator> _TraitsType;
00880       typedef typename _TraitsType::iterator_category _IteratorCategory;
00881       return __adjacent_find_switch(__begin, __end, __pred,
00882                                     _IteratorCategory());
00883     }
00884 
00885   // Sequential fallback
00886   template<typename _IIter, typename _Tp>
00887     inline typename iterator_traits<_IIter>::difference_type
00888     count(_IIter __begin, _IIter __end, const _Tp& __value, 
00889           __gnu_parallel::sequential_tag)
00890     { return _GLIBCXX_STD_P::count(__begin, __end, __value); }
00891 
00892   // Parallel code for random access iterators
00893   template<typename _RAIter, typename _Tp>
00894     typename iterator_traits<_RAIter>::difference_type
00895     __count_switch(_RAIter __begin, _RAIter __end, 
00896                  const _Tp& __value, random_access_iterator_tag, 
00897                  __gnu_parallel::_Parallelism __parallelism_tag 
00898                  = __gnu_parallel::parallel_unbalanced)
00899     {
00900       typedef iterator_traits<_RAIter> _TraitsType;
00901       typedef typename _TraitsType::value_type _ValueType;
00902       typedef typename _TraitsType::difference_type _DifferenceType;
00903       typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
00904 
00905       if (_GLIBCXX_PARALLEL_CONDITION(
00906             static_cast<_SequenceIndex>(__end - __begin)
00907             >= __gnu_parallel::_Settings::get().count_minimal_n
00908             && __gnu_parallel::__is_parallel(__parallelism_tag)))
00909         {
00910           __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
00911             __functionality;
00912           _DifferenceType __res = 0;
00913           __gnu_parallel::
00914             __for_each_template_random_access(
00915               __begin, __end, __value, __functionality,
00916               std::plus<_SequenceIndex>(), __res, __res, -1,
00917               __parallelism_tag);
00918           return __res;
00919         }
00920       else
00921         return count(__begin, __end, __value,
00922                      __gnu_parallel::sequential_tag());
00923     }
00924 
00925   // Sequential fallback for input iterator case.
00926   template<typename _IIter, typename _Tp, typename _IteratorTag>
00927     inline typename iterator_traits<_IIter>::difference_type
00928     __count_switch(_IIter __begin, _IIter __end, const _Tp& __value, 
00929                  _IteratorTag)
00930     { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
00931       }
00932 
00933   // Public interface.
00934   template<typename _IIter, typename _Tp>
00935     inline typename iterator_traits<_IIter>::difference_type
00936     count(_IIter __begin, _IIter __end, const _Tp& __value, 
00937           __gnu_parallel::_Parallelism __parallelism_tag)
00938     {
00939       typedef iterator_traits<_IIter> _TraitsType;
00940       typedef typename _TraitsType::iterator_category _IteratorCategory;
00941       return __count_switch(__begin, __end, __value, _IteratorCategory(),
00942                             __parallelism_tag);
00943     }
00944 
00945   template<typename _IIter, typename _Tp>
00946     inline typename iterator_traits<_IIter>::difference_type
00947     count(_IIter __begin, _IIter __end, const _Tp& __value)
00948     {
00949       typedef iterator_traits<_IIter> _TraitsType;
00950       typedef typename _TraitsType::iterator_category _IteratorCategory;
00951       return __count_switch(__begin, __end, __value, _IteratorCategory());
00952     }
00953 
00954 
00955   // Sequential fallback.
00956   template<typename _IIter, typename _Predicate>
00957     inline typename iterator_traits<_IIter>::difference_type
00958     count_if(_IIter __begin, _IIter __end, _Predicate __pred, 
00959              __gnu_parallel::sequential_tag)
00960     { return _GLIBCXX_STD_P::count_if(__begin, __end, __pred); }
00961 
00962   // Parallel count_if for random access iterators
00963   template<typename _RAIter, typename _Predicate>
00964     typename iterator_traits<_RAIter>::difference_type
00965     __count_if_switch(_RAIter __begin, _RAIter __end, 
00966                     _Predicate __pred, random_access_iterator_tag,
00967                     __gnu_parallel::_Parallelism __parallelism_tag
00968                     = __gnu_parallel::parallel_unbalanced)
00969     {
00970       typedef iterator_traits<_RAIter> _TraitsType;
00971       typedef typename _TraitsType::value_type _ValueType;
00972       typedef typename _TraitsType::difference_type _DifferenceType;
00973       typedef __gnu_parallel::_SequenceIndex _SequenceIndex;
00974 
00975       if (_GLIBCXX_PARALLEL_CONDITION(
00976             static_cast<_SequenceIndex>(__end - __begin)
00977             >= __gnu_parallel::_Settings::get().count_minimal_n
00978             && __gnu_parallel::__is_parallel(__parallelism_tag)))
00979         {
00980           _DifferenceType __res = 0;
00981           __gnu_parallel::
00982             __count_if_selector<_RAIter, _DifferenceType>
00983             __functionality;
00984           __gnu_parallel::
00985             __for_each_template_random_access(
00986               __begin, __end, __pred, __functionality,
00987               std::plus<_SequenceIndex>(), __res, __res, -1,
00988               __parallelism_tag);
00989           return __res;
00990         }
00991       else
00992         return count_if(__begin, __end, __pred,
00993                         __gnu_parallel::sequential_tag());
00994     }
00995 
00996   // Sequential fallback for input iterator case.
00997   template<typename _IIter, typename _Predicate, typename _IteratorTag>
00998     inline typename iterator_traits<_IIter>::difference_type
00999     __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred, 
01000                     _IteratorTag)
01001     { return count_if(__begin, __end, __pred,
01002                       __gnu_parallel::sequential_tag()); }
01003 
01004   // Public interface.
01005   template<typename _IIter, typename _Predicate>
01006     inline typename iterator_traits<_IIter>::difference_type
01007     count_if(_IIter __begin, _IIter __end, _Predicate __pred, 
01008              __gnu_parallel::_Parallelism __parallelism_tag)
01009     {
01010       typedef iterator_traits<_IIter> _TraitsType;
01011       typedef typename _TraitsType::iterator_category _IteratorCategory;
01012       return __count_if_switch(__begin, __end, __pred, _IteratorCategory(), 
01013                              __parallelism_tag);
01014     }
01015 
01016   template<typename _IIter, typename _Predicate>
01017     inline typename iterator_traits<_IIter>::difference_type
01018     count_if(_IIter __begin, _IIter __end, _Predicate __pred)
01019     {
01020       typedef iterator_traits<_IIter> _TraitsType;
01021       typedef typename _TraitsType::iterator_category _IteratorCategory;
01022       return __count_if_switch(__begin, __end, __pred, _IteratorCategory());
01023     }
01024 
01025 
01026   // Sequential fallback.
01027   template<typename _FIterator1, typename _FIterator2>
01028     inline _FIterator1
01029     search(_FIterator1 __begin1, _FIterator1 __end1,
01030            _FIterator2 __begin2, _FIterator2 __end2,
01031            __gnu_parallel::sequential_tag)
01032     { return _GLIBCXX_STD_P::search(__begin1, __end1, __begin2, __end2); }
01033 
01034   // Parallel algorithm for random access iterator
01035   template<typename _RAIter1, typename _RAIter2>
01036     _RAIter1
01037     __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
01038                   _RAIter2 __begin2, _RAIter2 __end2,
01039                   random_access_iterator_tag, random_access_iterator_tag)
01040     {
01041       typedef std::iterator_traits<_RAIter1> _Iterator1Traits;
01042       typedef typename _Iterator1Traits::value_type _ValueType1;
01043       typedef std::iterator_traits<_RAIter2> _Iterator2Traits;
01044       typedef typename _Iterator2Traits::value_type _ValueType2;
01045 
01046       if (_GLIBCXX_PARALLEL_CONDITION(true))
01047         return __gnu_parallel::
01048           __search_template(
01049             __begin1, __end1, __begin2, __end2,
01050             __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
01051       else
01052         return search(__begin1, __end1, __begin2, __end2,
01053                       __gnu_parallel::sequential_tag());
01054     }
01055 
01056   // Sequential fallback for input iterator case
01057   template<typename _FIterator1, typename _FIterator2,
01058            typename _IteratorTag1, typename _IteratorTag2>
01059     inline _FIterator1
01060     __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
01061                   _FIterator2 __begin2, _FIterator2 __end2,
01062                   _IteratorTag1, _IteratorTag2)
01063     { return search(__begin1, __end1, __begin2, __end2,
01064                     __gnu_parallel::sequential_tag()); }
01065 
01066   // Public interface.
01067   template<typename _FIterator1, typename _FIterator2>
01068     inline _FIterator1
01069     search(_FIterator1 __begin1, _FIterator1 __end1,
01070            _FIterator2 __begin2, _FIterator2 __end2)
01071     {
01072       typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
01073       typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
01074       typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
01075       typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
01076 
01077       return __search_switch(__begin1, __end1, __begin2, __end2,
01078                            _IteratorCategory1(), _IteratorCategory2());
01079     }
01080 
01081   // Public interface.
01082   template<typename _FIterator1, typename _FIterator2,
01083            typename _BinaryPredicate>
01084     inline _FIterator1
01085     search(_FIterator1 __begin1, _FIterator1 __end1,
01086            _FIterator2 __begin2, _FIterator2 __end2,
01087            _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
01088     { return _GLIBCXX_STD_P::search(
01089                                __begin1, __end1, __begin2, __end2, __pred); }
01090 
01091   // Parallel algorithm for random access iterator.
01092   template<typename _RAIter1, typename _RAIter2,
01093            typename _BinaryPredicate>
01094     _RAIter1
01095     __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
01096                   _RAIter2 __begin2, _RAIter2 __end2,
01097                   _BinaryPredicate __pred,
01098                   random_access_iterator_tag, random_access_iterator_tag)
01099     {
01100       if (_GLIBCXX_PARALLEL_CONDITION(true))
01101         return __gnu_parallel::__search_template(__begin1, __end1,
01102                                                __begin2, __end2, __pred);
01103       else
01104         return search(__begin1, __end1, __begin2, __end2, __pred,
01105                       __gnu_parallel::sequential_tag());
01106     }
01107 
01108   // Sequential fallback for input iterator case
01109   template<typename _FIterator1, typename _FIterator2,
01110            typename _BinaryPredicate, typename _IteratorTag1,
01111            typename _IteratorTag2>
01112     inline _FIterator1
01113     __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
01114                   _FIterator2 __begin2, _FIterator2 __end2,
01115                   _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
01116     { return search(__begin1, __end1, __begin2, __end2, __pred,
01117                     __gnu_parallel::sequential_tag()); }
01118 
01119   // Public interface
01120   template<typename _FIterator1, typename _FIterator2,
01121            typename _BinaryPredicate>
01122     inline _FIterator1
01123     search(_FIterator1 __begin1, _FIterator1 __end1,
01124            _FIterator2 __begin2, _FIterator2 __end2,
01125            _BinaryPredicate  __pred)
01126     {
01127       typedef std::iterator_traits<_FIterator1> _Iterator1Traits;
01128       typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
01129       typedef std::iterator_traits<_FIterator2> _Iterator2Traits;
01130       typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
01131       return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
01132                            _IteratorCategory1(), _IteratorCategory2());
01133     }
01134 
01135   // Sequential fallback
01136   template<typename _FIterator, typename _Integer, typename _Tp>
01137     inline _FIterator
01138     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
01139              const _Tp& __val, __gnu_parallel::sequential_tag)
01140     { return _GLIBCXX_STD_P::search_n(__begin, __end, __count, __val); }
01141 
01142   // Sequential fallback
01143   template<typename _FIterator, typename _Integer, typename _Tp,
01144            typename _BinaryPredicate>
01145     inline _FIterator
01146     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
01147              const _Tp& __val, _BinaryPredicate __binary_pred,
01148              __gnu_parallel::sequential_tag)
01149     { return _GLIBCXX_STD_P::search_n(
01150                __begin, __end, __count, __val, __binary_pred); }
01151 
01152   // Public interface.
01153   template<typename _FIterator, typename _Integer, typename _Tp>
01154     inline _FIterator
01155     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
01156              const _Tp& __val)
01157     {
01158       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
01159       return search_n(__begin, __end, __count, __val,
01160                       __gnu_parallel::_EqualTo<_ValueType, _Tp>());
01161     }
01162 
01163   // Parallel algorithm for random access iterators.
01164   template<typename _RAIter, typename _Integer,
01165            typename _Tp, typename _BinaryPredicate>
01166     _RAIter
01167     __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
01168                       const _Tp& __val, _BinaryPredicate __binary_pred,
01169                       random_access_iterator_tag)
01170     {
01171       if (_GLIBCXX_PARALLEL_CONDITION(true))
01172         {
01173           __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
01174           return __gnu_parallel::__search_template(
01175                    __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
01176         }
01177       else
01178         return std::__search_n(__begin, __end, __count, __val,
01179                                __binary_pred, random_access_iterator_tag());
01180     }
01181 
01182   // Sequential fallback for input iterator case.
01183   template<typename _FIterator, typename _Integer, typename _Tp,
01184            typename _BinaryPredicate, typename _IteratorTag>
01185     inline _FIterator
01186     __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
01187                       const _Tp& __val, _BinaryPredicate __binary_pred,
01188                       _IteratorTag)
01189     { return __search_n(__begin, __end, __count, __val, __binary_pred,
01190                         _IteratorTag()); }
01191 
01192   // Public interface.
01193   template<typename _FIterator, typename _Integer, typename _Tp,
01194            typename _BinaryPredicate>
01195     inline _FIterator
01196     search_n(_FIterator __begin, _FIterator __end, _Integer __count,
01197              const _Tp& __val, _BinaryPredicate __binary_pred)
01198     {
01199       return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
01200                              typename std::iterator_traits<_FIterator>::
01201                              iterator_category());
01202     }
01203 
01204 
01205   // Sequential fallback.
01206   template<typename _IIter, typename _OutputIterator,
01207            typename _UnaryOperation>
01208     inline _OutputIterator
01209     transform(_IIter __begin, _IIter __end, _OutputIterator __result, 
01210               _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
01211     { return _GLIBCXX_STD_P::transform(__begin, __end, __result, __unary_op); }
01212 
01213   // Parallel unary transform for random access iterators.
01214   template<typename _RAIter1, typename _RAIter2,
01215            typename _UnaryOperation>
01216     _RAIter2
01217     __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
01218                       _RAIter2 __result, _UnaryOperation __unary_op,
01219                       random_access_iterator_tag, random_access_iterator_tag,
01220                       __gnu_parallel::_Parallelism __parallelism_tag
01221                       = __gnu_parallel::parallel_balanced)
01222     {
01223       if (_GLIBCXX_PARALLEL_CONDITION(
01224             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
01225             >= __gnu_parallel::_Settings::get().transform_minimal_n
01226             && __gnu_parallel::__is_parallel(__parallelism_tag)))
01227         {
01228           bool __dummy = true;
01229           typedef __gnu_parallel::_IteratorPair<_RAIter1,
01230             _RAIter2, random_access_iterator_tag> _ItTrip;
01231           _ItTrip __begin_pair(__begin, __result),
01232                   __end_pair(__end, __result + (__end - __begin));
01233           __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
01234           __gnu_parallel::
01235             __for_each_template_random_access(
01236               __begin_pair, __end_pair, __unary_op, __functionality,
01237               __gnu_parallel::_DummyReduct(),
01238               __dummy, __dummy, -1, __parallelism_tag);
01239           return __functionality._M_finish_iterator;
01240         }
01241       else
01242         return transform(__begin, __end, __result, __unary_op, 
01243                          __gnu_parallel::sequential_tag());
01244     }
01245 
01246   // Sequential fallback for input iterator case.
01247   template<typename _RAIter1, typename _RAIter2,
01248            typename _UnaryOperation, typename _IteratorTag1,
01249            typename _IteratorTag2>
01250     inline _RAIter2
01251     __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
01252                       _RAIter2 __result, _UnaryOperation __unary_op,
01253                       _IteratorTag1, _IteratorTag2)
01254     { return transform(__begin, __end, __result, __unary_op, 
01255                        __gnu_parallel::sequential_tag()); }
01256 
01257   // Public interface.
01258   template<typename _IIter, typename _OutputIterator,
01259            typename _UnaryOperation>
01260     inline _OutputIterator
01261     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
01262               _UnaryOperation __unary_op, 
01263               __gnu_parallel::_Parallelism __parallelism_tag)
01264     {
01265       typedef std::iterator_traits<_IIter> _IIterTraits;
01266       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
01267       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
01268       typedef typename _OIterTraits::iterator_category _OIterCategory;
01269 
01270       return __transform1_switch(__begin, __end, __result, __unary_op,
01271                                _IIteratorCategory(), _OIterCategory(), 
01272                                __parallelism_tag);
01273     }
01274 
01275   template<typename _IIter, typename _OutputIterator,
01276            typename _UnaryOperation>
01277     inline _OutputIterator
01278     transform(_IIter __begin, _IIter __end, _OutputIterator __result,
01279               _UnaryOperation __unary_op)
01280     {
01281       typedef std::iterator_traits<_IIter> _IIterTraits;
01282       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
01283       typedef typename _IIterTraits::iterator_category _IIteratorCategory;
01284       typedef typename _OIterTraits::iterator_category _OIterCategory;
01285 
01286       return __transform1_switch(__begin, __end, __result, __unary_op,
01287                                _IIteratorCategory(), _OIterCategory());
01288     }
01289 
01290 
01291   // Sequential fallback
01292   template<typename _IIter1, typename _IIter2,
01293            typename _OutputIterator, typename _BinaryOperation>
01294     inline _OutputIterator
01295     transform(_IIter1 __begin1, _IIter1 __end1,
01296               _IIter2 __begin2, _OutputIterator __result,
01297               _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
01298     { return _GLIBCXX_STD_P::transform(__begin1, __end1,
01299                                        __begin2, __result, __binary_op); }
01300 
01301   // Parallel binary transform for random access iterators.
01302   template<typename _RAIter1, typename _RAIter2,
01303            typename _RAIter3, typename _BinaryOperation>
01304     _RAIter3
01305     __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
01306                       _RAIter2 __begin2,
01307                       _RAIter3 __result, _BinaryOperation __binary_op,
01308                       random_access_iterator_tag, random_access_iterator_tag,
01309                       random_access_iterator_tag,
01310                       __gnu_parallel::_Parallelism __parallelism_tag 
01311                       = __gnu_parallel::parallel_balanced)
01312     {
01313       if (_GLIBCXX_PARALLEL_CONDITION(
01314             (__end1 - __begin1) >=
01315                 __gnu_parallel::_Settings::get().transform_minimal_n
01316             && __gnu_parallel::__is_parallel(__parallelism_tag)))
01317         {
01318           bool __dummy = true;
01319           typedef __gnu_parallel::_IteratorTriple<_RAIter1,
01320             _RAIter2, _RAIter3,
01321             random_access_iterator_tag> _ItTrip;
01322           _ItTrip __begin_triple(__begin1, __begin2, __result),
01323             __end_triple(__end1, __begin2 + (__end1 - __begin1),
01324                        __result + (__end1 - __begin1));
01325           __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
01326           __gnu_parallel::
01327             __for_each_template_random_access(__begin_triple, __end_triple,
01328                                             __binary_op, __functionality,
01329                                             __gnu_parallel::_DummyReduct(),
01330                                             __dummy, __dummy, -1,
01331                                             __parallelism_tag);
01332           return __functionality._M_finish_iterator;
01333         }
01334       else
01335         return transform(__begin1, __end1, __begin2, __result, __binary_op, 
01336                          __gnu_parallel::sequential_tag());
01337     }
01338 
01339   // Sequential fallback for input iterator case.
01340   template<typename _IIter1, typename _IIter2,
01341            typename _OutputIterator, typename _BinaryOperation,
01342            typename _Tag1, typename _Tag2, typename _Tag3>
01343     inline _OutputIterator
01344     __transform2_switch(_IIter1 __begin1, _IIter1 __end1, 
01345                       _IIter2 __begin2, _OutputIterator __result, 
01346                       _BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
01347     { return transform(__begin1, __end1, __begin2, __result, __binary_op,
01348                        __gnu_parallel::sequential_tag()); }
01349 
01350   // Public interface.
01351   template<typename _IIter1, typename _IIter2,
01352            typename _OutputIterator, typename _BinaryOperation>
01353     inline _OutputIterator
01354     transform(_IIter1 __begin1, _IIter1 __end1,
01355               _IIter2 __begin2, _OutputIterator __result,
01356               _BinaryOperation __binary_op, 
01357               __gnu_parallel::_Parallelism __parallelism_tag)
01358     {
01359       typedef std::iterator_traits<_IIter1> _IIterTraits1;
01360       typedef typename _IIterTraits1::iterator_category
01361         _IIterCategory1;
01362       typedef std::iterator_traits<_IIter2> _IIterTraits2;
01363       typedef typename _IIterTraits2::iterator_category
01364         _IIterCategory2;
01365       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
01366       typedef typename _OIterTraits::iterator_category _OIterCategory;
01367 
01368       return __transform2_switch(
01369                __begin1, __end1, __begin2, __result, __binary_op,
01370                _IIterCategory1(), _IIterCategory2(), _OIterCategory(),
01371                __parallelism_tag);
01372     }
01373 
01374   template<typename _IIter1, typename _IIter2,
01375            typename _OutputIterator, typename _BinaryOperation>
01376     inline _OutputIterator
01377     transform(_IIter1 __begin1, _IIter1 __end1,
01378               _IIter2 __begin2, _OutputIterator __result,
01379               _BinaryOperation __binary_op)
01380     {
01381       typedef std::iterator_traits<_IIter1> _IIterTraits1;
01382       typedef typename _IIterTraits1::iterator_category
01383         _IIterCategory1;
01384       typedef std::iterator_traits<_IIter2> _IIterTraits2;
01385       typedef typename _IIterTraits2::iterator_category
01386         _IIterCategory2;
01387       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
01388       typedef typename _OIterTraits::iterator_category _OIterCategory;
01389 
01390       return __transform2_switch(
01391                __begin1, __end1, __begin2, __result, __binary_op,
01392                _IIterCategory1(), _IIterCategory2(), _OIterCategory());
01393     }
01394 
01395   // Sequential fallback
01396   template<typename _FIterator, typename _Tp>
01397     inline void
01398     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, 
01399             const _Tp& __new_value, __gnu_parallel::sequential_tag)
01400     { _GLIBCXX_STD_P::replace(__begin, __end, __old_value, __new_value); }
01401 
01402   // Sequential fallback for input iterator case
01403   template<typename _FIterator, typename _Tp, typename _IteratorTag>
01404     inline void
01405     __replace_switch(_FIterator __begin, _FIterator __end, 
01406                      const _Tp& __old_value, const _Tp& __new_value,
01407                      _IteratorTag)
01408     { replace(__begin, __end, __old_value, __new_value, 
01409               __gnu_parallel::sequential_tag()); }
01410 
01411   // Parallel replace for random access iterators
01412   template<typename _RAIter, typename _Tp>
01413     inline void
01414     __replace_switch(_RAIter __begin, _RAIter __end, 
01415                    const _Tp& __old_value, const _Tp& __new_value, 
01416                    random_access_iterator_tag, 
01417                    __gnu_parallel::_Parallelism __parallelism_tag
01418                    = __gnu_parallel::parallel_balanced)
01419     {
01420       // XXX parallel version is where?
01421       replace(__begin, __end, __old_value, __new_value, 
01422               __gnu_parallel::sequential_tag()); 
01423     }
01424 
01425   // Public interface
01426   template<typename _FIterator, typename _Tp>
01427     inline void
01428     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, 
01429             const _Tp& __new_value,
01430             __gnu_parallel::_Parallelism __parallelism_tag)
01431     {
01432       typedef iterator_traits<_FIterator> _TraitsType;
01433       typedef typename _TraitsType::iterator_category _IteratorCategory;
01434       __replace_switch(__begin, __end, __old_value, __new_value,
01435                        _IteratorCategory(),
01436                      __parallelism_tag);
01437     }
01438 
01439   template<typename _FIterator, typename _Tp>
01440     inline void
01441     replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value, 
01442             const _Tp& __new_value)
01443     {
01444       typedef iterator_traits<_FIterator> _TraitsType;
01445       typedef typename _TraitsType::iterator_category _IteratorCategory;
01446       __replace_switch(__begin, __end, __old_value, __new_value,
01447                        _IteratorCategory());
01448     }
01449 
01450 
01451   // Sequential fallback
01452   template<typename _FIterator, typename _Predicate, typename _Tp>
01453     inline void
01454     replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred, 
01455                const _Tp& __new_value, __gnu_parallel::sequential_tag)
01456     { _GLIBCXX_STD_P::replace_if(__begin, __end, __pred, __new_value); }
01457 
01458   // Sequential fallback for input iterator case
01459   template<typename _FIterator, typename _Predicate, typename _Tp,
01460            typename _IteratorTag>
01461     inline void
01462     __replace_if_switch(_FIterator __begin, _FIterator __end,
01463                       _Predicate __pred, const _Tp& __new_value, _IteratorTag)
01464     { replace_if(__begin, __end, __pred, __new_value,
01465                  __gnu_parallel::sequential_tag()); }
01466 
01467   // Parallel algorithm for random access iterators.
01468   template<typename _RAIter, typename _Predicate, typename _Tp>
01469     void
01470     __replace_if_switch(_RAIter __begin, _RAIter __end,
01471                       _Predicate __pred, const _Tp& __new_value,
01472                       random_access_iterator_tag,
01473                       __gnu_parallel::_Parallelism __parallelism_tag
01474                       = __gnu_parallel::parallel_balanced)
01475     {
01476       if (_GLIBCXX_PARALLEL_CONDITION(
01477             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
01478             >= __gnu_parallel::_Settings::get().replace_minimal_n
01479             && __gnu_parallel::__is_parallel(__parallelism_tag)))
01480         {
01481           bool __dummy;
01482           __gnu_parallel::
01483             __replace_if_selector<_RAIter, _Predicate, _Tp>
01484             __functionality(__new_value);
01485           __gnu_parallel::
01486             __for_each_template_random_access(
01487               __begin, __end, __pred, __functionality,
01488               __gnu_parallel::_DummyReduct(),
01489               true, __dummy, -1, __parallelism_tag);
01490         }
01491       else
01492         replace_if(__begin, __end, __pred, __new_value, 
01493                    __gnu_parallel::sequential_tag());
01494     }
01495 
01496   // Public interface.
01497   template<typename _FIterator, typename _Predicate, typename _Tp>
01498     inline void
01499     replace_if(_FIterator __begin, _FIterator __end,
01500                _Predicate __pred, const _Tp& __new_value, 
01501                __gnu_parallel::_Parallelism __parallelism_tag)
01502     {
01503       typedef std::iterator_traits<_FIterator> _IteratorTraits;
01504       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
01505       __replace_if_switch(__begin, __end, __pred, __new_value,
01506                           _IteratorCategory(), __parallelism_tag);
01507     }
01508 
01509   template<typename _FIterator, typename _Predicate, typename _Tp>
01510     inline void
01511     replace_if(_FIterator __begin, _FIterator __end,
01512                _Predicate __pred, const _Tp& __new_value)
01513     {
01514       typedef std::iterator_traits<_FIterator> _IteratorTraits;
01515       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
01516       __replace_if_switch(__begin, __end, __pred, __new_value,
01517                           _IteratorCategory());
01518     }
01519 
01520   // Sequential fallback
01521   template<typename _FIterator, typename _Generator>
01522     inline void
01523     generate(_FIterator __begin, _FIterator __end, _Generator __gen, 
01524              __gnu_parallel::sequential_tag)
01525     { _GLIBCXX_STD_P::generate(__begin, __end, __gen); }
01526 
01527   // Sequential fallback for input iterator case.
01528   template<typename _FIterator, typename _Generator, typename _IteratorTag>
01529     inline void
01530     __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
01531                     _IteratorTag)
01532     { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }
01533 
01534   // Parallel algorithm for random access iterators.
01535   template<typename _RAIter, typename _Generator>
01536     void
01537     __generate_switch(_RAIter __begin, _RAIter __end,
01538                     _Generator __gen, random_access_iterator_tag, 
01539                     __gnu_parallel::_Parallelism __parallelism_tag
01540                     = __gnu_parallel::parallel_balanced)
01541     {
01542       if (_GLIBCXX_PARALLEL_CONDITION(
01543             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
01544             >= __gnu_parallel::_Settings::get().generate_minimal_n
01545             && __gnu_parallel::__is_parallel(__parallelism_tag)))
01546         {
01547           bool __dummy;
01548           __gnu_parallel::__generate_selector<_RAIter>
01549             __functionality;
01550           __gnu_parallel::
01551             __for_each_template_random_access(
01552               __begin, __end, __gen, __functionality,
01553               __gnu_parallel::_DummyReduct(),
01554               true, __dummy, -1, __parallelism_tag);
01555         }
01556       else
01557         generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
01558     }
01559 
01560   // Public interface.
01561   template<typename _FIterator, typename _Generator>
01562     inline void
01563     generate(_FIterator __begin, _FIterator __end,
01564              _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
01565     {
01566       typedef std::iterator_traits<_FIterator> _IteratorTraits;
01567       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
01568       __generate_switch(__begin, __end, __gen, _IteratorCategory(),
01569                         __parallelism_tag);
01570     }
01571 
01572   template<typename _FIterator, typename _Generator>
01573     inline void
01574     generate(_FIterator __begin, _FIterator __end, _Generator __gen)
01575     {
01576       typedef std::iterator_traits<_FIterator> _IteratorTraits;
01577       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
01578       __generate_switch(__begin, __end, __gen, _IteratorCategory());
01579     }
01580 
01581 
01582   // Sequential fallback.
01583   template<typename _OutputIterator, typename _Size, typename _Generator>
01584     inline _OutputIterator
01585     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, 
01586                __gnu_parallel::sequential_tag)
01587     { return _GLIBCXX_STD_P::generate_n(__begin, __n, __gen); }
01588 
01589   // Sequential fallback for input iterator case.
01590   template<typename _OutputIterator, typename _Size, typename _Generator,
01591            typename _IteratorTag>
01592     inline _OutputIterator
01593     __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen,
01594                         _IteratorTag)
01595     { return generate_n(__begin, __n, __gen,
01596                         __gnu_parallel::sequential_tag()); }
01597 
01598   // Parallel algorithm for random access iterators.
01599   template<typename _RAIter, typename _Size, typename _Generator>
01600     inline _RAIter
01601     __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen, 
01602                       random_access_iterator_tag, 
01603                       __gnu_parallel::_Parallelism __parallelism_tag
01604                       = __gnu_parallel::parallel_balanced)
01605     {
01606       // XXX parallel version is where?
01607       return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
01608     }
01609 
01610   // Public interface.
01611   template<typename _OutputIterator, typename _Size, typename _Generator>
01612     inline _OutputIterator
01613     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen, 
01614                __gnu_parallel::_Parallelism __parallelism_tag)
01615     {
01616       typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
01617       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
01618       return __generate_n_switch(__begin, __n, __gen, _IteratorCategory(), 
01619                                __parallelism_tag); 
01620     }
01621 
01622   template<typename _OutputIterator, typename _Size, typename _Generator>
01623     inline _OutputIterator
01624     generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
01625     {
01626       typedef std::iterator_traits<_OutputIterator> _IteratorTraits;
01627       typedef typename _IteratorTraits::iterator_category _IteratorCategory;
01628       return __generate_n_switch(__begin, __n, __gen, _IteratorCategory());
01629     }
01630 
01631 
01632   // Sequential fallback.
01633   template<typename _RAIter>
01634     inline void
01635     random_shuffle(_RAIter __begin, _RAIter __end, 
01636                    __gnu_parallel::sequential_tag)
01637     { _GLIBCXX_STD_P::random_shuffle(__begin, __end); }
01638 
01639   // Sequential fallback.
01640   template<typename _RAIter, typename _RandomNumberGenerator>
01641     inline void
01642     random_shuffle(_RAIter __begin, _RAIter __end, 
01643                    _RandomNumberGenerator& __rand,
01644                    __gnu_parallel::sequential_tag)
01645     { _GLIBCXX_STD_P::random_shuffle(__begin, __end, __rand); }
01646 
01647 
01648   /** @brief Functor wrapper for std::rand(). */
01649   template<typename _MustBeInt = int>
01650     struct _CRandNumber
01651     {
01652       int
01653       operator()(int __limit)
01654       { return rand() % __limit; }
01655     };
01656 
01657   // Fill in random number generator.
01658   template<typename _RAIter>
01659     inline void
01660     random_shuffle(_RAIter __begin, _RAIter __end)
01661     {
01662       _CRandNumber<> __r;
01663       // Parallelization still possible.
01664       __gnu_parallel::random_shuffle(__begin, __end, __r);
01665     }
01666 
01667   // Parallel algorithm for random access iterators.
01668   template<typename _RAIter, typename _RandomNumberGenerator>
01669     void
01670     random_shuffle(_RAIter __begin, _RAIter __end, 
01671                    _RandomNumberGenerator& __rand)
01672     {
01673       if (__begin == __end)
01674         return;
01675       if (_GLIBCXX_PARALLEL_CONDITION(
01676             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
01677             >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
01678         __gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
01679       else
01680         __gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
01681     }
01682 
01683   // Sequential fallback.
01684   template<typename _FIterator, typename _Predicate>
01685     inline _FIterator
01686     partition(_FIterator __begin, _FIterator __end,
01687               _Predicate __pred, __gnu_parallel::sequential_tag)
01688     { return _GLIBCXX_STD_P::partition(__begin, __end, __pred); }
01689 
01690   // Sequential fallback for input iterator case.
01691   template<typename _FIterator, typename _Predicate, typename _IteratorTag>
01692     inline _FIterator
01693     __partition_switch(_FIterator __begin, _FIterator __end,
01694                      _Predicate __pred, _IteratorTag)
01695     { return partition(__begin, __end, __pred,
01696                        __gnu_parallel::sequential_tag()); }
01697 
01698   // Parallel algorithm for random access iterators.
01699   template<typename _RAIter, typename _Predicate>
01700     _RAIter
01701     __partition_switch(_RAIter __begin, _RAIter __end,
01702                      _Predicate __pred, random_access_iterator_tag)
01703     {
01704       if (_GLIBCXX_PARALLEL_CONDITION(
01705             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
01706             >= __gnu_parallel::_Settings::get().partition_minimal_n))
01707         {
01708           typedef typename std::iterator_traits<_RAIter>::
01709             difference_type _DifferenceType;
01710           _DifferenceType __middle = __gnu_parallel::
01711             __parallel_partition(__begin, __end, __pred,
01712                                __gnu_parallel::__get_max_threads());
01713           return __begin + __middle;
01714         }
01715       else
01716         return partition(__begin, __end, __pred,
01717                          __gnu_parallel::sequential_tag());
01718     }
01719 
01720   // Public interface.
01721   template<typename _FIterator, typename _Predicate>
01722     inline _FIterator
01723     partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
01724     {
01725       typedef iterator_traits<_FIterator> _TraitsType;
01726       typedef typename _TraitsType::iterator_category _IteratorCategory;
01727       return __partition_switch(__begin, __end, __pred, _IteratorCategory());
01728     }
01729 
01730   // sort interface
01731 
01732   // Sequential fallback
01733   template<typename _RAIter>
01734     inline void
01735     sort(_RAIter __begin, _RAIter __end, 
01736          __gnu_parallel::sequential_tag)
01737     { _GLIBCXX_STD_P::sort(__begin, __end); }
01738 
01739   // Sequential fallback
01740   template<typename _RAIter, typename _Compare>
01741     inline void
01742     sort(_RAIter __begin, _RAIter __end, _Compare __comp,
01743          __gnu_parallel::sequential_tag)
01744     { _GLIBCXX_STD_P::sort<_RAIter, _Compare>(__begin, __end,
01745                                                              __comp); }
01746 
01747   // Public interface
01748   template<typename _RAIter, typename _Compare,
01749            typename _Parallelism>
01750   void
01751   sort(_RAIter __begin, _RAIter __end, _Compare __comp,
01752        _Parallelism __parallelism)
01753   {
01754     typedef iterator_traits<_RAIter> _TraitsType;
01755     typedef typename _TraitsType::value_type _ValueType;
01756 
01757     if (__begin != __end)
01758       {
01759         if (_GLIBCXX_PARALLEL_CONDITION(
01760             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
01761               __gnu_parallel::_Settings::get().sort_minimal_n))
01762           __gnu_parallel::__parallel_sort<false>(
01763                             __begin, __end, __comp, __parallelism);
01764         else
01765           sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
01766       }
01767   }
01768 
01769   // Public interface, insert default comparator
01770   template<typename _RAIter>
01771     inline void
01772     sort(_RAIter __begin, _RAIter __end)
01773     {
01774       typedef iterator_traits<_RAIter> _TraitsType;
01775       typedef typename _TraitsType::value_type _ValueType;
01776       sort(__begin, __end, std::less<_ValueType>(),
01777            __gnu_parallel::default_parallel_tag());
01778     }
01779 
01780   // Public interface, insert default comparator
01781   template<typename _RAIter>
01782   inline void
01783   sort(_RAIter __begin, _RAIter __end,
01784        __gnu_parallel::default_parallel_tag __parallelism)
01785   {
01786     typedef iterator_traits<_RAIter> _TraitsType;
01787     typedef typename _TraitsType::value_type _ValueType;
01788     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01789   }
01790 
01791   // Public interface, insert default comparator
01792   template<typename _RAIter>
01793   inline void
01794   sort(_RAIter __begin, _RAIter __end,
01795        __gnu_parallel::parallel_tag __parallelism)
01796   {
01797     typedef iterator_traits<_RAIter> _TraitsType;
01798     typedef typename _TraitsType::value_type _ValueType;
01799     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01800   }
01801 
01802   // Public interface, insert default comparator
01803   template<typename _RAIter>
01804   inline void
01805   sort(_RAIter __begin, _RAIter __end,
01806        __gnu_parallel::multiway_mergesort_tag __parallelism)
01807   {
01808     typedef iterator_traits<_RAIter> _TraitsType;
01809     typedef typename _TraitsType::value_type _ValueType;
01810     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01811   }
01812 
01813   // Public interface, insert default comparator
01814   template<typename _RAIter>
01815   inline void
01816   sort(_RAIter __begin, _RAIter __end,
01817        __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
01818   {
01819     typedef iterator_traits<_RAIter> _TraitsType;
01820     typedef typename _TraitsType::value_type _ValueType;
01821     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01822   }
01823 
01824   // Public interface, insert default comparator
01825   template<typename _RAIter>
01826   inline void
01827   sort(_RAIter __begin, _RAIter __end,
01828        __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
01829   {
01830     typedef iterator_traits<_RAIter> _TraitsType;
01831     typedef typename _TraitsType::value_type _ValueType;
01832     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01833   }
01834 
01835   // Public interface, insert default comparator
01836   template<typename _RAIter>
01837   inline void
01838   sort(_RAIter __begin, _RAIter __end,
01839        __gnu_parallel::quicksort_tag __parallelism)
01840   {
01841     typedef iterator_traits<_RAIter> _TraitsType;
01842     typedef typename _TraitsType::value_type _ValueType;
01843     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01844   }
01845 
01846   // Public interface, insert default comparator
01847   template<typename _RAIter>
01848   inline void
01849   sort(_RAIter __begin, _RAIter __end,
01850        __gnu_parallel::balanced_quicksort_tag __parallelism)
01851   {
01852     typedef iterator_traits<_RAIter> _TraitsType;
01853     typedef typename _TraitsType::value_type _ValueType;
01854     sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01855   }
01856 
01857   // Public interface
01858   template<typename _RAIter, typename _Compare>
01859     void
01860     sort(_RAIter __begin, _RAIter __end, _Compare __comp)
01861     {
01862       typedef iterator_traits<_RAIter> _TraitsType;
01863       typedef typename _TraitsType::value_type _ValueType;
01864     sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
01865   }
01866 
01867 
01868   // stable_sort interface
01869 
01870 
01871   // Sequential fallback
01872   template<typename _RAIter>
01873   inline void
01874   stable_sort(_RAIter __begin, _RAIter __end,
01875        __gnu_parallel::sequential_tag)
01876   { _GLIBCXX_STD_P::stable_sort(__begin, __end); }
01877 
01878   // Sequential fallback
01879   template<typename _RAIter, typename _Compare>
01880   inline void
01881   stable_sort(_RAIter __begin, _RAIter __end,
01882               _Compare __comp, __gnu_parallel::sequential_tag)
01883   { _GLIBCXX_STD_P::stable_sort<_RAIter, _Compare>(
01884       __begin, __end, __comp); }
01885 
01886   // Public interface
01887   template<typename _RAIter, typename _Compare,
01888            typename _Parallelism>
01889   void
01890   stable_sort(_RAIter __begin, _RAIter __end,
01891               _Compare __comp, _Parallelism __parallelism)
01892   {
01893     typedef iterator_traits<_RAIter> _TraitsType;
01894     typedef typename _TraitsType::value_type _ValueType;
01895 
01896     if (__begin != __end)
01897       {
01898         if (_GLIBCXX_PARALLEL_CONDITION(
01899               static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
01900               __gnu_parallel::_Settings::get().sort_minimal_n))
01901           __gnu_parallel::__parallel_sort<true>(
01902                             __begin, __end, __comp, __parallelism);
01903         else
01904           stable_sort(__begin, __end, __comp,
01905                       __gnu_parallel::sequential_tag());
01906       }
01907   }
01908 
01909   // Public interface, insert default comparator
01910   template<typename _RAIter>
01911   inline void
01912   stable_sort(_RAIter __begin, _RAIter __end)
01913   {
01914     typedef iterator_traits<_RAIter> _TraitsType;
01915     typedef typename _TraitsType::value_type _ValueType;
01916     stable_sort(__begin, __end, std::less<_ValueType>(),
01917                 __gnu_parallel::default_parallel_tag());
01918   }
01919 
01920   // Public interface, insert default comparator
01921   template<typename _RAIter>
01922   inline void
01923   stable_sort(_RAIter __begin, _RAIter __end,
01924               __gnu_parallel::default_parallel_tag __parallelism)
01925   {
01926     typedef iterator_traits<_RAIter> _TraitsType;
01927     typedef typename _TraitsType::value_type _ValueType;
01928     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01929   }
01930 
01931   // Public interface, insert default comparator
01932   template<typename _RAIter>
01933   inline void
01934   stable_sort(_RAIter __begin, _RAIter __end,
01935               __gnu_parallel::parallel_tag __parallelism)
01936   {
01937     typedef iterator_traits<_RAIter> _TraitsType;
01938     typedef typename _TraitsType::value_type _ValueType;
01939     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01940   }
01941 
01942   // Public interface, insert default comparator
01943   template<typename _RAIter>
01944   inline void
01945   stable_sort(_RAIter __begin, _RAIter __end,
01946               __gnu_parallel::multiway_mergesort_tag __parallelism)
01947   {
01948     typedef iterator_traits<_RAIter> _TraitsType;
01949     typedef typename _TraitsType::value_type _ValueType;
01950     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01951   }
01952 
01953   // Public interface, insert default comparator
01954   template<typename _RAIter>
01955   inline void
01956   stable_sort(_RAIter __begin, _RAIter __end,
01957               __gnu_parallel::quicksort_tag __parallelism)
01958   {
01959     typedef iterator_traits<_RAIter> _TraitsType;
01960     typedef typename _TraitsType::value_type _ValueType;
01961     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01962   }
01963 
01964   // Public interface, insert default comparator
01965   template<typename _RAIter>
01966   inline void
01967   stable_sort(_RAIter __begin, _RAIter __end,
01968               __gnu_parallel::balanced_quicksort_tag __parallelism)
01969   {
01970     typedef iterator_traits<_RAIter> _TraitsType;
01971     typedef typename _TraitsType::value_type _ValueType;
01972     stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
01973   }
01974 
01975   // Public interface
01976   template<typename _RAIter, typename _Compare>
01977   void
01978   stable_sort(_RAIter __begin, _RAIter __end,
01979               _Compare __comp)
01980   {
01981     typedef iterator_traits<_RAIter> _TraitsType;
01982     typedef typename _TraitsType::value_type _ValueType;
01983     stable_sort(
01984       __begin, __end, __comp, __gnu_parallel::default_parallel_tag());
01985   }
01986 
01987   // Sequential fallback
01988   template<typename _IIter1, typename _IIter2,
01989            typename _OutputIterator>
01990     inline _OutputIterator
01991     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
01992           _IIter2 __end2, _OutputIterator __result,
01993           __gnu_parallel::sequential_tag)
01994     { return _GLIBCXX_STD_P::merge(
01995                __begin1, __end1, __begin2, __end2, __result); }
01996 
01997   // Sequential fallback
01998   template<typename _IIter1, typename _IIter2,
01999            typename _OutputIterator, typename _Compare>
02000     inline _OutputIterator
02001     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
02002           _IIter2 __end2, _OutputIterator __result, _Compare __comp,
02003           __gnu_parallel::sequential_tag)
02004     { return _GLIBCXX_STD_P::merge(
02005                 __begin1, __end1, __begin2, __end2, __result, __comp); }
02006 
02007   // Sequential fallback for input iterator case
02008   template<typename _IIter1, typename _IIter2, typename _OutputIterator,
02009            typename _Compare, typename _IteratorTag1,
02010            typename _IteratorTag2, typename _IteratorTag3>
02011     inline _OutputIterator
02012     __merge_switch(_IIter1 __begin1, _IIter1 __end1,
02013                  _IIter2 __begin2, _IIter2 __end2,
02014                  _OutputIterator __result, _Compare __comp,
02015                  _IteratorTag1, _IteratorTag2, _IteratorTag3)
02016      { return _GLIBCXX_STD_P::merge(__begin1, __end1, __begin2, __end2,
02017                                     __result, __comp); }
02018 
02019   // Parallel algorithm for random access iterators
02020   template<typename _IIter1, typename _IIter2,
02021            typename _OutputIterator, typename _Compare>
02022     _OutputIterator
02023     __merge_switch(_IIter1 __begin1, _IIter1 __end1, 
02024                  _IIter2 __begin2, _IIter2 __end2, 
02025                  _OutputIterator __result, _Compare __comp, 
02026                  random_access_iterator_tag, random_access_iterator_tag, 
02027                  random_access_iterator_tag)
02028     {
02029       if (_GLIBCXX_PARALLEL_CONDITION(
02030             (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
02031              >= __gnu_parallel::_Settings::get().merge_minimal_n
02032              || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
02033              >= __gnu_parallel::_Settings::get().merge_minimal_n)))
02034         return __gnu_parallel::__parallel_merge_advance(
02035                  __begin1, __end1, __begin2, __end2, __result,
02036                  (__end1 - __begin1) + (__end2 - __begin2), __comp);
02037       else
02038         return __gnu_parallel::__merge_advance(
02039                  __begin1, __end1, __begin2, __end2, __result,
02040                  (__end1 - __begin1) + (__end2 - __begin2), __comp);
02041   }
02042 
02043   // Public interface
02044   template<typename _IIter1, typename _IIter2,
02045            typename _OutputIterator, typename _Compare>
02046     inline _OutputIterator
02047     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
02048           _IIter2 __end2, _OutputIterator __result, _Compare __comp)
02049     {
02050       typedef typename iterator_traits<_IIter1>::value_type _ValueType;
02051 
02052       typedef std::iterator_traits<_IIter1> _IIterTraits1;
02053       typedef std::iterator_traits<_IIter2> _IIterTraits2;
02054       typedef std::iterator_traits<_OutputIterator> _OIterTraits;
02055       typedef typename _IIterTraits1::iterator_category
02056         _IIterCategory1;
02057       typedef typename _IIterTraits2::iterator_category
02058         _IIterCategory2;
02059       typedef typename _OIterTraits::iterator_category _OIterCategory;
02060 
02061       return __merge_switch(
02062               __begin1, __end1, __begin2, __end2, __result, __comp,
02063               _IIterCategory1(), _IIterCategory2(), _OIterCategory());
02064   }
02065 
02066 
02067   // Public interface, insert default comparator
02068   template<typename _IIter1, typename _IIter2,
02069            typename _OutputIterator>
02070     inline _OutputIterator
02071     merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
02072           _IIter2 __end2, _OutputIterator __result)
02073     {
02074       typedef std::iterator_traits<_IIter1> _Iterator1Traits;
02075       typedef std::iterator_traits<_IIter2> _Iterator2Traits;
02076       typedef typename _Iterator1Traits::value_type _ValueType1;
02077       typedef typename _Iterator2Traits::value_type _ValueType2;
02078 
02079       return merge(__begin1, __end1, __begin2, __end2, __result, 
02080                    __gnu_parallel::_Less<_ValueType1, _ValueType2>());
02081     }
02082 
02083   // Sequential fallback
02084   template<typename _RAIter>
02085     inline void
02086     nth_element(_RAIter __begin, _RAIter __nth, 
02087                 _RAIter __end, __gnu_parallel::sequential_tag)
02088     { return _GLIBCXX_STD_P::nth_element(__begin, __nth, __end); }
02089 
02090   // Sequential fallback
02091   template<typename _RAIter, typename _Compare>
02092     inline void
02093     nth_element(_RAIter __begin, _RAIter __nth, 
02094                 _RAIter __end, _Compare __comp, 
02095               __gnu_parallel::sequential_tag)
02096     { return _GLIBCXX_STD_P::nth_element(__begin, __nth, __end, __comp); }
02097 
02098   // Public interface
02099   template<typename _RAIter, typename _Compare>
02100     inline void
02101     nth_element(_RAIter __begin, _RAIter __nth, 
02102                 _RAIter __end, _Compare __comp)
02103     {
02104       if (_GLIBCXX_PARALLEL_CONDITION(
02105             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
02106             >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
02107         __gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
02108       else
02109         nth_element(__begin, __nth, __end, __comp,
02110                     __gnu_parallel::sequential_tag());
02111     }
02112 
02113   // Public interface, insert default comparator
02114   template<typename _RAIter>
02115     inline void
02116     nth_element(_RAIter __begin, _RAIter __nth, 
02117                 _RAIter __end)
02118     {
02119       typedef iterator_traits<_RAIter> _TraitsType;
02120       typedef typename _TraitsType::value_type _ValueType;
02121       nth_element(__begin, __nth, __end, std::less<_ValueType>());
02122     }
02123 
02124   // Sequential fallback
02125   template<typename _RAIter, typename _Compare>
02126     inline void
02127     partial_sort(_RAIter __begin, _RAIter __middle, 
02128                  _RAIter __end, _Compare __comp,
02129                  __gnu_parallel::sequential_tag)
02130     { _GLIBCXX_STD_P::partial_sort(__begin, __middle, __end, __comp); }
02131 
02132   // Sequential fallback
02133   template<typename _RAIter>
02134     inline void
02135     partial_sort(_RAIter __begin, _RAIter __middle, 
02136                  _RAIter __end, __gnu_parallel::sequential_tag)
02137     { _GLIBCXX_STD_P::partial_sort(__begin, __middle, __end); }
02138 
02139   // Public interface, parallel algorithm for random access iterators
02140   template<typename _RAIter, typename _Compare>
02141     void
02142     partial_sort(_RAIter __begin, _RAIter __middle, 
02143                  _RAIter __end, _Compare __comp)
02144     {
02145       if (_GLIBCXX_PARALLEL_CONDITION(
02146             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
02147             >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
02148         __gnu_parallel::
02149           __parallel_partial_sort(__begin, __middle, __end, __comp);
02150       else
02151         partial_sort(__begin, __middle, __end, __comp,
02152                      __gnu_parallel::sequential_tag());
02153     }
02154 
02155   // Public interface, insert default comparator
02156   template<typename _RAIter>
02157     inline void
02158     partial_sort(_RAIter __begin, _RAIter __middle, 
02159                  _RAIter __end)
02160     {
02161       typedef iterator_traits<_RAIter> _TraitsType;
02162       typedef typename _TraitsType::value_type _ValueType;
02163       partial_sort(__begin, __middle, __end, std::less<_ValueType>());
02164     }
02165 
02166   // Sequential fallback
02167   template<typename _FIterator>
02168     inline _FIterator
02169     max_element(_FIterator __begin, _FIterator __end, 
02170                 __gnu_parallel::sequential_tag)
02171     { return _GLIBCXX_STD_P::max_element(__begin, __end); }
02172 
02173   // Sequential fallback
02174   template<typename _FIterator, typename _Compare>
02175     inline _FIterator
02176     max_element(_FIterator __begin, _FIterator __end, _Compare __comp, 
02177                 __gnu_parallel::sequential_tag)
02178     { return _GLIBCXX_STD_P::max_element(__begin, __end, __comp); }
02179 
02180   // Sequential fallback for input iterator case
02181   template<typename _FIterator, typename _Compare, typename _IteratorTag>
02182     inline _FIterator
02183     __max_element_switch(_FIterator __begin, _FIterator __end, 
02184                        _Compare __comp, _IteratorTag)
02185     { return max_element(__begin, __end, __comp,
02186                          __gnu_parallel::sequential_tag()); }
02187 
02188   // Parallel algorithm for random access iterators
02189   template<typename _RAIter, typename _Compare>
02190     _RAIter
02191     __max_element_switch(_RAIter __begin, _RAIter __end, 
02192                        _Compare __comp, random_access_iterator_tag, 
02193                        __gnu_parallel::_Parallelism __parallelism_tag
02194                        = __gnu_parallel::parallel_balanced)
02195     {
02196       if (_GLIBCXX_PARALLEL_CONDITION(
02197             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
02198             >= __gnu_parallel::_Settings::get().max_element_minimal_n
02199             && __gnu_parallel::__is_parallel(__parallelism_tag)))
02200         {
02201           _RAIter __res(__begin);
02202           __gnu_parallel::__identity_selector<_RAIter>
02203             __functionality;
02204           __gnu_parallel::
02205             __for_each_template_random_access(
02206               __begin, __end, __gnu_parallel::_Nothing(), __functionality,
02207               __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
02208               __res, __res, -1, __parallelism_tag);
02209           return __res;
02210         }
02211       else
02212         return max_element(__begin, __end, __comp,
02213                            __gnu_parallel::sequential_tag());
02214     }
02215 
02216   // Public interface, insert default comparator
02217   template<typename _FIterator>
02218     inline _FIterator
02219     max_element(_FIterator __begin, _FIterator __end, 
02220                 __gnu_parallel::_Parallelism __parallelism_tag)
02221     {
02222       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
02223       return max_element(__begin, __end, std::less<_ValueType>(),
02224                          __parallelism_tag);
02225     }
02226 
02227   template<typename _FIterator>
02228     inline _FIterator
02229     max_element(_FIterator __begin, _FIterator __end)
02230     {
02231       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
02232       return max_element(__begin, __end, std::less<_ValueType>());
02233     }
02234 
02235   // Public interface
02236   template<typename _FIterator, typename _Compare>
02237     inline _FIterator
02238     max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
02239                 __gnu_parallel::_Parallelism __parallelism_tag)
02240     {
02241       typedef iterator_traits<_FIterator> _TraitsType;
02242       typedef typename _TraitsType::iterator_category _IteratorCategory;
02243       return __max_element_switch(__begin, __end, __comp, _IteratorCategory(), 
02244                                   __parallelism_tag);
02245     }
02246 
02247   template<typename _FIterator, typename _Compare>
02248     inline _FIterator
02249     max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
02250     {
02251       typedef iterator_traits<_FIterator> _TraitsType;
02252       typedef typename _TraitsType::iterator_category _IteratorCategory;
02253       return __max_element_switch(__begin, __end, __comp, _IteratorCategory());
02254     }
02255 
02256 
02257   // Sequential fallback
02258   template<typename _FIterator>
02259     inline _FIterator
02260     min_element(_FIterator __begin, _FIterator __end, 
02261                 __gnu_parallel::sequential_tag)
02262     { return _GLIBCXX_STD_P::min_element(__begin, __end); }
02263 
02264   // Sequential fallback
02265   template<typename _FIterator, typename _Compare>
02266     inline _FIterator
02267     min_element(_FIterator __begin, _FIterator __end, _Compare __comp, 
02268                 __gnu_parallel::sequential_tag)
02269     { return _GLIBCXX_STD_P::min_element(__begin, __end, __comp); }
02270 
02271   // Sequential fallback for input iterator case
02272   template<typename _FIterator, typename _Compare, typename _IteratorTag>
02273     inline _FIterator
02274     __min_element_switch(_FIterator __begin, _FIterator __end, 
02275                        _Compare __comp, _IteratorTag)
02276     { return min_element(__begin, __end, __comp,
02277                          __gnu_parallel::sequential_tag()); }
02278 
02279   // Parallel algorithm for random access iterators
02280   template<typename _RAIter, typename _Compare>
02281     _RAIter
02282     __min_element_switch(_RAIter __begin, _RAIter __end, 
02283                        _Compare __comp, random_access_iterator_tag, 
02284                        __gnu_parallel::_Parallelism __parallelism_tag
02285                        = __gnu_parallel::parallel_balanced)
02286     {
02287       if (_GLIBCXX_PARALLEL_CONDITION(
02288             static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
02289             >= __gnu_parallel::_Settings::get().min_element_minimal_n
02290             && __gnu_parallel::__is_parallel(__parallelism_tag)))
02291         {
02292           _RAIter __res(__begin);
02293           __gnu_parallel::__identity_selector<_RAIter>
02294             __functionality;
02295           __gnu_parallel::
02296             __for_each_template_random_access(
02297               __begin, __end, __gnu_parallel::_Nothing(), __functionality,
02298               __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
02299               __res, __res, -1, __parallelism_tag);
02300           return __res;
02301         }
02302       else
02303         return min_element(__begin, __end, __comp,
02304                            __gnu_parallel::sequential_tag());
02305     }
02306 
02307   // Public interface, insert default comparator
02308   template<typename _FIterator>
02309     inline _FIterator
02310     min_element(_FIterator __begin, _FIterator __end, 
02311                 __gnu_parallel::_Parallelism __parallelism_tag)
02312     {
02313       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
02314       return min_element(__begin, __end, std::less<_ValueType>(),
02315                          __parallelism_tag);
02316     }
02317 
02318   template<typename _FIterator>
02319     inline _FIterator
02320     min_element(_FIterator __begin, _FIterator __end)
02321     {
02322       typedef typename iterator_traits<_FIterator>::value_type _ValueType;
02323       return min_element(__begin, __end, std::less<_ValueType>());
02324     }
02325 
02326   // Public interface
02327   template<typename _FIterator, typename _Compare>
02328     inline _FIterator
02329     min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
02330                 __gnu_parallel::_Parallelism __parallelism_tag)
02331     {
02332       typedef iterator_traits<_FIterator> _TraitsType;
02333       typedef typename _TraitsType::iterator_category _IteratorCategory;
02334       return __min_element_switch(__begin, __end, __comp, _IteratorCategory(), 
02335                                 __parallelism_tag);
02336     }
02337 
02338   template<typename _FIterator, typename _Compare>
02339     inline _FIterator
02340     min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
02341     {
02342       typedef iterator_traits<_FIterator> _TraitsType;
02343       typedef typename _TraitsType::iterator_category _IteratorCategory;
02344       return __min_element_switch(__begin, __end, __comp, _IteratorCategory());
02345     }
02346 } // end namespace
02347 } // end namespace
02348 
02349 #endif /* _GLIBCXX_PARALLEL_ALGO_H */

Generated on 11 Jan 2010 for libstdc++ by  doxygen 1.6.1