mirror of
https://github.com/boostorg/algorithm.git
synced 2025-07-03 07:46:49 +02:00
Merge from develop: clean up is_permutation; fix clamp interface, and merge fix for bug #9335 as well
This commit is contained in:
@ -31,8 +31,8 @@
|
|||||||
namespace boost { namespace algorithm {
|
namespace boost { namespace algorithm {
|
||||||
|
|
||||||
/// \fn clamp ( T const& val,
|
/// \fn 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 )
|
||||||
/// \return the value "val" brought into the range [ lo, hi ]
|
/// \return the value "val" brought into the range [ lo, hi ]
|
||||||
/// using the comparison predicate p.
|
/// using the comparison predicate p.
|
||||||
/// If p ( val, lo ) return lo.
|
/// If p ( val, lo ) return lo.
|
||||||
@ -56,8 +56,8 @@ namespace boost { namespace algorithm {
|
|||||||
|
|
||||||
|
|
||||||
/// \fn clamp ( T const& val,
|
/// \fn 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 )
|
/// typename boost::mpl::identity<T>::type const & hi )
|
||||||
/// \return the value "val" brought into the range [ lo, hi ].
|
/// \return the value "val" brought into the range [ lo, hi ].
|
||||||
/// If the value is less than lo, return lo.
|
/// If the value is less than lo, return lo.
|
||||||
/// If the value is greater than "hi", return hi.
|
/// 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,
|
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
/// std::iterator_traits<InputIterator>::value_type const & lo,
|
||||||
/// std::iterator_traits<InputIterator>::value_type hi )
|
/// std::iterator_traits<InputIterator>::value_type const & hi )
|
||||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
///
|
///
|
||||||
/// \param first The start of the range of values
|
/// \param first The start of the range of values
|
||||||
@ -88,8 +88,8 @@ namespace boost { namespace algorithm {
|
|||||||
///
|
///
|
||||||
template<typename InputIterator, typename OutputIterator>
|
template<typename InputIterator, typename OutputIterator>
|
||||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
typename std::iterator_traits<InputIterator>::value_type const & lo,
|
||||||
typename std::iterator_traits<InputIterator>::value_type hi )
|
typename std::iterator_traits<InputIterator>::value_type const & hi )
|
||||||
{
|
{
|
||||||
// this could also be written with bind and std::transform
|
// this could also be written with bind and std::transform
|
||||||
while ( first != last )
|
while ( first != last )
|
||||||
@ -98,8 +98,8 @@ namespace boost { namespace algorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
/// \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 const & 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 & hi )
|
||||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
///
|
///
|
||||||
/// \param r The range of values to be clamped
|
/// \param r The range of values to be clamped
|
||||||
@ -110,16 +110,16 @@ namespace boost { namespace algorithm {
|
|||||||
template<typename Range, typename OutputIterator>
|
template<typename Range, typename OutputIterator>
|
||||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
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 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 hi )
|
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 );
|
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
/// std::iterator_traits<InputIterator>::value_type const & lo,
|
||||||
/// std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
/// std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
|
||||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
/// using the comparison predicate p.
|
/// using the comparison predicate p.
|
||||||
///
|
///
|
||||||
@ -134,8 +134,8 @@ 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,
|
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
typename std::iterator_traits<InputIterator>::value_type const & lo,
|
||||||
typename std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p )
|
||||||
{
|
{
|
||||||
// this could also be written with bind and std::transform
|
// this could also be written with bind and std::transform
|
||||||
while ( first != last )
|
while ( first != last )
|
||||||
@ -144,8 +144,8 @@ namespace boost { namespace algorithm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
/// \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 const & 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 & hi,
|
||||||
/// Pred p )
|
/// Pred p )
|
||||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||||
/// using the comparison predicate p.
|
/// using the comparison predicate p.
|
||||||
@ -162,8 +162,8 @@ namespace boost { namespace algorithm {
|
|||||||
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
|
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 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 hi,
|
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type const & hi,
|
||||||
Pred p )
|
Pred p )
|
||||||
{
|
{
|
||||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
|
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
/// \brief Is a sequence a permutation of another sequence
|
/// \brief Is a sequence a permutation of another sequence
|
||||||
/// \author Marshall Clow
|
/// \author Marshall Clow
|
||||||
|
|
||||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
#ifndef BOOST_ALGORITHM_IS_PERMUTATION11_HPP
|
||||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
#define BOOST_ALGORITHM_IS_PERMUTATION11_HPP
|
||||||
|
|
||||||
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
||||||
#include <utility> // for std::make_pair
|
#include <utility> // for std::make_pair
|
||||||
@ -163,56 +163,6 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1, ForwardIt
|
|||||||
|
|
||||||
#endif
|
#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 )
|
/// \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
|
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||||
@ -243,4 +193,4 @@ is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
|||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
#endif // BOOST_ALGORITHM_IS_PERMUTATION11_HPP
|
||||||
|
@ -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
|
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 LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// \file equal.hpp
|
/// \file is_permutation.hpp
|
||||||
/// \brief Determines if one
|
/// \brief Is a sequence a permutation of another sequence (four iterator versions)
|
||||||
/// \author Marshall Clow
|
/// \author Marshall Clow
|
||||||
|
|
||||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
#ifndef BOOST_ALGORITHM_IS_PERMUTATION14_HPP
|
||||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
#define BOOST_ALGORITHM_IS_PERMUTATION14_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
||||||
#include <functional> // for std::equal_to
|
#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 boost { namespace algorithm {
|
||||||
|
|
||||||
namespace detail {
|
#if __cplusplus <= 201103L
|
||||||
|
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
|
||||||
template <class T1, class T2>
|
/// ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||||
struct is_perm_eq : public std::binary_function<T1, T2, bool> {
|
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2
|
||||||
bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;}
|
///
|
||||||
};
|
/// \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
|
||||||
template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
|
/// \param last1 One past the end of the second sequence
|
||||||
bool is_permutation ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
|
/// \note This function is part of the C++2014 standard library.
|
||||||
RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
|
/// We will use the standard one if it is available,
|
||||||
std::random_access_iterator_tag, std::random_access_iterator_tag )
|
/// otherwise we have our own implementation.
|
||||||
{
|
template< class ForwardIterator1, class ForwardIterator2 >
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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>
|
|
||||||
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||||
ForwardIterator2 first2, ForwardIterator2 last2 )
|
ForwardIterator2 first2, ForwardIterator2 last2 )
|
||||||
{
|
{
|
||||||
typedef typename iterator_traits<_ForwardIterator1>::value_type value1_t;
|
// How should I deal with the idea that ForwardIterator1::value_type
|
||||||
typedef typename iterator_traits<_ForwardIterator2>::value_type value2_t;
|
// and ForwardIterator2::value_type could be different? Define my own comparison predicate?
|
||||||
return boost::algorithm::detail::is_permutation (
|
std::pair<ForwardIterator1, ForwardIterator2> eq = boost::algorithm::mismatch
|
||||||
first1, last1, first2, last2,
|
( first1, last1, first2, last2 );
|
||||||
boost::algorithm::detail::is_perm_eq<
|
if ( eq.first == last1 && eq.second == last2)
|
||||||
typename std::iterator_traits<InputIterator1>::value_type,
|
return true;
|
||||||
typename std::iterator_traits<InputIterator2>::value_type> (),
|
return boost::algorithm::detail::is_permutation_tag (
|
||||||
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
eq.first, last1, eq.second, last2,
|
||||||
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> (),
|
||||||
|
typename std::iterator_traits<ForwardIterator1>::iterator_category (),
|
||||||
|
typename std::iterator_traits<ForwardIterator2>::iterator_category ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are already range-based versions of these.
|
/// \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,
|
||||||
|
BinaryPredicate pred )
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
}} // namespace boost and algorithm
|
}}
|
||||||
|
|
||||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
#endif // BOOST_ALGORITHM_IS_PERMUTATION14_HPP
|
||||||
|
@ -230,7 +230,7 @@ namespace boost {
|
|||||||
|
|
||||||
\post eof()==true
|
\post eof()==true
|
||||||
*/
|
*/
|
||||||
split_iterator() {}
|
split_iterator() { m_bEof = true; }
|
||||||
//! Copy constructor
|
//! Copy constructor
|
||||||
/*!
|
/*!
|
||||||
Construct a copy of the split_iterator
|
Construct a copy of the split_iterator
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/algorithm/cxx11/is_permutation.hpp>
|
#include <boost/algorithm/cxx11/is_permutation.hpp>
|
||||||
|
#include <boost/algorithm/cxx14/is_permutation.hpp>
|
||||||
|
|
||||||
#define BOOST_TEST_MAIN
|
#define BOOST_TEST_MAIN
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
Reference in New Issue
Block a user