1 // Boost string_algo library sequence.hpp header file ---------------------------// 2 3 // Copyright Pavol Droba 2002-2003. 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 // See http://www.boost.org/ for updates, documentation, and revision history. 10 11 #ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP 12 #define BOOST_STRING_DETAIL_SEQUENCE_HPP 13 14 #include <boost/algorithm/string/config.hpp> 15 #include <boost/mpl/bool.hpp> 16 #include <boost/mpl/logical.hpp> 17 #include <boost/range/begin.hpp> 18 #include <boost/range/end.hpp> 19 20 #include <boost/algorithm/string/sequence_traits.hpp> 21 22 namespace boost { 23 namespace algorithm { 24 namespace detail { 25 26 // insert helpers -------------------------------------------------// 27 28 template< typename InputT, typename ForwardIteratorT > insert(InputT & Input,BOOST_STRING_TYPENAME InputT::iterator At,ForwardIteratorT Begin,ForwardIteratorT End)29 inline void insert( 30 InputT& Input, 31 BOOST_STRING_TYPENAME InputT::iterator At, 32 ForwardIteratorT Begin, 33 ForwardIteratorT End ) 34 { 35 Input.insert( At, Begin, End ); 36 } 37 38 template< typename InputT, typename InsertT > insert(InputT & Input,BOOST_STRING_TYPENAME InputT::iterator At,const InsertT & Insert)39 inline void insert( 40 InputT& Input, 41 BOOST_STRING_TYPENAME InputT::iterator At, 42 const InsertT& Insert ) 43 { 44 ::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) ); 45 } 46 47 // erase helper ---------------------------------------------------// 48 49 // Erase a range in the sequence 50 /* 51 Returns the iterator pointing just after the erase subrange 52 */ 53 template< typename InputT > erase(InputT & Input,BOOST_STRING_TYPENAME InputT::iterator From,BOOST_STRING_TYPENAME InputT::iterator To)54 inline typename InputT::iterator erase( 55 InputT& Input, 56 BOOST_STRING_TYPENAME InputT::iterator From, 57 BOOST_STRING_TYPENAME InputT::iterator To ) 58 { 59 return Input.erase( From, To ); 60 } 61 62 // replace helper implementation ----------------------------------// 63 64 // Optimized version of replace for generic sequence containers 65 // Assumption: insert and erase are expensive 66 template< bool HasConstTimeOperations > 67 struct replace_const_time_helper 68 { 69 template< typename InputT, typename ForwardIteratorT > operator ()boost::algorithm::detail::replace_const_time_helper70 void operator()( 71 InputT& Input, 72 BOOST_STRING_TYPENAME InputT::iterator From, 73 BOOST_STRING_TYPENAME InputT::iterator To, 74 ForwardIteratorT Begin, 75 ForwardIteratorT End ) 76 { 77 // Copy data to the container ( as much as possible ) 78 ForwardIteratorT InsertIt=Begin; 79 BOOST_STRING_TYPENAME InputT::iterator InputIt=From; 80 for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ ) 81 { 82 *InputIt=*InsertIt; 83 } 84 85 if ( InsertIt!=End ) 86 { 87 // Replace sequence is longer, insert it 88 Input.insert( InputIt, InsertIt, End ); 89 } 90 else 91 { 92 if ( InputIt!=To ) 93 { 94 // Replace sequence is shorter, erase the rest 95 Input.erase( InputIt, To ); 96 } 97 } 98 } 99 }; 100 101 template<> 102 struct replace_const_time_helper< true > 103 { 104 // Const-time erase and insert methods -> use them 105 template< typename InputT, typename ForwardIteratorT > operator ()boost::algorithm::detail::replace_const_time_helper106 void operator()( 107 InputT& Input, 108 BOOST_STRING_TYPENAME InputT::iterator From, 109 BOOST_STRING_TYPENAME InputT::iterator To, 110 ForwardIteratorT Begin, 111 ForwardIteratorT End ) 112 { 113 BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To ); 114 if ( Begin!=End ) 115 { 116 if(!Input.empty()) 117 { 118 Input.insert( At, Begin, End ); 119 } 120 else 121 { 122 Input.insert( Input.begin(), Begin, End ); 123 } 124 } 125 } 126 }; 127 128 // No native replace method 129 template< bool HasNative > 130 struct replace_native_helper 131 { 132 template< typename InputT, typename ForwardIteratorT > operator ()boost::algorithm::detail::replace_native_helper133 void operator()( 134 InputT& Input, 135 BOOST_STRING_TYPENAME InputT::iterator From, 136 BOOST_STRING_TYPENAME InputT::iterator To, 137 ForwardIteratorT Begin, 138 ForwardIteratorT End ) 139 { 140 replace_const_time_helper< 141 boost::mpl::and_< 142 has_const_time_insert<InputT>, 143 has_const_time_erase<InputT> >::value >()( 144 Input, From, To, Begin, End ); 145 } 146 }; 147 148 // Container has native replace method 149 template<> 150 struct replace_native_helper< true > 151 { 152 template< typename InputT, typename ForwardIteratorT > operator ()boost::algorithm::detail::replace_native_helper153 void operator()( 154 InputT& Input, 155 BOOST_STRING_TYPENAME InputT::iterator From, 156 BOOST_STRING_TYPENAME InputT::iterator To, 157 ForwardIteratorT Begin, 158 ForwardIteratorT End ) 159 { 160 Input.replace( From, To, Begin, End ); 161 } 162 }; 163 164 // replace helper -------------------------------------------------// 165 166 template< typename InputT, typename ForwardIteratorT > replace(InputT & Input,BOOST_STRING_TYPENAME InputT::iterator From,BOOST_STRING_TYPENAME InputT::iterator To,ForwardIteratorT Begin,ForwardIteratorT End)167 inline void replace( 168 InputT& Input, 169 BOOST_STRING_TYPENAME InputT::iterator From, 170 BOOST_STRING_TYPENAME InputT::iterator To, 171 ForwardIteratorT Begin, 172 ForwardIteratorT End ) 173 { 174 replace_native_helper< has_native_replace<InputT>::value >()( 175 Input, From, To, Begin, End ); 176 } 177 178 template< typename InputT, typename InsertT > replace(InputT & Input,BOOST_STRING_TYPENAME InputT::iterator From,BOOST_STRING_TYPENAME InputT::iterator To,const InsertT & Insert)179 inline void replace( 180 InputT& Input, 181 BOOST_STRING_TYPENAME InputT::iterator From, 182 BOOST_STRING_TYPENAME InputT::iterator To, 183 const InsertT& Insert ) 184 { 185 if(From!=To) 186 { 187 ::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) ); 188 } 189 else 190 { 191 ::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) ); 192 } 193 } 194 195 } // namespace detail 196 } // namespace algorithm 197 } // namespace boost 198 199 200 #endif // BOOST_STRING_DETAIL_SEQUENCE_HPP 201