find_selectors.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // -*- C++ -*-
  2. // Copyright (C) 2007-2022 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/find_selectors.h
  21. * @brief _Function objects representing different tasks to be plugged
  22. * into the parallel find algorithm.
  23. * This file is a GNU parallel extension to the Standard C++ Library.
  24. */
  25. // Written by Felix Putze.
  26. #ifndef _GLIBCXX_PARALLEL_FIND_SELECTORS_H
  27. #define _GLIBCXX_PARALLEL_FIND_SELECTORS_H 1
  28. #include <parallel/tags.h>
  29. #include <parallel/basic_iterator.h>
  30. #include <bits/stl_pair.h>
  31. namespace __gnu_parallel
  32. {
  33. /** @brief Base class of all __gnu_parallel::__find_template selectors. */
  34. struct __generic_find_selector
  35. { };
  36. /**
  37. * @brief Test predicate on a single element, used for std::find()
  38. * and std::find_if ().
  39. */
  40. struct __find_if_selector : public __generic_find_selector
  41. {
  42. /** @brief Test on one position.
  43. * @param __i1 _Iterator on first sequence.
  44. * @param __i2 _Iterator on second sequence (unused).
  45. * @param __pred Find predicate.
  46. */
  47. template<typename _RAIter1, typename _RAIter2,
  48. typename _Pred>
  49. bool
  50. operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
  51. { return __pred(*__i1); }
  52. /** @brief Corresponding sequential algorithm on a sequence.
  53. * @param __begin1 Begin iterator of first sequence.
  54. * @param __end1 End iterator of first sequence.
  55. * @param __begin2 Begin iterator of second sequence.
  56. * @param __pred Find predicate.
  57. */
  58. template<typename _RAIter1, typename _RAIter2,
  59. typename _Pred>
  60. std::pair<_RAIter1, _RAIter2>
  61. _M_sequential_algorithm(_RAIter1 __begin1,
  62. _RAIter1 __end1,
  63. _RAIter2 __begin2, _Pred __pred)
  64. { return std::make_pair(find_if(__begin1, __end1, __pred,
  65. sequential_tag()), __begin2); }
  66. };
  67. /** @brief Test predicate on two adjacent elements. */
  68. struct __adjacent_find_selector : public __generic_find_selector
  69. {
  70. /** @brief Test on one position.
  71. * @param __i1 _Iterator on first sequence.
  72. * @param __i2 _Iterator on second sequence (unused).
  73. * @param __pred Find predicate.
  74. */
  75. template<typename _RAIter1, typename _RAIter2,
  76. typename _Pred>
  77. bool
  78. operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
  79. {
  80. // Passed end iterator is one short.
  81. return __pred(*__i1, *(__i1 + 1));
  82. }
  83. /** @brief Corresponding sequential algorithm on a sequence.
  84. * @param __begin1 Begin iterator of first sequence.
  85. * @param __end1 End iterator of first sequence.
  86. * @param __begin2 Begin iterator of second sequence.
  87. * @param __pred Find predicate.
  88. */
  89. template<typename _RAIter1, typename _RAIter2,
  90. typename _Pred>
  91. std::pair<_RAIter1, _RAIter2>
  92. _M_sequential_algorithm(_RAIter1 __begin1,
  93. _RAIter1 __end1,
  94. _RAIter2 __begin2, _Pred __pred)
  95. {
  96. // Passed end iterator is one short.
  97. _RAIter1 __spot = adjacent_find(__begin1, __end1 + 1,
  98. __pred, sequential_tag());
  99. if (__spot == (__end1 + 1))
  100. __spot = __end1;
  101. return std::make_pair(__spot, __begin2);
  102. }
  103. };
  104. /** @brief Test inverted predicate on a single element. */
  105. struct __mismatch_selector : public __generic_find_selector
  106. {
  107. /**
  108. * @brief Test on one position.
  109. * @param __i1 _Iterator on first sequence.
  110. * @param __i2 _Iterator on second sequence (unused).
  111. * @param __pred Find predicate.
  112. */
  113. template<typename _RAIter1, typename _RAIter2,
  114. typename _Pred>
  115. bool
  116. operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
  117. { return !__pred(*__i1, *__i2); }
  118. /**
  119. * @brief Corresponding sequential algorithm on a sequence.
  120. * @param __begin1 Begin iterator of first sequence.
  121. * @param __end1 End iterator of first sequence.
  122. * @param __begin2 Begin iterator of second sequence.
  123. * @param __pred Find predicate.
  124. */
  125. template<typename _RAIter1, typename _RAIter2,
  126. typename _Pred>
  127. std::pair<_RAIter1, _RAIter2>
  128. _M_sequential_algorithm(_RAIter1 __begin1,
  129. _RAIter1 __end1,
  130. _RAIter2 __begin2, _Pred __pred)
  131. { return mismatch(__begin1, __end1, __begin2,
  132. __pred, sequential_tag()); }
  133. };
  134. /** @brief Test predicate on several elements. */
  135. template<typename _FIterator>
  136. struct __find_first_of_selector : public __generic_find_selector
  137. {
  138. _FIterator _M_begin;
  139. _FIterator _M_end;
  140. explicit __find_first_of_selector(_FIterator __begin,
  141. _FIterator __end)
  142. : _M_begin(__begin), _M_end(__end) { }
  143. /** @brief Test on one position.
  144. * @param __i1 _Iterator on first sequence.
  145. * @param __i2 _Iterator on second sequence (unused).
  146. * @param __pred Find predicate. */
  147. template<typename _RAIter1, typename _RAIter2,
  148. typename _Pred>
  149. bool
  150. operator()(_RAIter1 __i1, _RAIter2 __i2, _Pred __pred)
  151. {
  152. for (_FIterator __pos_in_candidates = _M_begin;
  153. __pos_in_candidates != _M_end; ++__pos_in_candidates)
  154. if (__pred(*__i1, *__pos_in_candidates))
  155. return true;
  156. return false;
  157. }
  158. /** @brief Corresponding sequential algorithm on a sequence.
  159. * @param __begin1 Begin iterator of first sequence.
  160. * @param __end1 End iterator of first sequence.
  161. * @param __begin2 Begin iterator of second sequence.
  162. * @param __pred Find predicate. */
  163. template<typename _RAIter1, typename _RAIter2,
  164. typename _Pred>
  165. std::pair<_RAIter1, _RAIter2>
  166. _M_sequential_algorithm(_RAIter1 __begin1,
  167. _RAIter1 __end1,
  168. _RAIter2 __begin2, _Pred __pred)
  169. {
  170. return std::make_pair(find_first_of(__begin1, __end1,
  171. _M_begin, _M_end, __pred,
  172. sequential_tag()), __begin2);
  173. }
  174. };
  175. }
  176. #endif /* _GLIBCXX_PARALLEL_FIND_SELECTORS_H */