diff --git a/include/boost/detail/is_sorted.hpp b/include/boost/detail/is_sorted.hpp new file mode 100644 index 0000000..91f254c --- /dev/null +++ b/include/boost/detail/is_sorted.hpp @@ -0,0 +1,56 @@ +/*============================================================================== + Copyright (c) 2010-2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#ifndef BOOST_DETAIL_SORTED_HPP +#define BOOST_DETAIL_SORTED_HPP + +#include + +#include + +namespace boost { +namespace detail { + +template +inline Iterator is_sorted_until (Iterator first, Iterator last, Comp compare) { + if (first == last) + return last; + + Iterator it = first; ++it; + + for (; it != last; first = it, ++it) + if (compare(*it, *first)) + return it; + + return it; +} + +template +inline Iterator is_sorted_until (Iterator first, Iterator last) { + typedef typename boost::detail::iterator_traits::value_type + value_type; + + typedef std::less compare; + + return is_sorted_until(first, last, compare()); +} + +template +inline bool is_sorted (Iterator first, Iterator last, Comp compare) { + return is_sorted_until(first, last, compare) == last; +} + +template +inline bool is_sorted (Iterator first, Iterator last) { + return is_sorted_until(first, last) == last; +} + +} // detail +} // boost + +#endif // BOOST_DETAIL_SORTED_HPP + diff --git a/test/is_sorted_test.cpp b/test/is_sorted_test.cpp new file mode 100644 index 0000000..36c03bc --- /dev/null +++ b/test/is_sorted_test.cpp @@ -0,0 +1,129 @@ +/*============================================================================== + Copyright (c) 2010-2011 Bryce Lelbach + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +==============================================================================*/ + +#include +#include +#include +#include +#include + +template +struct tracking_less: std::binary_function { + typedef bool result_type; + + #if defined(__PATHSCALE__) + tracking_less (void) { } + ~tracking_less (void) { } + #endif + + bool operator() (T const& x, T const& y) const { + std::cout << x << " < " << y << " == " << (x < y) << "\n"; + return x < y; + } +}; + +template +struct tracking_less_equal: std::binary_function { + typedef bool result_type; + + #if defined(__PATHSCALE__) + tracking_less_equal (void) { } + ~tracking_less_equal (void) { } + #endif + + bool operator() (T const& x, T const& y) const { + std::cout << x << " <= " << y << " == " << (x <= y) << "\n"; + return x <= y; + } +}; + +template +struct tracking_greater: std::binary_function { + typedef bool result_type; + + #if defined(__PATHSCALE__) + tracking_greater (void) { } + ~tracking_greater (void) { } + #endif + + bool operator() (T const& x, T const& y) const { + std::cout << x << " > " << y << " == " << (x > y) << "\n"; + return x > y; + } +}; + +template +struct tracking_greater_equal: std::binary_function { + typedef bool result_type; + + #if defined(__PATHSCALE__) + tracking_greater_equal (void) { } + ~tracking_greater_equal (void) { } + #endif + + bool operator() (T const& x, T const& y) const { + std::cout << x << " >= " << y << " == " << (x >= y) << "\n"; + return x >= y; + } +}; + +int main (void) { + using boost::detail::is_sorted; + using boost::detail::is_sorted_until; + using boost::array; + using boost::report_errors; + + std::cout << std::boolalpha; + + array a = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } }; + array b = { { 0, 1, 1, 2, 5, 8, 13, 34, 55, 89 } }; + array c = { { 0, 1, -1, 2, -3, 5, -8, 13, -21, 34 } }; + + tracking_less lt; + tracking_less_equal lte; + tracking_greater gt; + tracking_greater_equal gte; + + BOOST_TEST_EQ(is_sorted_until(a.begin(), a.end()), a.end()); + BOOST_TEST_EQ(is_sorted_until(a.begin(), a.end(), lt), a.end()); + BOOST_TEST_EQ(is_sorted_until(a.begin(), a.end(), lte), a.end()); + BOOST_TEST_EQ(*is_sorted_until(a.rbegin(), a.rend(), gt), *a.rend()); + BOOST_TEST_EQ(*is_sorted_until(a.rbegin(), a.rend(), gte), *a.rend()); + + BOOST_TEST_EQ(is_sorted(a.begin(), a.end()), true); + BOOST_TEST_EQ(is_sorted(a.begin(), a.end(), lt), true); + BOOST_TEST_EQ(is_sorted(a.begin(), a.end(), lte), true); + BOOST_TEST_EQ(is_sorted(a.rbegin(), a.rend(), gt), true); + BOOST_TEST_EQ(is_sorted(a.rbegin(), a.rend(), gte), true); + + BOOST_TEST_EQ(is_sorted_until(b.begin(), b.end()), b.end()); + BOOST_TEST_EQ(is_sorted_until(b.begin(), b.end(), lt), b.end()); + BOOST_TEST_EQ(is_sorted_until(b.begin(), b.end(), lte), &b[2]); + BOOST_TEST_EQ(*is_sorted_until(b.rbegin(), b.rend(), gt), *b.rend()); + BOOST_TEST_EQ(*is_sorted_until(b.rbegin(), b.rend(), gte), b[2]); + + BOOST_TEST_EQ(is_sorted(b.begin(), b.end()), true); + BOOST_TEST_EQ(is_sorted(b.begin(), b.end(), lt), true); + BOOST_TEST_EQ(is_sorted(b.begin(), b.end(), lte), false); + BOOST_TEST_EQ(is_sorted(b.rbegin(), b.rend(), gt), true); + BOOST_TEST_EQ(is_sorted(b.rbegin(), b.rend(), gte), false); + + BOOST_TEST_EQ(is_sorted_until(c.begin(), c.end()), &c[2]); + BOOST_TEST_EQ(is_sorted_until(c.begin(), c.end(), lt), &c[2]); + BOOST_TEST_EQ(is_sorted_until(c.begin(), c.end(), lte), &c[2]); + BOOST_TEST_EQ(*is_sorted_until(c.rbegin(), c.rend(), gt), c[7]); + BOOST_TEST_EQ(*is_sorted_until(c.rbegin(), c.rend(), gte), c[7]); + + BOOST_TEST_EQ(is_sorted(c.begin(), c.end()), false); + BOOST_TEST_EQ(is_sorted(c.begin(), c.end(), lt), false); + BOOST_TEST_EQ(is_sorted(c.begin(), c.end(), lte), false); + BOOST_TEST_EQ(is_sorted(c.rbegin(), c.rend(), gt), false); + BOOST_TEST_EQ(is_sorted(c.rbegin(), c.rend(), gte), false); + + return report_errors(); +} +