Line data Source code
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 0 : inline void insert(
30 : InputT& Input,
31 : BOOST_STRING_TYPENAME InputT::iterator At,
32 : ForwardIteratorT Begin,
33 : ForwardIteratorT End )
34 : {
35 0 : Input.insert( At, Begin, End );
36 0 : }
37 :
38 : template< typename InputT, typename InsertT >
39 0 : inline void insert(
40 : InputT& Input,
41 : BOOST_STRING_TYPENAME InputT::iterator At,
42 : const InsertT& Insert )
43 : {
44 0 : ::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) );
45 0 : }
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 0 : inline typename InputT::iterator erase(
55 : InputT& Input,
56 : BOOST_STRING_TYPENAME InputT::iterator From,
57 : BOOST_STRING_TYPENAME InputT::iterator To )
58 : {
59 0 : 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
|