Updated constexpr tests for all affected modules. Added conditional constexpr to equal, which uses std::distance.

This commit is contained in:
MMaximoff
2017-04-07 22:31:23 +03:00
parent 8d095e9d30
commit dfa332e915
15 changed files with 625 additions and 185 deletions

View File

@ -15,6 +15,13 @@
#include <algorithm> // for std::equal #include <algorithm> // for std::equal
#include <functional> // for std::equal_to #include <functional> // 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 boost { namespace algorithm {
namespace detail { namespace detail {
@ -25,6 +32,7 @@ namespace detail {
}; };
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate> template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
BOOST_CONSTEXPR_IF_STD_CONSTEXPR
bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1, bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
std::random_access_iterator_tag, std::random_access_iterator_tag ) std::random_access_iterator_tag, std::random_access_iterator_tag )
@ -37,7 +45,8 @@ namespace detail {
} }
template <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
BOOST_CXX14_CONSTEXPR bool equal ( InputIterator1 first1, InputIterator1 last1, BOOST_CXX14_CONSTEXPR
bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred,
std::input_iterator_tag, std::input_iterator_tag ) 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 last2 One past the end of the second range.
/// \param pred A predicate for comparing the elements of the ranges /// \param pred A predicate for comparing the elements of the ranges
template <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
BOOST_CXX14_CONSTEXPR
bool equal ( InputIterator1 first1, InputIterator1 last1, bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred ) 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 first2 The start of the second range.
/// \param last2 One past the end of the second range. /// \param last2 One past the end of the second range.
template <class InputIterator1, class InputIterator2> template <class InputIterator1, class InputIterator2>
BOOST_CXX14_CONSTEXPR
bool equal ( InputIterator1 first1, InputIterator1 last1, bool equal ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 ) InputIterator2 first2, InputIterator2 last2 )
{ {

View File

@ -210,6 +210,110 @@ void test_int_range ()
BOOST_CHECK ( std::equal ( b_e(junk), outputs )); 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 ) BOOST_AUTO_TEST_CASE( test_main )
{ {
test_ints (); test_ints ();
@ -217,6 +321,8 @@ BOOST_AUTO_TEST_CASE( test_main )
test_custom (); test_custom ();
test_int_range (); test_int_range ();
test_constexpr ();
// test_float_range (); // test_float_range ();
// test_custom_range (); // test_custom_range ();
} }

View File

@ -10,6 +10,8 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/algorithm/cxx11/copy_if.hpp> #include <boost/algorithm/cxx11/copy_if.hpp>
#include "iterator_test.hpp"
#define BOOST_TEST_MAIN #define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -20,6 +22,7 @@
#include <list> #include <list>
#include <boost/algorithm/cxx11/all_of.hpp> #include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/algorithm/cxx14/equal.hpp>
#include <boost/algorithm/cxx11/none_of.hpp> #include <boost/algorithm/cxx11/none_of.hpp>
namespace ba = boost::algorithm; 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_false ( int v ) { return false; }
BOOST_CXX14_CONSTEXPR bool is_even ( int v ) { return v % 2 == 0; } 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_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 <typename Container> template <typename Container>
void test_copy_if ( Container const &c ) { void test_copy_if ( Container const &c ) {
@ -171,6 +161,71 @@ void test_copy_until ( Container const &c ) {
BOOST_CHECK ( std::equal ( v.begin (), v.end (), c.begin ())); 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<const int *>(out_data), input_iterator<const int *>(out_data + sz),
input_iterator<const int *>(from), input_iterator<const int *>(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<const int *>(out_data), input_iterator<const int *>(out_data + sz),
input_iterator<const int *>(from), input_iterator<const int *>(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<const int *>(out_data), input_iterator<const int *>(out_data + sz),
input_iterator<const int *>(from), input_iterator<const int *>(to)));
return res;
}
void test_sequence1 () { void test_sequence1 () {
std::vector<int> v; std::vector<int> v;
for ( int i = 5; i < 15; ++i ) for ( int i = 5; i < 15; ++i )
@ -179,8 +234,12 @@ void test_sequence1 () {
test_copy_while ( v ); test_copy_while ( v );
test_copy_until ( v ); test_copy_until ( v );
BOOST_CXX14_CONSTEXPR bool constexpr_res = constexpr_helper(0, 0); BOOST_CXX14_CONSTEXPR bool constexpr_res_if = constexpr_test_copy_if();
BOOST_CHECK ( constexpr_res ); 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<int> l; std::list<int> l;
for ( int i = 25; i > 15; --i ) for ( int i = 25; i > 15; --i )

View File

@ -9,6 +9,10 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/algorithm/cxx11/copy_n.hpp> #include <boost/algorithm/cxx11/copy_n.hpp>
#include <boost/algorithm/cxx14/equal.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include "iterator_test.hpp"
#define BOOST_TEST_MAIN #define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -21,6 +25,8 @@
namespace ba = boost::algorithm; namespace ba = boost::algorithm;
// namespace ba = boost; // namespace ba = boost;
BOOST_CXX14_CONSTEXPR bool is_zero( int v ) { return v == 0; }
template <typename Container> template <typename Container>
void test_sequence ( Container const &c ) { 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<const int *>(out_data), input_iterator<const int *>(out_data + sz),
input_iterator<const int *>(from), input_iterator<const int *>(to)));
return res;
}
void test_sequence1 () { void test_sequence1 () {
std::vector<int> v; std::vector<int> v;
for ( int i = 5; i < 15; ++i ) for ( int i = 5; i < 15; ++i )
v.push_back ( i ); v.push_back ( i );
test_sequence ( v ); test_sequence ( v );
BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr();
BOOST_CHECK(constexpr_res);
std::list<int> l; std::list<int> l;
for ( int i = 25; i > 15; --i ) for ( int i = 25; i > 15; --i )
l.push_back ( i ); l.push_back ( i );

View File

@ -16,7 +16,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
template <typename T> template <typename T>
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 <typename T> template <typename T>
bool never_eq ( const T&, const T& ) { return false; } 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<int *>(num), input_iterator<int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num))
// Identical long sequences are equal
&& ba::equal ( input_iterator<int *>(num), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz),
eq<int> )
// Different sequences are different
&& !ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(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<int *>(num), random_access_iterator<int *>(num),
random_access_iterator<int *>(num), random_access_iterator<int *>(num))
// Identical long sequences are equal
&& ba::equal ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz),
eq<int> )
// Different sequences are different
&& !ba::equal ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + sz),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz))
);
#endif
return res;
}
BOOST_AUTO_TEST_CASE( test_main ) BOOST_AUTO_TEST_CASE( test_main )
{ {
test_equal (); test_equal ();
BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr_equal ();
BOOST_CHECK (constexpr_res);
} }

