Merge to master for 1.62.0 release

This commit is contained in:
Marshall Clow
2016-08-17 13:32:45 -07:00
47 changed files with 1105 additions and 225 deletions

View File

@@ -17,6 +17,8 @@
#ifndef BOOST_ALGORITHM_HPP
#define BOOST_ALGORITHM_HPP
#include <functional> // for plus and multiplies
#include <boost/utility/enable_if.hpp> // for boost::disable_if
#include <boost/type_traits/is_integral.hpp>
@@ -56,7 +58,7 @@ power (T x, Integer n) {
/// \fn power ( T x, Integer n, Operation op )
/// \return the value "x" raised to the power "n"
/// using the operaton "op".
/// using the operation "op".
///
/// \param x The value to be exponentiated
/// \param n The exponent (must be >= 0)

View File

@@ -12,7 +12,6 @@
#ifndef BOOST_ALGORITHM_ALL_OF_HPP
#define BOOST_ALGORITHM_ALL_OF_HPP
#include <algorithm> // for std::all_of, if available
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -27,8 +26,6 @@ namespace boost { namespace algorithm {
/// \param p A predicate for testing the elements of the 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<typename InputIterator, typename Predicate>
bool all_of ( InputIterator first, InputIterator last, Predicate p )
{

View File

@@ -14,7 +14,6 @@
#ifndef BOOST_ALGORITHM_ANY_OF_HPP
#define BOOST_ALGORITHM_ANY_OF_HPP
#include <algorithm> // for std::any_of, if available
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>

View File

@@ -12,7 +12,7 @@
#ifndef BOOST_ALGORITHM_COPY_IF_HPP
#define BOOST_ALGORITHM_COPY_IF_HPP
#include <algorithm> // for std::copy_if, if available
#include <utility> // for std::pair, std::make_pair
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -28,8 +28,6 @@ namespace boost { namespace algorithm {
/// \param result An output iterator to write the results into
/// \param p A predicate for testing the elements of the range
/// \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<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
{

View File

@@ -12,8 +12,6 @@
#ifndef BOOST_ALGORITHM_COPY_N_HPP
#define BOOST_ALGORITHM_COPY_N_HPP
#include <algorithm> // for std::copy_n, if available
namespace boost { namespace algorithm {
/// \fn copy_n ( InputIterator first, Size n, OutputIterator result )
@@ -25,8 +23,6 @@ namespace boost { namespace algorithm {
/// \param n The number of elements to copy
/// \param result An output iterator to write the results into
/// \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 <typename InputIterator, typename Size, typename OutputIterator>
OutputIterator copy_n ( InputIterator first, Size n, OutputIterator result )
{

View File

@@ -12,8 +12,6 @@
#ifndef BOOST_ALGORITHM_FIND_IF_NOT_HPP
#define BOOST_ALGORITHM_FIND_IF_NOT_HPP
#include <algorithm> // for std::find_if_not, if it exists
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -27,8 +25,6 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the input sequence
/// \param p A predicate for testing the elements of the range
/// \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<typename InputIterator, typename Predicate>
InputIterator find_if_not ( InputIterator first, InputIterator last, Predicate p )
{

View File

@@ -12,8 +12,6 @@
#ifndef BOOST_ALGORITHM_IOTA_HPP
#define BOOST_ALGORITHM_IOTA_HPP
#include <numeric>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -26,8 +24,6 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the input sequence
/// \param value The initial value of the sequence to be generated
/// \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 <typename ForwardIterator, typename T>
void iota ( ForwardIterator first, ForwardIterator last, T value )
{

View File

@@ -12,8 +12,6 @@
#ifndef BOOST_ALGORITHM_IS_PARTITIONED_HPP
#define BOOST_ALGORITHM_IS_PARTITIONED_HPP
#include <algorithm> // for std::is_partitioned, if available
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -26,8 +24,6 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the input sequence
/// \param p The predicate to test the values 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 <typename InputIterator, typename UnaryPredicate>
bool is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
{

View File

@@ -12,8 +12,8 @@
#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
#include <algorithm> // for std::find_if, count_if, mismatch
#include <utility> // for std::pair
#include <functional> // for std::equal_to
#include <iterator>
@@ -108,8 +108,6 @@ namespace detail {
/// \param p 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, BinaryPredicate p )
@@ -135,8 +133,6 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
/// \param last2 One past the end of the input sequence
/// \param first2 The start 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 )
{

View File

@@ -13,7 +13,6 @@
#ifndef BOOST_ALGORITHM_ORDERED_HPP
#define BOOST_ALGORITHM_ORDERED_HPP
#include <algorithm>
#include <functional>
#include <iterator>

View File

@@ -12,7 +12,6 @@
#ifndef BOOST_ALGORITHM_NONE_OF_HPP
#define BOOST_ALGORITHM_NONE_OF_HPP
#include <algorithm> // for std::none_of, if available
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -29,9 +28,9 @@ namespace boost { namespace algorithm {
template<typename InputIterator, typename Predicate>
bool none_of ( InputIterator first, InputIterator last, Predicate p )
{
for ( ; first != last; ++first )
if ( p(*first))
return false;
for ( ; first != last; ++first )
if ( p(*first))
return false;
return true;
}

View File

@@ -12,8 +12,7 @@
#ifndef BOOST_ALGORITHM_PARTITION_COPY_HPP
#define BOOST_ALGORITHM_PARTITION_COPY_HPP
#include <algorithm> // for std::partition_copy, if available
#include <utility> // for make_pair
#include <utility> // for std::pair
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -34,8 +33,6 @@ namespace boost { namespace algorithm {
/// \param p A predicate for dividing the elements of the input 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 <typename InputIterator,
typename OutputIterator1, typename OutputIterator2, typename UnaryPredicate>
std::pair<OutputIterator1, OutputIterator2>

View File

@@ -12,7 +12,7 @@
#ifndef BOOST_ALGORITHM_PARTITION_POINT_HPP
#define BOOST_ALGORITHM_PARTITION_POINT_HPP
#include <algorithm> // for std::partition_point, if available
#include <iterator> // for std::distance, advance
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
@@ -27,8 +27,6 @@ namespace boost { namespace algorithm {
/// \param last One past the end of the input sequence
/// \param p The predicate to test the values 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 <typename ForwardIterator, typename Predicate>
ForwardIterator partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
{

View File

@@ -13,7 +13,8 @@
#define BOOST_ALGORITHM_EQUAL_HPP
#include <algorithm> // for std::equal
#include <functional> // for std::equal_to
#include <functional> // for std::binary_function
#include <iterator>
namespace boost { namespace algorithm {

View File

@@ -12,8 +12,7 @@
#ifndef BOOST_ALGORITHM_IS_PERMUTATION14_HPP
#define BOOST_ALGORITHM_IS_PERMUTATION14_HPP
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
#include <utility> // for std::make_pair
#include <utility> // for std::pair
#include <functional> // for std::equal_to
#include <iterator>
@@ -31,8 +30,6 @@ namespace boost { namespace algorithm {
/// \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 )
@@ -62,8 +59,6 @@ bool is_permutation ( ForwardIterator1 first1, ForwardIterator1 last1,
/// \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,

View File

@@ -12,7 +12,6 @@
#ifndef BOOST_ALGORITHM_MISMATCH_HPP
#define BOOST_ALGORITHM_MISMATCH_HPP
#include <algorithm> // for std::mismatch
#include <utility> // for std::pair
namespace boost { namespace algorithm {

View File

@@ -1,9 +1,9 @@
/*
/*
Copyright (c) Marshall Clow 2011-2012.
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)
Thanks to Nevin for his comments/help.
*/
@@ -13,7 +13,7 @@
*/
/// \file hex.hpp
/// \brief Convert sequence of integral types into a sequence of hexadecimal
/// \brief Convert sequence of integral types into a sequence of hexadecimal
/// characters and back. Based on the MySQL functions HEX and UNHEX
/// \author Marshall Clow
@@ -25,7 +25,9 @@
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/exception/all.hpp>
#include <boost/exception/exception.hpp>
#include <boost/exception/info.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
@@ -33,17 +35,17 @@
namespace boost { namespace algorithm {
/*!
\struct hex_decode_error
\brief Base exception class for all hex decoding errors
/*!
\struct hex_decode_error
\brief Base exception class for all hex decoding errors
*/ /*!
\struct non_hex_input
\struct non_hex_input
\brief Thrown when a non-hex value (0-9, A-F) encountered when decoding.
Contains the offending character
*/ /*!
\struct not_enough_input
*/ /*!
\struct not_enough_input
\brief Thrown when the input sequence unexpectedly ends
*/
struct hex_decode_error : virtual boost::exception, virtual std::exception {};
struct not_enough_input : virtual hex_decode_error {};
@@ -54,12 +56,12 @@ namespace detail {
/// \cond DOXYGEN_HIDE
template <typename T, typename OutputIterator>
OutputIterator encode_one ( T val, OutputIterator out ) {
OutputIterator encode_one ( T val, OutputIterator out, const char * hexDigits ) {
const std::size_t num_hex_digits = 2 * sizeof ( T );
char res [ num_hex_digits ];
char *p = res + num_hex_digits;
for ( std::size_t i = 0; i < num_hex_digits; ++i, val >>= 4 )
*--p = "0123456789ABCDEF" [ val & 0x0F ];
*--p = hexDigits [ val & 0x0F ];
return std::copy ( res, res + num_hex_digits, out );
}
@@ -106,12 +108,12 @@ namespace detail {
typedef T value_type;
};
template <typename Iterator>
template <typename Iterator>
bool iter_end ( Iterator current, Iterator last ) { return current == last; }
template <typename T>
bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
// What can we assume here about the inputs?
// is std::iterator_traits<InputIterator>::value_type always 'char' ?
// Could it be wchar_t, say? Does it matter?
@@ -124,11 +126,11 @@ namespace detail {
// Need to make sure that we get can read that many chars here.
for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
if ( pred ( first, last ))
if ( pred ( first, last ))
BOOST_THROW_EXCEPTION (not_enough_input ());
res = ( 16 * res ) + hex_char_to_int (*first);
}
*out = res;
return ++out;
}
@@ -138,7 +140,7 @@ namespace detail {
/// \fn hex ( InputIterator first, InputIterator last, OutputIterator out )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out An output iterator to the results into
@@ -148,14 +150,31 @@ template <typename InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
hex ( InputIterator first, InputIterator last, OutputIterator out ) {
for ( ; first != last; ++first )
out = detail::encode_one ( *first, out );
out = detail::encode_one ( *first, out, "0123456789ABCDEF" );
return out;
}
/// \fn hex_lower ( InputIterator first, InputIterator last, OutputIterator out )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename InputIterator, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<InputIterator>::value_type>, OutputIterator>::type
hex_lower ( InputIterator first, InputIterator last, OutputIterator out ) {
for ( ; first != last; ++first )
out = detail::encode_one ( *first, out, "0123456789abcdef" );
return out;
}
/// \fn hex ( const T *ptr, OutputIterator out )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
///
/// \param ptr A pointer to a 0-terminated sequence of data.
/// \param out An output iterator to the results into
/// \return The updated output iterator
@@ -164,13 +183,30 @@ template <typename T, typename OutputIterator>
typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
hex ( const T *ptr, OutputIterator out ) {
while ( *ptr )
out = detail::encode_one ( *ptr++, out );
out = detail::encode_one ( *ptr++, out, "0123456789ABCDEF" );
return out;
}
/// \fn hex_lower ( const T *ptr, OutputIterator out )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param ptr A pointer to a 0-terminated sequence of data.
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename T, typename OutputIterator>
typename boost::enable_if<boost::is_integral<T>, OutputIterator>::type
hex_lower ( const T *ptr, OutputIterator out ) {
while ( *ptr )
out = detail::encode_one ( *ptr++, out, "0123456789abcdef" );
return out;
}
/// \fn hex ( const Range &r, OutputIterator out )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
///
/// \param r The input range
/// \param out An output iterator to the results into
/// \return The updated output iterator
@@ -182,9 +218,23 @@ hex ( const Range &r, OutputIterator out ) {
}
/// \fn hex_lower ( const Range &r, OutputIterator out )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param r The input range
/// \param out An output iterator to the results into
/// \return The updated output iterator
/// \note Based on the MySQL function of the same name
template <typename Range, typename OutputIterator>
typename boost::enable_if<boost::is_integral<typename detail::hex_iterator_traits<typename Range::iterator>::value_type>, OutputIterator>::type
hex_lower ( const Range &r, OutputIterator out ) {
return hex_lower (boost::begin(r), boost::end(r), out);
}
/// \fn unhex ( InputIterator first, InputIterator last, OutputIterator out )
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
///
///
/// \param first The start of the input sequence
/// \param last One past the end of the input sequence
/// \param out An output iterator to the results into
@@ -200,7 +250,7 @@ OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator o
/// \fn unhex ( const T *ptr, OutputIterator out )
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
///
///
/// \param ptr A pointer to a null-terminated input sequence.
/// \param out An output iterator to the results into
/// \return The updated output iterator
@@ -218,7 +268,7 @@ OutputIterator unhex ( const T *ptr, OutputIterator out ) {
/// \fn OutputIterator unhex ( const Range &r, OutputIterator out )
/// \brief Converts a sequence of hexadecimal characters into a sequence of integers.
///
///
/// \param r The input range
/// \param out An output iterator to the results into
/// \return The updated output iterator
@@ -231,7 +281,7 @@ OutputIterator unhex ( const Range &r, OutputIterator out ) {
/// \fn String hex ( const String &input )
/// \brief Converts a sequence of integral types into a hexadecimal sequence of characters.
///
///
/// \param input A container to be converted
/// \return A container with the encoded text
template<typename String>
@@ -242,9 +292,24 @@ String hex ( const String &input ) {
return output;
}
/// \fn String hex_lower ( const String &input )
/// \brief Converts a sequence of integral types into a lower case hexadecimal sequence of characters.
///
/// \param input A container to be converted
/// \return A container with the encoded text
template<typename String>
String hex_lower ( const String &input ) {
String output;
output.reserve (input.size () * (2 * sizeof (typename String::value_type)));
(void) hex_lower (input, std::back_inserter (output));
return output;
}
/// \fn String unhex ( const String &input )
/// \brief Converts a sequence of hexadecimal characters into a sequence of characters.
///
///
/// \param input A container to be converted
/// \return A container with the decoded text
template<typename String>

View File

@@ -0,0 +1,108 @@
/*
Copyright (c) Alexander Zaitsev <zamazan4ik@gmail.com>, 2016
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)
See http://www.boost.org/ for latest version.
*/
/// \file is_palindrome.hpp
/// \brief Checks the input sequence on palindrome.
/// \author Alexander Zaitsev
#ifndef BOOST_ALGORITHM_IS_PALINDROME_HPP
#define BOOST_ALGORITHM_IS_PALINDROME_HPP
#include <iterator>
#include <functional>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn is_palindrome ( BidirectionalIterator begin, BidirectionalIterator end, Predicate p )
/// \return true if the entire sequence is palindrome
///
/// \param begin The start of the input sequence
/// \param end One past the end of the input sequence
/// \param p A predicate used to compare the values.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename BidirectionalIterator, typename Predicate>
bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end, Predicate p)
{
if(begin == end)
{
return true;
}
--end;
while(begin != end)
{
if(!p(*begin, *end))
{
return false;
}
++begin;
if(begin == end)
{
break;
}
--end;
}
return true;
}
/// \fn is_palindrome ( BidirectionalIterator begin, BidirectionalIterator end )
/// \return true if the entire sequence is palindrome
///
/// \param begin The start of the input sequence
/// \param end One past the end of the input sequence
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename BidirectionalIterator>
bool is_palindrome(BidirectionalIterator begin, BidirectionalIterator end)
{
return is_palindrome(begin, end,
std::equal_to<typename std::iterator_traits<BidirectionalIterator>::value_type> ());
}
/// \fn is_palindrome ( const R& range )
/// \return true if the entire sequence is palindrome
///
/// \param range The range to be tested.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename R>
bool is_palindrome(const R& range)
{
return is_palindrome(boost::begin(range), boost::end(range));
}
/// \fn is_palindrome ( const R& range, Predicate p )
/// \return true if the entire sequence is palindrome
///
/// \param range The range to be tested.
/// \param p A predicate used to compare the values.
///
/// \note This function will return true for empty sequences and for palindromes.
/// For other sequences function will return false.
/// Complexity: O(N).
template <typename R, typename Predicate>
bool is_palindrome(const R& range, Predicate p)
{
return is_palindrome(boost::begin(range), boost::end(range), p);
}
}}
#endif // BOOST_ALGORITHM_IS_PALINDROME_HPP

View File

@@ -75,25 +75,27 @@ Requirements:
/// \param corpus_last One past the end of the data to search
///
template <typename corpusIter>
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
std::pair<corpusIter, corpusIter>
operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
// If the pattern is larger than the corpus, we can't find it!
if ( k_corpus_length < k_pattern_length )
return corpus_last;
return std::make_pair(corpus_last, corpus_last);
// Do the search
return this->do_search ( corpus_first, corpus_last );
return this->do_search ( corpus_first, corpus_last );
}
template <typename Range>
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
std::pair<typename boost::range_iterator<Range>::type, typename boost::range_iterator<Range>::type>
operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
@@ -112,7 +114,8 @@ Requirements:
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
std::pair<corpusIter, corpusIter>
do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
/* ---- Do the matching ---- */
corpusIter curPos = corpus_first;
const corpusIter lastPos = corpus_last - k_pattern_length;
@@ -126,7 +129,7 @@ Requirements:
j--;
// We matched - we're done!
if ( j == 0 )
return curPos;
return std::make_pair(curPos, curPos + k_pattern_length);
}
// Since we didn't match, figure out how far to skip forward
@@ -138,7 +141,7 @@ Requirements:
curPos += suffix_ [ j ];
}
return corpus_last; // We didn't find anything
return std::make_pair(corpus_last, corpus_last); // We didn't find anything
}
@@ -211,7 +214,7 @@ Requirements:
/// \param pat_last One past the end of the data to search for
///
template <typename patIter, typename corpusIter>
corpusIter boyer_moore_search (
std::pair<corpusIter, corpusIter> boyer_moore_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
@@ -220,7 +223,7 @@ Requirements:
}
template <typename PatternRange, typename corpusIter>
corpusIter boyer_moore_search (
std::pair<corpusIter, corpusIter> boyer_moore_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
@@ -229,8 +232,9 @@ Requirements:
}
template <typename patIter, typename CorpusRange>
typename boost::lazy_disable_if_c<
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
typename boost::disable_if_c<
boost::is_same<CorpusRange, patIter>::value,
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type> >
::type
boyer_moore_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
@@ -239,7 +243,7 @@ Requirements:
}
template <typename PatternRange, typename CorpusRange>
typename boost::range_iterator<CorpusRange>::type
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type>
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;

View File

@@ -64,33 +64,34 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
~boyer_moore_horspool () {}
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last)
/// \brief Searches the corpus for the pattern that was passed into the constructor
///
/// \param corpus_first The start of the data to search (Random Access Iterator)
/// \param corpus_last One past the end of the data to search
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
std::pair<corpusIter, corpusIter>
operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
// If the pattern is larger than the corpus, we can't find it!
if ( k_corpus_length < k_pattern_length )
return corpus_last;
return std::make_pair(corpus_last, corpus_last);
// Do the search
return this->do_search ( corpus_first, corpus_last );
}
template <typename Range>
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
std::pair<typename boost::range_iterator<Range>::type, typename boost::range_iterator<Range>::type>
operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
@@ -108,7 +109,8 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
/// \param k_corpus_length The length of the corpus to search
///
template <typename corpusIter>
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
std::pair<corpusIter, corpusIter>
do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
corpusIter curPos = corpus_first;
const corpusIter lastPos = corpus_last - k_pattern_length;
while ( curPos <= lastPos ) {
@@ -117,14 +119,14 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
while ( pat_first [j] == curPos [j] ) {
// We matched - we're done!
if ( j == 0 )
return curPos;
return std::make_pair(curPos, curPos + k_pattern_length);
j--;
}
curPos += skip_ [ curPos [ k_pattern_length - 1 ]];
}
return corpus_last;
return std::make_pair(corpus_last, corpus_last);
}
// \endcond
};
@@ -142,7 +144,7 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
/// \param pat_last One past the end of the data to search for
///
template <typename patIter, typename corpusIter>
corpusIter boyer_moore_horspool_search (
std::pair<corpusIter, corpusIter> boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
@@ -151,7 +153,7 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
}
template <typename PatternRange, typename corpusIter>
corpusIter boyer_moore_horspool_search (
std::pair<corpusIter, corpusIter> boyer_moore_horspool_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
@@ -160,8 +162,9 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
}
template <typename patIter, typename CorpusRange>
typename boost::lazy_disable_if_c<
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
typename boost::disable_if_c<
boost::is_same<CorpusRange, patIter>::value,
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type> >
::type
boyer_moore_horspool_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
@@ -170,7 +173,7 @@ http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
}
template <typename PatternRange, typename CorpusRange>
typename boost::range_iterator<CorpusRange>::type
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type>
boyer_moore_horspool_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;

View File

@@ -79,7 +79,7 @@ namespace boost { namespace algorithm { namespace detail {
skip_map skip_;
const value_type k_default_value;
public:
skip_table ( std::size_t patSize, value_type default_value ) : k_default_value ( default_value ) {
skip_table ( std::size_t /*patSize*/, value_type default_value ) : k_default_value ( default_value ) {
std::fill_n ( skip_.begin(), skip_.size(), default_value );
}

View File

@@ -69,23 +69,26 @@ namespace boost { namespace algorithm {
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
corpusIter operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
std::pair<corpusIter, corpusIter>
operator () ( corpusIter corpus_first, corpusIter corpus_last ) const {
BOOST_STATIC_ASSERT (( boost::is_same<
typename std::iterator_traits<patIter>::value_type,
typename std::iterator_traits<corpusIter>::value_type>::value ));
if ( corpus_first == corpus_last ) return corpus_last; // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return corpus_first; // empty pattern matches at start
if ( corpus_first == corpus_last ) return std::make_pair(corpus_last, corpus_last); // if nothing to search, we didn't find it!
if ( pat_first == pat_last ) return std::make_pair(corpus_first, corpus_first); // empty pattern matches at start
const difference_type k_corpus_length = std::distance ( corpus_first, corpus_last );
// If the pattern is larger than the corpus, we can't find it!
if ( k_corpus_length < k_pattern_length )
return corpus_last;
return std::make_pair(corpus_last, corpus_last);
return do_search ( corpus_first, corpus_last, k_corpus_length );
return do_search ( corpus_first, corpus_last, k_corpus_length );
}
template <typename Range>
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
std::pair<typename boost::range_iterator<Range>::type, typename boost::range_iterator<Range>::type>
operator () ( Range &r ) const {
return (*this) (boost::begin(r), boost::end(r));
}
@@ -103,7 +106,8 @@ namespace boost { namespace algorithm {
/// \param p A predicate used for the search comparisons.
///
template <typename corpusIter>
corpusIter do_search ( corpusIter corpus_first, corpusIter corpus_last,
std::pair<corpusIter, corpusIter>
do_search ( corpusIter corpus_first, corpusIter corpus_last,
difference_type k_corpus_length ) const {
difference_type match_start = 0; // position in the corpus that we're matching
@@ -135,7 +139,7 @@ namespace boost { namespace algorithm {
while ( match_start <= last_match ) {
while ( pat_first [ idx ] == corpus_first [ match_start + idx ] ) {
if ( ++idx == k_pattern_length )
return corpus_first + match_start;
return std::make_pair(corpus_first + match_start, corpus_first + match_start + k_pattern_length);
}
// Figure out where to start searching again
// assert ( idx - skip_ [ idx ] > 0 ); // we're always moving forward
@@ -146,7 +150,7 @@ namespace boost { namespace algorithm {
#endif
// We didn't find anything
return corpus_last;
return std::make_pair(corpus_last, corpus_last);
}
@@ -202,7 +206,7 @@ namespace boost { namespace algorithm {
/// \param pat_last One past the end of the data to search for
///
template <typename patIter, typename corpusIter>
corpusIter knuth_morris_pratt_search (
std::pair<corpusIter, corpusIter> knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last,
patIter pat_first, patIter pat_last )
{
@@ -211,7 +215,7 @@ namespace boost { namespace algorithm {
}
template <typename PatternRange, typename corpusIter>
corpusIter knuth_morris_pratt_search (
std::pair<corpusIter, corpusIter> knuth_morris_pratt_search (
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;
@@ -220,8 +224,9 @@ namespace boost { namespace algorithm {
}
template <typename patIter, typename CorpusRange>
typename boost::lazy_disable_if_c<
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
typename boost::disable_if_c<
boost::is_same<CorpusRange, patIter>::value,
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type> >
::type
knuth_morris_pratt_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
{
@@ -230,7 +235,7 @@ namespace boost { namespace algorithm {
}
template <typename PatternRange, typename CorpusRange>
typename boost::range_iterator<CorpusRange>::type
std::pair<typename boost::range_iterator<CorpusRange>::type, typename boost::range_iterator<CorpusRange>::type>
knuth_morris_pratt_search ( CorpusRange &corpus, const PatternRange &pattern )
{
typedef typename boost::range_iterator<const PatternRange>::type pattern_iterator;

View File

@@ -0,0 +1,109 @@
/*
Copyright (c) Marshall Clow 2008-2012.
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)
Revision history:
28 Sep 2015 mtc First version
*/
/// \file sort_subrange.hpp
/// \brief Sort a subrange
/// \author Marshall Clow
///
/// Suggested by Sean Parent in his CppCon 2015 keynote
#ifndef BOOST_ALGORITHM_SORT_SUBRANGE_HPP
#define BOOST_ALGORITHM_SORT_SUBRANGE_HPP
#include <functional> // For std::less
#include <iterator> // For std::iterator_traits
#include <algorithm> // For nth_element and partial_sort
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
namespace boost { namespace algorithm {
/// \fn sort_subrange ( T const& val,
/// Iterator first, Iterator last,
/// Iterator sub_first, Iterator sub_last,
/// Pred p )
/// \brief Sort the subrange [sub_first, sub_last) that is inside
/// the range [first, last) as if you had sorted the entire range.
///
/// \param first The start of the larger range
/// \param last The end of the larger range
/// \param sub_first The start of the sub range
/// \param sub_last The end of the sub range
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
///
template<typename Iterator, typename Pred>
void sort_subrange (
Iterator first, Iterator last,
Iterator sub_first, Iterator sub_last,
Pred p)
{
if (sub_first == sub_last) return; // the empty sub-range is already sorted.
if (sub_first != first) { // sub-range is at the start, don't need to partition
(void) std::nth_element(first, sub_first, last, p);
++sub_first;
}
std::partial_sort(sub_first, sub_last, last, p);
}
template<typename Iterator>
void sort_subrange (Iterator first, Iterator last, Iterator sub_first, Iterator sub_last)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
return sort_subrange(first, last, sub_first, sub_last, std::less<value_type>());
}
/// range versions?
/// \fn partition_subrange ( T const& val,
/// Iterator first, Iterator last,
/// Iterator sub_first, Iterator sub_last,
/// Pred p )
/// \brief Gather the elements of the subrange [sub_first, sub_last) that is
/// inside the range [first, last) as if you had sorted the entire range.
///
/// \param first The start of the larger range
/// \param last The end of the larger range
/// \param sub_first The start of the sub range
/// \param sub_last The end of the sub range
/// \param p A predicate to use to compare the values.
/// p ( a, b ) returns a boolean.
///
template<typename Iterator, typename Pred>
void partition_subrange (
Iterator first, Iterator last,
Iterator sub_first, Iterator sub_last,
Pred p)
{
if (sub_first != first) {
(void) std::nth_element(first, sub_first, last, p);
++sub_first;
}
if (sub_last != last)
(void) std::nth_element(sub_first, sub_last, last, p);
}
template<typename Iterator>
void partition_subrange (Iterator first, Iterator last, Iterator sub_first, Iterator sub_last)
{
typedef typename std::iterator_traits<Iterator>::value_type value_type;
return partition_subrange(first, last, sub_first, sub_last, std::less<value_type>());
}
}}
#endif // BOOST_ALGORITHM_SORT_SUBRANGE_HPP

View File

@@ -401,7 +401,6 @@ namespace boost {
\param Search A substring to be searched for
\param Format A substitute string
\param Loc A locale used for case insensitive comparison
\return A reference to the modified input
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void ireplace_last(
@@ -643,7 +642,6 @@ namespace boost {
\param Input An input string
\param Search A substring to be searched for
\param Format A substitute string
\return A reference to the modified input
*/
template<typename SequenceT, typename Range1T, typename Range2T>
inline void replace_all(