base.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. // -*- C++ -*-
  2. // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the terms
  6. // of the GNU General Public License as published by the Free Software
  7. // Foundation; either version 3, or (at your option) any later
  8. // version.
  9. // This library is distributed in the hope that it will be useful, but
  10. // WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file parallel/base.h
  21. * @brief Sequential helper functions.
  22. * This file is a GNU parallel extension to the Standard C++ Library.
  23. */
  24. // Written by Johannes Singler.
  25. #ifndef _GLIBCXX_PARALLEL_BASE_H
  26. #define _GLIBCXX_PARALLEL_BASE_H 1
  27. #include <functional>
  28. #include <omp.h>
  29. #include <parallel/features.h>
  30. #include <parallel/basic_iterator.h>
  31. #include <parallel/parallel.h>
  32. // Parallel mode namespaces.
  33. /**
  34. * @namespace std::__parallel
  35. * @brief GNU parallel code, replaces standard behavior with parallel behavior.
  36. */
  37. namespace std
  38. {
  39. namespace __parallel { }
  40. }
  41. /**
  42. * @namespace __gnu_parallel
  43. * @brief GNU parallel code for public use.
  44. */
  45. namespace __gnu_parallel
  46. {
  47. // Import all the parallel versions of components in namespace std.
  48. using namespace std::__parallel;
  49. }
  50. /**
  51. * @namespace __gnu_sequential
  52. * @brief GNU sequential classes for public use.
  53. */
  54. namespace __gnu_sequential
  55. {
  56. // Import whatever is the serial version.
  57. #ifdef _GLIBCXX_PARALLEL
  58. using namespace std::__norm;
  59. #else
  60. using namespace std;
  61. #endif
  62. }
  63. namespace __gnu_parallel
  64. {
  65. // NB: Including this file cannot produce (unresolved) symbols from
  66. // the OpenMP runtime unless the parallel mode is actually invoked
  67. // and active, which imples that the OpenMP runtime is actually
  68. // going to be linked in.
  69. inline int
  70. get_max_threads()
  71. {
  72. int __i = omp_get_max_threads();
  73. return __i > 1 ? __i : 1;
  74. }
  75. inline bool
  76. is_parallel(const _Parallelism __p) { return __p != sequential; }
  77. // XXX remove std::duplicates from here if possible,
  78. // XXX but keep minimal dependencies.
  79. /** @brief Calculates the rounded-down logarithm of @c n for base 2.
  80. * @param n Argument.
  81. * @return Returns 0 for any argument <1.
  82. */
  83. template<typename Size>
  84. inline Size
  85. __log2(Size n)
  86. {
  87. Size k;
  88. for (k = 0; n > 1; n >>= 1)
  89. ++k;
  90. return k;
  91. }
  92. /** @brief Encode two integers into one __gnu_parallel::lcas_t.
  93. * @param a First integer, to be encoded in the most-significant @c
  94. * lcas_t_bits/2 bits.
  95. * @param b Second integer, to be encoded in the least-significant
  96. * @c lcas_t_bits/2 bits.
  97. * @return __gnu_parallel::lcas_t value encoding @c a and @c b.
  98. * @see decode2
  99. */
  100. inline lcas_t
  101. encode2(int a, int b) //must all be non-negative, actually
  102. {
  103. return (((lcas_t)a) << (lcas_t_bits / 2)) | (((lcas_t)b) << 0);
  104. }
  105. /** @brief Decode two integers from one __gnu_parallel::lcas_t.
  106. * @param x __gnu_parallel::lcas_t to decode integers from.
  107. * @param a First integer, to be decoded from the most-significant
  108. * @c lcas_t_bits/2 bits of @c x.
  109. * @param b Second integer, to be encoded in the least-significant
  110. * @c lcas_t_bits/2 bits of @c x.
  111. * @see encode2
  112. */
  113. inline void
  114. decode2(lcas_t x, int& a, int& b)
  115. {
  116. a = (int)((x >> (lcas_t_bits / 2)) & lcas_t_mask);
  117. b = (int)((x >> 0 ) & lcas_t_mask);
  118. }
  119. /** @brief Equivalent to std::min. */
  120. template<typename T>
  121. const T&
  122. min(const T& a, const T& b)
  123. { return (a < b) ? a : b; }
  124. /** @brief Equivalent to std::max. */
  125. template<typename T>
  126. const T&
  127. max(const T& a, const T& b)
  128. { return (a > b) ? a : b; }
  129. /** @brief Constructs predicate for equality from strict weak
  130. * ordering predicate
  131. */
  132. // XXX comparator at the end, as per others
  133. template<typename Comparator, typename T1, typename T2>
  134. class equal_from_less : public std::binary_function<T1, T2, bool>
  135. {
  136. private:
  137. Comparator& comp;
  138. public:
  139. equal_from_less(Comparator& _comp) : comp(_comp) { }
  140. bool operator()(const T1& a, const T2& b)
  141. {
  142. return !comp(a, b) && !comp(b, a);
  143. }
  144. };
  145. /** @brief Similar to std::binder1st,
  146. * but giving the argument types explicitly. */
  147. template<typename _Predicate, typename argument_type>
  148. class unary_negate
  149. : public std::unary_function<argument_type, bool>
  150. {
  151. protected:
  152. _Predicate _M_pred;
  153. public:
  154. explicit
  155. unary_negate(const _Predicate& __x) : _M_pred(__x) { }
  156. bool
  157. operator()(const argument_type& __x)
  158. { return !_M_pred(__x); }
  159. };
  160. /** @brief Similar to std::binder1st,
  161. * but giving the argument types explicitly. */
  162. template<typename _Operation, typename first_argument_type,
  163. typename second_argument_type, typename result_type>
  164. class binder1st
  165. : public std::unary_function<second_argument_type, result_type>
  166. {
  167. protected:
  168. _Operation op;
  169. first_argument_type value;
  170. public:
  171. binder1st(const _Operation& __x,
  172. const first_argument_type& __y)
  173. : op(__x), value(__y) { }
  174. result_type
  175. operator()(const second_argument_type& __x)
  176. { return op(value, __x); }
  177. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  178. // 109. Missing binders for non-const sequence elements
  179. result_type
  180. operator()(second_argument_type& __x) const
  181. { return op(value, __x); }
  182. };
  183. /**
  184. * @brief Similar to std::binder2nd, but giving the argument types
  185. * explicitly.
  186. */
  187. template<typename _Operation, typename first_argument_type,
  188. typename second_argument_type, typename result_type>
  189. class binder2nd
  190. : public std::unary_function<first_argument_type, result_type>
  191. {
  192. protected:
  193. _Operation op;
  194. second_argument_type value;
  195. public:
  196. binder2nd(const _Operation& __x,
  197. const second_argument_type& __y)
  198. : op(__x), value(__y) { }
  199. result_type
  200. operator()(const first_argument_type& __x) const
  201. { return op(__x, value); }
  202. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  203. // 109. Missing binders for non-const sequence elements
  204. result_type
  205. operator()(first_argument_type& __x)
  206. { return op(__x, value); }
  207. };
  208. /** @brief Similar to std::equal_to, but allows two different types. */
  209. template<typename T1, typename T2>
  210. struct equal_to : std::binary_function<T1, T2, bool>
  211. {
  212. bool operator()(const T1& t1, const T2& t2) const
  213. { return t1 == t2; }
  214. };
  215. /** @brief Similar to std::less, but allows two different types. */
  216. template<typename T1, typename T2>
  217. struct less : std::binary_function<T1, T2, bool>
  218. {
  219. bool
  220. operator()(const T1& t1, const T2& t2) const
  221. { return t1 < t2; }
  222. bool
  223. operator()(const T2& t2, const T1& t1) const
  224. { return t2 < t1; }
  225. };
  226. // Partial specialization for one type. Same as std::less.
  227. template<typename _Tp>
  228. struct less<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, bool>
  229. {
  230. bool
  231. operator()(const _Tp& __x, const _Tp& __y) const
  232. { return __x < __y; }
  233. };
  234. /** @brief Similar to std::plus, but allows two different types. */
  235. template<typename _Tp1, typename _Tp2>
  236. struct plus : public std::binary_function<_Tp1, _Tp2, _Tp1>
  237. {
  238. typedef __typeof__(*static_cast<_Tp1*>(NULL)
  239. + *static_cast<_Tp2*>(NULL)) result;
  240. result
  241. operator()(const _Tp1& __x, const _Tp2& __y) const
  242. { return __x + __y; }
  243. };
  244. // Partial specialization for one type. Same as std::plus.
  245. template<typename _Tp>
  246. struct plus<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
  247. {
  248. typedef __typeof__(*static_cast<_Tp*>(NULL)
  249. + *static_cast<_Tp*>(NULL)) result;
  250. result
  251. operator()(const _Tp& __x, const _Tp& __y) const
  252. { return __x + __y; }
  253. };
  254. /** @brief Similar to std::multiplies, but allows two different types. */
  255. template<typename _Tp1, typename _Tp2>
  256. struct multiplies : public std::binary_function<_Tp1, _Tp2, _Tp1>
  257. {
  258. typedef __typeof__(*static_cast<_Tp1*>(NULL)
  259. * *static_cast<_Tp2*>(NULL)) result;
  260. result
  261. operator()(const _Tp1& __x, const _Tp2& __y) const
  262. { return __x * __y; }
  263. };
  264. // Partial specialization for one type. Same as std::multiplies.
  265. template<typename _Tp>
  266. struct multiplies<_Tp, _Tp> : public std::binary_function<_Tp, _Tp, _Tp>
  267. {
  268. typedef __typeof__(*static_cast<_Tp*>(NULL)
  269. * *static_cast<_Tp*>(NULL)) result;
  270. result
  271. operator()(const _Tp& __x, const _Tp& __y) const
  272. { return __x * __y; }
  273. };
  274. template<typename T, typename _DifferenceTp>
  275. class pseudo_sequence;
  276. /** @brief Iterator associated with __gnu_parallel::pseudo_sequence.
  277. * If features the usual random-access iterator functionality.
  278. * @param T Sequence value type.
  279. * @param difference_type Sequence difference type.
  280. */
  281. template<typename T, typename _DifferenceTp>
  282. class pseudo_sequence_iterator
  283. {
  284. public:
  285. typedef _DifferenceTp difference_type;
  286. private:
  287. typedef pseudo_sequence_iterator<T, _DifferenceTp> type;
  288. const T& val;
  289. difference_type pos;
  290. public:
  291. pseudo_sequence_iterator(const T& val, difference_type pos)
  292. : val(val), pos(pos) { }
  293. // Pre-increment operator.
  294. type&
  295. operator++()
  296. {
  297. ++pos;
  298. return *this;
  299. }
  300. // Post-increment operator.
  301. const type
  302. operator++(int)
  303. { return type(pos++); }
  304. const T&
  305. operator*() const
  306. { return val; }
  307. const T&
  308. operator[](difference_type) const
  309. { return val; }
  310. bool
  311. operator==(const type& i2)
  312. { return pos == i2.pos; }
  313. difference_type
  314. operator!=(const type& i2)
  315. { return pos != i2.pos; }
  316. difference_type
  317. operator-(const type& i2)
  318. { return pos - i2.pos; }
  319. };
  320. /** @brief Sequence that conceptually consists of multiple copies of
  321. the same element.
  322. * The copies are not stored explicitly, of course.
  323. * @param T Sequence value type.
  324. * @param difference_type Sequence difference type.
  325. */
  326. template<typename T, typename _DifferenceTp>
  327. class pseudo_sequence
  328. {
  329. typedef pseudo_sequence<T, _DifferenceTp> type;
  330. public:
  331. typedef _DifferenceTp difference_type;
  332. // Better case down to uint64, than up to _DifferenceTp.
  333. typedef pseudo_sequence_iterator<T, uint64> iterator;
  334. /** @brief Constructor.
  335. * @param val Element of the sequence.
  336. * @param count Number of (virtual) copies.
  337. */
  338. pseudo_sequence(const T& val, difference_type count)
  339. : val(val), count(count) { }
  340. /** @brief Begin iterator. */
  341. iterator
  342. begin() const
  343. { return iterator(val, 0); }
  344. /** @brief End iterator. */
  345. iterator
  346. end() const
  347. { return iterator(val, count); }
  348. private:
  349. const T& val;
  350. difference_type count;
  351. };
  352. /** @brief Functor that does nothing */
  353. template<typename _ValueTp>
  354. class void_functor
  355. {
  356. inline void
  357. operator()(const _ValueTp& v) const { }
  358. };
  359. /** @brief Compute the median of three referenced elements,
  360. according to @c comp.
  361. * @param a First iterator.
  362. * @param b Second iterator.
  363. * @param c Third iterator.
  364. * @param comp Comparator.
  365. */
  366. template<typename RandomAccessIterator, typename Comparator>
  367. RandomAccessIterator
  368. median_of_three_iterators(RandomAccessIterator a, RandomAccessIterator b,
  369. RandomAccessIterator c, Comparator& comp)
  370. {
  371. if (comp(*a, *b))
  372. if (comp(*b, *c))
  373. return b;
  374. else
  375. if (comp(*a, *c))
  376. return c;
  377. else
  378. return a;
  379. else
  380. {
  381. // Just swap a and b.
  382. if (comp(*a, *c))
  383. return a;
  384. else
  385. if (comp(*b, *c))
  386. return c;
  387. else
  388. return b;
  389. }
  390. }
  391. #define _GLIBCXX_PARALLEL_ASSERT(_Condition) __glibcxx_assert(_Condition)
  392. } //namespace __gnu_parallel
  393. #endif /* _GLIBCXX_PARALLEL_BASE_H */