diff --git a/include/boost/algorithm/clamp.hpp b/include/boost/algorithm/clamp.hpp index ae98d15..7bfa47e 100644 --- a/include/boost/algorithm/clamp.hpp +++ b/include/boost/algorithm/clamp.hpp @@ -31,8 +31,8 @@ namespace boost { namespace algorithm { /// \fn clamp ( T const& val, -/// typename boost::mpl::identity::type const& lo, -/// typename boost::mpl::identity::type const& hi, Pred p ) +/// typename boost::mpl::identity::type const & lo, +/// typename boost::mpl::identity::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::type const& lo, -/// typename boost::mpl::identity::type const& hi ) +/// typename boost::mpl::identity::type const & lo, +/// typename boost::mpl::identity::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::value_type lo, -/// std::iterator_traits::value_type hi ) +/// std::iterator_traits::value_type const & lo, +/// std::iterator_traits::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 OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, - typename std::iterator_traits::value_type lo, - typename std::iterator_traits::value_type hi ) + typename std::iterator_traits::value_type const & lo, + typename std::iterator_traits::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::type>::value_type lo, -/// typename std::iterator_traits::type>::value_type hi ) +/// typename std::iterator_traits::type>::value_type const & lo, +/// typename std::iterator_traits::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 boost::disable_if_c::value, OutputIterator>::type clamp_range ( const Range &r, OutputIterator out, - typename std::iterator_traits::type>::value_type lo, - typename std::iterator_traits::type>::value_type hi ) + typename std::iterator_traits::type>::value_type const & lo, + typename std::iterator_traits::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::value_type lo, -/// std::iterator_traits::value_type hi, Pred p ) +/// std::iterator_traits::value_type const & lo, +/// std::iterator_traits::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 OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, - typename std::iterator_traits::value_type lo, - typename std::iterator_traits::value_type hi, Pred p ) + typename std::iterator_traits::value_type const & lo, + typename std::iterator_traits::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::type>::value_type lo, -/// typename std::iterator_traits::type>::value_type hi, +/// typename std::iterator_traits::type>::value_type const & lo, +/// typename std::iterator_traits::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 boost::disable_if_c::value, OutputIterator>::type clamp_range ( const Range &r, OutputIterator out, - typename std::iterator_traits::type>::value_type lo, - typename std::iterator_traits::type>::value_type hi, + typename std::iterator_traits::type>::value_type const & lo, + typename std::iterator_traits::type>::value_type const & hi, Pred p ) { return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p ); diff --git a/include/boost/algorithm/cxx11/is_permutation.hpp b/include/boost/algorithm/cxx11/is_permutation.hpp index 3eff5ce..9b3bc22 100644 --- a/include/boost/algorithm/cxx11/is_permutation.hpp +++ b/include/boost/algorithm/cxx11/is_permutation.hpp @@ -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 // for std::less, tie, mismatch and is_permutation (if available) #include // 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::value_type> (), - typename std::iterator_traits::iterator_category (), - typename std::iterator_traits::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::iterator_category (), - typename std::iterator_traits::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 diff --git a/include/boost/algorithm/cxx14/is_permutation.hpp b/include/boost/algorithm/cxx14/is_permutation.hpp index 779acef..d8002cb 100644 --- a/include/boost/algorithm/cxx14/is_permutation.hpp +++ b/include/boost/algorithm/cxx14/is_permutation.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 -#include // for std::equal_to +#include // for std::less, tie, mismatch and is_permutation (if available) +#include // for std::make_pair +#include // for std::equal_to +#include + +#include +#include namespace boost { namespace algorithm { -namespace detail { - - template - struct is_perm_eq : public std::binary_function { - bool operator () ( const T1& v1, const T2& v2 ) const { return v1 == v2 ;} - }; - - - template - 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 - 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::difference_type diff1_t; - diff1_t len1 = _VSTD::distance(first1, last1); - typedef typename std::iterator_traits::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 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::value_type> (), + typename std::iterator_traits::iterator_category (), + typename std::iterator_traits::iterator_category ()); } - -template -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::iterator_category (), - typename std::iterator_traits::iterator_category ()); -} - -template +/// \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::value_type, - typename std::iterator_traits::value_type> (), - typename std::iterator_traits::iterator_category (), - typename std::iterator_traits::iterator_category ()); + std::pair 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::iterator_category (), + typename std::iterator_traits::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 diff --git a/include/boost/algorithm/string/find_iterator.hpp b/include/boost/algorithm/string/find_iterator.hpp index 1502c7d..5834407 100644 --- a/include/boost/algorithm/string/find_iterator.hpp +++ b/include/boost/algorithm/string/find_iterator.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 diff --git a/test/is_permutation_test1.cpp b/test/is_permutation_test1.cpp index e819643..2e1a12f 100644 --- a/test/is_permutation_test1.cpp +++ b/test/is_permutation_test1.cpp @@ -11,6 +11,7 @@ #include #include +#include #define BOOST_TEST_MAIN #include