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