algorithm.hpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // (C) Copyright Gennadiy Rozental 2001.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. /// @file
  8. /// Addition to STL algorithms
  9. // ***************************************************************************
  10. #ifndef BOOST_TEST_UTILS_ALGORITHM_HPP
  11. #define BOOST_TEST_UTILS_ALGORITHM_HPP
  12. // STL
  13. #include <utility>
  14. #include <algorithm> // std::find
  15. #include <functional> // std::bind1st
  16. #include <boost/test/detail/suppress_warnings.hpp>
  17. //____________________________________________________________________________//
  18. namespace boost {
  19. namespace unit_test {
  20. namespace utils {
  21. /// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
  22. /// of iterators, first pointing to the mismatch position in first collection, second iterator in second one
  23. ///
  24. /// @param first1 - first collection begin iterator
  25. /// @param last1 - first collection end iterator
  26. /// @param first2 - second collection begin iterator
  27. /// @param last2 - second collection end iterator
  28. template <class InputIter1, class InputIter2>
  29. inline std::pair<InputIter1, InputIter2>
  30. mismatch( InputIter1 first1, InputIter1 last1,
  31. InputIter2 first2, InputIter2 last2 )
  32. {
  33. while( first1 != last1 && first2 != last2 && *first1 == *first2 ) {
  34. ++first1;
  35. ++first2;
  36. }
  37. return std::pair<InputIter1, InputIter2>(first1, first2);
  38. }
  39. //____________________________________________________________________________//
  40. /// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
  41. /// of iterators, first pointing to the mismatch position in first collection, second iterator in second one. This algorithms
  42. /// uses supplied predicate for collection elements comparison
  43. ///
  44. /// @param first1 - first collection begin iterator
  45. /// @param last1 - first collection end iterator
  46. /// @param first2 - second collection begin iterator
  47. /// @param last2 - second collection end iterator
  48. /// @param pred - predicate to be used for search
  49. template <class InputIter1, class InputIter2, class Predicate>
  50. inline std::pair<InputIter1, InputIter2>
  51. mismatch( InputIter1 first1, InputIter1 last1,
  52. InputIter2 first2, InputIter2 last2,
  53. Predicate pred )
  54. {
  55. while( first1 != last1 && first2 != last2 && pred( *first1, *first2 ) ) {
  56. ++first1;
  57. ++first2;
  58. }
  59. return std::pair<InputIter1, InputIter2>(first1, first2);
  60. }
  61. //____________________________________________________________________________//
  62. /// @brief this algorithm search through first collection for first element that does not belong a second one
  63. ///
  64. /// @param first1 - first collection begin iterator
  65. /// @param last1 - first collection end iterator
  66. /// @param first2 - second collection begin iterator
  67. /// @param last2 - second collection end iterator
  68. template<class ForwardIterator1, class ForwardIterator2>
  69. inline ForwardIterator1
  70. find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
  71. ForwardIterator2 first2, ForwardIterator2 last2 )
  72. {
  73. while( first1 != last1 ) {
  74. if( std::find( first2, last2, *first1 ) == last2 )
  75. break;
  76. ++first1;
  77. }
  78. return first1;
  79. }
  80. //____________________________________________________________________________//
  81. /// @brief this algorithm search through first collection for first element that does not satisfy binary
  82. /// predicate in conjunction will any element in second collection
  83. ///
  84. /// @param first1 - first collection begin iterator
  85. /// @param last1 - first collection end iterator
  86. /// @param first2 - second collection begin iterator
  87. /// @param last2 - second collection end iterator
  88. /// @param pred - predicate to be used for search
  89. template<class ForwardIterator1, class ForwardIterator2, class Predicate>
  90. inline ForwardIterator1
  91. find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
  92. ForwardIterator2 first2, ForwardIterator2 last2,
  93. Predicate pred )
  94. {
  95. while( first1 != last1 ) {
  96. if( std::find_if( first2, last2, std::bind1st( pred, *first1 ) ) == last2 )
  97. break;
  98. ++first1;
  99. }
  100. return first1;
  101. }
  102. //____________________________________________________________________________//
  103. /// @brief this algorithm search through first collection for last element that belongs to a second one
  104. ///
  105. /// @param first1 - first collection begin iterator
  106. /// @param last1 - first collection end iterator
  107. /// @param first2 - second collection begin iterator
  108. /// @param last2 - second collection end iterator
  109. template<class BidirectionalIterator1, class ForwardIterator2>
  110. inline BidirectionalIterator1
  111. find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  112. ForwardIterator2 first2, ForwardIterator2 last2 )
  113. {
  114. if( first1 == last1 || first2 == last2 )
  115. return last1;
  116. BidirectionalIterator1 it1 = last1;
  117. while( --it1 != first1 && std::find( first2, last2, *it1 ) == last2 ) {}
  118. return it1 == first1 && std::find( first2, last2, *it1 ) == last2 ? last1 : it1;
  119. }
  120. //____________________________________________________________________________//
  121. /// @brief this algorithm search through first collection for last element that satisfy binary
  122. /// predicate in conjunction will at least one element in second collection
  123. ///
  124. /// @param first1 - first collection begin iterator
  125. /// @param last1 - first collection end iterator
  126. /// @param first2 - second collection begin iterator
  127. /// @param last2 - second collection end iterator
  128. /// @param pred - predicate to be used for search
  129. template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
  130. inline BidirectionalIterator1
  131. find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  132. ForwardIterator2 first2, ForwardIterator2 last2,
  133. Predicate pred )
  134. {
  135. if( first1 == last1 || first2 == last2 )
  136. return last1;
  137. BidirectionalIterator1 it1 = last1;
  138. while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ) {}
  139. return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
  140. }
  141. //____________________________________________________________________________//
  142. /// @brief this algorithm search through first collection for last element that does not belong to a second one
  143. ///
  144. /// @param first1 - first collection begin iterator
  145. /// @param last1 - first collection end iterator
  146. /// @param first2 - second collection begin iterator
  147. /// @param last2 - second collection end iterator
  148. template<class BidirectionalIterator1, class ForwardIterator2>
  149. inline BidirectionalIterator1
  150. find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  151. ForwardIterator2 first2, ForwardIterator2 last2 )
  152. {
  153. if( first1 == last1 || first2 == last2 )
  154. return last1;
  155. BidirectionalIterator1 it1 = last1;
  156. while( --it1 != first1 && std::find( first2, last2, *it1 ) != last2 ) {}
  157. return it1 == first1 && std::find( first2, last2, *it1 ) != last2 ? last1 : it1;
  158. }
  159. //____________________________________________________________________________//
  160. /// @brief this algorithm search through first collection for last element that does not satisfy binary
  161. /// predicate in conjunction will any element in second collection
  162. ///
  163. /// @param first1 - first collection begin iterator
  164. /// @param last1 - first collection end iterator
  165. /// @param first2 - second collection begin iterator
  166. /// @param last2 - second collection end iterator
  167. /// @param pred - predicate to be used for search
  168. template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
  169. inline BidirectionalIterator1
  170. find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  171. ForwardIterator2 first2, ForwardIterator2 last2,
  172. Predicate pred )
  173. {
  174. if( first1 == last1 || first2 == last2 )
  175. return last1;
  176. BidirectionalIterator1 it1 = last1;
  177. while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) != last2 ) {}
  178. return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
  179. }
  180. //____________________________________________________________________________//
  181. } // namespace utils
  182. } // namespace unit_test
  183. } // namespace boost
  184. #include <boost/test/detail/enable_warnings.hpp>
  185. #endif // BOOST_TEST_UTILS_ALGORITHM_HPP