libstdc++
|
00001 // -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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/base.h 00026 * @brief Sequential helper functions. 00027 * This file is a GNU parallel extension to the Standard C++ Library. 00028 */ 00029 00030 // Written by Johannes Singler. 00031 00032 #ifndef _GLIBCXX_PARALLEL_BASE_H 00033 #define _GLIBCXX_PARALLEL_BASE_H 1 00034 00035 #include <bits/c++config.h> 00036 #include <bits/stl_function.h> 00037 #include <omp.h> 00038 #include <parallel/features.h> 00039 #include <parallel/basic_iterator.h> 00040 #include <parallel/parallel.h> 00041 00042 // Parallel mode namespaces. 00043 00044 /** 00045 * @namespace std::__parallel 00046 * @brief GNU parallel code, replaces standard behavior with parallel behavior. 00047 */ 00048 namespace std _GLIBCXX_VISIBILITY(default) 00049 { 00050 namespace __parallel { } 00051 } 00052 00053 /** 00054 * @namespace __gnu_parallel 00055 * @brief GNU parallel code for public use. 00056 */ 00057 namespace __gnu_parallel 00058 { 00059 // Import all the parallel versions of components in namespace std. 00060 using namespace std::__parallel; 00061 } 00062 00063 /** 00064 * @namespace __gnu_sequential 00065 * @brief GNU sequential classes for public use. 00066 */ 00067 namespace __gnu_sequential 00068 { 00069 // Import whatever is the serial version. 00070 #ifdef _GLIBCXX_PARALLEL 00071 using namespace std::_GLIBCXX_STD_A; 00072 #else 00073 using namespace std; 00074 #endif 00075 } 00076 00077 00078 namespace __gnu_parallel 00079 { 00080 // NB: Including this file cannot produce (unresolved) symbols from 00081 // the OpenMP runtime unless the parallel mode is actually invoked 00082 // and active, which imples that the OpenMP runtime is actually 00083 // going to be linked in. 00084 inline _ThreadIndex 00085 __get_max_threads() 00086 { 00087 _ThreadIndex __i = omp_get_max_threads(); 00088 return __i > 1 ? __i : 1; 00089 } 00090 00091 00092 inline bool 00093 __is_parallel(const _Parallelism __p) { return __p != sequential; } 00094 00095 00096 /** @brief Calculates the rounded-down logarithm of @c __n for base 2. 00097 * @param __n Argument. 00098 * @return Returns 0 for any argument <1. 00099 */ 00100 template<typename _Size> 00101 inline _Size 00102 __rd_log2(_Size __n) 00103 { 00104 _Size __k; 00105 for (__k = 0; __n > 1; __n >>= 1) 00106 ++__k; 00107 return __k; 00108 } 00109 00110 /** @brief Encode two integers into one gnu_parallel::_CASable. 00111 * @param __a First integer, to be encoded in the most-significant @c 00112 * _CASable_bits/2 bits. 00113 * @param __b Second integer, to be encoded in the least-significant 00114 * @c _CASable_bits/2 bits. 00115 * @return value encoding @c __a and @c __b. 00116 * @see __decode2 00117 */ 00118 inline _CASable 00119 __encode2(int __a, int __b) //must all be non-negative, actually 00120 { 00121 return (((_CASable)__a) << (_CASable_bits / 2)) | (((_CASable)__b) << 0); 00122 } 00123 00124 /** @brief Decode two integers from one gnu_parallel::_CASable. 00125 * @param __x __gnu_parallel::_CASable to decode integers from. 00126 * @param __a First integer, to be decoded from the most-significant 00127 * @c _CASable_bits/2 bits of @c __x. 00128 * @param __b Second integer, to be encoded in the least-significant 00129 * @c _CASable_bits/2 bits of @c __x. 00130 * @see __encode2 00131 */ 00132 inline void 00133 __decode2(_CASable __x, int& __a, int& __b) 00134 { 00135 __a = (int)((__x >> (_CASable_bits / 2)) & _CASable_mask); 00136 __b = (int)((__x >> 0 ) & _CASable_mask); 00137 } 00138 00139 //needed for parallel "numeric", even if "algorithm" not included 00140 00141 /** @brief Equivalent to std::min. */ 00142 template<typename _Tp> 00143 inline const _Tp& 00144 min(const _Tp& __a, const _Tp& __b) 00145 { return (__a < __b) ? __a : __b; } 00146 00147 /** @brief Equivalent to std::max. */ 00148 template<typename _Tp> 00149 inline const _Tp& 00150 max(const _Tp& __a, const _Tp& __b) 00151 { return (__a > __b) ? __a : __b; } 00152 00153 /** @brief Constructs predicate for equality from strict weak 00154 * ordering predicate 00155 */ 00156 template<typename _T1, typename _T2, typename _Compare> 00157 class _EqualFromLess : public std::binary_function<_T1, _T2, bool> 00158 { 00159 private: 00160 _Compare& _M_comp; 00161 00162 public: 00163 _EqualFromLess(_Compare& __comp) : _M_comp(__comp) { } 00164 00165 bool operator()(const _T1& __a, const _T2& __b) 00166 { return !_M_comp(__a, __b) && !_M_comp(__b, __a); } 00167 }; 00168 00169 00170 /** @brief Similar to std::unary_negate, 00171 * but giving the argument types explicitly. */ 00172 template<typename _Predicate, typename argument_type> 00173 class __unary_negate 00174 : public std::unary_function<argument_type, bool> 00175 { 00176 protected: 00177 _Predicate _M_pred; 00178 00179 public: 00180 explicit 00181 __unary_negate(const _Predicate& __x) : _M_pred(__x) { } 00182 00183 bool 00184 operator()(const argument_type& __x) 00185 { return !_M_pred(__x); } 00186 }; 00187 00188 /** @brief Similar to std::binder1st, 00189 * but giving the argument types explicitly. */ 00190 template<typename _Operation, typename _FirstArgumentType, 00191 typename _SecondArgumentType, typename _ResultType> 00192 class __binder1st 00193 : public std::unary_function<_SecondArgumentType, _ResultType> 00194 { 00195 protected: 00196 _Operation _M_op; 00197 _FirstArgumentType _M_value; 00198 00199 public: 00200 __binder1st(const _Operation& __x, const _FirstArgumentType& __y) 00201 : _M_op(__x), _M_value(__y) { } 00202 00203 _ResultType 00204 operator()(const _SecondArgumentType& __x) 00205 { return _M_op(_M_value, __x); } 00206 00207 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00208 // 109. Missing binders for non-const sequence elements 00209 _ResultType 00210 operator()(_SecondArgumentType& __x) const 00211 { return _M_op(_M_value, __x); } 00212 }; 00213 00214 /** 00215 * @brief Similar to std::binder2nd, but giving the argument types 00216 * explicitly. 00217 */ 00218 template<typename _Operation, typename _FirstArgumentType, 00219 typename _SecondArgumentType, typename _ResultType> 00220 class __binder2nd 00221 : public std::unary_function<_FirstArgumentType, _ResultType> 00222 { 00223 protected: 00224 _Operation _M_op; 00225 _SecondArgumentType _M_value; 00226 00227 public: 00228 __binder2nd(const _Operation& __x, const _SecondArgumentType& __y) 00229 : _M_op(__x), _M_value(__y) { } 00230 00231 _ResultType 00232 operator()(const _FirstArgumentType& __x) const 00233 { return _M_op(__x, _M_value); } 00234 00235 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00236 // 109. Missing binders for non-const sequence elements 00237 _ResultType 00238 operator()(_FirstArgumentType& __x) 00239 { return _M_op(__x, _M_value); } 00240 }; 00241 00242 /** @brief Similar to std::equal_to, but allows two different types. */ 00243 template<typename _T1, typename _T2> 00244 struct _EqualTo : std::binary_function<_T1, _T2, bool> 00245 { 00246 bool operator()(const _T1& __t1, const _T2& __t2) const 00247 { return __t1 == __t2; } 00248 }; 00249 00250 /** @brief Similar to std::less, but allows two different types. */ 00251 template<typename _T1, typename _T2> 00252 struct _Less : std::binary_function<_T1, _T2, bool> 00253 { 00254 bool 00255 operator()(const _T1& __t1, const _T2& __t2) const 00256 { return __t1 < __t2; } 00257 00258 bool 00259 operator()(const _T2& __t2, const _T1& __t1) const 00260 { return __t2 < __t1; } 00261 }; 00262 00263 // Partial specialization for one type. Same as std::less. 00264 template<typename _Tp> 00265 struct _Less<_Tp, _Tp> 00266 : public std::less<_Tp> { }; 00267 00268 /** @brief Similar to std::plus, but allows two different types. */ 00269 template<typename _Tp1, typename _Tp2, typename _Result 00270 = __typeof__(*static_cast<_Tp1*>(0) 00271 + *static_cast<_Tp2*>(0))> 00272 struct _Plus : public std::binary_function<_Tp1, _Tp2, _Result> 00273 { 00274 _Result 00275 operator()(const _Tp1& __x, const _Tp2& __y) const 00276 { return __x + __y; } 00277 }; 00278 00279 // Partial specialization for one type. Same as std::plus. 00280 template<typename _Tp> 00281 struct _Plus<_Tp, _Tp, _Tp> 00282 : public std::plus<_Tp> { }; 00283 00284 /** @brief Similar to std::multiplies, but allows two different types. */ 00285 template<typename _Tp1, typename _Tp2, typename _Result 00286 = __typeof__(*static_cast<_Tp1*>(0) 00287 * *static_cast<_Tp2*>(0))> 00288 struct _Multiplies : public std::binary_function<_Tp1, _Tp2, _Result> 00289 { 00290 _Result 00291 operator()(const _Tp1& __x, const _Tp2& __y) const 00292 { return __x * __y; } 00293 }; 00294 00295 // Partial specialization for one type. Same as std::multiplies. 00296 template<typename _Tp> 00297 struct _Multiplies<_Tp, _Tp, _Tp> 00298 : public std::multiplies<_Tp> { }; 00299 00300 /** @brief _Iterator associated with __gnu_parallel::_PseudoSequence. 00301 * If features the usual random-access iterator functionality. 00302 * @param _Tp Sequence _M_value type. 00303 * @param _DifferenceTp Sequence difference type. 00304 */ 00305 template<typename _Tp, typename _DifferenceTp> 00306 class _PseudoSequenceIterator 00307 { 00308 public: 00309 typedef _DifferenceTp _DifferenceType; 00310 00311 _PseudoSequenceIterator(const _Tp& __val, _DifferenceType __pos) 00312 : _M_val(__val), _M_pos(__pos) { } 00313 00314 // Pre-increment operator. 00315 _PseudoSequenceIterator& 00316 operator++() 00317 { 00318 ++_M_pos; 00319 return *this; 00320 } 00321 00322 // Post-increment operator. 00323 _PseudoSequenceIterator 00324 operator++(int) 00325 { return _PseudoSequenceIterator(_M_pos++); } 00326 00327 const _Tp& 00328 operator*() const 00329 { return _M_val; } 00330 00331 const _Tp& 00332 operator[](_DifferenceType) const 00333 { return _M_val; } 00334 00335 bool 00336 operator==(const _PseudoSequenceIterator& __i2) 00337 { return _M_pos == __i2._M_pos; } 00338 00339 bool 00340 operator!=(const _PseudoSequenceIterator& __i2) 00341 { return _M_pos != __i2._M_pos; } 00342 00343 _DifferenceType 00344 operator-(const _PseudoSequenceIterator& __i2) 00345 { return _M_pos - __i2._M_pos; } 00346 00347 private: 00348 const _Tp& _M_val; 00349 _DifferenceType _M_pos; 00350 }; 00351 00352 /** @brief Sequence that conceptually consists of multiple copies of 00353 the same element. 00354 * The copies are not stored explicitly, of course. 00355 * @param _Tp Sequence _M_value type. 00356 * @param _DifferenceTp Sequence difference type. 00357 */ 00358 template<typename _Tp, typename _DifferenceTp> 00359 class _PseudoSequence 00360 { 00361 public: 00362 typedef _DifferenceTp _DifferenceType; 00363 00364 // Better cast down to uint64_t, than up to _DifferenceTp. 00365 typedef _PseudoSequenceIterator<_Tp, uint64_t> iterator; 00366 00367 /** @brief Constructor. 00368 * @param __val Element of the sequence. 00369 * @param __count Number of (virtual) copies. 00370 */ 00371 _PseudoSequence(const _Tp& __val, _DifferenceType __count) 00372 : _M_val(__val), _M_count(__count) { } 00373 00374 /** @brief Begin iterator. */ 00375 iterator 00376 begin() const 00377 { return iterator(_M_val, 0); } 00378 00379 /** @brief End iterator. */ 00380 iterator 00381 end() const 00382 { return iterator(_M_val, _M_count); } 00383 00384 private: 00385 const _Tp& _M_val; 00386 _DifferenceType _M_count; 00387 }; 00388 00389 /** @brief Compute the median of three referenced elements, 00390 according to @c __comp. 00391 * @param __a First iterator. 00392 * @param __b Second iterator. 00393 * @param __c Third iterator. 00394 * @param __comp Comparator. 00395 */ 00396 template<typename _RAIter, typename _Compare> 00397 _RAIter 00398 __median_of_three_iterators(_RAIter __a, _RAIter __b, 00399 _RAIter __c, _Compare __comp) 00400 { 00401 if (__comp(*__a, *__b)) 00402 if (__comp(*__b, *__c)) 00403 return __b; 00404 else 00405 if (__comp(*__a, *__c)) 00406 return __c; 00407 else 00408 return __a; 00409 else 00410 { 00411 // Just swap __a and __b. 00412 if (__comp(*__a, *__c)) 00413 return __a; 00414 else 00415 if (__comp(*__b, *__c)) 00416 return __c; 00417 else 00418 return __b; 00419 } 00420 } 00421 00422 #define _GLIBCXX_PARALLEL_ASSERT(_Condition) __glibcxx_assert(_Condition) 00423 00424 } //namespace __gnu_parallel 00425 00426 #endif /* _GLIBCXX_PARALLEL_BASE_H */