3 * Copyright (c) 1998-2009 John Maddock
4 * Copyright 2008 Eric Niebler.
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)
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.
21 #ifndef BOOST_REGEX_FORMAT_HPP
22 #define BOOST_REGEX_FORMAT_HPP
24 #include <type_traits>
30 // Forward declaration:
32 template <class BidiIterator, class Allocator = typename std::vector<sub_match<BidiIterator> >::allocator_type >
35 namespace BOOST_REGEX_DETAIL_NS{
38 // struct trivial_format_traits:
39 // defines minimum localisation support for formatting
40 // in the case that the actual regex traits is unavailable.
42 template <class charT>
43 struct trivial_format_traits
45 typedef charT char_type;
47 static std::ptrdiff_t length(const charT* p)
49 return global_length(p);
51 static charT tolower(charT c)
53 return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);
55 static charT toupper(charT c)
57 return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);
59 static int value(const charT c, int radix)
61 int result = global_value(c);
62 return result >= radix ? -1 : result;
64 int toi(const charT*& p1, const charT* p2, int radix)const
66 return (int)global_toi(p1, p2, radix, *this);
70 #ifdef BOOST_REGEX_MSVC
71 # pragma warning(push)
72 #pragma warning(disable:26812)
74 template <class OutputIterator, class Results, class traits, class ForwardIter>
75 class basic_regex_formatter
78 typedef typename traits::char_type char_type;
79 basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
80 : m_traits(t), m_results(r), m_out(o), m_position(), m_end(), m_flags(), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}
81 OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f);
82 OutputIterator format(ForwardIter p1, match_flag_type f)
84 return format(p1, p1 + m_traits.length(p1), f);
87 typedef typename Results::value_type sub_match_type;
98 void put(char_type c);
99 void put(const sub_match_type& sub);
102 void format_escape();
103 void format_conditional();
104 void format_until_scope_end();
105 bool handle_perl_verb(bool have_brace);
107 inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const std::integral_constant<bool, false>&)
109 std::vector<char_type> v(i, j);
110 return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size())
111 : this->m_results.named_subexpression(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
113 inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const std::integral_constant<bool, true>&)
115 return this->m_results.named_subexpression(i, j);
117 inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j)
119 typedef typename std::is_convertible<ForwardIter, const char_type*>::type tag_type;
120 return get_named_sub(i, j, tag_type());
122 inline int get_named_sub_index(ForwardIter i, ForwardIter j, const std::integral_constant<bool, false>&)
124 std::vector<char_type> v(i, j);
125 return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size())
126 : this->m_results.named_subexpression_index(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
128 inline int get_named_sub_index(ForwardIter i, ForwardIter j, const std::integral_constant<bool, true>&)
130 return this->m_results.named_subexpression_index(i, j);
132 inline int get_named_sub_index(ForwardIter i, ForwardIter j)
134 typedef typename std::is_convertible<ForwardIter, const char_type*>::type tag_type;
135 return get_named_sub_index(i, j, tag_type());
137 #ifdef BOOST_REGEX_MSVC
138 // msvc-8.0 issues a spurious warning on the call to std::advance here:
139 #pragma warning(push)
140 #pragma warning(disable:4244)
142 inline int toi(ForwardIter& i, ForwardIter j, int base, const std::integral_constant<bool, false>&)
146 std::vector<char_type> v(i, j);
147 const char_type* start = &v[0];
148 const char_type* pos = start;
149 int r = (int)m_traits.toi(pos, &v[0] + v.size(), base);
150 std::advance(i, pos - start);
155 #ifdef BOOST_REGEX_MSVC
158 inline int toi(ForwardIter& i, ForwardIter j, int base, const std::integral_constant<bool, true>&)
160 return m_traits.toi(i, j, base);
162 inline int toi(ForwardIter& i, ForwardIter j, int base)
164 #if defined(_MSC_VER) && defined(__INTEL_COMPILER) && ((__INTEL_COMPILER == 9999) || (__INTEL_COMPILER == 1210))
165 // Workaround for Intel support issue #656654.
166 // See also https://svn.boost.org/trac/boost/ticket/6359
167 return toi(i, j, base, std::integral_constant<bool, false>());
169 typedef typename std::is_convertible<ForwardIter, const char_type*&>::type tag_type;
170 return toi(i, j, base, tag_type());
174 const traits& m_traits; // the traits class for localised formatting operations
175 const Results& m_results; // the match_results being used.
176 OutputIterator m_out; // where to send output.
177 ForwardIter m_position; // format string, current position
178 ForwardIter m_end; // format string end
179 match_flag_type m_flags; // format flags to use
180 output_state m_state; // what to do with the next character
181 output_state m_restore_state; // what state to restore to.
182 bool m_have_conditional; // we are parsing a conditional
184 basic_regex_formatter(const basic_regex_formatter&);
185 basic_regex_formatter& operator=(const basic_regex_formatter&);
187 #ifdef BOOST_REGEX_MSVC
188 # pragma warning(pop)
191 template <class OutputIterator, class Results, class traits, class ForwardIter>
192 OutputIterator basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format(ForwardIter p1, ForwardIter p2, match_flag_type f)
201 template <class OutputIterator, class Results, class traits, class ForwardIter>
202 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_all()
205 while(m_position != m_end)
210 if(m_flags & ::boost::regex_constants::format_sed)
222 if(m_flags & boost::regex_constants::format_all)
225 bool have_conditional = m_have_conditional;
226 m_have_conditional = false;
227 format_until_scope_end();
228 m_have_conditional = have_conditional;
229 if(m_position == m_end)
231 BOOST_REGEX_ASSERT(*m_position == static_cast<char_type>(')'));
232 ++m_position; // skip the closing ')'
239 if(m_flags & boost::regex_constants::format_all)
247 if((m_flags & boost::regex_constants::format_all) && m_have_conditional)
255 if(m_flags & boost::regex_constants::format_all)
258 format_conditional();
265 if((m_flags & format_sed) == 0)
270 // not a special character:
271 BOOST_REGEX_FALLTHROUGH;
280 template <class OutputIterator, class Results, class traits, class ForwardIter>
281 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_perl()
284 // On entry *m_position points to a '$' character
285 // output the information that goes with it:
287 BOOST_REGEX_ASSERT(*m_position == '$');
289 // see if this is a trailing '$':
291 if(++m_position == m_end)
299 // OK find out what kind it is:
301 bool have_brace = false;
302 ForwardIter save_position = m_position;
307 put(this->m_results[0]);
311 put(this->m_results.prefix());
315 put(this->m_results.suffix());
321 if((++m_position != m_end) && (*m_position == '{'))
323 ForwardIter base = ++m_position;
324 while((m_position != m_end) && (*m_position != '}')) ++m_position;
325 if(m_position != m_end)
327 // Named sub-expression:
328 put(get_named_sub(base, m_position));
337 put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
342 BOOST_REGEX_FALLTHROUGH;
344 // see if we have a number:
346 std::ptrdiff_t len = std::distance(m_position, m_end);
347 //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
348 int v = this->toi(m_position, m_position + len, 10);
349 if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))
351 // Look for a Perl-5.10 verb:
352 if(!handle_perl_verb(have_brace))
354 // leave the $ as is, and carry on:
355 m_position = --save_position;
361 // otherwise output sub v:
362 put(this->m_results[v]);
369 template <class OutputIterator, class Results, class traits, class ForwardIter>
370 bool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle_perl_verb(bool have_brace)
373 // We may have a capitalised string containing a Perl action:
375 static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };
376 static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };
377 static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };
378 static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };
379 static const char_type LAST_SUBMATCH_RESULT[] = { 'L', 'A', 'S', 'T', '_', 'S', 'U', 'B', 'M', 'A', 'T', 'C', 'H', '_', 'R', 'E', 'S', 'U', 'L', 'T' };
380 static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };
382 if(m_position == m_end)
384 if(have_brace && (*m_position == '^'))
387 std::ptrdiff_t max_len = m_end - m_position;
389 if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))
394 if((m_position != m_end) && (*m_position == '}'))
402 put(this->m_results[0]);
405 if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))
410 if((m_position != m_end) && (*m_position == '}'))
418 put(this->m_results.prefix());
421 if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))
426 if((m_position != m_end) && (*m_position == '}'))
434 put(this->m_results.suffix());
437 if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))
442 if((m_position != m_end) && (*m_position == '}'))
450 put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
453 if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))
458 if((m_position != m_end) && (*m_position == '}'))
466 put(this->m_results.get_last_closed_paren());
469 if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))
474 if((m_position != m_end) && (*m_position == '}'))
482 put(this->m_results.get_last_closed_paren());
488 template <class OutputIterator, class Results, class traits, class ForwardIter>
489 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_escape()
491 // skip the escape and check for trailing escape:
492 if(++m_position == m_end)
494 put(static_cast<char_type>('\\'));
497 // now switch on the escape type:
501 put(static_cast<char_type>('\a'));
505 put(static_cast<char_type>('\f'));
509 put(static_cast<char_type>('\n'));
513 put(static_cast<char_type>('\r'));
517 put(static_cast<char_type>('\t'));
521 put(static_cast<char_type>('\v'));
525 if(++m_position == m_end)
527 put(static_cast<char_type>('x'));
530 // maybe have \x{ddd}
531 if(*m_position == static_cast<char_type>('{'))
534 int val = this->toi(m_position, m_end, 16);
537 // invalid value treat everything as literals:
538 put(static_cast<char_type>('x'));
539 put(static_cast<char_type>('{'));
542 if((m_position == m_end) || (*m_position != static_cast<char_type>('}')))
545 while(*m_position != static_cast<char_type>('\\'))
552 put(static_cast<char_type>(val));
557 std::ptrdiff_t len = std::distance(m_position, m_end);
558 len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
559 int val = this->toi(m_position, m_position + len, 16);
566 put(static_cast<char_type>(val));
570 if(++m_position == m_end)
576 put(static_cast<char_type>(*m_position++ % 32));
579 put(static_cast<char_type>(27));
583 // see if we have a perl specific escape:
584 if((m_flags & boost::regex_constants::format_sed) == 0)
586 bool breakout = false;
591 m_restore_state = m_state;
592 m_state = output_next_lower;
597 m_state = output_lower;
602 m_restore_state = m_state;
603 m_state = output_next_upper;
608 m_state = output_upper;
613 m_state = output_copy;
620 // see if we have a \n sed style backreference:
621 std::ptrdiff_t len = std::distance(m_position, m_end);
622 len = (std::min)(static_cast<std::ptrdiff_t>(1), len);
623 int v = this->toi(m_position, m_position+len, 10);
624 if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))
631 // octal ecape sequence:
633 len = std::distance(m_position, m_end);
634 len = (std::min)(static_cast<std::ptrdiff_t>(4), len);
635 v = this->toi(m_position, m_position + len, 8);
636 BOOST_REGEX_ASSERT(v >= 0);
637 put(static_cast<char_type>(v));
640 // Otherwise output the character "as is":
646 template <class OutputIterator, class Results, class traits, class ForwardIter>
647 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_conditional()
649 if(m_position == m_end)
651 // oops trailing '?':
652 put(static_cast<char_type>('?'));
656 if(*m_position == '{')
658 ForwardIter base = m_position;
660 v = this->toi(m_position, m_end, 10);
663 // Try a named subexpression:
664 while((m_position != m_end) && (*m_position != '}'))
666 v = this->get_named_sub_index(base + 1, m_position);
668 if((v < 0) || (*m_position != '}'))
671 // oops trailing '?':
672 put(static_cast<char_type>('?'));
675 // Skip trailing '}':
680 std::ptrdiff_t len = std::distance(m_position, m_end);
681 len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
682 v = this->toi(m_position, m_position + len, 10);
686 // oops not a number:
687 put(static_cast<char_type>('?'));
691 // output varies depending upon whether sub-expression v matched or not:
692 if(m_results[v].matched)
694 m_have_conditional = true;
696 m_have_conditional = false;
697 if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
701 // save output state, then turn it off:
702 output_state saved_state = m_state;
703 m_state = output_none;
704 // format the rest of this scope:
705 format_until_scope_end();
706 // restore output state:
707 m_state = saved_state;
712 // save output state, then turn it off:
713 output_state saved_state = m_state;
714 m_state = output_none;
715 // format until ':' or ')':
716 m_have_conditional = true;
718 m_have_conditional = false;
720 m_state = saved_state;
721 if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
725 // format the rest of this scope:
726 format_until_scope_end();
731 template <class OutputIterator, class Results, class traits, class ForwardIter>
732 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_until_scope_end()
737 if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
740 }while(m_position != m_end);
743 template <class OutputIterator, class Results, class traits, class ForwardIter>
744 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(char_type c)
746 // write a single character to output
747 // according to which case translation mode we are in:
748 switch(this->m_state)
752 case output_next_lower:
753 c = m_traits.tolower(c);
754 this->m_state = m_restore_state;
756 case output_next_upper:
757 c = m_traits.toupper(c);
758 this->m_state = m_restore_state;
761 c = m_traits.tolower(c);
764 c = m_traits.toupper(c);
773 template <class OutputIterator, class Results, class traits, class ForwardIter>
774 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(const sub_match_type& sub)
776 typedef typename sub_match_type::iterator iterator_type;
777 iterator_type i = sub.first;
778 while(i != sub.second)
786 class string_out_iterator
790 string_out_iterator(S& s) : out(&s) {}
791 string_out_iterator& operator++() { return *this; }
792 string_out_iterator& operator++(int) { return *this; }
793 string_out_iterator& operator*() { return *this; }
794 string_out_iterator& operator=(typename S::value_type v)
800 typedef std::ptrdiff_t difference_type;
801 typedef typename S::value_type value_type;
802 typedef value_type* pointer;
803 typedef value_type& reference;
804 typedef std::output_iterator_tag iterator_category;
807 template <class OutputIterator, class Iterator, class Alloc, class ForwardIter, class traits>
808 OutputIterator regex_format_imp(OutputIterator out,
809 const match_results<Iterator, Alloc>& m,
810 ForwardIter p1, ForwardIter p2,
811 match_flag_type flags,
815 if(flags & regex_constants::format_literal)
817 return BOOST_REGEX_DETAIL_NS::copy(p1, p2, out);
820 BOOST_REGEX_DETAIL_NS::basic_regex_formatter<
822 match_results<Iterator, Alloc>,
823 traits, ForwardIter> f(out, m, t);
824 return f.format(p1, p2, flags);
828 struct has_const_iterator
831 static typename U::const_iterator tester(U*);
832 static char tester(...);
836 static const bool value = sizeof(tester(get())) != sizeof(char);
843 template <class T, class U>
844 any_type(const T&, const U&);
845 template <class T, class U, class V>
846 any_type(const T&, const U&, const V&);
848 typedef char no_type;
849 typedef char (&unary_type)[2];
850 typedef char (&binary_type)[3];
851 typedef char (&ternary_type)[4];
853 no_type check_is_formatter(unary_type, binary_type, ternary_type);
855 unary_type check_is_formatter(T const &, binary_type, ternary_type);
857 binary_type check_is_formatter(unary_type, T const &, ternary_type);
858 template<typename T, typename U>
859 binary_type check_is_formatter(T const &, U const &, ternary_type);
861 ternary_type check_is_formatter(unary_type, binary_type, T const &);
862 template<typename T, typename U>
863 ternary_type check_is_formatter(T const &, binary_type, U const &);
864 template<typename T, typename U>
865 ternary_type check_is_formatter(unary_type, T const &, U const &);
866 template<typename T, typename U, typename V>
867 ternary_type check_is_formatter(T const &, U const &, V const &);
869 struct unary_binary_ternary
871 typedef unary_type (*unary_fun)(any_type);
872 typedef binary_type (*binary_fun)(any_type, any_type);
873 typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);
874 operator unary_fun();
875 operator binary_fun();
876 operator ternary_fun();
879 template<typename Formatter, bool IsFunction = std::is_function<Formatter>::value>
880 struct formatter_wrapper
882 , unary_binary_ternary
884 formatter_wrapper(){}
887 template<typename Formatter>
888 struct formatter_wrapper<Formatter, true>
889 : unary_binary_ternary
891 operator Formatter *();
894 template<typename Formatter>
895 struct formatter_wrapper<Formatter *, false>
896 : unary_binary_ternary
898 operator Formatter *();
902 struct do_unwrap_reference
907 struct do_unwrap_reference<std::reference_wrapper<T> >
913 T& do_unwrap_ref(T& r) { return r; }
915 T& do_unwrap_ref(std::reference_wrapper<T> const& r) { return r.get(); }
917 template <class F, class M, class O>
918 struct format_traits_imp
922 // F must be a pointer, a function, or a class with a function call operator:
924 static_assert((::std::is_pointer<F>::value || ::std::is_function<F>::value || ::std::is_class<F>::value), "The functor must be a pointer or a class with a function call operator");
925 static formatter_wrapper<typename do_unwrap_reference<F>::type> f;
928 static boost::regex_constants::match_flag_type flags;
930 static const int value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags)));
933 template <class F, class M, class O>
938 // Type is std::integral_constant<int, N> where N is one of:
940 // 0 : F is a pointer to a presumably null-terminated string.
941 // 1 : F is a character-container such as a std::string.
942 // 2 : F is a Unary Functor.
943 // 3 : F is a Binary Functor.
944 // 4 : F is a Ternary Functor.
946 typedef typename std::conditional<
947 std::is_pointer<F>::value && !std::is_function<typename std::remove_pointer<F>::type>::value,
948 std::integral_constant<int, 0>,
949 typename std::conditional<
950 has_const_iterator<F>::value,
951 std::integral_constant<int, 1>,
952 std::integral_constant<int, format_traits_imp<F, M, O>::value>
956 // This static assertion will fail if the functor passed does not accept
957 // the same type of arguments passed.
959 static_assert( std::is_class<F>::value && !has_const_iterator<F>::value ? (type::value > 1) : true, "Argument mismatch in Functor type");
962 template <class Base, class Match>
963 struct format_functor3
965 format_functor3(Base b) : func(b) {}
966 template <class OutputIter>
967 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f)
969 return do_unwrap_ref(func)(m, i, f);
971 template <class OutputIter, class Traits>
972 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
974 return (*this)(m, i, f);
978 format_functor3(const format_functor3&);
979 format_functor3& operator=(const format_functor3&);
982 template <class Base, class Match>
983 struct format_functor2
985 format_functor2(Base b) : func(b) {}
986 template <class OutputIter>
987 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
989 return do_unwrap_ref(func)(m, i);
991 template <class OutputIter, class Traits>
992 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
994 return (*this)(m, i, f);
998 format_functor2(const format_functor2&);
999 format_functor2& operator=(const format_functor2&);
1002 template <class Base, class Match>
1003 struct format_functor1
1005 format_functor1(Base b) : func(b) {}
1007 template <class S, class OutputIter>
1008 OutputIter do_format_string(const S& s, OutputIter i)
1010 return std::copy(s.begin(), s.end(), i);
1012 template <class S, class OutputIter>
1013 inline OutputIter do_format_string(const S* s, OutputIter i)
1023 template <class OutputIter>
1024 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
1026 return do_format_string(do_unwrap_ref(func)(m), i);
1028 template <class OutputIter, class Traits>
1029 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
1031 return (*this)(m, i, f);
1035 format_functor1(const format_functor1&);
1036 format_functor1& operator=(const format_functor1&);
1039 template <class charT, class Match, class Traits>
1040 struct format_functor_c_string
1042 format_functor_c_string(const charT* ps) : func(ps) {}
1044 template <class OutputIter>
1045 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())
1047 //typedef typename Match::char_type char_type;
1048 const charT* end = func;
1050 return regex_format_imp(i, m, func, end, f, t);
1054 format_functor_c_string(const format_functor_c_string&);
1055 format_functor_c_string& operator=(const format_functor_c_string&);
1058 template <class Container, class Match, class Traits>
1059 struct format_functor_container
1061 format_functor_container(const Container& c) : func(c) {}
1063 template <class OutputIter>
1064 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())
1066 //typedef typename Match::char_type char_type;
1067 return BOOST_REGEX_DETAIL_NS::regex_format_imp(i, m, func.begin(), func.end(), f, t);
1070 const Container& func;
1071 format_functor_container(const format_functor_container&);
1072 format_functor_container& operator=(const format_functor_container&);
1075 template <class Func, class Match, class OutputIterator, class Traits = BOOST_REGEX_DETAIL_NS::trivial_format_traits<typename Match::char_type> >
1076 struct compute_functor_type
1078 typedef typename format_traits<Func, Match, OutputIterator>::type tag;
1079 typedef typename std::remove_cv< typename std::remove_pointer<Func>::type>::type maybe_char_type;
1081 typedef typename std::conditional<
1082 tag::value == 0, format_functor_c_string<maybe_char_type, Match, Traits>,
1083 typename std::conditional<
1084 tag::value == 1, format_functor_container<Func, Match, Traits>,
1085 typename std::conditional<
1086 tag::value == 2, format_functor1<Func, Match>,
1087 typename std::conditional<
1088 tag::value == 3, format_functor2<Func, Match>,
1089 format_functor3<Func, Match>
1096 } // namespace BOOST_REGEX_DETAIL_NS
1098 template <class OutputIterator, class Iterator, class Allocator, class Functor>
1099 inline OutputIterator regex_format(OutputIterator out,
1100 const match_results<Iterator, Allocator>& m,
1102 match_flag_type flags = format_all
1105 return m.format(out, fmt, flags);
1108 template <class Iterator, class Allocator, class Functor>
1109 inline std::basic_string<typename match_results<Iterator, Allocator>::char_type> regex_format(const match_results<Iterator, Allocator>& m,
1111 match_flag_type flags = format_all)
1113 return m.format(fmt, flags);
1116 } // namespace boost
1118 #endif // BOOST_REGEX_FORMAT_HPP