diff --git a/doc/history.qbk b/doc/history.qbk index 360f8922..4f78bcee 100644 --- a/doc/history.qbk +++ b/doc/history.qbk @@ -8,6 +8,10 @@ [section:history History] +[h4 Boost 1.42] + +* Added support for Functors rather than strings as format expressions. + [h4 Boost 1.40] * Added support for many Perl 5.10 syntax elements including named diff --git a/doc/html/boost_regex/background_information/examples.html b/doc/html/boost_regex/background_information/examples.html index 39bd0df1..2c2e3639 100644 --- a/doc/html/boost_regex/background_information/examples.html +++ b/doc/html/boost_regex/background_information/examples.html @@ -28,7 +28,7 @@ Example Programs
- + Test Programs
@@ -107,7 +107,7 @@ Files: captures_test.cpp.

- + Example programs
@@ -133,7 +133,7 @@ Files: regex_timer.cpp.

- + Code snippets
diff --git a/doc/html/boost_regex/background_information/history.html b/doc/html/boost_regex/background_information/history.html index 084381fc..b5b7a907 100644 --- a/doc/html/boost_regex/background_information/history.html +++ b/doc/html/boost_regex/background_information/history.html @@ -25,8 +25,16 @@

History

+
+ + Boost + 1.42 +
+
- + Boost 1.40
@@ -35,7 +43,7 @@ branch resets and recursive regular expressions.
- + Boost 1.38
@@ -62,7 +70,7 @@
- + Boost 1.34
@@ -85,7 +93,7 @@
- + Boost 1.33.1
@@ -155,7 +163,7 @@
- + Boost 1.33.0
@@ -210,7 +218,7 @@
- + Boost 1.32.1
@@ -218,7 +226,7 @@ Fixed bug in partial matches of bounded repeats of '.'.
- + Boost 1.31.0
diff --git a/doc/html/boost_regex/background_information/locale.html b/doc/html/boost_regex/background_information/locale.html index eb901bae..732fb07e 100644 --- a/doc/html/boost_regex/background_information/locale.html +++ b/doc/html/boost_regex/background_information/locale.html @@ -58,7 +58,7 @@ There are three separate localization mechanisms supported by Boost.Regex:

- + Win32 localization model.
@@ -90,7 +90,7 @@ are treated as "unknown" graphic characters.

- + C localization model.
@@ -114,7 +114,7 @@ libraries including version 1 of this library.

- + C++ localization model.
@@ -151,7 +151,7 @@ in your code. The best way to ensure this is to add the #define to <boost/regex/user.hpp>.

- + Providing a message catalogue
diff --git a/doc/html/boost_regex/background_information/standards.html b/doc/html/boost_regex/background_information/standards.html index 31c09f0d..e0df6eec 100644 --- a/doc/html/boost_regex/background_information/standards.html +++ b/doc/html/boost_regex/background_information/standards.html @@ -28,7 +28,7 @@ Conformance
- + C++

@@ -36,7 +36,7 @@ Report on C++ Library Extensions.

- + ECMAScript / JavaScript
@@ -49,7 +49,7 @@ rather than a Unicode escape sequence; use \x{DDDD} for Unicode escape sequences.

- + Perl

@@ -62,7 +62,7 @@ (??{code}) Not implementable in a compiled strongly typed language.

- + POSIX

@@ -82,7 +82,7 @@ a custom traits class.

- + Unicode

diff --git a/doc/html/boost_regex/captures.html b/doc/html/boost_regex/captures.html index c6345106..a977b271 100644 --- a/doc/html/boost_regex/captures.html +++ b/doc/html/boost_regex/captures.html @@ -35,7 +35,7 @@ accessed.

- + Marked sub-expressions

@@ -218,7 +218,7 @@ output stream.

- + Unmatched Sub-Expressions

@@ -231,7 +231,7 @@ you can determine which sub-expressions matched by accessing the sub_match::matched data member.

- + Repeated Captures

diff --git a/doc/html/boost_regex/format/boost_format_syntax.html b/doc/html/boost_regex/format/boost_format_syntax.html index 90053a97..8461f686 100644 --- a/doc/html/boost_regex/format/boost_format_syntax.html +++ b/doc/html/boost_regex/format/boost_format_syntax.html @@ -32,7 +32,7 @@ '$', '\', '(', ')', '?', and ':'.

- + Grouping

@@ -40,7 +40,7 @@ you want a to output literal parenthesis.

- + Conditionals

@@ -79,7 +79,7 @@ ?{NAME}true-expression:false-expression

- + Placeholder Sequences
@@ -319,7 +319,7 @@ as a literal.

- + Escape Sequences
diff --git a/doc/html/boost_regex/install.html b/doc/html/boost_regex/install.html index 3f61840d..e6c47fd0 100644 --- a/doc/html/boost_regex/install.html +++ b/doc/html/boost_regex/install.html @@ -49,7 +49,7 @@ file before you can use it, instructions for specific platforms are as follows:

- + Building with bjam

@@ -58,7 +58,7 @@ started guide for more information.

- + Building With Unicode and ICU Support
@@ -96,11 +96,11 @@ ICU you are using is binary compatible with the toolset you use to build Boost.

- + Building via makefiles
- + Borland C++ Builder:
- + GCC(2.95 and later)

@@ -302,7 +302,7 @@ see the config library documentation.

- + Sun Workshop 6.1

@@ -347,7 +347,7 @@ will build v9 variants of the regex library named libboost_regex_v9.a etc.

- + Makefiles for Other compilers
diff --git a/doc/html/boost_regex/ref/bad_expression.html b/doc/html/boost_regex/ref/bad_expression.html index f4b5f922..9954dc42 100644 --- a/doc/html/boost_regex/ref/bad_expression.html +++ b/doc/html/boost_regex/ref/bad_expression.html @@ -27,7 +27,7 @@ bad_expression
- + Synopsis
#include <boost/pattern_except.hpp>
@@ -54,7 +54,7 @@
 } // namespace boost
 
- + Description
regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos);
diff --git a/doc/html/boost_regex/ref/basic_regex.html b/doc/html/boost_regex/ref/basic_regex.html
index 30d3449c..a630316d 100644
--- a/doc/html/boost_regex/ref/basic_regex.html
+++ b/doc/html/boost_regex/ref/basic_regex.html
@@ -27,7 +27,7 @@
  basic_regex
 
 
- + Synopsis
#include <boost/regex.hpp>
@@ -244,7 +244,7 @@
 } // namespace boost
 
- + Description

@@ -327,7 +327,7 @@ basic_regex.

-

Table 1. basic_regex default construction postconditions

+

Table 1. basic_regex default construction postconditions

@@ -407,7 +407,7 @@ flags specified in f.

-

Table 2. Postconditions for basic_regex construction

+

Table 2. Postconditions for basic_regex construction

@@ -512,7 +512,7 @@ specified in f.

-

Table 3. Postconditions for basic_regex construction

+

Table 3. Postconditions for basic_regex construction

@@ -616,7 +616,7 @@ according the option flags specified in f.

-

Table 4. Postconditions for basic_regex construction

+

Table 4. Postconditions for basic_regex construction

@@ -727,7 +727,7 @@ flags specified in f.

-

Table 5. Postconditions for basic_regex construction

+

Table 5. Postconditions for basic_regex construction

@@ -829,7 +829,7 @@ flags specified in f.

-

Table 6. Postconditions for basic_regex construction

+

Table 6. Postconditions for basic_regex construction

@@ -1043,7 +1043,7 @@ in f.

-

Table 7. Postconditions for basic_regex::assign

+

Table 7. Postconditions for basic_regex::assign

diff --git a/doc/html/boost_regex/ref/concepts/traits_concept.html b/doc/html/boost_regex/ref/concepts/traits_concept.html index 3d051b83..18b1d732 100644 --- a/doc/html/boost_regex/ref/concepts/traits_concept.html +++ b/doc/html/boost_regex/ref/concepts/traits_concept.html @@ -34,7 +34,7 @@ Boost-specific enhanced interface.

- + Minimal requirements.
@@ -381,7 +381,7 @@
- + Additional Optional Requirements
diff --git a/doc/html/boost_regex/ref/deprecated_interfaces/regex_format.html b/doc/html/boost_regex/ref/deprecated_interfaces/regex_format.html index 8e482ee8..291ee71f 100644 --- a/doc/html/boost_regex/ref/deprecated_interfaces/regex_format.html +++ b/doc/html/boost_regex/ref/deprecated_interfaces/regex_format.html @@ -34,7 +34,7 @@ previous version of Boost.Regex and will not be further updated:

- + Algorithm regex_format
@@ -46,15 +46,10 @@ string, regex_format can be used for search and replace operations:

