Chris@16: // Boost string_algo library sequence.hpp header file ---------------------------// Chris@16: Chris@16: // Copyright Pavol Droba 2002-2003. Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/ for updates, documentation, and revision history. Chris@16: Chris@16: #ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP Chris@16: #define BOOST_STRING_DETAIL_SEQUENCE_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace algorithm { Chris@16: namespace detail { Chris@16: Chris@16: // insert helpers -------------------------------------------------// Chris@16: Chris@16: template< typename InputT, typename ForwardIteratorT > Chris@16: inline void insert( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator At, Chris@16: ForwardIteratorT Begin, Chris@16: ForwardIteratorT End ) Chris@16: { Chris@16: Input.insert( At, Begin, End ); Chris@16: } Chris@16: Chris@16: template< typename InputT, typename InsertT > Chris@16: inline void insert( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator At, Chris@16: const InsertT& Insert ) Chris@16: { Chris@16: ::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) ); Chris@16: } Chris@16: Chris@16: // erase helper ---------------------------------------------------// Chris@16: Chris@16: // Erase a range in the sequence Chris@16: /* Chris@16: Returns the iterator pointing just after the erase subrange Chris@16: */ Chris@16: template< typename InputT > Chris@16: inline typename InputT::iterator erase( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To ) Chris@16: { Chris@16: return Input.erase( From, To ); Chris@16: } Chris@16: Chris@16: // replace helper implementation ----------------------------------// Chris@16: Chris@16: // Optimized version of replace for generic sequence containers Chris@16: // Assumption: insert and erase are expensive Chris@16: template< bool HasConstTimeOperations > Chris@16: struct replace_const_time_helper Chris@16: { Chris@16: template< typename InputT, typename ForwardIteratorT > Chris@16: void operator()( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To, Chris@16: ForwardIteratorT Begin, Chris@16: ForwardIteratorT End ) Chris@16: { Chris@16: // Copy data to the container ( as much as possible ) Chris@16: ForwardIteratorT InsertIt=Begin; Chris@16: BOOST_STRING_TYPENAME InputT::iterator InputIt=From; Chris@16: for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ ) Chris@16: { Chris@16: *InputIt=*InsertIt; Chris@16: } Chris@16: Chris@16: if ( InsertIt!=End ) Chris@16: { Chris@16: // Replace sequence is longer, insert it Chris@16: Input.insert( InputIt, InsertIt, End ); Chris@16: } Chris@16: else Chris@16: { Chris@16: if ( InputIt!=To ) Chris@16: { Chris@16: // Replace sequence is shorter, erase the rest Chris@16: Input.erase( InputIt, To ); Chris@16: } Chris@16: } Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct replace_const_time_helper< true > Chris@16: { Chris@16: // Const-time erase and insert methods -> use them Chris@16: template< typename InputT, typename ForwardIteratorT > Chris@16: void operator()( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To, Chris@16: ForwardIteratorT Begin, Chris@16: ForwardIteratorT End ) Chris@16: { Chris@16: BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To ); Chris@16: if ( Begin!=End ) Chris@16: { Chris@16: if(!Input.empty()) Chris@16: { Chris@16: Input.insert( At, Begin, End ); Chris@16: } Chris@16: else Chris@16: { Chris@16: Input.insert( Input.begin(), Begin, End ); Chris@16: } Chris@16: } Chris@16: } Chris@16: }; Chris@16: Chris@16: // No native replace method Chris@16: template< bool HasNative > Chris@16: struct replace_native_helper Chris@16: { Chris@16: template< typename InputT, typename ForwardIteratorT > Chris@16: void operator()( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To, Chris@16: ForwardIteratorT Begin, Chris@16: ForwardIteratorT End ) Chris@16: { Chris@16: replace_const_time_helper< Chris@16: boost::mpl::and_< Chris@16: has_const_time_insert, Chris@16: has_const_time_erase >::value >()( Chris@16: Input, From, To, Begin, End ); Chris@16: } Chris@16: }; Chris@16: Chris@16: // Container has native replace method Chris@16: template<> Chris@16: struct replace_native_helper< true > Chris@16: { Chris@16: template< typename InputT, typename ForwardIteratorT > Chris@16: void operator()( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To, Chris@16: ForwardIteratorT Begin, Chris@16: ForwardIteratorT End ) Chris@16: { Chris@16: Input.replace( From, To, Begin, End ); Chris@16: } Chris@16: }; Chris@16: Chris@16: // replace helper -------------------------------------------------// Chris@16: Chris@16: template< typename InputT, typename ForwardIteratorT > Chris@16: inline void replace( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To, Chris@16: ForwardIteratorT Begin, Chris@16: ForwardIteratorT End ) Chris@16: { Chris@16: replace_native_helper< has_native_replace::value >()( Chris@16: Input, From, To, Begin, End ); Chris@16: } Chris@16: Chris@16: template< typename InputT, typename InsertT > Chris@16: inline void replace( Chris@16: InputT& Input, Chris@16: BOOST_STRING_TYPENAME InputT::iterator From, Chris@16: BOOST_STRING_TYPENAME InputT::iterator To, Chris@16: const InsertT& Insert ) Chris@16: { Chris@16: if(From!=To) Chris@16: { Chris@16: ::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) ); Chris@16: } Chris@16: else Chris@16: { Chris@16: ::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) ); Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace algorithm Chris@16: } // namespace boost Chris@16: Chris@16: Chris@16: #endif // BOOST_STRING_DETAIL_SEQUENCE_HPP