forked from boostorg/algorithm
		
	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 {
 | 
			
		||||
 | 
			
		||||
/// \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 );
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -163,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
 | 
			
		||||
@@ -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
 | 
			
		||||
   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
 | 
			
		||||
 
 | 
			
		||||
@@ -230,7 +230,7 @@ namespace boost {
 | 
			
		||||
    
 | 
			
		||||
                \post eof()==true
 | 
			
		||||
            */
 | 
			
		||||
            split_iterator() {}
 | 
			
		||||
            split_iterator() { m_bEof = true; }
 | 
			
		||||
            //! Copy constructor
 | 
			
		||||
            /*!
 | 
			
		||||
                Construct a copy of the split_iterator
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user