You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
200 lines
7.4 KiB
200 lines
7.4 KiB
// 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
|
|
|