algobase.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/algobase.h
00026  *  @brief Parallel STL function calls corresponding to the
00027  *  stl_algobase.h header.  The functions defined here mainly do case
00028  *  switches and call the actual parallelized versions in other files.
00029  *  Inlining policy: Functions that basically only contain one
00030  *  function call, are declared inline.
00031  *  This file is a GNU parallel extension to the Standard C++ Library.
00032  */
00033 
00034 // Written by Johannes Singler and Felix Putze.
00035 
00036 #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H
00037 #define _GLIBCXX_PARALLEL_ALGOBASE_H 1
00038 
00039 #include <bits/stl_algobase.h>
00040 #include <parallel/base.h>
00041 #include <parallel/tags.h>
00042 #include <parallel/settings.h>
00043 #include <parallel/find.h>
00044 #include <parallel/find_selectors.h>
00045 
00046 namespace std
00047 {
00048 namespace __parallel
00049 {
00050   // NB: equal and lexicographical_compare require mismatch.
00051 
00052   // Sequential fallback
00053   template<typename _IIter1, typename _IIter2>
00054     inline pair<_IIter1, _IIter2>
00055     mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
00056              __gnu_parallel::sequential_tag)
00057     { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2); }
00058 
00059   // Sequential fallback
00060   template<typename _IIter1, typename _IIter2, typename _Predicate>
00061     inline pair<_IIter1, _IIter2>
00062     mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
00063              _Predicate __pred, __gnu_parallel::sequential_tag)
00064     { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred); }
00065 
00066   // Sequential fallback for input iterator case
00067   template<typename _IIter1, typename _IIter2,
00068            typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
00069     inline pair<_IIter1, _IIter2>
00070     __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
00071                       _Predicate __pred, _IteratorTag1, _IteratorTag2)
00072     { return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred); }
00073 
00074   // Parallel mismatch for random access iterators
00075   template<typename _RAIter1, typename _RAIter2, typename _Predicate>
00076     pair<_RAIter1, _RAIter2>
00077     __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1,
00078                       _RAIter2 __begin2, _Predicate __pred, 
00079                       random_access_iterator_tag, random_access_iterator_tag)
00080     {
00081       if (_GLIBCXX_PARALLEL_CONDITION(true))
00082         {
00083           _RAIter1 __res =
00084             __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred,
00085                                             __gnu_parallel::
00086                                             __mismatch_selector()).first;
00087           return make_pair(__res , __begin2 + (__res - __begin1));
00088         }
00089       else
00090         return _GLIBCXX_STD_P::mismatch(__begin1, __end1, __begin2, __pred);
00091     }
00092 
00093   // Public interface
00094   template<typename _IIter1, typename _IIter2>
00095     inline pair<_IIter1, _IIter2>
00096     mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
00097     {
00098       typedef std::iterator_traits<_IIter1> _Iterator1Traits;
00099       typedef std::iterator_traits<_IIter2> _Iterator2Traits;
00100       typedef typename _Iterator1Traits::value_type _ValueType1;
00101       typedef typename _Iterator2Traits::value_type _ValueType2;
00102       typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
00103       typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
00104 
00105       typedef __gnu_parallel::_EqualTo<_ValueType1, _ValueType2> _EqualTo;
00106 
00107       return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(),
00108                                _IteratorCategory1(), _IteratorCategory2());
00109     }
00110 
00111   // Public interface
00112   template<typename _IIter1, typename _IIter2, typename _Predicate>
00113     inline pair<_IIter1, _IIter2>
00114     mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
00115              _Predicate __pred)
00116     {
00117       typedef std::iterator_traits<_IIter1> _Iterator1Traits;
00118       typedef std::iterator_traits<_IIter2> _Iterator2Traits;
00119       typedef typename _Iterator1Traits::iterator_category _IteratorCategory1;
00120       typedef typename _Iterator2Traits::iterator_category _IteratorCategory2;
00121 
00122       return __mismatch_switch(__begin1, __end1, __begin2, __pred,
00123                                _IteratorCategory1(), _IteratorCategory2());
00124     }
00125 
00126   // Sequential fallback
00127   template<typename _IIter1, typename _IIter2>
00128     inline bool
00129     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
00130           __gnu_parallel::sequential_tag)
00131     { return _GLIBCXX_STD_P::equal(__begin1, __end1, __begin2); }
00132 
00133   // Sequential fallback
00134   template<typename _IIter1, typename _IIter2, typename _Predicate>
00135     inline bool
00136     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
00137           _Predicate __pred, __gnu_parallel::sequential_tag)
00138     { return _GLIBCXX_STD_P::equal(__begin1, __end1, __begin2, __pred); }
00139 
00140   // Public interface
00141   template<typename _IIter1, typename _IIter2>
00142     inline bool
00143     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2)
00144     { return mismatch(__begin1, __end1, __begin2).first == __end1; }
00145 
00146   // Public interface
00147   template<typename _IIter1, typename _IIter2, typename _Predicate>
00148     inline bool
00149     equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 
00150           _Predicate __pred)
00151     { return mismatch(__begin1, __end1, __begin2, __pred).first == __end1; }
00152 
00153   // Sequential fallback
00154   template<typename _IIter1, typename _IIter2>
00155     inline bool
00156     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 
00157                             _IIter2 __begin2, _IIter2 __end2, 
00158                             __gnu_parallel::sequential_tag)
00159     { return _GLIBCXX_STD_P::lexicographical_compare(__begin1, __end1,
00160                                                      __begin2, __end2); }
00161 
00162   // Sequential fallback
00163   template<typename _IIter1, typename _IIter2, typename _Predicate>
00164     inline bool
00165     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 
00166                             _IIter2 __begin2, _IIter2 __end2, 
00167                             _Predicate __pred, __gnu_parallel::sequential_tag)
00168     { return _GLIBCXX_STD_P::lexicographical_compare(
00169                __begin1, __end1, __begin2, __end2, __pred); }
00170 
00171   // Sequential fallback for input iterator case
00172   template<typename _IIter1, typename _IIter2,
00173            typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
00174     inline bool
00175     __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1,
00176                                      _IIter2 __begin2, _IIter2 __end2, 
00177                                      _Predicate __pred,
00178                                      _IteratorTag1, _IteratorTag2)
00179     { return _GLIBCXX_STD_P::lexicographical_compare(
00180                __begin1, __end1, __begin2, __end2, __pred); }
00181 
00182   // Parallel lexicographical_compare for random access iterators
00183   // Limitation: Both valuetypes must be the same
00184   template<typename _RAIter1, typename _RAIter2, typename _Predicate>
00185     bool
00186     __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1,
00187                                      _RAIter2 __begin2, _RAIter2 __end2,
00188                                      _Predicate __pred,
00189                                      random_access_iterator_tag, 
00190                                      random_access_iterator_tag)
00191     {
00192       if (_GLIBCXX_PARALLEL_CONDITION(true))
00193         {
00194           typedef iterator_traits<_RAIter1> _TraitsType1;
00195           typedef typename _TraitsType1::value_type _ValueType1;
00196 
00197           typedef iterator_traits<_RAIter2> _TraitsType2;
00198           typedef typename _TraitsType2::value_type _ValueType2;
00199 
00200           typedef __gnu_parallel::
00201                   _EqualFromLess<_ValueType1, _ValueType2, _Predicate>
00202                   _EqualFromLessCompare;
00203 
00204           // Longer sequence in first place.
00205           if ((__end1 - __begin1) < (__end2 - __begin2))
00206             {
00207               typedef pair<_RAIter1, _RAIter2> _SpotType;
00208               _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2, 
00209                                              _EqualFromLessCompare(__pred), 
00210                                              random_access_iterator_tag(), 
00211                                              random_access_iterator_tag());
00212 
00213               return (__mm.first == __end1)
00214                         || bool(__pred(*__mm.first, *__mm.second));
00215             }
00216           else
00217             {
00218               typedef pair<_RAIter2, _RAIter1> _SpotType;
00219               _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1, 
00220                                              _EqualFromLessCompare(__pred), 
00221                                              random_access_iterator_tag(), 
00222                                              random_access_iterator_tag());
00223 
00224               return (__mm.first != __end2)
00225                         && bool(__pred(*__mm.second, *__mm.first));
00226             }
00227         }
00228       else
00229         return _GLIBCXX_STD_P::lexicographical_compare(
00230                  __begin1, __end1, __begin2, __end2, __pred);
00231     }
00232 
00233   // Public interface
00234   template<typename _IIter1, typename _IIter2>
00235     inline bool
00236     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
00237                             _IIter2 __begin2, _IIter2 __end2)
00238     {
00239       typedef iterator_traits<_IIter1> _TraitsType1;
00240       typedef typename _TraitsType1::value_type _ValueType1;
00241       typedef typename _TraitsType1::iterator_category _IteratorCategory1;
00242 
00243       typedef iterator_traits<_IIter2> _TraitsType2;
00244       typedef typename _TraitsType2::value_type _ValueType2;
00245       typedef typename _TraitsType2::iterator_category _IteratorCategory2;
00246       typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType;
00247 
00248       return __lexicographical_compare_switch(
00249                __begin1, __end1, __begin2, __end2, _LessType(),
00250                _IteratorCategory1(), _IteratorCategory2());
00251     }
00252 
00253   // Public interface
00254   template<typename _IIter1, typename _IIter2, typename _Predicate>
00255     inline bool
00256     lexicographical_compare(_IIter1 __begin1, _IIter1 __end1,
00257                             _IIter2 __begin2, _IIter2 __end2,
00258                             _Predicate __pred)
00259     {
00260       typedef iterator_traits<_IIter1> _TraitsType1;
00261       typedef typename _TraitsType1::iterator_category _IteratorCategory1;
00262 
00263       typedef iterator_traits<_IIter2> _TraitsType2;
00264       typedef typename _TraitsType2::iterator_category _IteratorCategory2;
00265 
00266       return __lexicographical_compare_switch(
00267                __begin1, __end1, __begin2, __end2, __pred,
00268                _IteratorCategory1(), _IteratorCategory2());
00269     }
00270 } // end namespace
00271 } // end namespace
00272 
00273 #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */

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