Added constexpr modifiers for C++14 mode and some tests

This commit is contained in:
Antony Polukhin
2016-01-25 13:11:01 +03:00
parent 61a4bd45fb
commit 8d095e9d30
19 changed files with 111 additions and 71 deletions

View File

@ -40,7 +40,7 @@ T identity_operation ( std::plus<T> ) { return T(0); }
// \remark Taken from Knuth, The Art of Computer Programming, Volume 2: // \remark Taken from Knuth, The Art of Computer Programming, Volume 2:
// Seminumerical Algorithms, Section 4.6.3 // Seminumerical Algorithms, Section 4.6.3
template <typename T, typename Integer> template <typename T, typename Integer>
typename boost::enable_if<boost::is_integral<Integer>, T>::type BOOST_CXX14_CONSTEXPR typename boost::enable_if<boost::is_integral<Integer>, T>::type
power (T x, Integer n) { power (T x, Integer n) {
T y = 1; // Should be "T y{1};" T y = 1; // Should be "T y{1};"
if (n == 0) return y; if (n == 0) return y;
@ -67,7 +67,7 @@ power (T x, Integer n) {
// \remark Taken from Knuth, The Art of Computer Programming, Volume 2: // \remark Taken from Knuth, The Art of Computer Programming, Volume 2:
// Seminumerical Algorithms, Section 4.6.3 // Seminumerical Algorithms, Section 4.6.3
template <typename T, typename Integer, typename Operation> template <typename T, typename Integer, typename Operation>
typename boost::enable_if<boost::is_integral<Integer>, T>::type BOOST_CXX14_CONSTEXPR typename boost::enable_if<boost::is_integral<Integer>, T>::type
power (T x, Integer n, Operation op) { power (T x, Integer n, Operation op) {
T y = identity_operation(op); T y = identity_operation(op);
if (n == 0) return y; if (n == 0) return y;

View File

@ -46,7 +46,7 @@ namespace boost { namespace algorithm {
/// p ( a, b ) returns a boolean. /// p ( a, b ) returns a boolean.
/// ///
template<typename T, typename Pred> template<typename T, typename Pred>
T const & clamp ( T const& val, BOOST_CXX14_CONSTEXPR T const & clamp ( T const& val,
typename boost::mpl::identity<T>::type const & lo, typename boost::mpl::identity<T>::type const & lo,
typename boost::mpl::identity<T>::type const & hi, Pred p ) typename boost::mpl::identity<T>::type const & hi, Pred p )
{ {
@ -68,7 +68,7 @@ namespace boost { namespace algorithm {
/// \param hi The upper bound of the range to be clamped to /// \param hi The upper bound of the range to be clamped to
/// ///
template<typename T> template<typename T>
T const& clamp ( const T& val, BOOST_CXX14_CONSTEXPR T const& clamp ( const T& val,
typename boost::mpl::identity<T>::type const & lo, typename boost::mpl::identity<T>::type const & lo,
typename boost::mpl::identity<T>::type const & hi ) typename boost::mpl::identity<T>::type const & hi )
{ {
@ -87,7 +87,7 @@ namespace boost { namespace algorithm {
/// \param hi The upper bound of the range to be clamped to /// \param hi The upper bound of the range to be clamped to
/// ///
template<typename InputIterator, typename OutputIterator> template<typename InputIterator, typename OutputIterator>
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, BOOST_CXX14_CONSTEXPR OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
typename std::iterator_traits<InputIterator>::value_type const & lo, typename std::iterator_traits<InputIterator>::value_type const & lo,
typename std::iterator_traits<InputIterator>::value_type const & hi ) typename std::iterator_traits<InputIterator>::value_type const & hi )
{ {
@ -108,7 +108,7 @@ namespace boost { namespace algorithm {
/// \param hi The upper bound of the range to be clamped to /// \param hi The upper bound of the range to be clamped to
/// ///
template<typename Range, typename OutputIterator> template<typename Range, typename OutputIterator>
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type BOOST_CXX14_CONSTEXPR typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
clamp_range ( const Range &r, OutputIterator out, clamp_range ( const Range &r, OutputIterator out,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi ) typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi )
@ -133,7 +133,7 @@ namespace boost { namespace algorithm {
/// ///
template<typename InputIterator, typename OutputIterator, typename Pred> template<typename InputIterator, typename OutputIterator, typename Pred>
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, BOOST_CXX14_CONSTEXPR OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
typename std::iterator_traits<InputIterator>::value_type const & lo, typename std::iterator_traits<InputIterator>::value_type const & lo,
typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p ) typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
{ {
@ -160,7 +160,7 @@ namespace boost { namespace algorithm {
// Disable this template if the first two parameters are the same type; // Disable this template if the first two parameters are the same type;
// In that case, the user will get the two iterator version. // In that case, the user will get the two iterator version.
template<typename Range, typename OutputIterator, typename Pred> template<typename Range, typename OutputIterator, typename Pred>
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type BOOST_CXX14_CONSTEXPR typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
clamp_range ( const Range &r, OutputIterator out, clamp_range ( const Range &r, OutputIterator out,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & lo,
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,

View File

@ -30,7 +30,7 @@ namespace boost { namespace algorithm {
/// We will use the standard one if it is available, /// We will use the standard one if it is available,
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
bool all_of ( InputIterator first, InputIterator last, Predicate p ) BOOST_CXX14_CONSTEXPR bool all_of ( InputIterator first, InputIterator last, Predicate p )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( !p(*first)) if ( !p(*first))
@ -46,7 +46,7 @@ bool all_of ( InputIterator first, InputIterator last, Predicate p )
/// \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>
bool all_of ( const Range &r, Predicate p ) BOOST_CXX14_CONSTEXPR bool all_of ( const Range &r, Predicate p )
{ {
return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p ); return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p );
} }
@ -60,7 +60,7 @@ bool all_of ( const Range &r, Predicate p )
/// \param val A value to compare against /// \param val A value to compare against
/// ///
template<typename InputIterator, typename T> template<typename InputIterator, typename T>
bool all_of_equal ( InputIterator first, InputIterator last, const T &val ) BOOST_CXX14_CONSTEXPR bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( val != *first ) if ( val != *first )
@ -76,7 +76,7 @@ bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
/// \param val A value to compare against /// \param val A value to compare against
/// ///
template<typename Range, typename T> template<typename Range, typename T>
bool all_of_equal ( const Range &r, const T &val ) BOOST_CXX14_CONSTEXPR bool all_of_equal ( const Range &r, const T &val )
{ {
return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val ); return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val );
} }

View File

@ -29,7 +29,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the sequence /// \param p A predicate for testing the elements of the sequence
/// ///
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
bool any_of ( InputIterator first, InputIterator last, Predicate p ) BOOST_CXX14_CONSTEXPR bool any_of ( InputIterator first, InputIterator last, Predicate p )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( p(*first)) if ( p(*first))
@ -45,7 +45,7 @@ bool any_of ( InputIterator first, InputIterator last, Predicate p )
/// \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>
bool any_of ( const Range &r, Predicate p ) BOOST_CXX14_CONSTEXPR bool any_of ( const Range &r, Predicate p )
{ {
return boost::algorithm::any_of (boost::begin (r), boost::end (r), p); return boost::algorithm::any_of (boost::begin (r), boost::end (r), p);
} }
@ -59,7 +59,7 @@ bool any_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 any_of_equal ( InputIterator first, InputIterator last, const V &val ) BOOST_CXX14_CONSTEXPR bool any_of_equal ( InputIterator first, InputIterator last, const V &val )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( val == *first ) if ( val == *first )
@ -75,7 +75,7 @@ bool any_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 any_of_equal ( const Range &r, const V &val ) BOOST_CXX14_CONSTEXPR bool any_of_equal ( const Range &r, const V &val )
{ {
return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val); return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val);
} }

View File

@ -31,7 +31,7 @@ namespace boost { namespace algorithm {
/// We will use the standard one if it is available, /// We will use the standard one if it is available,
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template<typename InputIterator, typename OutputIterator, typename Predicate> template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) BOOST_CXX14_CONSTEXPR OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if (p(*first)) if (p(*first))
@ -49,7 +49,7 @@ OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator
/// \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 OutputIterator, typename Predicate> template<typename Range, typename OutputIterator, typename Predicate>
OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p ) BOOST_CXX14_CONSTEXPR OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
{ {
return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p); return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p);
} }
@ -66,7 +66,7 @@ OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
/// \param p A predicate for testing the elements of the range /// \param p A predicate for testing the elements of the range
/// ///
template<typename InputIterator, typename OutputIterator, typename Predicate> template<typename InputIterator, typename OutputIterator, typename Predicate>
std::pair<InputIterator, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<InputIterator, OutputIterator>
copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{ {
for ( ; first != last && p(*first); ++first ) for ( ; first != last && p(*first); ++first )
@ -84,7 +84,7 @@ copy_while ( InputIterator first, InputIterator last, OutputIterator result, 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 OutputIterator, typename Predicate> template<typename Range, typename OutputIterator, typename Predicate>
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_while ( const Range &r, OutputIterator result, Predicate p ) copy_while ( const Range &r, OutputIterator result, Predicate p )
{ {
return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p); return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
@ -102,7 +102,7 @@ copy_while ( const Range &r, OutputIterator result, Predicate p )
/// \param p A predicate for testing the elements of the range /// \param p A predicate for testing the elements of the range
/// ///
template<typename InputIterator, typename OutputIterator, typename Predicate> template<typename InputIterator, typename OutputIterator, typename Predicate>
std::pair<InputIterator, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<InputIterator, OutputIterator>
copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p ) copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{ {
for ( ; first != last && !p(*first); ++first ) for ( ; first != last && !p(*first); ++first )
@ -120,7 +120,7 @@ copy_until ( InputIterator first, InputIterator last, OutputIterator result, 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 OutputIterator, typename Predicate> template<typename Range, typename OutputIterator, typename Predicate>
std::pair<typename boost::range_iterator<const Range>::type, OutputIterator> BOOST_CXX14_CONSTEXPR std::pair<typename boost::range_iterator<const Range>::type, OutputIterator>
copy_until ( const Range &r, OutputIterator result, Predicate p ) copy_until ( const Range &r, OutputIterator result, Predicate p )
{ {
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p); return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);

View File

@ -28,7 +28,7 @@ namespace boost { namespace algorithm {
/// We will use the standard one if it is available, /// We will use the standard one if it is available,
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template <typename InputIterator, typename Size, typename OutputIterator> template <typename InputIterator, typename Size, typename OutputIterator>
OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result ) BOOST_CXX14_CONSTEXPR OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result )
{ {
for ( ; n > 0; --n, ++first, ++result ) for ( ; n > 0; --n, ++first, ++result )
*result = *first; *result = *first;

View File

@ -30,7 +30,7 @@ namespace boost { namespace algorithm {
/// We will use the standard one if it is available, /// We will use the standard one if it is available,
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p ) BOOST_CXX14_CONSTEXPR InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( !p(*first)) if ( !p(*first))
@ -46,7 +46,7 @@ InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p
/// \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>
typename boost::range_iterator<const Range>::type find_if_not ( const Range &r, Predicate p ) BOOST_CXX14_CONSTEXPR typename boost::range_iterator<const Range>::type find_if_not ( const Range &r, Predicate p )
{ {
return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p); return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p);
} }

View File

@ -29,7 +29,7 @@ namespace boost { namespace algorithm {
/// We will use the standard one if it is available, /// We will use the standard one if it is available,
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template <typename ForwardIterator, typename T> template <typename ForwardIterator, typename T>
void iota ( ForwardIterator first, ForwardIterator last, T value ) BOOST_CXX14_CONSTEXPR void iota ( ForwardIterator first, ForwardIterator last, T value )
{ {
for ( ; first != last; ++first, ++value ) for ( ; first != last; ++first, ++value )
*first = value; *first = value;
@ -42,7 +42,7 @@ void iota ( ForwardIterator first, ForwardIterator last, T value )
/// \param value The initial value of the sequence to be generated /// \param value The initial value of the sequence to be generated
/// ///
template <typename Range, typename T> template <typename Range, typename T>
void iota ( Range &r, T value ) BOOST_CXX14_CONSTEXPR void iota ( Range &r, T value )
{ {
boost::algorithm::iota (boost::begin(r), boost::end(r), value); boost::algorithm::iota (boost::begin(r), boost::end(r), value);
} }
@ -56,7 +56,7 @@ void iota ( Range &r, T value )
/// \param n The number of items to write /// \param n The number of items to write
/// ///
template <typename OutputIterator, typename T> template <typename OutputIterator, typename T>
OutputIterator iota_n ( OutputIterator out, T value, std::size_t n ) BOOST_CXX14_CONSTEXPR OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
{ {
for ( ; n > 0; --n, ++value ) for ( ; n > 0; --n, ++value )
*out++ = value; *out++ = value;

View File

@ -29,7 +29,7 @@ namespace boost { namespace algorithm {
/// We will use the standard one if it is available, /// We will use the standard one if it is available,
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template <typename InputIterator, typename UnaryPredicate> template <typename InputIterator, typename UnaryPredicate>
bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p ) BOOST_CXX14_CONSTEXPR bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
{ {
// Run through the part that satisfy the predicate // Run through the part that satisfy the predicate
for ( ; first != last; ++first ) for ( ; first != last; ++first )
@ -49,7 +49,7 @@ bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p
/// \param p The predicate to test the values with /// \param p The predicate to test the values with
/// ///
template <typename Range, typename UnaryPredicate> template <typename Range, typename UnaryPredicate>
bool is_partitioned ( const Range &r, UnaryPredicate p ) BOOST_CXX14_CONSTEXPR bool is_partitioned ( const Range &r, UnaryPredicate p )
{ {
return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p); return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p);
} }

View File

@ -35,7 +35,7 @@ namespace boost { namespace algorithm {
/// \param p A binary predicate that returns true if two elements are ordered. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename ForwardIterator, typename Pred> template <typename ForwardIterator, typename Pred>
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p ) BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
{ {
if ( first == last ) return last; // the empty sequence is ordered if ( first == last ) return last; // the empty sequence is ordered
ForwardIterator next = first; ForwardIterator next = first;
@ -55,7 +55,7 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the sequence /// \param last One past the end of the sequence
/// ///
template <typename ForwardIterator> template <typename ForwardIterator>
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>()); return boost::algorithm::is_sorted_until ( first, last, std::less<value_type>());
@ -70,7 +70,7 @@ namespace boost { namespace algorithm {
/// \param p A binary predicate that returns true if two elements are ordered. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename ForwardIterator, typename Pred> template <typename ForwardIterator, typename Pred>
bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p ) BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
{ {
return boost::algorithm::is_sorted_until (first, last, p) == last; return boost::algorithm::is_sorted_until (first, last, p) == last;
} }
@ -82,7 +82,7 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the sequence /// \param last One past the end of the sequence
/// ///
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_sorted ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_sorted ( ForwardIterator first, ForwardIterator last )
{ {
return boost::algorithm::is_sorted_until (first, last) == last; return boost::algorithm::is_sorted_until (first, last) == last;
} }
@ -99,7 +99,7 @@ namespace boost { namespace algorithm {
/// \param p A binary predicate that returns true if two elements are ordered. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename R, typename Pred> template <typename R, typename Pred>
typename boost::lazy_disable_if_c< BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c<
boost::is_same<R, Pred>::value, boost::is_same<R, Pred>::value,
typename boost::range_iterator<const R> typename boost::range_iterator<const R>
>::type is_sorted_until ( const R &range, Pred p ) >::type is_sorted_until ( const R &range, Pred p )
@ -114,7 +114,7 @@ namespace boost { namespace algorithm {
/// \param range The range to be tested. /// \param range The range to be tested.
/// ///
template <typename R> template <typename R>
typename boost::range_iterator<const R>::type is_sorted_until ( const R &range ) BOOST_CXX14_CONSTEXPR typename boost::range_iterator<const R>::type is_sorted_until ( const R &range )
{ {
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range )); return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ));
} }
@ -127,7 +127,7 @@ namespace boost { namespace algorithm {
/// \param p A binary predicate that returns true if two elements are ordered. /// \param p A binary predicate that returns true if two elements are ordered.
/// ///
template <typename R, typename Pred> template <typename R, typename Pred>
typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type BOOST_CXX14_CONSTEXPR typename boost::lazy_disable_if_c< boost::is_same<R, Pred>::value, boost::mpl::identity<bool> >::type
is_sorted ( const R &range, Pred p ) is_sorted ( const R &range, Pred p )
{ {
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p ); return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p );
@ -140,7 +140,7 @@ namespace boost { namespace algorithm {
/// \param range The range to be tested. /// \param range The range to be tested.
/// ///
template <typename R> template <typename R>
bool is_sorted ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_sorted ( const R &range )
{ {
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range )); return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ));
} }
@ -160,7 +160,7 @@ namespace boost { namespace algorithm {
/// \note This function will return true for sequences that contain items that compare /// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_increasing instead. /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_increasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_increasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less<value_type>()); return boost::algorithm::is_sorted (first, last, std::less<value_type>());
@ -176,7 +176,7 @@ namespace boost { namespace algorithm {
/// \note This function will return true for sequences that contain items that compare /// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_increasing instead. /// equal. If that is not what you intended, you should use is_strictly_increasing instead.
template <typename R> template <typename R>
bool is_increasing ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_increasing ( const R &range )
{ {
return is_increasing ( boost::begin ( range ), boost::end ( range )); return is_increasing ( boost::begin ( range ), boost::end ( range ));
} }
@ -193,7 +193,7 @@ namespace boost { namespace algorithm {
/// \note This function will return true for sequences that contain items that compare /// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead. /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_decreasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_decreasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater<value_type>()); return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
@ -208,7 +208,7 @@ namespace boost { namespace algorithm {
/// \note This function will return true for sequences that contain items that compare /// \note This function will return true for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead. /// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
template <typename R> template <typename R>
bool is_decreasing ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_decreasing ( const R &range )
{ {
return is_decreasing ( boost::begin ( range ), boost::end ( range )); return is_decreasing ( boost::begin ( range ), boost::end ( range ));
} }
@ -225,7 +225,7 @@ namespace boost { namespace algorithm {
/// \note This function will return false for sequences that contain items that compare /// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_increasing instead. /// equal. If that is not what you intended, you should use is_increasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>()); return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
@ -240,7 +240,7 @@ namespace boost { namespace algorithm {
/// \note This function will return false for sequences that contain items that compare /// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_increasing instead. /// equal. If that is not what you intended, you should use is_increasing instead.
template <typename R> template <typename R>
bool is_strictly_increasing ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_strictly_increasing ( const R &range )
{ {
return is_strictly_increasing ( boost::begin ( range ), boost::end ( range )); return is_strictly_increasing ( boost::begin ( range ), boost::end ( range ));
} }
@ -256,7 +256,7 @@ namespace boost { namespace algorithm {
/// \note This function will return false for sequences that contain items that compare /// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_decreasing instead. /// equal. If that is not what you intended, you should use is_decreasing instead.
template <typename ForwardIterator> template <typename ForwardIterator>
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last ) BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
{ {
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type; typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>()); return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
@ -271,7 +271,7 @@ namespace boost { namespace algorithm {
/// \note This function will return false for sequences that contain items that compare /// \note This function will return false for sequences that contain items that compare
/// equal. If that is not what you intended, you should use is_decreasing instead. /// equal. If that is not what you intended, you should use is_decreasing instead.
template <typename R> template <typename R>
bool is_strictly_decreasing ( const R &range ) BOOST_CXX14_CONSTEXPR bool is_strictly_decreasing ( const R &range )
{ {
return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range )); return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
} }

View File

@ -27,7 +27,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the sequence /// \param p A predicate for testing the elements of the sequence
/// ///
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
bool none_of ( InputIterator first, InputIterator last, Predicate p ) BOOST_CXX14_CONSTEXPR bool none_of ( InputIterator first, InputIterator last, Predicate p )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( p(*first)) if ( p(*first))
@ -43,7 +43,7 @@ for ( ; first != last; ++first )
/// \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>
bool none_of ( const Range &r, Predicate p ) BOOST_CXX14_CONSTEXPR bool none_of ( const Range &r, Predicate p )
{ {
return boost::algorithm::none_of (boost::begin (r), boost::end (r), p ); return boost::algorithm::none_of (boost::begin (r), boost::end (r), p );
} }
@ -57,7 +57,7 @@ bool none_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 none_of_equal ( InputIterator first, InputIterator last, const V &val ) BOOST_CXX14_CONSTEXPR bool none_of_equal ( InputIterator first, InputIterator last, const V &val )
{ {
for ( ; first != last; ++first ) for ( ; first != last; ++first )
if ( val == *first ) if ( val == *first )
@ -73,7 +73,7 @@ bool none_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 none_of_equal ( const Range &r, const V & val ) BOOST_CXX14_CONSTEXPR bool none_of_equal ( const Range &r, const V & val )
{ {
return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val); return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val);
} }

View File

@ -28,7 +28,7 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the sequence /// \param p A predicate for testing the elements of the sequence
/// ///
template<typename InputIterator, typename Predicate> template<typename InputIterator, typename Predicate>
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); InputIterator i = std::find_if (first, last, p);
if (i == last) if (i == last)
@ -43,7 +43,7 @@ bool one_of ( InputIterator first, InputIterator last, Predicate p )
/// \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>
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 );
} }

View File

@ -15,6 +15,7 @@
#include <algorithm> // for std::partition_copy, if available #include <algorithm> // for std::partition_copy, if available
#include <utility> // for make_pair #include <utility> // for make_pair
#include <boost/config.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
@ -38,7 +39,7 @@ namespace boost { namespace algorithm {
/// otherwise we have our own implementation. /// otherwise we have our own implementation.
template <typename InputIterator, template <typename InputIterator,
typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate> typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2> BOOST_CXX14_CONSTEXPR std::pair<OutputIterator1, OutputIterator2>
partition_copy ( InputIterator first, InputIterator last, partition_copy ( InputIterator first, InputIterator last,
OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p ) OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
{ {
@ -60,7 +61,7 @@ partition_copy ( InputIterator first, InputIterator last,
/// ///
template <typename Range, typename OutputIterator1, typename OutputIterator2, template <typename Range, typename OutputIterator1, typename OutputIterator2,
typename UnaryPredicate> typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2> BOOST_CXX14_CONSTEXPR std::pair<OutputIterator1, OutputIterator2>
partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false, partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false,
UnaryPredicate p ) UnaryPredicate p )
{ {

View File

@ -21,7 +21,7 @@ namespace detail {
template <class T1, class T2> template <class T1, class T2>
struct eq : public std::binary_function<T1, T2, bool> { struct eq : public std::binary_function<T1, T2, bool> {
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;} BOOST_CONSTEXPR bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
}; };
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate> template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
@ -37,7 +37,7 @@ namespace detail {
} }
template <class InputIterator1, class InputIterator2, class BinaryPredicate> template <class InputIterator1, class InputIterator2, class BinaryPredicate>
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 )
{ {

View File

@ -14,6 +14,7 @@
#include <algorithm> // for std::mismatch #include <algorithm> // for std::mismatch
#include <utility> // for std::pair #include <utility> // for std::pair
#include <boost/config.hpp>
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
@ -28,7 +29,7 @@ namespace boost { namespace algorithm {
/// \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>
std::pair<InputIterator1, InputIterator2> mismatch ( BOOST_CXX14_CONSTEXPR std::pair<InputIterator1, InputIterator2> mismatch (
InputIterator1 first1, InputIterator1 last1, InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, InputIterator2 first2, InputIterator2 last2,
BinaryPredicate pred ) BinaryPredicate pred )
@ -48,7 +49,7 @@ std::pair<InputIterator1, InputIterator2> mismatch (
/// \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>
std::pair<InputIterator1, InputIterator2> mismatch ( BOOST_CXX14_CONSTEXPR std::pair<InputIterator1, InputIterator2> mismatch (
InputIterator1 first1, InputIterator1 last1, InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 ) InputIterator2 first2, InputIterator2 last2 )
{ {

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_all () void test_all ()
{ {
// 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, 1, 18, 10 }; BOOST_CXX14_CONSTEXPR int some_numbers[] = { 1, 1, 1, 18, 10 };
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 ());
@ -77,7 +77,14 @@ void test_all ()
l_iter++; l_iter++; l_iter++; l_iter++; l_iter++; l_iter++;
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 = (
!ba::all_of_equal ( some_numbers, 1 )
&& !ba::all_of ( some_numbers, is_<int> ( 1 ))
&& ba::all_of_equal ( some_numbers, some_numbers + 3, 1 )
&& ba::all_of ( some_numbers, some_numbers + 3, is_<int> ( 1 ))
);
BOOST_CHECK ( constexpr_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_any () void test_any ()
{ {
// 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, 10 }; BOOST_CXX14_CONSTEXPR int some_numbers[] = { 1, 5, 0, 18, 10 };
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 ());
@ -97,6 +97,15 @@ void test_any ()
BOOST_CHECK ( ba::any_of ( li.begin(), l_iter, is_<int> ( 5 ))); BOOST_CHECK ( ba::any_of ( li.begin(), l_iter, is_<int> ( 5 )));
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 = (
ba::any_of_equal ( some_numbers, 1 )
&& ba::any_of ( some_numbers, is_<int> ( 1 ))
&& !ba::any_of_equal ( some_numbers, some_numbers + 3, 777 )
&& !ba::any_of ( some_numbers, some_numbers + 3, is_<int> ( 777 ))
);
BOOST_CHECK ( constexpr_res );
} }

View File

@ -45,6 +45,10 @@ void test_ints()
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 0, 1, 10 )); BOOST_CHECK_EQUAL ( 1, ba::clamp ( 0, 1, 10 ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, 1, 10 )); BOOST_CHECK_EQUAL ( 10, ba::clamp ( 10, 1, 10 ));
BOOST_CHECK_EQUAL ( 10, ba::clamp ( 11, 1, 10 )); BOOST_CHECK_EQUAL ( 10, ba::clamp ( 11, 1, 10 ));
BOOST_CXX14_CONSTEXPR bool constexpr_res = (
ba::clamp ( 3, 1, 10 ) == 3
);
BOOST_CHECK( constexpr_res );
BOOST_CHECK_EQUAL ( 3, ba::clamp ( 3, 10, 1, intGreater )); BOOST_CHECK_EQUAL ( 3, ba::clamp ( 3, 10, 1, intGreater ));
BOOST_CHECK_EQUAL ( 1, ba::clamp ( 1, 10, 1, intGreater )); BOOST_CHECK_EQUAL ( 1, ba::clamp ( 1, 10, 1, intGreater ));

View File

@ -25,10 +25,25 @@
namespace ba = boost::algorithm; namespace ba = boost::algorithm;
// namespace ba = boost; // namespace ba = boost;
bool is_true ( int v ) { return true; } BOOST_CXX14_CONSTEXPR bool is_true ( int v ) { return true; }
bool is_false ( int v ) { return false; } BOOST_CXX14_CONSTEXPR bool is_false ( int v ) { return false; }
bool is_even ( int v ) { return v % 2 == 0; } BOOST_CXX14_CONSTEXPR bool is_even ( int v ) { return v % 2 == 0; }
bool is_odd ( int v ) { return v % 2 == 1; } BOOST_CXX14_CONSTEXPR bool is_odd ( int v ) { return v % 2 == 1; }
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 ) {
@ -164,6 +179,9 @@ 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_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 );