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
22namespace boost {
23 namespace algorithm {
24 namespace detail {
25
26// insert helpers -------------------------------------------------//
27
28 template< typename InputT, typename ForwardIteratorT >
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 >
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 >
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 >
70 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 >
106 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 >
133 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 >
153 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 >
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 >
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