mirror of
https://github.com/boostorg/algorithm.git
synced 2025-06-25 20:11:50 +02:00
Compare commits
34 Commits
boost-1.54
...
boost-1.56
Author | SHA1 | Date | |
---|---|---|---|
cf249c090c | |||
0f63883818 | |||
645be22fa7 | |||
28b12d7264 | |||
4d28d579e3 | |||
5adab54486 | |||
a4d5f17173 | |||
848b521850 | |||
bc3b806f56 | |||
685a76f094 | |||
0ac413ecb8 | |||
747722a8da | |||
5988a55b96 | |||
617ec03937 | |||
4c3b17ce77 | |||
ef78dde448 | |||
432b3a3da0 | |||
850fc02667 | |||
b44dff3a5b | |||
5279c8f061 | |||
4b9a073780 | |||
083c6f5891 | |||
8b89b5ba27 | |||
d528574fe9 | |||
fe51eb60a9 | |||
fc0fe6af52 | |||
ca23b6f4f8 | |||
5f79807d02 | |||
4f269a270c | |||
05475fec0f | |||
44d65cb4ae | |||
3e5f571230 | |||
73cfe03b97 | |||
b9d89c559b |
@ -22,7 +22,7 @@ Consider the two sequences:
|
||||
|
||||
std::equal ( seq1.begin (), seq1.end (), seq2.begin ()); // true
|
||||
std::equal ( seq2.begin (), seq2.end (), seq1.begin ()); // Undefined behavior
|
||||
std::equal ( seq1.begin (), seq1.end (), seq1.begin (), seq2.end ()); // false
|
||||
std::equal ( seq1.begin (), seq1.end (), seq2.begin (), seq2.end ()); // false
|
||||
```
|
||||
|
||||
You can argue that `true` is the correct answer in the first case, even though the sequences are not the same. The first N entries in `seq2` are the same as the entries in `seq1` - but that's not all that's in `seq2`. But in the second case, the algorithm will read past the end of `seq1`, resulting in undefined behavior (large earthquake, incorrect results, pregnant cat, etc).
|
||||
|
@ -22,7 +22,7 @@ Consider the two sequences:
|
||||
|
||||
std::mismatch ( seq1.begin (), seq1.end (), seq2.begin ()); // <3, 3>
|
||||
std::mismatch ( seq2.begin (), seq2.end (), seq1.begin ()); // Undefined behavior
|
||||
std::mismatch ( seq1.begin (), seq1.end (), seq1.begin (), seq2.end ()); // <3, 3>
|
||||
std::mismatch ( seq1.begin (), seq1.end (), seq2.begin (), seq2.end ()); // <3, 3>
|
||||
```
|
||||
|
||||
The first N entries in `seq2` are the same as the entries in `seq1` - but that's not all that's in `seq2`. In the second case, the algorithm will read past the end of `seq1`, resulting in undefined behavior (large earthquake, incorrect results, pregnant cat, etc).
|
||||
|
@ -75,7 +75,7 @@ All of the variants of `one_of` and `one_of_equal` take their parameters by valu
|
||||
|
||||
* `one_of` and `one_of_equal` both return false for empty ranges, no matter what is passed to test against.
|
||||
|
||||
* The second parameter to `one_of_value` is a template parameter, rather than deduced from the first parameter (`std::iterator_traits<InputIterator>::value_type`) because that allows more flexibility for callers, and takes advantage of built-in comparisons for the type that is pointed to by the iterator. The function is defined to return true if, for one element in the sequence, the expression `*iter == val` evaluates to true (where `iter` is an iterator to each element in the sequence)
|
||||
* The second parameter to `one_of_equal` is a template parameter, rather than deduced from the first parameter (`std::iterator_traits<InputIterator>::value_type`) because that allows more flexibility for callers, and takes advantage of built-in comparisons for the type that is pointed to by the iterator. The function is defined to return true if, for one element in the sequence, the expression `*iter == val` evaluates to true (where `iter` is an iterator to each element in the sequence)
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -19,11 +19,11 @@ The function `is_sorted(sequence)` determines whether or not a sequence is compl
|
||||
|
||||
``
|
||||
namespace boost { namespace algorithm {
|
||||
template <typename Iterator, typename Pred>
|
||||
bool is_sorted ( Iterator first, Iterator last, Pred p );
|
||||
template <typename ForwardIterator, typename Pred>
|
||||
bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p );
|
||||
|
||||
template <typename Iterator>
|
||||
bool is_sorted ( Iterator first, Iterator last );
|
||||
template <typename ForwardIterator>
|
||||
bool is_sorted ( ForwardIterator first, ForwardIterator last );
|
||||
|
||||
|
||||
template <typename Range, typename Pred>
|
||||
@ -34,7 +34,7 @@ namespace boost { namespace algorithm {
|
||||
}}
|
||||
``
|
||||
|
||||
Iterator requirements: The `is_sorted` functions will work on all kinds of iterators (except output iterators).
|
||||
Iterator requirements: The `is_sorted` functions will work forward iterators or better.
|
||||
|
||||
[heading is_sorted_until]
|
||||
|
||||
@ -88,8 +88,8 @@ To test if a sequence is decreasing (each element no larger than the preceding o
|
||||
|
||||
``
|
||||
namespace boost { namespace algorithm {
|
||||
template <typename Iterator>
|
||||
bool is_decreasing ( Iterator first, Iterator last );
|
||||
template <typename ForwardIterator>
|
||||
bool is_decreasing ( ForwardIterator first, ForwardIterator last );
|
||||
|
||||
template <typename R>
|
||||
bool is_decreasing ( const R &range );
|
||||
@ -99,8 +99,8 @@ namespace boost { namespace algorithm {
|
||||
To test if a sequence is strictly increasing (each element larger than the preceding one):
|
||||
``
|
||||
namespace boost { namespace algorithm {
|
||||
template <typename Iterator>
|
||||
bool is_strictly_increasing ( Iterator first, Iterator last );
|
||||
template <typename ForwardIterator>
|
||||
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last );
|
||||
|
||||
template <typename R>
|
||||
bool is_strictly_increasing ( const R &range );
|
||||
@ -110,8 +110,8 @@ namespace boost { namespace algorithm {
|
||||
To test if a sequence is strictly decreasing (each element smaller than the preceding one):
|
||||
``
|
||||
namespace boost { namespace algorithm {
|
||||
template <typename Iterator>
|
||||
bool is_strictly_decreasing ( Iterator first, Iterator last );
|
||||
template <typename ForwardIterator>
|
||||
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last );
|
||||
|
||||
template <typename R>
|
||||
bool is_strictly_decreasing ( const R &range );
|
||||
|
@ -31,8 +31,8 @@
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn clamp ( T const& val,
|
||||
/// 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 & lo,
|
||||
/// typename boost::mpl::identity<T>::type const & hi, Pred p )
|
||||
/// \return the value "val" brought into the range [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
/// If p ( val, lo ) return lo.
|
||||
@ -56,8 +56,8 @@ namespace boost { namespace algorithm {
|
||||
|
||||
|
||||
/// \fn clamp ( T const& val,
|
||||
/// typename boost::mpl::identity<T>::type const& lo,
|
||||
/// typename boost::mpl::identity<T>::type const& hi )
|
||||
/// typename boost::mpl::identity<T>::type const & lo,
|
||||
/// typename boost::mpl::identity<T>::type const & hi )
|
||||
/// \return the value "val" brought into the range [ lo, hi ].
|
||||
/// If the value is less than lo, return lo.
|
||||
/// If the value is greater than "hi", return hi.
|
||||
@ -76,8 +76,8 @@ namespace boost { namespace algorithm {
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type hi )
|
||||
/// std::iterator_traits<InputIterator>::value_type const & lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type const & hi )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
///
|
||||
/// \param first The start of the range of values
|
||||
@ -88,8 +88,8 @@ namespace boost { namespace algorithm {
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type hi )
|
||||
typename std::iterator_traits<InputIterator>::value_type const & lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type const & hi )
|
||||
{
|
||||
// this could also be written with bind and std::transform
|
||||
while ( first != last )
|
||||
@ -98,8 +98,8 @@ namespace boost { namespace algorithm {
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||
/// 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 )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
///
|
||||
/// \param r The range of values to be clamped
|
||||
@ -110,16 +110,16 @@ namespace boost { namespace algorithm {
|
||||
template<typename Range, typename OutputIterator>
|
||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||
clamp_range ( const Range &r, OutputIterator out,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||
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 )
|
||||
{
|
||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
|
||||
}
|
||||
|
||||
|
||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||
/// std::iterator_traits<InputIterator>::value_type const & lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
///
|
||||
@ -134,8 +134,8 @@ namespace boost { namespace algorithm {
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Pred>
|
||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||
typename std::iterator_traits<InputIterator>::value_type const & lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
|
||||
{
|
||||
// this could also be written with bind and std::transform
|
||||
while ( first != last )
|
||||
@ -144,8 +144,8 @@ namespace boost { namespace algorithm {
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||
/// 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,
|
||||
/// Pred p )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
@ -162,8 +162,8 @@ namespace boost { namespace algorithm {
|
||||
template<typename Range, typename OutputIterator, typename Pred>
|
||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||
clamp_range ( const Range &r, OutputIterator out,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||
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,
|
||||
Pred p )
|
||||
{
|
||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
|
||||
|
@ -63,8 +63,8 @@ void iota ( Range &r, T value )
|
||||
template <typename OutputIterator, typename T>
|
||||
OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
|
||||
{
|
||||
while ( n-- > 0 )
|
||||
*out++ = value++;
|
||||
for ( ; n > 0; --n, ++value )
|
||||
*out++ = value;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
/// \brief Is a sequence a permutation of another sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION11_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION11_HPP
|
||||
|
||||
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
||||
#include <utility> // for std::make_pair
|
||||
@ -21,7 +21,6 @@
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/tr1/tr1/tuple> // for tie
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
@ -121,7 +120,6 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, BinaryPredicate p )
|
||||
{
|
||||
// Skip the common prefix (if any)
|
||||
// std::tie (first1, first2) = std::mismatch (first1, last1, first2, p);
|
||||
std::pair<ForwardIterator1, ForwardIterator2> eq = std::mismatch (first1, last1, first2, p);
|
||||
first1 = eq.first;
|
||||
first2 = eq.second;
|
||||
@ -165,56 +163,6 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1, ForwardIt
|
||||
|
||||
#endif
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||
/// ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last2 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param last1 One past the end of the second sequence
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2 >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
{
|
||||
// How should I deal with the idea that ForwardIterator1::value_type
|
||||
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
|
||||
return boost::algorithm::detail::is_permutation_tag (
|
||||
first1, last1, first2, last2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> (),
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||
/// ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
/// BinaryPredicate p )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last1 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param last2 One past the end of the second sequence
|
||||
/// \param pred The predicate to compare elements with
|
||||
///
|
||||
/// \note This function is part of the C++2011 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::detail::is_permutation_tag (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
@ -245,4 +193,4 @@ is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION11_HPP
|
||||
|
@ -12,41 +12,41 @@
|
||||
#ifndef BOOST_ALGORITHM_EQUAL_HPP
|
||||
#define BOOST_ALGORITHM_EQUAL_HPP
|
||||
|
||||
#include <algorithm> // for std::equal
|
||||
#include <functional> // for std::equal_to
|
||||
#include <algorithm> // for std::equal
|
||||
#include <functional> // for std::equal_to
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T1, class T2>
|
||||
struct eq : public std::binary_function<T1, T2, bool> {
|
||||
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
|
||||
};
|
||||
|
||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
||||
bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
|
||||
std::random_access_iterator_tag, std::random_access_iterator_tag )
|
||||
{
|
||||
// Random-access iterators let is check the sizes in constant time
|
||||
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
|
||||
return false;
|
||||
// If we know that the sequences are the same size, the original version is fine
|
||||
return std::equal ( first1, last1, first2, pred );
|
||||
}
|
||||
template <class T1, class T2>
|
||||
struct eq : public std::binary_function<T1, T2, bool> {
|
||||
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
|
||||
};
|
||||
|
||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
||||
bool equal ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
|
||||
std::random_access_iterator_tag, std::random_access_iterator_tag )
|
||||
{
|
||||
// Random-access iterators let is check the sizes in constant time
|
||||
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
|
||||
return false;
|
||||
// If we know that the sequences are the same size, the original version is fine
|
||||
return std::equal ( first1, last1, first2, pred );
|
||||
}
|
||||
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred,
|
||||
std::input_iterator_tag, std::input_iterator_tag )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2 )
|
||||
if ( !pred(*first1, *first2 ))
|
||||
return false;
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred,
|
||||
std::input_iterator_tag, std::input_iterator_tag )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2 )
|
||||
if ( !pred(*first1, *first2 ))
|
||||
return false;
|
||||
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
}
|
||||
|
||||
/// \fn equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
@ -63,10 +63,10 @@ template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::detail::equal (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<InputIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<InputIterator2>::iterator_category ());
|
||||
return boost::algorithm::detail::equal (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<InputIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<InputIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
/// \fn equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
@ -81,16 +81,16 @@ template <class InputIterator1, class InputIterator2>
|
||||
bool equal ( InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2 )
|
||||
{
|
||||
return boost::algorithm::detail::equal (
|
||||
first1, last1, first2, last2,
|
||||
boost::algorithm::detail::eq<
|
||||
typename std::iterator_traits<InputIterator1>::value_type,
|
||||
typename std::iterator_traits<InputIterator2>::value_type> (),
|
||||
typename std::iterator_traits<InputIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<InputIterator2>::iterator_category ());
|
||||
return boost::algorithm::detail::equal (
|
||||
first1, last1, first2, last2,
|
||||
boost::algorithm::detail::eq<
|
||||
typename std::iterator_traits<InputIterator1>::value_type,
|
||||
typename std::iterator_traits<InputIterator2>::value_type> (),
|
||||
typename std::iterator_traits<InputIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<InputIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
// There are already range-based versions of these.
|
||||
// There are already range-based versions of these.
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
|
@ -1,130 +1,86 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2013
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2014.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/// \file equal.hpp
|
||||
/// \brief Determines if one
|
||||
/// \file is_permutation.hpp
|
||||
/// \brief Is a sequence a permutation of another sequence (four iterator versions)
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION14_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION14_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional> // for std::equal_to
|
||||
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
||||
#include <utility> // for std::make_pair
|
||||
#include <functional> // for std::equal_to
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/algorithm/cxx11/is_permutation.hpp>
|
||||
#include <boost/algorithm/cxx14/mismatch.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T1, class T2>
|
||||
struct is_perm_eq : public std::binary_function<T1, T2, bool> {
|
||||
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
|
||||
};
|
||||
|
||||
|
||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
||||
bool is_permutation ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
|
||||
std::random_access_iterator_tag, std::random_access_iterator_tag )
|
||||
{
|
||||
// Random-access iterators let is check the sizes in constant time
|
||||
if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
|
||||
return false;
|
||||
// If we know that the sequences are the same size, the original version is fine
|
||||
return std::is_permutation ( first1, last1, first2, pred );
|
||||
}
|
||||
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
|
||||
bool is_permutation (
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred,
|
||||
std::forward_iterator_tag, std::forward_iterator_tag )
|
||||
{
|
||||
|
||||
// Look for common prefix
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
if (!pred(*first1, *first2))
|
||||
goto not_done;
|
||||
// We've reached the end of one of the sequences without a mismatch.
|
||||
return first1 == last1 && first2 == last2;
|
||||
not_done:
|
||||
|
||||
// Check and make sure that we have the same # of elements left
|
||||
typedef typename std::iterator_traits<ForwardIterator1>::difference_type diff1_t;
|
||||
diff1_t len1 = _VSTD::distance(first1, last1);
|
||||
typedef typename std::iterator_traits<ForwardIterator2>::difference_type diff2_t;
|
||||
diff2_t len2 = _VSTD::distance(first2, last2);
|
||||
if (len1 != len2)
|
||||
return false;
|
||||
|
||||
// For each element in [f1, l1) see if there are the
|
||||
// same number of equal elements in [f2, l2)
|
||||
for ( ForwardIterator1 i = first1; i != last1; ++i )
|
||||
{
|
||||
// Have we already counted this value?
|
||||
ForwardIterator1 j;
|
||||
for ( j = first1; j != i; ++j )
|
||||
if (pred(*j, *i))
|
||||
break;
|
||||
if ( j == i ) // didn't find it...
|
||||
{
|
||||
// Count number of *i in [f2, l2)
|
||||
diff1_t c2 = 0;
|
||||
for ( ForwardIterator2 iter2 = first2; iter2 != last2; ++iter2 )
|
||||
if (pred(*i, *iter2))
|
||||
++c2;
|
||||
if (c2 == 0)
|
||||
return false;
|
||||
|
||||
// Count number of *i in [i, l1)
|
||||
diff1_t c1 = 0;
|
||||
for (_ForwardIterator1 iter1 = i; iter1 != last1; ++iter1 )
|
||||
if (pred(*i, *iter1))
|
||||
++c1;
|
||||
if (c1 != c2)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#if __cplusplus <= 201103L
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||
/// ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last2 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param last1 One past the end of the second sequence
|
||||
/// \note This function is part of the C++2014 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2 >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
{
|
||||
// How should I deal with the idea that ForwardIterator1::value_type
|
||||
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
|
||||
std::pair<ForwardIterator1, ForwardIterator2> eq = boost::algorithm::mismatch
|
||||
( first1, last1, first2, last2 );
|
||||
if ( eq.first == last1 && eq.second == last2)
|
||||
return true;
|
||||
}
|
||||
|
||||
return boost::algorithm::detail::is_permutation_tag (
|
||||
eq.first, last1, eq.second, last2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> (),
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
|
||||
bool is_permutation (
|
||||
ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::detail::is_permutation (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
|
||||
template<class ForwardIterator1, class ForwardIterator2>
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||
/// ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
/// BinaryPredicate p )
|
||||
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first1 The start of the input sequence
|
||||
/// \param last1 One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param last2 One past the end of the second sequence
|
||||
/// \param pred The predicate to compare elements with
|
||||
///
|
||||
/// \note This function is part of the C++2014 standard library.
|
||||
/// We will use the standard one if it is available,
|
||||
/// otherwise we have our own implementation.
|
||||
template< class ForwardIterator1, class ForwardIterator2, class BinaryPredicate >
|
||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||
ForwardIterator2 first2, ForwardIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
typedef typename iterator_traits<_ForwardIterator1>::value_type value1_t;
|
||||
typedef typename iterator_traits<_ForwardIterator2>::value_type value2_t;
|
||||
return boost::algorithm::detail::is_permutation (
|
||||
first1, last1, first2, last2,
|
||||
boost::algorithm::detail::is_perm_eq<
|
||||
typename std::iterator_traits<InputIterator1>::value_type,
|
||||
typename std::iterator_traits<InputIterator2>::value_type> (),
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
std::pair<ForwardIterator1, ForwardIterator2> eq = boost::algorithm::mismatch
|
||||
( first1, last1, first2, last2, pred );
|
||||
if ( eq.first == last1 && eq.second == last2)
|
||||
return true;
|
||||
return boost::algorithm::detail::is_permutation_tag (
|
||||
first1, last1, first2, last2, pred,
|
||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||
}
|
||||
#endif
|
||||
|
||||
// There are already range-based versions of these.
|
||||
}}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION14_HPP
|
||||
|
@ -12,13 +12,11 @@
|
||||
#ifndef BOOST_ALGORITHM_MISMATCH_HPP
|
||||
#define BOOST_ALGORITHM_MISMATCH_HPP
|
||||
|
||||
#include <algorithm> // for std::mismatch
|
||||
#include <utility> // for std::pair
|
||||
#include <algorithm> // for std::mismatch
|
||||
#include <utility> // for std::pair
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
|
||||
/// \fn mismatch ( InputIterator1 first1, InputIterator1 last1,
|
||||
/// InputIterator2 first2, InputIterator2 last2,
|
||||
/// BinaryPredicate pred )
|
||||
@ -29,10 +27,11 @@ template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
/// \param first2 The start 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
|
||||
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
|
||||
std::pair<InputIterator1, InputIterator2> mismatch (
|
||||
InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2,
|
||||
BinaryPredicate pred )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
if ( !pred ( *first1, *first2 ))
|
||||
@ -50,8 +49,8 @@ std::pair<InputIterator1, InputIterator2> mismatch (
|
||||
/// \param last2 One past the end of the second range.
|
||||
template <class InputIterator1, class InputIterator2>
|
||||
std::pair<InputIterator1, InputIterator2> mismatch (
|
||||
InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2 )
|
||||
InputIterator1 first1, InputIterator1 last1,
|
||||
InputIterator2 first2, InputIterator2 last2 )
|
||||
{
|
||||
for (; first1 != last1 && first2 != last2; ++first1, ++first2)
|
||||
if ( *first1 != *first2 )
|
||||
@ -59,7 +58,7 @@ std::pair<InputIterator1, InputIterator2> mismatch (
|
||||
return std::pair<InputIterator1, InputIterator2>(first1, first2);
|
||||
}
|
||||
|
||||
// There are already range-based versions of these.
|
||||
// There are already range-based versions of these.
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
|
@ -20,7 +20,11 @@
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
|
||||
#include <boost/tr1/tr1/unordered_map>
|
||||
#else
|
||||
#include <unordered_map>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
@ -35,7 +39,11 @@ namespace boost { namespace algorithm { namespace detail {
|
||||
template<typename key_type, typename value_type>
|
||||
class skip_table<key_type, value_type, false> {
|
||||
private:
|
||||
#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
|
||||
typedef std::tr1::unordered_map<key_type, value_type> skip_map;
|
||||
#else
|
||||
typedef std::unordered_map<key_type, value_type> skip_map;
|
||||
#endif
|
||||
const value_type k_default_value;
|
||||
skip_map skip_;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BOOST_STRING_CONCEPT_HPP
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/algorithm/string/detail/find_format_store.hpp>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/algorithm/string/detail/find_format_store.hpp>
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <boost/algorithm/string/constants.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/empty.hpp>
|
||||
@ -142,7 +142,6 @@ namespace boost {
|
||||
ForwardIteratorT End,
|
||||
std::forward_iterator_tag ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
first_finder_type first_finder(
|
||||
@ -263,7 +262,6 @@ namespace boost {
|
||||
ForwardIteratorT End,
|
||||
unsigned int N) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
// Sanity check
|
||||
@ -298,7 +296,6 @@ namespace boost {
|
||||
ForwardIteratorT End,
|
||||
unsigned int N) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
// Sanity check
|
||||
@ -362,7 +359,6 @@ namespace boost {
|
||||
unsigned int N,
|
||||
std::random_access_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
|
||||
@ -436,7 +432,6 @@ namespace boost {
|
||||
unsigned int N,
|
||||
std::random_access_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
|
||||
@ -627,8 +622,6 @@ namespace boost {
|
||||
{
|
||||
#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
|
||||
return iterator_range<const ForwardIterator2T>(this->m_Range);
|
||||
#elif BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
return iterator_range<ForwardIterator2T>(m_Range.begin(), m_Range.end());
|
||||
#else
|
||||
return m_Range;
|
||||
#endif
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BOOST_STRING_FORMATTER_DETAIL_HPP
|
||||
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <functional>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <deque>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
@ -132,12 +132,7 @@ namespace boost {
|
||||
// increment
|
||||
void increment()
|
||||
{
|
||||
if(m_Match.begin() == m_Match.end())
|
||||
m_Match=this->do_find(m_Match.end(),m_End);
|
||||
else {
|
||||
input_iterator_type last = m_Match.begin();
|
||||
m_Match=this->do_find(++last,m_End);
|
||||
}
|
||||
m_Match=this->do_find(m_Match.end(),m_End);
|
||||
}
|
||||
|
||||
// comparison
|
||||
@ -235,7 +230,7 @@ namespace boost {
|
||||
|
||||
\post eof()==true
|
||||
*/
|
||||
split_iterator() {}
|
||||
split_iterator() { m_bEof = true; }
|
||||
//! Copy constructor
|
||||
/*!
|
||||
Construct a copy of the split_iterator
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
|
||||
#include <boost/algorithm/string/detail/formatter.hpp>
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <iterator>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
|
||||
#include <boost/algorithm/string/compare.hpp>
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
|
@ -36,47 +36,6 @@ namespace boost {
|
||||
|
||||
// sequence traits -----------------------------------------------//
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
//! Native replace tester
|
||||
/*!
|
||||
Declare an override of this tester function with return
|
||||
type boost::string_algo::yes_type for a sequence with this property.
|
||||
|
||||
\return yes_type if the container has basic_string like native replace
|
||||
method.
|
||||
*/
|
||||
no_type has_native_replace_tester(...);
|
||||
|
||||
//! Stable iterators tester
|
||||
/*!
|
||||
Declare an override of this tester function with return
|
||||
type boost::string_algo::yes_type for a sequence with this property.
|
||||
|
||||
\return yes_type if the sequence's insert/replace/erase methods do not invalidate
|
||||
existing iterators.
|
||||
*/
|
||||
no_type has_stable_iterators_tester(...);
|
||||
|
||||
//! const time insert tester
|
||||
/*!
|
||||
Declare an override of this tester function with return
|
||||
type boost::string_algo::yes_type for a sequence with this property.
|
||||
|
||||
\return yes_type if the sequence's insert method is working in constant time
|
||||
*/
|
||||
no_type has_const_time_insert_tester(...);
|
||||
|
||||
//! const time erase tester
|
||||
/*!
|
||||
Declare an override of this tester function with return
|
||||
type boost::string_algo::yes_type for a sequence with this property.
|
||||
|
||||
\return yes_type if the sequence's erase method is working in constant time
|
||||
*/
|
||||
no_type has_const_time_erase_tester(...);
|
||||
|
||||
#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
//! Native replace trait
|
||||
/*!
|
||||
@ -86,20 +45,12 @@ namespace boost {
|
||||
class has_native_replace
|
||||
{
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
private:
|
||||
static T* t;
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value=(
|
||||
sizeof(has_native_replace_tester(t))==sizeof(yes_type) ) );
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
public:
|
||||
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
enum { value = false };
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
|
||||
typedef mpl::bool_<has_native_replace<T>::value> type;
|
||||
@ -114,20 +65,12 @@ namespace boost {
|
||||
template< typename T >
|
||||
class has_stable_iterators
|
||||
{
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
private:
|
||||
static T* t;
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value=(
|
||||
sizeof(has_stable_iterators_tester(t))==sizeof(yes_type) ) );
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
public:
|
||||
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
enum { value = false };
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
typedef mpl::bool_<has_stable_iterators<T>::value> type;
|
||||
};
|
||||
@ -141,20 +84,12 @@ namespace boost {
|
||||
template< typename T >
|
||||
class has_const_time_insert
|
||||
{
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
private:
|
||||
static T* t;
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value=(
|
||||
sizeof(has_const_time_insert_tester(t))==sizeof(yes_type) ) );
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
public:
|
||||
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
enum { value = false };
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
typedef mpl::bool_<has_const_time_insert<T>::value> type;
|
||||
};
|
||||
@ -168,20 +103,12 @@ namespace boost {
|
||||
template< typename T >
|
||||
class has_const_time_erase
|
||||
{
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
private:
|
||||
static T* t;
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, value=(
|
||||
sizeof(has_const_time_erase_tester(t))==sizeof(yes_type) ) );
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
public:
|
||||
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
enum { value = false };
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value=false);
|
||||
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
typedef mpl::bool_<has_const_time_erase<T>::value> type;
|
||||
};
|
||||
|
@ -20,22 +20,6 @@ namespace boost {
|
||||
|
||||
// std::list<> traits -----------------------------------------------//
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// stable iterators tester
|
||||
template<typename T, typename AllocT>
|
||||
yes_type has_stable_iterators_tester( const ::std::list<T,AllocT>* );
|
||||
|
||||
// const time insert tester
|
||||
template<typename T, typename AllocT>
|
||||
yes_type has_const_time_insert_tester( const ::std::list<T,AllocT>* );
|
||||
|
||||
// const time erase tester
|
||||
template<typename T, typename AllocT>
|
||||
yes_type has_const_time_erase_tester( const ::std::list<T,AllocT>* );
|
||||
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// stable iterators trait
|
||||
template<typename T, typename AllocT>
|
||||
@ -75,7 +59,6 @@ namespace boost {
|
||||
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
typedef mpl::bool_<has_const_time_erase<T>::value> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -20,25 +20,6 @@ namespace boost {
|
||||
|
||||
// SGI's std::rope<> traits -----------------------------------------------//
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// native replace tester
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
yes_type has_native_replace_tester( const std::rope<T, TraitsT, AllocT>* );
|
||||
|
||||
// stable iterators tester
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
yes_type has_stable_iterators_tester( const std::rope<T, TraitsT, AllocT>* );
|
||||
|
||||
// const time insert tester
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
yes_type has_const_time_insert_tester( const std::rope<T, TraitsT, AllocT>* );
|
||||
|
||||
// const time erase tester
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
yes_type has_const_time_erase_tester( const std::rope<T, TraitsT, AllocT>* );
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// native replace trait
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
@ -91,7 +72,6 @@ namespace boost {
|
||||
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
typedef mpl::bool_<value> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -21,21 +21,6 @@ namespace boost {
|
||||
|
||||
// SGI's std::slist<> traits -----------------------------------------------//
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// stable iterators tester
|
||||
template<typename T, typename AllocT>
|
||||
yes_type has_stable_iterators_tester( const BOOST_STD_EXTENSION_NAMESPACE::slist<T,AllocT>* );
|
||||
|
||||
// const time insert tester
|
||||
template<typename T, typename AllocT>
|
||||
yes_type has_const_time_insert_tester( const BOOST_STD_EXTENSION_NAMESPACE::slist<T,AllocT>* );
|
||||
|
||||
// const time erase tester
|
||||
template<typename T, typename AllocT>
|
||||
yes_type has_const_time_erase_tester( const BOOST_STD_EXTENSION_NAMESPACE::slist<T,AllocT>* );
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// stable iterators trait
|
||||
template<typename T, typename AllocT>
|
||||
@ -75,7 +60,6 @@ namespace boost {
|
||||
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
|
||||
typedef mpl::bool_<has_const_time_erase<T>::value> type;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -20,13 +20,6 @@ namespace boost {
|
||||
|
||||
// std::basic_string<> traits -----------------------------------------------//
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// native replace tester
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
yes_type has_native_replace_tester( const std::basic_string<T, TraitsT, AllocT>* );
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// native replace trait
|
||||
template<typename T, typename TraitsT, typename AllocT>
|
||||
@ -43,7 +36,6 @@ namespace boost {
|
||||
};
|
||||
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
} // namespace algorithm
|
||||
} // namespace boost
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
|
||||
#include <boost/algorithm/string/detail/trim.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
@ -181,6 +181,21 @@ void find_test()
|
||||
( (cv_result.begin()-str1.begin()) == 3) &&
|
||||
( (cv_result.end()-str1.begin()) == 6) );
|
||||
|
||||
string s1("abc def ghi jkl");
|
||||
find_iterator<string::iterator> fEnd;
|
||||
|
||||
find_iterator<string::iterator> fxIt = make_find_iterator(s1,
|
||||
token_finder(is_alnum(), token_compress_on));
|
||||
BOOST_CHECK((fxIt != fEnd) && (*fxIt == string("abc")));
|
||||
++fxIt;
|
||||
BOOST_CHECK((fxIt != fEnd) && (*fxIt == string("def")));
|
||||
++fxIt;
|
||||
BOOST_CHECK((fxIt != fEnd) && (*fxIt == string("ghi")));
|
||||
++fxIt;
|
||||
BOOST_CHECK((fxIt != fEnd) && (*fxIt == string("jkl")));
|
||||
++fxIt;
|
||||
BOOST_CHECK(fxIt == fEnd);
|
||||
|
||||
nc_result=find_token( str1, is_any_of("abc"), token_compress_off );
|
||||
BOOST_CHECK(
|
||||
( (nc_result.begin()-str1.begin()) == 3) &&
|
||||
@ -251,19 +266,6 @@ void find_test()
|
||||
osstr << find_first( str1, "abc" );
|
||||
BOOST_CHECK( osstr.str()=="abc" );
|
||||
|
||||
// Empty string test
|
||||
BOOST_TEST_CHECKPOINT( "overlapping" );
|
||||
|
||||
std::string overlap_target("aaaa");
|
||||
std::vector<boost::iterator_range<std::string::iterator> > overlap_results;
|
||||
boost::algorithm::find_all(overlap_results, overlap_target, string("aaa"));
|
||||
BOOST_CHECK( overlap_results.size() == 2 );
|
||||
|
||||
std::string overlap_target2("aaaabbbbaaaa");
|
||||
boost::algorithm::find_all(overlap_results, overlap_target2, string("bb"));
|
||||
BOOST_CHECK( overlap_results.size() == 3 );
|
||||
boost::algorithm::find_all(overlap_results, overlap_target2, string("aa"));
|
||||
BOOST_CHECK( overlap_results.size() == 6 );
|
||||
}
|
||||
|
||||
// test main
|
||||
|
@ -46,7 +46,7 @@ void iterator_test()
|
||||
const char* pch1="xx-abc--xx-abb";
|
||||
vector<string> tokens;
|
||||
vector< vector<int> > vtokens;
|
||||
|
||||
|
||||
// find_all tests
|
||||
find_all(
|
||||
tokens,
|
||||
@ -182,7 +182,7 @@ void iterator_test()
|
||||
BOOST_CHECK(siter==split_iterator<string::iterator>());
|
||||
|
||||
// Make sure we work with forward iterators
|
||||
// See bug #7989
|
||||
// See bug #7989
|
||||
list<char> l1;
|
||||
find_iterator<list<char>::iterator> liter=make_find_iterator(l1, first_finder("xx"));
|
||||
}
|
||||
|
@ -42,11 +42,11 @@ void test_ints () {
|
||||
std::vector<int> v;
|
||||
std::list<int> l;
|
||||
|
||||
v.clear (); v.reserve ( 10 );
|
||||
v.clear (); v.resize ( 10 );
|
||||
boost::algorithm::iota ( v.begin (), v.end (), 23 );
|
||||
BOOST_CHECK ( test_iota_results ( v.begin (), v.end (), 23 ));
|
||||
|
||||
v.clear (); v.reserve ( 19 );
|
||||
v.clear (); v.resize ( 19 );
|
||||
boost::algorithm::iota ( v, 18 );
|
||||
BOOST_CHECK ( test_iota_results ( v, 18 ));
|
||||
|
||||
@ -54,6 +54,10 @@ void test_ints () {
|
||||
boost::algorithm::iota_n ( std::back_inserter(v), 99, 20 );
|
||||
BOOST_CHECK ( test_iota_results ( v, 99 ));
|
||||
|
||||
v.clear ();
|
||||
boost::algorithm::iota_n ( std::back_inserter(v), 99, 0 );
|
||||
BOOST_CHECK ( v.size() == 0 );
|
||||
|
||||
/*
|
||||
l.clear (); l.reserve ( 5 );
|
||||
boost::algorithm::iota ( l.begin (), l.end (), 123 );
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/cxx11/is_permutation.hpp>
|
||||
#include <boost/algorithm/cxx14/is_permutation.hpp>
|
||||
|
||||
#define BOOST_TEST_MAIN
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
@ -1,12 +1,21 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2013.
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef ITERATOR_TEST_H
|
||||
#define ITERATOR_TEST_H
|
||||
|
||||
/*
|
||||
A set of iterator adapters for constructing test cases
|
||||
From an iterator (or a pointer), you can make any class of iterator.
|
||||
Assuming you want to degrade the capabilities.
|
||||
|
||||
Modeled closely on work that Howard Hinnant did for libc++.
|
||||
A set of iterator adapters for constructing test cases
|
||||
From an iterator (or a pointer), you can make any class of iterator.
|
||||
Assuming you want to degrade the capabilities.
|
||||
|
||||
Modeled closely on work that Howard Hinnant did for libc++.
|
||||
*/
|
||||
|
||||
#include <iterator>
|
||||
@ -269,10 +278,10 @@ public:
|
||||
private:
|
||||
It it_;
|
||||
template <typename U> friend class output_iterator;
|
||||
};
|
||||
|
||||
// No comparison operators for output iterators
|
||||
|
||||
};
|
||||
|
||||
// No comparison operators for output iterators
|
||||
|
||||
|
||||
// == Get the base of an iterator; used for comparisons ==
|
||||
template <typename Iter>
|
||||
@ -290,7 +299,7 @@ inline Iter base(bidirectional_iterator<Iter> i) { return i.base(); }
|
||||
template <typename Iter>
|
||||
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; }
|
||||
|
||||
#endif // ITERATORS_H
|
||||
|
Reference in New Issue
Block a user