mirror of
https://github.com/boostorg/algorithm.git
synced 2025-06-25 20:11:50 +02:00
Compare commits
1 Commits
sandbox-br
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
72b87bdfc4 |
@ -1,22 +0,0 @@
|
||||
# Boost algorithm library example programs Jamfile
|
||||
#
|
||||
# Copyright Marshall Clow 2010-2012. Use, modification and
|
||||
# distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
|
||||
project /boost/algorithm/example
|
||||
: requirements
|
||||
<include>../../../
|
||||
<optimization>speed
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>msvc:<define>NOMINMAX
|
||||
<link>static
|
||||
:
|
||||
;
|
||||
|
||||
exe clamp_example : clamp_example.cpp ;
|
||||
exe search_example : search_example.cpp ;
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream> // for cout, etc
|
||||
|
||||
#include <boost/algorithm/clamp.hpp>
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
bool compare_string_lengths ( const std::string &one, const std::string &two )
|
||||
{
|
||||
return one.length () < two.length ();
|
||||
}
|
||||
|
||||
int main ( int /*argc*/, char * /*argv*/ [] ) {
|
||||
// Clamp takes a value and two "fenceposts", and brings the value "between" the fenceposts.
|
||||
|
||||
// If the input value is "between" the fenceposts, then it is returned unchanged.
|
||||
std::cout << "Clamping 5 to between [1, 10] -> " << ba::clamp ( 5, 1, 10 ) << std::endl;
|
||||
|
||||
// If the input value is out side the range of the fenceposts, it "brought into" range.
|
||||
std::cout << "Clamping 15 to between [1, 10] -> " << ba::clamp ( 15, 1, 10 ) << std::endl;
|
||||
std::cout << "Clamping -15 to between [1, 10] -> " << ba::clamp ( -15, 1, 10 ) << std::endl;
|
||||
|
||||
// It doesn't just work for ints
|
||||
std::cout << "Clamping 5.1 to between [1, 10] -> " << ba::clamp ( 5.1, 1.0, 10.0 ) << std::endl;
|
||||
|
||||
{
|
||||
std::string one ( "Lower Bound" ), two ( "upper bound!" ), test1 ( "test#" ), test2 ( "#test" );
|
||||
std::cout << "Clamping '" << test1 << "' between ['" << one << "' and '" << two << "'] -> '" <<
|
||||
ba::clamp ( test1, one, two ) << "'" << std::endl;
|
||||
std::cout << "Clamping '" << test2 << "' between ['" << one << "' and '" << two << "'] -> '" <<
|
||||
ba::clamp ( test2, one, two ) << "'" << std::endl;
|
||||
// There is also a predicate based version, if you want to compare objects in your own way
|
||||
std::cout << "Clamping '" << test1 << "' between ['" << one << "' and '" << two << "'] (comparing lengths) -> '" <<
|
||||
ba::clamp ( test1, one, two, compare_string_lengths ) << "'" << std::endl;
|
||||
std::cout << "Clamping '" << test2 << "' between ['" << one << "' and '" << two << "'] (comparing lengths) -> '" <<
|
||||
ba::clamp ( test2, one, two, compare_string_lengths ) << "'" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Sometimes, though, you don't get quite what you expect
|
||||
// This is because the two double arguments get converted to int
|
||||
std::cout << "Somewhat unexpected: clamp ( 12, 14.7, 15.9 ) --> " << ba::clamp ( 12, 14.7, 15.9 ) << std::endl;
|
||||
std::cout << "Expected: clamp ((double)12, 14.7, 15.9 ) --> " << ba::clamp ((double) 12, 14.7, 15.9 ) << std::endl;
|
||||
return 0;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream> // for cout, etc.
|
||||
|
||||
#include <boost/algorithm/searching/boyer_moore.hpp>
|
||||
#include <boost/algorithm/searching/boyer_moore_horspool.hpp>
|
||||
#include <boost/algorithm/searching/knuth_morris_pratt.hpp>
|
||||
|
||||
namespace ba = boost::algorithm;
|
||||
|
||||
const std::string haystack ( "ABACAB is it everywhere!" );
|
||||
const std::string needle1 ( "ACAB" );
|
||||
const std::string needle2 ( "not ABA" );
|
||||
|
||||
|
||||
|
||||
int main ( int /*argc*/, char * /*argv*/ [] ) {
|
||||
// In search.hpp, there are generic implementations of three classic sequence search
|
||||
// algorithms. They all have the same (dual) interface.
|
||||
|
||||
// There is a procedural interface, based on std::search:
|
||||
if ( ba::boyer_moore_search ( haystack.begin (), haystack.end (), needle1.begin (), needle1.end ()) != haystack.end ())
|
||||
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (boyer-moore 1)" << std::endl;
|
||||
else
|
||||
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (boyer-moore 1)" << std::endl;
|
||||
|
||||
// If you plan on searching for the same pattern in several different data sets,
|
||||
// you can create a search object and use that over and over again - amortizing the setup
|
||||
// costs across several searches
|
||||
ba::boyer_moore<std::string::const_iterator> search1 ( needle1.begin (), needle1.end ());
|
||||
if ( search1 ( haystack.begin (), haystack.end ()) != haystack.end ())
|
||||
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (boyer-moore 2)" << std::endl;
|
||||
else
|
||||
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (boyer-moore 2)" << std::endl;
|
||||
|
||||
// There is also an implementation of boyer-moore-horspool searching
|
||||
if ( ba::boyer_moore_horspool_search ( haystack.begin (), haystack.end (), needle1.begin (), needle1.end ()) != haystack.end ())
|
||||
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (boyer-moore-horspool)" << std::endl;
|
||||
else
|
||||
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (boyer-moore-horspool)" << std::endl;
|
||||
|
||||
// And also the knuth-pratt-morris search algorithm
|
||||
if ( ba::knuth_morris_pratt_search ( haystack.begin (), haystack.end (), needle1.begin (), needle1.end ()) != haystack.end ())
|
||||
std::cout << "Found '" << needle1 << "' in '" << haystack << "' (knuth_morris_pratt)" << std::endl;
|
||||
else
|
||||
std::cout << "Did NOT find '" << needle1 << "' in '" << haystack << "' (knuth_morris_pratt)" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
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:
|
||||
27 June 2009 mtc First version
|
||||
23 Oct 2010 mtc Added predicate version
|
||||
|
||||
*/
|
||||
|
||||
/// \file clamp.hpp
|
||||
/// \brief Clamp algorithm
|
||||
/// \author Marshall Clow
|
||||
///
|
||||
/// Suggested by olafvdspek in https://svn.boost.org/trac/boost/ticket/3215
|
||||
|
||||
#ifndef BOOST_ALGORITHM_CLAMP_HPP
|
||||
#define BOOST_ALGORITHM_CLAMP_HPP
|
||||
|
||||
#include <functional> // For std::less
|
||||
#include <iterator> // For std::iterator_traits
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/mpl/identity.hpp> // for identity
|
||||
#include <boost/utility/enable_if.hpp> // for boost::disable_if
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn clamp ( T const& val,
|
||||
/// typename boost::mpl::identity<T>::type const& lo,
|
||||
/// typename boost::mpl::identity<T>::type const& hi, Pred p )
|
||||
/// \return the value "val" brought into the range [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
/// If p ( val, lo ) return lo.
|
||||
/// If p ( hi, val ) return hi.
|
||||
/// Otherwise, return the original value.
|
||||
///
|
||||
/// \param val The value to be clamped
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
/// \param p A predicate to use to compare the values.
|
||||
/// p ( a, b ) returns a boolean.
|
||||
///
|
||||
template<typename T, typename Pred>
|
||||
T const & clamp ( T const& val,
|
||||
typename boost::mpl::identity<T>::type const & lo,
|
||||
typename boost::mpl::identity<T>::type const & hi, Pred p )
|
||||
{
|
||||
// assert ( !p ( hi, lo )); // Can't assert p ( lo, hi ) b/c they might be equal
|
||||
return p ( val, lo ) ? lo : p ( hi, val ) ? hi : val;
|
||||
}
|
||||
|
||||
|
||||
/// \fn clamp ( T const& val,
|
||||
/// typename boost::mpl::identity<T>::type const& lo,
|
||||
/// typename boost::mpl::identity<T>::type const& hi )
|
||||
/// \return the value "val" brought into the range [ lo, hi ].
|
||||
/// If the value is less than lo, return lo.
|
||||
/// If the value is greater than "hi", return hi.
|
||||
/// Otherwise, return the original value.
|
||||
///
|
||||
/// \param val The value to be clamped
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
///
|
||||
template<typename T>
|
||||
T const& clamp ( const T& val,
|
||||
typename boost::mpl::identity<T>::type const & lo,
|
||||
typename boost::mpl::identity<T>::type const & hi )
|
||||
{
|
||||
return (clamp) ( val, lo, hi, std::less<T>());
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type hi )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
///
|
||||
/// \param first The start of the range of values
|
||||
/// \param last One past the end of the range of input values
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator>
|
||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type hi )
|
||||
{
|
||||
// this could also be written with bind and std::transform
|
||||
while ( first != last )
|
||||
*out++ = clamp ( *first++, lo, hi );
|
||||
return out;
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
///
|
||||
/// \param r The range of values to be clamped
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
///
|
||||
template<typename Range, typename OutputIterator>
|
||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||
clamp_range ( const Range &r, OutputIterator out,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi )
|
||||
{
|
||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi );
|
||||
}
|
||||
|
||||
|
||||
/// \fn clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
/// std::iterator_traits<InputIterator>::value_type lo,
|
||||
/// std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
///
|
||||
/// \param first The start of the range of values
|
||||
/// \param last One past the end of the range of input values
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
/// \param p A predicate to use to compare the values.
|
||||
/// p ( a, b ) returns a boolean.
|
||||
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Pred>
|
||||
OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out,
|
||||
typename std::iterator_traits<InputIterator>::value_type lo,
|
||||
typename std::iterator_traits<InputIterator>::value_type hi, Pred p )
|
||||
{
|
||||
// this could also be written with bind and std::transform
|
||||
while ( first != last )
|
||||
*out++ = clamp ( *first++, lo, hi, p );
|
||||
return out;
|
||||
}
|
||||
|
||||
/// \fn clamp_range ( const Range &r, OutputIterator out,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
/// typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||
/// Pred p )
|
||||
/// \return clamp the sequence of values [first, last) into [ lo, hi ]
|
||||
/// using the comparison predicate p.
|
||||
///
|
||||
/// \param r The range of values to be clamped
|
||||
/// \param out An output iterator to write the clamped values into
|
||||
/// \param lo The lower bound of the range to be clamped to
|
||||
/// \param hi The upper bound of the range to be clamped to
|
||||
/// \param p A predicate to use to compare the values.
|
||||
/// p ( a, b ) returns a boolean.
|
||||
//
|
||||
// Disable this template if the first two parameters are the same type;
|
||||
// In that case, the user will get the two iterator version.
|
||||
template<typename Range, typename OutputIterator, typename Pred>
|
||||
typename boost::disable_if_c<boost::is_same<Range, OutputIterator>::value, OutputIterator>::type
|
||||
clamp_range ( const Range &r, OutputIterator out,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo,
|
||||
typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi,
|
||||
Pred p )
|
||||
{
|
||||
return clamp_range ( boost::begin ( r ), boost::end ( r ), out, lo, hi, p );
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_CLAMP_HPP
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file all_of.hpp
|
||||
/// \brief Test ranges to see if all elements match a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ALL_OF_HPP
|
||||
#define BOOST_ALGORITHM_ALL_OF_HPP
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of all_of if it is available
|
||||
using std::all_of; // Section 25.2.1
|
||||
#else
|
||||
/// \fn all_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if all elements in [first, last) satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \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 )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( !p(*first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn all_of ( const Range &r, Predicate p )
|
||||
/// \return true if all elements in the range satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool all_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::all_of ( boost::begin (r), boost::end (r), p );
|
||||
}
|
||||
|
||||
/// \fn all_of_equal ( InputIterator first, InputIterator last, const T &val )
|
||||
/// \return true if all elements in [first, last) are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename T>
|
||||
bool all_of_equal ( InputIterator first, InputIterator last, const T &val )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( val != *first )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn all_of_equal ( const Range &r, const T &val )
|
||||
/// \return true if all elements in the range are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename T>
|
||||
bool all_of_equal ( const Range &r, const T &val )
|
||||
{
|
||||
return boost::algorithm::all_of_equal ( boost::begin (r), boost::end (r), val );
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ALL_OF_HPP
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
/// \file
|
||||
/// \brief Test ranges to see if any elements match a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ANY_OF_HPP
|
||||
#define BOOST_ALGORITHM_ANY_OF_HPP
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
// Use the C++11 versions of any_of if it is available
|
||||
#if __cplusplus >= 201103L
|
||||
using std::any_of; // Section 25.2.2
|
||||
#else
|
||||
/// \fn any_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if any of the elements in [first, last) satisfy the predicate
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool any_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( p(*first))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn any_of ( const Range &r, Predicate p )
|
||||
/// \return true if any elements in the range satisfy the predicate 'p'
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool any_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::any_of (boost::begin (r), boost::end (r), p);
|
||||
}
|
||||
|
||||
/// \fn any_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
/// \return true if any of the elements in [first, last) are equal to 'val'
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename V>
|
||||
bool any_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( val == *first )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \fn any_of_equal ( const Range &r, const V &val )
|
||||
/// \return true if any of the elements in the range are equal to 'val'
|
||||
/// \note returns false on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool any_of_equal ( const Range &r, const V &val )
|
||||
{
|
||||
return boost::algorithm::any_of_equal (boost::begin (r), boost::end (r), val);
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ANY_OF_HPP
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file copy_if.hpp
|
||||
/// \brief Copy a subset of a sequence to a new sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_COPY_IF_HPP
|
||||
#define BOOST_ALGORITHM_COPY_IF_HPP
|
||||
|
||||
#include <algorithm> // for std::copy_if, if available
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of copy_if if it is available
|
||||
using std::copy_if; // Section 25.3.1
|
||||
#else
|
||||
/// \fn copy_if ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements from the input range that satisfy the
|
||||
/// predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \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 )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if (p(*first))
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn copy_if ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements from the input range that satisfy the
|
||||
/// predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_if ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_if (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_while ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_while ( InputIterator first, InputIterator last,
|
||||
OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && p(*first); ++first )
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \fn copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_while ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_while (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
||||
|
||||
/// \fn copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that do not
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename InputIterator, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( InputIterator first, InputIterator last, OutputIterator result, Predicate p )
|
||||
{
|
||||
for ( ; first != last && !p(*first); ++first )
|
||||
*result++ = first;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \fn copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
/// \brief Copies all the elements at the start of the input range that do not
|
||||
/// satisfy the predicate to the output range.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param result An output iterator to write the results into
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename OutputIterator, typename Predicate>
|
||||
OutputIterator copy_until ( const Range &r, OutputIterator result, Predicate p )
|
||||
{
|
||||
return boost::algorithm::copy_until (boost::begin (r), boost::end(r), result, p);
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_COPY_IF_HPP
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file copy_n.hpp
|
||||
/// \brief Copy n items from one sequence to another
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_COPY_N_HPP
|
||||
#define BOOST_ALGORITHM_COPY_N_HPP
|
||||
|
||||
#include <algorithm> // for std::copy_n, if available
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of copy_n if it is available
|
||||
using std::copy_n; // Section 25.3.1
|
||||
#else
|
||||
/// \fn copy_n ( InputIterator first, Size n, OutputIterator result )
|
||||
/// \brief Copies exactly n (n > 0) elements from the range starting at first to
|
||||
/// the range starting at result.
|
||||
/// \return The updated output iterator
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \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 )
|
||||
{
|
||||
for ( ; n > 0; --n, ++first, ++result )
|
||||
*result = *first;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_COPY_IF_HPP
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file find_if_not.hpp
|
||||
/// \brief Find the first element in a sequence that does not satisfy a predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#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>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of find_if_not if it is available
|
||||
using std::find_if_not; // Section 25.2.5
|
||||
#else
|
||||
/// \fn find_if_not(InputIterator first, InputIterator last, Predicate p)
|
||||
/// \brief Finds the first element in the sequence that does not satisfy the predicate.
|
||||
/// \return The iterator pointing to the desired element.
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \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 )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( !p(*first))
|
||||
break;
|
||||
return first;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn find_if_not ( const Range &r, Predicate p )
|
||||
/// \brief Finds the first element in the sequence that does not satisfy the predicate.
|
||||
/// \return The iterator pointing to the desired element.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
typename boost::range_iterator<const Range>::type find_if_not ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::find_if_not (boost::begin (r), boost::end(r), p);
|
||||
}
|
||||
|
||||
}}
|
||||
#endif // BOOST_ALGORITHM_FIND_IF_NOT_HPP
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file iota.hpp
|
||||
/// \brief Generate an increasing series
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IOTA_HPP
|
||||
#define BOOST_ALGORITHM_IOTA_HPP
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of iota if it is available
|
||||
using std::iota; // Section 26.7.6
|
||||
#else
|
||||
/// \fn iota ( ForwardIterator first, ForwardIterator last, T value )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in [first, last)
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \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 )
|
||||
{
|
||||
for ( ; first != last; ++first, ++value )
|
||||
*first = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn iota ( Range &r, T value )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param value The initial value of the sequence to be generated
|
||||
///
|
||||
template <typename Range, typename T>
|
||||
void iota ( Range &r, T value )
|
||||
{
|
||||
boost::algorithm::iota (boost::begin(r), boost::end(r), value);
|
||||
}
|
||||
|
||||
|
||||
/// \fn iota_n ( OutputIterator out, T value, std::size_t n )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
|
||||
///
|
||||
/// \param out An output iterator to write the results into
|
||||
/// \param value The initial value of the sequence to be generated
|
||||
/// \param n The number of items to write
|
||||
///
|
||||
template <typename OutputIterator, typename T>
|
||||
OutputIterator iota_n ( OutputIterator out, T value, std::size_t n )
|
||||
{
|
||||
while ( n-- > 0 )
|
||||
*out++ = value++;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IOTA_HPP
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file is_partitioned.hpp
|
||||
/// \brief Tell if a sequence is partitioned
|
||||
/// \author Marshall Clow
|
||||
|
||||
#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>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of iota if it is available
|
||||
using std::is_partitioned; // Section 25.3.13
|
||||
#else
|
||||
/// \fn is_partitioned ( InputIterator first, InputIterator last, UnaryPredicate p )
|
||||
/// \brief Tests to see if a sequence is partititioned according to a predicate
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p The predicicate 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 )
|
||||
{
|
||||
// Run through the part that satisfy the predicate
|
||||
for ( ; first != last; ++first )
|
||||
if ( !p (*first))
|
||||
break;
|
||||
// Now the part that does not satisfy the predicate
|
||||
for ( ; first != last; ++first )
|
||||
if ( p (*first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn is_partitioned ( const Range &r, UnaryPredicate p )
|
||||
/// \brief Generates an increasing sequence of values, and stores them in the input Range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p The predicicate to test the values with
|
||||
///
|
||||
template <typename Range, typename UnaryPredicate>
|
||||
bool is_partitioned ( const Range &r, UnaryPredicate p )
|
||||
{
|
||||
return boost::algorithm::is_partitioned (boost::begin(r), boost::end(r), p);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PARTITIONED_HPP
|
@ -1,139 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file is_permutation.hpp
|
||||
/// \brief Is a sequence a permutation of another sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
#define BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
||||
|
||||
#include <algorithm> // for std::less, tie, mismatch and is_permutation (if available)
|
||||
#include <utility> // for std::make_pair
|
||||
#include <functional> // for std::equal_to
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/tr1/tr1/tuple> // for tie
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of is_permutation if it is available
|
||||
using std::is_permutation; // Section 25.2.12
|
||||
#else
|
||||
/// \cond DOXYGEN_HIDE
|
||||
namespace detail {
|
||||
template <typename Predicate, typename Iterator>
|
||||
struct value_predicate {
|
||||
value_predicate ( Predicate p, Iterator it ) : p_ ( p ), it_ ( it ) {}
|
||||
|
||||
template <typename T1>
|
||||
bool operator () ( const T1 &t1 ) const { return p_ ( *it_, t1 ); }
|
||||
private:
|
||||
Predicate &p_;
|
||||
Iterator it_;
|
||||
};
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2, BinaryPredicate p )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \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 )
|
||||
{
|
||||
// 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);
|
||||
first1 = eq.first;
|
||||
first2 = eq.second;
|
||||
if ( first1 != last1 ) {
|
||||
// Create last2
|
||||
ForwardIterator2 last2 = first2;
|
||||
std::advance ( last2, std::distance (first1, last1));
|
||||
|
||||
// for each unique value in the sequence [first1,last1), count how many times
|
||||
// it occurs, and make sure it occurs the same number of times in [first2, last2)
|
||||
for ( ForwardIterator1 iter = first1; iter != last1; ++iter ) {
|
||||
detail::value_predicate<BinaryPredicate, ForwardIterator1> pred ( p, iter );
|
||||
|
||||
/* For each value we haven't seen yet... */
|
||||
if ( std::find_if ( first1, iter, pred ) == iter ) {
|
||||
std::size_t dest_count = std::count_if ( first2, last2, pred );
|
||||
if ( dest_count == 0 || dest_count != (std::size_t) std::count_if ( iter, last1, pred ))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 first2 )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last 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 first, ForwardIterator1 last, ForwardIterator2 first2 )
|
||||
{
|
||||
// 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::is_permutation ( first, last, first2,
|
||||
std::equal_to<typename std::iterator_traits<ForwardIterator1>::value_type> ());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param first2 The start of the second sequence
|
||||
template <typename Range, typename ForwardIterator>
|
||||
bool is_permutation ( const Range &r, ForwardIterator first2 )
|
||||
{
|
||||
return boost::algorithm::is_permutation (boost::begin (r), boost::end (r), first2 );
|
||||
}
|
||||
|
||||
/// \fn is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
/// \brief Tests to see if a the sequence [first,last) is a permutation of the sequence starting at first2
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param first2 The start of the second sequence
|
||||
/// \param pred The predicate to compare elements with
|
||||
///
|
||||
// Disable this template when the first two parameters are the same type
|
||||
// That way the non-range version will be chosen.
|
||||
template <typename Range, typename ForwardIterator, typename BinaryPredicate>
|
||||
typename boost::disable_if_c<boost::is_same<Range, ForwardIterator>::value, bool>::type
|
||||
is_permutation ( const Range &r, ForwardIterator first2, BinaryPredicate pred )
|
||||
{
|
||||
return boost::algorithm::is_permutation (boost::begin (r), boost::end (r), first2, pred );
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_IS_PERMUTATION_HPP
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file none_of.hpp
|
||||
/// \brief Test ranges to see if no elements match a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_NONE_OF_HPP
|
||||
#define BOOST_ALGORITHM_NONE_OF_HPP
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
// Use the C++11 versions of the none_of if it is available
|
||||
#if __cplusplus >= 201103L
|
||||
using std::none_of; // Section 25.2.3
|
||||
#else
|
||||
/// \fn none_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if none of the elements in [first, last) satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool none_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( p(*first))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn none_of ( const Range &r, Predicate p )
|
||||
/// \return true if none of the elements in the range satisfy the predicate 'p'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool none_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::none_of (boost::begin (r), boost::end (r), p );
|
||||
}
|
||||
|
||||
/// \fn none_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
/// \return true if none of the elements in [first, last) are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename V>
|
||||
bool none_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( val == *first )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \fn none_of_equal ( const Range &r, const V &val )
|
||||
/// \return true if none of the elements in the range are equal to 'val'
|
||||
/// \note returns true on an empty range
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool none_of_equal ( const Range &r, const V & val )
|
||||
{
|
||||
return boost::algorithm::none_of_equal (boost::begin (r), boost::end (r), val);
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_NONE_OF_HPP
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file one_of.hpp
|
||||
/// \brief Test ranges to see if only one element matches a value or predicate.
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ONE_OF_HPP
|
||||
#define BOOST_ALGORITHM_ONE_OF_HPP
|
||||
|
||||
#include <algorithm> // for std::find and std::find_if
|
||||
#include <boost/algorithm/cxx11/none_of.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/// \fn one_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
/// \return true if the predicate 'p' is true for exactly one item in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param p A predicate for testing the elements of the sequence
|
||||
///
|
||||
template<typename InputIterator, typename Predicate>
|
||||
bool one_of ( InputIterator first, InputIterator last, Predicate p )
|
||||
{
|
||||
InputIterator i = std::find_if (first, last, p);
|
||||
if (i == last)
|
||||
return false; // Didn't occur at all
|
||||
return boost::algorithm::none_of (++i, last, p);
|
||||
}
|
||||
|
||||
/// \fn one_of ( const Range &r, Predicate p )
|
||||
/// \return true if the predicate 'p' is true for exactly one item in the range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p A predicate for testing the elements of the range
|
||||
///
|
||||
template<typename Range, typename Predicate>
|
||||
bool one_of ( const Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::one_of ( boost::begin (r), boost::end (r), p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn one_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
/// \return true if the value 'val' exists only once in [first, last).
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename InputIterator, typename V>
|
||||
bool one_of_equal ( InputIterator first, InputIterator last, const V &val )
|
||||
{
|
||||
InputIterator i = std::find (first, last, val); // find first occurrence of 'val'
|
||||
if (i == last)
|
||||
return false; // Didn't occur at all
|
||||
return boost::algorithm::none_of_equal (++i, last, val);
|
||||
}
|
||||
|
||||
/// \fn one_of_equal ( const Range &r, const V &val )
|
||||
/// \return true if the value 'val' exists only once in the range.
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param val A value to compare against
|
||||
///
|
||||
template<typename Range, typename V>
|
||||
bool one_of_equal ( const Range &r, const V &val )
|
||||
{
|
||||
return boost::algorithm::one_of_equal ( boost::begin (r), boost::end (r), val );
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_ALL_HPP
|
@ -1,286 +0,0 @@
|
||||
// Copyright (c) 2010 Nuovation System Designs, LLC
|
||||
// Grant Erickson <gerickson@nuovations.com>
|
||||
//
|
||||
// Reworked somewhat by Marshall Clow; August 2010
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#ifndef BOOST_ALGORITHM_ORDERED_HPP
|
||||
#define BOOST_ALGORITHM_ORDERED_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of iota if it is available
|
||||
using std::is_sorted_until; // Section 25.4.1.5
|
||||
using std::is_sorted; // Section 25.4.1.5
|
||||
#else
|
||||
/// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
/// \return the point in the sequence [first, last) where the elements are unordered
|
||||
/// (according to the comparison predicate 'p').
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename ForwardIterator, typename Pred>
|
||||
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
{
|
||||
if ( first == last ) return last; // the empty sequence is ordered
|
||||
ForwardIterator next = first;
|
||||
while ( ++next != last )
|
||||
{
|
||||
if ( !p ( *first, *next ))
|
||||
return next;
|
||||
first = next;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
/// \fn is_sorted_until ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return the point in the sequence [first, last) where the elements are unordered
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
template <typename ForwardIterator>
|
||||
ForwardIterator is_sorted_until ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted_until ( first, last, std::less_equal<value_type>());
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
/// \return whether or not the entire sequence is sorted
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename ForwardIterator, typename Pred>
|
||||
bool is_sorted ( ForwardIterator first, ForwardIterator last, Pred p )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until (first, last, p) == last;
|
||||
}
|
||||
|
||||
/// \fn is_sorted ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return whether or not the entire sequence is sorted
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
template <typename ForwardIterator>
|
||||
bool is_sorted ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until (first, last) == last;
|
||||
}
|
||||
#endif
|
||||
|
||||
///
|
||||
/// -- Range based versions of the C++11 functions
|
||||
///
|
||||
|
||||
/// \fn is_sorted_until ( const R &range, Pred p )
|
||||
/// \return the point in the range R where the elements are unordered
|
||||
/// (according to the comparison predicate 'p').
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename R, typename Pred>
|
||||
typename boost::lazy_disable_if_c<
|
||||
boost::is_same<R, Pred>::value,
|
||||
typename boost::range_iterator<const R>
|
||||
>::type is_sorted_until ( const R &range, Pred p )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted_until ( const R &range )
|
||||
/// \return the point in the range R where the elements are unordered
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
template <typename R>
|
||||
typename boost::range_iterator<const R>::type is_sorted_until ( const R &range )
|
||||
{
|
||||
return boost::algorithm::is_sorted_until ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted ( const R &range, Pred p )
|
||||
/// \return whether or not the entire range R is sorted
|
||||
/// (according to the comparison predicate 'p').
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
/// \param p A binary predicate that returns true if two elements are ordered.
|
||||
///
|
||||
template <typename R, typename Pred>
|
||||
bool is_sorted ( const R &range, Pred p )
|
||||
{
|
||||
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ), p );
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_sorted ( const R &range )
|
||||
/// \return whether or not the entire range R is sorted
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
template <typename R, typename Pred>
|
||||
bool is_sorted ( const R &range )
|
||||
{
|
||||
return boost::algorithm::is_sorted ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// -- Range based versions of the C++11 functions
|
||||
///
|
||||
|
||||
/// \fn is_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is increasing; i.e, each item is greater than or
|
||||
/// equal to the previous one.
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_increasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::less_equal<value_type>());
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_increasing ( const R &range )
|
||||
/// \return true if the entire sequence is increasing; i.e, each item is greater than or
|
||||
/// equal to the previous one.
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_increasing instead.
|
||||
template <typename R>
|
||||
bool is_increasing ( const R &range )
|
||||
{
|
||||
return is_increasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \fn is_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is decreasing; i.e, each item is less than
|
||||
/// or equal to the previous one.
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::greater_equal<value_type>());
|
||||
}
|
||||
|
||||
/// \fn is_decreasing ( const R &range )
|
||||
/// \return true if the entire sequence is decreasing; i.e, each item is less than
|
||||
/// or equal to the previous one.
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return true for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_strictly_decreasing instead.
|
||||
template <typename R>
|
||||
bool is_decreasing ( const R &range )
|
||||
{
|
||||
return is_decreasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// \fn is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is strictly increasing; i.e, each item is greater
|
||||
/// than the previous one
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_increasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_strictly_increasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::less<value_type>());
|
||||
}
|
||||
|
||||
/// \fn is_strictly_increasing ( const R &range )
|
||||
/// \return true if the entire sequence is strictly increasing; i.e, each item is greater
|
||||
/// than the previous one
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_increasing instead.
|
||||
template <typename R>
|
||||
bool is_strictly_increasing ( const R &range )
|
||||
{
|
||||
return is_strictly_increasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
|
||||
/// \fn is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
/// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
|
||||
/// the previous one
|
||||
///
|
||||
/// \param first The start of the sequence to be tested.
|
||||
/// \param last One past the end of the sequence
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_decreasing instead.
|
||||
template <typename ForwardIterator>
|
||||
bool is_strictly_decreasing ( ForwardIterator first, ForwardIterator last )
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type value_type;
|
||||
return boost::algorithm::is_sorted (first, last, std::greater<value_type>());
|
||||
}
|
||||
|
||||
/// \fn is_strictly_decreasing ( const R &range )
|
||||
/// \return true if the entire sequence is strictly decreasing; i.e, each item is less than
|
||||
/// the previous one
|
||||
///
|
||||
/// \param range The range to be tested.
|
||||
///
|
||||
/// \note This function will return false for sequences that contain items that compare
|
||||
/// equal. If that is not what you intended, you should use is_decreasing instead.
|
||||
template <typename R>
|
||||
bool is_strictly_decreasing ( const R &range )
|
||||
{
|
||||
return is_strictly_decreasing ( boost::begin ( range ), boost::end ( range ));
|
||||
}
|
||||
|
||||
}} // namespace boost
|
||||
|
||||
#endif // BOOST_ALGORITHM_ORDERED_HPP
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file partition_copy.hpp
|
||||
/// \brief Copy a subset of a sequence to a new sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_PARTITION_COPY_HPP
|
||||
#define BOOST_ALGORITHM_PARTITION_COPY_HPP
|
||||
|
||||
#include <utility> // for make_pair
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of partition_copy if it is available
|
||||
using std::partition_copy; // Section 25.3.13
|
||||
#else
|
||||
/// \fn partition_copy ( InputIterator first, InputIterator last,
|
||||
/// OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
|
||||
/// \brief Copies the elements that satisfy the predicate p from the range [first, last)
|
||||
/// to the range beginning at d_first_true, and
|
||||
/// copies the elements that do not satisfy p to the range beginning at d_first_false.
|
||||
///
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \param last One past the end of the input sequence
|
||||
/// \param out_true An output iterator to write the elements that satisfy the predicate into
|
||||
/// \param out_false An output iterator to write the elements that do not satisfy the predicate into
|
||||
/// \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>
|
||||
partition_copy ( InputIterator first, InputIterator last,
|
||||
OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
|
||||
{
|
||||
for ( ; first != last; ++first )
|
||||
if ( p (*first))
|
||||
*out_true++ = *first;
|
||||
else
|
||||
*out_false++ = *first;
|
||||
return std::pair<OutputIterator1, OutputIterator2> ( out_true, out_false );
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn partition_copy ( const Range &r,
|
||||
/// OutputIterator1 out_true, OutputIterator2 out_false, UnaryPredicate p )
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param out_true An output iterator to write the elements that satisfy the predicate into
|
||||
/// \param out_false An output iterator to write the elements that do not satisfy the predicate into
|
||||
/// \param p A predicate for dividing the elements of the input sequence.
|
||||
///
|
||||
template <typename Range, typename OutputIterator1, typename OutputIterator2,
|
||||
typename UnaryPredicate>
|
||||
std::pair<OutputIterator1, OutputIterator2>
|
||||
partition_copy ( const Range &r, OutputIterator1 out_true, OutputIterator2 out_false,
|
||||
UnaryPredicate p )
|
||||
{
|
||||
return boost::algorithm::partition_copy
|
||||
(boost::begin(r), boost::end(r), out_true, out_false, p );
|
||||
}
|
||||
|
||||
}} // namespace boost and algorithm
|
||||
|
||||
#endif // BOOST_ALGORITHM_PARTITION_COPY_HPP
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/// \file partition_point.hpp
|
||||
/// \brief Find the partition point in a sequence
|
||||
/// \author Marshall Clow
|
||||
|
||||
#ifndef BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
#define BOOST_ALGORITHM_PARTITION_POINT_HPP
|
||||
|
||||
#include <algorithm> // for std::partition_point, if available
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// Use the C++11 versions of iota if it is available
|
||||
using std::partition_point; // Section 25.3.13
|
||||
#else
|
||||
/// \fn partition_point ( ForwardIterator first, ForwardIterator last, Predicate p )
|
||||
/// \brief Given a partitioned range, returns the partition point, i.e, the first element
|
||||
/// that does not satisfy p
|
||||
///
|
||||
/// \param first The start of the input sequence
|
||||
/// \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 )
|
||||
{
|
||||
std::size_t dist = std::distance ( first, last );
|
||||
while ( first != last ) {
|
||||
std::size_t d2 = dist / 2;
|
||||
ForwardIterator ret_val = first;
|
||||
std::advance (ret_val, d2);
|
||||
if (p (*ret_val)) {
|
||||
first = ++ret_val;
|
||||
dist -= d2 + 1;
|
||||
}
|
||||
else {
|
||||
last = ret_val;
|
||||
dist = d2;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \fn partition_point ( Range &r, Predicate p )
|
||||
/// \brief Given a partitioned range, returns the partition point
|
||||
///
|
||||
/// \param r The input range
|
||||
/// \param p The predicate to test the values with
|
||||
///
|
||||
template <typename Range, typename Predicate>
|
||||
typename boost::range_iterator<Range> partition_point ( Range &r, Predicate p )
|
||||
{
|
||||
return boost::algorithm::partition_point (boost::begin(r), boost::end(r), p);
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_PARTITION_POINT_HPP
|
@ -1,7 +1,7 @@
|
||||
// (C) Copyright Herve Bronnimann 2004.
|
||||
//
|
||||
// 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)
|
||||
// Use, modification and distribution are subject to 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:
|
||||
|
@ -1,7 +1,7 @@
|
||||
// (C) Copyright Herve Bronnimann 2004.
|
||||
//
|
||||
// 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)
|
||||
// Use, modification and distribution are subject to 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:
|
||||
|
@ -1,268 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
||||
#define BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
||||
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/*
|
||||
A templated version of the boyer-moore searching algorithm.
|
||||
|
||||
References:
|
||||
http://www.cs.utexas.edu/users/moore/best-ideas/string-searching/
|
||||
http://www.cs.utexas.edu/~moore/publications/fstrpos.pdf
|
||||
|
||||
Explanations: boostinspect:noascii (test tool complains)
|
||||
http://en.wikipedia.org/wiki/Boyer–Moore_string_search_algorithm
|
||||
http://www.movsd.com/bm.htm
|
||||
http://www.cs.ucdavis.edu/~gusfield/cs224f09/bnotes.pdf
|
||||
|
||||
The Boyer-Moore search algorithm uses two tables, a "bad character" table
|
||||
to tell how far to skip ahead when it hits a character that is not in the pattern,
|
||||
and a "good character" table to tell how far to skip ahead when it hits a
|
||||
mismatch on a character that _is_ in the pattern.
|
||||
|
||||
Requirements:
|
||||
* Random access iterators
|
||||
* The two iterator types (patIter and corpusIter) must
|
||||
"point to" the same underlying type and be comparable.
|
||||
* Additional requirements may be imposed but the skip table, such as:
|
||||
** Numeric type (array-based skip table)
|
||||
** Hashable type (map-based skip table)
|
||||
*/
|
||||
|
||||
template <typename patIter, typename traits = detail::BM_traits<patIter> >
|
||||
class boyer_moore {
|
||||
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||
public:
|
||||
boyer_moore ( patIter first, patIter last )
|
||||
: pat_first ( first ), pat_last ( last ),
|
||||
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||
skip_ ( k_pattern_length, -1 ),
|
||||
suffix_ ( k_pattern_length + 1 )
|
||||
{
|
||||
this->build_skip_table ( first, last );
|
||||
this->build_suffix_table ( first, last );
|
||||
}
|
||||
|
||||
~boyer_moore () {}
|
||||
|
||||
/// \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
|
||||
///
|
||||
template <typename 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
|
||||
|
||||
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;
|
||||
|
||||
// Do the search
|
||||
return this->do_search ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
typename boost::range_iterator<Range>::type operator () ( Range &r ) const {
|
||||
return (*this) (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
private:
|
||||
/// \cond DOXYGEN_HIDE
|
||||
patIter pat_first, pat_last;
|
||||
const difference_type k_pattern_length;
|
||||
typename traits::skip_table_t skip_;
|
||||
std::vector <difference_type> suffix_;
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \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 do_search ( corpusIter corpus_first, corpusIter corpus_last ) const {
|
||||
/* ---- Do the matching ---- */
|
||||
corpusIter curPos = corpus_first;
|
||||
const corpusIter lastPos = corpus_last - k_pattern_length;
|
||||
difference_type j, k, m;
|
||||
|
||||
while ( curPos <= lastPos ) {
|
||||
/* while ( std::distance ( curPos, corpus_last ) >= k_pattern_length ) { */
|
||||
// Do we match right where we are?
|
||||
j = k_pattern_length;
|
||||
while ( pat_first [j-1] == curPos [j-1] ) {
|
||||
j--;
|
||||
// We matched - we're done!
|
||||
if ( j == 0 )
|
||||
return curPos;
|
||||
}
|
||||
|
||||
// Since we didn't match, figure out how far to skip forward
|
||||
k = skip_ [ curPos [ j - 1 ]];
|
||||
m = j - k - 1;
|
||||
if ( k < j && m > suffix_ [ j ] )
|
||||
curPos += m;
|
||||
else
|
||||
curPos += suffix_ [ j ];
|
||||
}
|
||||
|
||||
return corpus_last; // We didn't find anything
|
||||
}
|
||||
|
||||
|
||||
void build_skip_table ( patIter first, patIter last ) {
|
||||
for ( std::size_t i = 0; first != last; ++first, ++i )
|
||||
skip_.insert ( *first, i );
|
||||
}
|
||||
|
||||
|
||||
template<typename Iter, typename Container>
|
||||
void compute_bm_prefix ( Iter pat_first, Iter pat_last, Container &prefix ) {
|
||||
const std::size_t count = std::distance ( pat_first, pat_last );
|
||||
BOOST_ASSERT ( count > 0 );
|
||||
BOOST_ASSERT ( prefix.size () == count );
|
||||
|
||||
prefix[0] = 0;
|
||||
std::size_t k = 0;
|
||||
for ( std::size_t i = 1; i < count; ++i ) {
|
||||
BOOST_ASSERT ( k < count );
|
||||
while ( k > 0 && ( pat_first[k] != pat_first[i] )) {
|
||||
BOOST_ASSERT ( k < count );
|
||||
k = prefix [ k - 1 ];
|
||||
}
|
||||
|
||||
if ( pat_first[k] == pat_first[i] )
|
||||
k++;
|
||||
prefix [ i ] = k;
|
||||
}
|
||||
}
|
||||
|
||||
void build_suffix_table ( patIter pat_first, patIter pat_last ) {
|
||||
const std::size_t count = (std::size_t) std::distance ( pat_first, pat_last );
|
||||
|
||||
if ( count > 0 ) { // empty pattern
|
||||
std::vector<typename std::iterator_traits<patIter>::value_type> reversed(count);
|
||||
(void) std::reverse_copy ( pat_first, pat_last, reversed.begin ());
|
||||
|
||||
std::vector<difference_type> prefix (count);
|
||||
compute_bm_prefix ( pat_first, pat_last, prefix );
|
||||
|
||||
std::vector<difference_type> prefix_reversed (count);
|
||||
compute_bm_prefix ( reversed.begin (), reversed.end (), prefix_reversed );
|
||||
|
||||
for ( std::size_t i = 0; i <= count; i++ )
|
||||
suffix_[i] = count - prefix [count-1];
|
||||
|
||||
for ( std::size_t i = 0; i < count; i++ ) {
|
||||
const std::size_t j = count - prefix_reversed[i];
|
||||
const difference_type k = i - prefix_reversed[i] + 1;
|
||||
|
||||
if (suffix_[j] > k)
|
||||
suffix_[j] = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
|
||||
/* Two ranges as inputs gives us four possibilities; with 2,3,3,4 parameters
|
||||
Use a bit of TMP to disambiguate the 3-argument templates */
|
||||
|
||||
/// \fn boyer_moore_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
/// patIter pat_first, patIter pat_last )
|
||||
/// \brief Searches the corpus for the pattern.
|
||||
///
|
||||
/// \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 pat_first The start of the pattern to search for (Random Access Iterator)
|
||||
/// \param pat_last One past the end of the data to search for
|
||||
///
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter boyer_moore_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last )
|
||||
{
|
||||
boyer_moore<patIter> bm ( pat_first, pat_last );
|
||||
return bm ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename corpusIter>
|
||||
corpusIter boyer_moore_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<PatternRange> pattern_iterator;
|
||||
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
|
||||
return bm ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
template <typename patIter, typename CorpusRange>
|
||||
typename boost::lazy_disable_if_c<
|
||||
boost::is_same<CorpusRange, patIter>::value, typename boost::range_iterator<CorpusRange> >
|
||||
::type
|
||||
boyer_moore_search ( CorpusRange &corpus, patIter pat_first, patIter pat_last )
|
||||
{
|
||||
boyer_moore<patIter> bm ( pat_first, pat_last );
|
||||
return bm (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
template <typename PatternRange, typename CorpusRange>
|
||||
typename boost::range_iterator<CorpusRange>::type
|
||||
boyer_moore_search ( CorpusRange &corpus, const PatternRange &pattern )
|
||||
{
|
||||
typedef typename boost::range_iterator<PatternRange> pattern_iterator;
|
||||
boyer_moore<pattern_iterator> bm ( boost::begin(pattern), boost::end (pattern));
|
||||
return bm (boost::begin (corpus), boost::end (corpus));
|
||||
}
|
||||
|
||||
|
||||
// Creator functions -- take a pattern range, return an object
|
||||
template <typename Range>
|
||||
boost::algorithm::boyer_moore<typename boost::range_iterator<const Range>::type>
|
||||
make_boyer_moore ( const Range &r ) {
|
||||
return boost::algorithm::boyer_moore
|
||||
<typename boost::range_iterator<const Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
template <typename Range>
|
||||
boost::algorithm::boyer_moore<typename boost::range_iterator<Range>::type>
|
||||
make_boyer_moore ( Range &r ) {
|
||||
return boost::algorithm::boyer_moore
|
||||
<typename boost::range_iterator<Range>::type> (boost::begin(r), boost::end(r));
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_BOYER_MOORE_SEARCH_HPP
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
||||
#define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
||||
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/bm_traits.hpp>
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
// #define BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
/*
|
||||
A templated version of the boyer-moore-horspool searching algorithm.
|
||||
|
||||
Requirements:
|
||||
* Random access iterators
|
||||
* The two iterator types (patIter and corpusIter) must
|
||||
"point to" the same underlying type.
|
||||
* Additional requirements may be imposed buy the skip table, such as:
|
||||
** Numeric type (array-based skip table)
|
||||
** Hashable type (map-based skip table)
|
||||
|
||||
http://www-igm.univ-mlv.fr/%7Elecroq/string/node18.html
|
||||
|
||||
*/
|
||||
|
||||
template <typename patIter, typename traits = detail::BM_traits<patIter> >
|
||||
class boyer_moore_horspool {
|
||||
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||
public:
|
||||
boyer_moore_horspool ( patIter first, patIter last )
|
||||
: pat_first ( first ), pat_last ( last ),
|
||||
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||
skip_ ( k_pattern_length, k_pattern_length ) {
|
||||
|
||||
// Build the skip table
|
||||
std::size_t i = 0;
|
||||
if ( first != last ) // empty pattern?
|
||||
for ( patIter iter = first; iter != last-1; ++iter, ++i )
|
||||
skip_.insert ( *iter, k_pattern_length - 1 - i );
|
||||
#ifdef BOOST_ALGORITHM_BOYER_MOORE_HORSPOOL_DEBUG_HPP
|
||||
skip_.PrintSkipTable ();
|
||||
#endif
|
||||
}
|
||||
|
||||
~boyer_moore_horspool () {}
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \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 {
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
// Do the search
|
||||
return this->do_search ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
private:
|
||||
/// \cond DOXYGEN_HIDE
|
||||
patIter pat_first, pat_last;
|
||||
const difference_type k_pattern_length;
|
||||
typename traits::skip_table_t skip_;
|
||||
|
||||
/// \fn do_search ( 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 k_corpus_length The length of the corpus to search
|
||||
///
|
||||
template <typename 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 ) {
|
||||
// Do we match right where we are?
|
||||
std::size_t j = k_pattern_length - 1;
|
||||
while ( pat_first [j] == curPos [j] ) {
|
||||
// We matched - we're done!
|
||||
if ( j == 0 )
|
||||
return curPos;
|
||||
j--;
|
||||
}
|
||||
|
||||
curPos += skip_ [ curPos [ k_pattern_length - 1 ]];
|
||||
}
|
||||
|
||||
return corpus_last;
|
||||
}
|
||||
// \endcond
|
||||
};
|
||||
|
||||
/// \fn boyer_moore_horspool_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
/// patIter pat_first, patIter pat_last )
|
||||
/// \brief Searches the corpus for the pattern.
|
||||
///
|
||||
/// \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 pat_first The start of the pattern to search for (Random Access Iterator)
|
||||
/// \param pat_last One past the end of the data to search for
|
||||
///
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter boyer_moore_horspool_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last ) {
|
||||
boyer_moore_horspool<patIter> bmh ( pat_first, pat_last );
|
||||
return bmh ( corpus_first, corpus_last );
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_BOYER_MOORE_HORSPOOOL_SEARCH_HPP
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
||||
#define BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
||||
|
||||
#include <climits> // for CHAR_BIT
|
||||
#include <vector>
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/tr1/tr1/unordered_map>
|
||||
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
namespace boost { namespace algorithm { namespace detail {
|
||||
|
||||
//
|
||||
// Default implementations of the skip tables for B-M and B-M-H
|
||||
//
|
||||
template<typename key_type, typename value_type, bool /*useArray*/> class skip_table;
|
||||
|
||||
// General case for data searching other than bytes; use a map
|
||||
template<typename key_type, typename value_type>
|
||||
class skip_table<key_type, value_type, false> {
|
||||
private:
|
||||
typedef std::tr1::unordered_map<key_type, value_type> skip_map;
|
||||
const value_type k_default_value;
|
||||
skip_map skip_;
|
||||
|
||||
public:
|
||||
skip_table ( std::size_t patSize, value_type default_value )
|
||||
: k_default_value ( default_value ), skip_ ( patSize ) {}
|
||||
|
||||
void insert ( key_type key, value_type val ) {
|
||||
skip_ [ key ] = val; // Would skip_.insert (val) be better here?
|
||||
}
|
||||
|
||||
value_type operator [] ( key_type key ) const {
|
||||
typename skip_map::const_iterator it = skip_.find ( key );
|
||||
return it == skip_.end () ? k_default_value : it->second;
|
||||
}
|
||||
|
||||
void PrintSkipTable () const {
|
||||
std::cout << "BM(H) Skip Table <unordered_map>:" << std::endl;
|
||||
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
|
||||
if ( it->second != k_default_value )
|
||||
std::cout << " " << it->first << ": " << it->second << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Special case small numeric values; use an array
|
||||
template<typename key_type, typename value_type>
|
||||
class skip_table<key_type, value_type, true> {
|
||||
private:
|
||||
typedef typename boost::make_unsigned<key_type>::type unsigned_key_type;
|
||||
typedef boost::array<value_type, 1U << (CHAR_BIT * sizeof(key_type))> skip_map;
|
||||
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 ) {
|
||||
std::fill_n ( skip_.begin(), skip_.size(), default_value );
|
||||
}
|
||||
|
||||
void insert ( key_type key, value_type val ) {
|
||||
skip_ [ static_cast<unsigned_key_type> ( key ) ] = val;
|
||||
}
|
||||
|
||||
value_type operator [] ( key_type key ) const {
|
||||
return skip_ [ static_cast<unsigned_key_type> ( key ) ];
|
||||
}
|
||||
|
||||
void PrintSkipTable () const {
|
||||
std::cout << "BM(H) Skip Table <boost:array>:" << std::endl;
|
||||
for ( typename skip_map::const_iterator it = skip_.begin (); it != skip_.end (); ++it )
|
||||
if ( *it != k_default_value )
|
||||
std::cout << " " << std::distance (skip_.begin (), it) << ": " << *it << std::endl;
|
||||
std::cout << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
struct BM_traits {
|
||||
typedef typename std::iterator_traits<Iterator>::difference_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::value_type key_type;
|
||||
typedef boost::algorithm::detail::skip_table<key_type, value_type,
|
||||
boost::is_integral<key_type>::value && (sizeof(key_type)==1)> skip_table_t;
|
||||
};
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_BM_TRAITS_HPP
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
||||
#define BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
||||
|
||||
#include <iostream>
|
||||
/// \cond DOXYGEN_HIDE
|
||||
|
||||
namespace boost { namespace algorithm { namespace detail {
|
||||
|
||||
// Debugging support
|
||||
template <typename Iter>
|
||||
void PrintTable ( Iter first, Iter last ) {
|
||||
std::cout << std::distance ( first, last ) << ": { ";
|
||||
for ( Iter iter = first; iter != last; ++iter )
|
||||
std::cout << *iter << " ";
|
||||
std::cout << "}" << std::endl;
|
||||
}
|
||||
|
||||
}}}
|
||||
/// \endcond
|
||||
|
||||
#endif // BOOST_ALGORITHM_SEARCH_DETAIL_DEBUG_HPP
|
@ -1,200 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Marshall Clow 2010-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)
|
||||
|
||||
For more information, see http://www.boost.org
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
||||
#define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <iterator> // for std::iterator_traits
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/algorithm/searching/detail/debugging.hpp>
|
||||
|
||||
// #define BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
|
||||
|
||||
namespace boost { namespace algorithm {
|
||||
|
||||
// #define NEW_KMP
|
||||
|
||||
/*
|
||||
A templated version of the Knuth-Morris-Pratt searching algorithm.
|
||||
|
||||
Requirements:
|
||||
* Random-access iterators
|
||||
* The two iterator types (I1 and I2) must "point to" the same underlying type.
|
||||
|
||||
http://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm
|
||||
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/kmpen.htm
|
||||
*/
|
||||
|
||||
template <typename patIter>
|
||||
class knuth_morris_pratt {
|
||||
typedef typename std::iterator_traits<patIter>::difference_type difference_type;
|
||||
public:
|
||||
knuth_morris_pratt ( patIter first, patIter last )
|
||||
: pat_first ( first ), pat_last ( last ),
|
||||
k_pattern_length ( std::distance ( pat_first, pat_last )),
|
||||
skip_ ( k_pattern_length + 1 ) {
|
||||
#ifdef NEW_KMP
|
||||
preKmp ( pat_first, pat_last );
|
||||
#else
|
||||
init_skip_table ( pat_first, pat_last );
|
||||
#endif
|
||||
#ifdef BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_DEBUG
|
||||
detail::PrintTable ( skip_.begin (), skip_.end ());
|
||||
#endif
|
||||
}
|
||||
|
||||
~knuth_morris_pratt () {}
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \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 {
|
||||
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
|
||||
|
||||
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 do_search ( corpus_first, corpus_last, k_corpus_length );
|
||||
}
|
||||
|
||||
private:
|
||||
/// \cond DOXYGEN_HIDE
|
||||
patIter pat_first, pat_last;
|
||||
const difference_type k_pattern_length;
|
||||
std::vector <difference_type> skip_;
|
||||
|
||||
/// \fn operator ( corpusIter corpus_first, corpusIter corpus_last, Pred p )
|
||||
/// \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 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
|
||||
|
||||
#ifdef NEW_KMP
|
||||
int patternIdx = 0;
|
||||
while ( match_start < k_corpus_length ) {
|
||||
while ( patternIdx > -1 && pat_first[patternIdx] != corpus_first [match_start] )
|
||||
patternIdx = skip_ [patternIdx]; //<--- Shifting the pattern on mismatch
|
||||
|
||||
patternIdx++;
|
||||
match_start++; //<--- corpus is always increased by 1
|
||||
|
||||
if ( patternIdx >= (int) k_pattern_length )
|
||||
return corpus_first + match_start - patternIdx;
|
||||
}
|
||||
|
||||
#else
|
||||
// At this point, we know:
|
||||
// k_pattern_length <= k_corpus_length
|
||||
// for all elements of skip, it holds -1 .. k_pattern_length
|
||||
//
|
||||
// In the loop, we have the following invariants
|
||||
// idx is in the range 0 .. k_pattern_length
|
||||
// match_start is in the range 0 .. k_corpus_length - k_pattern_length + 1
|
||||
|
||||
const difference_type last_match = k_corpus_length - k_pattern_length;
|
||||
difference_type idx = 0; // position in the pattern we're comparing
|
||||
|
||||
while ( match_start <= last_match ) {
|
||||
while ( pat_first [ idx ] == corpus_first [ match_start + idx ] ) {
|
||||
if ( ++idx == k_pattern_length )
|
||||
return corpus_first + match_start;
|
||||
}
|
||||
// Figure out where to start searching again
|
||||
// assert ( idx - skip_ [ idx ] > 0 ); // we're always moving forward
|
||||
match_start += idx - skip_ [ idx ];
|
||||
idx = skip_ [ idx ] >= 0 ? skip_ [ idx ] : 0;
|
||||
// assert ( idx >= 0 && idx < k_pattern_length );
|
||||
}
|
||||
#endif
|
||||
|
||||
// We didn't find anything
|
||||
return corpus_last;
|
||||
}
|
||||
|
||||
|
||||
void preKmp ( patIter first, patIter last ) {
|
||||
const /*std::size_t*/ int count = std::distance ( first, last );
|
||||
|
||||
int i, j;
|
||||
|
||||
i = 0;
|
||||
j = skip_[0] = -1;
|
||||
while (i < count) {
|
||||
while (j > -1 && first[i] != first[j])
|
||||
j = skip_[j];
|
||||
i++;
|
||||
j++;
|
||||
if (first[i] == first[j])
|
||||
skip_[i] = skip_[j];
|
||||
else
|
||||
skip_[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void init_skip_table ( patIter first, patIter last ) {
|
||||
const difference_type count = std::distance ( first, last );
|
||||
|
||||
int j;
|
||||
skip_ [ 0 ] = -1;
|
||||
for ( int i = 1; i <= count; ++i ) {
|
||||
j = skip_ [ i - 1 ];
|
||||
while ( j >= 0 ) {
|
||||
if ( first [ j ] == first [ i - 1 ] )
|
||||
break;
|
||||
j = skip_ [ j ];
|
||||
}
|
||||
skip_ [ i ] = j + 1;
|
||||
}
|
||||
}
|
||||
// \endcond
|
||||
};
|
||||
|
||||
|
||||
/// \fn knuth_morris_pratt_search ( corpusIter corpus_first, corpusIter corpus_last,
|
||||
/// patIter pat_first, patIter pat_last )
|
||||
/// \brief Searches the corpus for the pattern.
|
||||
///
|
||||
/// \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 pat_first The start of the pattern to search for (Random Access Iterator)
|
||||
/// \param pat_last One past the end of the data to search for
|
||||
///
|
||||
template <typename patIter, typename corpusIter>
|
||||
corpusIter knuth_morris_pratt_search (
|
||||
corpusIter corpus_first, corpusIter corpus_last,
|
||||
patIter pat_first, patIter pat_last ) {
|
||||
knuth_morris_pratt<patIter> kmp ( pat_first, pat_last );
|
||||
return kmp ( corpus_first, corpus_last );
|
||||
}
|
||||
}}
|
||||
|
||||
#endif // BOOST_ALGORITHM_KNUTH_MORRIS_PRATT_SEARCH_HPP
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library string_algo.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2004.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2004. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_ALGO_HPP
|
||||
#define BOOST_STRING_ALGO_HPP
|
||||
@ -21,7 +20,6 @@
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string/erase.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library case_conv.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CASE_CONV_HPP
|
||||
#define BOOST_STRING_CASE_CONV_HPP
|
||||
@ -16,7 +15,6 @@
|
||||
#include <locale>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
@ -57,10 +55,11 @@ namespace boost {
|
||||
const RangeT& Input,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::detail::transform_range_copy(
|
||||
Output,
|
||||
::boost::as_literal(Input),
|
||||
::boost::algorithm::detail::to_lowerF<
|
||||
return std::transform(
|
||||
begin(Input),
|
||||
end(Input),
|
||||
Output,
|
||||
::boost::algorithm::detail::to_lowerF<
|
||||
typename range_value<RangeT>::type >(Loc));
|
||||
}
|
||||
|
||||
@ -73,10 +72,15 @@ namespace boost {
|
||||
const SequenceT& Input,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::detail::transform_range_copy<SequenceT>(
|
||||
Input,
|
||||
::boost::algorithm::detail::to_lowerF<
|
||||
typename range_value<SequenceT>::type >(Loc));
|
||||
return SequenceT(
|
||||
make_transform_iterator(
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::to_lowerF<
|
||||
typename range_value<SequenceT>::type >(Loc)),
|
||||
make_transform_iterator(
|
||||
end(Input),
|
||||
::boost::algorithm::detail::to_lowerF<
|
||||
typename range_value<SequenceT>::type >(Loc)));
|
||||
}
|
||||
|
||||
//! Convert to lower case
|
||||
@ -92,8 +96,10 @@ namespace boost {
|
||||
WritableRangeT& Input,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
::boost::algorithm::detail::transform_range(
|
||||
::boost::as_literal(Input),
|
||||
std::transform(
|
||||
begin(Input),
|
||||
end(Input),
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::to_lowerF<
|
||||
typename range_value<WritableRangeT>::type >(Loc));
|
||||
}
|
||||
@ -122,10 +128,11 @@ namespace boost {
|
||||
const RangeT& Input,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::detail::transform_range_copy(
|
||||
Output,
|
||||
::boost::as_literal(Input),
|
||||
::boost::algorithm::detail::to_upperF<
|
||||
return std::transform(
|
||||
begin(Input),
|
||||
end(Input),
|
||||
Output,
|
||||
::boost::algorithm::detail::to_upperF<
|
||||
typename range_value<RangeT>::type >(Loc));
|
||||
}
|
||||
|
||||
@ -138,10 +145,16 @@ namespace boost {
|
||||
const SequenceT& Input,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::detail::transform_range_copy<SequenceT>(
|
||||
Input,
|
||||
::boost::algorithm::detail::to_upperF<
|
||||
typename range_value<SequenceT>::type >(Loc));
|
||||
return SequenceT(
|
||||
make_transform_iterator(
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::to_upperF<
|
||||
typename range_value<SequenceT>::type >(Loc)),
|
||||
make_transform_iterator(
|
||||
end(Input),
|
||||
::boost::algorithm::detail::to_upperF<
|
||||
typename range_value<SequenceT>::type >(Loc)));
|
||||
|
||||
}
|
||||
|
||||
//! Convert to upper case
|
||||
@ -157,8 +170,10 @@ namespace boost {
|
||||
WritableRangeT& Input,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
::boost::algorithm::detail::transform_range(
|
||||
::boost::as_literal(Input),
|
||||
std::transform(
|
||||
begin(Input),
|
||||
end(Input),
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::to_upperF<
|
||||
typename range_value<WritableRangeT>::type >(Loc));
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library classification.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CLASSIFICATION_HPP
|
||||
#define BOOST_STRING_CLASSIFICATION_HPP
|
||||
@ -14,11 +13,9 @@
|
||||
#include <algorithm>
|
||||
#include <locale>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/algorithm/string/detail/classification.hpp>
|
||||
#include <boost/algorithm/string/predicate_facade.hpp>
|
||||
|
||||
|
||||
/*! \file
|
||||
Classification predicates are included in the library to give
|
||||
some more convenience when using algorithms like \c trim() and \c all().
|
||||
@ -202,8 +199,8 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME range_value<RangeT>::type>
|
||||
is_any_of( const RangeT& Set )
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_set(boost::as_literal(Set));
|
||||
return detail::is_any_ofF<BOOST_STRING_TYPENAME range_value<RangeT>::type>(lit_set);
|
||||
return detail::is_any_ofF<
|
||||
BOOST_STRING_TYPENAME range_value<RangeT>::type>(Set);
|
||||
}
|
||||
|
||||
//! is_from_range predicate
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library compare.hpp header file -------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_COMPARE_HPP
|
||||
#define BOOST_STRING_COMPARE_HPP
|
||||
@ -38,7 +37,7 @@ namespace boost {
|
||||
Compare two operands for equality
|
||||
*/
|
||||
template< typename T1, typename T2 >
|
||||
bool operator()( const T1& Arg1, const T2& Arg2 ) const
|
||||
bool operator ()( const T1& Arg1, const T2& Arg2 ) const
|
||||
{
|
||||
return Arg1==Arg2;
|
||||
}
|
||||
@ -63,12 +62,12 @@ namespace boost {
|
||||
Compare two operands. Case is ignored.
|
||||
*/
|
||||
template< typename T1, typename T2 >
|
||||
bool operator()( const T1& Arg1, const T2& Arg2 ) const
|
||||
bool operator ()( const T1& Arg1, const T2& Arg2 ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::toupper(Arg1)==std::toupper(Arg2);
|
||||
#else
|
||||
return std::toupper<T1>(Arg1,m_Loc)==std::toupper<T2>(Arg2,m_Loc);
|
||||
return std::toupper(Arg1,m_Loc)==std::toupper(Arg2,m_Loc);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -76,122 +75,11 @@ namespace boost {
|
||||
std::locale m_Loc;
|
||||
};
|
||||
|
||||
// is_less functor -----------------------------------------------//
|
||||
|
||||
//! is_less functor
|
||||
/*!
|
||||
Convenient version of standard std::less. Operation is templated, therefore it is
|
||||
not required to specify the exact types upon the construction
|
||||
*/
|
||||
struct is_less
|
||||
{
|
||||
//! Functor operation
|
||||
/*!
|
||||
Compare two operands using > operator
|
||||
*/
|
||||
template< typename T1, typename T2 >
|
||||
bool operator()( const T1& Arg1, const T2& Arg2 ) const
|
||||
{
|
||||
return Arg1<Arg2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! case insensitive version of is_less
|
||||
/*!
|
||||
Case insensitive comparison predicate. Comparison is done using
|
||||
specified locales.
|
||||
*/
|
||||
struct is_iless
|
||||
{
|
||||
//! Constructor
|
||||
/*!
|
||||
\param Loc locales used for comparison
|
||||
*/
|
||||
is_iless( const std::locale& Loc=std::locale() ) :
|
||||
m_Loc( Loc ) {}
|
||||
|
||||
//! Function operator
|
||||
/*!
|
||||
Compare two operands. Case is ignored.
|
||||
*/
|
||||
template< typename T1, typename T2 >
|
||||
bool operator()( const T1& Arg1, const T2& Arg2 ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::toupper(Arg1)<std::toupper(Arg2);
|
||||
#else
|
||||
return std::toupper<T1>(Arg1,m_Loc)<std::toupper<T2>(Arg2,m_Loc);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
std::locale m_Loc;
|
||||
};
|
||||
|
||||
// is_not_greater functor -----------------------------------------------//
|
||||
|
||||
//! is_not_greater functor
|
||||
/*!
|
||||
Convenient version of standard std::not_greater_to. Operation is templated, therefore it is
|
||||
not required to specify the exact types upon the construction
|
||||
*/
|
||||
struct is_not_greater
|
||||
{
|
||||
//! Functor operation
|
||||
/*!
|
||||
Compare two operands using > operator
|
||||
*/
|
||||
template< typename T1, typename T2 >
|
||||
bool operator()( const T1& Arg1, const T2& Arg2 ) const
|
||||
{
|
||||
return Arg1<=Arg2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! case insensitive version of is_not_greater
|
||||
/*!
|
||||
Case insensitive comparison predicate. Comparison is done using
|
||||
specified locales.
|
||||
*/
|
||||
struct is_not_igreater
|
||||
{
|
||||
//! Constructor
|
||||
/*!
|
||||
\param Loc locales used for comparison
|
||||
*/
|
||||
is_not_igreater( const std::locale& Loc=std::locale() ) :
|
||||
m_Loc( Loc ) {}
|
||||
|
||||
//! Function operator
|
||||
/*!
|
||||
Compare two operands. Case is ignored.
|
||||
*/
|
||||
template< typename T1, typename T2 >
|
||||
bool operator()( const T1& Arg1, const T2& Arg2 ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::toupper(Arg1)<=std::toupper(Arg2);
|
||||
#else
|
||||
return std::toupper<T1>(Arg1,m_Loc)<=std::toupper<T2>(Arg2,m_Loc);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
std::locale m_Loc;
|
||||
};
|
||||
|
||||
|
||||
} // namespace algorithm
|
||||
|
||||
// pull names to the boost namespace
|
||||
using algorithm::is_equal;
|
||||
using algorithm::is_iequal;
|
||||
using algorithm::is_less;
|
||||
using algorithm::is_iless;
|
||||
using algorithm::is_not_greater;
|
||||
using algorithm::is_not_igreater;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library concept.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CONCEPT_HPP
|
||||
#define BOOST_STRING_CONCEPT_HPP
|
||||
@ -65,8 +64,8 @@ namespace boost {
|
||||
void constraints()
|
||||
{
|
||||
// Operation
|
||||
::boost::begin((*pFo)( (*pF)(i,i) ));
|
||||
::boost::end((*pFo)( (*pF)(i,i) ));
|
||||
begin((*pFo)( (*pF)(i,i) ));
|
||||
end((*pFo)( (*pF)(i,i) ));
|
||||
}
|
||||
private:
|
||||
IteratorT i;
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library config.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CONFIG_HPP
|
||||
#define BOOST_STRING_CONFIG_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library constants.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CONSTANTS_HPP
|
||||
#define BOOST_STRING_CONSTANTS_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library string_funct.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CASE_CONV_DETAIL_HPP
|
||||
#define BOOST_STRING_CASE_CONV_DETAIL_HPP
|
||||
@ -15,37 +14,30 @@
|
||||
#include <locale>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
namespace detail {
|
||||
|
||||
// case conversion functors -----------------------------------------------//
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
|
||||
// a tolower functor
|
||||
template<typename CharT>
|
||||
struct to_lowerF : public std::unary_function<CharT, CharT>
|
||||
{
|
||||
// Constructor
|
||||
to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {}
|
||||
to_lowerF( const std::locale& Loc ) : m_Loc( Loc ) {}
|
||||
|
||||
// Operation
|
||||
CharT operator ()( CharT Ch ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::tolower( static_cast<typename boost::make_unsigned <CharT>::type> ( Ch ));
|
||||
return std::tolower( Ch);
|
||||
#else
|
||||
return std::tolower<CharT>( Ch, *m_Loc );
|
||||
return std::tolower( Ch, m_Loc );
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
const std::locale* m_Loc;
|
||||
const std::locale& m_Loc;
|
||||
};
|
||||
|
||||
// a toupper functor
|
||||
@ -53,68 +45,21 @@ namespace boost {
|
||||
struct to_upperF : public std::unary_function<CharT, CharT>
|
||||
{
|
||||
// Constructor
|
||||
to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {}
|
||||
to_upperF( const std::locale& Loc ) : m_Loc( Loc ) {}
|
||||
|
||||
// Operation
|
||||
CharT operator ()( CharT Ch ) const
|
||||
{
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
return std::toupper( static_cast<typename boost::make_unsigned <CharT>::type> ( Ch ));
|
||||
return std::toupper( Ch);
|
||||
#else
|
||||
return std::toupper<CharT>( Ch, *m_Loc );
|
||||
return std::toupper( Ch, m_Loc );
|
||||
#endif
|
||||
}
|
||||
private:
|
||||
const std::locale* m_Loc;
|
||||
const std::locale& m_Loc;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
// algorithm implementation -------------------------------------------------------------------------
|
||||
|
||||
// Transform a range
|
||||
template<typename OutputIteratorT, typename RangeT, typename FunctorT>
|
||||
OutputIteratorT transform_range_copy(
|
||||
OutputIteratorT Output,
|
||||
const RangeT& Input,
|
||||
FunctorT Functor)
|
||||
{
|
||||
return std::transform(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
Output,
|
||||
Functor);
|
||||
}
|
||||
|
||||
// Transform a range (in-place)
|
||||
template<typename RangeT, typename FunctorT>
|
||||
void transform_range(
|
||||
const RangeT& Input,
|
||||
FunctorT Functor)
|
||||
{
|
||||
std::transform(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
::boost::begin(Input),
|
||||
Functor);
|
||||
}
|
||||
|
||||
template<typename SequenceT, typename RangeT, typename FunctorT>
|
||||
inline SequenceT transform_range_copy(
|
||||
const RangeT& Input,
|
||||
FunctorT Functor)
|
||||
{
|
||||
return SequenceT(
|
||||
::boost::make_transform_iterator(
|
||||
::boost::begin(Input),
|
||||
Functor),
|
||||
::boost::make_transform_iterator(
|
||||
::boost::end(Input),
|
||||
Functor));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace algorithm
|
||||
} // namespace boost
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library classification.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
|
||||
#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
|
||||
@ -15,6 +14,7 @@
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <locale>
|
||||
#include <set>
|
||||
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
@ -28,16 +28,17 @@ namespace boost {
|
||||
|
||||
// classification functors -----------------------------------------------//
|
||||
|
||||
// is_classified functor
|
||||
// is_classified functor
|
||||
struct is_classifiedF :
|
||||
public predicate_facade<is_classifiedF>
|
||||
{
|
||||
// Boost.ResultOf support
|
||||
typedef bool result_type;
|
||||
// Boost.Lambda support
|
||||
template <class Args> struct sig { typedef bool type; };
|
||||
|
||||
// Constructor from a locale
|
||||
is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
|
||||
m_Type(Type), m_Locale(Loc) {}
|
||||
|
||||
// Operation
|
||||
template<typename CharT>
|
||||
bool operator()( CharT Ch ) const
|
||||
@ -45,7 +46,7 @@ namespace boost {
|
||||
return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
|
||||
}
|
||||
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL)
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x564) && !defined(_USE_OLD_RW_STL)
|
||||
template<>
|
||||
bool operator()( char const Ch ) const
|
||||
{
|
||||
@ -54,11 +55,10 @@ namespace boost {
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::ctype_base::mask m_Type;
|
||||
std::locale m_Locale;
|
||||
const std::ctype_base::mask m_Type;
|
||||
const std::locale m_Locale;
|
||||
};
|
||||
|
||||
|
||||
// is_any_of functor
|
||||
/*
|
||||
returns true if the value is from the specified set
|
||||
@ -67,181 +67,25 @@ namespace boost {
|
||||
struct is_any_ofF :
|
||||
public predicate_facade<is_any_ofF<CharT> >
|
||||
{
|
||||
private:
|
||||
// set cannot operate on const value-type
|
||||
typedef typename ::boost::remove_const<CharT>::type set_value_type;
|
||||
|
||||
public:
|
||||
// Boost.ResultOf support
|
||||
typedef bool result_type;
|
||||
// Boost.Lambda support
|
||||
template <class Args> struct sig { typedef bool type; };
|
||||
|
||||
// Constructor
|
||||
template<typename RangeT>
|
||||
is_any_ofF( const RangeT& Range ) : m_Size(0)
|
||||
{
|
||||
// Prepare storage
|
||||
m_Storage.m_dynSet=0;
|
||||
|
||||
std::size_t Size=::boost::distance(Range);
|
||||
m_Size=Size;
|
||||
set_value_type* Storage=0;
|
||||
|
||||
if(use_fixed_storage(m_Size))
|
||||
{
|
||||
// Use fixed storage
|
||||
Storage=&m_Storage.m_fixSet[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use dynamic storage
|
||||
m_Storage.m_dynSet=new set_value_type[m_Size];
|
||||
Storage=m_Storage.m_dynSet;
|
||||
}
|
||||
|
||||
// Use fixed storage
|
||||
::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
|
||||
::std::sort(Storage, Storage+m_Size);
|
||||
}
|
||||
|
||||
// Copy constructor
|
||||
is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
|
||||
{
|
||||
// Prepare storage
|
||||
m_Storage.m_dynSet=0;
|
||||
const set_value_type* SrcStorage=0;
|
||||
set_value_type* DestStorage=0;
|
||||
|
||||
if(use_fixed_storage(m_Size))
|
||||
{
|
||||
// Use fixed storage
|
||||
DestStorage=&m_Storage.m_fixSet[0];
|
||||
SrcStorage=&Other.m_Storage.m_fixSet[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use dynamic storage
|
||||
m_Storage.m_dynSet=new set_value_type[m_Size];
|
||||
DestStorage=m_Storage.m_dynSet;
|
||||
SrcStorage=Other.m_Storage.m_dynSet;
|
||||
}
|
||||
|
||||
// Use fixed storage
|
||||
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~is_any_ofF()
|
||||
{
|
||||
if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
|
||||
{
|
||||
delete [] m_Storage.m_dynSet;
|
||||
}
|
||||
}
|
||||
|
||||
// Assignment
|
||||
is_any_ofF& operator=(const is_any_ofF& Other)
|
||||
{
|
||||
// Handle self assignment
|
||||
if(this==&Other) return *this;
|
||||
|
||||
// Prepare storage
|
||||
const set_value_type* SrcStorage;
|
||||
set_value_type* DestStorage;
|
||||
|
||||
if(use_fixed_storage(Other.m_Size))
|
||||
{
|
||||
// Use fixed storage
|
||||
DestStorage=&m_Storage.m_fixSet[0];
|
||||
SrcStorage=&Other.m_Storage.m_fixSet[0];
|
||||
|
||||
// Delete old storage if was present
|
||||
if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
|
||||
{
|
||||
delete [] m_Storage.m_dynSet;
|
||||
}
|
||||
|
||||
// Set new size
|
||||
m_Size=Other.m_Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Other uses dynamic storage
|
||||
SrcStorage=Other.m_Storage.m_dynSet;
|
||||
|
||||
// Check what kind of storage are we using right now
|
||||
if(use_fixed_storage(m_Size))
|
||||
{
|
||||
// Using fixed storage, allocate new
|
||||
set_value_type* pTemp=new set_value_type[Other.m_Size];
|
||||
DestStorage=pTemp;
|
||||
m_Storage.m_dynSet=pTemp;
|
||||
m_Size=Other.m_Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Using dynamic storage, check if can reuse
|
||||
if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
|
||||
{
|
||||
// Reuse the current storage
|
||||
DestStorage=m_Storage.m_dynSet;
|
||||
m_Size=Other.m_Size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate the new one
|
||||
set_value_type* pTemp=new set_value_type[Other.m_Size];
|
||||
DestStorage=pTemp;
|
||||
|
||||
// Delete old storage if necessary
|
||||
if(m_Storage.m_dynSet!=0)
|
||||
{
|
||||
delete [] m_Storage.m_dynSet;
|
||||
}
|
||||
// Store the new storage
|
||||
m_Storage.m_dynSet=pTemp;
|
||||
// Set new size
|
||||
m_Size=Other.m_Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the data
|
||||
::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
|
||||
|
||||
return *this;
|
||||
}
|
||||
is_any_ofF( const RangeT& Range ) :
|
||||
m_Set( begin(Range), end(Range) ) {}
|
||||
|
||||
// Operation
|
||||
template<typename Char2T>
|
||||
bool operator()( Char2T Ch ) const
|
||||
{
|
||||
const set_value_type* Storage=
|
||||
(use_fixed_storage(m_Size))
|
||||
? &m_Storage.m_fixSet[0]
|
||||
: m_Storage.m_dynSet;
|
||||
|
||||
return ::std::binary_search(Storage, Storage+m_Size, Ch);
|
||||
}
|
||||
private:
|
||||
// check if the size is eligible for fixed storage
|
||||
static bool use_fixed_storage(std::size_t size)
|
||||
{
|
||||
return size<=sizeof(set_value_type*)*2;
|
||||
return m_Set.find(Ch)!=m_Set.end();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// storage
|
||||
// The actual used storage is selected on the type
|
||||
union
|
||||
{
|
||||
set_value_type* m_dynSet;
|
||||
set_value_type m_fixSet[sizeof(set_value_type*)*2];
|
||||
}
|
||||
m_Storage;
|
||||
|
||||
// storage size
|
||||
::std::size_t m_Size;
|
||||
// set cannot operate on const value-type
|
||||
typedef typename remove_const<CharT>::type set_value_type;
|
||||
std::set<set_value_type> m_Set;
|
||||
};
|
||||
|
||||
// is_from_range functor
|
||||
@ -253,8 +97,8 @@ namespace boost {
|
||||
struct is_from_rangeF :
|
||||
public predicate_facade< is_from_rangeF<CharT> >
|
||||
{
|
||||
// Boost.ResultOf support
|
||||
typedef bool result_type;
|
||||
// Boost.Lambda support
|
||||
template <class Args> struct sig { typedef bool type; };
|
||||
|
||||
// Constructor
|
||||
is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
|
||||
@ -278,8 +122,8 @@ namespace boost {
|
||||
{
|
||||
public:
|
||||
|
||||
// Boost.ResultOf support
|
||||
typedef bool result_type;
|
||||
// Boost.Lambda support
|
||||
template <class Args> struct sig { typedef bool type; };
|
||||
|
||||
// Constructor
|
||||
pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
|
||||
@ -303,8 +147,8 @@ namespace boost {
|
||||
public predicate_facade< pred_orF<Pred1T,Pred2T> >
|
||||
{
|
||||
public:
|
||||
// Boost.ResultOf support
|
||||
typedef bool result_type;
|
||||
// Boost.Lambda support
|
||||
template <class Args> struct sig { typedef bool type; };
|
||||
|
||||
// Constructor
|
||||
pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
|
||||
@ -328,8 +172,8 @@ namespace boost {
|
||||
public predicate_facade< pred_notF<PredT> >
|
||||
{
|
||||
public:
|
||||
// Boost.ResultOf support
|
||||
typedef bool result_type;
|
||||
// Boost.Lambda support
|
||||
template <class Args> struct sig { typedef bool type; };
|
||||
|
||||
// Constructor
|
||||
pred_notF( PredT Pred ) : m_Pred(Pred) {}
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find_format.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_FORMAT_DETAIL_HPP
|
||||
#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP
|
||||
@ -24,15 +23,39 @@ namespace boost {
|
||||
|
||||
// find_format_copy (iterator variant) implementation -------------------------------//
|
||||
|
||||
template<
|
||||
template<
|
||||
typename OutputIteratorT,
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline OutputIteratorT find_format_copy_impl(
|
||||
OutputIteratorT Output,
|
||||
const InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult )
|
||||
{
|
||||
return find_format_copy_impl2(
|
||||
Output,
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
|
||||
template<
|
||||
typename OutputIteratorT,
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT,
|
||||
typename FormatResultT >
|
||||
inline OutputIteratorT find_format_copy_impl2(
|
||||
OutputIteratorT Output,
|
||||
const InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult,
|
||||
const FormatResultT& FormatResult )
|
||||
@ -49,54 +72,51 @@ namespace boost {
|
||||
if ( !M )
|
||||
{
|
||||
// Match not found - return original sequence
|
||||
Output = std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
|
||||
std::copy( begin(Input), end(Input), Output );
|
||||
return Output;
|
||||
}
|
||||
|
||||
// Copy the beginning of the sequence
|
||||
Output = std::copy( ::boost::begin(Input), ::boost::begin(M), Output );
|
||||
std::copy( begin(Input), begin(M), Output );
|
||||
// Format find result
|
||||
// Copy formated result
|
||||
Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output );
|
||||
std::copy( begin(M.format_result()), end(M.format_result()), Output );
|
||||
// Copy the rest of the sequence
|
||||
Output = std::copy( M.end(), ::boost::end(Input), Output );
|
||||
std::copy( M.end(), end(Input), Output );
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
template<
|
||||
typename OutputIteratorT,
|
||||
typename InputT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline OutputIteratorT find_format_copy_impl(
|
||||
OutputIteratorT Output,
|
||||
const InputT& Input,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult )
|
||||
{
|
||||
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
|
||||
return ::boost::algorithm::detail::find_format_copy_impl2(
|
||||
Output,
|
||||
Input,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
} else {
|
||||
return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// find_format_copy implementation --------------------------------------------------//
|
||||
|
||||
template<
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline InputT find_format_copy_impl(
|
||||
const InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult)
|
||||
{
|
||||
return find_format_copy_impl2(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT,
|
||||
typename FormatResultT >
|
||||
inline InputT find_format_copy_impl2(
|
||||
const InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult,
|
||||
const FormatResultT& FormatResult)
|
||||
@ -118,44 +138,45 @@ namespace boost {
|
||||
|
||||
InputT Output;
|
||||
// Copy the beginning of the sequence
|
||||
insert( Output, ::boost::end(Output), ::boost::begin(Input), M.begin() );
|
||||
insert( Output, end(Output), begin(Input), M.begin() );
|
||||
// Copy formated result
|
||||
insert( Output, ::boost::end(Output), M.format_result() );
|
||||
insert( Output, end(Output), M.format_result() );
|
||||
// Copy the rest of the sequence
|
||||
insert( Output, ::boost::end(Output), M.end(), ::boost::end(Input) );
|
||||
insert( Output, end(Output), M.end(), end(Input) );
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline InputT find_format_copy_impl(
|
||||
const InputT& Input,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult)
|
||||
{
|
||||
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
|
||||
return ::boost::algorithm::detail::find_format_copy_impl2(
|
||||
Input,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
} else {
|
||||
return Input;
|
||||
}
|
||||
}
|
||||
|
||||
// replace implementation ----------------------------------------------------//
|
||||
// replace implementation ----------------------------------------------------//
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline void find_format_impl(
|
||||
InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult)
|
||||
{
|
||||
find_format_impl2(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT,
|
||||
typename FormatResultT >
|
||||
inline void find_format_impl2(
|
||||
InputT& Input,
|
||||
FinderT,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult,
|
||||
const FormatResultT& FormatResult)
|
||||
@ -176,25 +197,7 @@ namespace boost {
|
||||
}
|
||||
|
||||
// Replace match
|
||||
::boost::algorithm::detail::replace( Input, M.begin(), M.end(), M.format_result() );
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline void find_format_impl(
|
||||
InputT& Input,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult)
|
||||
{
|
||||
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
|
||||
::boost::algorithm::detail::find_format_impl2(
|
||||
Input,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
replace( Input, M.begin(), M.end(), M.format_result() );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find_format_all.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
|
||||
#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
|
||||
@ -24,7 +23,29 @@ namespace boost {
|
||||
|
||||
// find_format_all_copy (iterator variant) implementation ---------------------------//
|
||||
|
||||
template<
|
||||
template<
|
||||
typename OutputIteratorT,
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline OutputIteratorT find_format_all_copy_impl(
|
||||
OutputIteratorT Output,
|
||||
const InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult )
|
||||
{
|
||||
return find_format_all_copy_impl2(
|
||||
Output,
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
|
||||
template<
|
||||
typename OutputIteratorT,
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
@ -51,56 +72,49 @@ namespace boost {
|
||||
store_type M( FindResult, FormatResult, Formatter );
|
||||
|
||||
// Initialize last match
|
||||
input_iterator_type LastMatch=::boost::begin(Input);
|
||||
input_iterator_type LastMatch=begin(Input);
|
||||
|
||||
// Iterate through all matches
|
||||
while( M )
|
||||
{
|
||||
// Copy the beginning of the sequence
|
||||
Output = std::copy( LastMatch, M.begin(), Output );
|
||||
std::copy( LastMatch, M.begin(), Output );
|
||||
// Copy formated result
|
||||
Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output );
|
||||
std::copy( begin(M.format_result()), end(M.format_result()), Output );
|
||||
|
||||
// Proceed to the next match
|
||||
LastMatch=M.end();
|
||||
M=Finder( LastMatch, ::boost::end(Input) );
|
||||
M=Finder( LastMatch, end(Input) );
|
||||
}
|
||||
|
||||
// Copy the rest of the sequence
|
||||
Output = std::copy( LastMatch, ::boost::end(Input), Output );
|
||||
std::copy( LastMatch, end(Input), Output );
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
// find_format_all_copy implementation ----------------------------------------------//
|
||||
|
||||
template<
|
||||
typename OutputIteratorT,
|
||||
typename InputT,
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline OutputIteratorT find_format_all_copy_impl(
|
||||
OutputIteratorT Output,
|
||||
inline InputT find_format_all_copy_impl(
|
||||
const InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult )
|
||||
{
|
||||
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
|
||||
return ::boost::algorithm::detail::find_format_all_copy_impl2(
|
||||
Output,
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
} else {
|
||||
return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
|
||||
}
|
||||
const FindResultT& FindResult)
|
||||
{
|
||||
return find_format_all_copy_impl2(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
|
||||
// find_format_all_copy implementation ----------------------------------------------//
|
||||
|
||||
template<
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
@ -125,7 +139,7 @@ namespace boost {
|
||||
store_type M( FindResult, FormatResult, Formatter );
|
||||
|
||||
// Initialize last match
|
||||
input_iterator_type LastMatch=::boost::begin(Input);
|
||||
input_iterator_type LastMatch=begin(Input);
|
||||
|
||||
// Output temporary
|
||||
InputT Output;
|
||||
@ -134,46 +148,42 @@ namespace boost {
|
||||
while( M )
|
||||
{
|
||||
// Copy the beginning of the sequence
|
||||
insert( Output, ::boost::end(Output), LastMatch, M.begin() );
|
||||
insert( Output, end(Output), LastMatch, M.begin() );
|
||||
// Copy formated result
|
||||
insert( Output, ::boost::end(Output), M.format_result() );
|
||||
insert( Output, end(Output), M.format_result() );
|
||||
|
||||
// Proceed to the next match
|
||||
LastMatch=M.end();
|
||||
M=Finder( LastMatch, ::boost::end(Input) );
|
||||
M=Finder( LastMatch, end(Input) );
|
||||
}
|
||||
|
||||
// Copy the rest of the sequence
|
||||
::boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, ::boost::end(Input) );
|
||||
insert( Output, end(Output), LastMatch, end(Input) );
|
||||
|
||||
return Output;
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
// find_format_all implementation ------------------------------------------------//
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline InputT find_format_all_copy_impl(
|
||||
const InputT& Input,
|
||||
inline void find_format_all_impl(
|
||||
InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
const FindResultT& FindResult)
|
||||
FindResultT FindResult)
|
||||
{
|
||||
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
|
||||
return ::boost::algorithm::detail::find_format_all_copy_impl2(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
} else {
|
||||
return Input;
|
||||
}
|
||||
find_format_all_impl2(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
}
|
||||
|
||||
// find_format_all implementation ------------------------------------------------//
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
@ -202,8 +212,8 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME range_value<InputT>::type> Storage;
|
||||
|
||||
// Initialize replacement iterators
|
||||
input_iterator_type InsertIt=::boost::begin(Input);
|
||||
input_iterator_type SearchIt=::boost::begin(Input);
|
||||
input_iterator_type InsertIt=begin(Input);
|
||||
input_iterator_type SearchIt=begin(Input);
|
||||
|
||||
while( M )
|
||||
{
|
||||
@ -219,50 +229,29 @@ namespace boost {
|
||||
SearchIt=M.end();
|
||||
|
||||
// Copy formated replace to the storage
|
||||
::boost::algorithm::detail::copy_to_storage( Storage, M.format_result() );
|
||||
copy_to_storage( Storage, M.format_result() );
|
||||
|
||||
// Find range for a next match
|
||||
M=Finder( SearchIt, ::boost::end(Input) );
|
||||
M=Finder( SearchIt, end(Input) );
|
||||
}
|
||||
|
||||
// process the last segment
|
||||
InsertIt=::boost::algorithm::detail::process_segment(
|
||||
InsertIt=process_segment(
|
||||
Storage,
|
||||
Input,
|
||||
InsertIt,
|
||||
SearchIt,
|
||||
::boost::end(Input) );
|
||||
end(Input) );
|
||||
|
||||
if ( Storage.empty() )
|
||||
{
|
||||
// Truncate input
|
||||
::boost::algorithm::detail::erase( Input, InsertIt, ::boost::end(Input) );
|
||||
erase( Input, InsertIt, end(Input) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy remaining data to the end of input
|
||||
::boost::algorithm::detail::insert( Input, ::boost::end(Input), Storage.begin(), Storage.end() );
|
||||
}
|
||||
}
|
||||
|
||||
template<
|
||||
typename InputT,
|
||||
typename FinderT,
|
||||
typename FormatterT,
|
||||
typename FindResultT >
|
||||
inline void find_format_all_impl(
|
||||
InputT& Input,
|
||||
FinderT Finder,
|
||||
FormatterT Formatter,
|
||||
FindResultT FindResult)
|
||||
{
|
||||
if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
|
||||
::boost::algorithm::detail::find_format_all_impl2(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
FindResult,
|
||||
Formatter(FindResult) );
|
||||
insert( Input, end(Input), Storage.begin(), Storage.end() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find_format_store.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
|
||||
#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
|
||||
@ -20,10 +19,6 @@ namespace boost {
|
||||
|
||||
// temporary format and find result storage --------------------------------//
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4512) //assignment operator could not be generated
|
||||
#endif
|
||||
template<
|
||||
typename ForwardIteratorT,
|
||||
typename FormatterT,
|
||||
@ -52,9 +47,7 @@ namespace boost {
|
||||
find_format_store& operator=( FindResultT FindResult )
|
||||
{
|
||||
iterator_range<ForwardIteratorT>::operator=(FindResult);
|
||||
if( !this->empty() ) {
|
||||
m_FormatResult=m_Formatter(FindResult);
|
||||
}
|
||||
m_FormatResult=m_Formatter(FindResult);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -70,18 +63,6 @@ namespace boost {
|
||||
const formatter_type& m_Formatter;
|
||||
};
|
||||
|
||||
template<typename InputT, typename FindResultT>
|
||||
bool check_find_result(InputT&, FindResultT& FindResult)
|
||||
{
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<InputT>::type input_iterator_type;
|
||||
iterator_range<input_iterator_type> ResultRange(FindResult);
|
||||
return !ResultRange.empty();
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
} // namespace detail
|
||||
} // namespace algorithm
|
||||
} // namespace boost
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find_iterator.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
|
||||
#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library finder.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FINDER_DETAIL_HPP
|
||||
#define BOOST_STRING_FINDER_DETAIL_HPP
|
||||
@ -19,7 +18,6 @@
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/empty.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
@ -41,7 +39,7 @@ namespace boost {
|
||||
// Construction
|
||||
template< typename SearchT >
|
||||
first_finderF( const SearchT& Search, PredicateT Comp ) :
|
||||
m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
|
||||
m_Search(begin(Search), end(Search)), m_Comp(Comp) {}
|
||||
first_finderF(
|
||||
search_iterator_type SearchBegin,
|
||||
search_iterator_type SearchEnd,
|
||||
@ -92,7 +90,7 @@ namespace boost {
|
||||
|
||||
// find last functor -----------------------------------------------//
|
||||
|
||||
// find the last match a subseqeunce in the sequence ( functor )
|
||||
// find the last match a subsequnce in the sequence ( functor )
|
||||
/*
|
||||
Returns a pair <begin,end> marking the subsequence in the sequence.
|
||||
If the find fails, returns <End,End>
|
||||
@ -108,7 +106,7 @@ namespace boost {
|
||||
// Construction
|
||||
template< typename SearchT >
|
||||
last_finderF( const SearchT& Search, PredicateT Comp ) :
|
||||
m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {}
|
||||
m_Search(begin(Search), end(Search)), m_Comp(Comp) {}
|
||||
last_finderF(
|
||||
search_iterator_type SearchBegin,
|
||||
search_iterator_type SearchEnd,
|
||||
@ -154,7 +152,7 @@ namespace boost {
|
||||
while( M )
|
||||
{
|
||||
Last=M;
|
||||
M=first_finder( ::boost::end(M), End );
|
||||
M=first_finder( end(M), End );
|
||||
}
|
||||
|
||||
return Last;
|
||||
@ -202,7 +200,7 @@ namespace boost {
|
||||
|
||||
// find n-th functor -----------------------------------------------//
|
||||
|
||||
// find the n-th match of a subsequence in the sequence ( functor )
|
||||
// find the n-th match of a subsequnce in the sequence ( functor )
|
||||
/*
|
||||
Returns a pair <begin,end> marking the subsequence in the sequence.
|
||||
If the find fails, returns <End,End>
|
||||
@ -214,23 +212,20 @@ namespace boost {
|
||||
typedef first_finderF<
|
||||
search_iterator_type,
|
||||
PredicateT> first_finder_type;
|
||||
typedef last_finderF<
|
||||
search_iterator_type,
|
||||
PredicateT> last_finder_type;
|
||||
|
||||
// Construction
|
||||
template< typename SearchT >
|
||||
nth_finderF(
|
||||
const SearchT& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
PredicateT Comp) :
|
||||
m_Search(::boost::begin(Search), ::boost::end(Search)),
|
||||
m_Search(begin(Search), end(Search)),
|
||||
m_Nth(Nth),
|
||||
m_Comp(Comp) {}
|
||||
nth_finderF(
|
||||
search_iterator_type SearchBegin,
|
||||
search_iterator_type SearchEnd,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
PredicateT Comp) :
|
||||
m_Search(SearchBegin, SearchEnd),
|
||||
m_Nth(Nth),
|
||||
@ -242,26 +237,6 @@ namespace boost {
|
||||
operator()(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End ) const
|
||||
{
|
||||
if(m_Nth>=0)
|
||||
{
|
||||
return find_forward(Begin, End, m_Nth);
|
||||
}
|
||||
else
|
||||
{
|
||||
return find_backward(Begin, End, -m_Nth);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
// Implementation helpers
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_forward(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
@ -270,16 +245,16 @@ namespace boost {
|
||||
if( boost::empty(m_Search) )
|
||||
return result_type( End, End );
|
||||
|
||||
// Instantiate find functor
|
||||
// Instantiate find funtor
|
||||
first_finder_type first_finder(
|
||||
m_Search.begin(), m_Search.end(), m_Comp );
|
||||
|
||||
result_type M( Begin, Begin );
|
||||
|
||||
for( unsigned int n=0; n<=N; ++n )
|
||||
for( unsigned int n=0; n<=m_Nth; ++n )
|
||||
{
|
||||
// find next match
|
||||
M=first_finder( ::boost::end(M), End );
|
||||
M=first_finder( end(M), End );
|
||||
|
||||
if ( !M )
|
||||
{
|
||||
@ -291,179 +266,14 @@ namespace boost {
|
||||
return M;
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_backward(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
// Sanity check
|
||||
if( boost::empty(m_Search) )
|
||||
return result_type( End, End );
|
||||
|
||||
// Instantiate find functor
|
||||
last_finder_type last_finder(
|
||||
m_Search.begin(), m_Search.end(), m_Comp );
|
||||
|
||||
result_type M( End, End );
|
||||
|
||||
for( unsigned int n=1; n<=N; ++n )
|
||||
{
|
||||
// find next match
|
||||
M=last_finder( Begin, ::boost::begin(M) );
|
||||
|
||||
if ( !M )
|
||||
{
|
||||
// Subsequence not found, return
|
||||
return M;
|
||||
}
|
||||
}
|
||||
|
||||
return M;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
iterator_range<search_iterator_type> m_Search;
|
||||
int m_Nth;
|
||||
unsigned int m_Nth;
|
||||
PredicateT m_Comp;
|
||||
};
|
||||
|
||||
// find head/tail implementation helpers ---------------------------//
|
||||
|
||||
template<typename ForwardIteratorT>
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_head_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N,
|
||||
std::forward_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
input_iterator_type It=Begin;
|
||||
for(
|
||||
unsigned int Index=0;
|
||||
Index<N && It!=End; ++Index,++It ) {};
|
||||
|
||||
return result_type( Begin, It );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_head_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N,
|
||||
std::random_access_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
|
||||
return result_type( Begin, End );
|
||||
|
||||
return result_type(Begin,Begin+N);
|
||||
}
|
||||
|
||||
// Find head implementation
|
||||
template<typename ForwardIteratorT>
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_head_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N )
|
||||
{
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
iterator_traits<ForwardIteratorT>::iterator_category category;
|
||||
|
||||
return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_tail_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N,
|
||||
std::forward_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
unsigned int Index=0;
|
||||
input_iterator_type It=Begin;
|
||||
input_iterator_type It2=Begin;
|
||||
|
||||
// Advance It2 by N increments
|
||||
for( Index=0; Index<N && It2!=End; ++Index,++It2 ) {};
|
||||
|
||||
// Advance It, It2 to the end
|
||||
for(; It2!=End; ++It,++It2 ) {};
|
||||
|
||||
return result_type( It, It2 );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_tail_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N,
|
||||
std::bidirectional_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
input_iterator_type It=End;
|
||||
for(
|
||||
unsigned int Index=0;
|
||||
Index<N && It!=Begin; ++Index,--It ) {};
|
||||
|
||||
return result_type( It, End );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_tail_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N,
|
||||
std::random_access_iterator_tag )
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
|
||||
return result_type( Begin, End );
|
||||
|
||||
return result_type( End-N, End );
|
||||
}
|
||||
|
||||
// Operation
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
find_tail_impl(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
unsigned int N )
|
||||
{
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
iterator_traits<ForwardIteratorT>::iterator_category category;
|
||||
|
||||
return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// find head functor -----------------------------------------------//
|
||||
|
||||
|
||||
// find a head in the sequence ( functor )
|
||||
/*
|
||||
This functor find a head of the specified range. For
|
||||
@ -473,7 +283,7 @@ namespace boost {
|
||||
struct head_finderF
|
||||
{
|
||||
// Construction
|
||||
head_finderF( int N ) : m_N(N) {}
|
||||
head_finderF( unsigned int N ) : m_N(N) {}
|
||||
|
||||
// Operation
|
||||
template< typename ForwardIteratorT >
|
||||
@ -482,26 +292,54 @@ namespace boost {
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End ) const
|
||||
{
|
||||
if(m_N>=0)
|
||||
{
|
||||
return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N );
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator_range<ForwardIteratorT> Res=
|
||||
::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N );
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
iterator_traits<ForwardIteratorT>::iterator_category category;
|
||||
|
||||
return ::boost::make_iterator_range(Begin, Res.begin());
|
||||
}
|
||||
return findit( Begin, End, category() );
|
||||
}
|
||||
|
||||
private:
|
||||
int m_N;
|
||||
// Find operation implementation
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
findit(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
std::forward_iterator_tag ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
input_iterator_type It=Begin;
|
||||
for(
|
||||
unsigned int Index=0;
|
||||
Index<m_N && It!=End; ++Index,++It ) {};
|
||||
|
||||
return result_type( Begin, It );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
findit(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
std::random_access_iterator_tag ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < m_N ) )
|
||||
return result_type( Begin, End );
|
||||
|
||||
return result_type(Begin,Begin+m_N);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int m_N;
|
||||
};
|
||||
|
||||
// find tail functor -----------------------------------------------//
|
||||
|
||||
|
||||
// find a tail in the sequence ( functor )
|
||||
/*
|
||||
This functor find a tail of the specified range. For
|
||||
@ -511,7 +349,7 @@ namespace boost {
|
||||
struct tail_finderF
|
||||
{
|
||||
// Construction
|
||||
tail_finderF( int N ) : m_N(N) {}
|
||||
tail_finderF( unsigned int N ) : m_N(N) {}
|
||||
|
||||
// Operation
|
||||
template< typename ForwardIteratorT >
|
||||
@ -520,21 +358,74 @@ namespace boost {
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End ) const
|
||||
{
|
||||
if(m_N>=0)
|
||||
{
|
||||
return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N );
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator_range<ForwardIteratorT> Res=
|
||||
::boost::algorithm::detail::find_head_impl( Begin, End, -m_N );
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
iterator_traits<ForwardIteratorT>::iterator_category category;
|
||||
|
||||
return ::boost::make_iterator_range(Res.end(), End);
|
||||
}
|
||||
return findit( Begin, End, category() );
|
||||
}
|
||||
|
||||
private:
|
||||
int m_N;
|
||||
// Find operation implementation
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
findit(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
std::forward_iterator_tag ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
unsigned int Index=0;
|
||||
input_iterator_type It=Begin;
|
||||
input_iterator_type It2=Begin;
|
||||
|
||||
// Advance It2 by N incremets
|
||||
for( Index=0; Index<m_N && It2!=End; ++Index,++It2 ) {};
|
||||
|
||||
// Advance It, It2 to the end
|
||||
for(; It2!=End; ++It,++It2 ) {};
|
||||
|
||||
return result_type( It, It2 );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
findit(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
std::bidirectional_iterator_tag ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
input_iterator_type It=End;
|
||||
for(
|
||||
unsigned int Index=0;
|
||||
Index<m_N && It!=Begin; ++Index,--It ) {};
|
||||
|
||||
return result_type( It, End );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT >
|
||||
iterator_range<ForwardIteratorT>
|
||||
findit(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End,
|
||||
std::random_access_iterator_tag ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef iterator_range<ForwardIteratorT> result_type;
|
||||
|
||||
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < m_N ) )
|
||||
return result_type( Begin, End );
|
||||
|
||||
return result_type( End-m_N, End );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
unsigned int m_N;
|
||||
};
|
||||
|
||||
// find token functor -----------------------------------------------//
|
||||
@ -584,7 +475,7 @@ namespace boost {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Advance by one position
|
||||
// Advance by one possition
|
||||
++It2;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find_regex.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FINDER_REGEX_DETAIL_HPP
|
||||
#define BOOST_STRING_FINDER_REGEX_DETAIL_HPP
|
||||
@ -98,7 +97,7 @@ namespace boost {
|
||||
// instantiate match result
|
||||
match_results<input_iterator_type> result;
|
||||
// search for a match
|
||||
if ( ::boost::regex_search( Begin, End, result, m_Rx, m_MatchFlags ) )
|
||||
if ( regex_search( Begin, End, result, m_Rx, m_MatchFlags ) )
|
||||
{
|
||||
// construct a result
|
||||
return result_type( result );
|
||||
|
@ -1,10 +1,9 @@
|
||||
// Boost string_algo library formatter.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
@ -39,7 +38,7 @@ namespace boost {
|
||||
public:
|
||||
// Construction
|
||||
const_formatF(const RangeT& Format) :
|
||||
m_Format(::boost::begin(Format), ::boost::end(Format)) {}
|
||||
m_Format(begin(Format), end(Format)) {}
|
||||
|
||||
// Operation
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
@ -70,7 +69,7 @@ namespace boost {
|
||||
template< typename Range2T >
|
||||
const RangeT& operator()(const Range2T& Replace) const
|
||||
{
|
||||
return RangeT(::boost::begin(Replace), ::boost::end(Replace));
|
||||
return RangeT(begin(Replace), end(Replace));
|
||||
}
|
||||
};
|
||||
|
||||
@ -87,31 +86,6 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
|
||||
// dissect format functor ----------------------------------------------------//
|
||||
|
||||
// dissect format functor
|
||||
template<typename FinderT>
|
||||
struct dissect_formatF
|
||||
{
|
||||
public:
|
||||
// Construction
|
||||
dissect_formatF(FinderT Finder) :
|
||||
m_Finder(Finder) {}
|
||||
|
||||
// Operation
|
||||
template<typename RangeT>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
|
||||
operator()(const RangeT& Replace) const
|
||||
{
|
||||
return m_Finder(::boost::begin(Replace), ::boost::end(Replace));
|
||||
}
|
||||
|
||||
private:
|
||||
FinderT m_Finder;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace algorithm
|
||||
} // namespace boost
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library formatter_regex.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP
|
||||
#define BOOST_STRING_FORMATTER_REGEX_DETAIL_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library predicate.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_PREDICATE_DETAIL_HPP
|
||||
#define BOOST_STRING_PREDICATE_DETAIL_HPP
|
||||
@ -63,7 +62,7 @@ namespace boost {
|
||||
|
||||
iterator_range<ForwardIterator1T> Result
|
||||
=last_finder(
|
||||
::boost::make_iterator_range(SubBegin, SubEnd),
|
||||
make_iterator_range(SubBegin, SubEnd),
|
||||
Comp)(Begin, End);
|
||||
|
||||
return !Result.empty() && Result.end()==End;
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library replace_storage.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
|
||||
#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP
|
||||
@ -46,7 +45,7 @@ namespace boost {
|
||||
StorageT& Storage,
|
||||
const WhatT& What )
|
||||
{
|
||||
Storage.insert( Storage.end(), ::boost::begin(What), ::boost::end(What) );
|
||||
Storage.insert( Storage.end(), begin(What), end(What) );
|
||||
}
|
||||
|
||||
|
||||
@ -68,7 +67,7 @@ namespace boost {
|
||||
ForwardIteratorT SegmentEnd )
|
||||
{
|
||||
// Copy data from the storage until the beginning of the segment
|
||||
ForwardIteratorT It=::boost::algorithm::detail::move_from_storage( Storage, InsertIt, SegmentBegin );
|
||||
ForwardIteratorT It=move_from_storage( Storage, InsertIt, SegmentBegin );
|
||||
|
||||
// 3 cases are possible :
|
||||
// a) Storage is empty, It==SegmentBegin
|
||||
@ -125,7 +124,7 @@ namespace boost {
|
||||
|
||||
{
|
||||
// Call replace to do the job
|
||||
::boost::algorithm::detail::replace( Input, InsertIt, SegmentBegin, Storage );
|
||||
replace( Input, InsertIt, SegmentBegin, Storage );
|
||||
// Empty the storage
|
||||
Storage.clear();
|
||||
// Iterators were not changed, simply return the end of segment
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library sequence.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP
|
||||
#define BOOST_STRING_DETAIL_SEQUENCE_HPP
|
||||
@ -41,7 +40,7 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME InputT::iterator At,
|
||||
const InsertT& Insert )
|
||||
{
|
||||
::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) );
|
||||
insert( Input, At, begin(Insert), end(Insert) );
|
||||
}
|
||||
|
||||
// erase helper ---------------------------------------------------//
|
||||
@ -184,11 +183,11 @@ namespace boost {
|
||||
{
|
||||
if(From!=To)
|
||||
{
|
||||
::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) );
|
||||
replace( Input, From, To, begin(Insert), end(Insert) );
|
||||
}
|
||||
else
|
||||
{
|
||||
::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) );
|
||||
insert( Input, From, begin(Insert), end(Insert) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library trim.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_TRIM_DETAIL_HPP
|
||||
#define BOOST_STRING_TRIM_DETAIL_HPP
|
||||
@ -20,6 +19,36 @@ namespace boost {
|
||||
|
||||
// trim iterator helper -----------------------------------------------//
|
||||
|
||||
// Search for first non matching character from the beginning of the sequence
|
||||
template< typename ForwardIteratorT, typename PredicateT >
|
||||
inline ForwardIteratorT trim_begin(
|
||||
ForwardIteratorT InBegin,
|
||||
ForwardIteratorT InEnd,
|
||||
PredicateT IsSpace )
|
||||
{
|
||||
ForwardIteratorT It=InBegin;
|
||||
for(; It!=InEnd; ++It )
|
||||
{
|
||||
if (!IsSpace(*It))
|
||||
return It;
|
||||
}
|
||||
|
||||
return It;
|
||||
}
|
||||
|
||||
// Search for first non matching character from the end of the sequence
|
||||
template< typename ForwardIteratorT, typename PredicateT >
|
||||
inline ForwardIteratorT trim_end(
|
||||
ForwardIteratorT InBegin,
|
||||
ForwardIteratorT InEnd,
|
||||
PredicateT IsSpace )
|
||||
{
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
iterator_traits<ForwardIteratorT>::iterator_category category;
|
||||
|
||||
return trim_end_iter_select( InBegin, InEnd, IsSpace, category() );
|
||||
}
|
||||
|
||||
template< typename ForwardIteratorT, typename PredicateT >
|
||||
inline ForwardIteratorT trim_end_iter_select(
|
||||
ForwardIteratorT InBegin,
|
||||
@ -56,36 +85,6 @@ namespace boost {
|
||||
|
||||
return InBegin;
|
||||
}
|
||||
// Search for first non matching character from the beginning of the sequence
|
||||
template< typename ForwardIteratorT, typename PredicateT >
|
||||
inline ForwardIteratorT trim_begin(
|
||||
ForwardIteratorT InBegin,
|
||||
ForwardIteratorT InEnd,
|
||||
PredicateT IsSpace )
|
||||
{
|
||||
ForwardIteratorT It=InBegin;
|
||||
for(; It!=InEnd; ++It )
|
||||
{
|
||||
if (!IsSpace(*It))
|
||||
return It;
|
||||
}
|
||||
|
||||
return It;
|
||||
}
|
||||
|
||||
// Search for first non matching character from the end of the sequence
|
||||
template< typename ForwardIteratorT, typename PredicateT >
|
||||
inline ForwardIteratorT trim_end(
|
||||
ForwardIteratorT InBegin,
|
||||
ForwardIteratorT InEnd,
|
||||
PredicateT IsSpace )
|
||||
{
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
iterator_traits<ForwardIteratorT>::iterator_category category;
|
||||
|
||||
return ::boost::algorithm::detail::trim_end_iter_select( InBegin, InEnd, IsSpace, category() );
|
||||
}
|
||||
|
||||
|
||||
} // namespace detail
|
||||
} // namespace algorithm
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library util.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_UTIL_DETAIL_HPP
|
||||
#define BOOST_STRING_UTIL_DETAIL_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library erase.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_ERASE_HPP
|
||||
#define BOOST_STRING_ERASE_HPP
|
||||
@ -54,11 +53,11 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type>& SearchRange )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::range_finder(SearchRange),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
range_finder(SearchRange),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase range algorithm
|
||||
@ -72,10 +71,10 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<SequenceT>::type>& SearchRange )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::range_finder(SearchRange),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
range_finder(SearchRange),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase range algorithm
|
||||
@ -93,10 +92,10 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME
|
||||
range_iterator<SequenceT>::type>& SearchRange )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::range_finder(SearchRange),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
range_finder(SearchRange),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_first --------------------------------------------------------//
|
||||
@ -124,11 +123,11 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Search )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase first algorithm
|
||||
@ -140,10 +139,10 @@ namespace boost {
|
||||
const SequenceT& Input,
|
||||
const RangeT& Search )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase first algorithm
|
||||
@ -159,10 +158,10 @@ namespace boost {
|
||||
SequenceT& Input,
|
||||
const RangeT& Search )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_first ( case insensitive ) ------------------------------------//
|
||||
@ -193,11 +192,11 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase first algorithm ( case insensitive )
|
||||
@ -210,10 +209,10 @@ namespace boost {
|
||||
const RangeT& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase first algorithm ( case insensitive )
|
||||
@ -231,10 +230,10 @@ namespace boost {
|
||||
const RangeT& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_last --------------------------------------------------------//
|
||||
@ -262,11 +261,11 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Search )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
last_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase last algorithm
|
||||
@ -278,10 +277,10 @@ namespace boost {
|
||||
const SequenceT& Input,
|
||||
const RangeT& Search )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
last_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase last algorithm
|
||||
@ -297,10 +296,10 @@ namespace boost {
|
||||
SequenceT& Input,
|
||||
const RangeT& Search )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
last_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_last ( case insensitive ) ------------------------------------//
|
||||
@ -331,11 +330,11 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
last_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase last algorithm ( case insensitive )
|
||||
@ -348,10 +347,10 @@ namespace boost {
|
||||
const RangeT& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
last_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase last algorithm ( case insensitive )
|
||||
@ -369,10 +368,10 @@ namespace boost {
|
||||
const RangeT& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
last_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_nth --------------------------------------------------------------------//
|
||||
@ -388,7 +387,6 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
|
||||
@ -402,13 +400,13 @@ namespace boost {
|
||||
OutputIteratorT Output,
|
||||
const Range1T& Input,
|
||||
const Range2T& Search,
|
||||
int Nth )
|
||||
unsigned int Nth )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
nth_finder(Search, Nth),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase nth algorithm
|
||||
@ -419,12 +417,12 @@ namespace boost {
|
||||
inline SequenceT erase_nth_copy(
|
||||
const SequenceT& Input,
|
||||
const RangeT& Search,
|
||||
int Nth )
|
||||
unsigned int Nth )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
nth_finder(Search, Nth),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase nth algorithm
|
||||
@ -435,18 +433,17 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for.
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline void erase_nth(
|
||||
SequenceT& Input,
|
||||
const RangeT& Search,
|
||||
int Nth )
|
||||
unsigned int Nth )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
nth_finder(Search, Nth),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_nth ( case insensitive ) ---------------------------------------------//
|
||||
@ -462,7 +459,6 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for.
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\param Loc A locale used for case insensitive comparison
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
@ -477,14 +473,14 @@ namespace boost {
|
||||
OutputIteratorT Output,
|
||||
const Range1T& Input,
|
||||
const Range2T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase nth algorithm
|
||||
@ -495,12 +491,12 @@ namespace boost {
|
||||
inline SequenceT ierase_nth_copy(
|
||||
const SequenceT& Input,
|
||||
const RangeT& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
@ -512,20 +508,19 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for.
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\param Loc A locale used for case insensitive comparison
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline void ierase_nth(
|
||||
SequenceT& Input,
|
||||
const RangeT& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
|
||||
@ -555,11 +550,11 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Search )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase all algorithm
|
||||
@ -571,10 +566,10 @@ namespace boost {
|
||||
const SequenceT& Input,
|
||||
const RangeT& Search )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase all algorithm
|
||||
@ -590,10 +585,10 @@ namespace boost {
|
||||
SequenceT& Input,
|
||||
const RangeT& Search )
|
||||
{
|
||||
::boost::algorithm::find_format_all(
|
||||
find_format_all(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_all ( case insensitive ) ------------------------------------//
|
||||
@ -624,11 +619,11 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase all algorithm ( case insensitive )
|
||||
@ -641,10 +636,10 @@ namespace boost {
|
||||
const RangeT& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
//! Erase all algorithm ( case insensitive )
|
||||
@ -662,10 +657,10 @@ namespace boost {
|
||||
const RangeT& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format_all(
|
||||
find_format_all(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::empty_formatter(Input) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
empty_formatter(Input) );
|
||||
}
|
||||
|
||||
// erase_head --------------------------------------------------------------------//
|
||||
@ -680,9 +675,7 @@ namespace boost {
|
||||
|
||||
\param Output An output iterator to which the result will be copied
|
||||
\param Input An input string
|
||||
\param N Length of the head.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the head
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
|
||||
@ -694,13 +687,13 @@ namespace boost {
|
||||
inline OutputIteratorT erase_head_copy(
|
||||
OutputIteratorT Output,
|
||||
const RangeT& Input,
|
||||
int N )
|
||||
unsigned int N )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::head_finder(N),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
head_finder(N),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase head algorithm
|
||||
@ -710,12 +703,12 @@ namespace boost {
|
||||
template<typename SequenceT>
|
||||
inline SequenceT erase_head_copy(
|
||||
const SequenceT& Input,
|
||||
int N )
|
||||
unsigned int N )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::head_finder(N),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
head_finder(N),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase head algorithm
|
||||
@ -726,18 +719,16 @@ namespace boost {
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the head
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
*/
|
||||
template<typename SequenceT>
|
||||
inline void erase_head(
|
||||
SequenceT& Input,
|
||||
int N )
|
||||
unsigned int N )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::head_finder(N),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
head_finder(N),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
// erase_tail --------------------------------------------------------------------//
|
||||
@ -752,9 +743,7 @@ namespace boost {
|
||||
|
||||
\param Output An output iterator to which the result will be copied
|
||||
\param Input An input string
|
||||
\param N Length of the tail.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the head
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
|
||||
@ -766,13 +755,13 @@ namespace boost {
|
||||
inline OutputIteratorT erase_tail_copy(
|
||||
OutputIteratorT Output,
|
||||
const RangeT& Input,
|
||||
int N )
|
||||
unsigned int N )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::tail_finder(N),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
tail_finder(N),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase tail algorithm
|
||||
@ -782,12 +771,12 @@ namespace boost {
|
||||
template<typename SequenceT>
|
||||
inline SequenceT erase_tail_copy(
|
||||
const SequenceT& Input,
|
||||
int N )
|
||||
unsigned int N )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::tail_finder(N),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
tail_finder(N),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase tail algorithm
|
||||
@ -797,19 +786,17 @@ namespace boost {
|
||||
considered to be the tail. The input sequence is modified in-place.
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the tail
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the head
|
||||
*/
|
||||
template<typename SequenceT>
|
||||
inline void erase_tail(
|
||||
SequenceT& Input,
|
||||
int N )
|
||||
unsigned int N )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::tail_finder(N),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
tail_finder(N),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_HPP
|
||||
#define BOOST_STRING_FIND_HPP
|
||||
@ -17,7 +16,8 @@
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
|
||||
#include <boost/algorithm/string/finder.hpp>
|
||||
#include <boost/algorithm/string/compare.hpp>
|
||||
@ -48,21 +48,19 @@ namespace boost {
|
||||
*/
|
||||
template<typename RangeT, typename FinderT>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>
|
||||
find(
|
||||
RangeT& Input,
|
||||
const FinderT& Finder)
|
||||
FinderT Finder)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
|
||||
return Finder(::boost::begin(lit_input),::boost::end(lit_input));
|
||||
return Finder(begin(Input),end(Input));
|
||||
}
|
||||
|
||||
// find_first -----------------------------------------------//
|
||||
|
||||
//! Find first algorithm
|
||||
/*!
|
||||
Search for the first occurrence of the substring in the input.
|
||||
Search for the first occurence of the substring in the input.
|
||||
|
||||
\param Input A string which will be searched.
|
||||
\param Search A substring to be searched for.
|
||||
@ -76,12 +74,13 @@ namespace boost {
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<Range1T>::type>
|
||||
find_first(
|
||||
Range1T& Input,
|
||||
const Range2T& Search)
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::first_finder(Search));
|
||||
return first_finder(Search)(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
//! Find first algorithm ( case insensitive )
|
||||
@ -102,20 +101,21 @@ namespace boost {
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<Range1T>::type>
|
||||
ifind_first(
|
||||
Range1T& Input,
|
||||
const Range2T& Search,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::first_finder(Search,is_iequal(Loc)));
|
||||
return first_finder(Search,is_iequal(Loc))(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
// find_last -----------------------------------------------//
|
||||
|
||||
//! Find last algorithm
|
||||
/*!
|
||||
Search for the last occurrence of the substring in the input.
|
||||
Search for the last occurence of the substring in the input.
|
||||
|
||||
\param Input A string which will be searched.
|
||||
\param Search A substring to be searched for.
|
||||
@ -129,12 +129,13 @@ namespace boost {
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<Range1T>::type>
|
||||
find_last(
|
||||
Range1T& Input,
|
||||
const Range2T& Search)
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::last_finder(Search));
|
||||
return last_finder(Search)(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
//! Find last algorithm ( case insensitive )
|
||||
@ -155,26 +156,26 @@ namespace boost {
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<Range1T>::type>
|
||||
ifind_last(
|
||||
Range1T& Input,
|
||||
const Range2T& Search,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::last_finder(Search, is_iequal(Loc)));
|
||||
return last_finder(Search, is_iequal(Loc))(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
// find_nth ----------------------------------------------------------------------//
|
||||
|
||||
//! Find n-th algorithm
|
||||
/*!
|
||||
Search for the n-th (zero-indexed) occurrence of the substring in the
|
||||
Search for the n-th (zero-indexed) occurence of the substring in the
|
||||
input.
|
||||
|
||||
\param Input A string which will be searched.
|
||||
\param Search A substring to be searched for.
|
||||
\param Nth An index (zero-indexed) of the match to be found.
|
||||
For negative N, the matches are counted from the end of string.
|
||||
\return
|
||||
An \c iterator_range delimiting the match.
|
||||
Returned iterator is either \c Range1T::iterator or
|
||||
@ -183,24 +184,24 @@ namespace boost {
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<Range1T>::type>
|
||||
find_nth(
|
||||
Range1T& Input,
|
||||
const Range2T& Search,
|
||||
int Nth)
|
||||
unsigned int Nth)
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::nth_finder(Search,Nth));
|
||||
return nth_finder(Search,Nth)(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
//! Find n-th algorithm ( case insensitive ).
|
||||
/*!
|
||||
Search for the n-th (zero-indexed) occurrence of the substring in the
|
||||
Search for the n-th (zero-indexed) occurence of the substring in the
|
||||
input. Searching is case insensitive.
|
||||
|
||||
\param Input A string which will be searched.
|
||||
\param Search A substring to be searched for.
|
||||
\param Nth An index (zero-indexed) of the match to be found.
|
||||
For negative N, the matches are counted from the end of string.
|
||||
\param Nth An index (zero-indexed) of the match to be found.
|
||||
\param Loc A locale used for case insensitive comparison
|
||||
\return
|
||||
An \c iterator_range delimiting the match.
|
||||
@ -213,14 +214,15 @@ namespace boost {
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<Range1T>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<Range1T>::type>
|
||||
ifind_nth(
|
||||
Range1T& Input,
|
||||
const Range2T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::nth_finder(Search,Nth,is_iequal(Loc)));
|
||||
return nth_finder(Search,Nth,is_iequal(Loc))(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
// find_head ----------------------------------------------------------------------//
|
||||
@ -233,8 +235,6 @@ namespace boost {
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the head
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\return
|
||||
An \c iterator_range delimiting the match.
|
||||
Returned iterator is either \c Range1T::iterator or
|
||||
@ -245,26 +245,25 @@ namespace boost {
|
||||
*/
|
||||
template<typename RangeT>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>
|
||||
find_head(
|
||||
RangeT& Input,
|
||||
int N)
|
||||
unsigned int N)
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::head_finder(N));
|
||||
return head_finder(N)(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
// find_tail ----------------------------------------------------------------------//
|
||||
|
||||
//! Find tail algorithm
|
||||
/*!
|
||||
Get the tail of the input. Tail is a suffix of the string of the
|
||||
Get the head of the input. Head is a suffix of the string of the
|
||||
given size. If the input is shorter then required, whole input if considered
|
||||
to be the tail.
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the tail.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the tail
|
||||
\return
|
||||
An \c iterator_range delimiting the match.
|
||||
Returned iterator is either \c RangeT::iterator or
|
||||
@ -276,12 +275,13 @@ namespace boost {
|
||||
*/
|
||||
template<typename RangeT>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>
|
||||
find_tail(
|
||||
RangeT& Input,
|
||||
int N)
|
||||
unsigned int N)
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::tail_finder(N));
|
||||
return tail_finder(N)(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
// find_token --------------------------------------------------------------------//
|
||||
@ -305,13 +305,14 @@ namespace boost {
|
||||
*/
|
||||
template<typename RangeT, typename PredicateT>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>
|
||||
find_token(
|
||||
RangeT& Input,
|
||||
PredicateT Pred,
|
||||
token_compress_mode_type eCompress=token_compress_off)
|
||||
{
|
||||
return ::boost::algorithm::find(Input, ::boost::algorithm::token_finder(Pred, eCompress));
|
||||
return token_finder(Pred, eCompress)(
|
||||
begin(Input),end(Input));
|
||||
}
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library find_format.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_FORMAT_HPP
|
||||
#define BOOST_STRING_FIND_FORMAT_HPP
|
||||
@ -17,7 +16,6 @@
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
|
||||
#include <boost/algorithm/string/concept.hpp>
|
||||
#include <boost/algorithm/string/detail/find_format.hpp>
|
||||
@ -62,24 +60,20 @@ namespace boost {
|
||||
FormatterT Formatter )
|
||||
{
|
||||
// Concept check
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
|
||||
));
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
|
||||
function_requires<
|
||||
FormatterConcept<
|
||||
FormatterT,
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
|
||||
));
|
||||
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
|
||||
|
||||
return detail::find_format_copy_impl(
|
||||
Output,
|
||||
lit_input,
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
Finder( ::boost::begin(lit_input), ::boost::end(lit_input) ) );
|
||||
Finder( begin(Input), end(Input) ) );
|
||||
}
|
||||
|
||||
//! Generic replace algorithm
|
||||
@ -96,21 +90,19 @@ namespace boost {
|
||||
FormatterT Formatter )
|
||||
{
|
||||
// Concept check
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
function_requires<
|
||||
FormatterConcept<
|
||||
FormatterT,
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
|
||||
return detail::find_format_copy_impl(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
Finder(::boost::begin(Input), ::boost::end(Input)));
|
||||
Finder(begin(Input), end(Input)));
|
||||
}
|
||||
|
||||
//! Generic replace algorithm
|
||||
@ -132,21 +124,19 @@ namespace boost {
|
||||
FormatterT Formatter)
|
||||
{
|
||||
// Concept check
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
function_requires<
|
||||
FormatterConcept<
|
||||
FormatterT,
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
|
||||
detail::find_format_impl(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
Finder(::boost::begin(Input), ::boost::end(Input)));
|
||||
Finder(begin(Input), end(Input)));
|
||||
}
|
||||
|
||||
|
||||
@ -181,25 +171,20 @@ namespace boost {
|
||||
FormatterT Formatter)
|
||||
{
|
||||
// Concept check
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
|
||||
));
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
|
||||
function_requires<
|
||||
FormatterConcept<
|
||||
FormatterT,
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type>
|
||||
));
|
||||
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
|
||||
|
||||
return detail::find_format_all_copy_impl(
|
||||
Output,
|
||||
lit_input,
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
Finder(::boost::begin(lit_input), ::boost::end(lit_input)));
|
||||
Finder(begin(Input), end(Input)));
|
||||
}
|
||||
|
||||
//! Generic replace all algorithm
|
||||
@ -216,22 +201,19 @@ namespace boost {
|
||||
FormatterT Formatter )
|
||||
{
|
||||
// Concept check
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
function_requires<
|
||||
FormatterConcept<
|
||||
FormatterT,
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
|
||||
return detail::find_format_all_copy_impl(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
Finder( ::boost::begin(Input), ::boost::end(Input) ) );
|
||||
Finder( begin(Input), end(Input) ) );
|
||||
}
|
||||
|
||||
//! Generic replace all algorithm
|
||||
@ -254,22 +236,19 @@ namespace boost {
|
||||
FormatterT Formatter )
|
||||
{
|
||||
// Concept check
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
function_requires<
|
||||
FormatterConcept<
|
||||
FormatterT,
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type>
|
||||
));
|
||||
FinderT,BOOST_STRING_TYPENAME range_const_iterator<SequenceT>::type> >();
|
||||
|
||||
detail::find_format_all_impl(
|
||||
Input,
|
||||
Finder,
|
||||
Formatter,
|
||||
Finder(::boost::begin(Input), ::boost::end(Input)));
|
||||
Finder(begin(Input), end(Input)));
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
// Boost string_algo library find_iterator.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2004.
|
||||
//
|
||||
// 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 updates, documentation, and revision history.
|
||||
// Copyright Pavol Droba 2002-2004. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FIND_ITERATOR_HPP
|
||||
#define BOOST_STRING_FIND_ITERATOR_HPP
|
||||
@ -18,13 +16,12 @@
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
|
||||
#include <boost/algorithm/string/detail/find_iterator.hpp>
|
||||
|
||||
/*! \file
|
||||
Defines find iterator classes. Find iterator repeatedly applies a Finder
|
||||
Defines find iterator classes. Find iterator repeatly applies a Finder
|
||||
to the specified input string to search for matches. Dereferencing
|
||||
the iterator yields the current match or a range between the last and the current
|
||||
match depending on the iterator used.
|
||||
@ -58,6 +55,12 @@ namespace boost {
|
||||
// facade support
|
||||
friend class ::boost::iterator_core_access;
|
||||
|
||||
// base type
|
||||
typedef iterator_facade<
|
||||
find_iterator<IteratorT>,
|
||||
const iterator_range<IteratorT>,
|
||||
forward_traversal_tag> facade_type;
|
||||
|
||||
private:
|
||||
// typedefs
|
||||
|
||||
@ -111,12 +114,10 @@ namespace boost {
|
||||
find_iterator(
|
||||
RangeT& Col,
|
||||
FinderT Finder ) :
|
||||
detail::find_iterator_base<IteratorT>(Finder,0)
|
||||
detail::find_iterator_base<IteratorT>(Finder,0),
|
||||
m_Match(begin(Col),begin(Col)),
|
||||
m_End(end(Col))
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
|
||||
m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
|
||||
m_End=::boost::end(lit_col);
|
||||
|
||||
increment();
|
||||
}
|
||||
|
||||
@ -179,13 +180,13 @@ namespace boost {
|
||||
*/
|
||||
template<typename RangeT, typename FinderT>
|
||||
inline find_iterator<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>
|
||||
make_find_iterator(
|
||||
RangeT& Collection,
|
||||
FinderT Finder)
|
||||
{
|
||||
return find_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
|
||||
Collection, Finder);
|
||||
return find_iterator<BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>(
|
||||
begin(Collection), end(Collection), Finder);
|
||||
}
|
||||
|
||||
// split iterator -----------------------------------------------//
|
||||
@ -214,6 +215,12 @@ namespace boost {
|
||||
// facade support
|
||||
friend class ::boost::iterator_core_access;
|
||||
|
||||
// base type
|
||||
typedef iterator_facade<
|
||||
find_iterator<IteratorT>,
|
||||
iterator_range<IteratorT>,
|
||||
forward_traversal_tag> facade_type;
|
||||
|
||||
private:
|
||||
// typedefs
|
||||
|
||||
@ -240,7 +247,7 @@ namespace boost {
|
||||
m_Match(Other.m_Match),
|
||||
m_Next(Other.m_Next),
|
||||
m_End(Other.m_End),
|
||||
m_bEof(Other.m_bEof)
|
||||
m_bEof(false)
|
||||
{}
|
||||
|
||||
//! Constructor
|
||||
@ -259,11 +266,7 @@ namespace boost {
|
||||
m_End(End),
|
||||
m_bEof(false)
|
||||
{
|
||||
// force the correct behavior for empty sequences and yield at least one token
|
||||
if(Begin!=End)
|
||||
{
|
||||
increment();
|
||||
}
|
||||
increment();
|
||||
}
|
||||
//! Constructor
|
||||
/*!
|
||||
@ -275,18 +278,12 @@ namespace boost {
|
||||
RangeT& Col,
|
||||
FinderT Finder ) :
|
||||
detail::find_iterator_base<IteratorT>(Finder,0),
|
||||
m_Match(begin(Col),begin(Col)),
|
||||
m_Next(begin(Col)),
|
||||
m_End(end(Col)),
|
||||
m_bEof(false)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_col(::boost::as_literal(Col));
|
||||
m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col));
|
||||
m_Next=::boost::begin(lit_col);
|
||||
m_End=::boost::end(lit_col);
|
||||
|
||||
// force the correct behavior for empty sequences and yield at least one token
|
||||
if(m_Next!=m_End)
|
||||
{
|
||||
increment();
|
||||
}
|
||||
increment();
|
||||
}
|
||||
|
||||
|
||||
@ -359,13 +356,13 @@ namespace boost {
|
||||
*/
|
||||
template<typename RangeT, typename FinderT>
|
||||
inline split_iterator<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>
|
||||
make_split_iterator(
|
||||
RangeT& Collection,
|
||||
FinderT Finder)
|
||||
{
|
||||
return split_iterator<BOOST_STRING_TYPENAME range_iterator<RangeT>::type>(
|
||||
Collection, Finder);
|
||||
return split_iterator<BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type>(
|
||||
begin(Collection), end(Collection), Finder);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library finder.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FINDER_HPP
|
||||
#define BOOST_STRING_FINDER_HPP
|
||||
@ -46,35 +45,35 @@ namespace boost {
|
||||
\param Comp An element comparison predicate
|
||||
\return An instance of the \c first_finder object
|
||||
*/
|
||||
template<typename RangeT>
|
||||
template<typename ContainerT>
|
||||
inline detail::first_finderF<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<ContainerT>::type,
|
||||
is_equal>
|
||||
first_finder( const RangeT& Search )
|
||||
first_finder( const ContainerT& Search )
|
||||
{
|
||||
return
|
||||
detail::first_finderF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type,
|
||||
is_equal>( ::boost::as_literal(Search), is_equal() ) ;
|
||||
range_const_iterator<ContainerT>::type,
|
||||
is_equal>( Search, is_equal() ) ;
|
||||
}
|
||||
|
||||
//! "First" finder
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
template<typename RangeT,typename PredicateT>
|
||||
template<typename ContainerT,typename PredicateT>
|
||||
inline detail::first_finderF<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<ContainerT>::type,
|
||||
PredicateT>
|
||||
first_finder(
|
||||
const RangeT& Search, PredicateT Comp )
|
||||
const ContainerT& Search, PredicateT Comp )
|
||||
{
|
||||
return
|
||||
detail::first_finderF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type,
|
||||
PredicateT>( ::boost::as_literal(Search), Comp );
|
||||
range_const_iterator<ContainerT>::type,
|
||||
PredicateT>( Search, Comp );
|
||||
}
|
||||
|
||||
//! "Last" finder
|
||||
@ -87,33 +86,33 @@ namespace boost {
|
||||
\param Comp An element comparison predicate
|
||||
\return An instance of the \c last_finder object
|
||||
*/
|
||||
template<typename RangeT>
|
||||
template<typename ContainerT>
|
||||
inline detail::last_finderF<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<ContainerT>::type,
|
||||
is_equal>
|
||||
last_finder( const RangeT& Search )
|
||||
last_finder( const ContainerT& Search )
|
||||
{
|
||||
return
|
||||
detail::last_finderF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type,
|
||||
is_equal>( ::boost::as_literal(Search), is_equal() );
|
||||
range_const_iterator<ContainerT>::type,
|
||||
is_equal>( Search, is_equal() );
|
||||
}
|
||||
//! "Last" finder
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
template<typename RangeT, typename PredicateT>
|
||||
template<typename ContainerT, typename PredicateT>
|
||||
inline detail::last_finderF<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<ContainerT>::type,
|
||||
PredicateT>
|
||||
last_finder( const RangeT& Search, PredicateT Comp )
|
||||
last_finder( const ContainerT& Search, PredicateT Comp )
|
||||
{
|
||||
return
|
||||
detail::last_finderF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type,
|
||||
PredicateT>( ::boost::as_literal(Search), Comp ) ;
|
||||
range_const_iterator<ContainerT>::type,
|
||||
PredicateT>( Search, Comp ) ;
|
||||
}
|
||||
|
||||
//! "Nth" finder
|
||||
@ -127,38 +126,38 @@ namespace boost {
|
||||
\param Comp An element comparison predicate
|
||||
\return An instance of the \c nth_finder object
|
||||
*/
|
||||
template<typename RangeT>
|
||||
template<typename ContainerT>
|
||||
inline detail::nth_finderF<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<ContainerT>::type,
|
||||
is_equal>
|
||||
nth_finder(
|
||||
const RangeT& Search,
|
||||
int Nth)
|
||||
const ContainerT& Search,
|
||||
unsigned int Nth)
|
||||
{
|
||||
return
|
||||
detail::nth_finderF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type,
|
||||
is_equal>( ::boost::as_literal(Search), Nth, is_equal() ) ;
|
||||
range_const_iterator<ContainerT>::type,
|
||||
is_equal>( Search, Nth, is_equal() ) ;
|
||||
}
|
||||
//! "Nth" finder
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
template<typename RangeT, typename PredicateT>
|
||||
template<typename ContainerT, typename PredicateT>
|
||||
inline detail::nth_finderF<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type,
|
||||
BOOST_STRING_TYPENAME range_const_iterator<ContainerT>::type,
|
||||
PredicateT>
|
||||
nth_finder(
|
||||
const RangeT& Search,
|
||||
int Nth,
|
||||
const ContainerT& Search,
|
||||
unsigned int Nth,
|
||||
PredicateT Comp )
|
||||
{
|
||||
return
|
||||
detail::nth_finderF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type,
|
||||
PredicateT>( ::boost::as_literal(Search), Nth, Comp );
|
||||
range_const_iterator<ContainerT>::type,
|
||||
PredicateT>( Search, Nth, Comp );
|
||||
}
|
||||
|
||||
//! "Head" finder
|
||||
@ -173,7 +172,7 @@ namespace boost {
|
||||
\return An instance of the \c head_finder object
|
||||
*/
|
||||
inline detail::head_finderF
|
||||
head_finder( int N )
|
||||
head_finder( unsigned int N )
|
||||
{
|
||||
return detail::head_finderF(N);
|
||||
}
|
||||
@ -190,7 +189,7 @@ namespace boost {
|
||||
\return An instance of the \c tail_finder object
|
||||
*/
|
||||
inline detail::tail_finderF
|
||||
tail_finder( int N )
|
||||
tail_finder( unsigned int N )
|
||||
{
|
||||
return detail::tail_finderF(N);
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library formatter.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_FORMATTER_HPP
|
||||
#define BOOST_STRING_FORMATTER_HPP
|
||||
@ -14,7 +13,6 @@
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
|
||||
#include <boost/algorithm/string/detail/formatter.hpp>
|
||||
|
||||
@ -36,44 +34,36 @@ namespace boost {
|
||||
|
||||
//! Constant formatter
|
||||
/*!
|
||||
Constructs a \c const_formatter. Const formatter always returns
|
||||
Construct the \c const_formatter. Const formatter always returns
|
||||
the same value, regardless of the parameter.
|
||||
|
||||
\param Format A predefined value used as a result for formating
|
||||
\return An instance of the \c const_formatter object.
|
||||
*/
|
||||
template<typename RangeT>
|
||||
inline detail::const_formatF<
|
||||
iterator_range<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >
|
||||
inline detail::const_formatF<RangeT>
|
||||
const_formatter(const RangeT& Format)
|
||||
{
|
||||
return detail::const_formatF<
|
||||
iterator_range<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >(::boost::as_literal(Format));
|
||||
return detail::const_formatF<RangeT>(Format);
|
||||
}
|
||||
|
||||
//! Identity formatter
|
||||
/*!
|
||||
Constructs an \c identity_formatter. Identity formatter always returns
|
||||
Construct the \c identity_formatter. Identity formatter always returns
|
||||
the parameter.
|
||||
|
||||
\return An instance of the \c identity_formatter object.
|
||||
*/
|
||||
template<typename RangeT>
|
||||
inline detail::identity_formatF<
|
||||
iterator_range<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >
|
||||
inline detail::identity_formatF<RangeT>
|
||||
identity_formatter()
|
||||
{
|
||||
return detail::identity_formatF<
|
||||
iterator_range<
|
||||
BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> >();
|
||||
return detail::identity_formatF<RangeT>();
|
||||
}
|
||||
|
||||
//! Empty formatter
|
||||
/*!
|
||||
Constructs an \c empty_formatter. Empty formatter always returns an empty
|
||||
Construct the \c empty_formatter. Empty formatter always returns an empty
|
||||
sequence.
|
||||
|
||||
\param Input container used to select a correct value_type for the
|
||||
@ -89,22 +79,6 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME range_value<RangeT>::type>();
|
||||
}
|
||||
|
||||
//! Empty formatter
|
||||
/*!
|
||||
Constructs a \c dissect_formatter. Dissect formatter uses a specified finder
|
||||
to extract a portion of the formatted sequence. The first finder's match is returned
|
||||
as a result
|
||||
|
||||
\param Finder a finder used to select a portion of the formated sequence
|
||||
\return An instance of the \c dissect_formatter object.
|
||||
*/
|
||||
template<typename FinderT>
|
||||
inline detail::dissect_formatF< FinderT >
|
||||
dissect_formatter(const FinderT& Finder)
|
||||
{
|
||||
return detail::dissect_formatF<FinderT>(Finder);
|
||||
}
|
||||
|
||||
|
||||
} // namespace algorithm
|
||||
|
||||
@ -112,7 +86,6 @@ namespace boost {
|
||||
using algorithm::const_formatter;
|
||||
using algorithm::identity_formatter;
|
||||
using algorithm::empty_formatter;
|
||||
using algorithm::dissect_formatter;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library iter_find.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_ITER_FIND_HPP
|
||||
#define BOOST_STRING_ITER_FIND_HPP
|
||||
@ -19,9 +18,8 @@
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
|
||||
#include <boost/algorithm/string/concept.hpp>
|
||||
#include <boost/algorithm/string/find_iterator.hpp>
|
||||
@ -74,34 +72,30 @@ namespace boost {
|
||||
RangeT& Input,
|
||||
FinderT Finder )
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
FinderConcept<
|
||||
FinderT,
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
));
|
||||
|
||||
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type> >();
|
||||
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_iterator<RangeT>::type input_iterator_type;
|
||||
range_result_iterator<RangeT>::type input_iterator_type;
|
||||
typedef find_iterator<input_iterator_type> find_iterator_type;
|
||||
typedef detail::copy_iterator_rangeF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_value<SequenceSequenceT>::type,
|
||||
input_iterator_type> copy_range_type;
|
||||
|
||||
input_iterator_type InputEnd=::boost::end(lit_input);
|
||||
input_iterator_type InputEnd=end(Input);
|
||||
|
||||
typedef transform_iterator<copy_range_type, find_iterator_type>
|
||||
transform_iter_type;
|
||||
|
||||
transform_iter_type itBegin=
|
||||
::boost::make_transform_iterator(
|
||||
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
|
||||
make_transform_iterator(
|
||||
find_iterator_type( begin(Input), InputEnd, Finder ),
|
||||
copy_range_type());
|
||||
|
||||
transform_iter_type itEnd=
|
||||
::boost::make_transform_iterator(
|
||||
make_transform_iterator(
|
||||
find_iterator_type(),
|
||||
copy_range_type());
|
||||
|
||||
@ -145,33 +139,30 @@ namespace boost {
|
||||
RangeT& Input,
|
||||
FinderT Finder )
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT((
|
||||
function_requires<
|
||||
FinderConcept<FinderT,
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type>
|
||||
));
|
||||
|
||||
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type> >();
|
||||
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_iterator<RangeT>::type input_iterator_type;
|
||||
range_result_iterator<RangeT>::type input_iterator_type;
|
||||
typedef split_iterator<input_iterator_type> find_iterator_type;
|
||||
typedef detail::copy_iterator_rangeF<
|
||||
BOOST_STRING_TYPENAME
|
||||
range_value<SequenceSequenceT>::type,
|
||||
input_iterator_type> copy_range_type;
|
||||
|
||||
input_iterator_type InputEnd=::boost::end(lit_input);
|
||||
input_iterator_type InputEnd=end(Input);
|
||||
|
||||
typedef transform_iterator<copy_range_type, find_iterator_type>
|
||||
transform_iter_type;
|
||||
|
||||
transform_iter_type itBegin=
|
||||
::boost::make_transform_iterator(
|
||||
find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ),
|
||||
make_transform_iterator(
|
||||
find_iterator_type( begin(Input), InputEnd, Finder ),
|
||||
copy_range_type() );
|
||||
|
||||
transform_iter_type itEnd=
|
||||
::boost::make_transform_iterator(
|
||||
make_transform_iterator(
|
||||
find_iterator_type(),
|
||||
copy_range_type() );
|
||||
|
||||
|
@ -1,145 +0,0 @@
|
||||
// Boost string_algo library join.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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 updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_JOIN_HPP
|
||||
#define BOOST_STRING_JOIN_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/algorithm/string/detail/sequence.hpp>
|
||||
#include <boost/range/value_type.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
|
||||
/*! \file
|
||||
Defines join algorithm.
|
||||
|
||||
Join algorithm is a counterpart to split algorithms.
|
||||
It joins strings from a 'list' by adding user defined separator.
|
||||
Additionally there is a version that allows simple filtering
|
||||
by providing a predicate.
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
|
||||
// join --------------------------------------------------------------//
|
||||
|
||||
//! Join algorithm
|
||||
/*!
|
||||
This algorithm joins all strings in a 'list' into one long string.
|
||||
Segments are concatenated by given separator.
|
||||
|
||||
\param Input A container that holds the input strings. It must be a container-of-containers.
|
||||
\param Separator A string that will separate the joined segments.
|
||||
\return Concatenated string.
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template< typename SequenceSequenceT, typename Range1T>
|
||||
inline typename range_value<SequenceSequenceT>::type
|
||||
join(
|
||||
const SequenceSequenceT& Input,
|
||||
const Range1T& Separator)
|
||||
{
|
||||
// Define working types
|
||||
typedef typename range_value<SequenceSequenceT>::type ResultT;
|
||||
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
|
||||
|
||||
// Parse input
|
||||
InputIteratorT itBegin=::boost::begin(Input);
|
||||
InputIteratorT itEnd=::boost::end(Input);
|
||||
|
||||
// Construct container to hold the result
|
||||
ResultT Result;
|
||||
|
||||
// Append first element
|
||||
if(itBegin!=itEnd)
|
||||
{
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
++itBegin;
|
||||
}
|
||||
|
||||
for(;itBegin!=itEnd; ++itBegin)
|
||||
{
|
||||
// Add separator
|
||||
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
|
||||
// Add element
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// join_if ----------------------------------------------------------//
|
||||
|
||||
//! Conditional join algorithm
|
||||
/*!
|
||||
This algorithm joins all strings in a 'list' into one long string.
|
||||
Segments are concatenated by given separator. Only segments that
|
||||
satisfy the predicate will be added to the result.
|
||||
|
||||
\param Input A container that holds the input strings. It must be a container-of-containers.
|
||||
\param Separator A string that will separate the joined segments.
|
||||
\param Pred A segment selection predicate
|
||||
\return Concatenated string.
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template< typename SequenceSequenceT, typename Range1T, typename PredicateT>
|
||||
inline typename range_value<SequenceSequenceT>::type
|
||||
join_if(
|
||||
const SequenceSequenceT& Input,
|
||||
const Range1T& Separator,
|
||||
PredicateT Pred)
|
||||
{
|
||||
// Define working types
|
||||
typedef typename range_value<SequenceSequenceT>::type ResultT;
|
||||
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
|
||||
|
||||
// Parse input
|
||||
InputIteratorT itBegin=::boost::begin(Input);
|
||||
InputIteratorT itEnd=::boost::end(Input);
|
||||
|
||||
// Construct container to hold the result
|
||||
ResultT Result;
|
||||
|
||||
// Roll to the first element that will be added
|
||||
while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin;
|
||||
// Add this element
|
||||
if(itBegin!=itEnd)
|
||||
{
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
++itBegin;
|
||||
}
|
||||
|
||||
for(;itBegin!=itEnd; ++itBegin)
|
||||
{
|
||||
if(Pred(*itBegin))
|
||||
{
|
||||
// Add separator
|
||||
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
|
||||
// Add element
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
} // namespace algorithm
|
||||
|
||||
// pull names to the boost namespace
|
||||
using algorithm::join;
|
||||
using algorithm::join_if;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_STRING_JOIN_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library predicate.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_PREDICATE_HPP
|
||||
#define BOOST_STRING_PREDICATE_HPP
|
||||
@ -16,8 +15,6 @@
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
#include <boost/algorithm/string/compare.hpp>
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
@ -59,19 +56,16 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
PredicateT Comp)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
|
||||
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<Range1T>::type Iterator1T;
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<Range2T>::type Iterator2T;
|
||||
|
||||
Iterator1T InputEnd=::boost::end(lit_input);
|
||||
Iterator2T TestEnd=::boost::end(lit_test);
|
||||
Iterator1T InputEnd=end(Input);
|
||||
Iterator2T TestEnd=end(Test);
|
||||
|
||||
Iterator1T it=::boost::begin(lit_input);
|
||||
Iterator2T pit=::boost::begin(lit_test);
|
||||
Iterator1T it=begin(Input);
|
||||
Iterator2T pit=begin(Test);
|
||||
for(;
|
||||
it!=InputEnd && pit!=TestEnd;
|
||||
++it,++pit)
|
||||
@ -92,7 +86,7 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Test)
|
||||
{
|
||||
return ::boost::algorithm::starts_with(Input, Test, is_equal());
|
||||
return starts_with(Input, Test, is_equal());
|
||||
}
|
||||
|
||||
//! 'Starts with' predicate ( case insensitive )
|
||||
@ -114,7 +108,7 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::starts_with(Input, Test, is_iequal(Loc));
|
||||
return starts_with(Input, Test, is_iequal(Loc));
|
||||
}
|
||||
|
||||
|
||||
@ -141,9 +135,6 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
PredicateT Comp)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
|
||||
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<Range1T>::type Iterator1T;
|
||||
typedef BOOST_STRING_TYPENAME boost::detail::
|
||||
@ -151,10 +142,10 @@ namespace boost {
|
||||
|
||||
return detail::
|
||||
ends_with_iter_select(
|
||||
::boost::begin(lit_input),
|
||||
::boost::end(lit_input),
|
||||
::boost::begin(lit_test),
|
||||
::boost::end(lit_test),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
begin(Test),
|
||||
end(Test),
|
||||
Comp,
|
||||
category());
|
||||
}
|
||||
@ -169,7 +160,7 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Test)
|
||||
{
|
||||
return ::boost::algorithm::ends_with(Input, Test, is_equal());
|
||||
return ends_with(Input, Test, is_equal());
|
||||
}
|
||||
|
||||
//! 'Ends with' predicate ( case insensitive )
|
||||
@ -191,7 +182,7 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::ends_with(Input, Test, is_iequal(Loc));
|
||||
return ends_with(Input, Test, is_iequal(Loc));
|
||||
}
|
||||
|
||||
// contains predicate -----------------------------------------------//
|
||||
@ -215,17 +206,14 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
PredicateT Comp)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
|
||||
|
||||
if (::boost::empty(lit_test))
|
||||
if (empty(Test))
|
||||
{
|
||||
// Empty range is contained always
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use the temporary variable to make VACPP happy
|
||||
bool bResult=(::boost::algorithm::first_finder(lit_test,Comp)(::boost::begin(lit_input), ::boost::end(lit_input)));
|
||||
bool bResult=(first_finder(Test,Comp)(begin(Input), end(Input)));
|
||||
return bResult;
|
||||
}
|
||||
|
||||
@ -238,7 +226,7 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Test)
|
||||
{
|
||||
return ::boost::algorithm::contains(Input, Test, is_equal());
|
||||
return contains(Input, Test, is_equal());
|
||||
}
|
||||
|
||||
//! 'Contains' predicate ( case insensitive )
|
||||
@ -259,7 +247,7 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::contains(Input, Test, is_iequal(Loc));
|
||||
return contains(Input, Test, is_iequal(Loc));
|
||||
}
|
||||
|
||||
// equals predicate -----------------------------------------------//
|
||||
@ -286,19 +274,16 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
PredicateT Comp)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_input(::boost::as_literal(Input));
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_test(::boost::as_literal(Test));
|
||||
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<Range1T>::type Iterator1T;
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<Range2T>::type Iterator2T;
|
||||
|
||||
Iterator1T InputEnd=::boost::end(lit_input);
|
||||
Iterator2T TestEnd=::boost::end(lit_test);
|
||||
Iterator1T InputEnd=end(Input);
|
||||
Iterator2T TestEnd=end(Test);
|
||||
|
||||
Iterator1T it=::boost::begin(lit_input);
|
||||
Iterator2T pit=::boost::begin(lit_test);
|
||||
Iterator1T it=begin(Input);
|
||||
Iterator2T pit=begin(Test);
|
||||
for(;
|
||||
it!=InputEnd && pit!=TestEnd;
|
||||
++it,++pit)
|
||||
@ -319,10 +304,10 @@ namespace boost {
|
||||
const Range1T& Input,
|
||||
const Range2T& Test)
|
||||
{
|
||||
return ::boost::algorithm::equals(Input, Test, is_equal());
|
||||
return equals(Input, Test, is_equal());
|
||||
}
|
||||
|
||||
//! 'Equals' predicate ( case insensitive )
|
||||
//! 'Equals' predicate ( casa insensitive )
|
||||
/*!
|
||||
This predicate holds when the test container is equal to the
|
||||
input container i.e. all elements in both containers are same.
|
||||
@ -343,84 +328,9 @@ namespace boost {
|
||||
const Range2T& Test,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::equals(Input, Test, is_iequal(Loc));
|
||||
return equals(Input, Test, is_iequal(Loc));
|
||||
}
|
||||
|
||||
// lexicographical_compare predicate -----------------------------//
|
||||
|
||||
//! Lexicographical compare predicate
|
||||
/*!
|
||||
This predicate is an overload of std::lexicographical_compare
|
||||
for range arguments
|
||||
|
||||
It check whether the first argument is lexicographically less
|
||||
then the second one.
|
||||
|
||||
If the optional predicate is specified, it is used for character-wise
|
||||
comparison
|
||||
|
||||
\param Arg1 First argument
|
||||
\param Arg2 Second argument
|
||||
\param Pred Comparison predicate
|
||||
\return The result of the test
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template<typename Range1T, typename Range2T, typename PredicateT>
|
||||
inline bool lexicographical_compare(
|
||||
const Range1T& Arg1,
|
||||
const Range2T& Arg2,
|
||||
PredicateT Pred)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range1T>::type> lit_arg1(::boost::as_literal(Arg1));
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<Range2T>::type> lit_arg2(::boost::as_literal(Arg2));
|
||||
|
||||
return std::lexicographical_compare(
|
||||
::boost::begin(lit_arg1),
|
||||
::boost::end(lit_arg1),
|
||||
::boost::begin(lit_arg2),
|
||||
::boost::end(lit_arg2),
|
||||
Pred);
|
||||
}
|
||||
|
||||
//! Lexicographical compare predicate
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline bool lexicographical_compare(
|
||||
const Range1T& Arg1,
|
||||
const Range2T& Arg2)
|
||||
{
|
||||
return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_less());
|
||||
}
|
||||
|
||||
//! Lexicographical compare predicate (case-insensitive)
|
||||
/*!
|
||||
This predicate is an overload of std::lexicographical_compare
|
||||
for range arguments.
|
||||
It check whether the first argument is lexicographically less
|
||||
then the second one.
|
||||
Elements are compared case insensitively
|
||||
|
||||
|
||||
\param Arg1 First argument
|
||||
\param Arg2 Second argument
|
||||
\param Loc A locale used for case insensitive comparison
|
||||
\return The result of the test
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template<typename Range1T, typename Range2T>
|
||||
inline bool ilexicographical_compare(
|
||||
const Range1T& Arg1,
|
||||
const Range2T& Arg2,
|
||||
const std::locale& Loc=std::locale())
|
||||
{
|
||||
return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_iless(Loc));
|
||||
}
|
||||
|
||||
|
||||
// all predicate -----------------------------------------------//
|
||||
|
||||
//! 'All' predicate
|
||||
@ -439,13 +349,11 @@ namespace boost {
|
||||
const RangeT& Input,
|
||||
PredicateT Pred)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
|
||||
typedef BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type Iterator1T;
|
||||
|
||||
Iterator1T InputEnd=::boost::end(lit_input);
|
||||
for( Iterator1T It=::boost::begin(lit_input); It!=InputEnd; ++It)
|
||||
Iterator1T InputEnd=end(Input);
|
||||
for( Iterator1T It=begin(Input); It!=InputEnd; ++It)
|
||||
{
|
||||
if (!Pred(*It))
|
||||
return false;
|
||||
@ -466,8 +374,6 @@ namespace boost {
|
||||
using algorithm::equals;
|
||||
using algorithm::iequals;
|
||||
using algorithm::all;
|
||||
using algorithm::lexicographical_compare;
|
||||
using algorithm::ilexicographical_compare;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library predicate_facade.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_PREDICATE_FACADE_HPP
|
||||
#define BOOST_STRING_PREDICATE_FACADE_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library regex.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_REGEX_HPP
|
||||
#define BOOST_STRING_REGEX_HPP
|
||||
@ -17,8 +16,7 @@
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/result_iterator.hpp>
|
||||
|
||||
#include <boost/algorithm/string/find_format.hpp>
|
||||
#include <boost/algorithm/string/regex_find_format.hpp>
|
||||
@ -54,16 +52,14 @@ namespace boost {
|
||||
typename CharT,
|
||||
typename RegexTraitsT>
|
||||
inline iterator_range<
|
||||
BOOST_STRING_TYPENAME range_iterator<RangeT>::type >
|
||||
BOOST_STRING_TYPENAME range_result_iterator<RangeT>::type >
|
||||
find_regex(
|
||||
RangeT& Input,
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_iterator<RangeT>::type> lit_input(::boost::as_literal(Input));
|
||||
|
||||
return ::boost::algorithm::regex_finder(Rx,Flags)(
|
||||
::boost::begin(lit_input), ::boost::end(lit_input) );
|
||||
return regex_finder(Rx,Flags)(
|
||||
begin(Input), end(Input) );
|
||||
}
|
||||
|
||||
// replace_regex --------------------------------------------------------------------//
|
||||
@ -98,11 +94,11 @@ namespace boost {
|
||||
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
|
||||
match_flag_type Flags=match_default | format_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::regex_formatter( Format, Flags ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
regex_formatter( Format, Flags ) );
|
||||
}
|
||||
|
||||
//! Replace regex algorithm
|
||||
@ -120,10 +116,10 @@ namespace boost {
|
||||
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
|
||||
match_flag_type Flags=match_default | format_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::regex_formatter( Format, Flags ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
regex_formatter( Format, Flags ) );
|
||||
}
|
||||
|
||||
//! Replace regex algorithm
|
||||
@ -147,10 +143,10 @@ namespace boost {
|
||||
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
|
||||
match_flag_type Flags=match_default | format_default )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::regex_formatter( Format, Flags ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
regex_formatter( Format, Flags ) );
|
||||
}
|
||||
|
||||
// replace_all_regex --------------------------------------------------------------------//
|
||||
@ -184,11 +180,11 @@ namespace boost {
|
||||
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
|
||||
match_flag_type Flags=match_default | format_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::regex_formatter( Format, Flags ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
regex_formatter( Format, Flags ) );
|
||||
}
|
||||
|
||||
//! Replace all regex algorithm
|
||||
@ -206,10 +202,10 @@ namespace boost {
|
||||
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
|
||||
match_flag_type Flags=match_default | format_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::regex_formatter( Format, Flags ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
regex_formatter( Format, Flags ) );
|
||||
}
|
||||
|
||||
//! Replace all regex algorithm
|
||||
@ -233,10 +229,10 @@ namespace boost {
|
||||
const std::basic_string<CharT, FormatStringTraitsT, FormatStringAllocatorT>& Format,
|
||||
match_flag_type Flags=match_default | format_default )
|
||||
{
|
||||
::boost::algorithm::find_format_all(
|
||||
find_format_all(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::regex_formatter( Format, Flags ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
regex_formatter( Format, Flags ) );
|
||||
}
|
||||
|
||||
// erase_regex --------------------------------------------------------------------//
|
||||
@ -267,11 +263,11 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase regex algorithm
|
||||
@ -287,10 +283,10 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase regex algorithm
|
||||
@ -311,10 +307,10 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
// erase_all_regex --------------------------------------------------------------------//
|
||||
@ -346,11 +342,11 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase all regex algorithm
|
||||
@ -366,10 +362,10 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
//! Erase all regex algorithm
|
||||
@ -390,10 +386,10 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
::boost::algorithm::find_format_all(
|
||||
find_format_all(
|
||||
Input,
|
||||
::boost::algorithm::regex_finder( Rx, Flags ),
|
||||
::boost::algorithm::empty_formatter( Input ) );
|
||||
regex_finder( Rx, Flags ),
|
||||
empty_formatter( Input ) );
|
||||
}
|
||||
|
||||
// find_all_regex ------------------------------------------------------------------//
|
||||
@ -431,10 +427,10 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
return ::boost::algorithm::iter_find(
|
||||
return iter_find(
|
||||
Result,
|
||||
Input,
|
||||
::boost::algorithm::regex_finder(Rx,Flags) );
|
||||
regex_finder(Rx,Flags) );
|
||||
}
|
||||
|
||||
// split_regex ------------------------------------------------------------------//
|
||||
@ -472,153 +468,12 @@ namespace boost {
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
return ::boost::algorithm::iter_split(
|
||||
return iter_split(
|
||||
Result,
|
||||
Input,
|
||||
::boost::algorithm::regex_finder(Rx,Flags) );
|
||||
regex_finder(Rx,Flags) );
|
||||
}
|
||||
|
||||
// join_if ------------------------------------------------------------------//
|
||||
|
||||
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
//! Conditional join algorithm
|
||||
/*!
|
||||
This algorithm joins all strings in a 'list' into one long string.
|
||||
Segments are concatenated by given separator. Only segments that
|
||||
match the given regular expression will be added to the result
|
||||
|
||||
This is a specialization of join_if algorithm.
|
||||
|
||||
\param Input A container that holds the input strings. It must be a container-of-containers.
|
||||
\param Separator A string that will separate the joined segments.
|
||||
\param Rx A regular expression
|
||||
\param Flags Regex options
|
||||
\return Concatenated string.
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template<
|
||||
typename SequenceSequenceT,
|
||||
typename Range1T,
|
||||
typename CharT,
|
||||
typename RegexTraitsT >
|
||||
inline typename range_value<SequenceSequenceT>::type
|
||||
join_if(
|
||||
const SequenceSequenceT& Input,
|
||||
const Range1T& Separator,
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
// Define working types
|
||||
typedef typename range_value<SequenceSequenceT>::type ResultT;
|
||||
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
|
||||
|
||||
// Parse input
|
||||
InputIteratorT itBegin=::boost::begin(Input);
|
||||
InputIteratorT itEnd=::boost::end(Input);
|
||||
|
||||
// Construct container to hold the result
|
||||
ResultT Result;
|
||||
|
||||
|
||||
// Roll to the first element that will be added
|
||||
while(
|
||||
itBegin!=itEnd &&
|
||||
!::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) ++itBegin;
|
||||
|
||||
// Add this element
|
||||
if(itBegin!=itEnd)
|
||||
{
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
++itBegin;
|
||||
}
|
||||
|
||||
for(;itBegin!=itEnd; ++itBegin)
|
||||
{
|
||||
if(::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags))
|
||||
{
|
||||
// Add separator
|
||||
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
|
||||
// Add element
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
//! Conditional join algorithm
|
||||
/*!
|
||||
This algorithm joins all strings in a 'list' into one long string.
|
||||
Segments are concatenated by given separator. Only segments that
|
||||
match the given regular expression will be added to the result
|
||||
|
||||
This is a specialization of join_if algorithm.
|
||||
|
||||
\param Input A container that holds the input strings. It must be a container-of-containers.
|
||||
\param Separator A string that will separate the joined segments.
|
||||
\param Rx A regular expression
|
||||
\param Flags Regex options
|
||||
\return Concatenated string.
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template<
|
||||
typename SequenceSequenceT,
|
||||
typename Range1T,
|
||||
typename CharT,
|
||||
typename RegexTraitsT >
|
||||
inline typename range_value<SequenceSequenceT>::type
|
||||
join_if_regex(
|
||||
const SequenceSequenceT& Input,
|
||||
const Range1T& Separator,
|
||||
const basic_regex<CharT, RegexTraitsT>& Rx,
|
||||
match_flag_type Flags=match_default )
|
||||
{
|
||||
// Define working types
|
||||
typedef typename range_value<SequenceSequenceT>::type ResultT;
|
||||
typedef typename range_const_iterator<SequenceSequenceT>::type InputIteratorT;
|
||||
|
||||
// Parse input
|
||||
InputIteratorT itBegin=::boost::begin(Input);
|
||||
InputIteratorT itEnd=::boost::end(Input);
|
||||
|
||||
// Construct container to hold the result
|
||||
ResultT Result;
|
||||
|
||||
|
||||
// Roll to the first element that will be added
|
||||
while(
|
||||
itBegin!=itEnd &&
|
||||
!::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags)) ++itBegin;
|
||||
|
||||
// Add this element
|
||||
if(itBegin!=itEnd)
|
||||
{
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
++itBegin;
|
||||
}
|
||||
|
||||
for(;itBegin!=itEnd; ++itBegin)
|
||||
{
|
||||
if(::boost::regex_match(::boost::begin(*itBegin), ::boost::end(*itBegin), Rx, Flags))
|
||||
{
|
||||
// Add separator
|
||||
detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator));
|
||||
// Add element
|
||||
detail::insert(Result, ::boost::end(Result), *itBegin);
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
} // namespace algorithm
|
||||
|
||||
// pull names into the boost namespace
|
||||
@ -634,12 +489,6 @@ namespace boost {
|
||||
using algorithm::find_all_regex;
|
||||
using algorithm::split_regex;
|
||||
|
||||
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
using algorithm::join_if;
|
||||
#else // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
using algorithm::join_if_regex;
|
||||
#endif // BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library regex_find_format.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_REGEX_FIND_FORMAT_HPP
|
||||
#define BOOST_STRING_REGEX_FIND_FORMAT_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library replace.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_REPLACE_HPP
|
||||
#define BOOST_STRING_REPLACE_HPP
|
||||
@ -61,11 +60,11 @@ namespace boost {
|
||||
range_const_iterator<Range1T>::type>& SearchRange,
|
||||
const Range2T& Format)
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::range_finder(SearchRange),
|
||||
::boost::algorithm::const_formatter(Format));
|
||||
range_finder(SearchRange),
|
||||
const_formatter(Format));
|
||||
}
|
||||
|
||||
//! Replace range algorithm
|
||||
@ -80,10 +79,10 @@ namespace boost {
|
||||
range_const_iterator<SequenceT>::type>& SearchRange,
|
||||
const RangeT& Format)
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::range_finder(SearchRange),
|
||||
::boost::algorithm::const_formatter(Format));
|
||||
range_finder(SearchRange),
|
||||
const_formatter(Format));
|
||||
}
|
||||
|
||||
//! Replace range algorithm
|
||||
@ -103,10 +102,10 @@ namespace boost {
|
||||
range_iterator<SequenceT>::type>& SearchRange,
|
||||
const RangeT& Format)
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::range_finder(SearchRange),
|
||||
::boost::algorithm::const_formatter(Format));
|
||||
range_finder(SearchRange),
|
||||
const_formatter(Format));
|
||||
}
|
||||
|
||||
// replace_first --------------------------------------------------------------------//
|
||||
@ -138,11 +137,11 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const Range3T& Format)
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace first algorithm
|
||||
@ -155,10 +154,10 @@ namespace boost {
|
||||
const Range1T& Search,
|
||||
const Range2T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace first algorithm
|
||||
@ -176,10 +175,10 @@ namespace boost {
|
||||
const Range1T& Search,
|
||||
const Range2T& Format )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_first ( case insensitive ) ---------------------------------------------//
|
||||
@ -214,11 +213,11 @@ namespace boost {
|
||||
const Range3T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace first algorithm ( case insensitive )
|
||||
@ -232,10 +231,10 @@ namespace boost {
|
||||
const Range1T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace first algorithm ( case insensitive )
|
||||
@ -256,10 +255,10 @@ namespace boost {
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_last --------------------------------------------------------------------//
|
||||
@ -291,11 +290,11 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const Range3T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
last_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace last algorithm
|
||||
@ -308,10 +307,10 @@ namespace boost {
|
||||
const Range1T& Search,
|
||||
const Range2T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
last_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace last algorithm
|
||||
@ -329,10 +328,10 @@ namespace boost {
|
||||
const Range1T& Search,
|
||||
const Range2T& Format )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
last_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_last ( case insensitive ) -----------------------------------------------//
|
||||
@ -367,11 +366,11 @@ namespace boost {
|
||||
const Range3T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
last_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace last algorithm ( case insensitive )
|
||||
@ -385,10 +384,10 @@ namespace boost {
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
last_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace last algorithm ( case insensitive )
|
||||
@ -410,10 +409,10 @@ namespace boost {
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::last_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
last_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_nth --------------------------------------------------------------------//
|
||||
@ -429,7 +428,6 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\param Format A substitute string
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
@ -445,14 +443,14 @@ namespace boost {
|
||||
OutputIteratorT Output,
|
||||
const Range1T& Input,
|
||||
const Range2T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const Range3T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
nth_finder(Search, Nth),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace nth algorithm
|
||||
@ -463,13 +461,13 @@ namespace boost {
|
||||
inline SequenceT replace_nth_copy(
|
||||
const SequenceT& Input,
|
||||
const Range1T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const Range2T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
nth_finder(Search, Nth),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace nth algorithm
|
||||
@ -480,20 +478,19 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\param Format A substitute string
|
||||
*/
|
||||
template<typename SequenceT, typename Range1T, typename Range2T>
|
||||
inline void replace_nth(
|
||||
SequenceT& Input,
|
||||
const Range1T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const Range2T& Format )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
nth_finder(Search, Nth),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_nth ( case insensitive ) -----------------------------------------------//
|
||||
@ -510,7 +507,6 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\param Format A substitute string
|
||||
\param Loc A locale used for case insensitive comparison
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
@ -527,15 +523,15 @@ namespace boost {
|
||||
OutputIteratorT Output,
|
||||
const Range1T& Input,
|
||||
const Range2T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const Range3T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc) ),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
nth_finder(Search, Nth, is_iequal(Loc) ),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace nth algorithm ( case insensitive )
|
||||
@ -546,14 +542,14 @@ namespace boost {
|
||||
inline SequenceT ireplace_nth_copy(
|
||||
const SequenceT& Input,
|
||||
const Range1T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace nth algorithm ( case insensitive )
|
||||
@ -565,7 +561,6 @@ namespace boost {
|
||||
\param Input An input string
|
||||
\param Search A substring to be searched for
|
||||
\param Nth An index of the match to be replaced. The index is 0-based.
|
||||
For negative N, matches are counted from the end of string.
|
||||
\param Format A substitute string
|
||||
\param Loc A locale used for case insensitive comparison
|
||||
*/
|
||||
@ -573,14 +568,14 @@ namespace boost {
|
||||
inline void ireplace_nth(
|
||||
SequenceT& Input,
|
||||
const Range1T& Search,
|
||||
int Nth,
|
||||
unsigned int Nth,
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
nth_finder(Search, Nth, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_all --------------------------------------------------------------------//
|
||||
@ -612,11 +607,11 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const Range3T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace all algorithm
|
||||
@ -629,10 +624,10 @@ namespace boost {
|
||||
const Range1T& Search,
|
||||
const Range2T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace all algorithm
|
||||
@ -651,10 +646,10 @@ namespace boost {
|
||||
const Range1T& Search,
|
||||
const Range2T& Format )
|
||||
{
|
||||
::boost::algorithm::find_format_all(
|
||||
find_format_all(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_all ( case insensitive ) -----------------------------------------------//
|
||||
@ -689,11 +684,11 @@ namespace boost {
|
||||
const Range3T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace all algorithm ( case insensitive )
|
||||
@ -707,10 +702,10 @@ namespace boost {
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::find_format_all_copy(
|
||||
return find_format_all_copy(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace all algorithm ( case insensitive )
|
||||
@ -731,10 +726,10 @@ namespace boost {
|
||||
const Range2T& Format,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
::boost::algorithm::find_format_all(
|
||||
find_format_all(
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc)),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
first_finder(Search, is_iequal(Loc)),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_head --------------------------------------------------------------------//
|
||||
@ -750,9 +745,7 @@ namespace boost {
|
||||
|
||||
\param Output An output iterator to which the result will be copied
|
||||
\param Input An input string
|
||||
\param N Length of the head.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the head
|
||||
\param Format A substitute string
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
@ -766,14 +759,14 @@ namespace boost {
|
||||
inline OutputIteratorT replace_head_copy(
|
||||
OutputIteratorT Output,
|
||||
const Range1T& Input,
|
||||
int N,
|
||||
unsigned int N,
|
||||
const Range2T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::head_finder(N),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
head_finder(N),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace head algorithm
|
||||
@ -783,13 +776,13 @@ namespace boost {
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline SequenceT replace_head_copy(
|
||||
const SequenceT& Input,
|
||||
int N,
|
||||
unsigned int N,
|
||||
const RangeT& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::head_finder(N),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
head_finder(N),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace head algorithm
|
||||
@ -800,21 +793,19 @@ namespace boost {
|
||||
considered to be the head. The input sequence is modified in-place.
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the head.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the head
|
||||
\param Format A substitute string
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline void replace_head(
|
||||
SequenceT& Input,
|
||||
int N,
|
||||
unsigned int N,
|
||||
const RangeT& Format )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::head_finder(N),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
head_finder(N),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
// replace_tail --------------------------------------------------------------------//
|
||||
@ -830,9 +821,7 @@ namespace boost {
|
||||
|
||||
\param Output An output iterator to which the result will be copied
|
||||
\param Input An input string
|
||||
\param N Length of the tail.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the tail
|
||||
\param Format A substitute string
|
||||
\return An output iterator pointing just after the last inserted character or
|
||||
a modified copy of the input
|
||||
@ -846,14 +835,14 @@ namespace boost {
|
||||
inline OutputIteratorT replace_tail_copy(
|
||||
OutputIteratorT Output,
|
||||
const Range1T& Input,
|
||||
int N,
|
||||
unsigned int N,
|
||||
const Range2T& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Output,
|
||||
Input,
|
||||
::boost::algorithm::tail_finder(N),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
tail_finder(N),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace tail algorithm
|
||||
@ -863,13 +852,13 @@ namespace boost {
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline SequenceT replace_tail_copy(
|
||||
const SequenceT& Input,
|
||||
int N,
|
||||
unsigned int N,
|
||||
const RangeT& Format )
|
||||
{
|
||||
return ::boost::algorithm::find_format_copy(
|
||||
return find_format_copy(
|
||||
Input,
|
||||
::boost::algorithm::tail_finder(N),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
tail_finder(N),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
//! Replace tail algorithm
|
||||
@ -880,21 +869,19 @@ namespace boost {
|
||||
considered to be the tail. The input sequence is modified in-place.
|
||||
|
||||
\param Input An input string
|
||||
\param N Length of the tail.
|
||||
For N>=0, at most N characters are extracted.
|
||||
For N<0, size(Input)-|N| characters are extracted.
|
||||
\param N Length of the tail
|
||||
\param Format A substitute string
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline void replace_tail(
|
||||
SequenceT& Input,
|
||||
int N,
|
||||
unsigned int N,
|
||||
const RangeT& Format )
|
||||
{
|
||||
::boost::algorithm::find_format(
|
||||
find_format(
|
||||
Input,
|
||||
::boost::algorithm::tail_finder(N),
|
||||
::boost::algorithm::const_formatter(Format) );
|
||||
tail_finder(N),
|
||||
const_formatter(Format) );
|
||||
}
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library sequence_traits.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_SEQUENCE_TRAITS_HPP
|
||||
#define BOOST_STRING_SEQUENCE_TRAITS_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library split.hpp header file ---------------------------//
|
||||
// Boost string_algo library find.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2006.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_SPLIT_HPP
|
||||
#define BOOST_STRING_SPLIT_HPP
|
||||
@ -56,7 +55,7 @@ namespace boost {
|
||||
|
||||
\note Prior content of the result will be overwritten.
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template< typename SequenceSequenceT, typename Range1T, typename Range2T >
|
||||
inline SequenceSequenceT& find_all(
|
||||
@ -64,10 +63,10 @@ namespace boost {
|
||||
Range1T& Input,
|
||||
const Range2T& Search)
|
||||
{
|
||||
return ::boost::algorithm::iter_find(
|
||||
return iter_find(
|
||||
Result,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search) );
|
||||
first_finder(Search) );
|
||||
}
|
||||
|
||||
//! Find all algorithm ( case insensitive )
|
||||
@ -91,7 +90,7 @@ namespace boost {
|
||||
|
||||
\note Prior content of the result will be overwritten.
|
||||
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
\note This function provides the strong exception-safety guarantee
|
||||
*/
|
||||
template< typename SequenceSequenceT, typename Range1T, typename Range2T >
|
||||
inline SequenceSequenceT& ifind_all(
|
||||
@ -100,10 +99,10 @@ namespace boost {
|
||||
const Range2T& Search,
|
||||
const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return ::boost::algorithm::iter_find(
|
||||
return iter_find(
|
||||
Result,
|
||||
Input,
|
||||
::boost::algorithm::first_finder(Search, is_iequal(Loc) ) );
|
||||
first_finder(Search, is_iequal(Loc) ) );
|
||||
}
|
||||
|
||||
|
||||
@ -143,10 +142,10 @@ namespace boost {
|
||||
PredicateT Pred,
|
||||
token_compress_mode_type eCompress=token_compress_off )
|
||||
{
|
||||
return ::boost::algorithm::iter_split(
|
||||
return iter_split(
|
||||
Result,
|
||||
Input,
|
||||
::boost::algorithm::token_finder( Pred, eCompress ) );
|
||||
token_finder( Pred, eCompress ) );
|
||||
}
|
||||
|
||||
} // namespace algorithm
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library list_traits.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_STD_LIST_TRAITS_HPP
|
||||
#define BOOST_STRING_STD_LIST_TRAITS_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library string_traits.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_STD_ROPE_TRAITS_HPP
|
||||
#define BOOST_STRING_STD_ROPE_TRAITS_HPP
|
||||
|
@ -1,19 +1,18 @@
|
||||
// Boost string_algo library slist_traits.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_STD_SLIST_TRAITS_HPP
|
||||
#define BOOST_STRING_STD_SLIST_TRAITS_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
#include <boost/algorithm/string/yes_no_type.hpp>
|
||||
#include BOOST_SLIST_HEADER
|
||||
#include <slist>
|
||||
#include <boost/algorithm/string/sequence_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library string_traits.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_STD_STRING_TRAITS_HPP
|
||||
#define BOOST_STRING_STD_STRING_TRAITS_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library std_containers_traits.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_STD_CONTAINERS_TRAITS_HPP
|
||||
#define BOOST_STRING_STD_CONTAINERS_TRAITS_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library trim.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_TRIM_HPP
|
||||
#define BOOST_STRING_TRIM_HPP
|
||||
@ -16,8 +15,6 @@
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/const_iterator.hpp>
|
||||
#include <boost/range/as_literal.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
|
||||
#include <boost/algorithm/string/detail/trim.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
@ -63,14 +60,12 @@ namespace boost {
|
||||
const RangeT& Input,
|
||||
PredicateT IsSpace)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
|
||||
|
||||
std::copy(
|
||||
::boost::algorithm::detail::trim_begin(
|
||||
::boost::begin(lit_range),
|
||||
::boost::end(lit_range),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace ),
|
||||
::boost::end(lit_range),
|
||||
end(Input),
|
||||
Output);
|
||||
|
||||
return Output;
|
||||
@ -85,10 +80,10 @@ namespace boost {
|
||||
{
|
||||
return SequenceT(
|
||||
::boost::algorithm::detail::trim_begin(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace ),
|
||||
::boost::end(Input));
|
||||
end(Input));
|
||||
}
|
||||
|
||||
//! Left trim - parametric
|
||||
@ -106,7 +101,7 @@ namespace boost {
|
||||
inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale())
|
||||
{
|
||||
return
|
||||
::boost::algorithm::trim_left_copy_if(
|
||||
trim_left_copy_if(
|
||||
Input,
|
||||
is_space(Loc));
|
||||
}
|
||||
@ -124,10 +119,10 @@ namespace boost {
|
||||
inline void trim_left_if(SequenceT& Input, PredicateT IsSpace)
|
||||
{
|
||||
Input.erase(
|
||||
::boost::begin(Input),
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::trim_begin(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace));
|
||||
}
|
||||
|
||||
@ -142,7 +137,7 @@ namespace boost {
|
||||
template<typename SequenceT>
|
||||
inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale())
|
||||
{
|
||||
::boost::algorithm::trim_left_if(
|
||||
trim_left_if(
|
||||
Input,
|
||||
is_space(Loc));
|
||||
}
|
||||
@ -171,13 +166,11 @@ namespace boost {
|
||||
const RangeT& Input,
|
||||
PredicateT IsSpace )
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
|
||||
|
||||
std::copy(
|
||||
::boost::begin(lit_range),
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::trim_end(
|
||||
::boost::begin(lit_range),
|
||||
::boost::end(lit_range),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace ),
|
||||
Output );
|
||||
|
||||
@ -192,10 +185,10 @@ namespace boost {
|
||||
inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace)
|
||||
{
|
||||
return SequenceT(
|
||||
::boost::begin(Input),
|
||||
begin(Input),
|
||||
::boost::algorithm::detail::trim_end(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace)
|
||||
);
|
||||
}
|
||||
@ -215,7 +208,7 @@ namespace boost {
|
||||
inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale())
|
||||
{
|
||||
return
|
||||
::boost::algorithm::trim_right_copy_if(
|
||||
trim_right_copy_if(
|
||||
Input,
|
||||
is_space(Loc));
|
||||
}
|
||||
@ -235,10 +228,10 @@ namespace boost {
|
||||
{
|
||||
Input.erase(
|
||||
::boost::algorithm::detail::trim_end(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace ),
|
||||
::boost::end(Input)
|
||||
end(Input)
|
||||
);
|
||||
}
|
||||
|
||||
@ -254,7 +247,7 @@ namespace boost {
|
||||
template<typename SequenceT>
|
||||
inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale())
|
||||
{
|
||||
::boost::algorithm::trim_right_if(
|
||||
trim_right_if(
|
||||
Input,
|
||||
is_space(Loc) );
|
||||
}
|
||||
@ -283,18 +276,16 @@ namespace boost {
|
||||
const RangeT& Input,
|
||||
PredicateT IsSpace)
|
||||
{
|
||||
iterator_range<BOOST_STRING_TYPENAME range_const_iterator<RangeT>::type> lit_range(::boost::as_literal(Input));
|
||||
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<RangeT>::type TrimEnd=
|
||||
::boost::algorithm::detail::trim_end(
|
||||
::boost::begin(lit_range),
|
||||
::boost::end(lit_range),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace);
|
||||
|
||||
std::copy(
|
||||
detail::trim_begin(
|
||||
::boost::begin(lit_range), TrimEnd, IsSpace),
|
||||
begin(Input), TrimEnd, IsSpace),
|
||||
TrimEnd,
|
||||
Output
|
||||
);
|
||||
@ -312,13 +303,13 @@ namespace boost {
|
||||
BOOST_STRING_TYPENAME
|
||||
range_const_iterator<SequenceT>::type TrimEnd=
|
||||
::boost::algorithm::detail::trim_end(
|
||||
::boost::begin(Input),
|
||||
::boost::end(Input),
|
||||
begin(Input),
|
||||
end(Input),
|
||||
IsSpace);
|
||||
|
||||
return SequenceT(
|
||||
detail::trim_begin(
|
||||
::boost::begin(Input),
|
||||
begin(Input),
|
||||
TrimEnd,
|
||||
IsSpace),
|
||||
TrimEnd
|
||||
@ -340,7 +331,7 @@ namespace boost {
|
||||
inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() )
|
||||
{
|
||||
return
|
||||
::boost::algorithm::trim_copy_if(
|
||||
trim_copy_if(
|
||||
Input,
|
||||
is_space(Loc) );
|
||||
}
|
||||
@ -357,8 +348,8 @@ namespace boost {
|
||||
template<typename SequenceT, typename PredicateT>
|
||||
inline void trim_if(SequenceT& Input, PredicateT IsSpace)
|
||||
{
|
||||
::boost::algorithm::trim_right_if( Input, IsSpace );
|
||||
::boost::algorithm::trim_left_if( Input, IsSpace );
|
||||
trim_right_if( Input, IsSpace );
|
||||
trim_left_if( Input, IsSpace );
|
||||
}
|
||||
|
||||
//! Trim
|
||||
@ -372,7 +363,7 @@ namespace boost {
|
||||
template<typename SequenceT>
|
||||
inline void trim(SequenceT& Input, const std::locale& Loc=std::locale())
|
||||
{
|
||||
::boost::algorithm::trim_if(
|
||||
trim_if(
|
||||
Input,
|
||||
is_space( Loc ) );
|
||||
}
|
||||
|
@ -1,217 +0,0 @@
|
||||
// Boost string_algo library trim.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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 updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_TRIM_ALL_HPP
|
||||
#define BOOST_STRING_TRIM_ALL_HPP
|
||||
|
||||
#include <boost/algorithm/string/config.hpp>
|
||||
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/find_format.hpp>
|
||||
#include <boost/algorithm/string/formatter.hpp>
|
||||
#include <boost/algorithm/string/finder.hpp>
|
||||
#include <locale>
|
||||
|
||||
/*! \file
|
||||
Defines trim_all algorithms.
|
||||
|
||||
Just like \c trim, \c trim_all removes all trailing and leading spaces from a
|
||||
sequence (string). In addition, spaces in the middle of the sequence are truncated
|
||||
to just one character. Space is recognized using given locales.
|
||||
|
||||
\c trim_fill acts as trim_all, but the spaces in the middle are replaces with
|
||||
a user-define sequence of character.
|
||||
|
||||
Parametric (\c _if) variants use a predicate (functor) to select which characters
|
||||
are to be trimmed..
|
||||
Functions take a selection predicate as a parameter, which is used to determine
|
||||
whether a character is a space. Common predicates are provided in classification.hpp header.
|
||||
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace algorithm {
|
||||
|
||||
// multi line trim ----------------------------------------------- //
|
||||
|
||||
//! Trim All - parametric
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
compress all other spaces to a single character.
|
||||
The result is a trimmed copy of the input
|
||||
|
||||
\param Input An input sequence
|
||||
\param IsSpace An unary predicate identifying spaces
|
||||
\return A trimmed copy of the input
|
||||
*/
|
||||
template<typename SequenceT, typename PredicateT>
|
||||
inline SequenceT trim_all_copy_if(const SequenceT& Input, PredicateT IsSpace)
|
||||
{
|
||||
return
|
||||
::boost::find_format_all_copy(
|
||||
::boost::trim_copy_if(Input, IsSpace),
|
||||
::boost::token_finder(IsSpace, ::boost::token_compress_on),
|
||||
::boost::dissect_formatter(::boost::head_finder(1)));
|
||||
}
|
||||
|
||||
|
||||
//! Trim All
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
compress all other spaces to a single character.
|
||||
The input sequence is modified in-place.
|
||||
|
||||
\param Input An input sequence
|
||||
\param IsSpace An unary predicate identifying spaces
|
||||
*/
|
||||
template<typename SequenceT, typename PredicateT>
|
||||
inline void trim_all_if(SequenceT& Input, PredicateT IsSpace)
|
||||
{
|
||||
::boost::trim_if(Input, IsSpace);
|
||||
::boost::find_format_all(
|
||||
Input,
|
||||
::boost::token_finder(IsSpace, ::boost::token_compress_on),
|
||||
::boost::dissect_formatter(::boost::head_finder(1)));
|
||||
}
|
||||
|
||||
|
||||
//! Trim All
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
compress all other spaces to a single character.
|
||||
The result is a trimmed copy of the input
|
||||
|
||||
\param Input An input sequence
|
||||
\param Loc A locale used for 'space' classification
|
||||
\return A trimmed copy of the input
|
||||
*/
|
||||
template<typename SequenceT>
|
||||
inline SequenceT trim_all_copy(const SequenceT& Input, const std::locale& Loc =std::locale())
|
||||
{
|
||||
return trim_all_copy_if(Input, ::boost::is_space(Loc));
|
||||
}
|
||||
|
||||
|
||||
//! Trim All
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
compress all other spaces to a single character.
|
||||
The input sequence is modified in-place.
|
||||
|
||||
\param Input An input sequence
|
||||
\param Loc A locale used for 'space' classification
|
||||
\return A trimmed copy of the input
|
||||
*/
|
||||
template<typename SequenceT>
|
||||
inline void trim_all(SequenceT& Input, const std::locale& Loc =std::locale())
|
||||
{
|
||||
trim_all_if(Input, ::boost::is_space(Loc));
|
||||
}
|
||||
|
||||
|
||||
//! Trim Fill - parametric
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
replace all every block of consecutive spaces with a fill string
|
||||
defined by user.
|
||||
The result is a trimmed copy of the input
|
||||
|
||||
\param Input An input sequence
|
||||
\param Fill A string used to fill the inner spaces
|
||||
\param IsSpace An unary predicate identifying spaces
|
||||
\return A trimmed copy of the input
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT, typename PredicateT>
|
||||
inline SequenceT trim_fill_copy_if(const SequenceT& Input, const RangeT& Fill, PredicateT IsSpace)
|
||||
{
|
||||
return
|
||||
::boost::find_format_all_copy(
|
||||
::boost::trim_copy_if(Input, IsSpace),
|
||||
::boost::token_finder(IsSpace, ::boost::token_compress_on),
|
||||
::boost::const_formatter(::boost::as_literal(Fill)));
|
||||
}
|
||||
|
||||
|
||||
//! Trim Fill
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
replace all every block of consecutive spaces with a fill string
|
||||
defined by user.
|
||||
The input sequence is modified in-place.
|
||||
|
||||
\param Input An input sequence
|
||||
\param Fill A string used to fill the inner spaces
|
||||
\param IsSpace An unary predicate identifying spaces
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT, typename PredicateT>
|
||||
inline void trim_fill_if(SequenceT& Input, const RangeT& Fill, PredicateT IsSpace)
|
||||
{
|
||||
::boost::trim_if(Input, IsSpace);
|
||||
::boost::find_format_all(
|
||||
Input,
|
||||
::boost::token_finder(IsSpace, ::boost::token_compress_on),
|
||||
::boost::const_formatter(::boost::as_literal(Fill)));
|
||||
}
|
||||
|
||||
|
||||
//! Trim Fill
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
replace all every block of consecutive spaces with a fill string
|
||||
defined by user.
|
||||
The result is a trimmed copy of the input
|
||||
|
||||
\param Input An input sequence
|
||||
\param Fill A string used to fill the inner spaces
|
||||
\param Loc A locale used for 'space' classification
|
||||
\return A trimmed copy of the input
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline SequenceT trim_fill_copy(const SequenceT& Input, const RangeT& Fill, const std::locale& Loc =std::locale())
|
||||
{
|
||||
return trim_fill_copy_if(Input, Fill, ::boost::is_space(Loc));
|
||||
}
|
||||
|
||||
|
||||
//! Trim Fill
|
||||
/*!
|
||||
Remove all leading and trailing spaces from the input and
|
||||
replace all every block of consecutive spaces with a fill string
|
||||
defined by user.
|
||||
The input sequence is modified in-place.
|
||||
|
||||
\param Input An input sequence
|
||||
\param Fill A string used to fill the inner spaces
|
||||
\param Loc A locale used for 'space' classification
|
||||
\return A trimmed copy of the input
|
||||
*/
|
||||
template<typename SequenceT, typename RangeT>
|
||||
inline void trim_fill(SequenceT& Input, const RangeT& Fill, const std::locale& Loc =std::locale())
|
||||
{
|
||||
trim_fill_if(Input, Fill, ::boost::is_space(Loc));
|
||||
}
|
||||
|
||||
|
||||
} // namespace algorithm
|
||||
|
||||
// pull names to the boost namespace
|
||||
using algorithm::trim_all;
|
||||
using algorithm::trim_all_if;
|
||||
using algorithm::trim_all_copy;
|
||||
using algorithm::trim_all_copy_if;
|
||||
using algorithm::trim_fill;
|
||||
using algorithm::trim_fill_if;
|
||||
using algorithm::trim_fill_copy;
|
||||
using algorithm::trim_fill_copy_if;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_STRING_TRIM_ALL_HPP
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library yes_no_type.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_YES_NO_TYPE_DETAIL_HPP
|
||||
#define BOOST_STRING_YES_NO_TYPE_DETAIL_HPP
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Boost string_algo library string_regex.hpp header file ---------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2004.
|
||||
//
|
||||
// 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)
|
||||
// Copyright Pavol Droba 2002-2004. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_STRING_ALGO_REGEX_HPP
|
||||
#define BOOST_STRING_ALGO_REGEX_HPP
|
||||
|
@ -1,524 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.77 [en] (X11; U; Linux 2.2.19 i686) [Netscape]">
|
||||
<meta name="Author" content="Herve Bronnimann">
|
||||
<meta name="Description" content="Small library to propose minmax_element algorithm.">
|
||||
<title>Boost minmax library</title>
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
Minmax_element Performance</h1></center>
|
||||
|
||||
<h3>
|
||||
<a NAME="Performance"></a><b>About performance</b></h3>
|
||||
Of course, there are many factors that affect the performance of an algorithm.
|
||||
The number of comparison is only one, but also branch prediction, pipelining,
|
||||
locality of reference (affects cache efficiency), etc. In practice,
|
||||
we observe that when the iterator type is a pointer,
|
||||
<tt>boost::minmax_element</tt>
|
||||
is only a tad slower than
|
||||
<tt>std::min_element</tt>, and is even faster
|
||||
than
|
||||
<tt>boost::first_min_last_max_element</tt>! This is even more true
|
||||
for slower iterators (<tt>list<>::iterator</tt> or
|
||||
<tt>map<>iterator</tt>
|
||||
for instance). The following experiments were conducted on a Pentium III
|
||||
500 Mhz running Linux and compiled with g++, version 2.95.2, flags -O3.
|
||||
In the tables, we use different distributions: <i>Identical</i> means that
|
||||
all the elements are identical, <i>2-valued</i> means that we replace the
|
||||
second half of the identical elements by a distinct element, <i>increasing</i>
|
||||
means that all the elements are distinct and in increasing order, <i>decrea</i>sing
|
||||
is the reverse, and <i>random</i> is produced by random_shuffle.
|
||||
<br>
|
||||
The program that created these tables is included in the distribution,
|
||||
under <a href="../example/minmax_timer.cpp">minmax_timer.cpp</a>
|
||||
<br>
|
||||
<center><table BORDER NOSAVE >
|
||||
<tr NOSAVE>
|
||||
<td NOSAVE><b>vector<int>::iterator</b></td>
|
||||
|
||||
<td>Identical</td>
|
||||
|
||||
<td>2-valued</td>
|
||||
|
||||
<td>Increasing</td>
|
||||
|
||||
<td>Decreasing</td>
|
||||
|
||||
<td>Random</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::min_element</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>22.94M/s</td>
|
||||
|
||||
<td>22.94M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::max_element</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>22.94M/s</td>
|
||||
|
||||
<td>22.62M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_min_element</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>23.04M/s</td>
|
||||
|
||||
<td>23.04M/s</td>
|
||||
|
||||
<td>22.94M/s</td>
|
||||
|
||||
<td>22.83M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_element</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>22.83M/s</td>
|
||||
|
||||
<td>16.23M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_max_element</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>23.04M/s</td>
|
||||
|
||||
<td>22.93M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_max_element</td>
|
||||
|
||||
<td>23.26M/s</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>23.15M/s</td>
|
||||
|
||||
<td>22.94M/s</td>
|
||||
|
||||
<td>16.18M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::minmax_element</td>
|
||||
|
||||
<td>21.83M/s</td>
|
||||
|
||||
<td>21.83M/s</td>
|
||||
|
||||
<td>21.83M/s</td>
|
||||
|
||||
<td>21.55M/s</td>
|
||||
|
||||
<td>17.79M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_min_last_max_element</td>
|
||||
|
||||
<td>18.52M/s</td>
|
||||
|
||||
<td>18.38M/s</td>
|
||||
|
||||
<td>18.38M/s</td>
|
||||
|
||||
<td>18.94M/s</td>
|
||||
|
||||
<td>16.29M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_first_max_element</td>
|
||||
|
||||
<td>20.08M/s</td>
|
||||
|
||||
<td>20.83M/s</td>
|
||||
|
||||
<td>20.75M/s</td>
|
||||
|
||||
<td>19.76M/s</td>
|
||||
|
||||
<td>15.87M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_last_max_element</td>
|
||||
|
||||
<td>18.66M/s</td>
|
||||
|
||||
<td>19.69M/s</td>
|
||||
|
||||
<td>19.69M/s</td>
|
||||
|
||||
<td>19.23M/s</td>
|
||||
|
||||
<td>15.77M/s</td>
|
||||
</tr>
|
||||
|
||||
<caption ALIGN=BOTTOM>Number of elements per second for standard vector
|
||||
container iterators</caption>
|
||||
</table></center>
|
||||
|
||||
<center><table BORDER NOSAVE >
|
||||
<tr NOSAVE>
|
||||
<td NOSAVE><b>list<int>::iterator</b></td>
|
||||
|
||||
<td>Identical</td>
|
||||
|
||||
<td>2-valued</td>
|
||||
|
||||
<td>Increasing</td>
|
||||
|
||||
<td>Decreasing</td>
|
||||
|
||||
<td>Random</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::min_element</td>
|
||||
|
||||
<td>5.8M/s</td>
|
||||
|
||||
<td>5.8M/s</td>
|
||||
|
||||
<td>5.80M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::max_element</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.78M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
|
||||
<td>5.75M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_min_element</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.79M/s</td>
|
||||
|
||||
<td>5.75M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_element</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.80M/s</td>
|
||||
|
||||
<td>5.79M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
|
||||
<td>5.03M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_max_element</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.80M/s</td>
|
||||
|
||||
<td>5.78M/s</td>
|
||||
|
||||
<td>5.74M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_max_element</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.80M/s</td>
|
||||
|
||||
<td>5.79M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
|
||||
<td>5.07M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::minmax_element</td>
|
||||
|
||||
<td>5.68M/s</td>
|
||||
|
||||
<td>5.80M/s</td>
|
||||
|
||||
<td>5.66M/s</td>
|
||||
|
||||
<td>5.74M/s</td>
|
||||
|
||||
<td>5.30M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_min_last_max_element</td>
|
||||
|
||||
<td>5.79M/s</td>
|
||||
|
||||
<td>5.81M/s</td>
|
||||
|
||||
<td>5.78M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
|
||||
<td>5.04M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_first_max_element</td>
|
||||
|
||||
<td>5.69M/s</td>
|
||||
|
||||
<td>5.79M/s</td>
|
||||
|
||||
<td>5.69M/s</td>
|
||||
|
||||
<td>5.73M/s</td>
|
||||
|
||||
<td>4.84M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_last_max_element</td>
|
||||
|
||||
<td>5.61M/s</td>
|
||||
|
||||
<td>5.79M/s</td>
|
||||
|
||||
<td>5.64M/s</td>
|
||||
|
||||
<td>5.74M/s</td>
|
||||
|
||||
<td>4.75M/s</td>
|
||||
</tr>
|
||||
|
||||
<caption ALIGN=BOTTOM>Runtimes for standard list container iterators</caption>
|
||||
</table></center>
|
||||
|
||||
<center><table BORDER NOSAVE >
|
||||
<tr NOSAVE>
|
||||
<td NOSAVE><b>multiset<int>::iterator</b></td>
|
||||
|
||||
<td>Identical</td>
|
||||
|
||||
<td>2-valued</td>
|
||||
|
||||
<td>Increasing</td>
|
||||
|
||||
<td>Decreasing</td>
|
||||
|
||||
<td>Random</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::min_element</td>
|
||||
|
||||
<td>4.03M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.02M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>2.97M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::max_element3.007M</td>
|
||||
|
||||
<td>4.02M/s</td>
|
||||
|
||||
<td>4.02M/s</td>
|
||||
|
||||
<td>4.01M/s</td>
|
||||
|
||||
<td>4.02M/s</td>
|
||||
|
||||
<td>2.96M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_min_element</td>
|
||||
|
||||
<td>4.01M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.03M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>3.01M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_element</td>
|
||||
|
||||
<td>4.03M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>3.00M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_max_element</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.06M/s</td>
|
||||
|
||||
<td>3.01M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_max_element</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>4.03M/s</td>
|
||||
|
||||
<td>4.04M/s</td>
|
||||
|
||||
<td>3.00M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::minmax_element</td>
|
||||
|
||||
<td>3.98M/s</td>
|
||||
|
||||
<td>3.99M/s</td>
|
||||
|
||||
<td>3.98M/s</td>
|
||||
|
||||
<td>3.99M/s</td>
|
||||
|
||||
<td>3.00M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::first_min_last_max_element</td>
|
||||
|
||||
<td>3.99M/s</td>
|
||||
|
||||
<td>3.98M/s</td>
|
||||
|
||||
<td>3.97M/s</td>
|
||||
|
||||
<td>3.99M/s</td>
|
||||
|
||||
<td>2.99M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_first_max_element</td>
|
||||
|
||||
<td>3.97M/s</td>
|
||||
|
||||
<td>3.98M/s</td>
|
||||
|
||||
<td>3.96M/s</td>
|
||||
|
||||
<td>3.98M/s</td>
|
||||
|
||||
<td>3.00M/s</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>boost::last_min_last_max_element</td>
|
||||
|
||||
<td>4.00M/s</td>
|
||||
|
||||
<td>4.00M/s</td>
|
||||
|
||||
<td>4.00M/s</td>
|
||||
|
||||
<td>4.02M/s</td>
|
||||
|
||||
<td>2.97M/s</td>
|
||||
</tr>
|
||||
|
||||
<caption ALIGN=BOTTOM>Runtimes for standard set/multiset container iterators</caption>
|
||||
</table></center>
|
||||
|
||||
<hr SIZE="6">
|
||||
<br>Last modified 2004-06-28
|
||||
<p><font face="Arial,Helvetica"><font size=-1>© Copyright Hervé
|
||||
Brönnimann, Polytechnic University, 2002--2004.
|
||||
Use, modification, and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">License_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</font></font>
|
||||
</body>
|
||||
</html>
|
@ -1,127 +0,0 @@
|
||||
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.77 [en] (X11; U; Linux 2.2.19 i686) [Netscape]">
|
||||
<meta name="Author" content="Herve Bronnimann">
|
||||
<meta name="Description" content="Small library to propose minmax_element algorithm.">
|
||||
<title>Boost minmax library synopsis</title>
|
||||
</head>
|
||||
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||
|
||||
<center>
|
||||
<h1>
|
||||
Minmax_element complete synopsis</h1></center>
|
||||
|
||||
<h3>
|
||||
Synopsis of <tt><boost/algorithm/minmax.hpp></tt></h3>
|
||||
|
||||
<pre>#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class T>
|
||||
tuple<T const&, T const&> >
|
||||
minmax(const T& a, const T& b);
|
||||
|
||||
template <class T, class <a href="http://www.sgi.com/tech/stl/ BinaryPredicate.html">BinaryPredicate</a>>
|
||||
tuple<T const&, T const&> >
|
||||
minmax(const T& a, const T& b, BinaryPredicate comp);
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>
|
||||
Synopsis of <tt><boost/algorithm/minmax_element.hpp></tt></h3>
|
||||
|
||||
<pre>#include <utility> //for std::pair
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
minmax_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
minmax_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
// Variants
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
ForwardIterator first_min_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
ForwardIterator first_min_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
ForwardIterator last_min_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
ForwardIterator last_min_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
ForwardIterator first_max_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
ForwardIterator first_max_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
ForwardIterator last_max_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
ForwardIterator last_max_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
first_min_first_max_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
first_min_first_max_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
first_min_last_max_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
first_min_last_max_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
last_min_first_max_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
last_min_first_max_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
last_min_last_max_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
last_min_last_max_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
}</pre>
|
||||
|
||||
<hr SIZE="6">
|
||||
<br>Last modified 2002-07-01
|
||||
<p><font face="Arial,Helvetica"><font size=-1>© Copyright Hervé
|
||||
Brönnimann, Polytechnic University, 2002--2004.
|
||||
Use, modification, and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">License_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</font></font>
|
||||
</body>
|
||||
</html>
|
@ -1,12 +0,0 @@
|
||||
# Boost.Minmax Library Example Jamfile
|
||||
#
|
||||
# Copyright (C) 2002--2004, Herve Bronnimann
|
||||
#
|
||||
# Use, modification, and distribution is subject to 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)
|
||||
#
|
||||
|
||||
exe minmax_ex : minmax_ex.cpp ;
|
||||
exe minmax_timer : minmax_timer.cpp ;
|
||||
|
@ -1,36 +0,0 @@
|
||||
// (C) Copyright Herve Bronnimann 2004.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/algorithm/minmax.hpp>
|
||||
#include <boost/algorithm/minmax_element.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// Demonstrating minmax()
|
||||
boost::tuple<int const&, int const&> result1 = boost::minmax(1, 0);
|
||||
assert( result1.get<0>() == 0 );
|
||||
assert( result1.get<1>() == 1 );
|
||||
|
||||
|
||||
// Demonstrating minmax_element()
|
||||
list<int> L;
|
||||
typedef list<int>::const_iterator iterator;
|
||||
generate_n(front_inserter(L), 1000, rand);
|
||||
pair< iterator, iterator > result2 = boost::minmax_element(L.begin(), L.end());
|
||||
|
||||
cout << "The smallest element is " << *(result2.first) << endl;
|
||||
cout << "The largest element is " << *(result2.second) << endl;
|
||||
|
||||
assert( result2.first == std::min_element(L.begin(), L.end()) );
|
||||
assert( result2.second == std::max_element(L.begin(), L.end()) );
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
// (C) Copyright Herve Bronnimann 2004.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
// What's the proper BOOST_ flag for <iomanip.h> vs <ios>
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/algorithm/minmax.hpp>
|
||||
|
||||
template <class T1, class T2>
|
||||
void tie(std::pair<T1, T2> p, T1& min, T2& max)
|
||||
{
|
||||
min = p.first; max = p.second;
|
||||
}
|
||||
|
||||
template <class Value>
|
||||
struct less_count : std::less<Value> {
|
||||
less_count(less_count<Value> const& lc) : _M_counter(lc._M_counter) {}
|
||||
less_count(int& counter) : _M_counter(counter) {}
|
||||
bool operator()(Value const& a, Value const& b) const {
|
||||
++_M_counter;
|
||||
return std::less<Value>::operator()(a,b);
|
||||
}
|
||||
void reset() {
|
||||
_M_counter = 0;
|
||||
}
|
||||
private:
|
||||
int& _M_counter;
|
||||
};
|
||||
|
||||
inline int opt_min_count(int n) {
|
||||
return (n==0) ? 0 : n-1;
|
||||
}
|
||||
inline int opt_minmax_count(int n) {
|
||||
if (n < 2) return 0;
|
||||
if (n == 2) return 1;
|
||||
return (n%2 == 0) ? 3*(n/2)-1 : 3*(n/2)+1;
|
||||
}
|
||||
inline int opt_boost_minmax_count(int n) {
|
||||
if (n < 2) return 0;
|
||||
if (n == 2) return 1;
|
||||
return (n%2 == 0) ? 3*(n/2)-2 : 3*(n/2);
|
||||
}
|
||||
|
||||
int repeats = 10;
|
||||
|
||||
#define TIMER( n, cmd , cmdname ) \
|
||||
t.restart(); \
|
||||
for (int i=0; i<repeats; ++i) { cmd ; } \
|
||||
std::cout << " " << std::setprecision(4) \
|
||||
<< (double)n*repeats/t.elapsed()/1.0E6 \
|
||||
<< "M items/sec " << cmdname << "\n"
|
||||
|
||||
#define CTIMER( n, cmd , cmdname, count, opt ) \
|
||||
t.restart(); lc.reset(); \
|
||||
for (int i=0; i<repeats; ++i) { cmd ; } \
|
||||
std::cout << " " << std::setprecision(4) \
|
||||
<< (double)n*repeats/t.elapsed()/1.0E6 \
|
||||
<< "M items/sec " << cmdname \
|
||||
<< " ("<< (count)/repeats << " vs " << opt << ")\n"
|
||||
|
||||
template <class CIterator>
|
||||
void test_minmax_element(CIterator first, CIterator last, int n, char* name)
|
||||
{
|
||||
typedef typename std::iterator_traits<CIterator>::value_type vtype;
|
||||
boost::timer t;
|
||||
|
||||
std::cout << " ON " << name << " WITH OPERATOR<()\n";
|
||||
TIMER( n, std::min_element(first, last),
|
||||
"std::min_element" << name << "");
|
||||
TIMER( n, std::max_element(first, last),
|
||||
"std::max_element" << name << "");
|
||||
TIMER( n, boost::first_min_element(first, last),
|
||||
"boost::first_min_element" << name << "");
|
||||
TIMER( n, boost::last_min_element(first, last),
|
||||
"boost::last_min_element" << name << " ");
|
||||
TIMER( n, boost::first_max_element(first, last),
|
||||
"boost::first_max_element" << name << "");
|
||||
TIMER( n, boost::last_max_element(first, last),
|
||||
"boost::last_max_element" << name << " ");
|
||||
TIMER( n, boost::minmax_element(first, last),
|
||||
"boost::minmax_element" << name << " ");
|
||||
TIMER( n, boost::first_min_last_max_element(first, last),
|
||||
"boost::first_min_last_max_element" << name << "");
|
||||
TIMER( n, boost::last_min_first_max_element(first, last),
|
||||
"boost::last_min_first_max_element" << name << "");
|
||||
TIMER( n, boost::last_min_last_max_element(first, last),
|
||||
"boost::last_min_last_max_element" << name << " ");
|
||||
|
||||
#define pred std::bind2nd( std::greater<vtype>(), vtype(10) )
|
||||
TIMER( n, boost::min_element_if(first, last, pred),
|
||||
"boost::min_element_if" << name << "");
|
||||
TIMER( n, boost::max_element_if(first, last, pred),
|
||||
"boost::max_element_if" << name << "");
|
||||
TIMER( n, std::min_element(boost::make_filter_iterator(first, last, pred),
|
||||
boost::make_filter_iterator(last, last, pred)),
|
||||
"std::min_element_with_filter_iterator" << name << "");
|
||||
TIMER( n, std::max_element(boost::make_filter_iterator(first, last, pred),
|
||||
boost::make_filter_iterator(last, last, pred)),
|
||||
"std::max_element_if_with_filter_iterator" << name << "");
|
||||
#undef pred
|
||||
|
||||
int counter = 0;
|
||||
less_count<vtype> lc(counter);
|
||||
std::cout << " ON " << name << " WITH LESS<> AND COUNTING COMPARISONS\n";
|
||||
CTIMER( n, std::min_element(first, last, lc),
|
||||
"std::min_element" << name << " ",
|
||||
counter, opt_min_count(n) );
|
||||
CTIMER( n, std::max_element(first, last, lc),
|
||||
"std::max_element" << name << " ",
|
||||
counter, opt_min_count(n) );
|
||||
CTIMER( n, boost::first_min_element(first, last, lc),
|
||||
"boost::first_min_element" << name << "",
|
||||
counter, opt_min_count(n) );
|
||||
CTIMER( n, boost::last_min_element(first, last, lc),
|
||||
"boost::last_max_element" << name << " ",
|
||||
counter, opt_min_count(n) );
|
||||
CTIMER( n, boost::first_max_element(first, last, lc),
|
||||
"boost::first_min_element" << name << "",
|
||||
counter, opt_min_count(n) );
|
||||
CTIMER( n, boost::last_max_element(first, last, lc),
|
||||
"boost::last_max_element" << name << " ",
|
||||
counter, opt_min_count(n) );
|
||||
CTIMER( n, boost::minmax_element(first, last, lc),
|
||||
"boost::minmax_element" << name << " ",
|
||||
counter, opt_minmax_count(n) );
|
||||
CTIMER( n, boost::first_min_last_max_element(first, last, lc),
|
||||
"boost::first_min_last_max_element" << name << "",
|
||||
counter, opt_boost_minmax_count(n) );
|
||||
CTIMER( n, boost::last_min_first_max_element(first, last, lc),
|
||||
"boost::last_min_first_max_element" << name << "",
|
||||
counter, opt_boost_minmax_count(n) );
|
||||
CTIMER( n, boost::last_min_last_max_element(first, last, lc),
|
||||
"boost::last_min_last_max_element" << name << " ",
|
||||
counter, opt_minmax_count(n) );
|
||||
}
|
||||
|
||||
template <class Container, class Iterator, class Value>
|
||||
void test_container(Iterator first, Iterator last, int n, char* name)
|
||||
{
|
||||
Container c(first, last);
|
||||
typename Container::iterator fit(c.begin()), lit(c.end());
|
||||
test_minmax_element(fit, lit, n, name);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
void test_range(Iterator first, Iterator last, int n)
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type Value;
|
||||
// Test various containers with these values
|
||||
test_container< std::vector<Value>, Iterator, Value >(first, last, n, "<vector>");
|
||||
#ifndef ONLY_VECTOR
|
||||
test_container< std::list<Value>, Iterator, Value >(first, last, n, "<list> ");
|
||||
test_container< std::multiset<Value>, Iterator, Value >(first, last, n, "<set> ");
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Value>
|
||||
void test(int n)
|
||||
{
|
||||
// Populate test vector with identical values
|
||||
std::cout << "IDENTICAL VALUES... \n";
|
||||
std::vector<Value> test_vector(n, Value(1));
|
||||
typename std::vector<Value>::iterator first( test_vector.begin() );
|
||||
typename std::vector<Value>::iterator last( test_vector.end() );
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with two values
|
||||
std::cout << "TWO DISTINCT VALUES...\n";
|
||||
typename std::vector<Value>::iterator middle( first + n/2 );
|
||||
std::fill(middle, last, Value(2));
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with increasing values
|
||||
std::cout << "INCREASING VALUES... \n";
|
||||
std::fill(first, last, Value(1));
|
||||
std::accumulate(first, last, Value(0));
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with decreasing values
|
||||
std::cout << "DECREASING VALUES... \n";
|
||||
std::reverse(first, last);
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with random values
|
||||
std::cout << "RANDOM VALUES... \n";
|
||||
std::random_shuffle(first, last);
|
||||
test_range(first, last, n);
|
||||
}
|
||||
|
||||
int
|
||||
main(char argc, char** argv)
|
||||
{
|
||||
int n = 100;
|
||||
if (argc > 1) n = atoi(argv[1]);
|
||||
if (argc > 2) repeats = atoi(argv[2]);
|
||||
|
||||
test<int>(n);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,527 +0,0 @@
|
||||
<!DOCTYPE html public "-//w3c//dtd html 4.0 transitional//en">
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../boost.css">
|
||||
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<META name="GENERATOR" content="Mozilla/4.77 [en] (X11; U; Linux 2.2.19 i686) [Netscape]">
|
||||
<META name="Author" content="Herve Bronnimann">
|
||||
<META name="Description" content="Small library to propose minmax_element algorithm.">
|
||||
<title>Boost Minmax library</title>
|
||||
</HEAD>
|
||||
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
|
||||
|
||||
<h2><img src="../../../boost.png" WIDTH="276" HEIGHT="86">Header <<A
|
||||
HREF="../../../boost/algorithm/minmax.hpp">boost/algorithm/minmax.hpp</A>> </H2>
|
||||
|
||||
<quote>
|
||||
<b>
|
||||
<a href="#minmax_element">Motivation</a><br>
|
||||
<a href="#synopsis">Synopsis</a><br>
|
||||
<a href="#description">Function templates description</a><br>
|
||||
<a href="#definition">Definition</a><br>
|
||||
<a href="#reqs">Requirements on types</a><br>
|
||||
<a href="#precond">Preconditions</a><br>
|
||||
<a href="#postcond">Postconditions</a><br>
|
||||
<a href="#complexity">Complexity</a><br>
|
||||
<a href="#example">Example</a><br>
|
||||
<a href="#notes">Notes</a><br>
|
||||
<a href="#rationale">Rationale</a><br>
|
||||
<a href="#perf">Note about performance</a><br>
|
||||
<a href="#acks">Acknowledgements</a>
|
||||
</b>
|
||||
</quote>
|
||||
|
||||
|
||||
<a name="minmax_element">
|
||||
<h3>
|
||||
Motivation</h3>
|
||||
|
||||
<p>The minmax library is composed of two headers, <a
|
||||
href="../../../boost/algorithm/minmax.hpp"><boost/algorithm/minmax.hpp></a>
|
||||
and <a
|
||||
href="../../../boost/algorithm/minmax_element.hpp"><boost/algorithm/minmax_element.hpp></a>.
|
||||
(See <a href="#two_headers">rationale</a>.)
|
||||
The problem solved by this library is that simultaneous min and max
|
||||
computation requires
|
||||
only one comparison, but using <tt>std::min</tt> and <tt>std::max</tt>
|
||||
forces two comparisons. Worse, to compute the minimum and
|
||||
maximum elements of a range of <tt>n</tt> elements requires only
|
||||
<tt>3n/2+1</tt> comparisons, instead of the <tt>2n</tt> (in two passes)
|
||||
forced by <tt>std::min_element</tt> and <tt>std::max_element</tt>.
|
||||
I always thought it is a waste to have to call two functions to compute the
|
||||
extent of a range, performing two passes over the input, when one should
|
||||
be enough. The present library solves both problems.</p>
|
||||
|
||||
<p>The first file implements the function templates
|
||||
<tt>minmax</tt>
|
||||
as straightforward extensions of the C++
|
||||
standard. As it returns a pair of <tt>const&</tt>, we must use the <a
|
||||
href="../../tuple/index.html">Boost.tuple</a> library to construct such
|
||||
pairs. (Please note: the intent is not to fix the known defaults of
|
||||
<tt>std::min</tt>
|
||||
and <tt>std::max</tt>, but to add one more algorithms that combines both; see the
|
||||
<a href="#no-fix">rationale</a>.)</p>
|
||||
|
||||
<p>The second file implements the function templates
|
||||
<tt>minmax_element</tt>. In a
|
||||
second part, it also proposes variants that can usually not be computed by
|
||||
the minmax algorithm, and which are more flexible in case some elements are equal.
|
||||
Those variants could have been also provided with policy-based design,
|
||||
but I ruled against that (see <a href="#no-policy">rationale</a>).
|
||||
</p>
|
||||
|
||||
<p>If you are interested about
|
||||
<a href="doc/minmax_benchs.html">performance</a>,
|
||||
you will see that <tt>minmax_element</tt> is just slightly less efficient
|
||||
than a single <tt>min_element</tt> or <tt>max_element</tt>, and thus
|
||||
twice as efficient as two separate calls to <tt>min_element</tt> and
|
||||
<tt>max_element</tt>. From a
|
||||
theoretical standpoint,
|
||||
all the <tt>minmax_element</tt> functions perform at most
|
||||
<tt>3n/2+1</tt>
|
||||
comparisons and exactly n increments of the
|
||||
<tt>ForwardIterator</tt>.</p>
|
||||
</a>
|
||||
|
||||
<a name="synopsis">
|
||||
<h3>
|
||||
Synopsis of <tt><boost/algorithm/minmax.hpp></tt></h3>
|
||||
|
||||
<pre>#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class T>
|
||||
tuple<T const&, T const&>
|
||||
minmax(const T& a, const T& b);
|
||||
|
||||
template <class T, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
tuple<T const&, T const&>
|
||||
minmax(const T& a, const T& b, BinaryPredicate comp);
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3>
|
||||
Synopsis of <tt><boost/algorithm/minmax_element.hpp></tt></h3>
|
||||
|
||||
<pre>#include <utility> // for std::pair
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
minmax_element(ForwardIterator first, ForwardIterator last);
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>, class <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">BinaryPredicate</a>>
|
||||
std::pair<ForwardIterator,ForwardIterator>
|
||||
minmax_element(ForwardIterator first, ForwardIterator last,
|
||||
BinaryPredicate comp);
|
||||
|
||||
}
|
||||
</pre>
|
||||
|
||||
In addition, there are a bunch of extensions which specify
|
||||
which element(s) you want to pick in case of equal elements. They are:
|
||||
<ul>
|
||||
<li><tt>first_min_element</tt> and <tt>last_min_element</tt></li>
|
||||
<li><tt>first_max_element</tt> and <tt>last_max_element</tt></li>
|
||||
<li><tt>first_min_first_max_element</tt>,
|
||||
<tt>first_min_last_max_element</tt>,
|
||||
<tt>last_min_first_max_element</tt>, and
|
||||
<tt>last_min_last_max_element</tt></li>
|
||||
</ul>
|
||||
I won't bore you with the complete synopsis, they have exactly the same
|
||||
declaration as their corresponding <tt>_element</tt> function. Still,
|
||||
you can find the complete synopsis <a href="doc/minmax_synopsis.html">here</a>.
|
||||
</a>
|
||||
|
||||
<a name="description">
|
||||
<h3>
|
||||
Function templates description</h3>
|
||||
The <tt>minmax</tt> algorithm returns a pair <tt>p</tt> containing either
|
||||
<i>(a,b)</i>
|
||||
or <i>(b,a)</i>, such that <tt>p.first<p.second</tt> in the first version,
|
||||
or <tt>comp(p.first,p.second)</tt> in the second version. If the elements
|
||||
are equivalent, the pair <i>(a,b) </i>is returned. <a href="#Note1">[1]</a>
|
||||
<p>The <tt>minmax_element </tt>is semantically equivalent to <tt>first_min_first_max_element</tt>.
|
||||
<p><tt>First_min_element</tt> and <tt>first_max_element</tt> find the smallest
|
||||
and largest elements in the range <tt>[first, last)</tt>. If there are
|
||||
several instance of these elements, the first one is returned. They are
|
||||
identical to
|
||||
<tt>std::min_element</tt> and <tt>std::max_element</tt>and
|
||||
are only included in this library for symmetry.
|
||||
<p><tt>Last_min_element</tt> and <tt>last_max_element</tt> find the smallest
|
||||
and largest elements in the range <tt>[first, last)</tt>. They are almost
|
||||
identical to
|
||||
<tt>std::min_element</tt> and <tt>std::max_element</tt>, except
|
||||
that they return the last instance of the largest element (and not the
|
||||
first, as <tt>first_min_element</tt> and <tt>last_max_element</tt> would).
|
||||
<p>The family of algorithms comprising <tt>first_min_first_max_element</tt>,
|
||||
<tt>first_min_last_max_element</tt>,
|
||||
<tt>last_min_first_max_element</tt>,
|
||||
and <tt>last_min_last_max_element</tt> can be described generically as
|
||||
follows (using <i><tt>which</tt></i> and
|
||||
<i><tt>what</tt></i> for <tt>first</tt>
|
||||
or <tt>last</tt>): <tt><i>which</i>_min_<i>what</i>_max_element</tt> finds
|
||||
the (first or last, according to <i><tt>which</tt></i>) smallest element
|
||||
and the (first or last, according to <i><tt>what</tt></i>) largest element
|
||||
in the range
|
||||
<tt>[first, last)</tt>. The first version is semantically
|
||||
equivalent to:
|
||||
<pre><tt> std::make_pair(boost::<i>which</i>_min_element(first,last),
|
||||
boost::<i>what</i>_max_element(first,last))</tt>,</pre>
|
||||
and the second version to:
|
||||
<pre><tt> std::make_pair(boost::<i>which</i>_min_element(first,last,comp),
|
||||
boost::<i>what</i>_max_element(first,last,comp))</tt>.</pre>
|
||||
|
||||
<p><br><b><i>Note</i></b>: the <tt>first_min_last_max_element</tt> can also be described
|
||||
as finding the first and last elements in the range if it were stably sorted.
|
||||
</a>
|
||||
|
||||
<a name="definition">
|
||||
<h3>
|
||||
Definition</h3>
|
||||
Defined in <a href="../../../boost/algorithm/minmax.hpp">minmax.hpp</a>
|
||||
and
|
||||
in <a href="../../../boost/algorithm/minmax_element.hpp">minmax_element.hpp</a>.
|
||||
</a>
|
||||
|
||||
<a name="reqs">
|
||||
<h3>
|
||||
Requirements on types</h3>
|
||||
For minmax, <tt>T</tt> must be a model of <a href="http://www.sgi.com/tech/stl/LessThanComparable.html">LessThan
|
||||
Comparable</a>.
|
||||
<p>For all the other function templates, versions with two template parameters:
|
||||
<ul>
|
||||
<li>
|
||||
<tt>ForwardIterator</tt> is a model of <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
|
||||
Iterator</a>.</li>
|
||||
|
||||
<li>
|
||||
<tt>ForwardIterator</tt>'s value type is <a href="http://www.sgi.com/tech/stl/LessThanComparable.html">LessThan
|
||||
Comparable</a>.</li>
|
||||
</ul>
|
||||
For the versions with three template parameters:
|
||||
<ul>
|
||||
<li>
|
||||
<tt>ForwardIterator</tt> is a model of <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
|
||||
Iterator</a>.</li>
|
||||
|
||||
<li>
|
||||
<tt>BinaryPredicate</tt> is a model of <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">Binary
|
||||
Predicate</a>.</li>
|
||||
|
||||
<li>
|
||||
<tt>ForwardIterator</tt>'s value type is convertible to <tt>BinaryPredicate</tt>'s
|
||||
first argument type and second argument type.</li>
|
||||
</ul>
|
||||
</a>
|
||||
|
||||
<a name="precond">
|
||||
<h3>
|
||||
Preconditions</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<tt>[first, last)</tt> is a valid range.</li>
|
||||
</ul>
|
||||
</a>
|
||||
|
||||
<a name="postcond">
|
||||
<h3>
|
||||
Postconditions</h3>
|
||||
In addition to the semantic description above. for <tt>minmax_element</tt>
|
||||
and all the <tt><i>which</i>_min_<i>what</i>_max_element</tt>
|
||||
variants, the return value is
|
||||
<tt>last</tt> or <tt>std::make_pair(last,last)</tt>
|
||||
if and only if <tt>[first, last)</tt> is an empty range. Otherwise, the
|
||||
return value or both members of the resulting pair are iterators in the
|
||||
range
|
||||
<tt>[first, last)</tt>.
|
||||
</a>
|
||||
|
||||
<a name="complexity">
|
||||
<h3>
|
||||
Complexity</h3>
|
||||
Minmax performs a single comparison and is otherwise of constant complexity.
|
||||
The use of <tt>boost::tuple<T const&></tt> prevents copy
|
||||
constructors in case the arguments are passed by reference.
|
||||
<p>The complexity of all the other algorithms is linear. They all perform
|
||||
exactly n increment operations, and zero comparisons if <tt>[first,last)</tt>
|
||||
is empty, otherwise :
|
||||
<ul>
|
||||
<li>
|
||||
all the <tt>min_element</tt> and <tt>max_element</tt> variants perform
|
||||
exactly<tt>(n-1)</tt> comparisons,</li>
|
||||
|
||||
<li>
|
||||
<tt>minmax_element</tt> , <tt>first_min_first_max_element</tt>, and <tt>last_min_last_max_element</tt>
|
||||
perform at most <tt>3(n/2)-1</tt> comparisons if <tt>n</tt> is even and
|
||||
non-zero, and at most <tt>3(n/2)+1</tt> if <tt>n</tt> is odd,
|
||||
<a href="#Note2">[2]</a></li>
|
||||
|
||||
<li>
|
||||
<tt>first_min_last_max_element</tt>, and <tt>last_min_first_max_element</tt>
|
||||
perform exactly <tt>3n/2-2</tt> comparisons if n is even and non-zero,
|
||||
and at most <tt>3(n/2)</tt> if <tt>n</tt> is odd,
|
||||
<a href="#Note1">[3]</a></li>
|
||||
</ul>
|
||||
where <tt>n</tt> is the number of elements in <tt>[first,last)</tt>.
|
||||
</a>
|
||||
|
||||
<a name="example">
|
||||
<h3>
|
||||
Example</h3>
|
||||
This example is included in the distribution in the examples section of
|
||||
the library under
|
||||
<a href="example/minmax_ex.cpp">minmax_ex.cpp</a>.
|
||||
|
||||
<pre>int main()
|
||||
{
|
||||
using namespace std;
|
||||
boost::tuple<int const&, int const&> result1 = boost::minmax(1, 0);
|
||||
|
||||
assert( result1.get<0>() == 0 );
|
||||
assert( result1.get<1>() == 1 );
|
||||
|
||||
<a href="http://www.sgi.com/tech/stl/List.html">list</a><int> L;
|
||||
<a href="http://www.sgi.com/tech/stl/generate_n.html">generate_n</a>(<a href="http://www.sgi.com/tech/stl/front_insert_iterator.html">front_inserter</a>(L), 1000, rand);
|
||||
|
||||
typedef list<int>::const_iterator iterator;
|
||||
pair< iterator, iterator > result2 = boost::minmax_element(L.begin(), L.end());
|
||||
cout << "The smallest element is " << *(result2.first) << endl;
|
||||
cout << "The largest element is " << *(result2.second) << endl;
|
||||
|
||||
assert( result2.first == std::min_element(L.begin(), L.end());
|
||||
assert( result2.second == std::max_element(L.begin(), L.end());
|
||||
}</pre>
|
||||
</a>
|
||||
|
||||
<a name="notes">
|
||||
<h3>
|
||||
Notes</h3>
|
||||
<a NAME="Note1"></a><a href="#Note1">[1]</a> We do not support
|
||||
idioms such as <tt><a href="../../tuple/doc/tuple_users_guide.html#tiers">tie</a>(a,b)=minmax(a,b)</tt>
|
||||
to order two elements <tt>a</tt>, <tt>b</tt>, although this would have
|
||||
the desired effect if we returned a reference instead of a constant
|
||||
reference. The reason is that two unnecessary assignments are
|
||||
performed if a and b are in order. It is better to stick to <tt>if (b<a)
|
||||
swap(a,b)</tt> to achieve that effect.
|
||||
<p><a NAME="Note2"></a><a href="#Note2">[2]</a> These algorithms always
|
||||
perform at least <tt>3n/2-2</tt> comparisons, which is a lower bound on
|
||||
the number of comparisons in any case (Cormen, Leiserson, Rivest: "Introduction
|
||||
to Algorithms", section 9.1, Exercise 9.1-). The algorithms essentially compare
|
||||
the elements in pairs, performing 1 comparison for the first two elements,
|
||||
then 3 comparisons for each remaining pair of elements (one to order the
|
||||
elements and one for updating each the minimum and and the maximum). When
|
||||
the number of elements is odd, the last one needs to be compared to the
|
||||
current minimum and also to the current maximum. In addition, for <tt>minmax</tt>,
|
||||
in cases where equality of the two members in the pair could occur, and
|
||||
the update stores the second, we save the first to check at the end if
|
||||
the update should have stored the first (in case of equality). It's hard
|
||||
to predict if the last comparison is performed or not, hence the at most
|
||||
in both cases.
|
||||
<p><a NAME="Note3"></a><a href="#Note3">[3]</a> These algorithms always
|
||||
perform at least <tt>3n/2-2</tt> comparisons, which is a lower bound on
|
||||
the number of comparisons in any case. The method is the same as in note
|
||||
<a href="#Note2">[2]</a>
|
||||
above, and like above, when the number of elements is odd, the last one
|
||||
needs to be compared to the current minimum and also to the current maximum.
|
||||
We can avoid the latter comparison if the former is successful, hence the
|
||||
<i>at
|
||||
most</i> instead of <i>exactly</i> in the odd case.
|
||||
</a>
|
||||
|
||||
<a name="rationale">
|
||||
<h3>
|
||||
<b>Rationale:</b></h3>
|
||||
|
||||
<a name="two_headers">
|
||||
<h4><b>Why not a single header <tt><boost/algorithm/minmax.hpp></tt>?</b></h4>
|
||||
<p>This was the design originally proposed and approved in the formal
|
||||
review. As the need for Boost.tuple became clear (due to the limitations
|
||||
of <tt>std::pair</tt>), it became also annoying to require another
|
||||
library for <tt>minmax_element</tt> which does not need it. Hence the
|
||||
separation into two header files.</p>
|
||||
|
||||
<a name="no-fix">
|
||||
<h4><b>Your minmax suffers from the same problems as std::min and
|
||||
std::max.</b></h4>
|
||||
<p>I am aware of the problems with std::min and
|
||||
std::max, and all the debate that has been going on (please consult
|
||||
<a href="http://www.cuj.com/documents/s=7996/cujcexp1904alexandr/alexandr.htm">Alexandrescu's paper</a> and the links therein). But I don't see the purpose of this
|
||||
library as fixing something that is part of the C++ standard. I humbly
|
||||
think it's beyond the scope of this library. Rather, I am
|
||||
following the way of the standard in simply providing one more function
|
||||
of the same family. If someone else wants to fix std::min, their fix
|
||||
would probably apply to boost::minmax as well.</p>
|
||||
</a>
|
||||
|
||||
<h4><b>Why no <tt>min/max_element_if</tt>?</b></h4>
|
||||
<p>In a first version of the library, I proposed <tt>_if</tt> versions of
|
||||
all the algorithms (well, not all, because that would be too much).
|
||||
However, there is simply no reason to do so, and all the versions I had
|
||||
were just as fast implemented using the excellent
|
||||
<tt><boost/iterator_adaptors.hpp></tt> library. Namely, a call to
|
||||
<tt>min_element_if(first, last, pred)</tt> would be just as well
|
||||
implemented by:
|
||||
<pre>
|
||||
// equivalent to min_element_if(first, last, pred)
|
||||
min_element(boost::make_filter_iterator(first, last, pred),
|
||||
boost::make_filter_iterator(last, last, pred));
|
||||
</pre>
|
||||
Arguably, the <tt>min_element_if</tt> version is somewhat shorter, but
|
||||
the overhead of iterator adaptors is not large, and they get rid of a
|
||||
lot of code (think of all the combinations between first/last and
|
||||
doubling them with _if variants!).</p>
|
||||
|
||||
<h4><b>Discussion: about std::max_element</b></h4>
|
||||
<p>This rationale is somewhat historical, but explains why there are all
|
||||
these <tt>first/last_min/max_element</tt> functions.</p>
|
||||
<p>The C++ standard mandates that <tt>std::min_element</tt> and <tt>std::max_element</tt>
|
||||
return the first instance of the smallest and largest elements (as opposed
|
||||
to, say, the last). This arbitrary choice has some consistency: In the
|
||||
case of v of type vector<int>, for instance, it is true that <tt>std::min_element(v.begin(),v.end(),std::less<int>())
|
||||
== std::max_element(v.begin(),v.end(),std::greater<int>())</tt>.
|
||||
<p>There is of course nothing wrong with this: it's simply a matter of
|
||||
choice. Yet another way to specify min_element and max_element is to define
|
||||
them as the first and the last elements if the range was stably sorted.
|
||||
(The <i>stable</i> sort is necessary to disambiguate between iterators
|
||||
that have the same value.) In that case, min should return the first instance
|
||||
and max should return the last. Then, both functions are related by
|
||||
<tt>reverse_iterator(std::first_min_element(v.begin(),v.end(),std::less<int>()))
|
||||
==
|
||||
std::last_max_element(v.rbegin(),v.rend(),std::greater<int>())</tt>.
|
||||
This definition is subtly different from the previous one.</p>
|
||||
<p>The definition problem surfaces when one tries to design a minmax_element,
|
||||
using the procedure proposed in (Cormen, Leiserson, Rivest: "Introduction
|
||||
to Algorithms", section 9.1). It <i>should</i> be possible to derive an
|
||||
algorithm using only <tt>3n/2</tt> comparisons if <tt>[first,last) </tt>has
|
||||
<tt>n</tt>
|
||||
elements, but if one tries to write a function called <tt>first_min_first_max_element()</tt>
|
||||
which returns both <tt>std::min_element</tt> and <tt>std::max_element</tt>
|
||||
in a pair, the trivial implementation does not work. The problem, rather
|
||||
subtly, is about equal elements: I had to think for a while to find a
|
||||
way to perform only three
|
||||
comparisons per pair and return the first min and first max elements.
|
||||
For a long time, it seemed any
|
||||
attempts at doing so would consume four comparisons per pair in the worst
|
||||
case. This implementation achieves three.</p>
|
||||
<p>It is not possible (or even desirable) to change the meaning of
|
||||
<tt>max_element</tt>,
|
||||
but it is still beneficial to provide a function called <tt>minmax_element</tt>,
|
||||
which returns a pair of <tt>min_element</tt> and <tt>max_element</tt>.
|
||||
Although it is easy enough to call <tt>min_element</tt> and <tt>max_element</tt>,
|
||||
this performs
|
||||
<tt>2(n-1)</tt> comparisons, and necessitates <b>two</b>
|
||||
passes over the input. In contrast,
|
||||
<tt>minmax_element</tt> will perform
|
||||
the fewer comparisons and perform a <b>single</b> pass over the input.
|
||||
The savings can be significant when the iterator type is not a raw pointer,
|
||||
or even is just a model of the InputIterator concept (although in that
|
||||
case the interface would have to be
|
||||
changed, as the return type could not be copied, so one could e.g.
|
||||
return a value).</p>
|
||||
<p>In order to benefit from all the variants of the algorithm, I propose
|
||||
to introduce both <tt>first_min_element</tt> and <tt>last_min_element</tt>,
|
||||
and their counterparts <tt>first_max_element</tt> and <tt>last_max_element</tt>.
|
||||
Then I also propose all the variants algorithms: <tt>first_min_last_max_element</tt>
|
||||
and <tt>last_min_first_max_element</tt>, which perform only at most <tt>3n/2</tt>
|
||||
comparisons, and only a single pass on the input. In fact, it can be proven
|
||||
that computing minmax requires at least <tt>3(n/2)-2</tt> comparisons in
|
||||
any instance of the problem (Cormen, Leiserson, Rivest, 2nd edition, section
|
||||
9.1). The implementation I give does not perform unnecessary comparisons
|
||||
(whose result could have been computed by transitivity from previous
|
||||
comparisons).</p>
|
||||
<p>It appears that <tt>first_min_last_max_element</tt> may be just a tad
|
||||
slower than
|
||||
<tt>first_min_element</tt> alone, still much less than <tt>first_min_element</tt>
|
||||
and
|
||||
<tt>last_max_element</tt> called separately. <a href="#Note2">[2]</a>
|
||||
|
||||
<h4><b>Why algorithms and not accumulators?</b></h4>
|
||||
<p>The minmax algorithms are useful in computing the extent of a range.
|
||||
In computer graphics, we need a bounding box of a set of objects.
|
||||
In that case the need for a single pass is even more stringent
|
||||
as all three directions must be done at once. Food for thoughts: there
|
||||
is matter for a nice generic programming library with stackable <tt>update_min</tt>
|
||||
and <tt>update_max</tt> function objects which store a reference to the
|
||||
<tt>min_result</tt>and
|
||||
<tt>max_result</tt> variables, in conjunction with the <tt>for_each</tt>
|
||||
algorithm).</p>
|
||||
<p>I believe many standard sequential algorithms could be reformulated
|
||||
with accumulators (and many others, such as in statistics, expectation /
|
||||
variance / etc.). It seems that there is room for another library, but I
|
||||
do not see it competing with minmax, rather extending several algorithms
|
||||
(including minmax) to the accumulator framework. However, I felt it is
|
||||
beyond the scope of this library to provide such accumulators.</p>
|
||||
|
||||
<a NAME="no-policy">
|
||||
<h4><b>This first/last is a perfect application for a policy-based
|
||||
design.</b></h4>
|
||||
<p>True, and I could have gone that way, with the default policy for
|
||||
<tt>min_element</tt> and <tt>max_element</tt> to pick the first
|
||||
occurence of the result. This would have thinned the number of
|
||||
combinations of the minmax_element variants. But it would also have
|
||||
meant to change the interface of <tt>boost::minmax_element</tt>.
|
||||
One of the goals of the <tt>minmax_element</tt> algorithm is its
|
||||
eventual addition to the C++ standard, in connection with
|
||||
<tt>std::min_element</tt> and <tt>std::max_element</tt>
|
||||
(and I feel that it would be quite natural
|
||||
given the shortness of the implementation, and the not quite trivial
|
||||
detail which is needed to get it right). So changing the interface by
|
||||
adding policies would have meant unfortunately to depart from the
|
||||
standard and created an obstacle towards that goal. Besides, the code
|
||||
remains rather readable and simple without policies. So I am quite happy
|
||||
to keep it like this.
|
||||
</p></a>
|
||||
</a>
|
||||
|
||||
<a name="perf">
|
||||
<a href="doc/minmax_benchs.html"><h3><b>About performance</b></h3></a>
|
||||
</a>
|
||||
|
||||
<a name="acks">
|
||||
<h3>
|
||||
Acknowledgements</h3>
|
||||
My students in CS903 (Polytechnic Univ., <a href="http://photon.poly.edu/~hbr/cs903/">http://photon.poly.edu/~hbr/cs903/</a>)
|
||||
who had <tt>minmax_element</tt> as an assignment helped clarify the issues,
|
||||
and also come up with the optimum number of comparisons for <tt>first_min_last_max_element</tt>.
|
||||
The identification of the issue surrounding <tt>max_element</tt> is solely
|
||||
my own.
|
||||
<p>One <tt>minmax_element</tt> implementation, which performs <tt>3(n/2)+O(log
|
||||
n)</tt> comparisons on the average when the elements are <tt>random_shuffle</tt>d,
|
||||
was suggested by my student Marc Glisse. The current one, which performs
|
||||
<tt>3(n/2)+1</tt>
|
||||
comparisons in the worst case, was suggested by John Iacono.<p>
|
||||
<p>Finally, Matthew Wilson and Jeremy Siek contributed pre-review
|
||||
comments, while Gennadiy Rozental, John Maddock, Craig Henderson, Gary
|
||||
Powell participated in the review of the library, managed by Thomas
|
||||
Witt. In particular, Gennadiy suggested a factorization of the code;
|
||||
while I haven't followed it all the way, his suggestions do make the
|
||||
code more readable and still work with older compilers.
|
||||
Late after the review, as I finally scrounged to add the library for a
|
||||
release, Eric Niebler noted the bad behavior of <tt>std::pair</tt> for
|
||||
<tt>minmax</tt> and suggested to use Boost.tuple instead.
|
||||
All my thanks for the excellent advice and reviews from all.
|
||||
<h3>
|
||||
See also</h3>
|
||||
<tt><a href="http://www.sgi.com/tech/stl/min.html">min</a></tt>, <tt><a href="http://www.sgi.com/tech/stl/max.html">max</a></tt>,
|
||||
<tt><a href="http://www.sgi.com/tech/stl/min_element.html">min_element</a></tt>,
|
||||
<tt><a href="http://www.sgi.com/tech/stl/max_element.html">max_element</a></tt>,
|
||||
<tt><a href="http://www.sgi.com/tech/stl/LessThanComparable.html">LessThan
|
||||
Comparable</a></tt>,
|
||||
<tt><a href="http://www.sgi.com/tech/stl/sort.html">sort</a></tt>,
|
||||
<tt><a href="http://www.sgi.com/tech/stl/nth_element.html">nth_element</a></tt>
|
||||
.
|
||||
<hr SIZE="6">
|
||||
<br>Last modified 2004-07-01
|
||||
<p><font face="Arial,Helvetica"><font size=-1>© Copyright Hervé
|
||||
Brönnimann, Polytechnic University, 2002--2004.
|
||||
Use, modification, and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">License_1_0.txt</a> or copy at
|
||||
<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</font></font>
|
||||
</body>
|
||||
</html>
|
@ -1,20 +0,0 @@
|
||||
# Boost.Minmax Library test Jamfile
|
||||
#
|
||||
# Copyright (C) 2002--2004, Herve Bronnimann
|
||||
#
|
||||
# Use, modification, and distribution is subject to 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)
|
||||
#
|
||||
|
||||
import testing ;
|
||||
|
||||
{
|
||||
test-suite algorithm/minmax:
|
||||
: [ run minmax_element_test.cpp
|
||||
: : : : minmax_element ]
|
||||
[ run minmax_test.cpp
|
||||
: : : : minmax ]
|
||||
;
|
||||
}
|
||||
|
@ -1,241 +0,0 @@
|
||||
// (C) Copyright Herve Bronnimann 2004.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <boost/config.hpp> /* prevents some nasty warns in MSVC */
|
||||
#include <boost/algorithm/minmax_element.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
|
||||
class custom {
|
||||
int m_x;
|
||||
friend bool operator<(custom const& x, custom const& y);
|
||||
public:
|
||||
explicit custom(int x = 0) : m_x(x) {}
|
||||
custom(custom const& y) : m_x(y.m_x) {}
|
||||
custom operator+(custom const& y) const { return custom(m_x+y.m_x); }
|
||||
custom& operator+=(custom const& y) { m_x += y.m_x; return *this; }
|
||||
};
|
||||
|
||||
bool operator< (custom const& x, custom const& y)
|
||||
{
|
||||
return x.m_x < y.m_x;
|
||||
}
|
||||
|
||||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(custom)
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct iterator_traits<int*> {
|
||||
typedef random_access_iterator_tag iterator_category;
|
||||
typedef int value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_traits<custom*> {
|
||||
typedef random_access_iterator_tag iterator_category;
|
||||
typedef custom value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
void tie(std::pair<T1, T2> p, T3& first, T4& second)
|
||||
{
|
||||
first = T3(p.first); second = T4(p.second);
|
||||
}
|
||||
|
||||
template <class Value>
|
||||
struct less_count : std::less<Value> {
|
||||
typedef std::less<Value> Base;
|
||||
less_count(less_count<Value> const& lc) : m_counter(lc.m_counter) {}
|
||||
less_count(int& counter) : m_counter(counter) {}
|
||||
bool operator()(Value const& a, Value const& b) const {
|
||||
++m_counter;
|
||||
return Base::operator()(a,b);
|
||||
}
|
||||
void reset() {
|
||||
m_counter = 0;
|
||||
}
|
||||
private:
|
||||
int& m_counter;
|
||||
};
|
||||
|
||||
inline int opt_min_count(int n) {
|
||||
return (n==0) ? 0 : n-1;
|
||||
}
|
||||
inline int opt_minmax_count(int n) {
|
||||
if (n < 2) return 0;
|
||||
if (n == 2) return 2;
|
||||
return (n%2 == 0) ? 3*(n/2)-1 : 3*(n/2)+1;
|
||||
}
|
||||
inline int opt_boost_minmax_count(int n) {
|
||||
if (n < 2) return 0;
|
||||
if (n == 2) return 1;
|
||||
return (n%2 == 0) ? 3*(n/2)-2 : 3*(n/2);
|
||||
}
|
||||
|
||||
#define CHECK_EQUAL_ITERATORS( left, right, first ) \
|
||||
BOOST_CHECK_EQUAL( std::distance( first, left ), std::distance( first, right ) )
|
||||
|
||||
template <class CIterator>
|
||||
void test_minmax(CIterator first, CIterator last, int n)
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef typename std::iterator_traits<CIterator>::value_type Value;
|
||||
typedef boost::reverse_iterator<CIterator> RCIterator;
|
||||
// assume that CIterator is BidirectionalIter
|
||||
CIterator min, max;
|
||||
RCIterator rfirst(last), rlast(first), rmin, rmax;
|
||||
int counter = 0;
|
||||
less_count<Value> lc(counter);
|
||||
|
||||
// standard extensions
|
||||
// first version, operator<
|
||||
tie( boost::minmax_element(first, last), min, max );
|
||||
|
||||
CHECK_EQUAL_ITERATORS( min, std::min_element(first, last), first );
|
||||
CHECK_EQUAL_ITERATORS( max, std::max_element(first, last), first );
|
||||
|
||||
// second version, comp function object (keeps a counter!)
|
||||
lc.reset();
|
||||
tie( boost::minmax_element(first, last, lc), min, max );
|
||||
BOOST_CHECK( counter <= opt_minmax_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( min, std::min_element(first, last, lc), first );
|
||||
CHECK_EQUAL_ITERATORS( max, std::max_element(first, last, lc), first );
|
||||
|
||||
// boost extensions
|
||||
// first version, operator<
|
||||
CHECK_EQUAL_ITERATORS( boost::first_min_element(first, last), std::min_element(first, last), first );
|
||||
rmin = RCIterator(boost::last_min_element(first, last));
|
||||
rmin = (rmin == rfirst) ? rlast : --rmin;
|
||||
CHECK_EQUAL_ITERATORS( rmin, std::min_element(rfirst, rlast), rfirst );
|
||||
CHECK_EQUAL_ITERATORS( boost::first_max_element(first, last), std::max_element(first, last), first );
|
||||
rmax = RCIterator(boost::last_max_element(first, last));
|
||||
rmax = (rmax == rfirst) ? rlast : --rmax;
|
||||
CHECK_EQUAL_ITERATORS( rmax, std::max_element(rfirst, rlast), rfirst );
|
||||
tie( boost::first_min_last_max_element(first, last), min, max );
|
||||
CHECK_EQUAL_ITERATORS( min, boost::first_min_element(first, last), first );
|
||||
CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last), first );
|
||||
tie( boost::last_min_first_max_element(first, last), min, max );
|
||||
CHECK_EQUAL_ITERATORS( min, boost::last_min_element(first, last), first );
|
||||
CHECK_EQUAL_ITERATORS( max, boost::first_max_element(first, last), first );
|
||||
tie( boost::last_min_last_max_element(first, last), min, max );
|
||||
CHECK_EQUAL_ITERATORS( min, boost::last_min_element(first, last), first );
|
||||
CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last), first );
|
||||
|
||||
// second version, comp function object (keeps a counter!)
|
||||
lc.reset();
|
||||
min = boost::first_min_element(first, last, lc);
|
||||
BOOST_CHECK( counter <= opt_min_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( min, std::min_element(first, last, lc), first );
|
||||
lc.reset();
|
||||
rmin = RCIterator(boost::last_min_element(first, last, lc));
|
||||
rmin = (rmin == rfirst) ? rlast : --rmin;
|
||||
BOOST_CHECK( counter <= opt_min_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( rmin, std::min_element(rfirst, rlast, lc), rfirst );
|
||||
lc.reset();
|
||||
max = boost::first_max_element(first, last, lc);
|
||||
BOOST_CHECK( counter <= opt_min_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( max, std::max_element(first, last, lc), first );
|
||||
lc.reset();
|
||||
rmax = RCIterator(boost::last_max_element(first, last, lc));
|
||||
rmax = (rmax == rfirst) ? rlast : --rmax;
|
||||
BOOST_CHECK( counter <= opt_min_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( rmax, std::max_element(rfirst, rlast, lc), rfirst );
|
||||
lc.reset();
|
||||
tie( boost::first_min_last_max_element(first, last, lc), min, max );
|
||||
BOOST_CHECK( counter <= opt_boost_minmax_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( min, boost::first_min_element(first, last, lc), first );
|
||||
CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last, lc), first );
|
||||
lc.reset();
|
||||
tie( boost::last_min_first_max_element(first, last, lc), min, max );
|
||||
BOOST_CHECK( counter <= opt_boost_minmax_count(n) );
|
||||
BOOST_CHECK( min == boost::last_min_element(first, last, lc) );
|
||||
CHECK_EQUAL_ITERATORS( max, boost::first_max_element(first, last, lc), first );
|
||||
lc.reset();
|
||||
tie( boost::last_min_last_max_element(first, last, lc), min, max );
|
||||
BOOST_CHECK( counter <= opt_minmax_count(n) );
|
||||
CHECK_EQUAL_ITERATORS( min, boost::last_min_element(first, last, lc), first );
|
||||
CHECK_EQUAL_ITERATORS( max, boost::last_max_element(first, last, lc), first );
|
||||
}
|
||||
|
||||
template <class Container, class Iterator, class Value>
|
||||
void test_container(Iterator first, Iterator last, int n,
|
||||
Container* dummy = 0
|
||||
BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Value) )
|
||||
{
|
||||
Container c(first, last);
|
||||
test_minmax(c.begin(), c.end(), n);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
void test_range(Iterator first, Iterator last, int n)
|
||||
{
|
||||
typedef typename std::iterator_traits<Iterator>::value_type Value;
|
||||
// Test various containers with these values
|
||||
test_container< std::vector<Value>, Iterator, Value >(first, last, n);
|
||||
test_container< std::list<Value>, Iterator, Value >(first, last, n);
|
||||
test_container< std::set<Value>, Iterator, Value >(first, last, n);
|
||||
}
|
||||
|
||||
template <class Value>
|
||||
void test(int n BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Value))
|
||||
{
|
||||
// Populate test vector with identical values
|
||||
std::vector<Value> test_vector(n, Value(1));
|
||||
typename std::vector<Value>::iterator first( test_vector.begin() );
|
||||
typename std::vector<Value>::iterator last( test_vector.end() );
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with two values
|
||||
typename std::vector<Value>::iterator middle( first + n/2 );
|
||||
std::fill(middle, last, Value(2));
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with increasing values
|
||||
std::accumulate(first, last, Value(0));
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with decreasing values
|
||||
std::reverse(first, last);
|
||||
test_range(first, last, n);
|
||||
|
||||
// Populate test vector with random values
|
||||
std::random_shuffle(first, last);
|
||||
test_range(first, last, n);
|
||||
}
|
||||
|
||||
int test_main( int argc, char* argv[] )
|
||||
{
|
||||
#ifndef BOOST_NO_STDC_NAMESPACE
|
||||
using std::atoi;
|
||||
#endif
|
||||
|
||||
int n = 100;
|
||||
if (argc > 1) n = atoi(argv[1]);
|
||||
|
||||
test<int>(n);
|
||||
test<custom>(n);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
// (C) Copyright Herve Bronnimann 2004.
|
||||
// Use, modification and distribution are subject to 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)
|
||||
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/algorithm/minmax.hpp>
|
||||
#include <boost/test/included/test_exec_monitor.hpp>
|
||||
|
||||
class custom {
|
||||
int m_x;
|
||||
friend std::ostream& operator<<(std::ostream& str, custom const& x);
|
||||
public:
|
||||
explicit custom(int x = 0) : m_x(x) {}
|
||||
custom(custom const& y) : m_x(y.m_x) {}
|
||||
bool operator==(custom const& y) const { return m_x == y.m_x; }
|
||||
bool operator<(custom const& y) const { return m_x < y.m_x; }
|
||||
custom operator+(custom const& y) const { return custom(m_x+y.m_x); }
|
||||
custom& operator+=(custom const& y) { m_x += y.m_x; return *this; }
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& str, custom const& x)
|
||||
{
|
||||
return str << x.m_x;
|
||||
}
|
||||
|
||||
template <class Value>
|
||||
struct less_count : std::less<Value> {
|
||||
typedef std::less<Value> Base;
|
||||
less_count(less_count<Value> const& lc) : m_counter(lc.m_counter) {}
|
||||
less_count(int& counter) : m_counter(counter) {}
|
||||
bool operator()(Value const& a, Value const& b) const {
|
||||
++m_counter;
|
||||
return Base::operator()(a,b);
|
||||
}
|
||||
void reset() {
|
||||
m_counter = 0;
|
||||
}
|
||||
private:
|
||||
int& m_counter;
|
||||
};
|
||||
|
||||
using namespace boost;
|
||||
|
||||
template <class Value>
|
||||
void test(BOOST_EXPLICIT_TEMPLATE_TYPE(Value))
|
||||
{
|
||||
Value zero(0), one(1);
|
||||
int counter = 0;
|
||||
less_count<Value> lc(counter);
|
||||
|
||||
// Test functionality
|
||||
tuple<Value const&, Value const&> result1 = boost::minmax(zero, one);
|
||||
BOOST_CHECK_EQUAL( get<0>(result1), zero );
|
||||
BOOST_CHECK_EQUAL( get<1>(result1), one );
|
||||
|
||||
tuple<Value const&, Value const&> result2 = boost::minmax(one, zero);
|
||||
BOOST_CHECK_EQUAL( get<0>(result2), zero );
|
||||
BOOST_CHECK_EQUAL( get<1>(result2), one );
|
||||
|
||||
// Test functionality and number of comparisons
|
||||
lc.reset();
|
||||
tuple<Value const&, Value const&> result3 = boost::minmax(zero, one, lc );
|
||||
BOOST_CHECK_EQUAL( get<0>(result3), zero );
|
||||
BOOST_CHECK_EQUAL( get<1>(result3), one );
|
||||
BOOST_CHECK_EQUAL( counter, 1 );
|
||||
|
||||
lc.reset();
|
||||
tuple<Value const&, Value const&> result4 = boost::minmax(one, zero, lc );
|
||||
BOOST_CHECK_EQUAL( get<0>(result4), zero );
|
||||
BOOST_CHECK_EQUAL( get<1>(result4), one );
|
||||
BOOST_CHECK_EQUAL( counter, 1);
|
||||
}
|
||||
|
||||
int test_main( int , char* [] )
|
||||
{
|
||||
test<int>(); // ("builtin");
|
||||
test<custom>(); // ("custom ");
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
# Boost string_algo library documentation Jamfile ---------------------------------
|
||||
#
|
||||
# Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
# distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
import toolset ;
|
||||
toolset.using doxygen ;
|
||||
|
||||
boostbook string_algo : string_algo.xml autodoc
|
||||
:
|
||||
<xsl:param>boost.root=../../../../..
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
|
||||
;
|
||||
|
||||
doxygen autodoc
|
||||
:
|
||||
[ glob ../../../../boost/algorithm/string.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string_regex.hpp ]
|
||||
|
||||
[ glob ../../../../boost/algorithm/string/classification.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/iterator_range.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/sequence_traits.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/std_containers_traits.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/concept.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/compare.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/constants.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/case_conv.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/find.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/finder.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/find_iterator.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/trim.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/predicate.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/split.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/iter_find.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/erase.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/join.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/replace.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/find_format.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/formatter.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/regex.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/regex_find_format.hpp ]
|
||||
[ glob ../../../../boost/algorithm/string/trim_all.hpp ]
|
||||
:
|
||||
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
|
||||
<doxygen:param>EXTRACT_PRIVATE=NO
|
||||
<doxygen:param>ENABLE_PREPROCESSING=YES
|
||||
<doxygen:param>MACRO_EXPANSION=YES
|
||||
<doxygen:param>EXPAND_ONLY_PREDEF=YES
|
||||
<doxygen:param>SEARCH_INCLUDES=YES
|
||||
<doxygen:param>PREDEFINED="BOOST_STRING_TYPENAME=typename \"BOOST_STATIC_CONSTANT(type,var)=static const type var;\""
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
@ -1,205 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.concept" last-revision="$Date$">
|
||||
<title>Concepts</title>
|
||||
|
||||
<using-namespace name="boost"/>
|
||||
<using-namespace name="boost::algorithm"/>
|
||||
|
||||
<section>
|
||||
<title>Definitions</title>
|
||||
|
||||
<table>
|
||||
<title>Notation</title>
|
||||
<tgroup cols="2" align="left">
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>F</code></entry>
|
||||
<entry>A type that is a model of Finder</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>Fmt</code></entry>
|
||||
<entry>A type that is a model of Formatter</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>Iter</code></entry>
|
||||
<entry>
|
||||
Iterator Type
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>f</code></entry>
|
||||
<entry>Object of type <code>F</code></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>fmt</code></entry>
|
||||
<entry>Object of type <code>Fmt</code></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>i,j</code></entry>
|
||||
<entry>Objects of type <code>Iter</code></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section id="string_algo.finder_concept">
|
||||
<title>Finder Concept</title>
|
||||
|
||||
<para>
|
||||
Finder is a functor which searches for an arbitrary part of a container.
|
||||
The result of the search is given as an <classname>iterator_range</classname>
|
||||
delimiting the selected part.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title>Valid Expressions</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Expression</entry>
|
||||
<entry>Return Type</entry>
|
||||
<entry>Effects</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>f(i,j)</code></entry>
|
||||
<entry>Convertible to <code>iterator_range<Iter></code></entry>
|
||||
<entry>Perform the search on the interval [i,j) and returns the result of the search</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
Various algorithms need to perform a search in a container and a Finder is a generalization of such
|
||||
search operations that allows algorithms to abstract from searching. For instance, generic replace
|
||||
algorithms can replace any part of the input, and the Finder is used to select the desired one.
|
||||
</para>
|
||||
<para>
|
||||
Note, that it is only required that the finder works with a particular iterator type. However,
|
||||
a Finder operation can be defined as a template, allowing the Finder to work with any iterator.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis role="bold">Examples</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
Finder implemented as a class. This Finder always returns the whole input as a match. <code>operator()</code>
|
||||
is templated, so that the finder can be used on any iterator type.
|
||||
|
||||
<programlisting>
|
||||
struct simple_finder
|
||||
{
|
||||
template<typename ForwardIteratorT>
|
||||
boost::iterator_range<ForwardIteratorT> operator()(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End )
|
||||
{
|
||||
return boost::make_range( Begin, End );
|
||||
}
|
||||
};
|
||||
</programlisting>
|
||||
</listitem>
|
||||
<listitem>
|
||||
Function Finder. Finder can be any function object. That is, any ordinary function with the
|
||||
required signature can be used as well. However, such a function can be used only for
|
||||
a specific iterator type.
|
||||
|
||||
<programlisting>
|
||||
boost::iterator_range<std::string> simple_finder(
|
||||
std::string::const_iterator Begin,
|
||||
std::string::const_iterator End )
|
||||
{
|
||||
return boost::make_range( Begin, End );
|
||||
}
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
<section id="string_algo.formatter_concept">
|
||||
<title>Formatter concept</title>
|
||||
|
||||
<para>
|
||||
Formatters are used by <link linkend="string_algo.replace">replace algorithms</link>.
|
||||
They are used in close combination with finders.
|
||||
A formatter is a functor, which takes a result from a Finder operation and transforms it in a specific way.
|
||||
The operation of the formatter can use additional information provided by a specific finder,
|
||||
for example <functionname>regex_formatter()</functionname> uses the match information from
|
||||
<functionname>regex_finder()</functionname> to format the result of formatter operation.
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title>Valid Expressions</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Expression</entry>
|
||||
<entry>Return Type</entry>
|
||||
<entry>Effects</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>fmt(f(i,j))</code></entry>
|
||||
<entry>A container type, accessible using container traits</entry>
|
||||
<entry>Formats the result of the finder operation</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
Similarly to finders, formatters generalize format operations. When a finder is used to
|
||||
select a part of the input, formatter takes this selection and performs some formating
|
||||
on it. Algorithms can abstract from formating using a formatter.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis role="bold">Examples</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
Formatter implemented as a class. This Formatter does not perform any formating and
|
||||
returns the match, repackaged. <code>operator()</code>
|
||||
is templated, so that the Formatter can be used on any Finder type.
|
||||
|
||||
<programlisting>
|
||||
struct simple_formatter
|
||||
{
|
||||
template<typename FindResultT>
|
||||
std::string operator()( const FindResultT& Match )
|
||||
{
|
||||
std::string Temp( Match.begin(), Match.end() );
|
||||
return Temp;
|
||||
}
|
||||
};
|
||||
</programlisting>
|
||||
</listitem>
|
||||
<listitem>
|
||||
Function Formatter. Similarly to Finder, Formatter can be any function object.
|
||||
However, as a function, it can be used only with a specific Finder type.
|
||||
|
||||
<programlisting>
|
||||
std::string simple_formatter( boost::iterator_range<std::string::const_iterator>& Match )
|
||||
{
|
||||
std::string Temp( Match.begin(), Match.end() );
|
||||
return Temp;
|
||||
}
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.credits" last-revision="$Date$">
|
||||
<title>Credits</title>
|
||||
<section id="string_algo.ack">
|
||||
<title>Acknowledgments</title>
|
||||
<para>
|
||||
The author would like to thank everybody who gave suggestions and comments. Especially valuable
|
||||
were the contributions of Thorsten Ottosen, Jeff Garland and the other boost members who participated
|
||||
in the review process, namely David Abrahams, Daniel Frey, Beman Dawes, John Maddock, David B.Held, Pavel Vozenilek
|
||||
and many other.
|
||||
</para>
|
||||
<para>
|
||||
Additional thanks go to Stefan Slapeta and Toon Knapen, who have been very resourceful in solving various
|
||||
portability issues.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
@ -1,223 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.design" last-revision="$Date$">
|
||||
<title>Design Topics</title>
|
||||
|
||||
<using-namespace name="boost"/>
|
||||
<using-namespace name="boost::algorithm"/>
|
||||
|
||||
<section id="string_algo.string">
|
||||
<title>String Representation</title>
|
||||
|
||||
<para>
|
||||
As the name suggest, this library works mainly with strings. However, in the context of this library,
|
||||
a string is not restricted to any particular implementation (like <code>std::basic_string</code>),
|
||||
rather it is a concept. This allows the algorithms in this library to be reused for any string type,
|
||||
that satisfies the given requirements.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis role="bold">Definition:</emphasis> A string is a
|
||||
<ulink url="../../libs/range/index.html">range</ulink> of characters accessible in sequential
|
||||
ordered fashion. Character is any value type with "cheap" copying and assignment.
|
||||
</para>
|
||||
<para>
|
||||
First requirement of string-type is that it must accessible using
|
||||
<ulink url="../../libs/range/index.html">Boost.Range</ulink>. This facility allows to access
|
||||
the elements inside the string in a uniform iterator-based fashion.
|
||||
This is sufficient for our library
|
||||
</para>
|
||||
<para>
|
||||
Second requirement defines the way in which the characters are stored in the string. Algorithms in
|
||||
this library work with an assumption that copying a character is cheaper then allocating extra
|
||||
storage to cache results. This is a natural assumption for common character types. Algorithms will
|
||||
work even if this requirement is not satisfied, however at the cost of performance degradation.
|
||||
<para>
|
||||
</para>
|
||||
In addition some algorithms have additional requirements on the string-type. Particularly, it is required
|
||||
that an algorithm can create a new string of the given type. In this case, it is required that
|
||||
the type satisfies the sequence (Std §23.1.1) requirements.
|
||||
</para>
|
||||
<para>
|
||||
In the reference and also in the code, requirement on the string type is designated by the name of
|
||||
template argument. <code>RangeT</code> means that the basic range requirements must hold.
|
||||
<code>SequenceT</code> designates extended sequence requirements.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="string_algo.sequence_traits">
|
||||
<title>Sequence Traits</title>
|
||||
|
||||
<para>
|
||||
The major difference between <code>std::list</code> and <code>std::vector</code> is not in the interfaces
|
||||
they provide, but rather in the inner details of the class and the way how it performs
|
||||
various operations. The problem is that it is not possible to infer this difference from the
|
||||
definitions of classes without some special mechanism.
|
||||
However, some algorithms can run significantly faster with the knowledge of the properties
|
||||
of a particular container.
|
||||
</para>
|
||||
<para>
|
||||
Sequence traits allow one to specify additional properties of a sequence container (see Std.§32.2).
|
||||
These properties are then used by algorithms to select optimized handling for some operations.
|
||||
The sequence traits are declared in the header
|
||||
<headername>boost/algorithm/string/sequence_traits.hpp</headername>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the table C denotes a container and c is an object of C.
|
||||
</para>
|
||||
<table>
|
||||
<title>Sequence Traits</title>
|
||||
<tgroup cols="2" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Trait</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><classname>has_native_replace<C></classname>::value</entry>
|
||||
<entry>Specifies that the sequence has std::string like replace method</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><classname>has_stable_iterators<C></classname>::value</entry>
|
||||
<entry>
|
||||
Specifies that the sequence has stable iterators. It means,
|
||||
that operations like <code>insert</code>/<code>erase</code>/<code>replace</code>
|
||||
do not invalidate iterators.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><classname>has_const_time_insert<C></classname>::value</entry>
|
||||
<entry>
|
||||
Specifies that the insert method of the sequence has
|
||||
constant time complexity.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><classname>has_const_time_erase<C></classname>::value</entry>
|
||||
<entry>
|
||||
Specifies that the erase method of the sequence has constant time complexity
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
Current implementation contains specializations for std::list<T> and
|
||||
std::basic_string<T> from the standard library and SGI's std::rope<T> and std::slist<T>.
|
||||
</para>
|
||||
</section>
|
||||
<section id="string_algo.find">
|
||||
<title>Find Algorithms</title>
|
||||
|
||||
<para>
|
||||
Find algorithms have similar functionality to <code>std::search()</code> algorithm. They provide a different
|
||||
interface which is more suitable for common string operations.
|
||||
Instead of returning just the start of matching subsequence they return a range which is necessary
|
||||
when the length of the matching subsequence is not known beforehand.
|
||||
This feature also allows a partitioning of the input sequence into three
|
||||
parts: a prefix, a substring and a suffix.
|
||||
</para>
|
||||
<para>
|
||||
Another difference is an addition of various searching methods besides find_first, including find_regex.
|
||||
</para>
|
||||
<para>
|
||||
It the library, find algorithms are implemented in terms of
|
||||
<link linkend="string_algo.finder_concept">Finders</link>. Finders are used also by other facilities
|
||||
(replace,split).
|
||||
For convenience, there are also function wrappers for these finders to simplify find operations.
|
||||
</para>
|
||||
<para>
|
||||
Currently the library contains only naive implementation of find algorithms with complexity
|
||||
O(n * m) where n is the size of the input sequence and m is the size of the search sequence.
|
||||
There are algorithms with complexity O(n), but for smaller sequence a constant overhead is
|
||||
rather big. For small m << n (m by magnitude smaller than n) the current implementation
|
||||
provides acceptable efficiency.
|
||||
Even the C++ standard defines the required complexity for search algorithm as O(n * m).
|
||||
It is possible that a future version of library will also contain algorithms with linear
|
||||
complexity as an option
|
||||
</para>
|
||||
</section>
|
||||
<section id="string_algo.replace">
|
||||
<title>Replace Algorithms</title>
|
||||
|
||||
<para>
|
||||
The implementation of replace algorithms follows the layered structure of the library. The
|
||||
lower layer implements generic substitution of a range in the input sequence.
|
||||
This layer takes a <link linkend="string_algo.finder_concept">Finder</link> object and a
|
||||
<link linkend="string_algo.formatter_concept">Formatter</link> object as an input. These two
|
||||
functors define what to replace and what to replace it with. The upper layer functions
|
||||
are just wrapping calls to the lower layer. Finders are shared with the find and split facility.
|
||||
</para>
|
||||
<para>
|
||||
As usual, the implementation of the lower layer is designed to work with a generic sequence while
|
||||
taking advantage of specific features if possible
|
||||
(by using <link linkend="string_algo.sequence_traits">Sequence traits</link>)
|
||||
</para>
|
||||
</section>
|
||||
<section id="string_algo.split">
|
||||
<title>Find Iterators & Split Algorithms</title>
|
||||
|
||||
<para>
|
||||
Find iterators are a logical extension of the <link linkend="string_algo.find">find facility</link>.
|
||||
Instead of searching for one match, the whole input can be iteratively searched for multiple matches.
|
||||
The result of the search is then used to partition the input. It depends on the algorithms which parts
|
||||
are returned as the result. They can be the matching parts (<classname>find_iterator</classname>) of the parts in
|
||||
between (<classname>split_iterator</classname>).
|
||||
</para>
|
||||
<para>
|
||||
In addition the split algorithms like <functionname>find_all()</functionname> and <functionname>split()</functionname>
|
||||
can simplify the common operations. They use a find iterator to search the whole input and copy the
|
||||
matches they found into the supplied container.
|
||||
</para>
|
||||
</section>
|
||||
<section id="string_algo.exception">
|
||||
<title>Exception Safety</title>
|
||||
|
||||
<para>
|
||||
The library requires that all operations on types used as template
|
||||
or function arguments provide the <emphasis>basic exception-safety guarantee</emphasis>.
|
||||
In turn, all functions and algorithms in this library, except where stated
|
||||
otherwise, will provide the <emphasis>basic exception-safety guarantee</emphasis>.
|
||||
In other words:
|
||||
The library maintains its invariants and does not leak resources in
|
||||
the face of exceptions. Some library operations give stronger
|
||||
guarantees, which are documented on an individual basis.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Some functions can provide the <emphasis>strong exception-safety guarantee</emphasis>.
|
||||
That means that following statements are true:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
If an exception is thrown, there are no effects other than those
|
||||
of the function
|
||||
</listitem>
|
||||
<listitem>
|
||||
If an exception is thrown other than by the function, there are no effects
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
This guarantee can be provided under the condition that the operations
|
||||
on the types used for arguments for these functions either
|
||||
provide the strong exception guarantee or do not alter the global state .
|
||||
</para>
|
||||
<para>
|
||||
In the reference, under the term <emphasis>strong exception-safety guarantee</emphasis>, we mean the
|
||||
guarantee as defined above.
|
||||
</para>
|
||||
<para>
|
||||
For more information about the exception safety topics, follow this
|
||||
<ulink url="http://www.boost.org/more/generic_exception_safety.html">link</ulink>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.env" last-revision="$Date$">
|
||||
<title>Environment</title>
|
||||
<section>
|
||||
<title>Build</title>
|
||||
<para>
|
||||
The whole library is provided in headers. Regex variants of some algorithms,
|
||||
however, are dependent on the <libraryname>Boost.Regex</libraryname> library. All such algorithms are
|
||||
separated in <headername>boost/algorithm/string_regex.hpp</headername>.
|
||||
If this header is used, the application must be linked with the <libraryname>Boost.Regex</libraryname>
|
||||
library.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Examples</title>
|
||||
<para>
|
||||
Examples showing the basic usage of the library can be found in the libs/algorithm/string/example
|
||||
directory. There is a separate file for the each part of the library. Please follow the boost
|
||||
build guidelines to build examples using the bjam. To successfully build regex examples
|
||||
the <libraryname>Boost.Regex</libraryname> library is required.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Tests</title>
|
||||
<para>
|
||||
A full set of test cases for the library is located in the libs/algorithm/string/test directory.
|
||||
The test cases can be executed using the boost build system. For the tests of regular
|
||||
expression variants of algorithms, the <libraryname>Boost.Regex</libraryname> library is required.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Portability</title>
|
||||
<para>
|
||||
The library has been successfully compiled and tested with the following compilers:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>Microsoft Visual C++ 7.0</listitem>
|
||||
<listitem>Microsoft Visual C++ 7.1</listitem>
|
||||
<listitem>GCC 3.2</listitem>
|
||||
<listitem>GCC 3.3.1</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
See <ulink url="http://boost.sourceforge.net/regression-logs/">Boost regression tables</ulink>
|
||||
for additional info for a particular compiler.
|
||||
</para>
|
||||
<para>
|
||||
There are known limitation on platforms not supporting partial template specialization.
|
||||
Library depends on correctly implemented <code>std::iterator_traits</code> class.
|
||||
If a standard library provided with compiler is broken, the String Algorithm Library
|
||||
cannot function properly. Usually it implies that primitive pointer iterators are not
|
||||
working with the library functions.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title> Concepts and External Concepts </title><meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"></head> <body><table ><tr ><td ><img src="../../../../boost.png" width="100%" border="0"></td><td ><h1 >Concepts and External Concepts</h1></td></tr></table><p >Generic programming in C++ is characterized by the use of function and class templates where
|
||||
the template parameter(s) must satisfy certain requirements.Often these
|
||||
requirements are so important that we give them a name: we call
|
||||
such a set of type requirements a <b>concept</b>. We say that a type <i>
|
||||
conforms to a concept</i> or that it <i>is a model of a concept</i> if it
|
||||
satisfies all of those requirements. The concept can be specified as a set
|
||||
of member functions with well-defined semantics
|
||||
and a set of nested typedefs with well-defined properties.</p><p >Often it much more flexible to provide free-standing functions and typedefs
|
||||
which provides the exact same semantics (but a different syntax) as
|
||||
specified
|
||||
by the concept. This allows generic code to treat different types <i> as if
|
||||
</i> they fulfilled the concept. In this case we say that the concept has
|
||||
been <b> externalized </b> or that the new requirements constitutes an <b>external
|
||||
concept </b>. We say that a type <i> conforms to an external concept </i>
|
||||
or that it <i> is a model of an external concept </i>. A concept may exist
|
||||
without a corresponding external concept and conversely.</p><p >Whenever a concept specifies a member function, the corresponding external
|
||||
concept
|
||||
must specify a free-standing function of the same name, same return type and
|
||||
the same argument list except there is an extra first argument which must
|
||||
be of the type (or a reference to that type) that is to fulfill the external
|
||||
concept. If the corresonding member function has any cv-qulifiers, the
|
||||
first argument must have the same cv-qualifiers. Whenever a concept
|
||||
specifies a nested typedef, the corresponding external concept
|
||||
specifies a <b>type-generator</b>, that is, a type with a nested typedef
|
||||
named <code>type</code>. The type-generator has the name as the nested typedef with
|
||||
<code>_of</code> appended.
|
||||
The converse relationship of an external concept and its corresponding concept
|
||||
also holds.</p><p ><b ><i >Example:</i></b></p><p >A type <code>T</code> fulfills the FooConcept if it
|
||||
has the follwing public members:</p><code> void T::foo( int ) const; <br>
|
||||
int T::bar(); <br>
|
||||
typedef <i>implementation defined </i> foo_type;</code><p >The corresponding external concept is the ExternalFooConcept.</p><p >A type <code>T</code> fullfills the ExternalFooConcept if these
|
||||
free-standing functions and type-generators exists:</p><code>void foo( const T&, int ); <br>
|
||||
int bar( T& ); <br>
|
||||
foo_type_of< T >::type;</code> <br> <br><hr size="1" ><h3 >Literature</h3><ul ><li > <a href="http://www.boost.org/more/generic_programming.html#type_generator" target="_self" >Type Generators</a> </li><li > <a href="http://www.boost.org/more/generic_programming.html#concept" target="_self" >Concepts</a> </li><li > <a href="http://www.sgi.com/tech/stl/stl_introduction.html" target="_self" >Concepts and SGI STL</a> </li></ul><hr size="1" ><p >© Thorsten Ottosen 2003-2004 (nesotto_AT_cs.auc.dk).
|
||||
<br>Use, modification and distribution is subject to the Boost
|
||||
Software License, Version 1.0. (See accompanying file
|
||||
<code class="filename">LICENSE_1_0.txt</code> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</br>
|
||||
</p>
|
||||
<!-- Copyright Dezide Aps 2003-2004 -->
|
@ -1,54 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.intro" last-revision="$Date$">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
The String Algorithm Library provides a generic implementation of
|
||||
string-related algorithms which are missing in STL. It is an extension
|
||||
to the algorithms library of STL and it includes trimming, case conversion,
|
||||
predicates and find/replace functions. All of them come in different variants
|
||||
so it is easier to choose the best fit for a particular need.
|
||||
</para>
|
||||
<para>
|
||||
The implementation is not restricted to work with a particular container
|
||||
(like <code>std::basic_string</code>), rather it is as generic as
|
||||
possible. This generalization is not compromising the performance since
|
||||
algorithms are using container specific features when it means a performance
|
||||
gain.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis role="bold">
|
||||
Important note: In this documentation we use term <emphasis>string</emphasis> to
|
||||
designate a sequence of <emphasis>characters</emphasis> stored in an arbitrary container.
|
||||
A <emphasis>string</emphasis> is not restricted to <code>std::basic_string</code> and
|
||||
<emphasis>character</emphasis> does not have to be <code>char</code> or <code>wchar_t</code>,
|
||||
although these are most common candidates.
|
||||
</emphasis>
|
||||
Consult the <link linkend="string_algo.design">design chapter</link> to see precise specification of
|
||||
supported string types.
|
||||
</para>
|
||||
<para>
|
||||
The library interface functions and classes are defined in namespace <code>boost::algorithm</code>, and
|
||||
they are lifted into namespace <code>boost</code> via using declaration.
|
||||
</para>
|
||||
<para>
|
||||
The documentation is divided into several sections. For a quick start read the
|
||||
<link linkend="string_algo.usage">Usage</link> section followed by
|
||||
<link linkend="string_algo.quickref">Quick Reference</link>.
|
||||
<link linkend="string_algo.design">The Design Topics</link>,
|
||||
<link linkend="string_algo.concept">Concepts</link> and <link linkend="string_algo.rationale">Rationale</link>
|
||||
provide some explanation about the library design and structure an explain how it should be used.
|
||||
See the <link linkend="string_algo.reference">Reference</link> for the complete list of provided utilities
|
||||
and algorithms. Functions and classes in the reference are organized by the headers in which they are defined.
|
||||
The reference contains links to the detailed description for every entity in the library.
|
||||
</para>
|
||||
</section>
|
@ -1,758 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.quickref" last-revision="$Date$">
|
||||
<title>Quick Reference</title>
|
||||
|
||||
<using-namespace name="boost"/>
|
||||
<using-namespace name="boost::algorithm"/>
|
||||
|
||||
<section>
|
||||
<title>Algorithms</title>
|
||||
|
||||
<table>
|
||||
<title>Case Conversion</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>to_upper</code></entry>
|
||||
<entry>Convert a string to upper case</entry>
|
||||
<entry>
|
||||
<functionname>to_upper_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>to_upper()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>to_lower</code></entry>
|
||||
<entry>Convert a string to lower case</entry>
|
||||
<entry>
|
||||
<functionname>to_lower_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>to_lower()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table>
|
||||
<title>Trimming</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>trim_left</code></entry>
|
||||
<entry>Remove leading spaces from a string</entry>
|
||||
<entry>
|
||||
<functionname>trim_left_copy_if()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_left_if()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_left_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_left()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>trim_right</code></entry>
|
||||
<entry>Remove trailing spaces from a string</entry>
|
||||
<entry>
|
||||
<functionname>trim_right_copy_if()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_right_if()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_right_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_right()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>trim</code></entry>
|
||||
<entry>Remove leading and trailing spaces from a string</entry>
|
||||
<entry>
|
||||
<functionname>trim_copy_if()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_if()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>trim()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table>
|
||||
<title>Predicates</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><code>starts_with</code></entry>
|
||||
<entry>Check if a string is a prefix of the other one</entry>
|
||||
<entry>
|
||||
<functionname>starts_with()</functionname>
|
||||
<sbr/>
|
||||
<functionname>istarts_with()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>ends_with</code></entry>
|
||||
<entry>Check if a string is a suffix of the other one</entry>
|
||||
<entry>
|
||||
<functionname>ends_with()</functionname>
|
||||
<sbr/>
|
||||
<functionname>iends_with()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>contains</code></entry>
|
||||
<entry>Check if a string is contained of the other one</entry>
|
||||
<entry>
|
||||
<functionname>contains()</functionname>
|
||||
<sbr/>
|
||||
<functionname>icontains()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>equals</code></entry>
|
||||
<entry>Check if two strings are equal</entry>
|
||||
<entry>
|
||||
<functionname>equals()</functionname>
|
||||
<sbr/>
|
||||
<functionname>iequals()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><code>lexicographical_compare</code></entry>
|
||||
<entry>Check if a string is lexicographically less then another one</entry>
|
||||
<entry>
|
||||
<functionname>lexicographical_compare()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ilexicographical_compare()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><code>all</code></entry>
|
||||
<entry>Check if all elements of a string satisfy the given predicate</entry>
|
||||
<entry>
|
||||
<functionname>all()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table>
|
||||
<title>Find algorithms</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>find_first</entry>
|
||||
<entry>Find the first occurrence of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>find_first()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ifind_first()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_last</entry>
|
||||
<entry>Find the last occurrence of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>find_last()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ifind_last()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_nth</entry>
|
||||
<entry>Find the nth (zero-indexed) occurrence of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>find_nth()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ifind_nth()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_head</entry>
|
||||
<entry>Retrieve the head of a string</entry>
|
||||
<entry>
|
||||
<functionname>find_head()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_tail</entry>
|
||||
<entry>Retrieve the tail of a string</entry>
|
||||
<entry>
|
||||
<functionname>find_tail()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_token</entry>
|
||||
<entry>Find first matching token in the string</entry>
|
||||
<entry>
|
||||
<functionname>find_token()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_regex</entry>
|
||||
<entry>Use the regular expression to search the string</entry>
|
||||
<entry>
|
||||
<functionname>find_regex()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find</entry>
|
||||
<entry>Generic find algorithm</entry>
|
||||
<entry>
|
||||
<functionname>find()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table>
|
||||
<title>Erase/Replace</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>replace/erase_first</entry>
|
||||
<entry>Replace/Erase the first occurrence of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>replace_first()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_first_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_first()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_first_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_first()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_first_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_first()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_first_copy()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_last</entry>
|
||||
<entry>Replace/Erase the last occurrence of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>replace_last()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_last_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_last()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_last_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_last()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_last_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_last()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_last_copy()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_nth</entry>
|
||||
<entry>Replace/Erase the nth (zero-indexed) occurrence of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>replace_nth()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_nth_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_nth()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_nth_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_nth()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_nth_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_nth()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_nth_copy()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_all</entry>
|
||||
<entry>Replace/Erase the all occurrences of a string in the input</entry>
|
||||
<entry>
|
||||
<functionname>replace_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_all_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ireplace_all_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_all_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ierase_all_copy()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_head</entry>
|
||||
<entry>Replace/Erase the head of the input</entry>
|
||||
<entry>
|
||||
<functionname>replace_head()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_head_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_head()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_head_copy()</functionname>
|
||||
<sbr/>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_tail</entry>
|
||||
<entry>Replace/Erase the tail of the input</entry>
|
||||
<entry>
|
||||
<functionname>replace_tail()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_tail_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_tail()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_tail_copy()</functionname>
|
||||
<sbr/>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_regex</entry>
|
||||
<entry>Replace/Erase a substring matching the given regular expression</entry>
|
||||
<entry>
|
||||
<functionname>replace_regex()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_regex_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_regex()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_regex_copy()</functionname>
|
||||
<sbr/>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>replace/erase_regex_all</entry>
|
||||
<entry>Replace/Erase all substrings matching the given regular expression</entry>
|
||||
<entry>
|
||||
<functionname>replace_all_regex()</functionname>
|
||||
<sbr/>
|
||||
<functionname>replace_all_regex_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_all_regex()</functionname>
|
||||
<sbr/>
|
||||
<functionname>erase_all_regex_copy()</functionname>
|
||||
<sbr/>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>find_format</entry>
|
||||
<entry>Generic replace algorithm</entry>
|
||||
<entry>
|
||||
<functionname>find_format()</functionname>
|
||||
<sbr/>
|
||||
<functionname>find_format_copy()</functionname>
|
||||
<sbr/>
|
||||
<functionname>find_format_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>find_format_all_copy()()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table>
|
||||
<title>Split</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>find_all</entry>
|
||||
<entry>Find/Extract all matching substrings in the input</entry>
|
||||
<entry>
|
||||
<functionname>find_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>ifind_all()</functionname>
|
||||
<sbr/>
|
||||
<functionname>find_all_regex()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>split</entry>
|
||||
<entry>Split input into parts</entry>
|
||||
<entry>
|
||||
<functionname>split()</functionname>
|
||||
<sbr/>
|
||||
<functionname>split_regex()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>iter_find</entry>
|
||||
<entry>Iteratively apply the finder to the input to find all matching substrings</entry>
|
||||
<entry>
|
||||
<functionname>iter_find()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>iter_split</entry>
|
||||
<entry>Use the finder to find matching substrings in the input and use them as separators to split the input into parts</entry>
|
||||
<entry>
|
||||
<functionname>iter_split()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<table>
|
||||
<title>Join</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Algorithm name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Functions</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>join</entry>
|
||||
<entry>Join all elements in a container into a single string</entry>
|
||||
<entry>
|
||||
<functionname>join</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>join_if</entry>
|
||||
<entry>Join all elements in a container that satisfies the condition into a single string</entry>
|
||||
<entry>
|
||||
<functionname>join_if()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<title>Finders and Formatters</title>
|
||||
|
||||
<table>
|
||||
<title>Finders</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Finder</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Generators</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>first_finder</entry>
|
||||
<entry>Search for the first match of the string in an input</entry>
|
||||
<entry>
|
||||
<functionname>first_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>last_finder</entry>
|
||||
<entry>Search for the last match of the string in an input</entry>
|
||||
<entry>
|
||||
<functionname>last_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>nth_finder</entry>
|
||||
<entry>Search for the nth (zero-indexed) match of the string in an input</entry>
|
||||
<entry>
|
||||
<functionname>nth_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>head_finder</entry>
|
||||
<entry>Retrieve the head of an input</entry>
|
||||
<entry>
|
||||
<functionname>head_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>tail_finder</entry>
|
||||
<entry>Retrieve the tail of an input</entry>
|
||||
<entry>
|
||||
<functionname>tail_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>token_finder</entry>
|
||||
<entry>Search for a matching token in an input</entry>
|
||||
<entry>
|
||||
<functionname>token_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>range_finder</entry>
|
||||
<entry>Do no search, always returns the given range</entry>
|
||||
<entry>
|
||||
<functionname>range_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>regex_finder</entry>
|
||||
<entry>Search for a substring matching the given regex</entry>
|
||||
<entry>
|
||||
<functionname>regex_finder()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<title>Formatters</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Formatter</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Generators</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>const_formatter</entry>
|
||||
<entry>Constant formatter. Always return the specified string</entry>
|
||||
<entry>
|
||||
<functionname>const_formatter()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>identity_formatter</entry>
|
||||
<entry>Identity formatter. Return unmodified input input</entry>
|
||||
<entry>
|
||||
<functionname>identity_formatter()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>empty_formatter</entry>
|
||||
<entry>Null formatter. Always return an empty string</entry>
|
||||
<entry>
|
||||
<functionname>empty_formatter()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>regex_formatter</entry>
|
||||
<entry>Regex formatter. Format regex match using the specification in the format string</entry>
|
||||
<entry>
|
||||
<functionname>regex_formatter()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<title>Iterators</title>
|
||||
|
||||
<table>
|
||||
<title>Find Iterators</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Iterator name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Iterator class</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>find_iterator</entry>
|
||||
<entry>Iterates through matching substrings in the input</entry>
|
||||
<entry>
|
||||
<classname>find_iterator</classname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>split_iterator</entry>
|
||||
<entry>Iterates through gaps between matching substrings in the input</entry>
|
||||
<entry>
|
||||
<classname>split_iterator</classname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Classification</title>
|
||||
|
||||
<table>
|
||||
<title>Predicates</title>
|
||||
<tgroup cols="3" align="left">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Predicate name</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Generator</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>is_classified</entry>
|
||||
<entry>Generic <code>ctype</code> mask based classification</entry>
|
||||
<entry>
|
||||
<functionname>is_classified()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_space</entry>
|
||||
<entry>Recognize spaces</entry>
|
||||
<entry>
|
||||
<functionname>is_space()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_alnum</entry>
|
||||
<entry>Recognize alphanumeric characters</entry>
|
||||
<entry>
|
||||
<functionname>is_alnum()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_alpha</entry>
|
||||
<entry>Recognize letters</entry>
|
||||
<entry>
|
||||
<functionname>is_alpha()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_cntrl</entry>
|
||||
<entry>Recognize control characters</entry>
|
||||
<entry>
|
||||
<functionname>is_cntrl()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_digit</entry>
|
||||
<entry>Recognize decimal digits</entry>
|
||||
<entry>
|
||||
<functionname>is_digit()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_graph</entry>
|
||||
<entry>Recognize graphical characters</entry>
|
||||
<entry>
|
||||
<functionname>is_graph()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_lower</entry>
|
||||
<entry>Recognize lower case characters</entry>
|
||||
<entry>
|
||||
<functionname>is_lower()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_print</entry>
|
||||
<entry>Recognize printable characters</entry>
|
||||
<entry>
|
||||
<functionname>is_print()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_punct</entry>
|
||||
<entry>Recognize punctuation characters</entry>
|
||||
<entry>
|
||||
<functionname>is_punct()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_upper</entry>
|
||||
<entry>Recognize uppercase characters</entry>
|
||||
<entry>
|
||||
<functionname>is_upper()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_xdigit</entry>
|
||||
<entry>Recognize hexadecimal digits</entry>
|
||||
<entry>
|
||||
<functionname>is_xdigit()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_any_of</entry>
|
||||
<entry>Recognize any of a sequence of characters</entry>
|
||||
<entry>
|
||||
<functionname>is_any_of()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>is_from_range</entry>
|
||||
<entry>Recognize characters inside a min..max range</entry>
|
||||
<entry>
|
||||
<functionname>is_from_range()</functionname>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
</section>
|
@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.rationale" last-revision="$Date$">
|
||||
<title>Rationale</title>
|
||||
|
||||
<using-namespace name="boost"/>
|
||||
<using-namespace name="boost::algorithm"/>
|
||||
|
||||
<section it="string_algo.locale">
|
||||
<title>Locales</title>
|
||||
|
||||
<para>
|
||||
Locales have a very close relation to string processing. They contain information about
|
||||
the character sets and are used, for example, to change the case of characters and
|
||||
to classify the characters.
|
||||
</para>
|
||||
<para>
|
||||
C++ allows to work with multiple different instances of locales at once. If an algorithm
|
||||
manipulates some data in a way that requires the usage of locales, there must be a way
|
||||
to specify them. However, one instance of locales is sufficient for most of the applications,
|
||||
and for a user it could be very tedious to specify which locales to use at every place
|
||||
where it is needed.
|
||||
</para>
|
||||
<para>
|
||||
Fortunately, the C++ standard allows to specify the <emphasis>global</emphasis> locales (using static member
|
||||
function <code>std:locale::global()</code>). When instantiating an
|
||||
<code>std::locale</code> class without explicit information, the instance will
|
||||
be initialized with the <emphasis>global</emphasis> locale. This implies, that if an algorithm needs a locale,
|
||||
it should have an <code>std::locale</code> parameter defaulting to <code>std::locale()</code>.
|
||||
If a user needs to specify locales explicitly, she can do so. Otherwise the <emphasis>global</emphasis>
|
||||
locales are used.
|
||||
</para>
|
||||
</section>
|
||||
<section id="string_algo.regex">
|
||||
<title>Regular Expressions</title>
|
||||
|
||||
<para>
|
||||
Regular expressions are an essential part of text processing. For this reason, the library
|
||||
also provides regex variants of some algorithms. The library does not attempt to replace
|
||||
<libraryname>Boost.Regex</libraryname>; it merely wraps its functionality in a new interface.
|
||||
As a part of this library, regex algorithms integrate smoothly with other components, which
|
||||
brings additional value.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<section id="string_algo.release_notes" last-revision="$Date$">
|
||||
|
||||
<using-namespace name="boost"/>
|
||||
<using-namespace name="boost::algorithm"/>
|
||||
|
||||
<title>Release Notes</title>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">1.32</emphasis></para>
|
||||
<para>Initial release in Boost</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">1.33</emphasis></para>
|
||||
<para>Internal version of collection traits removed, library adapted to Boost.Range</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">1.34</emphasis></para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<functionname>lexicographical_compare()</functionname>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<functionname>join()</functionname> and <functionname>join_if()</functionname>
|
||||
</listitem>
|
||||
<listitem>
|
||||
New comparison predicates <code>is_less</code>, <code>is_not_greater</code>
|
||||
</listitem>
|
||||
<listitem>
|
||||
Negative indexes support (like Perl) in various algorihtms
|
||||
(<code>*_head/tail</code>, <code>*_nth</code>).
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
@ -1,52 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
<library name="String Algorithms" dirname="algorithm/string" xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
id="string_algo" last-revision="$Date$">
|
||||
<libraryinfo>
|
||||
<author>
|
||||
<firstname>Pavol</firstname>
|
||||
<surname>Droba</surname>
|
||||
</author>
|
||||
|
||||
<copyright>
|
||||
<year>2002</year>
|
||||
<year>2003</year>
|
||||
<year>2004</year>
|
||||
<holder>Pavol Droba</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>Use, modification and distribution is subject to the Boost
|
||||
Software License, Version 1.0. (See accompanying file
|
||||
<filename>LICENSE_1_0.txt</filename> or copy at <ulink
|
||||
url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<librarypurpose>
|
||||
A set of generic string-related algorithms and utilities
|
||||
</librarypurpose>
|
||||
<librarycategory name="category:algorithms"/>
|
||||
<librarycategory name="category:string-text"/>
|
||||
</libraryinfo>
|
||||
|
||||
<title>Boost String Algorithms Library</title>
|
||||
<xi:include href="intro.xml"/>
|
||||
<xi:include href="release_notes.xml"/>
|
||||
<xi:include href="usage.xml"/>
|
||||
<xi:include href="quickref.xml"/>
|
||||
<xi:include href="design.xml"/>
|
||||
<xi:include href="concept.xml"/>
|
||||
<xi:include href="autodoc.xml"/>
|
||||
<xi:include href="rationale.xml"/>
|
||||
<xi:include href="environment.xml"/>
|
||||
<xi:include href="credits.xml"/>
|
||||
</library>
|
||||
|
@ -1,361 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
|
||||
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
|
||||
|
||||
|
||||
<!-- Copyright (c) 2002-2006 Pavol Droba.
|
||||
Subject to the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
|
||||
-->
|
||||
|
||||
|
||||
<section id="string_algo.usage" last-revision="$Date$">
|
||||
<title>Usage</title>
|
||||
|
||||
<using-namespace name="boost"/>
|
||||
<using-namespace name="boost::algorithm"/>
|
||||
|
||||
|
||||
<section>
|
||||
<title>First Example</title>
|
||||
|
||||
<para>
|
||||
Using the algorithms is straightforward. Let us have a look at the first example:
|
||||
</para>
|
||||
<programlisting>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
// ...
|
||||
|
||||
string str1(" hello world! ");
|
||||
to_upper(str1); // str1 == " HELLO WORLD! "
|
||||
trim(str1); // str1 == "HELLO WORLD!"
|
||||
|
||||
string str2=
|
||||
to_lower_copy(
|
||||
ireplace_first_copy(
|
||||
str1,"hello","goodbye")); // str2 == "goodbye world!"
|
||||
</programlisting>
|
||||
<para>
|
||||
This example converts str1 to upper case and trims spaces from the start and the end
|
||||
of the string. str2 is then created as a copy of str1 with "hello" replaced with "goodbye".
|
||||
This example demonstrates several important concepts used in the library:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">Container parameters:</emphasis>
|
||||
Unlike in the STL algorithms, parameters are not specified only in the form
|
||||
of iterators. The STL convention allows for great flexibility,
|
||||
but it has several limitations. It is not possible to <emphasis>stack</emphasis> algorithms together,
|
||||
because a container is passed in two parameters. Therefore it is not possible to use
|
||||
a return value from another algorithm. It is considerably easier to write
|
||||
<code>to_lower(str1)</code>, than <code>to_lower(str1.begin(), str1.end())</code>.
|
||||
</para>
|
||||
<para>
|
||||
The magic of <ulink url="../../libs/range/index.html">Boost.Range</ulink>
|
||||
provides a uniform way of handling different string types.
|
||||
If there is a need to pass a pair of iterators,
|
||||
<ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink>
|
||||
can be used to package iterators into a structure with a compatible interface.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">Copy vs. Mutable:</emphasis>
|
||||
Many algorithms in the library are performing a transformation of the input.
|
||||
The transformation can be done in-place, mutating the input sequence, or a copy
|
||||
of the transformed input can be created, leaving the input intact. None of
|
||||
these possibilities is superior to the other one and both have different
|
||||
advantages and disadvantages. For this reason, both are provided with the library.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">Algorithm stacking:</emphasis>
|
||||
Copy versions return a transformed input as a result, thus allow a simple chaining of
|
||||
transformations within one expression (i.e. one can write <code>trim_copy(to_upper_copy(s))</code>).
|
||||
Mutable versions have <code>void</code> return, to avoid misuse.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><emphasis role="bold">Naming:</emphasis>
|
||||
Naming follows the conventions from the Standard C++ Library. If there is a
|
||||
copy and a mutable version of the same algorithm, the mutable version has no suffix
|
||||
and the copy version has the suffix <emphasis>_copy</emphasis>.
|
||||
Some algorithms have the prefix <emphasis>i</emphasis>
|
||||
(e.g. <functionname>ifind_first()</functionname>).
|
||||
This prefix identifies that the algorithm works in a case-insensitive manner.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>
|
||||
To use the library, include the <headername>boost/algorithm/string.hpp</headername> header.
|
||||
If the regex related functions are needed, include the
|
||||
<headername>boost/algorithm/string_regex.hpp</headername> header.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Case conversion</title>
|
||||
|
||||
<para>
|
||||
STL has a nice way of converting character case. Unfortunately, it works only
|
||||
for a single character and we want to convert a string,
|
||||
</para>
|
||||
<programlisting>
|
||||
string str1("HeLlO WoRld!");
|
||||
to_upper(str1); // str1=="HELLO WORLD!"
|
||||
</programlisting>
|
||||
<para>
|
||||
<functionname>to_upper()</functionname> and <functionname>to_lower()</functionname> convert the case of
|
||||
characters in a string using a specified locale.
|
||||
</para>
|
||||
<para>
|
||||
For more information see the reference for <headername>boost/algorithm/string/case_conv.hpp</headername>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Predicates and Classification</title>
|
||||
<para>
|
||||
A part of the library deals with string related predicates. Consider this example:
|
||||
</para>
|
||||
<programlisting>
|
||||
bool is_executable( string& filename )
|
||||
{
|
||||
return
|
||||
iends_with(filename, ".exe") ||
|
||||
iends_with(filename, ".com");
|
||||
}
|
||||
|
||||
// ...
|
||||
string str1("command.com");
|
||||
cout
|
||||
<< str1
|
||||
<< (is_executable("command.com")? "is": "is not")
|
||||
<< "an executable"
|
||||
<< endl; // prints "command.com is an executable"
|
||||
|
||||
//..
|
||||
char text1[]="hello world!";
|
||||
cout
|
||||
<< text1
|
||||
<< (all( text1, is_lower() )? "is": "is not")
|
||||
<< " written in the lower case"
|
||||
<< endl; // prints "hello world! is written in the lower case"
|
||||
</programlisting>
|
||||
<para>
|
||||
The predicates determine whether if a substring is contained in the input string
|
||||
under various conditions. The conditions are: a string starts with the substring,
|
||||
ends with the substring,
|
||||
simply contains the substring or if both strings are equal. See the reference for
|
||||
<headername>boost/algorithm/string/predicate.hpp</headername> for more details.
|
||||
</para>
|
||||
<para>
|
||||
In addition the algorithm <functionname>all()</functionname> checks
|
||||
all elements of a container to satisfy a condition specified by a predicate.
|
||||
This predicate can be any unary predicate, but the library provides a bunch of
|
||||
useful string-related predicates and combinators ready for use.
|
||||
These are located in the <headername>boost/algorithm/string/classification.hpp</headername> header.
|
||||
Classification predicates can be combined using logical combinators to form
|
||||
a more complex expressions. For example: <code>is_from_range('a','z') || is_digit()</code>
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Trimming</title>
|
||||
|
||||
<para>
|
||||
When parsing the input from a user, strings usually have unwanted leading or trailing
|
||||
characters. To get rid of them, we need trim functions:
|
||||
</para>
|
||||
<programlisting>
|
||||
string str1=" hello world! ";
|
||||
string str2=trim_left_copy(str1); // str2 == "hello world! "
|
||||
string str3=trim_right_copy(str1); // str3 == " hello world!"
|
||||
trim(str1); // str1 == "hello world!"
|
||||
|
||||
string phone="00423333444";
|
||||
// remove leading 0 from the phone number
|
||||
trim_left_if(phone,is_any_of("0")); // phone == "423333444"
|
||||
</programlisting>
|
||||
<para>
|
||||
It is possible to trim the spaces on the right, on the left or on both sides of a string.
|
||||
And for those cases when there is a need to remove something else than blank space, there
|
||||
are <emphasis>_if</emphasis> variants. Using these, a user can specify a functor which will
|
||||
select the <emphasis>space</emphasis> to be removed. It is possible to use classification
|
||||
predicates like <functionname>is_digit()</functionname> mentioned in the previous paragraph.
|
||||
See the reference for the <headername>boost/algorithm/string/trim.hpp</headername>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Find algorithms</title>
|
||||
|
||||
<para>
|
||||
The library contains a set of find algorithms. Here is an example:
|
||||
</para>
|
||||
<programlisting>
|
||||
char text[]="hello dolly!";
|
||||
iterator_range<char*> result=find_last(text,"ll");
|
||||
|
||||
transform( result.begin(), result.end(), result.begin(), bind2nd(plus<char>(), 1) );
|
||||
// text = "hello dommy!"
|
||||
|
||||
to_upper(result); // text == "hello doMMy!"
|
||||
|
||||
// iterator_range is convertible to bool
|
||||
if(find_first(text, "dolly"))
|
||||
{
|
||||
cout << "Dolly is there" << endl;
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
We have used <functionname>find_last()</functionname> to search the <code>text</code> for "ll".
|
||||
The result is given in the <ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink>.
|
||||
This range delimits the
|
||||
part of the input which satisfies the find criteria. In our example it is the last occurrence of "ll".
|
||||
|
||||
As we can see, input of the <functionname>find_last()</functionname> algorithm can be also
|
||||
char[] because this type is supported by
|
||||
<ulink url="../../libs/range/index.html">Boost.Range</ulink>.
|
||||
|
||||
The following lines transform the result. Notice that
|
||||
<ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink> has familiar
|
||||
<code>begin()</code> and <code>end()</code> methods, so it can be used like any other STL container.
|
||||
Also it is convertible to bool therefore it is easy to use find algorithms for a simple containment checking.
|
||||
</para>
|
||||
<para>
|
||||
Find algorithms are located in <headername>boost/algorithm/string/find.hpp</headername>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Replace Algorithms</title>
|
||||
<para>
|
||||
Find algorithms can be used for searching for a specific part of string. Replace goes one step
|
||||
further. After a matching part is found, it is substituted with something else. The substitution is computed
|
||||
from the original, using some transformation.
|
||||
</para>
|
||||
<programlisting>
|
||||
string str1="Hello Dolly, Hello World!"
|
||||
replace_first(str1, "Dolly", "Jane"); // str1 == "Hello Jane, Hello World!"
|
||||
replace_last(str1, "Hello", "Goodbye"); // str1 == "Hello Jane, Goodbye World!"
|
||||
erase_all(str1, " "); // str1 == "HelloJane,GoodbyeWorld!"
|
||||
erase_head(str1, 6); // str1 == "Jane,GoodbyeWorld!"
|
||||
</programlisting>
|
||||
<para>
|
||||
For the complete list of replace and erase functions see the
|
||||
<link linkend="string_algo.reference">reference</link>.
|
||||
There is a lot of predefined function for common usage, however, the library allows you to
|
||||
define a custom <code>replace()</code> that suits a specific need. There is a generic <functionname>find_format()</functionname>
|
||||
function which takes two parameters.
|
||||
The first one is a <link linkend="string_algo.finder_concept">Finder</link> object, the second one is
|
||||
a <link linkend="string_algo.formatter_concept">Formatter</link> object.
|
||||
The Finder object is a functor which performs the searching for the replacement part. The Formatter object
|
||||
takes the result of the Finder (usually a reference to the found substring) and creates a
|
||||
substitute for it. Replace algorithm puts these two together and makes the desired substitution.
|
||||
</para>
|
||||
<para>
|
||||
Check <headername>boost/algorithm/string/replace.hpp</headername>, <headername>boost/algorithm/string/erase.hpp</headername> and
|
||||
<headername>boost/algorithm/string/find_format.hpp</headername> for reference.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Find Iterator</title>
|
||||
|
||||
<para>
|
||||
An extension to find algorithms it the Find Iterator. Instead of searching for just a one part of a string,
|
||||
the find iterator allows us to iterate over the substrings matching the specified criteria.
|
||||
This facility is using the <link linkend="string_algo.finder_concept">Finder</link> to incrementally
|
||||
search the string.
|
||||
Dereferencing a find iterator yields an <ulink url="../../libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></ulink>
|
||||
object, that delimits the current match.
|
||||
</para>
|
||||
<para>
|
||||
There are two iterators provided <classname>find_iterator</classname> and
|
||||
<classname>split_iterator</classname>. The former iterates over substrings that are found using the specified
|
||||
Finder. The latter iterates over the gaps between these substrings.
|
||||
</para>
|
||||
<programlisting>
|
||||
string str1("abc-*-ABC-*-aBc");
|
||||
// Find all 'abc' substrings (ignoring the case)
|
||||
// Create a find_iterator
|
||||
typedef find_iterator<string::iterator> string_find_iterator;
|
||||
for(string_find_iterator It=
|
||||
make_find_iterator(str1, first_finder("abc", is_iequal()));
|
||||
It!=string_find_iterator();
|
||||
++It)
|
||||
{
|
||||
cout << copy_range<std::string>(*It) << endl;
|
||||
}
|
||||
|
||||
// Output will be:
|
||||
// abc
|
||||
// ABC
|
||||
// aBC
|
||||
|
||||
typedef split_iterator<string::iterator> string_split_iterator;
|
||||
for(string_split_iterator It=
|
||||
make_split_iterator(str1, first_finder("-*-", is_iequal()));
|
||||
It!=string_split_iterator();
|
||||
++It)
|
||||
{
|
||||
cout << copy_range<std::string>(*It) << endl;
|
||||
}
|
||||
|
||||
// Output will be:
|
||||
// abc
|
||||
// ABC
|
||||
// aBC
|
||||
</programlisting>
|
||||
<para>
|
||||
Note that the find iterators have only one template parameter. It is the base iterator type.
|
||||
The Finder is specified at runtime. This allows us to typedef a find iterator for
|
||||
common string types and reuse it. Additionally make_*_iterator functions help
|
||||
to construct a find iterator for a particular range.
|
||||
</para>
|
||||
<para>
|
||||
See the reference in <headername>boost/algorithm/string/find_iterator.hpp</headername>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Split</title>
|
||||
|
||||
<para>
|
||||
Split algorithms are an extension to the find iterator for one common usage scenario.
|
||||
These algorithms use a find iterator and store all matches into the provided
|
||||
container. This container must be able to hold copies (e.g. <code>std::string</code>) or
|
||||
references (e.g. <code>iterator_range</code>) of the extracted substrings.
|
||||
</para>
|
||||
<para>
|
||||
Two algorithms are provided. <functionname>find_all()</functionname> finds all copies
|
||||
of a string in the input. <functionname>split()</functionname> splits the input into parts.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
string str1("hello abc-*-ABC-*-aBc goodbye");
|
||||
|
||||
typedef vector< iterator_range<string::iterator> > find_vector_type;
|
||||
|
||||
find_vector_type FindVec; // #1: Search for separators
|
||||
ifind_all( FindVec, str1, "abc" ); // FindVec == { [abc],[ABC],[aBc] }
|
||||
|
||||
typedef vector< string > split_vector_type;
|
||||
|
||||
split_vector_type SplitVec; // #2: Search for tokens
|
||||
split( SplitVec, str1, is_any_of("-*"), token_compress_on ); // SplitVec == { "hello abc","ABC","aBc goodbye" }
|
||||
</programlisting>
|
||||
<para>
|
||||
<code>[hello]</code> designates an <code>iterator_range</code> delimiting this substring.
|
||||
</para>
|
||||
<para>
|
||||
First example show how to construct a container to hold references to all extracted
|
||||
substrings. Algorithm <functionname>ifind_all()</functionname> puts into FindVec references
|
||||
to all substrings that are in case-insensitive manner equal to "abc".
|
||||
</para>
|
||||
<para>
|
||||
Second example uses <functionname>split()</functionname> to split string str1 into parts
|
||||
separated by characters '-' or '*'. These parts are then put into the SplitVec.
|
||||
It is possible to specify if adjacent separators are concatenated or not.
|
||||
</para>
|
||||
<para>
|
||||
More information can be found in the reference: <headername>boost/algorithm/string/split.hpp</headername>.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
@ -1,18 +0,0 @@
|
||||
# Boost string_algo library examples Jamfile ---------------------------------
|
||||
#
|
||||
# Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
# distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
|
||||
exe conv_example : conv_example.cpp ;
|
||||
exe predicate_example : predicate_example.cpp ;
|
||||
exe find_example : find_example.cpp ;
|
||||
exe replace_example : replace_example.cpp ;
|
||||
exe rle_example : rle_example.cpp ;
|
||||
exe trim_example : trim_example.cpp ;
|
||||
exe regex_example : regex_example.cpp /boost/regex//boost_regex ;
|
||||
exe split_example : split_example.cpp ;
|
@ -1,41 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Case Conversion Example *" << endl << endl;
|
||||
|
||||
string str1("AbCdEfG");
|
||||
vector<char> vec1( str1.begin(), str1.end() );
|
||||
|
||||
// Convert vector of chars to lower case
|
||||
cout << "lower-cased copy of vec1: ";
|
||||
to_lower_copy( ostream_iterator<char>(cout), vec1 );
|
||||
cout << endl;
|
||||
|
||||
// Conver string str1 to upper case ( copy the input )
|
||||
cout << "upper-cased copy of str1: " << to_upper_copy( str1 ) << endl;
|
||||
|
||||
// Inplace conversion
|
||||
to_lower( str1 );
|
||||
cout << "lower-cased str1: " << str1 << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Find Example *" << endl << endl;
|
||||
|
||||
string str1("abc___cde___efg");
|
||||
string str2("abc");
|
||||
|
||||
// find "cde" substring
|
||||
iterator_range<string::iterator> range=find_first( str1, string("cde") );
|
||||
|
||||
// convert a substring to upper case
|
||||
// note that iterator range can be directly passed to the algorithm
|
||||
to_upper( range );
|
||||
|
||||
cout << "str1 with upper-cased part matching cde: " << str1 << endl;
|
||||
|
||||
// get a head of the string
|
||||
iterator_range<string::iterator> head=find_head( str1, 3 );
|
||||
cout << "head(3) of the str1: " << string( head.begin(), head.end() ) << endl;
|
||||
|
||||
// get the tail
|
||||
head=find_tail( str2, 5 );
|
||||
cout << "tail(5) of the str2: " << string( head.begin(), head.end() ) << endl;
|
||||
|
||||
// char processing
|
||||
char text[]="hello dolly!";
|
||||
iterator_range<char*> crange=find_last(text,"ll");
|
||||
|
||||
// transform the range ( add 1 )
|
||||
transform( crange.begin(), crange.end(), crange.begin(), bind2nd( plus<char>(), 1 ) );
|
||||
// uppercase the range
|
||||
to_upper( crange );
|
||||
|
||||
cout << text << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Predicate Example *" << endl << endl;
|
||||
|
||||
string str1("123xxx321");
|
||||
string str2("abc");
|
||||
|
||||
// Check if str1 starts with '123'
|
||||
cout << "str1 starts with \"123\": " <<
|
||||
(starts_with( str1, string("123") )?"true":"false") << endl;
|
||||
|
||||
// Check if str1 ends with '123'
|
||||
cout << "str1 ends with \"123\": " <<
|
||||
(ends_with( str1, string("123") )?"true":"false") << endl;
|
||||
|
||||
// Check if str1 containes 'xxx'
|
||||
cout << "str1 contains \"xxx\": " <<
|
||||
(contains( str1, string("xxx") )?"true":"false") << endl;
|
||||
|
||||
|
||||
// Check if str2 equals to 'abc'
|
||||
cout << "str2 equals \"abc\": " <<
|
||||
(equals( str2, string("abc") )?"true":"false") << endl;
|
||||
|
||||
|
||||
// Classification functors and all predicate
|
||||
if ( all(";.,", is_punct() ) )
|
||||
{
|
||||
cout << "\";.,\" are all punctuation characters" << endl;
|
||||
}
|
||||
|
||||
// Classification predicates can be combined
|
||||
if ( all("abcxxx", is_any_of("xabc") && !is_space() ) )
|
||||
{
|
||||
cout << "true" << endl;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/algorithm/string/regex.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Regex Example *" << endl << endl;
|
||||
|
||||
string str1("abc__(456)__123__(123)__cde");
|
||||
|
||||
// Replace all substrings matching (digit+)
|
||||
cout <<
|
||||
"replace all (digit+) in str1 with #digit+# :" <<
|
||||
replace_all_regex_copy( str1, regex("\\(([0-9]+)\\)"), string("#$1#") ) << endl;
|
||||
|
||||
// Erase all substrings matching (digit+)
|
||||
cout <<
|
||||
"remove all sequences of letters from str1 :" <<
|
||||
erase_all_regex_copy( str1, regex("[[:alpha:]]+") ) << endl;
|
||||
|
||||
// in-place regex transformation
|
||||
replace_all_regex( str1, regex("_(\\([^\\)]*\\))_"), string("-$1-") );
|
||||
cout << "transformad str1: " << str1 << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
//#include <boost/algorithm/string/replace.hpp>
|
||||
//#include <boost/algorithm/string/erase.hpp>
|
||||
//#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
//Following two includes contain second-layer function.
|
||||
//They are already included by first-layer header
|
||||
|
||||
//#include <boost/algorithm/string/replace2.hpp>
|
||||
//#include <boost/algorithm/string/find2.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
// uppercase formatter
|
||||
/*
|
||||
Convert an input to upper case.
|
||||
Note, that this formatter can be used only on std::string inputs.
|
||||
*/
|
||||
inline string upcase_formatter(
|
||||
const iterator_range<string::const_iterator>& Replace )
|
||||
{
|
||||
string Temp(Replace.begin(), Replace.end());
|
||||
to_upper(Temp);
|
||||
return Temp;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Replace Example *" << endl << endl;
|
||||
|
||||
string str1("abc___cde___efg");
|
||||
|
||||
// Erase 6-9th characters from the string
|
||||
cout << "str1 without 6th to 9th character:" <<
|
||||
erase_range_copy( str1, make_iterator_range(str1.begin()+6, str1.begin()+9) ) << endl;
|
||||
|
||||
// Replace 6-9th character with '+++'
|
||||
cout << "str1 with 6th to 9th character replaced with '+++': " <<
|
||||
replace_range_copy(
|
||||
str1, make_iterator_range(str1.begin()+6, str1.begin()+9), "+++" ) << endl;
|
||||
|
||||
cout << "str1 with 'cde' replaced with 'XYZ': ";
|
||||
|
||||
// Replace first 'cde' with 'XYZ'. Modify the input
|
||||
replace_first_copy( ostream_iterator<char>(cout), str1, "cde", "XYZ" );
|
||||
cout << endl;
|
||||
|
||||
// Replace all '___'
|
||||
cout << "str1 with all '___' replaced with '---': " <<
|
||||
replace_all_copy( str1, "___", "---" ) << endl;
|
||||
|
||||
// Erase all '___'
|
||||
cout << "str1 without all '___': " <<
|
||||
erase_all_copy( str1, "___" ) << endl;
|
||||
|
||||
// replace third and 5th occurrence of _ in str1
|
||||
// note that nth argument is 0-based
|
||||
replace_nth( str1, "_", 4, "+" );
|
||||
replace_nth( str1, "_", 2, "+" );
|
||||
|
||||
cout << "str1 with third and 5th occurrence of _ replace: " << str1 << endl;
|
||||
|
||||
// Custom formatter examples
|
||||
string str2("abC-xxxx-AbC-xxxx-abc");
|
||||
|
||||
// Find string 'abc' ignoring the case and convert it to upper case
|
||||
cout << "Upcase all 'abc'(s) in the str2: " <<
|
||||
find_format_all_copy(
|
||||
str2,
|
||||
first_finder("abc", is_iequal()),
|
||||
upcase_formatter );
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,248 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
/*
|
||||
RLE compression using replace framework. Goal is to compress a sequence of
|
||||
repeating characters into 3 bytes ( repeat mark, character and repetition count ).
|
||||
For simplification, it works only on numeric-value sequences.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/algorithm/string/find_format.hpp>
|
||||
#include <boost/algorithm/string/finder.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
// replace mark specification, specialize for a specific element type
|
||||
template< typename T > T repeat_mark() { return (std::numeric_limits<T>::max)(); };
|
||||
|
||||
// Compression -----------------------------------------------------------------------
|
||||
|
||||
|
||||
// compress finder -rle
|
||||
/*
|
||||
Find a sequence which can be compressed. It has to be at least 3-character long
|
||||
sequence of repetitive characters
|
||||
*/
|
||||
struct find_compressF
|
||||
{
|
||||
// Construction
|
||||
find_compressF() {}
|
||||
|
||||
// Operation
|
||||
template<typename ForwardIteratorT>
|
||||
iterator_range<ForwardIteratorT> operator()(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef typename boost::detail::iterator_traits<input_iterator_type>::value_type value_type;
|
||||
typedef iterator_range<input_iterator_type> result_type;
|
||||
|
||||
// begin of the matching segment
|
||||
input_iterator_type MStart=End;
|
||||
// Repetition counter
|
||||
value_type Cnt=0;
|
||||
|
||||
// Search for a sequence of repetitive characters
|
||||
for(input_iterator_type It=Begin; It!=End;)
|
||||
{
|
||||
input_iterator_type It2=It++;
|
||||
|
||||
if ( It==End || Cnt>=(std::numeric_limits<value_type>::max)() )
|
||||
{
|
||||
return result_type( MStart, It );
|
||||
}
|
||||
|
||||
if ( *It==*It2 )
|
||||
{
|
||||
if ( MStart==End )
|
||||
{
|
||||
// Mark the start
|
||||
MStart=It2;
|
||||
}
|
||||
|
||||
// Increate repetition counter
|
||||
Cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( MStart!=End )
|
||||
{
|
||||
if ( Cnt>2 )
|
||||
return result_type( MStart, It );
|
||||
else
|
||||
{
|
||||
MStart=End;
|
||||
Cnt=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result_type( End, End );
|
||||
}
|
||||
};
|
||||
|
||||
// rle compress format
|
||||
/*
|
||||
Transform a sequence into repeat mark, character and count
|
||||
*/
|
||||
template<typename SeqT>
|
||||
struct format_compressF
|
||||
{
|
||||
private:
|
||||
typedef SeqT result_type;
|
||||
typedef typename SeqT::value_type value_type;
|
||||
|
||||
public:
|
||||
// Construction
|
||||
format_compressF() {};
|
||||
|
||||
// Operation
|
||||
template< typename ReplaceT >
|
||||
result_type operator()( const ReplaceT& Replace ) const
|
||||
{
|
||||
SeqT r;
|
||||
if(!Replace.empty())
|
||||
{
|
||||
r.push_back( repeat_mark<value_type>() );
|
||||
r.push_back( *(Replace.begin()) );
|
||||
r.push_back( value_type( Replace.size() ) );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
// Decompression -----------------------------------------------------------------------
|
||||
|
||||
|
||||
// find decompress-rle functor
|
||||
/*
|
||||
find a repetition block
|
||||
*/
|
||||
struct find_decompressF
|
||||
{
|
||||
// Construction
|
||||
find_decompressF() {}
|
||||
|
||||
// Operation
|
||||
template<typename ForwardIteratorT>
|
||||
iterator_range<ForwardIteratorT> operator()(
|
||||
ForwardIteratorT Begin,
|
||||
ForwardIteratorT End ) const
|
||||
{
|
||||
typedef ForwardIteratorT input_iterator_type;
|
||||
typedef typename boost::detail::iterator_traits<input_iterator_type>::value_type value_type;
|
||||
typedef iterator_range<input_iterator_type> result_type;
|
||||
|
||||
for(input_iterator_type It=Begin; It!=End; It++)
|
||||
{
|
||||
if( *It==repeat_mark<value_type>() )
|
||||
{
|
||||
// Repeat mark found, extract body
|
||||
input_iterator_type It2=It++;
|
||||
|
||||
if ( It==End ) break;
|
||||
It++;
|
||||
if ( It==End ) break;
|
||||
It++;
|
||||
|
||||
return result_type( It2, It );
|
||||
}
|
||||
}
|
||||
|
||||
return result_type( End, End );
|
||||
}
|
||||
};
|
||||
|
||||
// rle decompress format
|
||||
/*
|
||||
transform a repetition block into a sequence of characters
|
||||
*/
|
||||
template< typename SeqT >
|
||||
struct format_decompressF
|
||||
{
|
||||
private:
|
||||
typedef SeqT result_type;
|
||||
typedef typename SeqT::value_type value_type;
|
||||
|
||||
public:
|
||||
// Construction
|
||||
format_decompressF() {};
|
||||
|
||||
// Operation
|
||||
template< typename ReplaceT >
|
||||
result_type operator()( const ReplaceT& Replace ) const
|
||||
{
|
||||
SeqT r;
|
||||
|
||||
if(!Replace.empty())
|
||||
{
|
||||
// extract info
|
||||
typename ReplaceT::const_iterator It=Replace.begin();
|
||||
|
||||
value_type Value=*(++It);
|
||||
value_type Repeat=*(++It);
|
||||
|
||||
for( value_type Index=0; Index<Repeat; Index++ ) r.push_back( Value );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* RLE Compression Example *" << endl << endl;
|
||||
|
||||
string original("123_AA_*ZZZZZZZZZZZZZZ*34");
|
||||
|
||||
// copy compression
|
||||
string compress=find_format_all_copy(
|
||||
original,
|
||||
find_compressF(),
|
||||
format_compressF<string>() );
|
||||
|
||||
cout << "Compressed string: " << compress << endl;
|
||||
|
||||
// Copy decompression
|
||||
string decompress=find_format_all_copy(
|
||||
compress,
|
||||
find_decompressF(),
|
||||
format_decompressF<string>() );
|
||||
|
||||
cout << "Decompressed string: " << decompress << endl;
|
||||
|
||||
// in-place compression
|
||||
find_format_all(
|
||||
original,
|
||||
find_compressF(),
|
||||
format_compressF<string>() );
|
||||
|
||||
cout << "Compressed string: " << original << endl;
|
||||
|
||||
// in-place decompression
|
||||
find_format_all(
|
||||
original,
|
||||
find_decompressF(),
|
||||
format_decompressF<string>() );
|
||||
|
||||
cout << "Decompressed string: " << original << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/algorithm/string/find_iterator.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Split Example *" << endl << endl;
|
||||
|
||||
string str1("abc-*-ABC-*-aBc");
|
||||
|
||||
cout << "Before: " << str1 << endl;
|
||||
|
||||
// Find all 'abc' substrings (ignoring the case)
|
||||
// Create a find_iterator
|
||||
typedef find_iterator<string::iterator> string_find_iterator;
|
||||
for(string_find_iterator It=
|
||||
make_find_iterator(str1, first_finder("abc", is_iequal()));
|
||||
It!=string_find_iterator();
|
||||
++It)
|
||||
{
|
||||
cout << copy_range<std::string>(*It) << endl;
|
||||
// shift all chars in the match by one
|
||||
transform(
|
||||
It->begin(), It->end(),
|
||||
It->begin(),
|
||||
bind2nd( plus<char>(), 1 ) );
|
||||
}
|
||||
|
||||
// Print the string now
|
||||
cout << "After: " << str1 << endl;
|
||||
|
||||
// Split the string into tokens ( use '-' and '*' as delimiters )
|
||||
// We need copies of the input only, and adjacent tokens are compressed
|
||||
vector<std::string> ResultCopy;
|
||||
split(ResultCopy, str1, is_any_of("-*"), token_compress_on);
|
||||
|
||||
for(unsigned int nIndex=0; nIndex<ResultCopy.size(); nIndex++)
|
||||
{
|
||||
cout << nIndex << ":" << ResultCopy[nIndex] << endl;
|
||||
};
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
// Boost string_algo library example file ---------------------------------//
|
||||
|
||||
// Copyright Pavol Droba 2002-2003. Use, modification and
|
||||
// distribution is subject to 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 updates, documentation, and revision history.
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
|
||||
int main()
|
||||
{
|
||||
cout << "* Trim Example *" << endl << endl;
|
||||
|
||||
string str1(" 1x x x x1 ");
|
||||
string str2("<>trim<>");
|
||||
string str3("123abs343");
|
||||
|
||||
// Simple left trim
|
||||
cout << "trim_left copy of str1: " << "\"" << trim_left_copy( str1 ) << "\"" << endl;
|
||||
|
||||
// Inplace right trim
|
||||
trim_right( str1 );
|
||||
cout << "trim_right on str1: " << "\"" << str1 << "\"" << endl;
|
||||
|
||||
// Parametric trim. 'Space' is defined using is_any_of predicate
|
||||
cout
|
||||
<< "trimmed copy of str4 ( space='<>' ): "
|
||||
<< "\""<< trim_copy_if( str2, is_any_of("<>") ) << "\"" << endl;
|
||||
|
||||
|
||||
// Parametric trim. 'Space' is defined using is_digit predicate
|
||||
cout
|
||||
<< "trimmed copy of str5 ( space=digit ): "
|
||||
<< "\"" << trim_copy_if( str3, is_digit() ) << "\"" << endl;
|
||||
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user