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
@@ -107,7 +107,7 @@
Files: captures_test.cpp.
@@ -133,7 +133,7 @@
Files: regex_timer.cpp.
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 @@
+
+-
+ Added support for Functors rather than strings as format expressions.
+
@@ -35,7 +43,7 @@
branch resets and recursive regular expressions.
@@ -62,7 +70,7 @@
@@ -85,7 +93,7 @@
@@ -155,7 +163,7 @@
@@ -210,7 +218,7 @@
@@ -218,7 +226,7 @@
Fixed bug in partial matches of bounded repeats of '.'.
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:
@@ -90,7 +90,7 @@
are treated as "unknown" graphic characters.
@@ -114,7 +114,7 @@
libraries including version 1 of this library.
@@ -151,7 +151,7 @@
in your code. The best way to ensure this is to add the #define to <boost/regex/user.hpp>
.
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
@@ -36,7 +36,7 @@
Report on C++ Library Extensions.
@@ -49,7 +49,7 @@
rather than a Unicode escape sequence; use \x{DDDD} for Unicode escape sequences.
@@ -62,7 +62,7 @@
(??{code}) Not implementable in a compiled strongly typed language.
@@ -82,7 +82,7 @@
a custom traits class.
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.
@@ -218,7 +218,7 @@
output stream.
@@ -231,7 +231,7 @@
you can determine which sub-expressions matched by accessing the sub_match::matched
data member.
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 ':'.
@@ -40,7 +40,7 @@
you want a to output literal parenthesis.
@@ -79,7 +79,7 @@
?{NAME}true-expression:false-expression
@@ -319,7 +319,7 @@
as a literal.
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:
@@ -58,7 +58,7 @@
started guide for more information.
@@ -96,11 +96,11 @@
ICU you are using is binary compatible with the toolset you use to build Boost.
@@ -166,7 +166,7 @@
a lot in compile times!
@@ -253,7 +253,7 @@
@@ -302,7 +302,7 @@
see the config library documentation.
@@ -347,7 +347,7 @@
will build v9 variants of the regex library named libboost_regex_v9.a etc.
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
#include <boost/pattern_except.hpp>
@@ -54,7 +54,7 @@
}
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
#include <boost/regex.hpp>
@@ -244,7 +244,7 @@
}
@@ -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.
@@ -381,7 +381,7 @@
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:
@@ -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
@@ -57,7 +57,7 @@
}
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 @@
}
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
#include <boost/regex.hpp>
@@ -132,11 +132,12 @@
const_iterator begin() const;
const_iterator end() const;
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);
@@ -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:
+
+
+-
+ 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 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.
@@ -89,7 +89,7 @@
}
@@ -128,7 +128,7 @@
}
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
@@ -126,7 +126,7 @@
Provided of course that the input is encoded as UTF-8.
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:
@@ -82,7 +82,7 @@
}
@@ -110,7 +110,7 @@
}
@@ -149,7 +149,7 @@
}
@@ -164,7 +164,7 @@
+ s.GetLength(), e, f);
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
:
@@ -68,7 +68,7 @@
}
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 @@
@@ -379,7 +379,7 @@
@@ -467,7 +467,7 @@
@@ -537,7 +537,7 @@
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);
@@ -436,7 +436,7 @@
m.
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);
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)
.
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);
-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
.
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);
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)
.
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);
@@ -383,7 +383,7 @@
m.
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 @@
}
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 @@
}
@@ -473,7 +473,7 @@
@@ -1008,7 +1008,7 @@
+ m2.str().
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
@@ -46,7 +46,7 @@
@@ -56,7 +56,7 @@
.[{()\*+?|^$
@@ -74,7 +74,7 @@
@@ -86,7 +86,7 @@
of an expression, or the last character of a sub-expression.
@@ -98,7 +98,7 @@
to by a back-reference.
@@ -184,7 +184,7 @@ cab
operator to be applied to.
@@ -214,7 +214,7 @@ cab
@@ -227,7 +227,7 @@ cab
will match either of "abd" or "abef".
@@ -240,7 +240,7 @@ cab
A bracket expression may contain any combination of the following:
@@ -249,7 +249,7 @@ cab
or 'c'.
@@ -265,7 +265,7 @@ cab
the code points of the characters only.
@@ -274,7 +274,7 @@ cab
range a-c
.
@@ -284,7 +284,7 @@ cab
character class names.
@@ -312,7 +312,7 @@ cab
matches a NUL character.
@@ -329,7 +329,7 @@ cab
or even all locales on one platform.
@@ -337,7 +337,7 @@ cab
[[:digit:]a-c[.NUL.]]
.
@@ -363,7 +363,7 @@ cab
extensions are also supported by Boost.Regex:
@@ -552,7 +552,7 @@ cab
@@ -706,7 +706,7 @@ cab
@@ -813,7 +813,7 @@ cab
matches any "digit" character, as does
\p{digit}
.
@@ -888,7 +888,7 @@ cab
@@ -979,7 +979,7 @@ cab
@@ -991,7 +991,7 @@ cab
match to start where the last one ended.
@@ -1005,7 +1005,7 @@ cab
\*+aaa
@@ -1056,7 +1056,7 @@ cab
@@ -1065,7 +1065,7 @@ cab
\@ matches a literal '@'.
@@ -1101,7 +1101,7 @@ cab
@@ -1111,11 +1111,11 @@ cab
rule.
@@ -1136,7 +1136,7 @@ cab
used with the -E option.
@@ -1150,7 +1150,7 @@ cab
these by default anyway.
@@ -1163,7 +1163,7 @@ cab
modify how the case and locale sensitivity are to be applied.
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
@@ -45,7 +45,7 @@
@@ -55,7 +55,7 @@
.[\*^$
@@ -73,7 +73,7 @@
@@ -85,7 +85,7 @@
of an expression, or the last character of a sub-expression.
@@ -97,7 +97,7 @@
by a back-reference.
@@ -155,7 +155,7 @@ aaaa
to.
@@ -173,7 +173,7 @@ aaaa
aaabba
@@ -186,7 +186,7 @@ aaaa
A bracket expression may contain any combination of the following:
@@ -195,7 +195,7 @@ aaaa
or 'c'.
@@ -211,7 +211,7 @@ aaaa
of the characters only.
@@ -220,7 +220,7 @@ aaaa
range a-c.
@@ -230,7 +230,7 @@ aaaa
character class names.
@@ -259,7 +259,7 @@ aaaa
element names.
@@ -276,7 +276,7 @@ aaaa
or even all locales on one platform.
@@ -284,7 +284,7 @@ aaaa
[[:digit:]a-c[.NUL.]].
@@ -299,7 +299,7 @@ aaaa
will match either a literal '\' or a '^'.
@@ -309,13 +309,13 @@ aaaa
rule.
@@ -333,7 +333,7 @@ aaaa
As its name suggests, this behavior is consistent with the Unix utility grep.
@@ -613,7 +613,7 @@ aaaa
leftmost-longest rule.
@@ -627,7 +627,7 @@ aaaa
options modify how the case and locale sensitivity are to be applied.
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
@@ -43,7 +43,7 @@
boost::regex e2(my_expression, boost::regex::perl|boost::regex::icase);
@@ -53,7 +53,7 @@
.[{()\*+?|^$
@@ -73,7 +73,7 @@
@@ -83,7 +83,7 @@
A '$' character shall match the end of a line.
@@ -94,7 +94,7 @@
can also repeated, or referred to by a back-reference.
@@ -107,7 +107,7 @@
without splitting out any separate sub-expressions.
@@ -188,7 +188,7 @@
to be applied to.
@@ -218,7 +218,7 @@
while consuming as little input as possible.
@@ -250,7 +250,7 @@
while giving nothing back.
@@ -360,7 +360,7 @@
named "two".
@@ -387,7 +387,7 @@
(?:abc)??
has exactly the same effect.
@@ -399,7 +399,7 @@
A bracket expression may contain any combination of the following:
@@ -407,7 +407,7 @@
'b', or 'c'.
@@ -421,7 +421,7 @@
sensitive.
@@ -430,7 +430,7 @@
matches any character that is not in the range a-c
.
@@ -441,7 +441,7 @@
class names.
@@ -463,7 +463,7 @@
matches a \0
character.
@@ -480,7 +480,7 @@
or even all locales on one platform.
@@ -492,7 +492,7 @@
is not a "word" character.
@@ -500,7 +500,7 @@
[[:digit:]a-c[.NUL.]]
.
@@ -692,7 +692,7 @@
@@ -894,7 +894,7 @@
@@ -1002,7 +1002,7 @@
as does \p{digit}
.
@@ -1021,7 +1021,7 @@
\B
Matches only when not at a word boundary.
@@ -1046,7 +1046,7 @@
to the regular expression \n*\z
@@ -1058,7 +1058,7 @@
one ended.
@@ -1071,7 +1071,7 @@
\*+aaa
@@ -1081,7 +1081,7 @@
followed by a sequence of zero or more combining characters.
@@ -1090,7 +1090,7 @@
sequence, specifically it is identical to the expression (?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}])
.
@@ -1105,7 +1105,7 @@
This can be used to simulate variable width lookbehind assertions.
@@ -1114,7 +1114,7 @@
\@ matches a literal '@'.
@@ -1123,7 +1123,7 @@
(?
.
@@ -1145,14 +1145,14 @@
format string for search and replace operations, or in the match_results
member functions.
(?# ... )
is treated as a comment, it's contents are ignored.
@@ -1166,7 +1166,7 @@
pattern only.
@@ -1175,7 +1175,7 @@
an additional sub-expression.
@@ -1197,7 +1197,7 @@
# 1 2 2 3 2 3 4
@@ -1220,7 +1220,7 @@
could be used to validate the password.
@@ -1234,7 +1234,7 @@
(pattern must be of fixed length).
@@ -1247,7 +1247,7 @@
no match is found at all.
@@ -1271,7 +1271,7 @@
to the next sub-expression to be declared.
@@ -1319,7 +1319,7 @@
@@ -1354,7 +1354,7 @@
@@ -1529,7 +1529,7 @@
@@ -1538,7 +1538,7 @@
and JScript
are all synonyms for perl
.
@@ -1550,7 +1550,7 @@
are to be applied.
@@ -1562,7 +1562,7 @@
and no_mod_s
.
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:
@@ -56,7 +56,7 @@
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 @@
Copyright © 1998 -2007 John Maddock
-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