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 <boost/type_traits/is_pointer.hpp>
25 #include <boost/type_traits/is_function.hpp>
26 #include <boost/type_traits/is_class.hpp>
27 #include <boost/type_traits/is_same.hpp>
28 #include <boost/type_traits/is_convertible.hpp>
29 #include <boost/type_traits/remove_pointer.hpp>
30 #include <boost/type_traits/remove_cv.hpp>
31 #include <boost/mpl/if.hpp>
32 #include <boost/mpl/and.hpp>
33 #include <boost/mpl/not.hpp>
34 #ifndef BOOST_NO_SFINAE
35 #include <boost/mpl/has_xxx.hpp>
37 #include <boost/ref.hpp>
43 #pragma warning(disable: 4103)
45 #ifdef BOOST_HAS_ABI_HEADERS
46 # include BOOST_ABI_PREFIX
53 // Forward declaration:
55 template <class BidiIterator, class Allocator = BOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >
61 // struct trivial_format_traits:
62 // defines minimum localisation support for formatting
63 // in the case that the actual regex traits is unavailable.
65 template <class charT>
66 struct trivial_format_traits
68 typedef charT char_type;
70 static std::ptrdiff_t length(const charT* p)
72 return global_length(p);
74 static charT tolower(charT c)
76 return ::boost::re_detail::global_lower(c);
78 static charT toupper(charT c)
80 return ::boost::re_detail::global_upper(c);
82 static int value(const charT c, int radix)
84 int result = global_value(c);
85 return result >= radix ? -1 : result;
87 int toi(const charT*& p1, const charT* p2, int radix)const
89 return global_toi(p1, p2, radix, *this);
93 template <class OutputIterator, class Results, class traits, class ForwardIter>
94 class basic_regex_formatter
97 typedef typename traits::char_type char_type;
98 basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
99 : m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}
100 OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f);
101 OutputIterator format(ForwardIter p1, match_flag_type f)
103 return format(p1, p1 + m_traits.length(p1), f);
106 typedef typename Results::value_type sub_match_type;
117 void put(char_type c);
118 void put(const sub_match_type& sub);
121 void format_escape();
122 void format_conditional();
123 void format_until_scope_end();
124 bool handle_perl_verb(bool have_brace);
126 inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::false_&)
128 std::vector<char_type> v(i, j);
129 return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size())
130 : this->m_results.named_subexpression(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
132 inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::true_&)
134 return this->m_results.named_subexpression(i, j);
136 inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j)
138 typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type;
139 return get_named_sub(i, j, tag_type());
141 inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::false_&)
143 std::vector<char_type> v(i, j);
144 return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size())
145 : this->m_results.named_subexpression_index(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
147 inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::true_&)
149 return this->m_results.named_subexpression_index(i, j);
151 inline int get_named_sub_index(ForwardIter i, ForwardIter j)
153 typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type;
154 return get_named_sub_index(i, j, tag_type());
157 // msvc-8.0 issues a spurious warning on the call to std::advance here:
158 #pragma warning(push)
159 #pragma warning(disable:4244)
161 inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::false_&)
165 std::vector<char_type> v(i, j);
166 const char_type* start = &v[0];
167 const char_type* pos = start;
168 int r = m_traits.toi(pos, &v[0] + v.size(), base);
169 std::advance(i, pos - start);
177 inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::true_&)
179 return m_traits.toi(i, j, base);
181 inline int toi(ForwardIter& i, ForwardIter j, int base)
183 typedef typename boost::is_convertible<ForwardIter, const char_type*&>::type tag_type;
184 return toi(i, j, base, tag_type());
187 const traits& m_traits; // the traits class for localised formatting operations
188 const Results& m_results; // the match_results being used.
189 OutputIterator m_out; // where to send output.
190 ForwardIter m_position; // format string, current position
191 ForwardIter m_end; // format string end
192 match_flag_type m_flags; // format flags to use
193 output_state m_state; // what to do with the next character
194 output_state m_restore_state; // what state to restore to.
195 bool m_have_conditional; // we are parsing a conditional
197 basic_regex_formatter(const basic_regex_formatter&);
198 basic_regex_formatter& operator=(const basic_regex_formatter&);
201 template <class OutputIterator, class Results, class traits, class ForwardIter>
202 OutputIterator basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format(ForwardIter p1, ForwardIter p2, match_flag_type f)
211 template <class OutputIterator, class Results, class traits, class ForwardIter>
212 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_all()
215 while(m_position != m_end)
220 if(m_flags & ::boost::regex_constants::format_sed)
232 if(m_flags & boost::regex_constants::format_all)
235 bool have_conditional = m_have_conditional;
236 m_have_conditional = false;
237 format_until_scope_end();
238 m_have_conditional = have_conditional;
239 if(m_position == m_end)
241 BOOST_ASSERT(*m_position == static_cast<char_type>(')'));
242 ++m_position; // skip the closing ')'
249 if(m_flags & boost::regex_constants::format_all)
257 if((m_flags & boost::regex_constants::format_all) && m_have_conditional)
265 if(m_flags & boost::regex_constants::format_all)
268 format_conditional();
275 if((m_flags & format_sed) == 0)
280 // fall through, not a special character:
289 template <class OutputIterator, class Results, class traits, class ForwardIter>
290 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_perl()
293 // On entry *m_position points to a '$' character
294 // output the information that goes with it:
296 BOOST_ASSERT(*m_position == '$');
298 // see if this is a trailing '$':
300 if(++m_position == m_end)
308 // OK find out what kind it is:
310 bool have_brace = false;
311 ForwardIter save_position = m_position;
316 put(this->m_results[0]);
320 put(this->m_results.prefix());
324 put(this->m_results.suffix());
330 if((++m_position != m_end) && (*m_position == '{'))
332 ForwardIter base = ++m_position;
333 while((m_position != m_end) && (*m_position != '}')) ++m_position;
334 if(m_position != m_end)
336 // Named sub-expression:
337 put(get_named_sub(base, m_position));
346 put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
353 // see if we have a number:
355 std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
356 //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
357 int v = this->toi(m_position, m_position + len, 10);
358 if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))
360 // Look for a Perl-5.10 verb:
361 if(!handle_perl_verb(have_brace))
363 // leave the $ as is, and carry on:
364 m_position = --save_position;
370 // otherwise output sub v:
371 put(this->m_results[v]);
378 template <class OutputIterator, class Results, class traits, class ForwardIter>
379 bool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle_perl_verb(bool have_brace)
382 // We may have a capitalised string containing a Perl action:
384 static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };
385 static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };
386 static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };
387 static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };
388 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' };
389 static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };
391 if(m_position == m_end)
393 if(have_brace && (*m_position == '^'))
396 std::ptrdiff_t max_len = m_end - m_position;
398 if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))
403 if((m_position != m_end) && (*m_position == '}'))
411 put(this->m_results[0]);
414 if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))
419 if((m_position != m_end) && (*m_position == '}'))
427 put(this->m_results.prefix());
430 if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))
435 if((m_position != m_end) && (*m_position == '}'))
443 put(this->m_results.suffix());
446 if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))
451 if((m_position != m_end) && (*m_position == '}'))
459 put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
462 if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))
467 if((m_position != m_end) && (*m_position == '}'))
475 put(this->m_results.get_last_closed_paren());
478 if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))
483 if((m_position != m_end) && (*m_position == '}'))
491 put(this->m_results.get_last_closed_paren());
497 template <class OutputIterator, class Results, class traits, class ForwardIter>
498 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_escape()
500 // skip the escape and check for trailing escape:
501 if(++m_position == m_end)
503 put(static_cast<char_type>('\\'));
506 // now switch on the escape type:
510 put(static_cast<char_type>('\a'));
514 put(static_cast<char_type>('\f'));
518 put(static_cast<char_type>('\n'));
522 put(static_cast<char_type>('\r'));
526 put(static_cast<char_type>('\t'));
530 put(static_cast<char_type>('\v'));
534 if(++m_position == m_end)
536 put(static_cast<char_type>('x'));
539 // maybe have \x{ddd}
540 if(*m_position == static_cast<char_type>('{'))
543 int val = this->toi(m_position, m_end, 16);
546 // invalid value treat everything as literals:
547 put(static_cast<char_type>('x'));
548 put(static_cast<char_type>('{'));
551 if((m_position == m_end) || (*m_position != static_cast<char_type>('}')))
554 while(*m_position != static_cast<char_type>('\\'))
561 put(static_cast<char_type>(val));
566 std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
567 len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
568 int val = this->toi(m_position, m_position + len, 16);
575 put(static_cast<char_type>(val));
579 if(++m_position == m_end)
585 put(static_cast<char_type>(*m_position++ % 32));
588 put(static_cast<char_type>(27));
592 // see if we have a perl specific escape:
593 if((m_flags & boost::regex_constants::format_sed) == 0)
595 bool breakout = false;
600 m_restore_state = m_state;
601 m_state = output_next_lower;
606 m_state = output_lower;
611 m_restore_state = m_state;
612 m_state = output_next_upper;
617 m_state = output_upper;
622 m_state = output_copy;
629 // see if we have a \n sed style backreference:
630 std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
631 len = (std::min)(static_cast<std::ptrdiff_t>(1), len);
632 int v = this->toi(m_position, m_position+len, 10);
633 if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))
640 // octal ecape sequence:
642 len = ::boost::re_detail::distance(m_position, m_end);
643 len = (std::min)(static_cast<std::ptrdiff_t>(4), len);
644 v = this->toi(m_position, m_position + len, 8);
645 BOOST_ASSERT(v >= 0);
646 put(static_cast<char_type>(v));
649 // Otherwise output the character "as is":
655 template <class OutputIterator, class Results, class traits, class ForwardIter>
656 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_conditional()
658 if(m_position == m_end)
660 // oops trailing '?':
661 put(static_cast<char_type>('?'));
665 if(*m_position == '{')
667 ForwardIter base = m_position;
669 v = this->toi(m_position, m_end, 10);
672 // Try a named subexpression:
673 while((m_position != m_end) && (*m_position != '}'))
675 v = this->get_named_sub_index(base + 1, m_position);
677 if((v < 0) || (*m_position != '}'))
680 // oops trailing '?':
681 put(static_cast<char_type>('?'));
684 // Skip trailing '}':
689 std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end);
690 len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
691 v = this->toi(m_position, m_position + len, 10);
695 // oops not a number:
696 put(static_cast<char_type>('?'));
700 // output varies depending upon whether sub-expression v matched or not:
701 if(m_results[v].matched)
703 m_have_conditional = true;
705 m_have_conditional = false;
706 if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
710 // save output state, then turn it off:
711 output_state saved_state = m_state;
712 m_state = output_none;
713 // format the rest of this scope:
714 format_until_scope_end();
715 // restore output state:
716 m_state = saved_state;
721 // save output state, then turn it off:
722 output_state saved_state = m_state;
723 m_state = output_none;
724 // format until ':' or ')':
725 m_have_conditional = true;
727 m_have_conditional = false;
729 m_state = saved_state;
730 if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
734 // format the rest of this scope:
735 format_until_scope_end();
740 template <class OutputIterator, class Results, class traits, class ForwardIter>
741 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_until_scope_end()
746 if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
749 }while(m_position != m_end);
752 template <class OutputIterator, class Results, class traits, class ForwardIter>
753 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(char_type c)
755 // write a single character to output
756 // according to which case translation mode we are in:
757 switch(this->m_state)
761 case output_next_lower:
762 c = m_traits.tolower(c);
763 this->m_state = m_restore_state;
765 case output_next_upper:
766 c = m_traits.toupper(c);
767 this->m_state = m_restore_state;
770 c = m_traits.tolower(c);
773 c = m_traits.toupper(c);
782 template <class OutputIterator, class Results, class traits, class ForwardIter>
783 void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(const sub_match_type& sub)
785 typedef typename sub_match_type::iterator iterator_type;
786 iterator_type i = sub.first;
787 while(i != sub.second)
795 class string_out_iterator
796 #ifndef BOOST_NO_STD_ITERATOR
797 : public std::iterator<std::output_iterator_tag, typename S::value_type>
802 string_out_iterator(S& s) : out(&s) {}
803 string_out_iterator& operator++() { return *this; }
804 string_out_iterator& operator++(int) { return *this; }
805 string_out_iterator& operator*() { return *this; }
806 string_out_iterator& operator=(typename S::value_type v)
812 #ifdef BOOST_NO_STD_ITERATOR
813 typedef std::ptrdiff_t difference_type;
814 typedef typename S::value_type value_type;
815 typedef value_type* pointer;
816 typedef value_type& reference;
817 typedef std::output_iterator_tag iterator_category;
821 template <class OutputIterator, class Iterator, class Alloc, class ForwardIter, class traits>
822 OutputIterator regex_format_imp(OutputIterator out,
823 const match_results<Iterator, Alloc>& m,
824 ForwardIter p1, ForwardIter p2,
825 match_flag_type flags,
829 if(flags & regex_constants::format_literal)
831 return re_detail::copy(p1, p2, out);
834 re_detail::basic_regex_formatter<
836 match_results<Iterator, Alloc>,
837 traits, ForwardIter> f(out, m, t);
838 return f.format(p1, p2, flags);
841 #ifndef BOOST_NO_SFINAE
843 BOOST_MPL_HAS_XXX_TRAIT_DEF(const_iterator)
849 template <class T, class U>
850 any_type(const T&, const U&);
851 template <class T, class U, class V>
852 any_type(const T&, const U&, const V&);
854 typedef char no_type;
855 typedef char (&unary_type)[2];
856 typedef char (&binary_type)[3];
857 typedef char (&ternary_type)[4];
859 no_type check_is_formatter(unary_type, binary_type, ternary_type);
861 unary_type check_is_formatter(T const &, binary_type, ternary_type);
863 binary_type check_is_formatter(unary_type, T const &, ternary_type);
864 template<typename T, typename U>
865 binary_type check_is_formatter(T const &, U const &, ternary_type);
867 ternary_type check_is_formatter(unary_type, binary_type, T const &);
868 template<typename T, typename U>
869 ternary_type check_is_formatter(T const &, binary_type, U const &);
870 template<typename T, typename U>
871 ternary_type check_is_formatter(unary_type, T const &, U const &);
872 template<typename T, typename U, typename V>
873 ternary_type check_is_formatter(T const &, U const &, V const &);
875 struct unary_binary_ternary
877 typedef unary_type (*unary_fun)(any_type);
878 typedef binary_type (*binary_fun)(any_type, any_type);
879 typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);
880 operator unary_fun();
881 operator binary_fun();
882 operator ternary_fun();
885 template<typename Formatter, bool IsFunction = boost::is_function<Formatter>::value>
886 struct formatter_wrapper
888 , unary_binary_ternary
890 formatter_wrapper(){}
893 template<typename Formatter>
894 struct formatter_wrapper<Formatter, true>
895 : unary_binary_ternary
897 operator Formatter *();
900 template<typename Formatter>
901 struct formatter_wrapper<Formatter *, false>
902 : unary_binary_ternary
904 operator Formatter *();
907 template <class F, class M, class O>
908 struct format_traits_imp
912 // F must be a pointer, a function, or a class with a function call operator:
914 BOOST_STATIC_ASSERT((::boost::is_pointer<F>::value || ::boost::is_function<F>::value || ::boost::is_class<F>::value));
915 static formatter_wrapper<typename unwrap_reference<F>::type> f;
918 static boost::regex_constants::match_flag_type flags;
920 BOOST_STATIC_CONSTANT(int, value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags))));
923 template <class F, class M, class O>
928 // Type is mpl::int_<N> where N is one of:
930 // 0 : F is a pointer to a presumably null-terminated string.
931 // 1 : F is a character-container such as a std::string.
932 // 2 : F is a Unary Functor.
933 // 3 : F is a Binary Functor.
934 // 4 : F is a Ternary Functor.
936 typedef typename boost::mpl::if_<
937 boost::mpl::and_<boost::is_pointer<F>, boost::mpl::not_<boost::is_function<typename boost::remove_pointer<F>::type> > >,
939 typename boost::mpl::if_<
940 has_const_iterator<F>,
942 boost::mpl::int_<format_traits_imp<F, M, O>::value>
946 // This static assertion will fail if the functor passed does not accept
947 // the same type of arguments passed.
949 BOOST_STATIC_ASSERT( boost::is_class<F>::value && !has_const_iterator<F>::value ? (type::value > 1) : true);
952 #else // BOOST_NO_SFINAE
954 template <class F, class M, class O>
959 // Type is mpl::int_<N> where N is one of:
961 // 0 : F is a pointer to a presumably null-terminated string.
962 // 1 : F is a character-container such as a std::string.
964 // Other options such as F being a Functor are not supported without
967 typedef typename boost::mpl::if_<
968 boost::is_pointer<F>,
974 #endif // BOOST_NO_SFINAE
976 template <class Base, class Match>
977 struct format_functor3
979 format_functor3(Base b) : func(b) {}
980 template <class OutputIter>
981 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f)
983 return boost::unwrap_ref(func)(m, i, f);
985 template <class OutputIter, class Traits>
986 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
988 return (*this)(m, i, f);
992 format_functor3(const format_functor3&);
993 format_functor3& operator=(const format_functor3&);
996 template <class Base, class Match>
997 struct format_functor2
999 format_functor2(Base b) : func(b) {}
1000 template <class OutputIter>
1001 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
1003 return boost::unwrap_ref(func)(m, i);
1005 template <class OutputIter, class Traits>
1006 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
1008 return (*this)(m, i, f);
1012 format_functor2(const format_functor2&);
1013 format_functor2& operator=(const format_functor2&);
1016 template <class Base, class Match>
1017 struct format_functor1
1019 format_functor1(Base b) : func(b) {}
1021 template <class S, class OutputIter>
1022 OutputIter do_format_string(const S& s, OutputIter i)
1024 return re_detail::copy(s.begin(), s.end(), i);
1026 template <class S, class OutputIter>
1027 inline OutputIter do_format_string(const S* s, OutputIter i)
1037 template <class OutputIter>
1038 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
1040 return do_format_string(boost::unwrap_ref(func)(m), i);
1042 template <class OutputIter, class Traits>
1043 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
1045 return (*this)(m, i, f);
1049 format_functor1(const format_functor1&);
1050 format_functor1& operator=(const format_functor1&);
1053 template <class charT, class Match, class Traits>
1054 struct format_functor_c_string
1056 format_functor_c_string(const charT* ps) : func(ps) {}
1058 template <class OutputIter>
1059 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())
1061 typedef typename Match::char_type char_type;
1062 const charT* end = func;
1064 return regex_format_imp(i, m, func, end, f, t);
1068 format_functor_c_string(const format_functor_c_string&);
1069 format_functor_c_string& operator=(const format_functor_c_string&);
1072 template <class Container, class Match, class Traits>
1073 struct format_functor_container
1075 format_functor_container(const Container& c) : func(c) {}
1077 template <class OutputIter>
1078 OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())
1080 typedef typename Match::char_type char_type;
1081 return re_detail::regex_format_imp(i, m, func.begin(), func.end(), f, t);
1084 const Container& func;
1085 format_functor_container(const format_functor_container&);
1086 format_functor_container& operator=(const format_functor_container&);
1089 template <class Func, class Match, class OutputIterator, class Traits = re_detail::trivial_format_traits<typename Match::char_type> >
1090 struct compute_functor_type
1092 typedef typename format_traits<Func, Match, OutputIterator>::type tag;
1093 typedef typename boost::remove_cv< typename boost::remove_pointer<Func>::type>::type maybe_char_type;
1095 typedef typename mpl::if_<
1096 ::boost::is_same<tag, mpl::int_<0> >, format_functor_c_string<maybe_char_type, Match, Traits>,
1098 ::boost::is_same<tag, mpl::int_<1> >, format_functor_container<Func, Match, Traits>,
1100 ::boost::is_same<tag, mpl::int_<2> >, format_functor1<Func, Match>,
1102 ::boost::is_same<tag, mpl::int_<3> >, format_functor2<Func, Match>,
1103 format_functor3<Func, Match>
1110 } // namespace re_detail
1112 template <class OutputIterator, class Iterator, class Allocator, class Functor>
1113 inline OutputIterator regex_format(OutputIterator out,
1114 const match_results<Iterator, Allocator>& m,
1116 match_flag_type flags = format_all
1119 return m.format(out, fmt, flags);
1122 template <class Iterator, class Allocator, class Functor>
1123 inline std::basic_string<typename match_results<Iterator, Allocator>::char_type> regex_format(const match_results<Iterator, Allocator>& m,
1125 match_flag_type flags = format_all)
1127 return m.format(fmt, flags);
1131 #pragma warning(push)
1132 #pragma warning(disable: 4103)
1134 #ifdef BOOST_HAS_ABI_HEADERS
1135 # include BOOST_ABI_SUFFIX
1138 #pragma warning(pop)
1141 } // namespace boost
1143 #endif // BOOST_REGEX_FORMAT_HPP