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 > |
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 | |