forked from boostorg/algorithm
		
	
		
			
				
	
	
		
			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
 |