algorithm.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // (C) Copyright Gennadiy Rozental 2004-2008.
  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 : $RCSfile$
  8. //
  9. // Version : $Revision: 49312 $
  10. //
  11. // Description : addition to STL algorithms
  12. // ***************************************************************************
  13. #ifndef BOOST_ALGORITHM_HPP_062304GER
  14. #define BOOST_ALGORITHM_HPP_062304GER
  15. #include <utility>
  16. #include <algorithm> // std::find
  17. #include <functional> // std::bind1st
  18. #include <boost/test/detail/suppress_warnings.hpp>
  19. //____________________________________________________________________________//
  20. namespace boost {
  21. namespace unit_test {
  22. /// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
  23. /// of iterators, first pointing to the mismatch position in first collection, second iterator in second one
  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. /// @param first1 - first collection begin iterator
  44. /// @param last1 - first collection end iterator
  45. /// @param first2 - second collection begin iterator
  46. /// @param last2 - second collection end iterator
  47. /// @param pred - predicate to be used for search
  48. template <class InputIter1, class InputIter2, class Predicate>
  49. inline std::pair<InputIter1, InputIter2>
  50. mismatch( InputIter1 first1, InputIter1 last1,
  51. InputIter2 first2, InputIter2 last2,
  52. Predicate pred )
  53. {
  54. while( first1 != last1 && first2 != last2 && pred( *first1, *first2 ) ) {
  55. ++first1;
  56. ++first2;
  57. }
  58. return std::pair<InputIter1, InputIter2>(first1, first2);
  59. }
  60. //____________________________________________________________________________//
  61. /// @brief this algorithm search through first collection for first element that does not belong a second one
  62. /// @param first1 - first collection begin iterator
  63. /// @param last1 - first collection end iterator
  64. /// @param first2 - second collection begin iterator
  65. /// @param last2 - second collection end iterator
  66. template<class ForwardIterator1, class ForwardIterator2>
  67. inline ForwardIterator1
  68. find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
  69. ForwardIterator2 first2, ForwardIterator2 last2 )
  70. {
  71. while( first1 != last1 ) {
  72. if( std::find( first2, last2, *first1 ) == last2 )
  73. break;
  74. ++first1;
  75. }
  76. return first1;
  77. }
  78. //____________________________________________________________________________//
  79. /// @brief this algorithm search through first collection for first element that does not satisfy binary
  80. /// predicate in conjunction will any element in second collection
  81. /// @param first1 - first collection begin iterator
  82. /// @param last1 - first collection end iterator
  83. /// @param first2 - second collection begin iterator
  84. /// @param last2 - second collection end iterator
  85. /// @param pred - predicate to be used for search
  86. template<class ForwardIterator1, class ForwardIterator2, class Predicate>
  87. inline ForwardIterator1
  88. find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
  89. ForwardIterator2 first2, ForwardIterator2 last2,
  90. Predicate pred )
  91. {
  92. while( first1 != last1 ) {
  93. if( std::find_if( first2, last2, std::bind1st( pred, *first1 ) ) == last2 )
  94. break;
  95. ++first1;
  96. }
  97. return first1;
  98. }
  99. //____________________________________________________________________________//
  100. /// @brief this algorithm search through first collection for last element that belongs to a second one
  101. /// @param first1 - first collection begin iterator
  102. /// @param last1 - first collection end iterator
  103. /// @param first2 - second collection begin iterator
  104. /// @param last2 - second collection end iterator
  105. template<class BidirectionalIterator1, class ForwardIterator2>
  106. inline BidirectionalIterator1
  107. find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  108. ForwardIterator2 first2, ForwardIterator2 last2 )
  109. {
  110. if( first1 == last1 || first2 == last2 )
  111. return last1;
  112. BidirectionalIterator1 it1 = last1;
  113. while( --it1 != first1 && std::find( first2, last2, *it1 ) == last2 ) {}
  114. return it1 == first1 && std::find( first2, last2, *it1 ) == last2 ? last1 : it1;
  115. }
  116. //____________________________________________________________________________//
  117. /// @brief this algorithm search through first collection for last element that satisfy binary
  118. /// predicate in conjunction will at least one element in second collection
  119. /// @param first1 - first collection begin iterator
  120. /// @param last1 - first collection end iterator
  121. /// @param first2 - second collection begin iterator
  122. /// @param last2 - second collection end iterator
  123. /// @param pred - predicate to be used for search
  124. template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
  125. inline BidirectionalIterator1
  126. find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  127. ForwardIterator2 first2, ForwardIterator2 last2,
  128. Predicate pred )
  129. {
  130. if( first1 == last1 || first2 == last2 )
  131. return last1;
  132. BidirectionalIterator1 it1 = last1;
  133. while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ) {}
  134. return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
  135. }
  136. //____________________________________________________________________________//
  137. /// @brief this algorithm search through first collection for last element that does not belong to a second one
  138. /// @param first1 - first collection begin iterator
  139. /// @param last1 - first collection end iterator
  140. /// @param first2 - second collection begin iterator
  141. /// @param last2 - second collection end iterator
  142. template<class BidirectionalIterator1, class ForwardIterator2>
  143. inline BidirectionalIterator1
  144. find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  145. ForwardIterator2 first2, ForwardIterator2 last2 )
  146. {
  147. if( first1 == last1 || first2 == last2 )
  148. return last1;
  149. BidirectionalIterator1 it1 = last1;
  150. while( --it1 != first1 && std::find( first2, last2, *it1 ) != last2 ) {}
  151. return it1 == first1 && std::find( first2, last2, *it1 ) != last2 ? last1 : it1;
  152. }
  153. //____________________________________________________________________________//
  154. /// @brief this algorithm search through first collection for last element that does not satisfy binary
  155. /// predicate in conjunction will any element in second collection
  156. /// @param first1 - first collection begin iterator
  157. /// @param last1 - first collection end iterator
  158. /// @param first2 - second collection begin iterator
  159. /// @param last2 - second collection end iterator
  160. /// @param pred - predicate to be used for search
  161. template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
  162. inline BidirectionalIterator1
  163. find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
  164. ForwardIterator2 first2, ForwardIterator2 last2,
  165. Predicate pred )
  166. {
  167. if( first1 == last1 || first2 == last2 )
  168. return last1;
  169. BidirectionalIterator1 it1 = last1;
  170. while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) != last2 ) {}
  171. return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
  172. }
  173. //____________________________________________________________________________//
  174. } // namespace unit_test
  175. } // namespace boost
  176. //____________________________________________________________________________//
  177. #include <boost/test/detail/enable_warnings.hpp>
  178. #endif // BOOST_ALGORITHM_HPP_062304GER