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