201 lines
7.4 KiB
C++
201 lines
7.4 KiB
C++
// 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)
|
|
|
|
// See http://www.boost.org/ for updates, documentation, and revision history.
|
|
|
|
#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP
|
|
#define BOOST_STRING_DETAIL_SEQUENCE_HPP
|
|
|
|
#include <boost/algorithm/string/config.hpp>
|
|
#include <boost/mpl/bool.hpp>
|
|
#include <boost/mpl/logical.hpp>
|
|
#include <boost/range/begin.hpp>
|
|
#include <boost/range/end.hpp>
|
|
|
|
#include <boost/algorithm/string/sequence_traits.hpp>
|
|
|
|
namespace boost {
|
|
namespace algorithm {
|
|
namespace detail {
|
|
|
|
// insert helpers -------------------------------------------------//
|
|
|
|
template< typename InputT, typename ForwardIteratorT >
|
|
inline void insert(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator At,
|
|
ForwardIteratorT Begin,
|
|
ForwardIteratorT End )
|
|
{
|
|
Input.insert( At, Begin, End );
|
|
}
|
|
|
|
template< typename InputT, typename InsertT >
|
|
inline void insert(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator At,
|
|
const InsertT& Insert )
|
|
{
|
|
::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) );
|
|
}
|
|
|
|
// erase helper ---------------------------------------------------//
|
|
|
|
// Erase a range in the sequence
|
|
/*
|
|
Returns the iterator pointing just after the erase subrange
|
|
*/
|
|
template< typename InputT >
|
|
inline typename InputT::iterator erase(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To )
|
|
{
|
|
return Input.erase( From, To );
|
|
}
|
|
|
|
// replace helper implementation ----------------------------------//
|
|
|
|
// Optimized version of replace for generic sequence containers
|
|
// Assumption: insert and erase are expensive
|
|
template< bool HasConstTimeOperations >
|
|
struct replace_const_time_helper
|
|
{
|
|
template< typename InputT, typename ForwardIteratorT >
|
|
void operator()(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To,
|
|
ForwardIteratorT Begin,
|
|
ForwardIteratorT End )
|
|
{
|
|
// Copy data to the container ( as much as possible )
|
|
ForwardIteratorT InsertIt=Begin;
|
|
BOOST_STRING_TYPENAME InputT::iterator InputIt=From;
|
|
for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ )
|
|
{
|
|
*InputIt=*InsertIt;
|
|
}
|
|
|
|
if ( InsertIt!=End )
|
|
{
|
|
// Replace sequence is longer, insert it
|
|
Input.insert( InputIt, InsertIt, End );
|
|
}
|
|
else
|
|
{
|
|
if ( InputIt!=To )
|
|
{
|
|
// Replace sequence is shorter, erase the rest
|
|
Input.erase( InputIt, To );
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct replace_const_time_helper< true >
|
|
{
|
|
// Const-time erase and insert methods -> use them
|
|
template< typename InputT, typename ForwardIteratorT >
|
|
void operator()(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To,
|
|
ForwardIteratorT Begin,
|
|
ForwardIteratorT End )
|
|
{
|
|
BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To );
|
|
if ( Begin!=End )
|
|
{
|
|
if(!Input.empty())
|
|
{
|
|
Input.insert( At, Begin, End );
|
|
}
|
|
else
|
|
{
|
|
Input.insert( Input.begin(), Begin, End );
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// No native replace method
|
|
template< bool HasNative >
|
|
struct replace_native_helper
|
|
{
|
|
template< typename InputT, typename ForwardIteratorT >
|
|
void operator()(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To,
|
|
ForwardIteratorT Begin,
|
|
ForwardIteratorT End )
|
|
{
|
|
replace_const_time_helper<
|
|
boost::mpl::and_<
|
|
has_const_time_insert<InputT>,
|
|
has_const_time_erase<InputT> >::value >()(
|
|
Input, From, To, Begin, End );
|
|
}
|
|
};
|
|
|
|
// Container has native replace method
|
|
template<>
|
|
struct replace_native_helper< true >
|
|
{
|
|
template< typename InputT, typename ForwardIteratorT >
|
|
void operator()(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To,
|
|
ForwardIteratorT Begin,
|
|
ForwardIteratorT End )
|
|
{
|
|
Input.replace( From, To, Begin, End );
|
|
}
|
|
};
|
|
|
|
// replace helper -------------------------------------------------//
|
|
|
|
template< typename InputT, typename ForwardIteratorT >
|
|
inline void replace(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To,
|
|
ForwardIteratorT Begin,
|
|
ForwardIteratorT End )
|
|
{
|
|
replace_native_helper< has_native_replace<InputT>::value >()(
|
|
Input, From, To, Begin, End );
|
|
}
|
|
|
|
template< typename InputT, typename InsertT >
|
|
inline void replace(
|
|
InputT& Input,
|
|
BOOST_STRING_TYPENAME InputT::iterator From,
|
|
BOOST_STRING_TYPENAME InputT::iterator To,
|
|
const InsertT& Insert )
|
|
{
|
|
if(From!=To)
|
|
{
|
|
::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) );
|
|
}
|
|
else
|
|
{
|
|
::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) );
|
|
}
|
|
}
|
|
|
|
} // namespace detail
|
|
} // namespace algorithm
|
|
} // namespace boost
|
|
|
|
|
|
#endif // BOOST_STRING_DETAIL_SEQUENCE_HPP
|