diff --git a/include/boost/algorithm/cxx14/equal.hpp b/include/boost/algorithm/cxx14/equal.hpp index 78587fc..becaed2 100644 --- a/include/boost/algorithm/cxx14/equal.hpp +++ b/include/boost/algorithm/cxx14/equal.hpp @@ -15,6 +15,13 @@ #include // for std::equal #include // for std::equal_to +#ifdef __cpp_lib_array_constexpr // or cpp17 compiler +// if compiled according to C++17 standard or std functions are constexpr +#define BOOST_CONSTEXPR_IF_STD_CONSTEXPR constexpr +#else +#define BOOST_CONSTEXPR_IF_STD_CONSTEXPR +#endif + namespace boost { namespace algorithm { namespace detail { @@ -25,6 +32,7 @@ namespace detail { }; template + BOOST_CONSTEXPR_IF_STD_CONSTEXPR bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, std::random_access_iterator_tag, std::random_access_iterator_tag ) @@ -37,7 +45,8 @@ namespace detail { } template - BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, + BOOST_CXX14_CONSTEXPR + bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred, std::input_iterator_tag, std::input_iterator_tag ) { @@ -60,6 +69,7 @@ namespace detail { /// \param last2 One past the end of the second range. /// \param pred A predicate for comparing the elements of the ranges template +BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred ) { @@ -78,6 +88,7 @@ bool equal ( InputIterator1 first1, InputIterator1 last1, /// \param first2 The start of the second range. /// \param last2 One past the end of the second range. template +BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 ) { diff --git a/test/clamp_test.cpp b/test/clamp_test.cpp index a8aacc7..2513cf8 100644 --- a/test/clamp_test.cpp +++ b/test/clamp_test.cpp @@ -210,6 +210,110 @@ void test_int_range () BOOST_CHECK ( std::equal ( b_e(junk), outputs )); } +void test_constexpr() +{ + +// Inside the range, equal to the endpoints, and outside the endpoints. + { + BOOST_CXX14_CONSTEXPR bool check_inside = (3 == ba::clamp ( 3, 1, 10 )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_min = (1 == ba::clamp ( 1, 1, 10 )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (1 == ba::clamp ( 0, 1, 10 )); + BOOST_CHECK(check_min_out); + BOOST_CXX14_CONSTEXPR bool check_max = (10 == ba::clamp ( 10, 1, 10 )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (10 == ba::clamp ( 11, 1, 10 )); + BOOST_CHECK(check_max_out); + } + { + BOOST_CXX14_CONSTEXPR bool check_inside = (3 == ba::clamp ( 3, 10, 1, intGreater )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_min = (1 == ba::clamp ( 1, 10, 1, intGreater )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (1 == ba::clamp ( 0, 10, 1, intGreater )); + BOOST_CHECK(check_min_out); + BOOST_CXX14_CONSTEXPR bool check_max = (10 == ba::clamp ( 10, 10, 1, intGreater )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (10 == ba::clamp ( 11, 10, 1, intGreater )); + BOOST_CHECK(check_max_out); + } + +// Negative numbers + { + BOOST_CXX14_CONSTEXPR bool check_inside = (-3 == ba::clamp ( -3, -10, -1 )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_max = (-1 == ba::clamp ( -1, -10, -1 )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (-1 == ba::clamp ( 0, -10, -1 )); + BOOST_CHECK(check_max_out); + BOOST_CXX14_CONSTEXPR bool check_min = (-10 == ba::clamp ( -10, -10, -1 )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (-10 == ba::clamp ( -11, -10, -1 )); + BOOST_CHECK(check_min_out); + } + +// Mixed positive and negative numbers + { + BOOST_CXX14_CONSTEXPR bool check_inside = (5 == ba::clamp ( 5, -10, 10 )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_min = (-10 == ba::clamp ( -10, -10, 10 )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (-10 == ba::clamp ( -15, -10, 10 )); + BOOST_CHECK(check_min_out); + BOOST_CXX14_CONSTEXPR bool check_max = (10 == ba::clamp ( 10, -10, 10 )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (10 == ba::clamp ( 15, -10, 10 )); + BOOST_CHECK(check_max_out); + } +// Unsigned + { + BOOST_CXX14_CONSTEXPR bool check_inside = (5U == ba::clamp ( 5U, 1U, 10U )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_min = (1U == ba::clamp ( 1U, 1U, 10U )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (1U == ba::clamp ( 0U, 1U, 10U )); + BOOST_CHECK(check_min_out); + BOOST_CXX14_CONSTEXPR bool check_max = (10U == ba::clamp ( 10U, 1U, 10U )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (10U == ba::clamp ( 15U, 1U, 10U )); + BOOST_CHECK(check_max_out); + } +// Mixed (1) + { + BOOST_CXX14_CONSTEXPR bool check_inside = (5U == ba::clamp ( 5U, 1, 10 )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_min = (1U == ba::clamp ( 1U, 1, 10 )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (1U == ba::clamp ( 0U, 1, 10 )); + BOOST_CHECK(check_min_out); + BOOST_CXX14_CONSTEXPR bool check_max = (10U == ba::clamp ( 10U, 1, 10 )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (10U == ba::clamp ( 15U, 1, 10 )); + BOOST_CHECK(check_max_out); + } +// Mixed (3) + { + BOOST_CXX14_CONSTEXPR bool check_inside = (5U == ba::clamp ( 5U, 1, 10. )); + BOOST_CHECK(check_inside); + BOOST_CXX14_CONSTEXPR bool check_min = (1U == ba::clamp ( 1U, 1, 10. )); + BOOST_CHECK(check_min); + BOOST_CXX14_CONSTEXPR bool check_min_out = (1U == ba::clamp ( 0U, 1, 10. )); + BOOST_CHECK(check_min_out); + BOOST_CXX14_CONSTEXPR bool check_max = (10U == ba::clamp ( 10U, 1, 10. )); + BOOST_CHECK(check_max); + BOOST_CXX14_CONSTEXPR bool check_max_out = (10U == ba::clamp ( 15U, 1, 10. )); + BOOST_CHECK(check_max_out); + } + { + short foo = 50; + BOOST_CXX14_CONSTEXPR bool check_float = ( 56 == ba::clamp ( foo, 56.9, 129 )); + BOOST_CHECK(check_float); + BOOST_CXX14_CONSTEXPR bool check_over = ( 24910 == ba::clamp ( foo, 12345678, 123456999 )); + BOOST_CHECK(check_over); + } +} + BOOST_AUTO_TEST_CASE( test_main ) { test_ints (); @@ -217,6 +321,8 @@ BOOST_AUTO_TEST_CASE( test_main ) test_custom (); test_int_range (); + + test_constexpr (); // test_float_range (); // test_custom_range (); } diff --git a/test/copy_if_test1.cpp b/test/copy_if_test1.cpp index 1e093fd..b275f5f 100644 --- a/test/copy_if_test1.cpp +++ b/test/copy_if_test1.cpp @@ -10,6 +10,8 @@ #include #include +#include "iterator_test.hpp" + #define BOOST_TEST_MAIN #include @@ -20,6 +22,7 @@ #include #include +#include #include namespace ba = boost::algorithm; @@ -29,21 +32,8 @@ BOOST_CXX14_CONSTEXPR bool is_true ( int v ) { return true; } BOOST_CXX14_CONSTEXPR bool is_false ( int v ) { return false; } BOOST_CXX14_CONSTEXPR bool is_even ( int v ) { return v % 2 == 0; } BOOST_CXX14_CONSTEXPR bool is_odd ( int v ) { return v % 2 == 1; } +BOOST_CXX14_CONSTEXPR bool is_zero ( int v ) { return v == 0; } -BOOST_CXX14_CONSTEXPR inline bool constexpr_helper(const int* from, const int* to) { - bool res = true; - - int out_data[64] = {0}; - int* out = out_data; - ba::copy_if ( from, to, out, is_false); - - res = (res && out == out_data); - ba::copy_if ( from, to, out, is_true); - - res = (res && out == out_data + (to - from)); - - return res; -} template void test_copy_if ( Container const &c ) { @@ -170,6 +160,71 @@ void test_copy_until ( Container const &c ) { BOOST_CHECK ( ba::none_of ( v.begin (), v.end (), is_even )); BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); } + + +BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_if() { + const int sz = 64; + int in_data[sz] = {0}; + bool res = true; + + const int* from = in_data; + const int* to = in_data + sz; + + int out_data[sz] = {0}; + int* out = out_data; + out = ba::copy_if ( from, to, out, is_false ); // copy none + res = (res && out == out_data); + + out = ba::copy_if ( from, to, out, is_true ); // copy all + res = (res && out == out_data + sz + && ba::equal( input_iterator(out_data), input_iterator(out_data + sz), + input_iterator(from), input_iterator(to))); + + return res; + } + +BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_while() { + const int sz = 64; + int in_data[sz] = {0}; + bool res = true; + + const int* from = in_data; + const int* to = in_data + sz; + + int out_data[sz] = {0}; + int* out = out_data; + out = ba::copy_while ( from, to, out, is_false ).second; // copy none + res = (res && out == out_data && ba::all_of(out, out + sz, is_zero)); + + out = ba::copy_while ( from, to, out, is_true ).second; // copy all + res = (res && out == out_data + sz + && ba::equal( input_iterator(out_data), input_iterator(out_data + sz), + input_iterator(from), input_iterator(to))); + + return res; + } + +BOOST_CXX14_CONSTEXPR inline bool constexpr_test_copy_until() { + const int sz = 64; + int in_data[sz] = {0}; + bool res = true; + + const int* from = in_data; + const int* to = in_data + sz; + + int out_data[sz] = {0}; + int* out = out_data; + out = ba::copy_until ( from, to, out, is_true ).second; // copy none + res = (res && out == out_data && ba::all_of(out, out + sz, is_zero)); + + out = ba::copy_until ( from, to, out, is_false ).second; // copy all + res = (res && out == out_data + sz + && ba::equal( input_iterator(out_data), input_iterator(out_data + sz), + input_iterator(from), input_iterator(to))); + + return res; + } + void test_sequence1 () { std::vector v; @@ -179,8 +234,12 @@ void test_sequence1 () { test_copy_while ( v ); test_copy_until ( v ); - BOOST_CXX14_CONSTEXPR bool constexpr_res = constexpr_helper(0, 0); - BOOST_CHECK ( constexpr_res ); + BOOST_CXX14_CONSTEXPR bool constexpr_res_if = constexpr_test_copy_if(); + BOOST_CHECK ( constexpr_res_if ); + BOOST_CXX14_CONSTEXPR bool constexpr_res_while = constexpr_test_copy_while(); + BOOST_CHECK ( constexpr_res_while ); + BOOST_CXX14_CONSTEXPR bool constexpr_res_until = constexpr_test_copy_until(); + BOOST_CHECK ( constexpr_res_until ); std::list l; for ( int i = 25; i > 15; --i ) diff --git a/test/copy_n_test1.cpp b/test/copy_n_test1.cpp index a61c108..68284b3 100644 --- a/test/copy_n_test1.cpp +++ b/test/copy_n_test1.cpp @@ -9,6 +9,10 @@ #include #include +#include +#include + +#include "iterator_test.hpp" #define BOOST_TEST_MAIN #include @@ -21,6 +25,8 @@ namespace ba = boost::algorithm; // namespace ba = boost; +BOOST_CXX14_CONSTEXPR bool is_zero( int v ) { return v == 0; } + template void test_sequence ( Container const &c ) { @@ -67,12 +73,38 @@ void test_sequence ( Container const &c ) { } +BOOST_CXX14_CONSTEXPR inline bool test_constexpr() { + const size_t sz = 64; + int in_data[sz] = {0}; + bool res = true; + + const int* from = in_data; + const int* to = in_data + sz; + + int out_data[sz] = {0}; + int* out = out_data; + + out = ba::copy_n ( from, 0, out ); // Copy none + res = (res && out == out_data && ba::all_of(out, out + sz, is_zero)); + + out = ba::copy_n ( from, sz, out ); // Copy all + res = (res && out == out_data + sz + && ba::equal( input_iterator(out_data), input_iterator(out_data + sz), + input_iterator(from), input_iterator(to))); + + return res; + } + + void test_sequence1 () { std::vector v; for ( int i = 5; i < 15; ++i ) v.push_back ( i ); test_sequence ( v ); + BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr(); + BOOST_CHECK(constexpr_res); + std::list l; for ( int i = 25; i > 15; --i ) l.push_back ( i ); diff --git a/test/equal_test.cpp b/test/equal_test.cpp index c54e64d..3932098 100644 --- a/test/equal_test.cpp +++ b/test/equal_test.cpp @@ -16,7 +16,7 @@ #include template -bool eq ( const T& a, const T& b ) { return a == b; } +BOOST_CXX14_CONSTEXPR bool eq ( const T& a, const T& b ) { return a == b; } template bool never_eq ( const T&, const T& ) { return false; } @@ -123,7 +123,43 @@ void test_equal () } +BOOST_CXX14_CONSTEXPR bool test_constexpr_equal() { + int num[] = { 1, 1, 2, 3, 5}; + const int sz = sizeof (num)/sizeof(num[0]); + bool res = true; +// Empty sequences are equal to each other + res = ( ba::equal ( input_iterator(num), input_iterator(num), + input_iterator(num), input_iterator(num)) +// Identical long sequences are equal + && ba::equal ( input_iterator(num), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz), + eq ) +// Different sequences are different + && !ba::equal ( input_iterator(num + 1), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz)) + ); +#ifdef __cpp_lib_array_constexpr // or cpp17 compiler +// Turn on tests for random_access_iterator, because std functions used in equal are marked constexpr_res + res = ( res +// Empty sequences are equal to each other + && ba::equal ( random_access_iterator(num), random_access_iterator(num), + random_access_iterator(num), random_access_iterator(num)) +// Identical long sequences are equal + && ba::equal ( random_access_iterator(num), random_access_iterator(num + sz), + random_access_iterator(num), random_access_iterator(num + sz), + eq ) +// Different sequences are different + && !ba::equal ( random_access_iterator(num + 1), random_access_iterator(num + sz), + random_access_iterator(num), random_access_iterator(num + sz)) + ); +#endif + return res; + } + + BOOST_AUTO_TEST_CASE( test_main ) { test_equal (); + BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr_equal (); + BOOST_CHECK (constexpr_res); } diff --git a/test/find_if_not_test1.cpp b/test/find_if_not_test1.cpp index 1a17d95..2d79555 100644 --- a/test/find_if_not_test1.cpp +++ b/test/find_if_not_test1.cpp @@ -22,6 +22,29 @@ namespace ba = boost::algorithm; // namespace ba = boost; +BOOST_CXX14_CONSTEXPR bool is_true ( int v ) { return true; } +BOOST_CXX14_CONSTEXPR bool is_false ( int v ) { return false; } +BOOST_CXX14_CONSTEXPR bool is_not_three ( int v ) { return v != 3; } + +BOOST_CXX14_CONSTEXPR bool check_constexpr() { + int in_data[] = {1, 2, 3, 4, 5}; + bool res = true; + + const int* from = in_data; + const int* to = in_data + 5; + + const int* start = ba::find_if_not (from, to, is_false); // stops on first + res = (res && start == from); + + const int* end = ba::find_if_not(from, to, is_true); // stops on the end + res = (res && end == to); + + const int* three = ba::find_if_not(from, to, is_not_three); // stops on third element + res = (res && three == in_data + 2); + + return res; +} + template typename Container::iterator offset_to_iter ( Container &v, int offset ) { typename Container::iterator retval; diff --git a/test/iota_test1.cpp b/test/iota_test1.cpp index 747691f..dfc047d 100644 --- a/test/iota_test1.cpp +++ b/test/iota_test1.cpp @@ -20,7 +20,7 @@ // Test to make sure a sequence is "correctly formed"; i.e, ascending by one template -bool test_iota_results ( Iterator first, Iterator last, T initial_value ) { +BOOST_CXX14_CONSTEXPR bool test_iota_results ( Iterator first, Iterator last, T initial_value ) { if ( first == last ) return true; if ( initial_value != *first ) return false; Iterator prev = first; @@ -32,12 +32,13 @@ bool test_iota_results ( Iterator first, Iterator last, T initial_value ) { return true; } + template -bool test_iota_results ( const Range &r, T initial_value ) { +BOOST_CXX14_CONSTEXPR bool test_iota_results ( const Range &r, T initial_value ) { return test_iota_results (boost::begin (r), boost::end (r), initial_value ); } - + void test_ints () { std::vector v; std::list l; @@ -76,9 +77,38 @@ void test_ints () { boost::algorithm::iota_n ( std::front_inserter(l), 123, 20 ); BOOST_CHECK ( test_iota_results ( l.rbegin (), l.rend (), 123 )); } + +BOOST_CXX14_CONSTEXPR inline bool test_constexpr_iota() { + bool res = true; + int data[] = {0, 0, 0}; + boost::algorithm::iota(data, data, 1); // fill none + res = (res && data[0] == 0); + + boost::algorithm::iota(data, data + 3, 1); // fill all + res = (res && test_iota_results(data, data + 3, 1)); + + return res; + } + + +BOOST_CXX14_CONSTEXPR inline bool test_constexpr_iota_n() { + bool res = true; + int data[] = {0, 0, 0}; + boost::algorithm::iota_n(data, 1, 0); // fill none + res = (res && data[0] == 0); + + boost::algorithm::iota_n(data, 1, 3); // fill all + res = (res && test_iota_results(data, 1)); + + return res; + } BOOST_AUTO_TEST_CASE( test_main ) { test_ints (); + BOOST_CXX14_CONSTEXPR bool constexpr_iota_res = test_constexpr_iota (); + BOOST_CHECK(constexpr_iota_res); + BOOST_CXX14_CONSTEXPR bool constexpr_iota_n_res = test_constexpr_iota_n (); + BOOST_CHECK(constexpr_iota_n_res); } diff --git a/test/is_partitioned_test1.cpp b/test/is_partitioned_test1.cpp index 835de2d..d538a06 100644 --- a/test/is_partitioned_test1.cpp +++ b/test/is_partitioned_test1.cpp @@ -25,16 +25,27 @@ namespace ba = boost::algorithm; template struct less_than { public: - less_than ( T foo ) : val ( foo ) {} - less_than ( const less_than &rhs ) : val ( rhs.val ) {} + BOOST_CXX14_CONSTEXPR less_than ( T foo ) : val ( foo ) {} + BOOST_CXX14_CONSTEXPR less_than ( const less_than &rhs ) : val ( rhs.val ) {} - bool operator () ( const T &v ) const { return v < val; } + BOOST_CXX14_CONSTEXPR bool operator () ( const T &v ) const { return v < val; } private: less_than (); less_than operator = ( const less_than &rhs ); T val; }; + +BOOST_CXX14_CONSTEXPR bool test_constexpr() { + int v[] = { 4, 5, 6, 7, 8, 9, 10 }; + bool res = true; + res = ( res && ba::is_partitioned ( v, less_than(3))); // no elements + res = ( res && ba::is_partitioned ( v, less_than(5))); // only the first element + res = ( res && ba::is_partitioned ( v, less_than(8))); // in the middle somewhere + res = ( res && ba::is_partitioned ( v, less_than(99))); // all elements + return res; + } + void test_sequence1 () { std::vector v; @@ -61,4 +72,6 @@ void test_sequence1 () { BOOST_AUTO_TEST_CASE( test_main ) { test_sequence1 (); + BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr (); + BOOST_CHECK ( constexpr_res ); } diff --git a/test/iterator_test.hpp b/test/iterator_test.hpp index a79e7cf..da54456 100644 --- a/test/iterator_test.hpp +++ b/test/iterator_test.hpp @@ -30,23 +30,23 @@ public: typedef It pointer; typedef typename std::iterator_traits::reference reference; - It base() const {return it_;} + BOOST_CXX14_CONSTEXPR It base() const {return it_;} - input_iterator() : it_() {} - explicit input_iterator(It it) : it_(it) {} + BOOST_CXX14_CONSTEXPR input_iterator() : it_() {} + BOOST_CXX14_CONSTEXPR explicit input_iterator(It it) : it_(it) {} template - input_iterator(const input_iterator& u) :it_(u.it_) {} + BOOST_CXX14_CONSTEXPR input_iterator(const input_iterator& u) :it_(u.it_) {} - reference operator*() const {return *it_;} - pointer operator->() const {return it_;} + BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;} + BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;} - input_iterator& operator++() {++it_; return *this;} - input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;} + BOOST_CXX14_CONSTEXPR input_iterator& operator++() {++it_; return *this;} + BOOST_CXX14_CONSTEXPR input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;} - friend bool operator==(const input_iterator& x, const input_iterator& y) + BOOST_CXX14_CONSTEXPR friend bool operator==(const input_iterator& x, const input_iterator& y) {return x.it_ == y.it_;} - friend bool operator!=(const input_iterator& x, const input_iterator& y) + BOOST_CXX14_CONSTEXPR friend bool operator!=(const input_iterator& x, const input_iterator& y) {return !(x == y);} private: @@ -55,14 +55,14 @@ private: }; template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator==(const input_iterator& x, const input_iterator& y) { return x.base() == y.base(); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator!=(const input_iterator& x, const input_iterator& y) { return !(x == y); @@ -79,22 +79,22 @@ public: typedef It pointer; typedef typename std::iterator_traits::reference reference; - It base() const {return it_;} + BOOST_CXX14_CONSTEXPR It base() const {return it_;} - forward_iterator() : it_() {} - explicit forward_iterator(It it) : it_(it) {} + BOOST_CXX14_CONSTEXPR forward_iterator() : it_() {} + BOOST_CXX14_CONSTEXPR explicit forward_iterator(It it) : it_(it) {} template - forward_iterator(const forward_iterator& u) :it_(u.it_) {} + BOOST_CXX14_CONSTEXPR forward_iterator(const forward_iterator& u) :it_(u.it_) {} - reference operator*() const {return *it_;} - pointer operator->() const {return it_;} + BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;} + BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;} - forward_iterator& operator++() {++it_; return *this;} - forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;} + BOOST_CXX14_CONSTEXPR forward_iterator& operator++() {++it_; return *this;} + BOOST_CXX14_CONSTEXPR forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;} - friend bool operator==(const forward_iterator& x, const forward_iterator& y) + BOOST_CXX14_CONSTEXPR friend bool operator==(const forward_iterator& x, const forward_iterator& y) {return x.it_ == y.it_;} - friend bool operator!=(const forward_iterator& x, const forward_iterator& y) + BOOST_CXX14_CONSTEXPR friend bool operator!=(const forward_iterator& x, const forward_iterator& y) {return !(x == y);} private: It it_; @@ -103,14 +103,14 @@ private: }; template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator==(const forward_iterator& x, const forward_iterator& y) { return x.base() == y.base(); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator!=(const forward_iterator& x, const forward_iterator& y) { return !(x == y); @@ -127,35 +127,35 @@ public: typedef It pointer; typedef typename std::iterator_traits::reference reference; - It base() const {return it_;} + BOOST_CXX14_CONSTEXPR It base() const {return it_;} - bidirectional_iterator() : it_() {} - explicit bidirectional_iterator(It it) : it_(it) {} + BOOST_CXX14_CONSTEXPR bidirectional_iterator() : it_() {} + BOOST_CXX14_CONSTEXPR explicit bidirectional_iterator(It it) : it_(it) {} template - bidirectional_iterator(const bidirectional_iterator& u) :it_(u.it_) {} + BOOST_CXX14_CONSTEXPR bidirectional_iterator(const bidirectional_iterator& u) :it_(u.it_) {} - reference operator*() const {return *it_;} - pointer operator->() const {return it_;} + BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;} + BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;} - bidirectional_iterator& operator++() {++it_; return *this;} - bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;} + BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator++() {++it_; return *this;} + BOOST_CXX14_CONSTEXPR bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;} - bidirectional_iterator& operator--() {--it_; return *this;} - bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;} + BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator--() {--it_; return *this;} + BOOST_CXX14_CONSTEXPR bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;} private: It it_; template friend class bidirectional_iterator; }; template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator==(const bidirectional_iterator& x, const bidirectional_iterator& y) { return x.base() == y.base(); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator!=(const bidirectional_iterator& x, const bidirectional_iterator& y) { return !(x == y); @@ -172,30 +172,30 @@ public: typedef It pointer; typedef typename std::iterator_traits::reference reference; - It base() const {return it_;} + BOOST_CXX14_CONSTEXPR It base() const {return it_;} - random_access_iterator() : it_() {} - explicit random_access_iterator(It it) : it_(it) {} + BOOST_CXX14_CONSTEXPR random_access_iterator() : it_() {} + BOOST_CXX14_CONSTEXPR explicit random_access_iterator(It it) : it_(it) {} template - random_access_iterator(const random_access_iterator& u) :it_(u.it_) {} + BOOST_CXX14_CONSTEXPR random_access_iterator(const random_access_iterator& u) :it_(u.it_) {} - reference operator*() const {return *it_;} - pointer operator->() const {return it_;} + BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;} + BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;} - random_access_iterator& operator++() {++it_; return *this;} - random_access_iterator operator++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;} + BOOST_CXX14_CONSTEXPR random_access_iterator& operator++() {++it_; return *this;} + BOOST_CXX14_CONSTEXPR random_access_iterator operator++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;} - random_access_iterator& operator--() {--it_; return *this;} - random_access_iterator operator--(int) {random_access_iterator tmp(*this); --(*this); return tmp;} + BOOST_CXX14_CONSTEXPR random_access_iterator& operator--() {--it_; return *this;} + BOOST_CXX14_CONSTEXPR random_access_iterator operator--(int) {random_access_iterator tmp(*this); --(*this); return tmp;} - random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;} - random_access_iterator operator+ (difference_type n) const {random_access_iterator tmp(*this); tmp += n; return tmp;} - friend random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;} + BOOST_CXX14_CONSTEXPR random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;} + BOOST_CXX14_CONSTEXPR random_access_iterator operator+ (difference_type n) const {random_access_iterator tmp(*this); tmp += n; return tmp;} + BOOST_CXX14_CONSTEXPR friend random_access_iterator operator+(difference_type n, random_access_iterator x) {x += n; return x;} - random_access_iterator& operator-=(difference_type n) {return *this += -n;} - random_access_iterator operator- (difference_type n) const {random_access_iterator tmp(*this); tmp -= n; return tmp;} + BOOST_CXX14_CONSTEXPR random_access_iterator& operator-=(difference_type n) {return *this += -n;} + BOOST_CXX14_CONSTEXPR random_access_iterator operator- (difference_type n) const {random_access_iterator tmp(*this); tmp -= n; return tmp;} - reference operator[](difference_type n) const {return it_[n];} + BOOST_CXX14_CONSTEXPR reference operator[](difference_type n) const {return it_[n];} private: It it_; @@ -203,49 +203,49 @@ private: }; template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator==(const random_access_iterator& x, const random_access_iterator& y) { return x.base() == y.base(); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator!=(const random_access_iterator& x, const random_access_iterator& y) { return !(x == y); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator<(const random_access_iterator& x, const random_access_iterator& y) { return x.base() < y.base(); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator<=(const random_access_iterator& x, const random_access_iterator& y) { return !(y < x); } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator>(const random_access_iterator& x, const random_access_iterator& y) { return y < x; } template -inline bool +BOOST_CXX14_CONSTEXPR inline bool operator>=(const random_access_iterator& x, const random_access_iterator& y) { return !(x < y); } template -inline typename std::iterator_traits::difference_type +BOOST_CXX14_CONSTEXPR inline typename std::iterator_traits::difference_type operator-(const random_access_iterator& x, const random_access_iterator& y) { return x.base() - y.base(); @@ -262,18 +262,18 @@ public: typedef It pointer; typedef typename std::iterator_traits::reference reference; - It base() const {return it_;} + BOOST_CXX14_CONSTEXPR It base() const {return it_;} - output_iterator () {} - explicit output_iterator(It it) : it_(it) {} + BOOST_CXX14_CONSTEXPR output_iterator () {} + BOOST_CXX14_CONSTEXPR explicit output_iterator(It it) : it_(it) {} template - output_iterator(const output_iterator& u) :it_(u.it_) {} + BOOST_CXX14_CONSTEXPR output_iterator(const output_iterator& u) :it_(u.it_) {} - reference operator*() const {return *it_;} + BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;} - output_iterator& operator++() {++it_; return *this;} - output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;} + BOOST_CXX14_CONSTEXPR output_iterator& operator++() {++it_; return *this;} + BOOST_CXX14_CONSTEXPR output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;} private: It it_; @@ -285,21 +285,21 @@ private: // == Get the base of an iterator; used for comparisons == template -inline Iter base(output_iterator i) { return i.base(); } +BOOST_CXX14_CONSTEXPR inline Iter base(output_iterator i) { return i.base(); } template -inline Iter base(input_iterator i) { return i.base(); } +BOOST_CXX14_CONSTEXPR inline Iter base(input_iterator i) { return i.base(); } template -inline Iter base(forward_iterator i) { return i.base(); } +BOOST_CXX14_CONSTEXPR inline Iter base(forward_iterator i) { return i.base(); } template -inline Iter base(bidirectional_iterator i) { return i.base(); } +BOOST_CXX14_CONSTEXPR inline Iter base(bidirectional_iterator i) { return i.base(); } template -inline Iter base(random_access_iterator i) { return i.base(); } +BOOST_CXX14_CONSTEXPR inline Iter base(random_access_iterator i) { return i.base(); } template // everything else -inline Iter base(Iter i) { return i; } +BOOST_CXX14_CONSTEXPR inline Iter base(Iter i) { return i; } #endif // ITERATORS_H diff --git a/test/mismatch_test.cpp b/test/mismatch_test.cpp index 61a7506..1c056c7 100644 --- a/test/mismatch_test.cpp +++ b/test/mismatch_test.cpp @@ -16,149 +16,176 @@ #include template -bool eq ( const T& a, const T& b ) { return a == b; } +BOOST_CXX14_CONSTEXPR bool eq ( const T& a, const T& b ) { return a == b; } template -bool never_eq ( const T&, const T& ) { return false; } +BOOST_CXX14_CONSTEXPR bool never_eq ( const T&, const T& ) { return false; } namespace ba = boost::algorithm; template -bool iter_eq ( std::pair pr, Iter1 first, Iter2 second ) { +BOOST_CXX14_CONSTEXPR bool iter_eq ( std::pair pr, Iter1 first, Iter2 second ) { return pr.first == first && pr.second == second; } void test_mismatch () { // Note: The literal values here are tested against directly, careful if you change them: - int num[] = { 1, 1, 2, 3, 5 }; + BOOST_CXX14_CONSTEXPR int num[] = { 1, 1, 2, 3, 5 }; const int sz = sizeof (num)/sizeof(num[0]); // No mismatch for empty sequences BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num), - input_iterator(num), input_iterator(num)), - input_iterator(num), input_iterator(num))); + ba::mismatch ( input_iterator(num), input_iterator(num), + input_iterator(num), input_iterator(num)), + input_iterator(num), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num), - input_iterator(num), input_iterator(num), + ba::mismatch ( input_iterator(num), input_iterator(num), + input_iterator(num), input_iterator(num), never_eq ), - input_iterator(num), input_iterator(num))); + input_iterator(num), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( random_access_iterator(num), random_access_iterator(num), - random_access_iterator(num), random_access_iterator(num), + ba::mismatch ( random_access_iterator(num), random_access_iterator(num), + random_access_iterator(num), random_access_iterator(num), never_eq ), - random_access_iterator(num), random_access_iterator(num))); + random_access_iterator(num), random_access_iterator(num))); // Empty vs. non-empty mismatch immediately BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num), - input_iterator(num), input_iterator(num + 1)), - input_iterator(num), input_iterator(num))); + ba::mismatch ( input_iterator(num), input_iterator(num), + input_iterator(num), input_iterator(num + 1)), + input_iterator(num), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num + 1), input_iterator(num + 2), - input_iterator(num), input_iterator(num)), - input_iterator(num + 1), input_iterator(num))); + ba::mismatch ( input_iterator(num + 1), input_iterator(num + 2), + input_iterator(num), input_iterator(num)), + input_iterator(num + 1), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( random_access_iterator(num + 1), random_access_iterator(num + 2), - random_access_iterator(num), random_access_iterator(num)), - random_access_iterator(num + 1), random_access_iterator(num))); + ba::mismatch ( random_access_iterator(num + 1), random_access_iterator(num + 2), + random_access_iterator(num), random_access_iterator(num)), + random_access_iterator(num + 1), random_access_iterator(num))); // Single element sequences are equal if they contain the same value BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + 1), - input_iterator(num), input_iterator(num + 1)), - input_iterator(num + 1), input_iterator(num + 1))); + ba::mismatch ( input_iterator(num), input_iterator(num + 1), + input_iterator(num), input_iterator(num + 1)), + input_iterator(num + 1), input_iterator(num + 1))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + 1), - input_iterator(num), input_iterator(num + 1), + ba::mismatch ( input_iterator(num), input_iterator(num + 1), + input_iterator(num), input_iterator(num + 1), eq ), - input_iterator(num + 1), input_iterator(num + 1))); + input_iterator(num + 1), input_iterator(num + 1))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( random_access_iterator(num), random_access_iterator(num + 1), - random_access_iterator(num), random_access_iterator(num + 1), + ba::mismatch ( random_access_iterator(num), random_access_iterator(num + 1), + random_access_iterator(num), random_access_iterator(num + 1), eq ), - random_access_iterator(num + 1), random_access_iterator(num + 1))); + random_access_iterator(num + 1), random_access_iterator(num + 1))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + 1), - input_iterator(num), input_iterator(num + 1), + ba::mismatch ( input_iterator(num), input_iterator(num + 1), + input_iterator(num), input_iterator(num + 1), never_eq ), - input_iterator(num), input_iterator(num))); + input_iterator(num), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( random_access_iterator(num), random_access_iterator(num + 1), - random_access_iterator(num), random_access_iterator(num + 1), + ba::mismatch ( random_access_iterator(num), random_access_iterator(num + 1), + random_access_iterator(num), random_access_iterator(num + 1), never_eq ), - random_access_iterator(num), random_access_iterator(num))); + random_access_iterator(num), random_access_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + 1), - input_iterator(num + 1), input_iterator(num + 2)), - input_iterator(num + 1), input_iterator(num + 2))); + ba::mismatch ( input_iterator(num), input_iterator(num + 1), + input_iterator(num + 1), input_iterator(num + 2)), + input_iterator(num + 1), input_iterator(num + 2))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + 1), - input_iterator(num + 1), input_iterator(num + 2), + ba::mismatch ( input_iterator(num), input_iterator(num + 1), + input_iterator(num + 1), input_iterator(num + 2), eq ), - input_iterator(num + 1), input_iterator(num + 2))); + input_iterator(num + 1), input_iterator(num + 2))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num + 2), input_iterator(num + 3), - input_iterator(num), input_iterator(num + 1)), - input_iterator(num + 2), input_iterator(num))); + ba::mismatch ( input_iterator(num + 2), input_iterator(num + 3), + input_iterator(num), input_iterator(num + 1)), + input_iterator(num + 2), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num + 2), input_iterator(num + 3), - input_iterator(num), input_iterator(num + 1), + ba::mismatch ( input_iterator(num + 2), input_iterator(num + 3), + input_iterator(num), input_iterator(num + 1), eq ), - input_iterator(num + 2), input_iterator(num))); + input_iterator(num + 2), input_iterator(num))); // Identical long sequences are equal. BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + sz), - input_iterator(num), input_iterator(num + sz)), - input_iterator(num + sz), input_iterator(num + sz))); + ba::mismatch ( input_iterator(num), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz)), + input_iterator(num + sz), input_iterator(num + sz))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + sz), - input_iterator(num), input_iterator(num + sz), + ba::mismatch ( input_iterator(num), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz), eq ), - input_iterator(num + sz), input_iterator(num + sz))); + input_iterator(num + sz), input_iterator(num + sz))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + sz), - input_iterator(num), input_iterator(num + sz), + ba::mismatch ( input_iterator(num), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz), never_eq ), - input_iterator(num), input_iterator(num))); + input_iterator(num), input_iterator(num))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num), input_iterator(num + sz), - random_access_iterator(num), random_access_iterator(num + sz), + ba::mismatch ( input_iterator(num), input_iterator(num + sz), + random_access_iterator(num), random_access_iterator(num + sz), never_eq ), - input_iterator(num), random_access_iterator(num))); + input_iterator(num), random_access_iterator(num))); -// different sequences are different +// Different sequences are different BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num + 1), input_iterator(num + sz), - input_iterator(num), input_iterator(num + sz)), - input_iterator(num + 2), input_iterator(num + 1))); + ba::mismatch ( input_iterator(num + 1), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz)), + input_iterator(num + 2), input_iterator(num + 1))); BOOST_CHECK ( iter_eq ( - ba::mismatch ( input_iterator(num + 1), input_iterator(num + sz), - input_iterator(num), input_iterator(num + sz), + ba::mismatch ( input_iterator(num + 1), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz), eq ), - input_iterator(num + 2), input_iterator(num + 1))); - + input_iterator(num + 2), input_iterator(num + 1))); + +// Checks constexpr + BOOST_CXX14_CONSTEXPR bool res = ( +// No mismatch for empty + iter_eq ( + ba::mismatch ( input_iterator(num), input_iterator(num), + input_iterator(num), input_iterator(num)), + input_iterator(num), input_iterator(num)) +// Empty vs. non-empty mismatch immediately + && iter_eq ( + ba::mismatch ( input_iterator(num), input_iterator(num), + input_iterator(num), input_iterator(num + 1)), + input_iterator(num), input_iterator(num)) +// Single element sequences are equal if they contain the same value + && iter_eq ( + ba::mismatch ( input_iterator(num), input_iterator(num + 1), + input_iterator(num), input_iterator(num + 1), + eq), + input_iterator(num + 1), input_iterator(num + 1)) +// Identical long sequences are equal. + && iter_eq ( + ba::mismatch ( input_iterator(num), input_iterator(num + sz), + input_iterator(num), input_iterator(num + sz), + eq ), + input_iterator(num + sz), input_iterator(num + sz)) + ); + + BOOST_CHECK ( res ); } diff --git a/test/none_of_test.cpp b/test/none_of_test.cpp index fc74945..dc7b30b 100644 --- a/test/none_of_test.cpp +++ b/test/none_of_test.cpp @@ -19,9 +19,9 @@ template struct is_ : public std::unary_function { - is_ ( T v ) : val_ ( v ) {} - ~is_ () {} - bool operator () ( T comp ) const { return val_ == comp; } + BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {} + + BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; } private: is_ (); // need a value @@ -33,7 +33,7 @@ namespace ba = boost::algorithm; void test_none() { // Note: The literal values here are tested against directly, careful if you change them: - int some_numbers[] = { 1, 5, 0, 18, 1 }; + BOOST_CXX14_CONSTEXPR int some_numbers[] = { 1, 5, 0, 18, 1 }; std::vector vi(some_numbers, some_numbers + 5); std::list li(vi.begin(), vi.end ()); @@ -89,6 +89,14 @@ void test_none() BOOST_CHECK ( ba::none_of_equal ( li.begin(), l_iter, 18 )); BOOST_CHECK ( ba::none_of ( li.begin(), l_iter, is_ ( 18 ))); BOOST_CHECK (!ba::none_of ( li.begin(), l_iter, is_ ( 5 ))); + + BOOST_CXX14_CONSTEXPR bool constexpr_res = ( + !ba::none_of_equal ( some_numbers, 1 ) + && !ba::none_of ( some_numbers, is_ ( 1 )) + && ba::none_of_equal ( some_numbers, some_numbers + 3, 100 ) + && ba::none_of ( some_numbers, some_numbers + 3, is_ ( 100 )) + ); + BOOST_CHECK ( constexpr_res ); } BOOST_AUTO_TEST_CASE( test_main ) diff --git a/test/one_of_test.cpp b/test/one_of_test.cpp index 9422881..49e3d5a 100644 --- a/test/one_of_test.cpp +++ b/test/one_of_test.cpp @@ -19,9 +19,9 @@ template struct is_ : public std::unary_function { - is_ ( T v ) : val_ ( v ) {} - ~is_ () {} - bool operator () ( T comp ) const { return val_ == comp; } + BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {} + + BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; } private: is_ (); // need a value @@ -33,7 +33,7 @@ namespace ba = boost::algorithm; void test_one () { // Note: The literal values here are tested against directly, careful if you change them: - int some_numbers[] = { 1, 1, 2, 3, 5 }; + BOOST_CXX14_CONSTEXPR int some_numbers[] = { 1, 1, 2, 3, 5 }; std::vector vi(some_numbers, some_numbers + 5); std::list li(vi.begin(), vi.end ()); @@ -92,7 +92,13 @@ void test_one () BOOST_CHECK ( ba::one_of ( li.begin(), l_iter, is_ ( 2 ))); BOOST_CHECK (!ba::one_of_equal ( li.begin(), l_iter, 3 )); BOOST_CHECK (!ba::one_of ( li.begin(), l_iter, is_ ( 3 ))); + + BOOST_CXX14_CONSTEXPR bool constexpr_res = ( + !ba::one_of ( some_numbers, is_ ( 6 )) + && ba::one_of ( some_numbers, some_numbers + 3, is_ ( 1 )) + ); + BOOST_CHECK ( constexpr_res ); } diff --git a/test/ordered_test.cpp b/test/ordered_test.cpp index dbaf940..f2cbdd7 100644 --- a/test/ordered_test.cpp +++ b/test/ordered_test.cpp @@ -29,11 +29,13 @@ using namespace boost; namespace ba = boost::algorithm; +BOOST_CXX14_CONSTEXPR bool less( int x, int y ) { return x < y; } + static void test_ordered(void) { - const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 }; - const int randomValues[] = { 3, 6, 1, 2, 7 }; + BOOST_CXX14_CONSTEXPR const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 }; + BOOST_CXX14_CONSTEXPR const int randomValues[] = { 3, 6, 1, 2, 7 }; const int constantValues[] = { 1, 2, 2, 2, 5 }; int nonConstantArray[] = { 1, 2, 2, 2, 5 }; const int inOrderUntilTheEnd [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6 }; @@ -74,18 +76,26 @@ test_ordered(void) BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues)) == a_begin(randomValues)); BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1, std::equal_to()) == a_begin(randomValues) + 1); BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1 ) == a_begin(randomValues) + 1); + + BOOST_CXX14_CONSTEXPR bool constexpr_res = ( + ba::is_sorted ( boost::begin(strictlyIncreasingValues), boost::end(strictlyIncreasingValues) ) + && !ba::is_sorted (a_range(randomValues)) + && ba::is_sorted_until ( boost::begin(strictlyIncreasingValues), boost::end(strictlyIncreasingValues), less) == a_end(strictlyIncreasingValues) + && ba::is_sorted_until ( randomValues, less) == &randomValues[2] + ); + BOOST_CHECK ( constexpr_res ); } static void test_increasing_decreasing(void) { - const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 }; - const int strictlyDecreasingValues[] = { 9, 8, 7, 6, 5 }; - const int increasingValues[] = { 1, 2, 2, 2, 5 }; - const int decreasingValues[] = { 9, 7, 7, 7, 5 }; - const int randomValues[] = { 3, 6, 1, 2, 7 }; - const int constantValues[] = { 7, 7, 7, 7, 7 }; + BOOST_CXX14_CONSTEXPR const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 }; + BOOST_CXX14_CONSTEXPR const int strictlyDecreasingValues[] = { 9, 8, 7, 6, 5 }; + BOOST_CXX14_CONSTEXPR const int increasingValues[] = { 1, 2, 2, 2, 5 }; + BOOST_CXX14_CONSTEXPR const int decreasingValues[] = { 9, 7, 7, 7, 5 }; + BOOST_CXX14_CONSTEXPR const int randomValues[] = { 3, 6, 1, 2, 7 }; + BOOST_CXX14_CONSTEXPR const int constantValues[] = { 7, 7, 7, 7, 7 }; // Test a strictly increasing sequence BOOST_CHECK ( ba::is_strictly_increasing (b_e(strictlyIncreasingValues))); @@ -146,6 +156,15 @@ test_increasing_decreasing(void) BOOST_CHECK ( !ba::is_strictly_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+2)); BOOST_CHECK ( !ba::is_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+2)); + BOOST_CXX14_CONSTEXPR bool constexpr_res = ( + ba::is_increasing (boost::begin(increasingValues), boost::end(increasingValues)) + && ba::is_decreasing (boost::begin(decreasingValues), boost::end(decreasingValues)) + && ba::is_strictly_increasing (boost::begin(strictlyIncreasingValues), boost::end(strictlyIncreasingValues)) + && ba::is_strictly_decreasing (boost::begin(strictlyDecreasingValues), boost::end(strictlyDecreasingValues)) + && !ba::is_strictly_increasing (boost::begin(increasingValues), boost::end(increasingValues)) + && !ba::is_strictly_decreasing (boost::begin(decreasingValues), boost::end(decreasingValues)) + ); + BOOST_CHECK ( constexpr_res ); } BOOST_AUTO_TEST_CASE( test_main ) diff --git a/test/partition_copy_test1.cpp b/test/partition_copy_test1.cpp index c3afb1e..4499f40 100644 --- a/test/partition_copy_test1.cpp +++ b/test/partition_copy_test1.cpp @@ -47,10 +47,10 @@ void test_sequence ( const Container &c, Predicate comp ) { template struct less_than { public: - less_than ( T foo ) : val ( foo ) {} - less_than ( const less_than &rhs ) : val ( rhs.val ) {} + BOOST_CXX14_CONSTEXPR less_than ( T foo ) : val ( foo ) {} + BOOST_CXX14_CONSTEXPR less_than ( const less_than &rhs ) : val ( rhs.val ) {} - bool operator () ( const T &v ) const { return v < val; } + BOOST_CXX14_CONSTEXPR bool operator () ( const T &v ) const { return v < val; } private: less_than (); less_than operator = ( const less_than &rhs ); @@ -81,8 +81,30 @@ void test_sequence1 () { } + +BOOST_CXX14_CONSTEXPR bool test_constexpr () { + int in[] = {1, 1, 2}; + int out_true[3] = {0}; + int out_false[3] = {0}; + bool res = true; + ba::partition_copy( in, in + 3, out_true, out_false, less_than(2) ); + res = (res && ba::all_of(out_true, out_true + 2, less_than(2)) ); + res = (res && ba::none_of(out_false, out_false + 1, less_than(2)) ); + +// clear elements + out_true [0] = 0; + out_true [1] = 0; + out_false[0] = 0; + + ba::partition_copy( in, out_true, out_false, less_than(2)); + res = ( res && ba::all_of(out_true, out_true + 2, less_than(2))); + res = ( res && ba::none_of(out_false, out_false + 1, less_than(2))); + return res; + } BOOST_AUTO_TEST_CASE( test_main ) { test_sequence1 (); + BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr (); + BOOST_CHECK ( constexpr_res ); } diff --git a/test/power_test.cpp b/test/power_test.cpp index c1d5c23..c608a8b 100644 --- a/test/power_test.cpp +++ b/test/power_test.cpp @@ -18,7 +18,7 @@ namespace ba = boost::algorithm; -BOOST_AUTO_TEST_CASE( test_main ) +void test_power () { BOOST_CHECK ( ba::power(0, 0) == 1); BOOST_CHECK ( ba::power(5, 0) == 1); @@ -34,3 +34,51 @@ BOOST_AUTO_TEST_CASE( test_main ) BOOST_CHECK ( ba::power(3,2) == ba::power(3,2, std::multiplies())); BOOST_CHECK ( ba::power(3,2, std::plus()) == 6); } + + +void test_power_constexpr () +{ + BOOST_CXX14_CONSTEXPR bool check_zero_power1 = + ba::power(0, 0) == 1; + BOOST_CHECK(check_zero_power1); + BOOST_CXX14_CONSTEXPR bool check_zero_power2 = + ba::power(5, 0) == 1; + BOOST_CHECK(check_zero_power2); + BOOST_CXX14_CONSTEXPR bool check_one_base1 = + ba::power(1, 1) == 1; + BOOST_CHECK(check_one_base1); + BOOST_CXX14_CONSTEXPR bool check_one_base2 = + ba::power(1, 4) == 1; + BOOST_CHECK(check_one_base2); + BOOST_CXX14_CONSTEXPR bool check_power1 = + ba::power(3, 2) == 9; + BOOST_CHECK(check_power1); + BOOST_CXX14_CONSTEXPR bool check_power2 = + ba::power(2, 3) == 8; + BOOST_CHECK(check_power2); + BOOST_CXX14_CONSTEXPR bool check_power3 = + ba::power(3, 3) == 27; + BOOST_CHECK(check_power1); + BOOST_CXX14_CONSTEXPR bool check_power4 = + ba::power(2, 30) == 0x40000000; + BOOST_CHECK(check_power4); + BOOST_CXX14_CONSTEXPR bool check_power5 = + ba::power(5L, 10) == 3125*3125; + BOOST_CHECK(check_power5); + BOOST_CXX14_CONSTEXPR bool check_power6 = + ba::power(18, 3) == 18*18*18; + BOOST_CHECK(check_power6); + + BOOST_CXX14_CONSTEXPR bool check_multiple = + ba::power(3, 2, std::multiplies()) == ba::power(3, 2); + BOOST_CHECK(check_multiple); + BOOST_CXX14_CONSTEXPR bool check_plus = + ba::power(3, 2, std::plus()) == 6; + BOOST_CHECK(check_plus); +} + + +BOOST_AUTO_TEST_CASE( test_main ) { + test_power (); + test_power_constexpr (); +}