-
template <class OutputIterator, class iterator, class Allocator, class charT>
+
template <class OutputIterator, class iterator, class Allocator, class Formatter>
 OutputIterator regex_format(OutputIterator out,
                            const match_results<iterator, Allocator>& m,
-                           const charT* fmt,
-                           match_flag_type flags = 0);
-template <class OutputIterator, class iterator, class Allocator, class charT>
-OutputIterator regex_format(OutputIterator out,
-                           const match_results<iterator, Allocator>& m,
-                           const std::basic_string<charT>& fmt,
+                           Formatter fmt,
                            match_flag_type flags = 0);
 

@@ -71,16 +66,10 @@ form, depending upon your compilers capabilities

-
template <class iterator, class Allocator, class charT>
+
template <class iterator, class Allocator, class Formatter>
 std::basic_string<charT> regex_format
                                  (const match_results<iterator, Allocator>& m, 
-                                 const charT* fmt,
-                                 match_flag_type flags = 0);
-
-template <class iterator, class Allocator, class charT>
-std::basic_string<charT> regex_format
-                                 (const match_results<iterator, Allocator>& m, 
-                                 const std::basic_string<charT>& fmt,
+                                 Formatter fmt,
                                  match_flag_type flags = 0);
 

@@ -133,13 +122,14 @@

- const charT* fmt + Formatter fmt

- A format string that determines how the match is transformed into - the new string. + Either a format string that determines how the match is transformed + into the new string, or a functor that computes the new string + from m - see match_results<>::format.

diff --git a/doc/html/boost_regex/ref/error_type.html b/doc/html/boost_regex/ref/error_type.html index 331567be..f8c7c708 100644 --- a/doc/html/boost_regex/ref/error_type.html +++ b/doc/html/boost_regex/ref/error_type.html @@ -27,7 +27,7 @@ error_type
- + Synopsis

@@ -57,7 +57,7 @@ } // namespace boost

- + Description

diff --git a/doc/html/boost_regex/ref/match_flag_type.html b/doc/html/boost_regex/ref/match_flag_type.html index 102543d0..dd1a72cf 100644 --- a/doc/html/boost_regex/ref/match_flag_type.html +++ b/doc/html/boost_regex/ref/match_flag_type.html @@ -69,7 +69,7 @@ } // namespace boost

- + Description

diff --git a/doc/html/boost_regex/ref/match_results.html b/doc/html/boost_regex/ref/match_results.html index 6e8f7c0b..ddb66e3f 100644 --- a/doc/html/boost_regex/ref/match_results.html +++ b/doc/html/boost_regex/ref/match_results.html @@ -27,7 +27,7 @@ match_results

- + Synopsis
#include <boost/regex.hpp>
@@ -132,11 +132,12 @@
    const_iterator begin() const;
    const_iterator end() const;
    // format:
-   template <class OutputIterator>
+   template <class OutputIterator, class Formatter>
    OutputIterator format(OutputIterator out,
-                        const string_type& fmt,
+                        Formatter fmt,
                         match_flag_type flags = format_default) const;
-   string_type format(const string_type& fmt,
+   template <class Formatter>
+   string_type format(Formatter fmt,
                      match_flag_type flags = format_default) const;
 
    allocator_type get_allocator() const;
@@ -166,7 +167,7 @@
          match_results<BidirectionalIterator, Allocator>& m2);
 
- + Description

@@ -558,18 +559,32 @@

-
template <class OutputIterator>
+
template <class OutputIterator, class Formatter>
 OutputIterator format(OutputIterator out,
-                     const string_type& fmt,
-                     match_flag_type flags = format_default);
+                      Formatter fmt,
+                      match_flag_type flags = format_default);
 

Requires: The type OutputIterator conforms to the Output Iterator requirements (C++ std 24.1.2).

- Effects: Copies the character sequence - [fmt.begin(), fmt.end()) + The type Formatter must be + either a pointer to a null-terminated string of type char_type[], or be a container of char_type's + (for example std::basic_string<char_type>) + or be a unary, binary or ternary functor that computes the replacement string + from a function call: either fmt(*this) + which must return a container of char_type's + to be used as the replacement text, or either fmt(*this, + out) + or fmt(*this, out, flags), both of which write the replacement text + to *out, + and then return the new OutputIterator position. +

+

+ Effects: If fmt + is either a null-terminated string, or a container of char_type's, + then copies the character sequence [fmt.begin(), fmt.end()) to OutputIterator out. For each format specifier or escape sequence in fmt, replace that sequence with either the character(s) it represents, or the @@ -578,6 +593,27 @@ by default this is the format used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace.

+

+ If fmt is a function object, + then depending on the number of arguments the function object accepts, it + will either: +

+
+

+ In all cases the new position of the OutputIterator + is returned. +

See the format syntax guide for more information.

@@ -586,18 +622,57 @@

-
string_type format(const string_type& fmt,
-                  match_flag_type flags = format_default);
+
template <class Formatter>
+string_type format(Formatter fmt,
+                   match_flag_type flags = format_default);
 

- Effects: Returns a copy of the string fmt. - For each format specifier or escape sequence in fmt, - replace that sequence with either the character(s) it represents, or the - sequence of characters within *this to which it refers. The bitmasks specified - in flags determines what format specifiers or escape sequences are recognized, - by default this is the format used by ECMA-262, ECMAScript Language Specification, - Chapter 15 part 5.4.11 String.prototype.replace. + Requires The type Formatter + must be either a pointer to a null-terminated string of type char_type[], + or be a container of char_type's + (for example std::basic_string<char_type>) + or be a unary, binary or ternary functor that computes the replacement string + from a function call: either fmt(*this) + which must return a container of char_type's + to be used as the replacement text, or either fmt(*this, + out) + or fmt(*this, out, flags), both of which write the replacement text + to *out, + and then return the new OutputIterator position.

+

+ Effects: If fmt + is either a null-terminated string, or a container of char_type's, + then copies the string fmt: For each format specifier + or escape sequence in fmt, replace that sequence with + either the character(s) it represents, or the sequence of characters within + *this + to which it refers. The bitmasks specified in flags determines what format + specifiers or escape sequences are recognized, by default this is the format + used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 + String.prototype.replace. +

+

+ If fmt is a function object, + then depending on the number of arguments the function object accepts, it + will either: +

+
    +
  • + Call fmt(*this) and + return the result. +
  • +
  • + Call fmt(*this, unspecified-output-iterator), where unspecified-output-iterator + is an unspecified OutputIterator type used to copy the output to the string + result. +
  • +
  • + Call fmt(*this, unspecified-output-iterator, flags), where unspecified-output-iterator + is an unspecified OutputIterator type used to copy the output to the string + result. +
  • +

See the format syntax guide for more information.

diff --git a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html index 4ea31468..1e813aed 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_algo.html @@ -43,7 +43,7 @@ on to the "real" algorithm.

- + u32regex_match

@@ -89,7 +89,7 @@ }

- + u32regex_search

@@ -128,7 +128,7 @@ }

- + u32regex_replace

diff --git a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html index 892034a2..62992e75 100644 --- a/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html +++ b/doc/html/boost_regex/ref/non_std_strings/icu/unicode_iter.html @@ -28,7 +28,7 @@ Unicode Aware Regex Iterators

- + u32regex_iterator

@@ -126,7 +126,7 @@ Provided of course that the input is encoded as UTF-8.

- + u32regex_token_iterator

diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html index 6148023b..c4904305 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_algo.html @@ -34,7 +34,7 @@ here they are anyway:

- + regex_match

@@ -82,7 +82,7 @@ }

- + regex_match (second overload)
@@ -110,7 +110,7 @@ }
- + regex_search

@@ -149,7 +149,7 @@ }

- + regex_search (second overload)
@@ -164,7 +164,7 @@ + s.GetLength(), e, f);

- + regex_replace

diff --git a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html index 54858bc8..07f5da99 100644 --- a/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html +++ b/doc/html/boost_regex/ref/non_std_strings/mfc_strings/mfc_iter.html @@ -32,7 +32,7 @@ an MFC/ATL string to a regex_iterator or regex_token_iterator:

- + regex_iterator creation helper
@@ -68,7 +68,7 @@ }
- + regex_token_iterator creation helpers
diff --git a/doc/html/boost_regex/ref/posix.html b/doc/html/boost_regex/ref/posix.html index 6424b99c..843f96c4 100644 --- a/doc/html/boost_regex/ref/posix.html +++ b/doc/html/boost_regex/ref/posix.html @@ -165,7 +165,7 @@

- + regcomp

@@ -379,7 +379,7 @@

- + regerror

@@ -467,7 +467,7 @@

- + regexec

@@ -537,7 +537,7 @@

- + regfree

diff --git a/doc/html/boost_regex/ref/regex_iterator.html b/doc/html/boost_regex/ref/regex_iterator.html index 2a101c5e..fff1bf7f 100644 --- a/doc/html/boost_regex/ref/regex_iterator.html +++ b/doc/html/boost_regex/ref/regex_iterator.html @@ -78,7 +78,7 @@ regex_constants::match_flag_type m = regex_constants::match_default);

