is_sorted.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Copyright (c) 2010 Nuovation System Designs, LLC
  2. // Grant Erickson <gerickson@nuovations.com>
  3. //
  4. // Reworked somewhat by Marshall Clow; August 2010
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/ for latest version.
  11. //
  12. #ifndef BOOST_ALGORITHM_ORDERED_HPP
  13. #define BOOST_ALGORITHM_ORDERED_HPP
  14. #include <functional>
  15. #include <iterator>
  16. #include <boost/config.hpp>
  17. #include <boost/range/begin.hpp>
  18. #include <boost/range/end.hpp>
  19. #include <boost/utility/enable_if.hpp>
  20. #include <boost/type_traits/is_same.hpp>
  21. #include <boost/mpl/identity.hpp>
  22. namespace boost { namespace algorithm {
  23. /// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
  24. /// \return the point in the sequence [first, last) where the elements are unordered
  25. /// (according to the comparison predicate 'p').
  26. ///
  27. /// \param first The start of the sequence to be tested.
  28. /// \param last One past the end of the sequence
  29. /// \param p A binary predicate that returns true if two elements are ordered.
  30. ///
  31. template <typename ForwardIterator, typename Pred>
  32. BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
  33. {
  34. if ( first == last ) return last; // the empty sequence is ordered
  35. ForwardIterator next = first;
  36. while ( ++next != last )
  37. {
  38. if ( p ( *next, *first ))
  39. return next;
  40. first = next;
  41. }
  42. return last;
  43. }
  44. /// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last )
  45. /// \return the point in the sequence [first, last) where the elements are unordered
  46. ///
  47. /// \param first The start of the sequence to be tested.
  48. /// \param last One past the end of the sequence
  49. ///
  50. template <typename ForwardIterator>
  51. BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
  52. {
  53. typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
  54. return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
  55. }
  56. /// \fn is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
  57. /// \return whether or not the entire sequence is sorted
  58. ///
  59. /// \param first The start of the sequence to be tested.
  60. /// \param last One past the end of the sequence
  61. /// \param p A binary predicate that returns true if two elements are ordered.
  62. ///
  63. template <typename ForwardIterator, typename Pred>
  64. BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
  65. {
  66. return boost::algorithm::is_sorted_until (first, last, p) == last;
  67. }
  68. /// \fn is_sorted ( ForwardIterator first, ForwardIterator last )
  69. /// \return whether or not the entire sequence is sorted
  70. ///
  71. /// \param first The start of the sequence to be tested.
  72. /// \param last One past the end of the sequence
  73. ///
  74. template <typename ForwardIterator>
  75. BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last )
  76. {
  77. return boost::algorithm::is_sorted_until (first, last) == last;
  78. }
  79. ///
  80. /// -- Range based versions of the C++11 functions
  81. ///
  82. /// \fn is_sorted_until ( const R &range, Pred p )
  83. /// \return the point in the range R where the elements are unordered
  84. /// (according to the comparison predicate 'p').
  85. ///
  86. /// \param range The range to be tested.
  87. /// \param p A binary predicate that returns true if two elements are ordered.
  88. ///
  89. template <typename R, typename Pred>
  90. BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c<
  91. boost::is_same<R, Pred>::value,
  92. typename boost::range_iterator<const R>
  93. >::type is_sorted_until ( const R &range, Pred p )
  94. {
  95. return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ), p );
  96. }
  97. /// \fn is_sorted_until ( const R &range )
  98. /// \return the point in the range R where the elements are unordered
  99. ///
  100. /// \param range The range to be tested.
  101. ///
  102. template <typename R>
  103. BOOST_CXX14_CONSTEXPR typename boost::range_iterator<const R>::type is_sorted_until ( const R &range )
  104. {
  105. return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ));
  106. }
  107. /// \fn is_sorted ( const R &range, Pred p )
  108. /// \return whether or not the entire range R is sorted
  109. /// (according to the comparison predicate 'p').
  110. ///
  111. /// \param range The range to be tested.
  112. /// \param p A binary predicate that returns true if two elements are ordered.
  113. ///
  114. template <typename R, typename Pred>
  115. BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type
  116. is_sorted ( const R &range, Pred p )
  117. {
  118. return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p );
  119. }
  120. /// \fn is_sorted ( const R &range )
  121. /// \return whether or not the entire range R is sorted
  122. ///
  123. /// \param range The range to be tested.
  124. ///
  125. template <typename R>
  126. BOOST_CXX14_CONSTEXPR bool is_sorted ( const R &range )
  127. {
  128. return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ));
  129. }
  130. ///
  131. /// -- Range based versions of the C++11 functions
  132. ///
  133. /// \fn is_increasing ( ForwardIterator first, ForwardIterator last )
  134. /// \return true if the entire sequence is increasing; i.e, each item is greater than or
  135. /// equal to the previous one.
  136. ///
  137. /// \param first The start of the sequence to be tested.
  138. /// \param last One past the end of the sequence
  139. ///
  140. /// \note This function will return true for sequences that contain items that compare
  141. /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
  142. template <typename ForwardIterator>
  143. BOOST_CXX14_CONSTEXPR bool is_increasing ( ForwardIterator first, ForwardIterator last )
  144. {
  145. typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
  146. return boost::algorithm::is_sorted (first, last, std::less<value_type>());
  147. }
  148. /// \fn is_increasing ( const R &range )
  149. /// \return true if the entire sequence is increasing; i.e, each item is greater than or
  150. /// equal to the previous one.
  151. ///
  152. /// \param range The range to be tested.
  153. ///
  154. /// \note This function will return true for sequences that contain items that compare
  155. /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
  156. template <typename R>
  157. BOOST_CXX14_CONSTEXPR bool is_increasing ( const R &range )
  158. {
  159. return is_increasing ( boost::begin ( range ), boost::end ( range ));
  160. }
  161. /// \fn is_decreasing ( ForwardIterator first, ForwardIterator last )
  162. /// \return true if the entire sequence is decreasing; i.e, each item is less than
  163. /// or equal to the previous one.
  164. ///
  165. /// \param first The start of the sequence to be tested.
  166. /// \param last One past the end of the sequence
  167. ///
  168. /// \note This function will return true for sequences that contain items that compare
  169. /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
  170. template <typename ForwardIterator>
  171. BOOST_CXX14_CONSTEXPR bool is_decreasing ( ForwardIterator first, ForwardIterator last )
  172. {
  173. typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
  174. return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
  175. }
  176. /// \fn is_decreasing ( const R &range )
  177. /// \return true if the entire sequence is decreasing; i.e, each item is less than
  178. /// or equal to the previous one.
  179. ///
  180. /// \param range The range to be tested.
  181. ///
  182. /// \note This function will return true for sequences that contain items that compare
  183. /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
  184. template <typename R>
  185. BOOST_CXX14_CONSTEXPR bool is_decreasing ( const R &range )
  186. {
  187. return is_decreasing ( boost::begin ( range ), boost::end ( range ));
  188. }
  189. /// \fn is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
  190. /// \return true if the entire sequence is strictly increasing; i.e, each item is greater
  191. /// than the previous one
  192. ///
  193. /// \param first The start of the sequence to be tested.
  194. /// \param last One past the end of the sequence
  195. ///
  196. /// \note This function will return false for sequences that contain items that compare
  197. /// equal. If that is not what you intended, you should use is_increasing instead.
  198. template <typename ForwardIterator>
  199. BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
  200. {
  201. typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
  202. return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
  203. }
  204. /// \fn is_strictly_increasing ( const R &range )
  205. /// \return true if the entire sequence is strictly increasing; i.e, each item is greater
  206. /// than the previous one
  207. ///
  208. /// \param range The range to be tested.
  209. ///
  210. /// \note This function will return false for sequences that contain items that compare
  211. /// equal. If that is not what you intended, you should use is_increasing instead.
  212. template <typename R>
  213. BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( const R &range )
  214. {
  215. return is_strictly_increasing ( boost::begin ( range ), boost::end ( range ));
  216. }
  217. /// \fn is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
  218. /// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
  219. /// the previous one
  220. ///
  221. /// \param first The start of the sequence to be tested.
  222. /// \param last One past the end of the sequence
  223. ///
  224. /// \note This function will return false for sequences that contain items that compare
  225. /// equal. If that is not what you intended, you should use is_decreasing instead.
  226. template <typename ForwardIterator>
  227. BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
  228. {
  229. typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
  230. return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
  231. }
  232. /// \fn is_strictly_decreasing ( const R &range )
  233. /// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
  234. /// the previous one
  235. ///
  236. /// \param range The range to be tested.
  237. ///
  238. /// \note This function will return false for sequences that contain items that compare
  239. /// equal. If that is not what you intended, you should use is_decreasing instead.
  240. template <typename R>
  241. BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( const R &range )
  242. {
  243. return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
  244. }
  245. }} // namespace boost
  246. #endif // BOOST_ALGORITHM_ORDERED_HPP