View File

@ -22,6 +22,29 @@
namespace ba = boost::algorithm; namespace ba = boost::algorithm;
// namespace ba = boost; // 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> template <typename Container>
typename Container::iterator offset_to_iter ( Container &v, int offset ) { typename Container::iterator offset_to_iter ( Container &v, int offset ) {
typename Container::iterator retval; typename Container::iterator retval;

View File

@ -20,7 +20,7 @@
// Test to make sure a sequence is "correctly formed"; i.e, ascending by one // Test to make sure a sequence is "correctly formed"; i.e, ascending by one
template <typename Iterator, typename T> template <typename Iterator, typename T>
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 ( first == last ) return true;
if ( initial_value != *first ) return false; if ( initial_value != *first ) return false;
Iterator prev = first; Iterator prev = first;
@ -32,8 +32,9 @@ bool test_iota_results ( Iterator first, Iterator last, T initial_value ) {
return true; return true;
} }
template <typename Range, typename T> template <typename Range, typename T>
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 ); return test_iota_results (boost::begin (r), boost::end (r), initial_value );
} }
@ -77,8 +78,37 @@ void test_ints () {
BOOST_CHECK ( test_iota_results ( l.rbegin (), l.rend (), 123 )); 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 ) BOOST_AUTO_TEST_CASE( test_main )
{ {
test_ints (); 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);
} }

View File

@ -25,10 +25,10 @@ namespace ba = boost::algorithm;
template <typename T> template <typename T>
struct less_than { struct less_than {
public: public:
less_than ( T foo ) : val ( foo ) {} BOOST_CXX14_CONSTEXPR less_than ( T foo ) : val ( foo ) {}
less_than ( const less_than &rhs ) : val ( rhs.val ) {} 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: private:
less_than (); less_than ();
less_than operator = ( const less_than &rhs ); less_than operator = ( const less_than &rhs );
@ -36,6 +36,17 @@ private:
}; };
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<int>(3))); // no elements
res = ( res && ba::is_partitioned ( v, less_than<int>(5))); // only the first element
res = ( res && ba::is_partitioned ( v, less_than<int>(8))); // in the middle somewhere
res = ( res && ba::is_partitioned ( v, less_than<int>(99))); // all elements
return res;
}
void test_sequence1 () { void test_sequence1 () {
std::vector<int> v; std::vector<int> v;
@ -61,4 +72,6 @@ void test_sequence1 () {
BOOST_AUTO_TEST_CASE( test_main ) BOOST_AUTO_TEST_CASE( test_main )
{ {
test_sequence1 (); test_sequence1 ();
BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr ();
BOOST_CHECK ( constexpr_res );
} }

View File

@ -30,23 +30,23 @@ public:
typedef It pointer; typedef It pointer;
typedef typename std::iterator_traits<It>::reference reference; typedef typename std::iterator_traits<It>::reference reference;
It base() const {return it_;} BOOST_CXX14_CONSTEXPR It base() const {return it_;}
input_iterator() : it_() {} BOOST_CXX14_CONSTEXPR input_iterator() : it_() {}
explicit input_iterator(It it) : it_(it) {} BOOST_CXX14_CONSTEXPR explicit input_iterator(It it) : it_(it) {}
template <typename U> template <typename U>
input_iterator(const input_iterator<U>& u) :it_(u.it_) {} BOOST_CXX14_CONSTEXPR input_iterator(const input_iterator<U>& u) :it_(u.it_) {}
reference operator*() const {return *it_;} BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
pointer operator->() const {return it_;} BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
input_iterator& operator++() {++it_; return *this;} BOOST_CXX14_CONSTEXPR input_iterator& operator++() {++it_; return *this;}
input_iterator operator++(int) {input_iterator tmp(*this); ++(*this); return tmp;} 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_;} {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);} {return !(x == y);}
private: private:
@ -55,14 +55,14 @@ private:
}; };
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator==(const input_iterator<T>& x, const input_iterator<U>& y) operator==(const input_iterator<T>& x, const input_iterator<U>& y)
{ {
return x.base() == y.base(); return x.base() == y.base();
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator!=(const input_iterator<T>& x, const input_iterator<U>& y) operator!=(const input_iterator<T>& x, const input_iterator<U>& y)
{ {
return !(x == y); return !(x == y);
@ -79,22 +79,22 @@ public:
typedef It pointer; typedef It pointer;
typedef typename std::iterator_traits<It>::reference reference; typedef typename std::iterator_traits<It>::reference reference;
It base() const {return it_;} BOOST_CXX14_CONSTEXPR It base() const {return it_;}
forward_iterator() : it_() {} BOOST_CXX14_CONSTEXPR forward_iterator() : it_() {}
explicit forward_iterator(It it) : it_(it) {} BOOST_CXX14_CONSTEXPR explicit forward_iterator(It it) : it_(it) {}
template <typename U> template <typename U>
forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {} BOOST_CXX14_CONSTEXPR forward_iterator(const forward_iterator<U>& u) :it_(u.it_) {}
reference operator*() const {return *it_;} BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
pointer operator->() const {return it_;} BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
forward_iterator& operator++() {++it_; return *this;} BOOST_CXX14_CONSTEXPR forward_iterator& operator++() {++it_; return *this;}
forward_iterator operator++(int) {forward_iterator tmp(*this); ++(*this); return tmp;} 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_;} {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);} {return !(x == y);}
private: private:
It it_; It it_;
@ -103,14 +103,14 @@ private:
}; };
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator==(const forward_iterator<T>& x, const forward_iterator<U>& y) operator==(const forward_iterator<T>& x, const forward_iterator<U>& y)
{ {
return x.base() == y.base(); return x.base() == y.base();
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y) operator!=(const forward_iterator<T>& x, const forward_iterator<U>& y)
{ {
return !(x == y); return !(x == y);
@ -127,35 +127,35 @@ public:
typedef It pointer; typedef It pointer;
typedef typename std::iterator_traits<It>::reference reference; typedef typename std::iterator_traits<It>::reference reference;
It base() const {return it_;} BOOST_CXX14_CONSTEXPR It base() const {return it_;}
bidirectional_iterator() : it_() {} BOOST_CXX14_CONSTEXPR bidirectional_iterator() : it_() {}
explicit bidirectional_iterator(It it) : it_(it) {} BOOST_CXX14_CONSTEXPR explicit bidirectional_iterator(It it) : it_(it) {}
template <typename U> template <typename U>
bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {} BOOST_CXX14_CONSTEXPR bidirectional_iterator(const bidirectional_iterator<U>& u) :it_(u.it_) {}
reference operator*() const {return *it_;} BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
pointer operator->() const {return it_;} BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
bidirectional_iterator& operator++() {++it_; return *this;} BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator++() {++it_; return *this;}
bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;} BOOST_CXX14_CONSTEXPR bidirectional_iterator operator++(int) {bidirectional_iterator tmp(*this); ++(*this); return tmp;}
bidirectional_iterator& operator--() {--it_; return *this;} BOOST_CXX14_CONSTEXPR bidirectional_iterator& operator--() {--it_; return *this;}
bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;} BOOST_CXX14_CONSTEXPR bidirectional_iterator operator--(int) {bidirectional_iterator tmp(*this); --(*this); return tmp;}
private: private:
It it_; It it_;
template <typename U> friend class bidirectional_iterator; template <typename U> friend class bidirectional_iterator;
}; };
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y) operator==(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
{ {
return x.base() == y.base(); return x.base() == y.base();
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y) operator!=(const bidirectional_iterator<T>& x, const bidirectional_iterator<U>& y)
{ {
return !(x == y); return !(x == y);
@ -172,30 +172,30 @@ public:
typedef It pointer; typedef It pointer;
typedef typename std::iterator_traits<It>::reference reference; typedef typename std::iterator_traits<It>::reference reference;
It base() const {return it_;} BOOST_CXX14_CONSTEXPR It base() const {return it_;}
random_access_iterator() : it_() {} BOOST_CXX14_CONSTEXPR random_access_iterator() : it_() {}
explicit random_access_iterator(It it) : it_(it) {} BOOST_CXX14_CONSTEXPR explicit random_access_iterator(It it) : it_(it) {}
template <typename U> template <typename U>
random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {} BOOST_CXX14_CONSTEXPR random_access_iterator(const random_access_iterator<U>& u) :it_(u.it_) {}
reference operator*() const {return *it_;} BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
pointer operator->() const {return it_;} BOOST_CXX14_CONSTEXPR pointer operator->() const {return it_;}
random_access_iterator& operator++() {++it_; return *this;} BOOST_CXX14_CONSTEXPR 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++(int) {random_access_iterator tmp(*this); ++(*this); return tmp;}
random_access_iterator& operator--() {--it_; return *this;} BOOST_CXX14_CONSTEXPR 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--(int) {random_access_iterator tmp(*this); --(*this); return tmp;}
random_access_iterator& operator+=(difference_type n) {it_ += n; return *this;} BOOST_CXX14_CONSTEXPR 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;} BOOST_CXX14_CONSTEXPR 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 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;} BOOST_CXX14_CONSTEXPR 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) 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: private:
It it_; It it_;
@ -203,49 +203,49 @@ private:
}; };
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator==(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return x.base() == y.base(); return x.base() == y.base();
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator!=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return !(x == y); return !(x == y);
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator<(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return x.base() < y.base(); return x.base() < y.base();
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator<=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return !(y < x); return !(y < x);
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator>(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return y < x; return y < x;
} }
template <typename T, typename U> template <typename T, typename U>
inline bool BOOST_CXX14_CONSTEXPR inline bool
operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator>=(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return !(x < y); return !(x < y);
} }
template <typename T, typename U> template <typename T, typename U>
inline typename std::iterator_traits<T>::difference_type BOOST_CXX14_CONSTEXPR inline typename std::iterator_traits<T>::difference_type
operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y) operator-(const random_access_iterator<T>& x, const random_access_iterator<U>& y)
{ {
return x.base() - y.base(); return x.base() - y.base();
@ -262,18 +262,18 @@ public:
typedef It pointer; typedef It pointer;
typedef typename std::iterator_traits<It>::reference reference; typedef typename std::iterator_traits<It>::reference reference;
It base() const {return it_;} BOOST_CXX14_CONSTEXPR It base() const {return it_;}
output_iterator () {} BOOST_CXX14_CONSTEXPR output_iterator () {}
explicit output_iterator(It it) : it_(it) {} BOOST_CXX14_CONSTEXPR explicit output_iterator(It it) : it_(it) {}
template <typename U> template <typename U>
output_iterator(const output_iterator<U>& u) :it_(u.it_) {} BOOST_CXX14_CONSTEXPR output_iterator(const output_iterator<U>& u) :it_(u.it_) {}
reference operator*() const {return *it_;} BOOST_CXX14_CONSTEXPR reference operator*() const {return *it_;}
output_iterator& operator++() {++it_; return *this;} BOOST_CXX14_CONSTEXPR output_iterator& operator++() {++it_; return *this;}
output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;} BOOST_CXX14_CONSTEXPR output_iterator operator++(int) {output_iterator tmp(*this); ++(*this); return tmp;}
private: private:
It it_; It it_;
@ -285,21 +285,21 @@ private:
// == Get the base of an iterator; used for comparisons == // == Get the base of an iterator; used for comparisons ==
template <typename Iter> template <typename Iter>
inline Iter base(output_iterator<Iter> i) { return i.base(); } BOOST_CXX14_CONSTEXPR inline Iter base(output_iterator<Iter> i) { return i.base(); }
template <typename Iter> template <typename Iter>
inline Iter base(input_iterator<Iter> i) { return i.base(); } BOOST_CXX14_CONSTEXPR inline Iter base(input_iterator<Iter> i) { return i.base(); }
template <typename Iter> template <typename Iter>
inline Iter base(forward_iterator<Iter> i) { return i.base(); } BOOST_CXX14_CONSTEXPR inline Iter base(forward_iterator<Iter> i) { return i.base(); }
template <typename Iter> template <typename Iter>
inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); } BOOST_CXX14_CONSTEXPR inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
template <typename Iter> template <typename Iter>
inline Iter base(random_access_iterator<Iter> i) { return i.base(); } BOOST_CXX14_CONSTEXPR inline Iter base(random_access_iterator<Iter> i) { return i.base(); }
template <typename Iter> // everything else template <typename Iter> // everything else
inline Iter base(Iter i) { return i; } BOOST_CXX14_CONSTEXPR inline Iter base(Iter i) { return i; }
#endif // ITERATORS_H #endif // ITERATORS_H

View File

@ -16,149 +16,176 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
template <typename T> template <typename T>
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 <typename T> template <typename T>
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; namespace ba = boost::algorithm;
template <typename Iter1, typename Iter2> template <typename Iter1, typename Iter2>
bool iter_eq ( std::pair<Iter1, Iter2> pr, Iter1 first, Iter2 second ) { BOOST_CXX14_CONSTEXPR bool iter_eq ( std::pair<Iter1, Iter2> pr, Iter1 first, Iter2 second ) {
return pr.first == first && pr.second == second; return pr.first == first && pr.second == second;
} }
void test_mismatch () void test_mismatch ()
{ {
// Note: The literal values here are tested against directly, careful if you change them: // 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]); const int sz = sizeof (num)/sizeof(num[0]);
// No mismatch for empty sequences // No mismatch for empty sequences
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num)), input_iterator<const int *>(num), input_iterator<const int *>(num)),
input_iterator<int *>(num), input_iterator<int *>(num))); input_iterator<const int *>(num), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num), input_iterator<const int *>(num), input_iterator<const int *>(num),
never_eq<int> ), never_eq<int> ),
input_iterator<int *>(num), input_iterator<int *>(num))); input_iterator<const int *>(num), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( random_access_iterator<int *>(num), random_access_iterator<int *>(num), ba::mismatch ( random_access_iterator<const int *>(num), random_access_iterator<const int *>(num),
random_access_iterator<int *>(num), random_access_iterator<int *>(num), random_access_iterator<const int *>(num), random_access_iterator<const int *>(num),
never_eq<int> ), never_eq<int> ),
random_access_iterator<int *>(num), random_access_iterator<int *>(num))); random_access_iterator<const int *>(num), random_access_iterator<const int *>(num)));
// Empty vs. non-empty mismatch immediately // Empty vs. non-empty mismatch immediately
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num),
input_iterator<int *>(num), input_iterator<int *>(num + 1)), input_iterator<const int *>(num), input_iterator<const int *>(num + 1)),
input_iterator<int *>(num), input_iterator<int *>(num))); input_iterator<const int *>(num), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num + 1), input_iterator<int *>(num + 2), ba::mismatch ( input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 2),
input_iterator<int *>(num), input_iterator<int *>(num)), input_iterator<const int *>(num), input_iterator<const int *>(num)),
input_iterator<int *>(num + 1), input_iterator<int *>(num))); input_iterator<const int *>(num + 1), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2), ba::mismatch ( random_access_iterator<const int *>(num + 1), random_access_iterator<const int *>(num + 2),
random_access_iterator<int *>(num), random_access_iterator<int *>(num)), random_access_iterator<const int *>(num), random_access_iterator<const int *>(num)),
random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num))); random_access_iterator<const int *>(num + 1), random_access_iterator<const int *>(num)));
// Single element sequences are equal if they contain the same value // Single element sequences are equal if they contain the same value
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1)), input_iterator<const int *>(num), input_iterator<const int *>(num + 1)),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 1))); input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 1)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1), input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
eq<int> ), eq<int> ),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 1))); input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 1)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1), ba::mismatch ( random_access_iterator<const int *>(num), random_access_iterator<const int *>(num + 1),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1), random_access_iterator<const int *>(num), random_access_iterator<const int *>(num + 1),
eq<int> ), eq<int> ),
random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 1))); random_access_iterator<const int *>(num + 1), random_access_iterator<const int *>(num + 1)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
input_iterator<int *>(num), input_iterator<int *>(num + 1), input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
never_eq<int> ), never_eq<int> ),
input_iterator<int *>(num), input_iterator<int *>(num))); input_iterator<const int *>(num), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1), ba::mismatch ( random_access_iterator<const int *>(num), random_access_iterator<const int *>(num + 1),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + 1), random_access_iterator<const int *>(num), random_access_iterator<const int *>(num + 1),
never_eq<int> ), never_eq<int> ),
random_access_iterator<int *>(num), random_access_iterator<int *>(num))); random_access_iterator<const int *>(num), random_access_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)), input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 2)),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2))); input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 2)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + 1), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2), input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 2),
eq<int> ), eq<int> ),
input_iterator<int *>(num + 1), input_iterator<int *>(num + 2))); input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 2)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3), ba::mismatch ( input_iterator<const int *>(num + 2), input_iterator<const int *>(num + 3),
input_iterator<int *>(num), input_iterator<int *>(num + 1)), input_iterator<const int *>(num), input_iterator<const int *>(num + 1)),
input_iterator<int *>(num + 2), input_iterator<int *>(num))); input_iterator<const int *>(num + 2), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3), ba::mismatch ( input_iterator<const int *>(num + 2), input_iterator<const int *>(num + 3),
input_iterator<int *>(num), input_iterator<int *>(num + 1), input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
eq<int> ), eq<int> ),
input_iterator<int *>(num + 2), input_iterator<int *>(num))); input_iterator<const int *>(num + 2), input_iterator<const int *>(num)));
// Identical long sequences are equal. // Identical long sequences are equal.
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz)), input_iterator<const int *>(num), input_iterator<const int *>(num + sz)),
input_iterator<int *>(num + sz), input_iterator<int *>(num + sz))); input_iterator<const int *>(num + sz), input_iterator<const int *>(num + sz)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz), input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
eq<int> ), eq<int> ),
input_iterator<int *>(num + sz), input_iterator<int *>(num + sz))); input_iterator<const int *>(num + sz), input_iterator<const int *>(num + sz)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz), input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
never_eq<int> ), never_eq<int> ),
input_iterator<int *>(num), input_iterator<int *>(num))); input_iterator<const int *>(num), input_iterator<const int *>(num)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num), input_iterator<int *>(num + sz), ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
random_access_iterator<int *>(num), random_access_iterator<int *>(num + sz), random_access_iterator<const int *>(num), random_access_iterator<const int *>(num + sz),
never_eq<int> ), never_eq<int> ),
input_iterator<int *>(num), random_access_iterator<int *>(num))); input_iterator<const int *>(num), random_access_iterator<const int *>(num)));
// different sequences are different // Different sequences are different
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz), ba::mismatch ( input_iterator<const int *>(num + 1), input_iterator<const int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz)), input_iterator<const int *>(num), input_iterator<const int *>(num + sz)),
input_iterator<int *>(num + 2), input_iterator<int *>(num + 1))); input_iterator<const int *>(num + 2), input_iterator<const int *>(num + 1)));
BOOST_CHECK ( iter_eq ( BOOST_CHECK ( iter_eq (
ba::mismatch ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz), ba::mismatch ( input_iterator<const int *>(num + 1), input_iterator<const int *>(num + sz),
input_iterator<int *>(num), input_iterator<int *>(num + sz), input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
eq<int> ), eq<int> ),
input_iterator<int *>(num + 2), input_iterator<int *>(num + 1))); input_iterator<const int *>(num + 2), input_iterator<const int *>(num + 1)));
// Checks constexpr
BOOST_CXX14_CONSTEXPR bool res = (
// No mismatch for empty
iter_eq (
ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num),
input_iterator<const int *>(num), input_iterator<const int *>(num)),
input_iterator<const int *>(num), input_iterator<const int *>(num))
// Empty vs. non-empty mismatch immediately
&& iter_eq (
ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num),
input_iterator<const int *>(num), input_iterator<const int *>(num + 1)),
input_iterator<const int *>(num), input_iterator<const int *>(num))
// Single element sequences are equal if they contain the same value
&& iter_eq (
ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
input_iterator<const int *>(num), input_iterator<const int *>(num + 1),
eq<int>),
input_iterator<const int *>(num + 1), input_iterator<const int *>(num + 1))
// Identical long sequences are equal.
&& iter_eq (
ba::mismatch ( input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
input_iterator<const int *>(num), input_iterator<const int *>(num + sz),
eq<int> ),
input_iterator<const int *>(num + sz), input_iterator<const int *>(num + sz))
);
BOOST_CHECK ( res );
} }

View File

@ -19,9 +19,9 @@
template<typename T> template<typename T>
struct is_ : public std::unary_function<T, bool> { struct is_ : public std::unary_function<T, bool> {
is_ ( T v ) : val_ ( v ) {} BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {}
~is_ () {}
bool operator () ( T comp ) const { return val_ == comp; } BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; }
private: private:
is_ (); // need a value is_ (); // need a value
@ -33,7 +33,7 @@ namespace ba = boost::algorithm;
void test_none() void test_none()
{ {
// Note: The literal values here are tested against directly, careful if you change them: // 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<int> vi(some_numbers, some_numbers + 5); std::vector<int> vi(some_numbers, some_numbers + 5);
std::list<int> li(vi.begin(), vi.end ()); std::list<int> 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_equal ( li.begin(), l_iter, 18 ));
BOOST_CHECK ( ba::none_of ( li.begin(), l_iter, is_<int> ( 18 ))); BOOST_CHECK ( ba::none_of ( li.begin(), l_iter, is_<int> ( 18 )));
BOOST_CHECK (!ba::none_of ( li.begin(), l_iter, is_<int> ( 5 ))); BOOST_CHECK (!ba::none_of ( li.begin(), l_iter, is_<int> ( 5 )));
BOOST_CXX14_CONSTEXPR bool constexpr_res = (
!ba::none_of_equal ( some_numbers, 1 )
&& !ba::none_of ( some_numbers, is_<int> ( 1 ))
&& ba::none_of_equal ( some_numbers, some_numbers + 3, 100 )
&& ba::none_of ( some_numbers, some_numbers + 3, is_<int> ( 100 ))
);
BOOST_CHECK ( constexpr_res );
} }
BOOST_AUTO_TEST_CASE( test_main ) BOOST_AUTO_TEST_CASE( test_main )

View File

@ -19,9 +19,9 @@
template<typename T> template<typename T>
struct is_ : public std::unary_function<T, bool> { struct is_ : public std::unary_function<T, bool> {
is_ ( T v ) : val_ ( v ) {} BOOST_CXX14_CONSTEXPR is_ ( T v ) : val_ ( v ) {}
~is_ () {}
bool operator () ( T comp ) const { return val_ == comp; } BOOST_CXX14_CONSTEXPR bool operator () ( T comp ) const { return val_ == comp; }
private: private:
is_ (); // need a value is_ (); // need a value
@ -33,7 +33,7 @@ namespace ba = boost::algorithm;
void test_one () void test_one ()
{ {
// Note: The literal values here are tested against directly, careful if you change them: // 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<int> vi(some_numbers, some_numbers + 5); std::vector<int> vi(some_numbers, some_numbers + 5);
std::list<int> li(vi.begin(), vi.end ()); std::list<int> li(vi.begin(), vi.end ());
@ -93,6 +93,12 @@ void test_one ()
BOOST_CHECK (!ba::one_of_equal ( li.begin(), l_iter, 3 )); BOOST_CHECK (!ba::one_of_equal ( li.begin(), l_iter, 3 ));
BOOST_CHECK (!ba::one_of ( li.begin(), l_iter, is_<int> ( 3 ))); BOOST_CHECK (!ba::one_of ( li.begin(), l_iter, is_<int> ( 3 )));
BOOST_CXX14_CONSTEXPR bool constexpr_res = (
!ba::one_of ( some_numbers, is_<int> ( 6 ))
&& ba::one_of ( some_numbers, some_numbers + 3, is_<int> ( 1 ))
);
BOOST_CHECK ( constexpr_res );
} }

View File

@ -29,11 +29,13 @@ using namespace boost;
namespace ba = boost::algorithm; namespace ba = boost::algorithm;
BOOST_CXX14_CONSTEXPR bool less( int x, int y ) { return x < y; }
static void static void
test_ordered(void) test_ordered(void)
{ {
const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 }; BOOST_CXX14_CONSTEXPR const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 };
const int randomValues[] = { 3, 6, 1, 2, 7 }; BOOST_CXX14_CONSTEXPR const int randomValues[] = { 3, 6, 1, 2, 7 };
const int constantValues[] = { 1, 2, 2, 2, 5 }; const int constantValues[] = { 1, 2, 2, 2, 5 };
int nonConstantArray[] = { 1, 2, 2, 2, 5 }; int nonConstantArray[] = { 1, 2, 2, 2, 5 };
const int inOrderUntilTheEnd [] = { 0, 1, 2, 3, 4, 5, 6, 7, 6 }; 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)) == a_begin(randomValues));
BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1, std::equal_to<int>()) == a_begin(randomValues) + 1); BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1, std::equal_to<int>()) == a_begin(randomValues) + 1);
BOOST_CHECK ( ba::is_sorted_until ( a_begin(randomValues), a_begin(randomValues) + 1 ) == 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 static void
test_increasing_decreasing(void) test_increasing_decreasing(void)
{ {
const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 }; BOOST_CXX14_CONSTEXPR const int strictlyIncreasingValues[] = { 1, 2, 3, 4, 5 };
const int strictlyDecreasingValues[] = { 9, 8, 7, 6, 5 }; BOOST_CXX14_CONSTEXPR const int strictlyDecreasingValues[] = { 9, 8, 7, 6, 5 };
const int increasingValues[] = { 1, 2, 2, 2, 5 }; BOOST_CXX14_CONSTEXPR const int increasingValues[] = { 1, 2, 2, 2, 5 };
const int decreasingValues[] = { 9, 7, 7, 7, 5 }; BOOST_CXX14_CONSTEXPR const int decreasingValues[] = { 9, 7, 7, 7, 5 };
const int randomValues[] = { 3, 6, 1, 2, 7 }; BOOST_CXX14_CONSTEXPR const int randomValues[] = { 3, 6, 1, 2, 7 };
const int constantValues[] = { 7, 7, 7, 7, 7 }; BOOST_CXX14_CONSTEXPR const int constantValues[] = { 7, 7, 7, 7, 7 };
// Test a strictly increasing sequence // Test a strictly increasing sequence
BOOST_CHECK ( ba::is_strictly_increasing (b_e(strictlyIncreasingValues))); 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_strictly_decreasing (strictlyIncreasingValues, strictlyIncreasingValues+2));
BOOST_CHECK ( !ba::is_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 ) BOOST_AUTO_TEST_CASE( test_main )

View File

@ -47,10 +47,10 @@ void test_sequence ( const Container &c, Predicate comp ) {
template <typename T> template <typename T>
struct less_than { struct less_than {
public: public:
less_than ( T foo ) : val ( foo ) {} BOOST_CXX14_CONSTEXPR less_than ( T foo ) : val ( foo ) {}
less_than ( const less_than &rhs ) : val ( rhs.val ) {} 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: private:
less_than (); less_than ();
less_than operator = ( const less_than &rhs ); less_than operator = ( const less_than &rhs );
@ -82,7 +82,29 @@ 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<int>(2) );
res = (res && ba::all_of(out_true, out_true + 2, less_than<int>(2)) );
res = (res && ba::none_of(out_false, out_false + 1, less_than<int>(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<int>(2));
res = ( res && ba::all_of(out_true, out_true + 2, less_than<int>(2)));
res = ( res && ba::none_of(out_false, out_false + 1, less_than<int>(2)));
return res;
}
BOOST_AUTO_TEST_CASE( test_main ) BOOST_AUTO_TEST_CASE( test_main )
{ {
test_sequence1 (); test_sequence1 ();
BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr ();
BOOST_CHECK ( constexpr_res );
} }

View File

@ -18,7 +18,7 @@
namespace ba = boost::algorithm; namespace ba = boost::algorithm;
BOOST_AUTO_TEST_CASE( test_main ) void test_power ()
{ {
BOOST_CHECK ( ba::power(0, 0) == 1); BOOST_CHECK ( ba::power(0, 0) == 1);
BOOST_CHECK ( ba::power(5, 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<int>())); BOOST_CHECK ( ba::power(3,2) == ba::power(3,2, std::multiplies<int>()));
BOOST_CHECK ( ba::power(3,2, std::plus<int>()) == 6); BOOST_CHECK ( ba::power(3,2, std::plus<int>()) == 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<int>()) == ba::power(3, 2);
BOOST_CHECK(check_multiple);
BOOST_CXX14_CONSTEXPR bool check_plus =
ba::power(3, 2, std::plus<int>()) == 6;
BOOST_CHECK(check_plus);
}
BOOST_AUTO_TEST_CASE( test_main ) {
test_power ();
test_power_constexpr ();
}