- + Description

@@ -436,7 +436,7 @@ m.

- + Examples

diff --git a/doc/html/boost_regex/ref/regex_match.html b/doc/html/boost_regex/ref/regex_match.html index 9b1a7108..ad738b0b 100644 --- a/doc/html/boost_regex/ref/regex_match.html +++ b/doc/html/boost_regex/ref/regex_match.html @@ -80,7 +80,7 @@ match_flag_type flags = match_default);

- + Description
template <class BidirectionalIterator, class Allocator, class charT, class traits>
@@ -360,7 +360,7 @@
         Effects: Returns the result of regex_match(s.begin(), s.end(), e, flags).
       

- + Examples

diff --git a/doc/html/boost_regex/ref/regex_replace.html b/doc/html/boost_regex/ref/regex_replace.html index 70a65308..26acd84b 100644 --- a/doc/html/boost_regex/ref/regex_replace.html +++ b/doc/html/boost_regex/ref/regex_replace.html @@ -38,37 +38,40 @@ set. If the flag format_first_only is set then only the first occurrence is replaced rather than all occurrences.

-
template <class OutputIterator, class BidirectionalIterator, class traits, class charT>
+
template <class OutputIterator, class BidirectionalIterator, class traits, class Formatter>
 OutputIterator regex_replace(OutputIterator out,
                              BidirectionalIterator first,
                              BidirectionalIterator last,
                              const basic_regex<charT, traits>& e,
-                             const basic_string<charT>& fmt,
+                             Formatter fmt,
                              match_flag_type flags = match_default);
 
-template <class traits, class charT>
+template <class traits, class Formatter>
 basic_string<charT> regex_replace(const basic_string<charT>& s,
                                   const basic_regex<charT, traits>& e,
-                                  const basic_string<charT>& fmt,
+                                  Formatter fmt,
                                   match_flag_type flags = match_default);
 
- + Description
-
template <class OutputIterator, class BidirectionalIterator, class traits, class charT>
+
template <class OutputIterator, class BidirectionalIterator, class traits, class Formatter>
 OutputIterator regex_replace(OutputIterator out,
                              BidirectionalIterator first,
                              BidirectionalIterator last,
                              const basic_regex<charT, traits>& e,
-                             const basic_string<charT>& fmt,
+                             Formatter fmt,
                              match_flag_type flags = match_default);
 

Enumerates all the occurences of expression e in the sequence [first, last), replacing each occurence with the string that results by merging the match found with the format string fmt, - and copies the resulting string to out. + and copies the resulting string to out. In the case + that fmt is a unary, binary or ternary function object, + then the character sequence generated by that object is copied unchanged + to the output when performing a substitution.

If the flag format_no_copy @@ -85,6 +88,21 @@ along with the rules used for finding matches, are determined by the flags set in flags: see match_flag_type.

+

+ Requires The type Formatter + must be either a pointer to a null-terminated string of type char_type[], + or be a container of char_type's + (for example std::basic_string<char_type>) + or be a unary, binary or ternary functor that computes the replacement string + from a function call: either fmt(what) + which must return a container of char_type's + to be used as the replacement text, or either fmt(what, + out) + or fmt(what, out, flags), both of which write the replacement text + to *out, + and then return the new OutputIterator position. In each case what is the match_results object that represents + the match found. +

Effects: Constructs an regex_iterator object:

@@ -150,12 +168,27 @@

Returns: out.

-
template <class traits, class charT>
+
template <class traits, class Formatter>
 basic_string<charT> regex_replace(const basic_string<charT>& s,
                                   const basic_regex<charT, traits>& e,
-                                  const basic_string<charT>& fmt,
+                                  Formatter fmt,
                                   match_flag_type flags = match_default);
 
+

+ Requires The type Formatter + must be either a pointer to a null-terminated string of type char_type[], + or be a container of char_type's + (for example std::basic_string<char_type>) + or be a unary, binary or ternary functor that computes the replacement string + from a function call: either fmt(what) + which must return a container of char_type's + to be used as the replacement text, or either fmt(what, + out) + or fmt(what, out, flags), both of which write the replacement text + to *out, + and then return the new OutputIterator position. In each case what is the match_results object that represents + the match found. +

Effects: Constructs an object basic_string<charT> result, calls regex_replace(back_inserter(result), s.begin(), s.end(), e, fmt, @@ -163,7 +196,7 @@ and then returns result.

- + Examples

diff --git a/doc/html/boost_regex/ref/regex_search.html b/doc/html/boost_regex/ref/regex_search.html index 44faddee..b05f72bf 100644 --- a/doc/html/boost_regex/ref/regex_search.html +++ b/doc/html/boost_regex/ref/regex_search.html @@ -73,7 +73,7 @@ match_flag_type flags = match_default);

- + Description
template <class BidirectionalIterator, class Allocator, class charT, class traits>
@@ -355,7 +355,7 @@
         Effects: Returns the result of regex_search(s.begin(), s.end(), e, flags).
       

- + Examples

diff --git a/doc/html/boost_regex/ref/regex_token_iterator.html b/doc/html/boost_regex/ref/regex_token_iterator.html index 8728ee16..60d42bdf 100644 --- a/doc/html/boost_regex/ref/regex_token_iterator.html +++ b/doc/html/boost_regex/ref/regex_token_iterator.html @@ -136,7 +136,7 @@ regex_constants::match_flag_type m = regex_constants::match_default);

- + Description

@@ -383,7 +383,7 @@ m.

- + Examples

diff --git a/doc/html/boost_regex/ref/regex_traits.html b/doc/html/boost_regex/ref/regex_traits.html index cccf4917..c3161c62 100644 --- a/doc/html/boost_regex/ref/regex_traits.html +++ b/doc/html/boost_regex/ref/regex_traits.html @@ -46,7 +46,7 @@ } // namespace boost

- + Description

diff --git a/doc/html/boost_regex/ref/sub_match.html b/doc/html/boost_regex/ref/sub_match.html index 999f0ce4..b1dc0b72 100644 --- a/doc/html/boost_regex/ref/sub_match.html +++ b/doc/html/boost_regex/ref/sub_match.html @@ -329,11 +329,11 @@ } // namespace boost

- + Description
- + Members

@@ -473,7 +473,7 @@

- + sub_match non-member operators
@@ -1008,7 +1008,7 @@ + m2.str()
.

- + Stream inserter

diff --git a/doc/html/boost_regex/syntax/basic_extended.html b/doc/html/boost_regex/syntax/basic_extended.html index 6821fd0d..cf3e7fe0 100644 --- a/doc/html/boost_regex/syntax/basic_extended.html +++ b/doc/html/boost_regex/syntax/basic_extended.html @@ -28,7 +28,7 @@ Expression Syntax

- + Synopsis

@@ -46,7 +46,7 @@

- + POSIX Extended Syntax

@@ -56,7 +56,7 @@

