1 //  Boost string_algo library find_format_all.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_FIND_FORMAT_ALL_DETAIL_HPP
12 #define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
13 
14 #include <boost/algorithm/string/config.hpp>
15 #include <boost/range/iterator_range_core.hpp>
16 #include <boost/range/const_iterator.hpp>
17 #include <boost/range/value_type.hpp>
18 #include <boost/algorithm/string/detail/find_format_store.hpp>
19 #include <boost/algorithm/string/detail/replace_storage.hpp>
20 
21 #include <deque>
22 
23 namespace boost {
24     namespace algorithm {
25         namespace detail {
26 
27 // find_format_all_copy (iterator variant) implementation ---------------------------//
28 
29            template<
30                 typename OutputIteratorT,
31                 typename InputT,
32                 typename FinderT,
33                 typename FormatterT,
34                 typename FindResultT,
35                 typename FormatResultT >
find_format_all_copy_impl2(OutputIteratorT Output,const InputT & Input,FinderT Finder,FormatterT Formatter,const FindResultT & FindResult,const FormatResultT & FormatResult)36             inline OutputIteratorT find_format_all_copy_impl2(
37                 OutputIteratorT Output,
38                 const InputT& Input,
39                 FinderT Finder,
40                 FormatterT Formatter,
41                 const FindResultT& FindResult,
42                 const FormatResultT& FormatResult )
43             {
44                 typedef BOOST_STRING_TYPENAME
45                     range_const_iterator<InputT>::type input_iterator_type;
46 
47                 typedef find_format_store<
48                         input_iterator_type,
49                         FormatterT,
50                         FormatResultT > store_type;
51 
52                 // Create store for the find result
53                 store_type M( FindResult, FormatResult, Formatter );
54 
55                 // Initialize last match
56                 input_iterator_type LastMatch=::boost::begin(Input);
57 
58                 // Iterate through all matches
59                 while( M )
60                 {
61                     // Copy the beginning of the sequence
62                     Output = std::copy( LastMatch, M.begin(), Output );
63                     // Copy formatted result
64                     Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output );
65 
66                     // Proceed to the next match
67                     LastMatch=M.end();
68                     M=Finder( LastMatch, ::boost::end(Input) );
69                 }
70 
71                 // Copy the rest of the sequence
72                 Output = std::copy( LastMatch, ::boost::end(Input), Output );
73 
74                 return Output;
75             }
76 
77             template<
78                 typename OutputIteratorT,
79                 typename InputT,
80                 typename FinderT,
81                 typename FormatterT,
82                 typename FindResultT >
find_format_all_copy_impl(OutputIteratorT Output,const InputT & Input,FinderT Finder,FormatterT Formatter,const FindResultT & FindResult)83             inline OutputIteratorT find_format_all_copy_impl(
84                 OutputIteratorT Output,
85                 const InputT& Input,
86                 FinderT Finder,
87                 FormatterT Formatter,
88                 const FindResultT& FindResult )
89             {
90                 if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
91                     return ::boost::algorithm::detail::find_format_all_copy_impl2(
92                         Output,
93                         Input,
94                         Finder,
95                         Formatter,
96                         FindResult,
97                         Formatter(FindResult) );
98                 } else {
99                     return std::copy( ::boost::begin(Input), ::boost::end(Input), Output );
100                 }
101             }
102 
103  // find_format_all_copy implementation ----------------------------------------------//
104 
105            template<
106                 typename InputT,
107                 typename FinderT,
108                 typename FormatterT,
109                 typename FindResultT,
110                 typename FormatResultT >
find_format_all_copy_impl2(const InputT & Input,FinderT Finder,FormatterT Formatter,const FindResultT & FindResult,const FormatResultT & FormatResult)111             inline InputT find_format_all_copy_impl2(
112                 const InputT& Input,
113                 FinderT Finder,
114                 FormatterT Formatter,
115                 const FindResultT& FindResult,
116                 const FormatResultT& FormatResult)
117             {
118                 typedef BOOST_STRING_TYPENAME
119                     range_const_iterator<InputT>::type input_iterator_type;
120 
121                 typedef find_format_store<
122                         input_iterator_type,
123                         FormatterT,
124                         FormatResultT > store_type;
125 
126                 // Create store for the find result
127                 store_type M( FindResult, FormatResult, Formatter );
128 
129                 // Initialize last match
130                 input_iterator_type LastMatch=::boost::begin(Input);
131 
132                 // Output temporary
133                 InputT Output;
134 
135                 // Iterate through all matches
136                 while( M )
137                 {
138                     // Copy the beginning of the sequence
139                     boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, M.begin() );
140                     // Copy formatted result
141                     boost::algorithm::detail::insert( Output, ::boost::end(Output), M.format_result() );
142 
143                     // Proceed to the next match
144                     LastMatch=M.end();
145                     M=Finder( LastMatch, ::boost::end(Input) );
146                 }
147 
148                 // Copy the rest of the sequence
149                 ::boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, ::boost::end(Input) );
150 
151                 return Output;
152             }
153 
154             template<
155                 typename InputT,
156                 typename FinderT,
157                 typename FormatterT,
158                 typename FindResultT >
find_format_all_copy_impl(const InputT & Input,FinderT Finder,FormatterT Formatter,const FindResultT & FindResult)159             inline InputT find_format_all_copy_impl(
160                 const InputT& Input,
161                 FinderT Finder,
162                 FormatterT Formatter,
163                 const FindResultT& FindResult)
164             {
165                 if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
166                     return ::boost::algorithm::detail::find_format_all_copy_impl2(
167                         Input,
168                         Finder,
169                         Formatter,
170                         FindResult,
171                         Formatter(FindResult) );
172                 } else {
173                     return Input;
174                 }
175             }
176 
177  // find_format_all implementation ------------------------------------------------//
178 
179             template<
180                 typename InputT,
181                 typename FinderT,
182                 typename FormatterT,
183                 typename FindResultT,
184                 typename FormatResultT >
find_format_all_impl2(InputT & Input,FinderT Finder,FormatterT Formatter,FindResultT FindResult,FormatResultT FormatResult)185             inline void find_format_all_impl2(
186                 InputT& Input,
187                 FinderT Finder,
188                 FormatterT Formatter,
189                 FindResultT FindResult,
190                 FormatResultT FormatResult)
191             {
192                 typedef BOOST_STRING_TYPENAME
193                     range_iterator<InputT>::type input_iterator_type;
194                 typedef find_format_store<
195                         input_iterator_type,
196                         FormatterT,
197                         FormatResultT > store_type;
198 
199                 // Create store for the find result
200                 store_type M( FindResult, FormatResult, Formatter );
201 
202                 // Instantiate replacement storage
203                 std::deque<
204                     BOOST_STRING_TYPENAME range_value<InputT>::type> Storage;
205 
206                 // Initialize replacement iterators
207                 input_iterator_type InsertIt=::boost::begin(Input);
208                 input_iterator_type SearchIt=::boost::begin(Input);
209 
210                 while( M )
211                 {
212                     // process the segment
213                     InsertIt=process_segment(
214                         Storage,
215                         Input,
216                         InsertIt,
217                         SearchIt,
218                         M.begin() );
219 
220                     // Adjust search iterator
221                     SearchIt=M.end();
222 
223                     // Copy formatted replace to the storage
224                     ::boost::algorithm::detail::copy_to_storage( Storage, M.format_result() );
225 
226                     // Find range for a next match
227                     M=Finder( SearchIt, ::boost::end(Input) );
228                 }
229 
230                 // process the last segment
231                 InsertIt=::boost::algorithm::detail::process_segment(
232                     Storage,
233                     Input,
234                     InsertIt,
235                     SearchIt,
236                     ::boost::end(Input) );
237 
238                 if ( Storage.empty() )
239                 {
240                     // Truncate input
241                     ::boost::algorithm::detail::erase( Input, InsertIt, ::boost::end(Input) );
242                 }
243                 else
244                 {
245                     // Copy remaining data to the end of input
246                     ::boost::algorithm::detail::insert( Input, ::boost::end(Input), Storage.begin(), Storage.end() );
247                 }
248             }
249 
250             template<
251                 typename InputT,
252                 typename FinderT,
253                 typename FormatterT,
254                 typename FindResultT >
find_format_all_impl(InputT & Input,FinderT Finder,FormatterT Formatter,FindResultT FindResult)255             inline void find_format_all_impl(
256                 InputT& Input,
257                 FinderT Finder,
258                 FormatterT Formatter,
259                 FindResultT FindResult)
260             {
261                 if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) {
262                     ::boost::algorithm::detail::find_format_all_impl2(
263                         Input,
264                         Finder,
265                         Formatter,
266                         FindResult,
267                         Formatter(FindResult) );
268                 }
269             }
270 
271         } // namespace detail
272     } // namespace algorithm
273 } // namespace boost
274 
275 #endif  // BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
276