1 // -*- C++ -*- 2 3 // Copyright (C) 2007-2017 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the terms 7 // of the GNU General Public License as published by the Free Software 8 // Foundation; either version 3, or (at your option) any later 9 // version. 10 11 // This library is distributed in the hope that it will be useful, but 12 // WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 // General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file parallel/find_selectors.h 26 * @brief _Function objects representing different tasks to be plugged 27 * into the parallel find algorithm. 28 * This file is a GNU parallel extension to the Standard C++ Library. 29 */ 30 31 // Written by Felix Putze. 32 33 #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H 34 #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1 35 36 #include <parallel/tags.h> 37 #include <parallel/basic_iterator.h> 38 #include <bits/stl_pair.h> 39 40 namespace __gnu_parallel 41 { 42 /** @brief Base class of all __gnu_parallel::__find_template selectors. */ 43 struct __generic_find_selector 44 { }; 45 46 /** 47 * @brief Test predicate on a single element, used for std::find() 48 * and std::find_if (). 49 */ 50 struct __find_if_selector : public __generic_find_selector 51 { 52 /** @brief Test on one position. 53 * @param __i1 _Iterator on first sequence. 54 * @param __i2 _Iterator on second sequence (unused). 55 * @param __pred Find predicate. 56 */ 57 template<typename _RAIter1, typename _RAIter2, 58 typename _Pred> 59 bool operator__find_if_selector60 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 61 { return __pred(*__i1); } 62 63 /** @brief Corresponding sequential algorithm on a sequence. 64 * @param __begin1 Begin iterator of first sequence. 65 * @param __end1 End iterator of first sequence. 66 * @param __begin2 Begin iterator of second sequence. 67 * @param __pred Find predicate. 68 */ 69 template<typename _RAIter1, typename _RAIter2, 70 typename _Pred> 71 std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm__find_if_selector72 _M_sequential_algorithm(_RAIter1 __begin1, 73 _RAIter1 __end1, 74 _RAIter2 __begin2, _Pred __pred) 75 { return std::make_pair(find_if(__begin1, __end1, __pred, 76 sequential_tag()), __begin2); } 77 }; 78 79 /** @brief Test predicate on two adjacent elements. */ 80 struct __adjacent_find_selector : public __generic_find_selector 81 { 82 /** @brief Test on one position. 83 * @param __i1 _Iterator on first sequence. 84 * @param __i2 _Iterator on second sequence (unused). 85 * @param __pred Find predicate. 86 */ 87 template<typename _RAIter1, typename _RAIter2, 88 typename _Pred> 89 bool operator__adjacent_find_selector90 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 91 { 92 // Passed end iterator is one short. 93 return __pred(*__i1, *(__i1 + 1)); 94 } 95 96 /** @brief Corresponding sequential algorithm on a sequence. 97 * @param __begin1 Begin iterator of first sequence. 98 * @param __end1 End iterator of first sequence. 99 * @param __begin2 Begin iterator of second sequence. 100 * @param __pred Find predicate. 101 */ 102 template<typename _RAIter1, typename _RAIter2, 103 typename _Pred> 104 std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm__adjacent_find_selector105 _M_sequential_algorithm(_RAIter1 __begin1, 106 _RAIter1 __end1, 107 _RAIter2 __begin2, _Pred __pred) 108 { 109 // Passed end iterator is one short. 110 _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1, 111 __pred, sequential_tag()); 112 if (__spot == (__end1 + 1)) 113 __spot = __end1; 114 return std::make_pair(__spot, __begin2); 115 } 116 }; 117 118 /** @brief Test inverted predicate on a single element. */ 119 struct __mismatch_selector : public __generic_find_selector 120 { 121 /** 122 * @brief Test on one position. 123 * @param __i1 _Iterator on first sequence. 124 * @param __i2 _Iterator on second sequence (unused). 125 * @param __pred Find predicate. 126 */ 127 template<typename _RAIter1, typename _RAIter2, 128 typename _Pred> 129 bool operator__mismatch_selector130 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 131 { return !__pred(*__i1, *__i2); } 132 133 /** 134 * @brief Corresponding sequential algorithm on a sequence. 135 * @param __begin1 Begin iterator of first sequence. 136 * @param __end1 End iterator of first sequence. 137 * @param __begin2 Begin iterator of second sequence. 138 * @param __pred Find predicate. 139 */ 140 template<typename _RAIter1, typename _RAIter2, 141 typename _Pred> 142 std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm__mismatch_selector143 _M_sequential_algorithm(_RAIter1 __begin1, 144 _RAIter1 __end1, 145 _RAIter2 __begin2, _Pred __pred) 146 { return mismatch(__begin1, __end1, __begin2, 147 __pred, sequential_tag()); } 148 }; 149 150 151 /** @brief Test predicate on several elements. */ 152 template<typename _FIterator> 153 struct __find_first_of_selector : public __generic_find_selector 154 { 155 _FIterator _M_begin; 156 _FIterator _M_end; 157 __find_first_of_selector__find_first_of_selector158 explicit __find_first_of_selector(_FIterator __begin, 159 _FIterator __end) 160 : _M_begin(__begin), _M_end(__end) { } 161 162 /** @brief Test on one position. 163 * @param __i1 _Iterator on first sequence. 164 * @param __i2 _Iterator on second sequence (unused). 165 * @param __pred Find predicate. */ 166 template<typename _RAIter1, typename _RAIter2, 167 typename _Pred> 168 bool operator__find_first_of_selector169 operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred) 170 { 171 for (_FIterator __pos_in_candidates = _M_begin; 172 __pos_in_candidates != _M_end; ++__pos_in_candidates) 173 if (__pred(*__i1, *__pos_in_candidates)) 174 return true; 175 return false; 176 } 177 178 /** @brief Corresponding sequential algorithm on a sequence. 179 * @param __begin1 Begin iterator of first sequence. 180 * @param __end1 End iterator of first sequence. 181 * @param __begin2 Begin iterator of second sequence. 182 * @param __pred Find predicate. */ 183 template<typename _RAIter1, typename _RAIter2, 184 typename _Pred> 185 std::pair<_RAIter1, _RAIter2> _M_sequential_algorithm__find_first_of_selector186 _M_sequential_algorithm(_RAIter1 __begin1, 187 _RAIter1 __end1, 188 _RAIter2 __begin2, _Pred __pred) 189 { 190 return std::make_pair(find_first_of(__begin1, __end1, 191 _M_begin, _M_end, __pred, 192 sequential_tag()), __begin2); 193 } 194 }; 195 } 196 197 #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */ 198