.[{()\*+?|^$
- + Wildcard:

@@ -74,7 +74,7 @@

- + Anchors:

@@ -86,7 +86,7 @@ of an expression, or the last character of a sub-expression.

- + Marked sub-expressions:
@@ -98,7 +98,7 @@ to by a back-reference.

- + Repeats:

@@ -184,7 +184,7 @@ cab operator to be applied to.

- + Back references:

@@ -214,7 +214,7 @@ cab

- + Alternation

@@ -227,7 +227,7 @@ cab will match either of "abd" or "abef".

- + Character sets:
@@ -240,7 +240,7 @@ cab A bracket expression may contain any combination of the following:

- + Single characters:
@@ -249,7 +249,7 @@ cab or 'c'.

- + Character ranges:
@@ -265,7 +265,7 @@ cab the code points of the characters only.

- + Negation:

@@ -274,7 +274,7 @@ cab range a-c.

- + Character classes:
@@ -284,7 +284,7 @@ cab character class names.

- + Collating Elements:
@@ -312,7 +312,7 @@ cab matches a NUL character.

- + Equivalence classes:
@@ -329,7 +329,7 @@ cab or even all locales on one platform.

- + Combinations:

@@ -337,7 +337,7 @@ cab [[:digit:]a-c[.NUL.]].

- + Escapes

@@ -363,7 +363,7 @@ cab extensions are also supported by Boost.Regex:

- + Escapes matching a specific character
@@ -552,7 +552,7 @@ cab
- + "Single character" character classes:
@@ -706,7 +706,7 @@ cab
- + Character Properties
@@ -813,7 +813,7 @@ cab matches any "digit" character, as does \p{digit}.

- + Word Boundaries

@@ -888,7 +888,7 @@ cab

- + Buffer boundaries
@@ -979,7 +979,7 @@ cab
- + Continuation Escape
@@ -991,7 +991,7 @@ cab match to start where the last one ended.

- + Quoting escape
@@ -1005,7 +1005,7 @@ cab \*+aaa
- + Unicode escapes
@@ -1056,7 +1056,7 @@ cab
- + Any other escape
@@ -1065,7 +1065,7 @@ cab \@ matches a literal '@'.

- + Operator precedence
@@ -1101,7 +1101,7 @@ cab
- + What Gets Matched
@@ -1111,11 +1111,11 @@ cab rule.

- + Variations

- + Egrep

@@ -1136,7 +1136,7 @@ cab used with the -E option.

- + awk

@@ -1150,7 +1150,7 @@ cab these by default anyway.

- + Options

@@ -1163,7 +1163,7 @@ cab modify how the case and locale sensitivity are to be applied.

- + References

diff --git a/doc/html/boost_regex/syntax/basic_syntax.html b/doc/html/boost_regex/syntax/basic_syntax.html index 0c6e6604..f2812f9d 100644 --- a/doc/html/boost_regex/syntax/basic_syntax.html +++ b/doc/html/boost_regex/syntax/basic_syntax.html @@ -28,7 +28,7 @@ Expression Syntax

- + Synopsis

@@ -45,7 +45,7 @@

- + POSIX Basic Syntax

@@ -55,7 +55,7 @@

.[\*^$
- + Wildcard:

@@ -73,7 +73,7 @@

- + Anchors:

@@ -85,7 +85,7 @@ of an expression, or the last character of a sub-expression.

- + Marked sub-expressions:
@@ -97,7 +97,7 @@ by a back-reference.

- + Repeats:

@@ -155,7 +155,7 @@ aaaa to.

- + Back references:

@@ -173,7 +173,7 @@ aaaa

aaabba
- + Character sets:
@@ -186,7 +186,7 @@ aaaa A bracket expression may contain any combination of the following:

- + Single characters:
@@ -195,7 +195,7 @@ aaaa or 'c'.

- + Character ranges:
@@ -211,7 +211,7 @@ aaaa of the characters only.

- + Negation:

@@ -220,7 +220,7 @@ aaaa range a-c.

- + Character classes:
@@ -230,7 +230,7 @@ aaaa character class names.

- + Collating Elements:
@@ -259,7 +259,7 @@ aaaa element names.

- + Equivalence classes:
@@ -276,7 +276,7 @@ aaaa or even all locales on one platform.

- + Combinations:

@@ -284,7 +284,7 @@ aaaa [[:digit:]a-c[.NUL.]].

- + Escapes

@@ -299,7 +299,7 @@ aaaa will match either a literal '\' or a '^'.

- + What Gets Matched

@@ -309,13 +309,13 @@ aaaa rule.

- + Variations

- + Grep

@@ -333,7 +333,7 @@ aaaa As its name suggests, this behavior is consistent with the Unix utility grep.

- + emacs

@@ -613,7 +613,7 @@ aaaa leftmost-longest rule.

- + Options

@@ -627,7 +627,7 @@ aaaa options modify how the case and locale sensitivity are to be applied.

- + References

diff --git a/doc/html/boost_regex/syntax/perl_syntax.html b/doc/html/boost_regex/syntax/perl_syntax.html index cc7a368a..6bae14c3 100644 --- a/doc/html/boost_regex/syntax/perl_syntax.html +++ b/doc/html/boost_regex/syntax/perl_syntax.html @@ -28,7 +28,7 @@ Syntax

- + Synopsis

@@ -43,7 +43,7 @@ boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase);

- + Perl Regular Expression Syntax

@@ -53,7 +53,7 @@

.[{()\*+?|^$
- + Wildcard

@@ -73,7 +73,7 @@

- + Anchors

@@ -83,7 +83,7 @@ A '$' character shall match the end of a line.

- + Marked sub-expressions
@@ -94,7 +94,7 @@ can also repeated, or referred to by a back-reference.

- + Non-marking grouping
@@ -107,7 +107,7 @@ without splitting out any separate sub-expressions.

- + Repeats

@@ -188,7 +188,7 @@ to be applied to.

- + Non greedy repeats
@@ -218,7 +218,7 @@ while consuming as little input as possible.

- + Pocessive repeats
@@ -250,7 +250,7 @@ while giving nothing back.

- + Back references

@@ -360,7 +360,7 @@ named "two".

- + Alternation

@@ -387,7 +387,7 @@ (?:abc)?? has exactly the same effect.

- + Character sets

@@ -399,7 +399,7 @@ A bracket expression may contain any combination of the following:

- + Single characters

@@ -407,7 +407,7 @@ 'b', or 'c'.

- + Character ranges
@@ -421,7 +421,7 @@ sensitive.

- + Negation

@@ -430,7 +430,7 @@ matches any character that is not in the range a-c.

- + Character classes
@@ -441,7 +441,7 @@ class names.

- + Collating Elements
@@ -463,7 +463,7 @@ matches a \0 character.

- + Equivalence classes
@@ -480,7 +480,7 @@ or even all locales on one platform.

- + Escaped Characters
@@ -492,7 +492,7 @@ is not a "word" character.

- + Combinations

@@ -500,7 +500,7 @@ [[:digit:]a-c[.NUL.]].

- + Escapes

@@ -692,7 +692,7 @@

- + "Single character" character classes:
@@ -894,7 +894,7 @@
- + Character Properties
@@ -1002,7 +1002,7 @@ as does \p{digit}.

- + Word Boundaries

@@ -1021,7 +1021,7 @@ \B Matches only when not at a word boundary.

- + Buffer boundaries

@@ -1046,7 +1046,7 @@ to the regular expression \n*\z

- + Continuation Escape
@@ -1058,7 +1058,7 @@ one ended.

- + Quoting escape

@@ -1071,7 +1071,7 @@ \*+aaa

- + Unicode escapes

@@ -1081,7 +1081,7 @@ followed by a sequence of zero or more combining characters.

- + Matching Line Endings
@@ -1090,7 +1090,7 @@ sequence, specifically it is identical to the expression (?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}]).

- + Keeping back some text
@@ -1105,7 +1105,7 @@ This can be used to simulate variable width lookbehind assertions.

- + Any other escape
@@ -1114,7 +1114,7 @@ \@ matches a literal '@'.

- + Perl Extended Patterns
@@ -1123,7 +1123,7 @@ (?.

- + Named Subexpressions
@@ -1145,14 +1145,14 @@ format string for search and replace operations, or in the match_results member functions.

- + Comments

(?# ... ) is treated as a comment, it's contents are ignored.

- + Modifiers

@@ -1166,7 +1166,7 @@ pattern only.

- + Non-marking groups
@@ -1175,7 +1175,7 @@ an additional sub-expression.

- + Branch reset

@@ -1197,7 +1197,7 @@ # 1 2 2 3 2 3 4

- + Lookahead

@@ -1220,7 +1220,7 @@ could be used to validate the password.

- + Lookbehind

@@ -1234,7 +1234,7 @@ (pattern must be of fixed length).

- + Independent sub-expressions
@@ -1247,7 +1247,7 @@ no match is found at all.

- + Recursive Expressions
@@ -1271,7 +1271,7 @@ to the next sub-expression to be declared.

- + Conditional Expressions
@@ -1319,7 +1319,7 @@
- + Operator precedence
@@ -1354,7 +1354,7 @@

- + What gets matched

@@ -1529,7 +1529,7 @@

- + Variations

@@ -1538,7 +1538,7 @@ and JScript are all synonyms for perl.

- + Options

@@ -1550,7 +1550,7 @@ are to be applied.

- + Pattern Modifiers

@@ -1562,7 +1562,7 @@ and no_mod_s.

- + References

diff --git a/doc/html/boost_regex/unicode.html b/doc/html/boost_regex/unicode.html index 94b8709f..fd80edd8 100644 --- a/doc/html/boost_regex/unicode.html +++ b/doc/html/boost_regex/unicode.html @@ -30,7 +30,7 @@ There are two ways to use Boost.Regex with Unicode strings:

- + Rely on wchar_t

@@ -56,7 +56,7 @@

- + Use a Unicode Aware Regular Expression Type.
diff --git a/doc/html/index.html b/doc/html/index.html index cb420c49..68c0060c 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -28,7 +28,7 @@
-

+

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

@@ -196,7 +196,7 @@

- +

Last revised: July 29, 2009 at 15:59:46 GMT

Last revised: October 30, 2009 at 17:13:44 GMT


diff --git a/doc/match_result.qbk b/doc/match_result.qbk index 8e1ae788..680f868f 100644 --- a/doc/match_result.qbk +++ b/doc/match_result.qbk @@ -105,11 +105,12 @@ Class template `match_results` is most commonly used as one of the typedefs const_iterator ``[link boost_regex.match_results.begin begin]``() const; const_iterator ``[link boost_regex.match_results.end end]``() const; // format: - template + template OutputIterator ``[link boost_regex.match_results.format format]``(OutputIterator out, - const string_type& fmt, + Formatter fmt, match_flag_type flags = format_default) const; - string_type ``[link boost_regex.match_results.format2 format]``(const string_type& fmt, + template + string_type ``[link boost_regex.match_results.format2 format]``(Formatter fmt, match_flag_type flags = format_default) const; allocator_type ``[link boost_regex.match_results.get_allocator get_allocator]``() const; @@ -352,15 +353,25 @@ marked sub-expression matches stored in *this. [#boost_regex.match_results_format] [#boost_regex.match_results.format] - template + template OutputIterator format(OutputIterator out, - const string_type& fmt, - match_flag_type flags = format_default); + Formatter fmt, + match_flag_type flags = format_default); [*Requires]: The type `OutputIterator` conforms to the Output Iterator requirements (C++ std 24.1.2). -[*Effects]: Copies the character sequence `[fmt.begin(), fmt.end())` to +The type `Formatter` must be either a pointer to a null-terminated string +of type `char_type[]`, or be a container of `char_type`'s (for example +`std::basic_string`) or be a unary, binary or ternary functor +that computes the replacement string from a function call: either +`fmt(*this)` which must return a container of `char_type`'s to be used as the +replacement text, or either `fmt(*this, out)` or `fmt(*this, out, flags)`, both of +which write the replacement text to `*out`, and then return the new +OutputIterator position. + +[*Effects]: If `fmt` is either a null-terminated string, or a +container of `char_type`'s, then copies the character sequence `[fmt.begin(), fmt.end())` to `OutputIterator` /out/. For each format specifier or escape sequence in /fmt/, replace that sequence with either the character(s) it represents, or the sequence of characters within `*this` to which it refers. @@ -369,6 +380,16 @@ escape sequences are recognized, by default this is the format used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace. +If `fmt` is a function object, then depending on the number of arguments +the function object accepts, it will either: + +* Call `fmt(*this)` and copy the result to `OutputIterator` +/out/. +* Call `fmt(*this, out)`. +* Call `fmt(*this, out, flags)`. + +In all cases the new position of the `OutputIterator` is returned. + See the [link boost_regex.format format syntax guide for more information]. [*Returns]: out. @@ -376,10 +397,23 @@ See the [link boost_regex.format format syntax guide for more information]. [#boost_regex.match_results.format2] - string_type format(const string_type& fmt, - match_flag_type flags = format_default); + template + string_type format(Formatter fmt, + match_flag_type flags = format_default); -[*Effects]: Returns a copy of the string /fmt/. For each format specifier or +[*Requires] +The type `Formatter` must be either a pointer to a null-terminated string +of type `char_type[]`, or be a container of `char_type`'s (for example +`std::basic_string`) or be a unary, binary or ternary functor +that computes the replacement string from a function call: either +`fmt(*this)` which must return a container of `char_type`'s to be used as the +replacement text, or either `fmt(*this, out)` or `fmt(*this, out, flags)`, both of +which write the replacement text to `*out`, and then return the new +OutputIterator position. + +[*Effects]: +If `fmt` is either a null-terminated string, or a +container of `char_type`'s, then copies the string /fmt/: For each format specifier or escape sequence in /fmt/, replace that sequence with either the character(s) it represents, or the sequence of characters within `*this` to which it refers. The bitmasks specified in flags determines what format @@ -387,6 +421,15 @@ specifiers or escape sequences are recognized, by default this is the format used by ECMA-262, ECMAScript Language Specification, Chapter 15 part 5.4.11 String.prototype.replace. +If `fmt` is a function object, then depending on the number of arguments +the function object accepts, it will either: + +* Call `fmt(*this)` and return the result. +* Call `fmt(*this, unspecified-output-iterator)`, where `unspecified-output-iterator` +is an unspecified OutputIterator type used to copy the output to the string result. +* Call `fmt(*this, unspecified-output-iterator, flags)`, where `unspecified-output-iterator` +is an unspecified OutputIterator type used to copy the output to the string result. + See the [link boost_regex.format format syntax guide for more information]. [#boost_regex.match_results.get_allocator] diff --git a/doc/regex_format.qbk b/doc/regex_format.qbk index e59549e1..d9e249ba 100644 --- a/doc/regex_format.qbk +++ b/doc/regex_format.qbk @@ -21,15 +21,10 @@ The algorithm `regex_format` takes the results of a match and creates a new string based upon a format string, `regex_format` can be used for search and replace operations: - template + template OutputIterator regex_format(OutputIterator out, const match_results& m, - const charT* fmt, - match_flag_type flags = 0); - template - OutputIterator regex_format(OutputIterator out, - const match_results& m, - const std::basic_string& fmt, + Formatter fmt, match_flag_type flags = 0); The library also defines the following convenience variation of @@ -39,16 +34,10 @@ than outputting to an iterator. [note This version may not be available, or may be available in a more limited form, depending upon your compilers capabilities] - template + template std::basic_string regex_format (const match_results& m, - const charT* fmt, - match_flag_type flags = 0); - - template - std::basic_string regex_format - (const match_results& m, - const std::basic_string& fmt, + Formatter fmt, match_flag_type flags = 0); Parameters to the main version of the function are passed as follows: @@ -57,7 +46,7 @@ Parameters to the main version of the function are passed as follows: [[Parameter][Description]] [[`OutputIterator out`][An output iterator type, the output string is sent to this iterator. Typically this would be a std::ostream_iterator. ]] [[`const match_results& m`][An instance of [match_results] obtained from one of the matching algorithms above, and denoting what matched. ]] -[[`const charT* fmt`][A format string that determines how the match is transformed into the new string. ]] +[[`Formatter fmt`][Either a format string that determines how the match is transformed into the new string, or a functor that computes the new string from /m/ - see [match_results_format]. ]] [[`unsigned flags`][Optional flags which describe how the format string is to be interpreted. ]] ] diff --git a/doc/regex_replace.qbk b/doc/regex_replace.qbk index 252397aa..58f88778 100644 --- a/doc/regex_replace.qbk +++ b/doc/regex_replace.qbk @@ -18,34 +18,37 @@ output unchanged only if the /flags/ parameter does not have the flag `format_no_copy` set. If the flag `format_first_only` is set then only the first occurrence is replaced rather than all occurrences. - template + template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, - const basic_string& fmt, + Formatter fmt, match_flag_type flags = match_default); - template + template basic_string regex_replace(const basic_string& s, const basic_regex& e, - const basic_string& fmt, + Formatter fmt, match_flag_type flags = match_default); [h4 Description] - template + template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, - const basic_string& fmt, + Formatter fmt, match_flag_type flags = match_default); Enumerates all the occurences of expression /e/ in the sequence \[first, last), replacing each occurence with the string that results by merging the match found with the format string /fmt/, and copies the resulting string to /out/. +In the case that /fmt/ is a unary, binary or ternary function object, then the +character sequence generated by that object is copied unchanged to the output when performing +a substitution. If the flag `format_no_copy` is set in /flags/ then unmatched sections of text are not copied to output. @@ -57,6 +60,17 @@ The manner in which the format string /fmt/ is interpretted, along with the rules used for finding matches, are determined by the flags set in /flags/: see [match_flag_type]. +[*Requires] +The type `Formatter` must be either a pointer to a null-terminated string +of type `char_type[]`, or be a container of `char_type`'s (for example +`std::basic_string`) or be a unary, binary or ternary functor +that computes the replacement string from a function call: either +`fmt(what)` which must return a container of `char_type`'s to be used as the +replacement text, or either `fmt(what, out)` or `fmt(what, out, flags)`, both of +which write the replacement text to `*out`, and then return the new +OutputIterator position. In each case `what` is the [match_results] object +that represents the match found. + [*Effects]: Constructs an [regex_iterator] object: regex_iterator @@ -107,12 +121,23 @@ memory allocation (if Boost.Regex is configured in non-recursive mode). [*Returns]: out. - template + template basic_string regex_replace(const basic_string& s, const basic_regex& e, - const basic_string& fmt, + Formatter fmt, match_flag_type flags = match_default); +[*Requires] +The type `Formatter` must be either a pointer to a null-terminated string +of type `char_type[]`, or be a container of `char_type`'s (for example +`std::basic_string`) or be a unary, binary or ternary functor +that computes the replacement string from a function call: either +`fmt(what)` which must return a container of `char_type`'s to be used as the +replacement text, or either `fmt(what, out)` or `fmt(what, out, flags)`, both of +which write the replacement text to `*out`, and then return the new +OutputIterator position. In each case `what` is the [match_results] object +that represents the match found. + [*Effects]: Constructs an object `basic_string result`, calls `regex_replace(back_inserter(result), s.begin(), s.end(), e, fmt, flags)`, and then returns `result`. diff --git a/include/boost/regex/concepts.hpp b/include/boost/regex/concepts.hpp index 98fd5941..886395ec 100644 --- a/include/boost/regex/concepts.hpp +++ b/include/boost/regex/concepts.hpp @@ -747,6 +747,46 @@ struct RegexConcept }; #ifndef BOOST_REGEX_TEST_STD + +template +struct functor1 +{ + typedef typename M::char_type char_type; + const char_type* operator()(const M& m) + { + static const char_type c = static_cast(0); + return &c; + } +}; +template +struct functor1b +{ + typedef typename M::char_type char_type; + std::vector operator()(const M& m) + { + static const std::vector c; + return c; + } +}; +template +struct functor2 +{ + template + O operator()(const M& /*m*/, O i) + { + return i; + } +}; +template +struct functor3 +{ + template + O operator()(const M& /*m*/, O i, regex_constants::match_flag_type) + { + return i; + } +}; + // // BoostRegexConcept: // Test every interface in the Boost implementation: @@ -764,6 +804,7 @@ struct BoostRegexConcept typedef std::basic_string string_type; typedef typename Regex::const_iterator const_iterator; typedef bidirectional_iterator_archetype BidiIterator; + typedef output_iterator_archetype OutputIterator; typedef global_regex_namespace::sub_match sub_match_type; typedef global_regex_namespace::match_results match_results_type; @@ -884,6 +925,58 @@ struct BoostRegexConcept m_stream << m_sub; m_stream << m_cresults; #endif + // + // Extended formatting with a functor: + // + regex_constants::match_flag_type f = regex_constants::match_default; + OutputIterator out = static_object::get(); + functor3 func3; + out = regex_format(out, m_cresults, func3, f); + out = regex_format(out, m_cresults, func3); + functor2 func2; + out = regex_format(out, m_cresults, func2, f); + out = regex_format(out, m_cresults, func2); + functor1 func1; + out = regex_format(out, m_cresults, func1, f); + out = regex_format(out, m_cresults, func1); + + m_string += regex_format(m_cresults, func3, f); + m_string += regex_format(m_cresults, func3); + m_string += regex_format(m_cresults, func2, f); + m_string += regex_format(m_cresults, func2); + m_string += regex_format(m_cresults, func1, f); + m_string += regex_format(m_cresults, func1); + + out = m_cresults.format(out, func3, f); + out = m_cresults.format(out, func3); + out = m_cresults.format(out, func2, f); + out = m_cresults.format(out, func2); + out = m_cresults.format(out, func1, f); + out = m_cresults.format(out, func1); + + m_string += m_cresults.format(func3, f); + m_string += m_cresults.format(func3); + m_string += m_cresults.format(func2, f); + m_string += m_cresults.format(func2); + m_string += m_cresults.format(func1, f); + m_string += m_cresults.format(func1); + + out = regex_replace(out, m_in, m_in, ce, func3, f); + out = regex_replace(out, m_in, m_in, ce, func3); + out = regex_replace(out, m_in, m_in, ce, func2, f); + out = regex_replace(out, m_in, m_in, ce, func2); + out = regex_replace(out, m_in, m_in, ce, func1, f); + out = regex_replace(out, m_in, m_in, ce, func1); + + functor3 > func3s; + functor2 > func2s; + functor1 > func1s; + m_string += regex_replace(m_string, ce, func3s, f); + m_string += regex_replace(m_string, ce, func3s); + m_string += regex_replace(m_string, ce, func2s, f); + m_string += regex_replace(m_string, ce, func2s); + m_string += regex_replace(m_string, ce, func1s, f); + m_string += regex_replace(m_string, ce, func1s); } std::basic_ostream m_stream; @@ -893,6 +986,7 @@ struct BoostRegexConcept const value_type m_char; match_results_type m_results; const match_results_type m_cresults; + BidiIterator m_in; BoostRegexConcept(); BoostRegexConcept(const BoostRegexConcept&); diff --git a/include/boost/regex/v4/match_results.hpp b/include/boost/regex/v4/match_results.hpp index ce18c5c4..e493810b 100644 --- a/include/boost/regex/v4/match_results.hpp +++ b/include/boost/regex/v4/match_results.hpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 1998-2002 + * Copyright (c) 1998-2009 * John Maddock * * Use, modification and distribution are subject to the @@ -282,42 +282,55 @@ public: return m_subs.end(); } // format: - template + template OutputIterator format(OutputIterator out, - const string_type& fmt, + Functor fmt, match_flag_type flags = format_default) const { - re_detail::trivial_format_traits traits; - return re_detail::regex_format_imp(out, *this, fmt.data(), fmt.data() + fmt.size(), flags, traits); + typedef typename re_detail::compute_functor_type, OutputIterator>::type F; + F func(fmt); + return func(*this, out, flags); } - string_type format(const string_type& fmt, - match_flag_type flags = format_default) const + template + string_type format(Functor fmt, match_flag_type flags = format_default) const { - string_type result; - re_detail::string_out_iterator i(result); - re_detail::trivial_format_traits traits; - re_detail::regex_format_imp(i, *this, fmt.data(), fmt.data() + fmt.size(), flags, traits); + std::basic_string result; + re_detail::string_out_iterator > i(result); + + typedef typename re_detail::compute_functor_type, re_detail::string_out_iterator > >::type F; + F func(fmt); + + func(*this, i, flags); return result; } // format with locale: - template + template OutputIterator format(OutputIterator out, - const string_type& fmt, + Functor fmt, match_flag_type flags, const RegexT& re) const { - return ::boost::re_detail::regex_format_imp(out, *this, fmt.data(), fmt.data() + fmt.size(), flags, re.get_traits()); + typedef ::boost::regex_traits_wrapper traits_type; + typedef typename re_detail::compute_functor_type, OutputIterator, traits_type>::type F; + F func(fmt); + return func(*this, out, flags, re.get_traits()); } - template - string_type format(const string_type& fmt, + template + string_type format(Functor fmt, match_flag_type flags, const RegexT& re) const { - string_type result; - re_detail::string_out_iterator i(result); - ::boost::re_detail::regex_format_imp(i, *this, fmt.data(), fmt.data() + fmt.size(), flags, re.get_traits()); + typedef ::boost::regex_traits_wrapper traits_type; + std::basic_string result; + re_detail::string_out_iterator > i(result); + + typedef typename re_detail::compute_functor_type, re_detail::string_out_iterator >, traits_type >::type F; + F func(fmt); + + func(*this, i, flags, re.get_traits()); return result; } + const_reference get_last_closed_paren()const { return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren]; diff --git a/include/boost/regex/v4/regex_format.hpp b/include/boost/regex/v4/regex_format.hpp index 4e95112f..52e0f6b1 100644 --- a/include/boost/regex/v4/regex_format.hpp +++ b/include/boost/regex/v4/regex_format.hpp @@ -1,7 +1,7 @@ /* * - * Copyright (c) 1998-2002 - * John Maddock + * Copyright (c) 1998-2009 John Maddock + * Copyright 2008 Eric Niebler. * * Use, modification and distribution are subject to the * Boost Software License, Version 1.0. (See accompanying file @@ -21,6 +21,19 @@ #ifndef BOOST_REGEX_FORMAT_HPP #define BOOST_REGEX_FORMAT_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_SFINAE +#include +#endif namespace boost{ @@ -76,15 +89,15 @@ struct trivial_format_traits } }; -template +template class basic_regex_formatter { public: typedef typename traits::char_type char_type; basic_regex_formatter(OutputIterator o, const Results& r, const traits& t) : m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {} - OutputIterator format(const char_type* p1, const char_type* p2, match_flag_type f); - OutputIterator format(const char_type* p1, match_flag_type f) + OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f); + OutputIterator format(ForwardIter p1, match_flag_type f) { return format(p1, p1 + m_traits.length(p1), f); } @@ -109,22 +122,75 @@ private: void format_until_scope_end(); bool handle_perl_verb(bool have_brace); - const traits& m_traits; // the traits class for localised formatting operations - const Results& m_results; // the match_results being used. - OutputIterator m_out; // where to send output. - const char_type* m_position; // format string, current position - const char_type* m_end; // format string end - match_flag_type m_flags; // format flags to use - output_state m_state; // what to do with the next character - output_state m_restore_state; // what state to restore to. - bool m_have_conditional; // we are parsing a conditional + inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::false_&) + { + std::vector v(i, j); + return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size()) + : this->m_results.named_subexpression(static_cast(0), static_cast(0)); + } + inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::true_&) + { + return this->m_results.named_subexpression(i, j); + } + inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j) + { + typedef typename boost::is_convertible::type tag_type; + return get_named_sub(i, j, tag_type()); + } + inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::false_&) + { + std::vector v(i, j); + return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size()) + : this->m_results.named_subexpression_index(static_cast(0), static_cast(0)); + } + inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::true_&) + { + return this->m_results.named_subexpression_index(i, j); + } + inline int get_named_sub_index(ForwardIter i, ForwardIter j) + { + typedef typename boost::is_convertible::type tag_type; + return get_named_sub_index(i, j, tag_type()); + } + inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::false_&) + { + if(i != j) + { + std::vector v(i, j); + const char_type* start = &v[0]; + const char_type* pos = start; + int r = m_traits.toi(pos, &v[0] + v.size(), base); + std::advance(i, pos - start); + return r; + } + return -1; + } + inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::true_&) + { + return m_traits.toi(i, j, base); + } + inline int toi(ForwardIter& i, ForwardIter j, int base) + { + typedef typename boost::is_convertible::type tag_type; + return toi(i, j, base, tag_type()); + } + + const traits& m_traits; // the traits class for localised formatting operations + const Results& m_results; // the match_results being used. + OutputIterator m_out; // where to send output. + ForwardIter m_position; // format string, current position + ForwardIter m_end; // format string end + match_flag_type m_flags; // format flags to use + output_state m_state; // what to do with the next character + output_state m_restore_state; // what state to restore to. + bool m_have_conditional; // we are parsing a conditional private: basic_regex_formatter(const basic_regex_formatter&); basic_regex_formatter& operator=(const basic_regex_formatter&); }; -template -OutputIterator basic_regex_formatter::format(const char_type* p1, const char_type* p2, match_flag_type f) +template +OutputIterator basic_regex_formatter::format(ForwardIter p1, ForwardIter p2, match_flag_type f) { m_position = p1; m_end = p2; @@ -133,8 +199,8 @@ OutputIterator basic_regex_formatter::format(co return m_out; } -template -void basic_regex_formatter::format_all() +template +void basic_regex_formatter::format_all() { // over and over: while(m_position != m_end) @@ -211,8 +277,8 @@ void basic_regex_formatter::format_all() } } -template -void basic_regex_formatter::format_perl() +template +void basic_regex_formatter::format_perl() { // // On entry *m_position points to a '$' character @@ -233,7 +299,7 @@ void basic_regex_formatter::format_perl() // OK find out what kind it is: // bool have_brace = false; - const char_type* save_position = m_position; + ForwardIter save_position = m_position; switch(*m_position) { case '&': @@ -254,12 +320,12 @@ void basic_regex_formatter::format_perl() case '+': if((++m_position != m_end) && (*m_position == '{')) { - const char_type* base = ++m_position; + ForwardIter base = ++m_position; while((m_position != m_end) && (*m_position != '}')) ++m_position; if(m_position != m_end) { // Named sub-expression: - put(this->m_results.named_subexpression(base, m_position)); + put(get_named_sub(base, m_position)); ++m_position; break; } @@ -279,7 +345,7 @@ void basic_regex_formatter::format_perl() { std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end); //len = (std::min)(static_cast(2), len); - int v = m_traits.toi(m_position, m_position + len, 10); + int v = this->toi(m_position, m_position + len, 10); if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}')))) { // Look for a Perl-5.10 verb: @@ -300,8 +366,8 @@ void basic_regex_formatter::format_perl() } } -template -bool basic_regex_formatter::handle_perl_verb(bool have_brace) +template +bool basic_regex_formatter::handle_perl_verb(bool have_brace) { // // We may have a capitalised string containing a Perl action: @@ -313,6 +379,8 @@ bool basic_regex_formatter::handle_perl_verb(bo 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' }; static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' }; + if(m_position == m_end) + return false; if(have_brace && (*m_position == '^')) ++m_position; @@ -323,7 +391,7 @@ bool basic_regex_formatter::handle_perl_verb(bo m_position += 5; if(have_brace) { - if(*m_position == '}') + if((m_position != m_end) && (*m_position == '}')) ++m_position; else { @@ -339,7 +407,7 @@ bool basic_regex_formatter::handle_perl_verb(bo m_position += 8; if(have_brace) { - if(*m_position == '}') + if((m_position != m_end) && (*m_position == '}')) ++m_position; else { @@ -355,7 +423,7 @@ bool basic_regex_formatter::handle_perl_verb(bo m_position += 9; if(have_brace) { - if(*m_position == '}') + if((m_position != m_end) && (*m_position == '}')) ++m_position; else { @@ -371,7 +439,7 @@ bool basic_regex_formatter::handle_perl_verb(bo m_position += 16; if(have_brace) { - if(*m_position == '}') + if((m_position != m_end) && (*m_position == '}')) ++m_position; else { @@ -387,7 +455,7 @@ bool basic_regex_formatter::handle_perl_verb(bo m_position += 20; if(have_brace) { - if(*m_position == '}') + if((m_position != m_end) && (*m_position == '}')) ++m_position; else { @@ -403,7 +471,7 @@ bool basic_regex_formatter::handle_perl_verb(bo m_position += 2; if(have_brace) { - if(*m_position == '}') + if((m_position != m_end) && (*m_position == '}')) ++m_position; else { @@ -417,8 +485,8 @@ bool basic_regex_formatter::handle_perl_verb(bo return false; } -template -void basic_regex_formatter::format_escape() +template +void basic_regex_formatter::format_escape() { // skip the escape and check for trailing escape: if(++m_position == m_end) @@ -463,7 +531,7 @@ void basic_regex_formatter::format_escape() if(*m_position == static_cast('{')) { ++m_position; - int val = m_traits.toi(m_position, m_end, 16); + int val = this->toi(m_position, m_end, 16); if(val < 0) { // invalid value treat everything as literals: @@ -471,8 +539,9 @@ void basic_regex_formatter::format_escape() put(static_cast('{')); return; } - if(*m_position != static_cast('}')) + if((m_position == m_end) || (*m_position != static_cast('}'))) { + --m_position; while(*m_position != static_cast('\\')) --m_position; ++m_position; @@ -487,7 +556,7 @@ void basic_regex_formatter::format_escape() { std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end); len = (std::min)(static_cast(2), len); - int val = m_traits.toi(m_position, m_position + len, 16); + int val = this->toi(m_position, m_position + len, 16); if(val < 0) { --m_position; @@ -549,7 +618,9 @@ void basic_regex_formatter::format_escape() break; } // see if we have a \n sed style backreference: - int v = m_traits.toi(m_position, m_position+1, 10); + std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end); + len = (std::min)(static_cast(1), len); + int v = this->toi(m_position, m_position+len, 10); if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed))) { put(m_results[v]); @@ -561,7 +632,7 @@ void basic_regex_formatter::format_escape() --m_position; std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end); len = (std::min)(static_cast(4), len); - v = m_traits.toi(m_position, m_position + len, 8); + v = this->toi(m_position, m_position + len, 8); BOOST_ASSERT(v >= 0); put(static_cast(v)); break; @@ -572,8 +643,8 @@ void basic_regex_formatter::format_escape() } } -template -void basic_regex_formatter::format_conditional() +template +void basic_regex_formatter::format_conditional() { if(m_position == m_end) { @@ -584,15 +655,15 @@ void basic_regex_formatter::format_conditional( int v; if(*m_position == '{') { - const char_type* base = m_position; + ForwardIter base = m_position; ++m_position; - v = m_traits.toi(m_position, m_end, 10); + v = this->toi(m_position, m_end, 10); if(v < 0) { // Try a named subexpression: while((m_position != m_end) && (*m_position != '}')) ++m_position; - v = m_results.named_subexpression_index(base + 1, m_position); + v = this->get_named_sub_index(base + 1, m_position); } if((v < 0) || (*m_position != '}')) { @@ -608,7 +679,7 @@ void basic_regex_formatter::format_conditional( { std::ptrdiff_t len = ::boost::re_detail::distance(m_position, m_end); len = (std::min)(static_cast(2), len); - v = m_traits.toi(m_position, m_position + len, 10); + v = this->toi(m_position, m_position + len, 10); } if(v < 0) { @@ -657,8 +728,8 @@ void basic_regex_formatter::format_conditional( } } -template -void basic_regex_formatter::format_until_scope_end() +template +void basic_regex_formatter::format_until_scope_end() { do { @@ -669,8 +740,8 @@ void basic_regex_formatter::format_until_scope_ }while(m_position != m_end); } -template -void basic_regex_formatter::put(char_type c) +template +void basic_regex_formatter::put(char_type c) { // write a single character to output // according to which case translation mode we are in: @@ -699,8 +770,8 @@ void basic_regex_formatter::put(char_type c) ++m_out; } -template -void basic_regex_formatter::put(const sub_match_type& sub) +template +void basic_regex_formatter::put(const sub_match_type& sub) { typedef typename sub_match_type::iterator iterator_type; iterator_type i = sub.first; @@ -738,10 +809,10 @@ public: #endif }; -template +template OutputIterator regex_format_imp(OutputIterator out, const match_results& m, - const charT* p1, const charT* p2, + ForwardIter p1, ForwardIter p2, match_flag_type flags, const traits& t ) @@ -754,57 +825,279 @@ OutputIterator regex_format_imp(OutputIterator out, re_detail::basic_regex_formatter< OutputIterator, match_results, - traits > f(out, m, t); + traits, ForwardIter> f(out, m, t); return f.format(p1, p2, flags); } +#ifndef BOOST_NO_SFINAE + +BOOST_MPL_HAS_XXX_TRAIT_DEF(const_iterator); + +struct any_type { any_type(...); }; +typedef char no_type; +typedef char (&unary_type)[2]; +typedef char (&binary_type)[3]; +typedef char (&ternary_type)[4]; + +no_type check_is_formatter(unary_type, binary_type, ternary_type); +template +unary_type check_is_formatter(T const &, binary_type, ternary_type); +template +binary_type check_is_formatter(unary_type, T const &, ternary_type); +template +binary_type check_is_formatter(T const &, U const &, ternary_type); +template +ternary_type check_is_formatter(unary_type, binary_type, T const &); +template +ternary_type check_is_formatter(T const &, binary_type, U const &); +template +ternary_type check_is_formatter(unary_type, T const &, U const &); +template +ternary_type check_is_formatter(T const &, U const &, V const &); + +struct unary_binary_ternary +{ + typedef unary_type (*unary_fun)(any_type); + typedef binary_type (*binary_fun)(any_type, any_type); + typedef ternary_type (*ternary_fun)(any_type, any_type, any_type); + operator unary_fun(); + operator binary_fun(); + operator ternary_fun(); +}; + +template::value> +struct formatter_wrapper + : Formatter + , unary_binary_ternary +{ + formatter_wrapper(){} +}; + +template +struct formatter_wrapper + : unary_binary_ternary +{ + operator Formatter *(); +}; + +template +struct formatter_wrapper + : unary_binary_ternary +{ + operator Formatter *(); +}; + +template +struct format_traits_imp +{ +private: + // + // F must be a pointer, a function, or a class with a function call operator: + // + BOOST_STATIC_ASSERT((::boost::is_pointer::value || ::boost::is_function::value || ::boost::is_class::value)); + static formatter_wrapper f; + static M m; + static O out; + static boost::regex_constants::match_flag_type flags; +public: + BOOST_STATIC_CONSTANT(int, value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags)))); +}; + +template +struct format_traits +{ +public: + // + // Type is mpl::int_ where N is one of: + // + // 0 : F is a pointer to a presumably null-terminated string. + // 1 : F is a character-container such as a std::string. + // 2 : F is a Unary Functor. + // 3 : F is a Binary Functor. + // 4 : F is a Ternary Functor. + // + typedef typename boost::mpl::if_< + boost::mpl::and_, boost::mpl::not_::type> > >, + boost::mpl::int_<0>, + typename boost::mpl::if_< + has_const_iterator, + boost::mpl::int_<1>, + boost::mpl::int_::value> + >::type + >::type type; + // + // This static assertion will fail if the functor passed does not accept + // the same type of arguments passed. + // + BOOST_STATIC_ASSERT( boost::is_class::value && !has_const_iterator::value ? (type::value > 1) : true); +}; + +#else // BOOST_NO_SFINAE + +template +struct format_traits +{ +public: + // + // Type is mpl::int_ where N is one of: + // + // 0 : F is a pointer to a presumably null-terminated string. + // 1 : F is a character-container such as a std::string. + // + // Other options such as F being a Functor are not supported without + // SFINAE support. + // + typedef typename boost::mpl::if_< + boost::is_pointer, + boost::mpl::int_<0>, + boost::mpl::int_<1> + >::type type; +}; + +#endif // BOOST_NO_SFINAE + +template +struct format_functor3 +{ + format_functor3(Base b) : func(b) {} + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f) + { + return func(m, i, f); + } + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&) + { + return (*this)(m, i, f); + } +private: + Base func; +}; + +template +struct format_functor2 +{ + format_functor2(Base b) : func(b) {} + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/) + { + return func(m, i); + } + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&) + { + return (*this)(m, i, f); + } +private: + Base func; +}; + +template +struct format_functor1 +{ + format_functor1(Base b) : func(b) {} + + template + OutputIter do_format_string(const S& s, OutputIter i) + { + return re_detail::copy(s.begin(), s.end(), i); + } + template + inline OutputIter do_format_string(const S* s, OutputIter i) + { + while(s && *s) + { + *i = *s; + ++i; + ++s; + } + return i; + } + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/) + { + return do_format_string(func(m), i); + } + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&) + { + return (*this)(m, i, f); + } +private: + Base func; +}; + +template +struct format_functor_c_string +{ + format_functor_c_string(const charT* ps) : func(ps) {} + + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits()) + { + typedef typename Match::char_type char_type; + const charT* end = func; + while(*end) ++end; + return regex_format_imp(i, m, func, end, f, t); + } +private: + const charT* func; +}; + +template +struct format_functor_container +{ + format_functor_container(const Container& c) : func(c) {} + + template + OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits()) + { + typedef typename Match::char_type char_type; + return re_detail::regex_format_imp(i, m, func.begin(), func.end(), f, t); + } +private: + const Container& func; +}; + +template > +struct compute_functor_type +{ + typedef typename format_traits::type tag; + typedef typename boost::remove_cv< typename boost::remove_pointer::type>::type maybe_char_type; + + typedef typename mpl::if_< + ::boost::is_same >, format_functor_c_string, + typename mpl::if_< + ::boost::is_same >, format_functor_container, + typename mpl::if_< + ::boost::is_same >, format_functor1, + typename mpl::if_< + ::boost::is_same >, format_functor2, + format_functor3 + >::type + >::type + >::type + >::type type; +}; } // namespace re_detail -template -OutputIterator regex_format(OutputIterator out, - const match_results& m, - const charT* fmt, +template +inline OutputIterator regex_format(OutputIterator out, + const match_results& m, + Functor fmt, match_flag_type flags = format_all ) { - re_detail::trivial_format_traits traits; - return re_detail::regex_format_imp(out, m, fmt, fmt + traits.length(fmt), flags, traits); + return m.format(out, fmt, flags); } -template -OutputIterator regex_format(OutputIterator out, - const match_results& m, - const std::basic_string& fmt, - match_flag_type flags = format_all - ) -{ - re_detail::trivial_format_traits traits; - return re_detail::regex_format_imp(out, m, fmt.data(), fmt.data() + fmt.size(), flags, traits); -} - -template -std::basic_string regex_format(const match_results& m, - const charT* fmt, +template +inline std::basic_string::char_type> regex_format(const match_results& m, + Functor fmt, match_flag_type flags = format_all) { - std::basic_string result; - re_detail::string_out_iterator > i(result); - re_detail::trivial_format_traits traits; - re_detail::regex_format_imp(i, m, fmt, fmt + traits.length(fmt), flags, traits); - return result; -} - -template -std::basic_string regex_format(const match_results& m, - const std::basic_string& fmt, - match_flag_type flags = format_all) -{ - std::basic_string result; - re_detail::string_out_iterator > i(result); - re_detail::trivial_format_traits traits; - re_detail::regex_format_imp(i, m, fmt.data(), fmt.data() + fmt.size(), flags, traits); - return result; + return m.format(fmt, flags); } #ifdef BOOST_MSVC diff --git a/include/boost/regex/v4/regex_replace.hpp b/include/boost/regex/v4/regex_replace.hpp index c4544c05..ac8e3c81 100644 --- a/include/boost/regex/v4/regex_replace.hpp +++ b/include/boost/regex/v4/regex_replace.hpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 1998-2002 + * Copyright (c) 1998-2009 * John Maddock * * Use, modification and distribution are subject to the @@ -35,12 +35,12 @@ namespace boost{ #pragma warning(pop) #endif -template +template OutputIterator regex_replace(OutputIterator out, BidirectionalIterator first, BidirectionalIterator last, const basic_regex& e, - const charT* fmt, + Formatter fmt, match_flag_type flags = match_default) { regex_iterator i(first, last, e, flags); @@ -69,21 +69,10 @@ OutputIterator regex_replace(OutputIterator out, return out; } -template -inline OutputIterator regex_replace(OutputIterator out, - Iterator first, - Iterator last, - const basic_regex& e, - const std::basic_string& fmt, - match_flag_type flags = match_default) -{ - return regex_replace(out, first, last, e, fmt.c_str(), flags); -} - -template +template std::basic_string regex_replace(const std::basic_string& s, const basic_regex& e, - const charT* fmt, + Formatter fmt, match_flag_type flags = match_default) { std::basic_string result; @@ -92,18 +81,6 @@ std::basic_string regex_replace(const std::basic_string& s, return result; } -template -std::basic_string regex_replace(const std::basic_string& s, - const basic_regex& e, - const std::basic_string& fmt, - match_flag_type flags = match_default) -{ - std::basic_string result; - re_detail::string_out_iterator > i(result); - regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags); - return result; -} - #ifdef BOOST_MSVC #pragma warning(push) #pragma warning(disable: 4103)