Compare commits

..

1 Commits

Author SHA1 Message Date
ce9a8400e5 Release 1.55.0
[SVN r86621]
2013-11-11 19:45:21 +00:00
15 changed files with 338 additions and 119 deletions

View File

@ -19,11 +19,11 @@ The function `is_sorted(sequence)` determines whether or not a sequence is compl
`` ``
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
template <typename ForwardIterator, typename Pred> template <typename Iterator, typename Pred>
bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p ); bool is_sorted ( Iterator first, Iterator last, Pred p );
template <typename ForwardIterator> template <typename Iterator>
bool is_sorted ( ForwardIterator first, ForwardIterator last ); bool is_sorted ( Iterator first, Iterator last );
template <typename Range, typename Pred> template <typename Range, typename Pred>
@ -34,7 +34,7 @@ namespace boost { namespace algorithm {
}} }}
`` ``
Iterator requirements: The `is_sorted` functions will work forward iterators or better. Iterator requirements: The `is_sorted` functions will work on all kinds of iterators (except output iterators).
[heading is_sorted_until] [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 { namespace boost { namespace algorithm {
template <typename ForwardIterator> template <typename Iterator>
bool is_decreasing ( ForwardIterator first, ForwardIterator last ); bool is_decreasing ( Iterator first, Iterator last );
template <typename R> template <typename R>
bool is_decreasing ( const R &range ); 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): To test if a sequence is strictly increasing (each element larger than the preceding one):
`` ``
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
template <typename ForwardIterator> template <typename Iterator>
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last ); bool is_strictly_increasing ( Iterator first, Iterator last );
template <typename R> template <typename R>
bool is_strictly_increasing ( const R &range ); 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): To test if a sequence is strictly decreasing (each element smaller than the preceding one):
`` ``
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
template <typename ForwardIterator> template <typename Iterator>
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last ); bool is_strictly_decreasing ( Iterator first, Iterator last );
template <typename R> template <typename R>
bool is_strictly_decreasing ( const R &range ); bool is_strictly_decreasing ( const R &range );

View File

@ -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 const & lo, /// std::iterator_traits<InputIterator>::value_type lo,
/// std::iterator_traits<InputIterator>::value_type const & hi ) /// std::iterator_traits<InputIterator>::value_type 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 const & lo, typename std::iterator_traits<InputIterator>::value_type lo,
typename std::iterator_traits<InputIterator>::value_type const & hi ) typename std::iterator_traits<InputIterator>::value_type 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 const & lo, /// 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 & hi ) /// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type 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 const & lo, 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 & hi ) typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type 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 const & lo, /// std::iterator_traits<InputIterator>::value_type lo,
/// std::iterator_traits<InputIterator>::value_type const & hi, Pred p ) /// std::iterator_traits<InputIterator>::value_type 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 const & lo, typename std::iterator_traits<InputIterator>::value_type lo,
typename std::iterator_traits<InputIterator>::value_type const & hi, Pred p ) typename std::iterator_traits<InputIterator>::value_type 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 const & lo, /// 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 & hi, /// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type 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 const & lo, 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 & hi, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type 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 );

View File

@ -63,8 +63,8 @@ void iota ( Range &r, T value )
template <typename OutputIterator, typename T> template <typename OutputIterator, typename T>
OutputIterator iota_n ( OutputIterator out, T value, std::size_t n ) OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
{ {
for ( ; n > 0; --n, ++value ) while ( n-- > 0 )
*out++ = value; *out++ = value++;
return out; return out;
} }

View File

@ -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_PERMUTATION11_HPP #ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
#define BOOST_ALGORITHM_IS_PERMUTATION11_HPP #define BOOST_ALGORITHM_IS_PERMUTATION_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
@ -21,6 +21,7 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <boost/tr1/tr1/tuple> // for tie
namespace boost { namespace algorithm { namespace boost { namespace algorithm {
@ -120,6 +121,7 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, BinaryPredicate p ) ForwardIterator2 first2, BinaryPredicate p )
{ {
// Skip the common prefix (if any) // 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); std::pair<ForwardIterator1, ForwardIterator2> eq = std::mismatch (first1, last1, first2, p);
first1 = eq.first; first1 = eq.first;
first2 = eq.second; first2 = eq.second;
@ -163,6 +165,56 @@ 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
@ -193,4 +245,4 @@ is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
}} }}
#endif // BOOST_ALGORITHM_IS_PERMUTATION11_HPP #endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP

View File

