1 | /*
|
---|
2 | *
|
---|
3 | * Copyright (c) 1998-2002
|
---|
4 | * John Maddock
|
---|
5 | *
|
---|
6 | * Use, modification and distribution are subject to the
|
---|
7 | * Boost Software License, Version 1.0. (See accompanying file
|
---|
8 | * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
---|
9 | *
|
---|
10 | */
|
---|
11 |
|
---|
12 | /*
|
---|
13 | * LOCATION: see http://www.boost.org for most recent version.
|
---|
14 | * FILE regex_format.hpp
|
---|
15 | * VERSION see <boost/version.hpp>
|
---|
16 | * DESCRIPTION: Provides formatting output routines for search and replace
|
---|
17 | * operations. Note this is an internal header file included
|
---|
18 | * by regex.hpp, do not include on its own.
|
---|
19 | */
|
---|
20 |
|
---|
21 | #ifndef BOOST_REGEX_FORMAT_HPP
|
---|
22 | #define BOOST_REGEX_FORMAT_HPP
|
---|
23 |
|
---|
24 |
|
---|
25 | namespace boost{
|
---|
26 |
|
---|
27 | #ifdef BOOST_HAS_ABI_HEADERS
|
---|
28 | # include BOOST_ABI_PREFIX
|
---|
29 | #endif
|
---|
30 |
|
---|
31 | //
|
---|
32 | // Forward declaration:
|
---|
33 | //
|
---|
34 | template <class BidiIterator, class Allocator = BOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >
|
---|
35 | class match_results;
|
---|
36 |
|
---|
37 | namespace re_detail{
|
---|
38 |
|
---|
39 | //
|
---|
40 | // struct trivial_format_traits:
|
---|
41 | // defines minimum localisation support for formatting
|
---|
42 | // in the case that the actual regex traits is unavailable.
|
---|
43 | //
|
---|
44 | template <class charT>
|
---|
45 | struct trivial_format_traits
|
---|
46 | {
|
---|
47 | typedef charT char_type;
|
---|
48 |
|
---|
49 | static std::ptrdiff_t length(const charT* p)
|
---|
50 | {
|
---|
51 | return global_length(p);
|
---|
52 | }
|
---|
53 | static charT tolower(charT c)
|
---|
54 | {
|
---|
55 | return ::boost::re_detail::global_lower(c);
|
---|
56 | }
|
---|
57 | static charT toupper(charT c)
|
---|
58 | {
|
---|
59 | return ::boost::re_detail::global_upper(c);
|
---|
60 | }
|
---|
61 | static int value(const charT c, int radix)
|
---|
62 | {
|
---|
63 | int result = global_value(c);
|
---|
64 | return result >= radix ? -1 : result;
|
---|
65 | }
|
---|
66 | int toi(const charT*& p1, const charT* p2, int radix)const
|
---|
67 | {
|
---|
68 | return global_toi(p1, p2, radix, *this);
|
---|
69 | }
|
---|
70 | };
|
---|
71 |
|
---|
72 | template <class OutputIterator, class Results, class traits>
|
---|
73 | class basic_regex_formatter
|
---|
74 | {
|
---|
75 | public:
|
---|
76 | typedef typename traits::char_type char_type;
|
---|
77 | basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
|
---|
78 | : m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_have_conditional(false) {}
|
---|
79 | OutputIterator format(const char_type* p1, const char_type* p2, match_flag_type f);
|
---|
80 | OutputIterator format(const char_type* p1, match_flag_type f)
|
---|
81 | {
|
---|
82 | return format(p1, p1 + m_traits.length(p1), f);
|
---|
83 | }
|
---|
84 | private:
|
---|
85 | typedef typename Results::value_type sub_match_type;
|
---|
86 | enum output_state
|
---|
87 | {
|
---|
88 | output_copy,
|
---|
89 | output_next_lower,
|
---|
90 | output_next_upper,
|
---|
91 | output_lower,
|
---|
92 | output_upper,
|
---|
93 | output_none
|
---|
94 | };
|
---|
95 |
|
---|
96 | void put(char_type c);
|
---|
97 | void put(const sub_match_type& sub);
|
---|
98 | void format_all();
|
---|
99 | void format_perl();
|
---|
100 | void format_escape();
|
---|
101 | void format_conditional();
|
---|
102 | void format_until_scope_end();
|
---|
103 |
|
---|
104 | const traits& m_traits; // the traits class for localised formatting operations
|
---|
105 | const Results& m_results; // the match_results being used.
|
---|
106 | OutputIterator m_out; // where to send output.
|
---|
107 | const char_type* m_position; // format string, current position
|
---|
108 | const char_type* m_end; // format string end
|
---|
109 | match_flag_type m_flags; // format flags to use
|
---|
110 | output_state m_state; // what to do with the next character
|
---|
111 | bool m_have_conditional; // we are parsing a conditional
|
---|
112 | private:
|
---|
113 | basic_regex_formatter(const basic_regex_formatter&);
|
---|
114 | basic_regex_formatter& operator=(const basic_regex_formatter&);
|
---|
115 | };
|
---|
116 |
|
---|
117 | template <class OutputIterator, class Results, class traits>
|
---|
118 | OutputIterator basic_regex_formatter<OutputIterator, Results, traits>::format(const char_type* p1, const char_type* p2, match_flag_type f)
|
---|
119 | {
|
---|
120 | m_position = p1;
|
---|
121 | m_end = p2;
|
---|
122 | m_flags = f;
|
---|
123 | format_all();
|
---|
124 | return m_out;
|
---|
125 | }
|
---|
126 |
|
---|
127 | template <class OutputIterator, class Results, class traits>
|
---|
128 | void basic_regex_formatter<OutputIterator, Results, traits>::format_all()
|
---|
129 | {
|
---|
130 | // over and over:
|
---|
131 | while(m_position != m_end)
|
---|
132 | {
|
---|
133 | switch(*m_position)
|
---|
134 | {
|
---|
135 | case '&':
|
---|
136 | if(m_flags & ::boost::regex_constants::format_sed)
|
---|
137 | {
|
---|
138 | ++m_position;
|
---|
139 | put(m_results[0]);
|
---|
140 | break;
|
---|
141 | }
|
---|
142 | put(*m_position++);
|
---|
143 | break;
|
---|
144 | case '\\':
|
---|
145 | format_escape();
|
---|
146 | break;
|
---|
147 | case '(':
|
---|
148 | if(m_flags & boost::regex_constants::format_all)
|
---|
149 | {
|
---|
150 | ++m_position;
|
---|
151 | bool have_conditional = m_have_conditional;
|
---|
152 | m_have_conditional = false;
|
---|
153 | format_until_scope_end();
|
---|
154 | m_have_conditional = have_conditional;
|
---|
155 | if(m_position == m_end)
|
---|
156 | return;
|
---|
157 | BOOST_ASSERT(*m_position == static_cast<char_type>(')'));
|
---|
158 | ++m_position; // skip the closing ')'
|
---|
159 | break;
|
---|
160 | }
|
---|
161 | put(*m_position);
|
---|
162 | ++m_position;
|
---|
163 | break;
|
---|
164 | case ')':
|
---|
165 | if(m_flags & boost::regex_constants::format_all)
|
---|
166 | {
|
---|
167 | return;
|
---|
168 | }
|
---|
169 | put(*m_position);
|
---|
170 | ++m_position;
|
---|
171 | break;
|
---|
172 | case ':':
|
---|
173 | if((m_flags & boost::regex_constants::format_all) && m_have_conditional)
|
---|
174 | {
|
---|
175 | return;
|
---|
176 | }
|
---|
177 | put(*m_position);
|
---|
178 | ++m_position;
|
---|
179 | break;
|
---|
180 | case '?':
|
---|
181 | if(m_flags & boost::regex_constants::format_all)
|
---|
182 | {
|
---|
183 | ++m_position;
|
---|
184 | format_conditional();
|
---|
185 | break;
|
---|
186 | }
|
---|
187 | put(*m_position);
|
---|
188 | ++m_position;
|
---|
189 | break;
|
---|
190 | case '$':
|
---|
191 | if((m_flags & format_sed) == 0)
|
---|
192 | {
|
---|
193 | format_perl();
|
---|
194 | break;
|
---|
195 | }
|
---|
196 | // fall through, not a special character:
|
---|
197 | default:
|
---|
198 | put(*m_position);
|
---|
199 | ++m_position;
|
---|
200 | break;
|
---|
201 | }
|
---|
202 | }
|
---|
203 | }
|
---|
204 |
|
---|
205 | template <class OutputIterator, class Results, class traits>
|
---|
206 | void basic_regex_formatter<OutputIterator, Results, traits>::format_perl()
|
---|
207 | {
|
---|
208 | //
|
---|
209 | // On entry *m_position points to a '$' character
|
---|
210 | // output the information that goes with it:
|
---|
211 | //
|
---|
212 | BOOST_ASSERT(*m_position == '$');
|
---|
213 | //
|
---|
214 | // see if this is a trailing '$':
|
---|
215 | //
|
---|
216 | if(++m_position == m_end)
|
---|
217 | {
|
---|
218 | --m_position;
|
---|
219 | put(*m_position);
|
---|
220 | ++m_position;
|
---|
221 | return;
|
---|
222 | }
|
---|
223 | //
|
---|
224 | // OK find out what kind it is:
|
---|
225 | //
|
---|
226 | switch(*m_position)
|
---|
227 | {
|
---|
228 | case '&':
|
---|
229 | ++m_position;
|
---|
230 | put(this->m_results[0]);
|
---|
231 | break;
|
---|
232 | case '`':
|
---|
233 | ++m_position;
|
---|
234 | put(this->m_results.prefix());
|
---|
235 | break;
|
---|
236 | case '\'':
|
---|
237 | ++m_position;
|
---|
238 | put(this->m_results.suffix());
|
---|
239 | break;
|
---|
240 | case '$':
|
---|
241 | put(*m_position++);
|
---|
242 | break;
|
---|
243 | default:
|
---|
244 | // see if we have a number:
|
---|
245 | {
|
---|
246 | std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), ::boost::re_detail::distance(m_position, m_end));
|
---|
247 | int v = m_traits.toi(m_position, m_position + len, 10);
|
---|
248 | if(v < 0)
|
---|
249 | {
|
---|
250 | // leave the $ as is, and carry on:
|
---|
251 | --m_position;
|
---|
252 | put(*m_position);
|
---|
253 | ++m_position;
|
---|
254 | break;
|
---|
255 | }
|
---|
256 | // otherwise output sub v:
|
---|
257 | put(this->m_results[v]);
|
---|
258 | }
|
---|
259 | }
|
---|
260 | }
|
---|
261 |
|
---|
262 | template <class OutputIterator, class Results, class traits>
|
---|
263 | void basic_regex_formatter<OutputIterator, Results, traits>::format_escape()
|
---|
264 | {
|
---|
265 | // skip the escape and check for trailing escape:
|
---|
266 | if(++m_position == m_end)
|
---|
267 | {
|
---|
268 | put(static_cast<char_type>('\\'));
|
---|
269 | return;
|
---|
270 | }
|
---|
271 | // now switch on the escape type:
|
---|
272 | switch(*m_position)
|
---|
273 | {
|
---|
274 | case 'a':
|
---|
275 | put(static_cast<char_type>('\a'));
|
---|
276 | ++m_position;
|
---|
277 | break;
|
---|
278 | case 'f':
|
---|
279 | put(static_cast<char_type>('\f'));
|
---|
280 | ++m_position;
|
---|
281 | break;
|
---|
282 | case 'n':
|
---|
283 | put(static_cast<char_type>('\n'));
|
---|
284 | ++m_position;
|
---|
285 | break;
|
---|
286 | case 'r':
|
---|
287 | put(static_cast<char_type>('\r'));
|
---|
288 | ++m_position;
|
---|
289 | break;
|
---|
290 | case 't':
|
---|
291 | put(static_cast<char_type>('\t'));
|
---|
292 | ++m_position;
|
---|
293 | break;
|
---|
294 | case 'v':
|
---|
295 | put(static_cast<char_type>('\v'));
|
---|
296 | ++m_position;
|
---|
297 | break;
|
---|
298 | case 'x':
|
---|
299 | if(++m_position == m_end)
|
---|
300 | {
|
---|
301 | put(static_cast<char_type>('x'));
|
---|
302 | return;
|
---|
303 | }
|
---|
304 | // maybe have \x{ddd}
|
---|
305 | if(*m_position == static_cast<char_type>('{'))
|
---|
306 | {
|
---|
307 | ++m_position;
|
---|
308 | int val = m_traits.toi(m_position, m_end, 16);
|
---|
309 | if(val < 0)
|
---|
310 | {
|
---|
311 | // invalid value treat everything as literals:
|
---|
312 | put(static_cast<char_type>('x'));
|
---|
313 | put(static_cast<char_type>('{'));
|
---|
314 | return;
|
---|
315 | }
|
---|
316 | if(*m_position != static_cast<char_type>('}'))
|
---|
317 | {
|
---|
318 | while(*m_position != static_cast<char_type>('\\'))
|
---|
319 | --m_position;
|
---|
320 | ++m_position;
|
---|
321 | put(*m_position++);
|
---|
322 | return;
|
---|
323 | }
|
---|
324 | ++m_position;
|
---|
325 | put(static_cast<char_type>(val));
|
---|
326 | return;
|
---|
327 | }
|
---|
328 | else
|
---|
329 | {
|
---|
330 | std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), ::boost::re_detail::distance(m_position, m_end));
|
---|
331 | int val = m_traits.toi(m_position, m_position + len, 16);
|
---|
332 | if(val < 0)
|
---|
333 | {
|
---|
334 | --m_position;
|
---|
335 | put(*m_position++);
|
---|
336 | return;
|
---|
337 | }
|
---|
338 | put(static_cast<char_type>(val));
|
---|
339 | }
|
---|
340 | break;
|
---|
341 | case 'c':
|
---|
342 | if(++m_position == m_end)
|
---|
343 | {
|
---|
344 | --m_position;
|
---|
345 | put(*m_position++);
|
---|
346 | return;
|
---|
347 | }
|
---|
348 | put(static_cast<char_type>(*m_position++ % 32));
|
---|
349 | break;
|
---|
350 | case 'e':
|
---|
351 | put(static_cast<char_type>(27));
|
---|
352 | ++m_position;
|
---|
353 | break;
|
---|
354 | default:
|
---|
355 | // see if we have a perl specific escape:
|
---|
356 | if((m_flags & boost::regex_constants::format_sed) == 0)
|
---|
357 | {
|
---|
358 | bool breakout = false;
|
---|
359 | switch(*m_position)
|
---|
360 | {
|
---|
361 | case 'l':
|
---|
362 | ++m_position;
|
---|
363 | m_state = output_next_lower;
|
---|
364 | breakout = true;
|
---|
365 | break;
|
---|
366 | case 'L':
|
---|
367 | ++m_position;
|
---|
368 | m_state = output_lower;
|
---|
369 | breakout = true;
|
---|
370 | break;
|
---|
371 | case 'u':
|
---|
372 | ++m_position;
|
---|
373 | m_state = output_next_upper;
|
---|
374 | breakout = true;
|
---|
375 | break;
|
---|
376 | case 'U':
|
---|
377 | ++m_position;
|
---|
378 | m_state = output_upper;
|
---|
379 | breakout = true;
|
---|
380 | break;
|
---|
381 | case 'E':
|
---|
382 | ++m_position;
|
---|
383 | m_state = output_copy;
|
---|
384 | breakout = true;
|
---|
385 | break;
|
---|
386 | }
|
---|
387 | if(breakout)
|
---|
388 | break;
|
---|
389 | }
|
---|
390 | // see if we have a \n sed style backreference:
|
---|
391 | int v = m_traits.toi(m_position, m_position+1, 10);
|
---|
392 | if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))
|
---|
393 | {
|
---|
394 | put(m_results[v]);
|
---|
395 | break;
|
---|
396 | }
|
---|
397 | else if(v == 0)
|
---|
398 | {
|
---|
399 | // octal ecape sequence:
|
---|
400 | --m_position;
|
---|
401 | std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(4), ::boost::re_detail::distance(m_position, m_end));
|
---|
402 | v = m_traits.toi(m_position, m_position + len, 8);
|
---|
403 | BOOST_ASSERT(v >= 0);
|
---|
404 | put(static_cast<char_type>(v));
|
---|
405 | break;
|
---|
406 | }
|
---|
407 | // Otherwise output the character "as is":
|
---|
408 | put(*m_position++);
|
---|
409 | break;
|
---|
410 | }
|
---|
411 | }
|
---|
412 |
|
---|
413 | template <class OutputIterator, class Results, class traits>
|
---|
414 | void basic_regex_formatter<OutputIterator, Results, traits>::format_conditional()
|
---|
415 | {
|
---|
416 | if(m_position == m_end)
|
---|
417 | {
|
---|
418 | // oops trailing '?':
|
---|
419 | put(static_cast<char_type>('?'));
|
---|
420 | return;
|
---|
421 | }
|
---|
422 | std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), ::boost::re_detail::distance(m_position, m_end));
|
---|
423 | int v = m_traits.toi(m_position, m_position + len, 10);
|
---|
424 | if(v < 0)
|
---|
425 | {
|
---|
426 | // oops not a number:
|
---|
427 | put(static_cast<char_type>('?'));
|
---|
428 | return;
|
---|
429 | }
|
---|
430 |
|
---|
431 | // output varies depending upon whether sub-expression v matched or not:
|
---|
432 | if(m_results[v].matched)
|
---|
433 | {
|
---|
434 | m_have_conditional = true;
|
---|
435 | format_all();
|
---|
436 | m_have_conditional = false;
|
---|
437 | if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
|
---|
438 | {
|
---|
439 | // skip the ':':
|
---|
440 | ++m_position;
|
---|
441 | // save output state, then turn it off:
|
---|
442 | output_state saved_state = m_state;
|
---|
443 | m_state = output_none;
|
---|
444 | // format the rest of this scope:
|
---|
445 | format_until_scope_end();
|
---|
446 | // restore output state:
|
---|
447 | m_state = saved_state;
|
---|
448 | }
|
---|
449 | }
|
---|
450 | else
|
---|
451 | {
|
---|
452 | // save output state, then turn it off:
|
---|
453 | output_state saved_state = m_state;
|
---|
454 | m_state = output_none;
|
---|
455 | // format until ':' or ')':
|
---|
456 | m_have_conditional = true;
|
---|
457 | format_all();
|
---|
458 | m_have_conditional = false;
|
---|
459 | // restore state:
|
---|
460 | m_state = saved_state;
|
---|
461 | if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
|
---|
462 | {
|
---|
463 | // skip the ':':
|
---|
464 | ++m_position;
|
---|
465 | // format the rest of this scope:
|
---|
466 | format_until_scope_end();
|
---|
467 | }
|
---|
468 | }
|
---|
469 | }
|
---|
470 |
|
---|
471 | template <class OutputIterator, class Results, class traits>
|
---|
472 | void basic_regex_formatter<OutputIterator, Results, traits>::format_until_scope_end()
|
---|
473 | {
|
---|
474 | do
|
---|
475 | {
|
---|
476 | format_all();
|
---|
477 | if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
|
---|
478 | return;
|
---|
479 | put(*m_position++);
|
---|
480 | }while(m_position != m_end);
|
---|
481 | }
|
---|
482 |
|
---|
483 | template <class OutputIterator, class Results, class traits>
|
---|
484 | void basic_regex_formatter<OutputIterator, Results, traits>::put(char_type c)
|
---|
485 | {
|
---|
486 | // write a single character to output
|
---|
487 | // according to which case translation mode we are in:
|
---|
488 | switch(this->m_state)
|
---|
489 | {
|
---|
490 | case output_none:
|
---|
491 | return;
|
---|
492 | case output_next_lower:
|
---|
493 | c = m_traits.tolower(c);
|
---|
494 | this->m_state = output_copy;
|
---|
495 | break;
|
---|
496 | case output_next_upper:
|
---|
497 | c = m_traits.toupper(c);
|
---|
498 | this->m_state = output_copy;
|
---|
499 | break;
|
---|
500 | case output_lower:
|
---|
501 | c = m_traits.tolower(c);
|
---|
502 | break;
|
---|
503 | case output_upper:
|
---|
504 | c = m_traits.toupper(c);
|
---|
505 | break;
|
---|
506 | default:
|
---|
507 | break;
|
---|
508 | }
|
---|
509 | *m_out = c;
|
---|
510 | ++m_out;
|
---|
511 | }
|
---|
512 |
|
---|
513 | template <class OutputIterator, class Results, class traits>
|
---|
514 | void basic_regex_formatter<OutputIterator, Results, traits>::put(const sub_match_type& sub)
|
---|
515 | {
|
---|
516 | typedef typename sub_match_type::iterator iterator_type;
|
---|
517 | iterator_type i = sub.first;
|
---|
518 | while(i != sub.second)
|
---|
519 | {
|
---|
520 | put(*i);
|
---|
521 | ++i;
|
---|
522 | }
|
---|
523 | }
|
---|
524 |
|
---|
525 | template <class S>
|
---|
526 | class string_out_iterator
|
---|
527 | #ifndef BOOST_NO_STD_ITERATOR
|
---|
528 | : public std::iterator<std::output_iterator_tag, typename S::value_type>
|
---|
529 | #endif
|
---|
530 | {
|
---|
531 | S* out;
|
---|
532 | public:
|
---|
533 | string_out_iterator(S& s) : out(&s) {}
|
---|
534 | string_out_iterator& operator++() { return *this; }
|
---|
535 | string_out_iterator& operator++(int) { return *this; }
|
---|
536 | string_out_iterator& operator*() { return *this; }
|
---|
537 | string_out_iterator& operator=(typename S::value_type v)
|
---|
538 | {
|
---|
539 | out->append(1, v);
|
---|
540 | return *this;
|
---|
541 | }
|
---|
542 |
|
---|
543 | #ifdef BOOST_NO_STD_ITERATOR
|
---|
544 | typedef std::ptrdiff_t difference_type;
|
---|
545 | typedef typename S::value_type value_type;
|
---|
546 | typedef value_type* pointer;
|
---|
547 | typedef value_type& reference;
|
---|
548 | typedef std::output_iterator_tag iterator_category;
|
---|
549 | #endif
|
---|
550 | };
|
---|
551 |
|
---|
552 | template <class OutputIterator, class Iterator, class Alloc, class charT, class traits>
|
---|
553 | OutputIterator regex_format_imp(OutputIterator out,
|
---|
554 | const match_results<Iterator, Alloc>& m,
|
---|
555 | const charT* p1, const charT* p2,
|
---|
556 | match_flag_type flags,
|
---|
557 | const traits& t
|
---|
558 | )
|
---|
559 | {
|
---|
560 | if(flags & regex_constants::format_literal)
|
---|
561 | {
|
---|
562 | return re_detail::copy(p1, p2, out);
|
---|
563 | }
|
---|
564 |
|
---|
565 | re_detail::basic_regex_formatter<
|
---|
566 | OutputIterator,
|
---|
567 | match_results<Iterator, Alloc>,
|
---|
568 | traits > f(out, m, t);
|
---|
569 | return f.format(p1, p2, flags);
|
---|
570 | }
|
---|
571 |
|
---|
572 |
|
---|
573 | } // namespace re_detail
|
---|
574 |
|
---|
575 | template <class OutputIterator, class Iterator, class charT>
|
---|
576 | OutputIterator regex_format(OutputIterator out,
|
---|
577 | const match_results<Iterator>& m,
|
---|
578 | const charT* fmt,
|
---|
579 | match_flag_type flags = format_all
|
---|
580 | )
|
---|
581 | {
|
---|
582 | re_detail::trivial_format_traits<charT> traits;
|
---|
583 | return re_detail::regex_format_imp(out, m, fmt, fmt + traits.length(fmt), flags, traits);
|
---|
584 | }
|
---|
585 |
|
---|
586 | template <class OutputIterator, class Iterator, class charT>
|
---|
587 | OutputIterator regex_format(OutputIterator out,
|
---|
588 | const match_results<Iterator>& m,
|
---|
589 | const std::basic_string<charT>& fmt,
|
---|
590 | match_flag_type flags = format_all
|
---|
591 | )
|
---|
592 | {
|
---|
593 | re_detail::trivial_format_traits<charT> traits;
|
---|
594 | return re_detail::regex_format_imp(out, m, fmt.data(), fmt.data() + fmt.size(), flags, traits);
|
---|
595 | }
|
---|
596 |
|
---|
597 | template <class Iterator, class charT>
|
---|
598 | std::basic_string<charT> regex_format(const match_results<Iterator>& m,
|
---|
599 | const charT* fmt,
|
---|
600 | match_flag_type flags = format_all)
|
---|
601 | {
|
---|
602 | std::basic_string<charT> result;
|
---|
603 | re_detail::string_out_iterator<std::basic_string<charT> > i(result);
|
---|
604 | re_detail::trivial_format_traits<charT> traits;
|
---|
605 | re_detail::regex_format_imp(i, m, fmt, fmt + traits.length(fmt), flags, traits);
|
---|
606 | return result;
|
---|
607 | }
|
---|
608 |
|
---|
609 | template <class Iterator, class charT>
|
---|
610 | std::basic_string<charT> regex_format(const match_results<Iterator>& m,
|
---|
611 | const std::basic_string<charT>& fmt,
|
---|
612 | match_flag_type flags = format_all)
|
---|
613 | {
|
---|
614 | std::basic_string<charT> result;
|
---|
615 | re_detail::string_out_iterator<std::basic_string<charT> > i(result);
|
---|
616 | re_detail::trivial_format_traits<charT> traits;
|
---|
617 | re_detail::regex_format_imp(i, m, fmt.data(), fmt.data() + fmt.size(), flags, traits);
|
---|
618 | return result;
|
---|
619 | }
|
---|
620 |
|
---|
621 | #ifdef BOOST_HAS_ABI_HEADERS
|
---|
622 | # include BOOST_ABI_SUFFIX
|
---|
623 | #endif
|
---|
624 |
|
---|
625 | } // namespace boost
|
---|
626 |
|
---|
627 | #endif // BOOST_REGEX_FORMAT_HPP
|
---|
628 |
|
---|
629 |
|
---|
630 |
|
---|
631 |
|
---|
632 |
|
---|
633 |
|
---|