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