@ -1,86 +1,130 @@
/* /*
Copyright (c) Marshall Clow 2014. Copyright (c) Marshall Clow 2013
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 is_permutation.hpp /// \file equal.hpp
/// \brief Is a sequence a permutation of another sequence (four iterator versions) /// \brief Determines if one
/// \author Marshall Clow /// \author Marshall Clow
#ifndef BOOST_ALGORITHM_IS_PERMUTATION14_HPP #ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
#define BOOST_ALGORITHM_IS_PERMUTATION14_HPP #define BOOST_ALGORITHM_IS_PERMUTATION_HPP
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available) #include <algorithm>
#include <utility> // for std::make_pair #include <functional> // for std::equal_to
#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 {
#if __cplusplus <= 201103L namespace detail {
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
/// ForwardIterator2 first2, ForwardIterator2 last2 ) template <class T1, class T2>
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2 struct is_perm_eq : public std::binary_function<T1, T2, bool> {
/// 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
/// \param last1 One past the end of the second sequence template <class RandomAccessIterator1, class RandomAccessIterator2, class BinaryPredicate>
/// \note This function is part of the C++2014 standard library. bool is_permutation ( RandomAccessIterator1 first1, RandomAccessIterator1 last1,
/// We will use the standard one if it is available, RandomAccessIterator2 first2, RandomAccessIterator2 last2, BinaryPredicate pred,
/// otherwise we have our own implementation. std::random_access_iterator_tag, std::random_access_iterator_tag )
template< class ForwardIterator1, class ForwardIterator2 > {
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1, // Random-access iterators let is check the sizes in constant time
ForwardIterator2 first2, ForwardIterator2 last2 ) if ( std::distance ( first1, last1 ) != std::distance ( first2, last2 ))
{ return false;
// How should I deal with the idea that ForwardIterator1::value_type // If we know that the sequences are the same size, the original version is fine
// and ForwardIterator2::value_type could be different? Define my own comparison predicate? return std::is_permutation ( first1, last1, first2, pred );
std::pair<ForwardIterator1, ForwardIterator2> eq = boost::algorithm::mismatch }
( first1, last1, first2, last2 );
if ( eq.first == last1 && eq.second == last2)
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; 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 ());
} }
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last,
/// ForwardIterator2 first2, ForwardIterator2 last2, template<class ForwardIterator1, class ForwardIterator2, class BinaryPredicate>
/// BinaryPredicate p ) bool is_permutation (
/// \brief Tests to see if the sequence [first,last) is a permutation of the sequence starting at first2 ForwardIterator1 first1, ForwardIterator1 last1,
/// ForwardIterator2 first2, ForwardIterator2 last2,
/// \param first1 The start of the input sequence BinaryPredicate pred )
/// \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 return boost::algorithm::detail::is_permutation (
( first1, last1, first2, last2, pred ); first1, last1, first2, last2, pred,
if ( eq.first == last1 && eq.second == last2) typename std::iterator_traits<ForwardIterator1>::iterator_category (),
return true; typename std::iterator_traits<ForwardIterator2>::iterator_category ());
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
}} template<class ForwardIterator1, class ForwardIterator2>
bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
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 ());
}
#endif // BOOST_ALGORITHM_IS_PERMUTATION14_HPP // There are already range-based versions of these.
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP

View File

@ -20,11 +20,7 @@
#include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_const.hpp>
#include <boost/array.hpp> #include <boost/array.hpp>
#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
#include <boost/tr1/tr1/unordered_map> #include <boost/tr1/tr1/unordered_map>
#else
#include <unordered_map>
#endif
#include <boost/algorithm/searching/detail/debugging.hpp> #include <boost/algorithm/searching/detail/debugging.hpp>
@ -39,11 +35,7 @@ namespace boost { namespace algorithm { namespace detail {
template<typename key_type, typename value_type> template<typename key_type, typename value_type>
class skip_table<key_type, value_type, false> { class skip_table<key_type, value_type, false> {
private: private:
#ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
typedef std::tr1::unordered_map<key_type, value_type> skip_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; const value_type k_default_value;
skip_map skip_; skip_map skip_;

View File

@ -622,6 +622,8 @@ namespace boost {
{ {
#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 ) #if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 )
return iterator_range<const ForwardIterator2T>(this->m_Range); 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 #else
return m_Range; return m_Range;
#endif #endif

View File

@ -230,7 +230,7 @@ namespace boost {
\post eof()==true \post eof()==true
*/ */
split_iterator() { m_bEof = true; } split_iterator() {}
//! Copy constructor //! Copy constructor
/*! /*!
Construct a copy of the split_iterator Construct a copy of the split_iterator

View File

@ -36,6 +36,47 @@ namespace boost {
// sequence traits -----------------------------------------------// // 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 //! Native replace trait
/*! /*!
@ -45,12 +86,20 @@ namespace boost {
class has_native_replace 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: public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false }; enum { value = false };
# else # else
BOOST_STATIC_CONSTANT(bool, value=false); BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
typedef mpl::bool_<has_native_replace<T>::value> type; typedef mpl::bool_<has_native_replace<T>::value> type;
@ -65,12 +114,20 @@ namespace boost {
template< typename T > template< typename T >
class has_stable_iterators 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: public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false }; enum { value = false };
# else # else
BOOST_STATIC_CONSTANT(bool, value=false); BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
typedef mpl::bool_<has_stable_iterators<T>::value> type; typedef mpl::bool_<has_stable_iterators<T>::value> type;
}; };
@ -84,12 +141,20 @@ namespace boost {
template< typename T > template< typename T >
class has_const_time_insert 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: public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false }; enum { value = false };
# else # else
BOOST_STATIC_CONSTANT(bool, value=false); BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
typedef mpl::bool_<has_const_time_insert<T>::value> type; typedef mpl::bool_<has_const_time_insert<T>::value> type;
}; };
@ -103,12 +168,20 @@ namespace boost {
template< typename T > template< typename T >
class has_const_time_erase 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: public:
# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # if BOOST_WORKAROUND( __IBMCPP__, <= 600 )
enum { value = false }; enum { value = false };
# else # else
BOOST_STATIC_CONSTANT(bool, value=false); BOOST_STATIC_CONSTANT(bool, value=false);
# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) # endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
typedef mpl::bool_<has_const_time_erase<T>::value> type; typedef mpl::bool_<has_const_time_erase<T>::value> type;
}; };

View File

@ -20,6 +20,22 @@ namespace boost {
// std::list<> traits -----------------------------------------------// // 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 // stable iterators trait
template<typename T, typename AllocT> template<typename T, typename AllocT>
@ -59,6 +75,7 @@ namespace boost {
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) #endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_erase<T>::value> type; typedef mpl::bool_<has_const_time_erase<T>::value> type;
}; };
#endif
} // namespace algorithm } // namespace algorithm

View File

@ -20,6 +20,25 @@ namespace boost {
// SGI's std::rope<> traits -----------------------------------------------// // 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 // native replace trait
template<typename T, typename TraitsT, typename AllocT> template<typename T, typename TraitsT, typename AllocT>
@ -72,6 +91,7 @@ namespace boost {
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) #endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<value> type; typedef mpl::bool_<value> type;
}; };
#endif
} // namespace algorithm } // namespace algorithm

View File

@ -21,6 +21,21 @@ namespace boost {
// SGI's std::slist<> traits -----------------------------------------------// // 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 // stable iterators trait
template<typename T, typename AllocT> template<typename T, typename AllocT>
@ -60,6 +75,7 @@ namespace boost {
#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) #endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 )
typedef mpl::bool_<has_const_time_erase<T>::value> type; typedef mpl::bool_<has_const_time_erase<T>::value> type;
}; };
#endif
} // namespace algorithm } // namespace algorithm

View File

@ -20,6 +20,13 @@ namespace boost {
// std::basic_string<> traits -----------------------------------------------// // 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 // native replace trait
template<typename T, typename TraitsT, typename AllocT> template<typename T, typename TraitsT, typename AllocT>
@ -36,6 +43,7 @@ namespace boost {
}; };
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
} // namespace algorithm } // namespace algorithm
} // namespace boost } // namespace boost

View File

@ -42,11 +42,11 @@ void test_ints () {
std::vector<int> v; std::vector<int> v;
std::list<int> l; std::list<int> l;
v.clear (); v.resize ( 10 ); v.clear (); v.reserve ( 10 );
boost::algorithm::iota ( v.begin (), v.end (), 23 ); boost::algorithm::iota ( v.begin (), v.end (), 23 );
BOOST_CHECK ( test_iota_results ( v.begin (), v.end (), 23 )); BOOST_CHECK ( test_iota_results ( v.begin (), v.end (), 23 ));
v.clear (); v.resize ( 19 ); v.clear (); v.reserve ( 19 );
boost::algorithm::iota ( v, 18 ); boost::algorithm::iota ( v, 18 );
BOOST_CHECK ( test_iota_results ( v, 18 )); BOOST_CHECK ( test_iota_results ( v, 18 ));
@ -54,10 +54,6 @@ void test_ints () {
boost::algorithm::iota_n ( std::back_inserter(v), 99, 20 ); boost::algorithm::iota_n ( std::back_inserter(v), 99, 20 );
BOOST_CHECK ( test_iota_results ( v, 99 )); 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 ); l.clear (); l.reserve ( 5 );
boost::algorithm::iota ( l.begin (), l.end (), 123 ); boost::algorithm::iota ( l.begin (), l.end (), 123 );

View File

@ -11,7 +11,6 @@
#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>