libstdc++
|
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/find_selectors.h 00026 * @brief _Function objects representing different tasks to be plugged 00027 * into the parallel find algorithm. 00028 * This file is a GNU parallel extension to the Standard C++ Library. 00029 */ 00030 00031 // Written by Felix Putze. 00032 00033 #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H 00034 #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1 00035 00036 #include <parallel/tags.h> 00037 #include <parallel/basic_iterator.h> 00038 #include <bits/stl_pair.h> 00039 00040 namespace __gnu_parallel 00041 { 00042 /** @brief Base class of all __gnu_parallel::__find_template selectors. */ 00043 struct __generic_find_selector 00044 { }; 00045 00046 /** 00047 * @brief Test predicate on a single element, used for std::find() 00048 * and std::find_if (). 00049 */ 00050 struct __find_if_selector : public __generic_find_selector 00051 { 00052 /** @brief Test on one position. 00053 * @param __i1 _Iterator on first sequence. 00054 * @param __i2 _Iterator on second sequence (unused). 00055 * @param __pred Find predicate. 00056 */ 00057 template<typename _RAIter1, typename _RAIter2, 00058 typename _Pred> 00059 bool 00060 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 00061 { return __pred(*__i1); } 00062 00063 /** @brief Corresponding sequential algorithm on a sequence. 00064 * @param __begin1 Begin iterator of first sequence. 00065 * @param __end1 End iterator of first sequence. 00066 * @param __begin2 Begin iterator of second sequence. 00067 * @param __pred Find predicate. 00068 */ 00069 template<typename _RAIter1, typename _RAIter2, 00070 typename _Pred> 00071 std::pair<_RAIter1, _RAIter2> 00072 _M_sequential_algorithm(_RAIter1 __begin1, 00073 _RAIter1 __end1, 00074 _RAIter2 __begin2, _Pred __pred) 00075 { return std::make_pair(find_if(__begin1, __end1, __pred, 00076 sequential_tag()), __begin2); } 00077 }; 00078 00079 /** @brief Test predicate on two adjacent elements. */ 00080 struct __adjacent_find_selector : public __generic_find_selector 00081 { 00082 /** @brief Test on one position. 00083 * @param __i1 _Iterator on first sequence. 00084 * @param __i2 _Iterator on second sequence (unused). 00085 * @param __pred Find predicate. 00086 */ 00087 template<typename _RAIter1, typename _RAIter2, 00088 typename _Pred> 00089 bool 00090 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 00091 { 00092 // Passed end iterator is one short. 00093 return __pred(*__i1, *(__i1 + 1)); 00094 } 00095 00096 /** @brief Corresponding sequential algorithm on a sequence. 00097 * @param __begin1 Begin iterator of first sequence. 00098 * @param __end1 End iterator of first sequence. 00099 * @param __begin2 Begin iterator of second sequence. 00100 * @param __pred Find predicate. 00101 */ 00102 template<typename _RAIter1, typename _RAIter2, 00103 typename _Pred> 00104 std::pair<_RAIter1, _RAIter2> 00105 _M_sequential_algorithm(_RAIter1 __begin1, 00106 _RAIter1 __end1, 00107 _RAIter2 __begin2, _Pred __pred) 00108 { 00109 // Passed end iterator is one short. 00110 _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1, 00111 __pred, sequential_tag()); 00112 if (__spot == (__end1 + 1)) 00113 __spot = __end1; 00114 return std::make_pair(__spot, __begin2); 00115 } 00116 }; 00117 00118 /** @brief Test inverted predicate on a single element. */ 00119 struct __mismatch_selector : public __generic_find_selector 00120 { 00121 /** 00122 * @brief Test on one position. 00123 * @param __i1 _Iterator on first sequence. 00124 * @param __i2 _Iterator on second sequence (unused). 00125 * @param __pred Find predicate. 00126 */ 00127 template<typename _RAIter1, typename _RAIter2, 00128 typename _Pred> 00129 bool 00130 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 00131 { return !__pred(*__i1, *__i2); } 00132 00133 /** 00134 * @brief Corresponding sequential algorithm on a sequence. 00135 * @param __begin1 Begin iterator of first sequence. 00136 * @param __end1 End iterator of first sequence. 00137 * @param __begin2 Begin iterator of second sequence. 00138 * @param __pred Find predicate. 00139 */ 00140 template<typename _RAIter1, typename _RAIter2, 00141 typename _Pred> 00142 std::pair<_RAIter1, _RAIter2> 00143 _M_sequential_algorithm(_RAIter1 __begin1, 00144 _RAIter1 __end1, 00145 _RAIter2 __begin2, _Pred __pred) 00146 { return mismatch(__begin1, __end1, __begin2, 00147 __pred, sequential_tag()); } 00148 }; 00149 00150 00151 /** @brief Test predicate on several elements. */ 00152 template<typename _FIterator> 00153 struct __find_first_of_selector : public __generic_find_selector 00154 { 00155 _FIterator _M_begin; 00156 _FIterator _M_end; 00157 00158 explicit __find_first_of_selector(_FIterator __begin, 00159 _FIterator __end) 00160 : _M_begin(__begin), _M_end(__end) { } 00161 00162 /** @brief Test on one position. 00163 * @param __i1 _Iterator on first sequence. 00164 * @param __i2 _Iterator on second sequence (unused). 00165 * @param __pred Find predicate. */ 00166 template<typename _RAIter1, typename _RAIter2, 00167 typename _Pred> 00168 bool 00169 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 00170 { 00171 for (_FIterator __pos_in_candidates = _M_begin; 00172 __pos_in_candidates != _M_end; ++__pos_in_candidates) 00173 if (__pred(*__i1, *__pos_in_candidates)) 00174 return true; 00175 return false; 00176 } 00177 00178 /** @brief Corresponding sequential algorithm on a sequence. 00179 * @param __begin1 Begin iterator of first sequence. 00180 * @param __end1 End iterator of first sequence. 00181 * @param __begin2 Begin iterator of second sequence. 00182 * @param __pred Find predicate. */ 00183 template<typename _RAIter1, typename _RAIter2, 00184 typename _Pred> 00185 std::pair<_RAIter1, _RAIter2> 00186 _M_sequential_algorithm(_RAIter1 __begin1, 00187 _RAIter1 __end1, 00188 _RAIter2 __begin2, _Pred __pred) 00189 { 00190 return std::make_pair(find_first_of(__begin1, __end1, 00191 _M_begin, _M_end, __pred, 00192 sequential_tag()), __begin2); 00193 } 00194 }; 00195 } 00196 00197 #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */