fix constexpr-ness of a couple of algorithhms - and tests. Based on Pull Request #44 by Flast - thanks!

This commit is contained in:
Marshall Clow
2018-04-04 11:18:38 -07:00
parent 509201f29f
commit 3af7acabc7
7 changed files with 52 additions and 47 deletions

View File

@ -12,7 +12,6 @@
#ifndef BOOST_ALGORITHM_ONE_OF_HPP #ifndef BOOST_ALGORITHM_ONE_OF_HPP
#define BOOST_ALGORITHM_ONE_OF_HPP #define BOOST_ALGORITHM_ONE_OF_HPP
#include <algorithm> // for std::find and std::find_if
#include <boost/algorithm/cxx11/none_of.hpp> #include <boost/algorithm/cxx11/none_of.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
@ -30,10 +29,14 @@ namespace boost { namespace algorithm {
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
BOOST_CXX14_CONSTEXPR bool one_of ( InputIterator first, InputIterator last, Predicate p ) BOOST_CXX14_CONSTEXPR bool one_of ( InputIterator first, InputIterator last, Predicate p )
{ {
InputIterator i = std::find_if (first, last, p); // find_if
if (i == last) for (; first != last; ++first)
if (p(*first))
break;
if (first == last)
return false; // Didn't occur at all return false; // Didn't occur at all
return boost::algorithm::none_of (++i, last, p); return boost::algorithm::none_of (++first, last, p);
} }
/// \fn one_of ( const Range &r, Predicate p ) /// \fn one_of ( const Range &r, Predicate p )
@ -43,7 +46,7 @@ BOOST_CXX14_CONSTEXPR bool one_of ( InputIterator first, InputIterator last, Pre
/// \param p A predicate for testing the elements of the range /// \param p A predicate for testing the elements of the range
/// ///
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
BOOST_CXX14_CONSTEXPR bool one_of ( const Range &r, Predicate p ) BOOST_CXX14_CONSTEXPR bool one_of ( const Range &r, Predicate p )
{ {
return boost::algorithm::one_of ( boost::begin (r), boost::end (r), p ); return boost::algorithm::one_of ( boost::begin (r), boost::end (r), p );
} }
@ -57,12 +60,16 @@ BOOST_CXX14_CONSTEXPR bool one_of ( const Range &r, Predicate p )
/// \param val A value to compare against /// \param val A value to compare against
/// ///
template<typename InputIterator, typename V> template<typename InputIterator, typename V>
bool one_of_equal ( InputIterator first, InputIterator last, const V &val ) BOOST_CXX14_CONSTEXPR bool one_of_equal ( InputIterator first, InputIterator last, const V &val )
{ {
InputIterator i = std::find (first, last, val); // find first occurrence of 'val' // find
if (i == last) for (; first != last; ++first)
if (*first == val)
break;
if (first == last)
return false; // Didn't occur at all return false; // Didn't occur at all
return boost::algorithm::none_of_equal (++i, last, val); return boost::algorithm::none_of_equal (++first, last, val);
} }
/// \fn one_of_equal ( const Range &r, const V &val ) /// \fn one_of_equal ( const Range &r, const V &val )
@ -72,7 +79,7 @@ bool one_of_equal ( InputIterator first, InputIterator last, const V &val )
/// \param val A value to compare against /// \param val A value to compare against
/// ///
template<typename Range, typename V> template<typename Range, typename V>
bool one_of_equal ( const Range &r, const V &val ) BOOST_CXX14_CONSTEXPR bool one_of_equal ( const Range &r, const V &val )
{ {
return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val ); return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val );
} }

View File

@ -12,16 +12,8 @@
#ifndef BOOST_ALGORITHM_EQUAL_HPP #ifndef BOOST_ALGORITHM_EQUAL_HPP
#define BOOST_ALGORITHM_EQUAL_HPP #define BOOST_ALGORITHM_EQUAL_HPP
#include <algorithm> // for std::equal
#include <iterator> #include <iterator>
#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 {
@ -32,7 +24,7 @@ namespace detail {
}; };
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate> template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
BOOST_CONSTEXPR_IF_STD_CONSTEXPR BOOST_CXX14_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 )
@ -40,12 +32,16 @@ namespace detail {
// Random-access iterators let is check the sizes in constant time // Random-access iterators let is check the sizes in constant time
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 )) if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
return false; return false;
// If we know that the sequences are the same size, the original version is fine
return std::equal ( first1, last1, first2, pred ); // std::equal
for (; first1 != last1; ++first1, ++first2)
if (!pred(*first1, *first2))
return false;
return true;
} }
template <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
BOOST_CXX14_CONSTEXPR 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,
std::input_iterator_tag, std::input_iterator_tag ) std::input_iterator_tag, std::input_iterator_tag )

View File

@ -77,12 +77,13 @@ void test_all ()
BOOST_CHECK ( ba::all_of_equal ( li.begin(), l_iter, 1 )); BOOST_CHECK ( ba::all_of_equal ( li.begin(), l_iter, 1 ));
BOOST_CHECK ( ba::all_of ( li.begin(), l_iter, is_<int> ( 1 ))); BOOST_CHECK ( ba::all_of ( li.begin(), l_iter, is_<int> ( 1 )));
BOOST_CXX14_CONSTEXPR bool constexpr_res = ( BOOST_CXX14_CONSTEXPR bool constexpr_res =
!ba::all_of_equal ( some_numbers, 1 ) !ba::all_of_equal ( some_numbers, 1 ) &&
&& !ba::all_of ( some_numbers, is_<int> ( 1 )) !ba::all_of ( some_numbers, is_<int> ( 1 )) &&
&& ba::all_of_equal ( some_numbers, some_numbers + 3, 1 ) ba::all_of_equal ( some_numbers, some_numbers + 3, 1 ) &&
&& ba::all_of ( some_numbers, some_numbers + 3, is_<int> ( 1 )) ba::all_of ( some_numbers, some_numbers + 3, is_<int> ( 1 )) &&
); true;
BOOST_CHECK ( constexpr_res ); BOOST_CHECK ( constexpr_res );
} }

View File

@ -97,13 +97,13 @@ void test_any ()
BOOST_CHECK (!ba::any_of_equal ( li.begin(), l_iter, 18 )); BOOST_CHECK (!ba::any_of_equal ( li.begin(), l_iter, 18 ));
BOOST_CHECK (!ba::any_of ( li.begin(), l_iter, is_<int> ( 18 ))); BOOST_CHECK (!ba::any_of ( li.begin(), l_iter, is_<int> ( 18 )));
BOOST_CXX14_CONSTEXPR bool constexpr_res =
BOOST_CXX14_CONSTEXPR bool constexpr_res = ( ba::any_of_equal ( some_numbers, 1 ) &&
ba::any_of_equal ( some_numbers, 1 ) ba::any_of ( some_numbers, is_<int> ( 1 )) &&
&& ba::any_of ( some_numbers, is_<int> ( 1 )) !ba::any_of_equal ( some_numbers, some_numbers + 3, 777 ) &&
&& !ba::any_of_equal ( some_numbers, some_numbers + 3, 777 ) !ba::any_of ( some_numbers, some_numbers + 3, is_<int> ( 777 )) &&
&& !ba::any_of ( some_numbers, some_numbers + 3, is_<int> ( 777 )) true;
);
BOOST_CHECK ( constexpr_res ); BOOST_CHECK ( constexpr_res );
} }

View File

@ -306,7 +306,7 @@ void test_constexpr()
BOOST_CHECK(check_max_out); BOOST_CHECK(check_max_out);
} }
{ {
short foo = 50; BOOST_CXX14_CONSTEXPR short foo = 50;
BOOST_CXX14_CONSTEXPR bool check_float = ( 56 == ba::clamp ( foo, 56.9, 129 )); BOOST_CXX14_CONSTEXPR bool check_float = ( 56 == ba::clamp ( foo, 56.9, 129 ));
BOOST_CHECK(check_float); BOOST_CHECK(check_float);
BOOST_CXX14_CONSTEXPR bool check_over = ( 24910 == ba::clamp ( foo, 12345678, 123456999 )); BOOST_CXX14_CONSTEXPR bool check_over = ( 24910 == ba::clamp ( foo, 12345678, 123456999 ));

View File

@ -88,13 +88,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 = ( BOOST_CXX14_CONSTEXPR bool constexpr_res =
!ba::none_of_equal ( some_numbers, 1 ) !ba::none_of_equal ( some_numbers, 1 ) &&
&& !ba::none_of ( some_numbers, is_<int> ( 1 )) !ba::none_of ( some_numbers, is_<int> ( 1 )) &&
&& ba::none_of_equal ( some_numbers, some_numbers + 3, 100 ) ba::none_of_equal ( some_numbers, some_numbers + 3, 100 ) &&
&& ba::none_of ( some_numbers, some_numbers + 3, is_<int> ( 100 )) ba::none_of ( some_numbers, some_numbers + 3, is_<int> ( 100 )) &&
); true;
BOOST_CHECK ( constexpr_res ); BOOST_CHECK ( constexpr_res );
} }

View File

@ -92,10 +92,10 @@ 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 = ( BOOST_CXX14_CONSTEXPR bool constexpr_res =
!ba::one_of ( some_numbers, is_<int> ( 6 )) !ba::one_of ( some_numbers, is_<int> ( 6 )) &&
&& ba::one_of ( some_numbers + 1, some_numbers + 3, is_<int> ( 1 )) ba::one_of ( some_numbers + 1, some_numbers + 3, is_<int> ( 1 )) &&
); true;
BOOST_CHECK ( constexpr_res ); BOOST_CHECK ( constexpr_res );
} }