1 // Copyright (c) 2010 Nuovation System Designs, LLC
2 // Grant Erickson <gerickson@nuovations.com>
4 // Reworked somewhat by Marshall Clow; August 2010
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)
10 // See http://www.boost.org/ for latest version.
13 #ifndef BOOST_ALGORITHM_ORDERED_HPP
14 #define BOOST_ALGORITHM_ORDERED_HPP
19 #include <boost/config.hpp>
20 #include <boost/range/begin.hpp>
21 #include <boost/range/end.hpp>
23 #include <boost/utility/enable_if.hpp>
24 #include <boost/type_traits/is_same.hpp>
25 #include <boost/mpl/identity.hpp>
27 namespace boost { namespace algorithm {
29 /// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
30 /// \return the point in the sequence [first, last) where the elements are unordered
31 /// (according to the comparison predicate 'p').
33 /// \param first The start of the sequence to be tested.
34 /// \param last One past the end of the sequence
35 /// \param p A binary predicate that returns true if two elements are ordered.
37 template <typename ForwardIterator, typename Pred>
38 BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
40 if ( first == last ) return last; // the empty sequence is ordered
41 ForwardIterator next = first;
42 while ( ++next != last )
44 if ( p ( *next, *first ))
51 /// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last )
52 /// \return the point in the sequence [first, last) where the elements are unordered
54 /// \param first The start of the sequence to be tested.
55 /// \param last One past the end of the sequence
57 template <typename ForwardIterator>
58 BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
60 typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
61 return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
65 /// \fn is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
66 /// \return whether or not the entire sequence is sorted
68 /// \param first The start of the sequence to be tested.
69 /// \param last One past the end of the sequence
70 /// \param p A binary predicate that returns true if two elements are ordered.
72 template <typename ForwardIterator, typename Pred>
73 BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
75 return boost::algorithm::is_sorted_until (first, last, p) == last;
78 /// \fn is_sorted ( ForwardIterator first, ForwardIterator last )
79 /// \return whether or not the entire sequence is sorted
81 /// \param first The start of the sequence to be tested.
82 /// \param last One past the end of the sequence
84 template <typename ForwardIterator>
85 BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last )
87 return boost::algorithm::is_sorted_until (first, last) == last;
91 /// -- Range based versions of the C++11 functions
94 /// \fn is_sorted_until ( const R &range, Pred p )
95 /// \return the point in the range R where the elements are unordered
96 /// (according to the comparison predicate 'p').
98 /// \param range The range to be tested.
99 /// \param p A binary predicate that returns true if two elements are ordered.
101 template <typename R, typename Pred>
102 BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c<
103 boost::is_same<R, Pred>::value,
104 typename boost::range_iterator<const R>
105 >::type is_sorted_until ( const R &range, Pred p )
107 return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ), p );
111 /// \fn is_sorted_until ( const R &range )
112 /// \return the point in the range R where the elements are unordered
114 /// \param range The range to be tested.
116 template <typename R>
117 BOOST_CXX14_CONSTEXPR typename boost::range_iterator<const R>::type is_sorted_until ( const R &range )
119 return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ));
122 /// \fn is_sorted ( const R &range, Pred p )
123 /// \return whether or not the entire range R is sorted
124 /// (according to the comparison predicate 'p').
126 /// \param range The range to be tested.
127 /// \param p A binary predicate that returns true if two elements are ordered.
129 template <typename R, typename Pred>
130 BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type
131 is_sorted ( const R &range, Pred p )
133 return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p );
137 /// \fn is_sorted ( const R &range )
138 /// \return whether or not the entire range R is sorted
140 /// \param range The range to be tested.
142 template <typename R>
143 BOOST_CXX14_CONSTEXPR bool is_sorted ( const R &range )
145 return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ));
150 /// -- Range based versions of the C++11 functions
153 /// \fn is_increasing ( ForwardIterator first, ForwardIterator last )
154 /// \return true if the entire sequence is increasing; i.e, each item is greater than or
155 /// equal to the previous one.
157 /// \param first The start of the sequence to be tested.
158 /// \param last One past the end of the sequence
160 /// \note This function will return true for sequences that contain items that compare
161 /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
162 template <typename ForwardIterator>
163 BOOST_CXX14_CONSTEXPR bool is_increasing ( ForwardIterator first, ForwardIterator last )
165 typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
166 return boost::algorithm::is_sorted (first, last, std::less<value_type>());
170 /// \fn is_increasing ( const R &range )
171 /// \return true if the entire sequence is increasing; i.e, each item is greater than or
172 /// equal to the previous one.
174 /// \param range The range to be tested.
176 /// \note This function will return true for sequences that contain items that compare
177 /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
178 template <typename R>
179 BOOST_CXX14_CONSTEXPR bool is_increasing ( const R &range )
181 return is_increasing ( boost::begin ( range ), boost::end ( range ));
186 /// \fn is_decreasing ( ForwardIterator first, ForwardIterator last )
187 /// \return true if the entire sequence is decreasing; i.e, each item is less than
188 /// or equal to the previous one.
190 /// \param first The start of the sequence to be tested.
191 /// \param last One past the end of the sequence
193 /// \note This function will return true for sequences that contain items that compare
194 /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
195 template <typename ForwardIterator>
196 BOOST_CXX14_CONSTEXPR bool is_decreasing ( ForwardIterator first, ForwardIterator last )
198 typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
199 return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
202 /// \fn is_decreasing ( const R &range )
203 /// \return true if the entire sequence is decreasing; i.e, each item is less than
204 /// or equal to the previous one.
206 /// \param range The range to be tested.
208 /// \note This function will return true for sequences that contain items that compare
209 /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
210 template <typename R>
211 BOOST_CXX14_CONSTEXPR bool is_decreasing ( const R &range )
213 return is_decreasing ( boost::begin ( range ), boost::end ( range ));
218 /// \fn is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
219 /// \return true if the entire sequence is strictly increasing; i.e, each item is greater
220 /// than the previous one
222 /// \param first The start of the sequence to be tested.
223 /// \param last One past the end of the sequence
225 /// \note This function will return false for sequences that contain items that compare
226 /// equal. If that is not what you intended, you should use is_increasing instead.
227 template <typename ForwardIterator>
228 BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
230 typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
231 return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
234 /// \fn is_strictly_increasing ( const R &range )
235 /// \return true if the entire sequence is strictly increasing; i.e, each item is greater
236 /// than the previous one
238 /// \param range The range to be tested.
240 /// \note This function will return false for sequences that contain items that compare
241 /// equal. If that is not what you intended, you should use is_increasing instead.
242 template <typename R>
243 BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( const R &range )
245 return is_strictly_increasing ( boost::begin ( range ), boost::end ( range ));
249 /// \fn is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
250 /// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
253 /// \param first The start of the sequence to be tested.
254 /// \param last One past the end of the sequence
256 /// \note This function will return false for sequences that contain items that compare
257 /// equal. If that is not what you intended, you should use is_decreasing instead.
258 template <typename ForwardIterator>
259 BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
261 typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
262 return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
265 /// \fn is_strictly_decreasing ( const R &range )
266 /// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
269 /// \param range The range to be tested.
271 /// \note This function will return false for sequences that contain items that compare
272 /// equal. If that is not what you intended, you should use is_decreasing instead.
273 template <typename R>
274 BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( const R &range )
276 return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
279 }} // namespace boost
281 #endif // BOOST_ALGORITHM_ORDERED_HPP