1 // -*- C++ -*- 2 3 // Copyright (C) 2007-2013 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/algobase.h 26 * @brief Parallel STL function calls corresponding to the 27 * stl_algobase.h header. The functions defined here mainly do case 28 * switches and call the actual parallelized versions in other files. 29 * Inlining policy: Functions that basically only contain one 30 * function call, are declared inline. 31 * This file is a GNU parallel extension to the Standard C++ Library. 32 */ 33 34 // Written by Johannes Singler and Felix Putze. 35 36 #ifndef _GLIBCXX_PARALLEL_ALGOBASE_H 37 #define _GLIBCXX_PARALLEL_ALGOBASE_H 1 38 39 #include <bits/stl_algobase.h> 40 #include <parallel/base.h> 41 #include <parallel/algorithmfwd.h> 42 #include <parallel/find.h> 43 #include <parallel/find_selectors.h> 44 45 namespace std _GLIBCXX_VISIBILITY(default) 46 { 47 namespace __parallel 48 { 49 // NB: equal and lexicographical_compare require mismatch. 50 51 // Sequential fallback 52 template<typename _IIter1, typename _IIter2> 53 inline pair<_IIter1, _IIter2> 54 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 55 __gnu_parallel::sequential_tag) 56 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2); } 57 58 // Sequential fallback 59 template<typename _IIter1, typename _IIter2, typename _Predicate> 60 inline pair<_IIter1, _IIter2> 61 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 62 _Predicate __pred, __gnu_parallel::sequential_tag) 63 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } 64 65 // Sequential fallback for input iterator case 66 template<typename _IIter1, typename _IIter2, 67 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> 68 inline pair<_IIter1, _IIter2> 69 __mismatch_switch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 70 _Predicate __pred, _IteratorTag1, _IteratorTag2) 71 { return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); } 72 73 // Parallel mismatch for random access iterators 74 template<typename _RAIter1, typename _RAIter2, typename _Predicate> 75 pair<_RAIter1, _RAIter2> 76 __mismatch_switch(_RAIter1 __begin1, _RAIter1 __end1, 77 _RAIter2 __begin2, _Predicate __pred, 78 random_access_iterator_tag, random_access_iterator_tag) 79 { 80 if (_GLIBCXX_PARALLEL_CONDITION(true)) 81 { 82 _RAIter1 __res = 83 __gnu_parallel::__find_template(__begin1, __end1, __begin2, __pred, 84 __gnu_parallel:: 85 __mismatch_selector()).first; 86 return make_pair(__res , __begin2 + (__res - __begin1)); 87 } 88 else 89 return _GLIBCXX_STD_A::mismatch(__begin1, __end1, __begin2, __pred); 90 } 91 92 // Public interface 93 template<typename _IIter1, typename _IIter2> 94 inline pair<_IIter1, _IIter2> 95 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) 96 { 97 typedef std::iterator_traits<_IIter1> _Iterator1Traits; 98 typedef std::iterator_traits<_IIter2> _Iterator2Traits; 99 typedef typename _Iterator1Traits::value_type _ValueType1; 100 typedef typename _Iterator2Traits::value_type _ValueType2; 101 typedef typename _Iterator1Traits::iterator_category _IteratorCategory1; 102 typedef typename _Iterator2Traits::iterator_category _IteratorCategory2; 103 104 typedef __gnu_parallel::_EqualTo<_ValueType1, _ValueType2> _EqualTo; 105 106 return __mismatch_switch(__begin1, __end1, __begin2, _EqualTo(), 107 _IteratorCategory1(), _IteratorCategory2()); 108 } 109 110 // Public interface 111 template<typename _IIter1, typename _IIter2, typename _Predicate> 112 inline pair<_IIter1, _IIter2> 113 mismatch(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 114 _Predicate __pred) 115 { 116 typedef std::iterator_traits<_IIter1> _Iterator1Traits; 117 typedef std::iterator_traits<_IIter2> _Iterator2Traits; 118 typedef typename _Iterator1Traits::iterator_category _IteratorCategory1; 119 typedef typename _Iterator2Traits::iterator_category _IteratorCategory2; 120 121 return __mismatch_switch(__begin1, __end1, __begin2, __pred, 122 _IteratorCategory1(), _IteratorCategory2()); 123 } 124 125 // Sequential fallback 126 template<typename _IIter1, typename _IIter2> 127 inline bool 128 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 129 __gnu_parallel::sequential_tag) 130 { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2); } 131 132 // Sequential fallback 133 template<typename _IIter1, typename _IIter2, typename _Predicate> 134 inline bool 135 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 136 _Predicate __pred, __gnu_parallel::sequential_tag) 137 { return _GLIBCXX_STD_A::equal(__begin1, __end1, __begin2, __pred); } 138 139 // Public interface 140 template<typename _IIter1, typename _IIter2> 141 inline bool 142 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2) 143 { 144 return __gnu_parallel::mismatch(__begin1, __end1, __begin2).first 145 == __end1; 146 } 147 148 // Public interface 149 template<typename _IIter1, typename _IIter2, typename _Predicate> 150 inline bool 151 equal(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, 152 _Predicate __pred) 153 { 154 return __gnu_parallel::mismatch(__begin1, __end1, __begin2, __pred).first 155 == __end1; 156 } 157 158 // Sequential fallback 159 template<typename _IIter1, typename _IIter2> 160 inline bool 161 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 162 _IIter2 __begin2, _IIter2 __end2, 163 __gnu_parallel::sequential_tag) 164 { return _GLIBCXX_STD_A::lexicographical_compare(__begin1, __end1, 165 __begin2, __end2); } 166 167 // Sequential fallback 168 template<typename _IIter1, typename _IIter2, typename _Predicate> 169 inline bool 170 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 171 _IIter2 __begin2, _IIter2 __end2, 172 _Predicate __pred, __gnu_parallel::sequential_tag) 173 { return _GLIBCXX_STD_A::lexicographical_compare( 174 __begin1, __end1, __begin2, __end2, __pred); } 175 176 // Sequential fallback for input iterator case 177 template<typename _IIter1, typename _IIter2, 178 typename _Predicate, typename _IteratorTag1, typename _IteratorTag2> 179 inline bool 180 __lexicographical_compare_switch(_IIter1 __begin1, _IIter1 __end1, 181 _IIter2 __begin2, _IIter2 __end2, 182 _Predicate __pred, 183 _IteratorTag1, _IteratorTag2) 184 { return _GLIBCXX_STD_A::lexicographical_compare( 185 __begin1, __end1, __begin2, __end2, __pred); } 186 187 // Parallel lexicographical_compare for random access iterators 188 // Limitation: Both valuetypes must be the same 189 template<typename _RAIter1, typename _RAIter2, typename _Predicate> 190 bool 191 __lexicographical_compare_switch(_RAIter1 __begin1, _RAIter1 __end1, 192 _RAIter2 __begin2, _RAIter2 __end2, 193 _Predicate __pred, 194 random_access_iterator_tag, 195 random_access_iterator_tag) 196 { 197 if (_GLIBCXX_PARALLEL_CONDITION(true)) 198 { 199 typedef iterator_traits<_RAIter1> _TraitsType1; 200 typedef typename _TraitsType1::value_type _ValueType1; 201 202 typedef iterator_traits<_RAIter2> _TraitsType2; 203 typedef typename _TraitsType2::value_type _ValueType2; 204 205 typedef __gnu_parallel:: 206 _EqualFromLess<_ValueType1, _ValueType2, _Predicate> 207 _EqualFromLessCompare; 208 209 // Longer sequence in first place. 210 if ((__end1 - __begin1) < (__end2 - __begin2)) 211 { 212 typedef pair<_RAIter1, _RAIter2> _SpotType; 213 _SpotType __mm = __mismatch_switch(__begin1, __end1, __begin2, 214 _EqualFromLessCompare(__pred), 215 random_access_iterator_tag(), 216 random_access_iterator_tag()); 217 218 return (__mm.first == __end1) 219 || bool(__pred(*__mm.first, *__mm.second)); 220 } 221 else 222 { 223 typedef pair<_RAIter2, _RAIter1> _SpotType; 224 _SpotType __mm = __mismatch_switch(__begin2, __end2, __begin1, 225 _EqualFromLessCompare(__pred), 226 random_access_iterator_tag(), 227 random_access_iterator_tag()); 228 229 return (__mm.first != __end2) 230 && bool(__pred(*__mm.second, *__mm.first)); 231 } 232 } 233 else 234 return _GLIBCXX_STD_A::lexicographical_compare( 235 __begin1, __end1, __begin2, __end2, __pred); 236 } 237 238 // Public interface 239 template<typename _IIter1, typename _IIter2> 240 inline bool 241 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 242 _IIter2 __begin2, _IIter2 __end2) 243 { 244 typedef iterator_traits<_IIter1> _TraitsType1; 245 typedef typename _TraitsType1::value_type _ValueType1; 246 typedef typename _TraitsType1::iterator_category _IteratorCategory1; 247 248 typedef iterator_traits<_IIter2> _TraitsType2; 249 typedef typename _TraitsType2::value_type _ValueType2; 250 typedef typename _TraitsType2::iterator_category _IteratorCategory2; 251 typedef __gnu_parallel::_Less<_ValueType1, _ValueType2> _LessType; 252 253 return __lexicographical_compare_switch( 254 __begin1, __end1, __begin2, __end2, _LessType(), 255 _IteratorCategory1(), _IteratorCategory2()); 256 } 257 258 // Public interface 259 template<typename _IIter1, typename _IIter2, typename _Predicate> 260 inline bool 261 lexicographical_compare(_IIter1 __begin1, _IIter1 __end1, 262 _IIter2 __begin2, _IIter2 __end2, 263 _Predicate __pred) 264 { 265 typedef iterator_traits<_IIter1> _TraitsType1; 266 typedef typename _TraitsType1::iterator_category _IteratorCategory1; 267 268 typedef iterator_traits<_IIter2> _TraitsType2; 269 typedef typename _TraitsType2::iterator_category _IteratorCategory2; 270 271 return __lexicographical_compare_switch( 272 __begin1, __end1, __begin2, __end2, __pred, 273 _IteratorCategory1(), _IteratorCategory2()); 274 } 275 } // end namespace 276 } // end namespace 277 278 #endif /* _GLIBCXX_PARALLEL_ALGOBASE_H */ 279