Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-06-19 22:30:26


Author: eric_niebler
Date: 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
New Revision: 46539
URL: http://svn.boost.org/trac/boost/changeset/46539

Log:
latest xpressive and proto
Added:
   branches/release/boost/xpressive/proto/detail/as_lvalue.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/detail/dont_care.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/detail/ignore_unused.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/detail/pop_front.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/detail/reverse.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/transform/bind.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/transform/call.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/transform/make.hpp (contents, props changed)
   branches/release/boost/xpressive/proto/transform/when.hpp (contents, props changed)
   branches/release/libs/xpressive/doc/tracking_ptr.qbk (contents, props changed)
   branches/release/libs/xpressive/proto/doc/CallableTransform.xml (contents, props changed)
   branches/release/libs/xpressive/proto/doc/concepts/
   branches/release/libs/xpressive/proto/doc/concepts/PolymorphicFunctionObject.xml (contents, props changed)
   branches/release/libs/xpressive/proto/doc/concepts/PrimitiveTransform.xml (contents, props changed)
   branches/release/libs/xpressive/proto/doc/concepts/Transform.xml (contents, props changed)
   branches/release/libs/xpressive/proto/doc/proto.xml (contents, props changed)
   branches/release/libs/xpressive/proto/example/futures.cpp (contents, props changed)
   branches/release/libs/xpressive/proto/example/lambda.cpp (contents, props changed)
   branches/release/libs/xpressive/proto/example/map_assign.cpp (contents, props changed)
   branches/release/libs/xpressive/proto/test/deep_copy.cpp (contents, props changed)
   branches/release/libs/xpressive/proto/test/make_expr.cpp (contents, props changed)
   branches/release/libs/xpressive/test/test_format.cpp (contents, props changed)
   branches/release/libs/xpressive/test/test_skip.cpp (contents, props changed)
Removed:
   branches/release/boost/xpressive/proto/transform/apply.hpp
   branches/release/boost/xpressive/proto/transform/branch.hpp
   branches/release/boost/xpressive/proto/transform/compose.hpp
   branches/release/boost/xpressive/proto/transform/construct.hpp
   branches/release/boost/xpressive/proto/transform/function.hpp
   branches/release/boost/xpressive/proto/transform/list.hpp
Text files modified:
   branches/release/boost/xpressive/basic_regex.hpp | 6
   branches/release/boost/xpressive/detail/core/access.hpp | 2
   branches/release/boost/xpressive/detail/core/action.hpp | 2
   branches/release/boost/xpressive/detail/core/adaptor.hpp | 2
   branches/release/boost/xpressive/detail/core/finder.hpp | 24
   branches/release/boost/xpressive/detail/core/flow_control.hpp | 2
   branches/release/boost/xpressive/detail/core/icase.hpp | 2
   branches/release/boost/xpressive/detail/core/linker.hpp | 36
   branches/release/boost/xpressive/detail/core/matcher/action_matcher.hpp | 168 +-
   branches/release/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/alternate_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/any_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/assert_line_base.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp | 10
   branches/release/boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/attr_end_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/attr_matcher.hpp | 14
   branches/release/boost/xpressive/detail/core/matcher/charset_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/end_matcher.hpp | 21
   branches/release/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/keeper_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/literal_matcher.hpp | 15
   branches/release/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp | 8
   branches/release/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/mark_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/optional_matcher.hpp | 10
   branches/release/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/predicate_matcher.hpp | 4
   branches/release/boost/xpressive/detail/core/matcher/range_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/regex_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/set_matcher.hpp | 10
   branches/release/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp | 32
   branches/release/boost/xpressive/detail/core/matcher/string_matcher.hpp | 6
   branches/release/boost/xpressive/detail/core/matcher/true_matcher.hpp | 2
   branches/release/boost/xpressive/detail/core/matchers.hpp | 2
   branches/release/boost/xpressive/detail/core/optimize.hpp | 11
   branches/release/boost/xpressive/detail/core/peeker.hpp | 112
   branches/release/boost/xpressive/detail/core/quant_style.hpp | 2
   branches/release/boost/xpressive/detail/core/regex_impl.hpp | 2
   branches/release/boost/xpressive/detail/core/results_cache.hpp | 3
   branches/release/boost/xpressive/detail/core/state.hpp | 23
   branches/release/boost/xpressive/detail/core/sub_match_impl.hpp | 2
   branches/release/boost/xpressive/detail/core/sub_match_vector.hpp | 2
   branches/release/boost/xpressive/detail/detail_fwd.hpp | 75
   branches/release/boost/xpressive/detail/dynamic/dynamic.hpp | 18
   branches/release/boost/xpressive/detail/dynamic/matchable.hpp | 2
   branches/release/boost/xpressive/detail/dynamic/parse_charset.hpp | 2
   branches/release/boost/xpressive/detail/dynamic/parser.hpp | 44
   branches/release/boost/xpressive/detail/dynamic/parser_enum.hpp | 2
   branches/release/boost/xpressive/detail/dynamic/parser_traits.hpp | 2
   branches/release/boost/xpressive/detail/dynamic/sequence.hpp | 2
   branches/release/boost/xpressive/detail/static/compile.hpp | 4
   branches/release/boost/xpressive/detail/static/grammar.hpp | 216 +-
   branches/release/boost/xpressive/detail/static/is_pure.hpp | 12
   branches/release/boost/xpressive/detail/static/modifier.hpp | 2
   branches/release/boost/xpressive/detail/static/placeholders.hpp | 2
   branches/release/boost/xpressive/detail/static/static.hpp | 2
   branches/release/boost/xpressive/detail/static/transforms/as_action.hpp | 292 ++--
   branches/release/boost/xpressive/detail/static/transforms/as_alternate.hpp | 190 +-
   branches/release/boost/xpressive/detail/static/transforms/as_independent.hpp | 169 +
   branches/release/boost/xpressive/detail/static/transforms/as_inverse.hpp | 61
   branches/release/boost/xpressive/detail/static/transforms/as_marker.hpp | 73
   branches/release/boost/xpressive/detail/static/transforms/as_matcher.hpp | 31
   branches/release/boost/xpressive/detail/static/transforms/as_modifier.hpp | 52
   branches/release/boost/xpressive/detail/static/transforms/as_quantifier.hpp | 282 ++--
   branches/release/boost/xpressive/detail/static/transforms/as_sequence.hpp | 26
   branches/release/boost/xpressive/detail/static/transforms/as_set.hpp | 240 +--
   branches/release/boost/xpressive/detail/static/transmogrify.hpp | 12
   branches/release/boost/xpressive/detail/static/type_traits.hpp | 2
   branches/release/boost/xpressive/detail/static/visitor.hpp | 2
   branches/release/boost/xpressive/detail/static/width_of.hpp | 4
   branches/release/boost/xpressive/detail/utility/algorithm.hpp | 2
   branches/release/boost/xpressive/detail/utility/any.hpp | 2
   branches/release/boost/xpressive/detail/utility/boyer_moore.hpp | 2
   branches/release/boost/xpressive/detail/utility/chset/chset.hpp | 2
   branches/release/boost/xpressive/detail/utility/cons.hpp | 2
   branches/release/boost/xpressive/detail/utility/dont_care.hpp | 2
   branches/release/boost/xpressive/detail/utility/hash_peek_bitset.hpp | 2
   branches/release/boost/xpressive/detail/utility/ignore_unused.hpp | 2
   branches/release/boost/xpressive/detail/utility/literals.hpp | 2
   branches/release/boost/xpressive/detail/utility/never_true.hpp | 2
   branches/release/boost/xpressive/detail/utility/save_restore.hpp | 2
   branches/release/boost/xpressive/detail/utility/sequence_stack.hpp | 2
   branches/release/boost/xpressive/detail/utility/symbols.hpp | 1
   branches/release/boost/xpressive/detail/utility/tracking_ptr.hpp | 3
   branches/release/boost/xpressive/detail/utility/traits_utils.hpp | 2
   branches/release/boost/xpressive/detail/utility/width.hpp | 2
   branches/release/boost/xpressive/match_results.hpp | 376 ++++
   branches/release/boost/xpressive/proto/args.hpp | 2
   branches/release/boost/xpressive/proto/context.hpp | 2
   branches/release/boost/xpressive/proto/context/callable.hpp | 143 +
   branches/release/boost/xpressive/proto/context/default.hpp | 155 +-
   branches/release/boost/xpressive/proto/context/null.hpp | 10
   branches/release/boost/xpressive/proto/debug.hpp | 56
   branches/release/boost/xpressive/proto/deep_copy.hpp | 87 +
   branches/release/boost/xpressive/proto/detail/funop.hpp | 10
   branches/release/boost/xpressive/proto/detail/prefix.hpp | 2
   branches/release/boost/xpressive/proto/detail/suffix.hpp | 2
   branches/release/boost/xpressive/proto/domain.hpp | 114 +
   branches/release/boost/xpressive/proto/eval.hpp | 43
   branches/release/boost/xpressive/proto/expr.hpp | 142 +-
   branches/release/boost/xpressive/proto/extends.hpp | 377 +++--
   branches/release/boost/xpressive/proto/fusion.hpp | 626 +++++---
   branches/release/boost/xpressive/proto/generate.hpp | 97
   branches/release/boost/xpressive/proto/literal.hpp | 44
   branches/release/boost/xpressive/proto/make_expr.hpp | 722 +++++++---
   branches/release/boost/xpressive/proto/matches.hpp | 583 +++++++-
   branches/release/boost/xpressive/proto/operators.hpp | 68
   branches/release/boost/xpressive/proto/proto.hpp | 6
   branches/release/boost/xpressive/proto/proto_fwd.hpp | 400 ++++-
   branches/release/boost/xpressive/proto/proto_typeof.hpp | 2
   branches/release/boost/xpressive/proto/ref.hpp | 146 +
   branches/release/boost/xpressive/proto/tags.hpp | 4
   branches/release/boost/xpressive/proto/traits.hpp | 2707 +++++++++++++++++++++++++++++++++++----
   branches/release/boost/xpressive/proto/transform.hpp | 12
   branches/release/boost/xpressive/proto/transform/arg.hpp | 313 ++--
   branches/release/boost/xpressive/proto/transform/fold.hpp | 416 ++++-
   branches/release/boost/xpressive/proto/transform/fold_tree.hpp | 235 ++
   branches/release/boost/xpressive/proto/transform/pass_through.hpp | 169 +
   branches/release/boost/xpressive/regex_actions.hpp | 95 +
   branches/release/boost/xpressive/regex_algorithms.hpp | 338 +++-
   branches/release/boost/xpressive/regex_compiler.hpp | 14
   branches/release/boost/xpressive/regex_constants.hpp | 2
   branches/release/boost/xpressive/regex_error.hpp | 2
   branches/release/boost/xpressive/regex_iterator.hpp | 11
   branches/release/boost/xpressive/regex_primitives.hpp | 289 +++
   branches/release/boost/xpressive/regex_token_iterator.hpp | 14
   branches/release/boost/xpressive/regex_traits.hpp | 2
   branches/release/boost/xpressive/sub_match.hpp | 2
   branches/release/boost/xpressive/traits/c_regex_traits.hpp | 2
   branches/release/boost/xpressive/traits/cpp_regex_traits.hpp | 3
   branches/release/boost/xpressive/traits/detail/c_ctype.hpp | 2
   branches/release/boost/xpressive/traits/null_regex_traits.hpp | 2
   branches/release/boost/xpressive/xpressive.hpp | 2
   branches/release/boost/xpressive/xpressive_dynamic.hpp | 2
   branches/release/boost/xpressive/xpressive_fwd.hpp | 2
   branches/release/boost/xpressive/xpressive_static.hpp | 2
   branches/release/boost/xpressive/xpressive_typeof.hpp | 29
   branches/release/libs/xpressive/doc/acknowledgements.qbk | 11
   branches/release/libs/xpressive/doc/actions.qbk | 62
   branches/release/libs/xpressive/doc/concepts.qbk | 2
   branches/release/libs/xpressive/doc/dynamic_regexes.qbk | 4
   branches/release/libs/xpressive/doc/examples.qbk | 2
   branches/release/libs/xpressive/doc/grammars.qbk | 2
   branches/release/libs/xpressive/doc/history.qbk | 25
   branches/release/libs/xpressive/doc/installation.qbk | 4
   branches/release/libs/xpressive/doc/introduction.qbk | 4
   branches/release/libs/xpressive/doc/matching.qbk | 10
   branches/release/libs/xpressive/doc/nyi.qbk | 4
   branches/release/libs/xpressive/doc/perf.qbk | 2
   branches/release/libs/xpressive/doc/preface.qbk | 2
   branches/release/libs/xpressive/doc/quick_start.qbk | 2
   branches/release/libs/xpressive/doc/regexpp_diffs.qbk | 2
   branches/release/libs/xpressive/doc/results.qbk | 2
   branches/release/libs/xpressive/doc/static_regexes.qbk | 2
   branches/release/libs/xpressive/doc/substitutions.qbk | 175 ++
   branches/release/libs/xpressive/doc/symbols.qbk | 4
   branches/release/libs/xpressive/doc/tips_n_tricks.qbk | 2
   branches/release/libs/xpressive/doc/tokenization.qbk | 2
   branches/release/libs/xpressive/doc/traits.qbk | 2
   branches/release/libs/xpressive/doc/xpressive.qbk | 8
   branches/release/libs/xpressive/example/numbers.cpp | 118
   branches/release/libs/xpressive/proto/doc/Jamfile.v2 | 120
   branches/release/libs/xpressive/proto/doc/acknowledgements.qbk | 2
   branches/release/libs/xpressive/proto/doc/calculator.qbk | 6
   branches/release/libs/xpressive/proto/doc/construction.qbk | 695 ++++++++++
   branches/release/libs/xpressive/proto/doc/evaluation.qbk | 525 +++++++
   branches/release/libs/xpressive/proto/doc/examples.qbk | 135 +
   branches/release/libs/xpressive/proto/doc/extensibility.qbk | 2
   branches/release/libs/xpressive/proto/doc/grammars.qbk | 30
   branches/release/libs/xpressive/proto/doc/history.qbk | 7
   branches/release/libs/xpressive/proto/doc/implementation.qbk | 162 ++
   branches/release/libs/xpressive/proto/doc/installation.qbk | 21
   branches/release/libs/xpressive/proto/doc/preface.qbk | 16
   branches/release/libs/xpressive/proto/doc/proto.qbk | 76
   branches/release/libs/xpressive/proto/doc/protodoc.xml | 1403 +++++++++++---------
   branches/release/libs/xpressive/proto/doc/quick_start.qbk | 2
   branches/release/libs/xpressive/proto/doc/rationale.qbk | 76 +
   branches/release/libs/xpressive/proto/doc/transforms.qbk | 1595 +++++++++++++++--------
   branches/release/libs/xpressive/proto/example/Jamfile.v2 | 15
   branches/release/libs/xpressive/proto/example/calc1.cpp | 16
   branches/release/libs/xpressive/proto/example/calc2.cpp | 34
   branches/release/libs/xpressive/proto/example/calc3.cpp | 119 -
   branches/release/libs/xpressive/proto/example/hello.cpp | 4
   branches/release/libs/xpressive/proto/example/lazy_vector.cpp | 12
   branches/release/libs/xpressive/proto/example/mixed.cpp | 108
   branches/release/libs/xpressive/proto/example/rgb.cpp | 74
   branches/release/libs/xpressive/proto/example/tarray.cpp | 26
   branches/release/libs/xpressive/proto/example/vec3.cpp | 52
   branches/release/libs/xpressive/proto/example/vector.cpp | 12
   branches/release/libs/xpressive/proto/test/Jamfile.v2 | 10
   branches/release/libs/xpressive/proto/test/calculator.cpp | 16
   branches/release/libs/xpressive/proto/test/examples.cpp | 383 +++-
   branches/release/libs/xpressive/proto/test/lambda.cpp | 94
   branches/release/libs/xpressive/proto/test/matches.cpp | 32
   branches/release/libs/xpressive/proto/test/proto_fusion.cpp | 22
   branches/release/libs/xpressive/proto/test/proto_fusion_s.cpp | 40
   branches/release/libs/xpressive/proto/test/toy_spirit.cpp | 107
   branches/release/libs/xpressive/proto/test/toy_spirit2.cpp | 441 ++---
   branches/release/libs/xpressive/test/Jamfile.v2 | 3
   branches/release/libs/xpressive/test/misc1.cpp | 2
   branches/release/libs/xpressive/test/misc2.cpp | 58
   branches/release/libs/xpressive/test/multiple_defs1.cpp | 2
   branches/release/libs/xpressive/test/multiple_defs2.cpp | 2
   branches/release/libs/xpressive/test/regress.ipp | 15
   branches/release/libs/xpressive/test/test.hpp | 2
   branches/release/libs/xpressive/test/test1.cpp | 2
   branches/release/libs/xpressive/test/test1.hpp | 2
   branches/release/libs/xpressive/test/test10.cpp | 2
   branches/release/libs/xpressive/test/test10.hpp | 2
   branches/release/libs/xpressive/test/test10u.cpp | 2
   branches/release/libs/xpressive/test/test11.cpp | 2
   branches/release/libs/xpressive/test/test11.hpp | 2
   branches/release/libs/xpressive/test/test11u.cpp | 2
   branches/release/libs/xpressive/test/test1u.cpp | 2
   branches/release/libs/xpressive/test/test2.cpp | 2
   branches/release/libs/xpressive/test/test2.hpp | 2
   branches/release/libs/xpressive/test/test2u.cpp | 2
   branches/release/libs/xpressive/test/test3.cpp | 2
   branches/release/libs/xpressive/test/test3.hpp | 2
   branches/release/libs/xpressive/test/test3u.cpp | 2
   branches/release/libs/xpressive/test/test4.cpp | 2
   branches/release/libs/xpressive/test/test4.hpp | 2
   branches/release/libs/xpressive/test/test4u.cpp | 2
   branches/release/libs/xpressive/test/test5.cpp | 2
   branches/release/libs/xpressive/test/test5.hpp | 2
   branches/release/libs/xpressive/test/test5u.cpp | 2
   branches/release/libs/xpressive/test/test6.cpp | 2
   branches/release/libs/xpressive/test/test6.hpp | 2
   branches/release/libs/xpressive/test/test6u.cpp | 2
   branches/release/libs/xpressive/test/test7.cpp | 2
   branches/release/libs/xpressive/test/test7.hpp | 2
   branches/release/libs/xpressive/test/test7u.cpp | 2
   branches/release/libs/xpressive/test/test8.cpp | 2
   branches/release/libs/xpressive/test/test8.hpp | 2
   branches/release/libs/xpressive/test/test8u.cpp | 2
   branches/release/libs/xpressive/test/test9.cpp | 2
   branches/release/libs/xpressive/test/test9.hpp | 2
   branches/release/libs/xpressive/test/test9u.cpp | 2
   branches/release/libs/xpressive/test/test_actions.cpp | 6
   branches/release/libs/xpressive/test/test_assert.cpp | 4
   branches/release/libs/xpressive/test/test_basic_regex.cpp | 2
   branches/release/libs/xpressive/test/test_cycles.cpp | 2
   branches/release/libs/xpressive/test/test_dynamic.cpp | 2
   branches/release/libs/xpressive/test/test_dynamic_grammar.cpp | 2
   branches/release/libs/xpressive/test/test_match_results.cpp | 2
   branches/release/libs/xpressive/test/test_non_char.cpp | 8
   branches/release/libs/xpressive/test/test_partial_match.cpp | 2
   branches/release/libs/xpressive/test/test_regex_algorithms.cpp | 2
   branches/release/libs/xpressive/test/test_regex_compiler.cpp | 2
   branches/release/libs/xpressive/test/test_regex_constants.cpp | 2
   branches/release/libs/xpressive/test/test_regex_error.cpp | 2
   branches/release/libs/xpressive/test/test_regex_iterator.cpp | 2
   branches/release/libs/xpressive/test/test_regex_primitives.cpp | 2
   branches/release/libs/xpressive/test/test_regex_token_iterator.cpp | 2
   branches/release/libs/xpressive/test/test_regex_traits.cpp | 2
   branches/release/libs/xpressive/test/test_static.cpp | 2
   branches/release/libs/xpressive/test/test_sub_match.cpp | 2
   branches/release/libs/xpressive/test/test_symbols.cpp | 88
   branches/release/libs/xpressive/test/test_typeof.cpp | 2
   branches/release/libs/xpressive/test/test_typeof2.cpp | 14
   271 files changed, 13012 insertions(+), 5581 deletions(-)

Modified: branches/release/boost/xpressive/basic_regex.hpp
==============================================================================
--- branches/release/boost/xpressive/basic_regex.hpp (original)
+++ branches/release/boost/xpressive/basic_regex.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains the definition of the basic_regex\<\> class template and its
 /// associated helper functions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -152,7 +152,7 @@
     /// \return A basic_regex object corresponding to the regular expression
     /// represented by the character range.
     /// \pre [begin,end) is a valid range.
- /// \pre The range of characters specified by [begin,end) contains a
+ /// \pre The range of characters specified by [begin,end) contains a
     /// valid string-based representation of a regular expression.
     /// \throw regex_error when the range of characters has invalid regular
     /// expression syntax.
@@ -239,7 +239,7 @@
     // No-op for invalid static regexes.
     /// INTERNAL ONLY
     template<typename Expr>
- void compile_(Expr const &expr, mpl::false_)
+ void compile_(Expr const &, mpl::false_)
     {
     }
 

Modified: branches/release/boost/xpressive/detail/core/access.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/access.hpp (original)
+++ branches/release/boost/xpressive/detail/core/access.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // access.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/action.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/action.hpp (original)
+++ branches/release/boost/xpressive/detail/core/action.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // action.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/adaptor.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/adaptor.hpp (original)
+++ branches/release/boost/xpressive/detail/core/adaptor.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // adaptor.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/finder.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/finder.hpp (original)
+++ branches/release/boost/xpressive/detail/core/finder.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 /// Contains the definition of the basic_regex\<\> class template and its associated helper functions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -190,6 +190,28 @@
     bool bits_[256];
 };
 
+///////////////////////////////////////////////////////////////////////////////
+// leading_simple_repeat_finder
+//
+template<typename BidiIter>
+struct leading_simple_repeat_finder
+ : finder<BidiIter>
+{
+ leading_simple_repeat_finder()
+ : finder<BidiIter>()
+ {}
+
+ bool operator ()(match_state<BidiIter> &state) const
+ {
+ state.cur_ = state.next_search_;
+ return true;
+ }
+
+private:
+ leading_simple_repeat_finder(leading_simple_repeat_finder const &);
+ leading_simple_repeat_finder &operator =(leading_simple_repeat_finder const &);
+};
+
 }}}
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)

Modified: branches/release/boost/xpressive/detail/core/flow_control.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/flow_control.hpp (original)
+++ branches/release/boost/xpressive/detail/core/flow_control.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // flow_control.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/icase.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/icase.hpp (original)
+++ branches/release/boost/xpressive/detail/core/icase.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // icase.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/linker.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/linker.hpp (original)
+++ branches/release/boost/xpressive/detail/core/linker.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // linker.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -145,6 +145,7 @@
       : back_stack_()
       , traits_(&traits)
       , traits_type_(&typeid(Traits))
+ , has_backrefs_(false)
     {
     }
 
@@ -154,12 +155,30 @@
         // no-op
     }
 
+ template<typename Traits, typename ICase>
+ void accept(mark_matcher<Traits, ICase> const &, void const *)
+ {
+ this->has_backrefs_ = true;
+ }
+
+ template<typename Action>
+ void accept(action_matcher<Action> const &, void const *)
+ {
+ this->has_backrefs_ = true;
+ }
+
+ template<typename Predicate>
+ void accept(predicate_matcher<Predicate> const &, void const *)
+ {
+ this->has_backrefs_ = true;
+ }
+
     void accept(repeat_begin_matcher const &, void const *next)
     {
         this->back_stack_.push(next);
     }
 
- template<bool Greedy>
+ template<typename Greedy>
     void accept(repeat_end_matcher<Greedy> const &matcher, void const *)
     {
         matcher.back_ = this->back_stack_.top();
@@ -179,14 +198,14 @@
         this->back_stack_.pop();
     }
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     void accept(optional_matcher<Xpr, Greedy> const &matcher, void const *next)
     {
         this->back_stack_.push(next);
         matcher.xpr_.link(*this);
     }
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     void accept(optional_mark_matcher<Xpr, Greedy> const &matcher, void const *next)
     {
         this->back_stack_.push(next);
@@ -211,12 +230,18 @@
         matcher.xpr_.link(*this);
     }
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     void accept(simple_repeat_matcher<Xpr, Greedy> const &matcher, void const *)
     {
         matcher.xpr_.link(*this);
     }
 
+ // accessors
+ bool has_backrefs() const
+ {
+ return this->has_backrefs_;
+ }
+
     // for use by alt_link_pred below
     template<typename Xpr>
     void alt_branch_link(Xpr const &xpr, void const *next, xpression_peeker<Char> *peeker)
@@ -292,6 +317,7 @@
     std::stack<void const *> back_stack_;
     void const *traits_;
     std::type_info const *traits_type_;
+ bool has_backrefs_;
 };
 
 }}} // namespace boost::xpressive::detail

Modified: branches/release/boost/xpressive/detail/core/matcher/action_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/action_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/action_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,8 +1,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 // action_matcher.hpp
 //
-// Copyright 2007 Eric Niebler.
-// Copyright 2007 David Jenkins.
+// Copyright 2008 Eric Niebler.
+// Copyright 2008 David Jenkins.
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -16,6 +16,7 @@
 # pragma once
 #endif
 
+#include <boost/config.hpp>
 #include <boost/version.hpp>
 #include <boost/ref.hpp>
 #include <boost/assert.hpp>
@@ -39,6 +40,13 @@
 # include <boost/fusion/include/pop_front.hpp>
 #endif
 
+#if BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4510) // default constructor could not be generated
+#pragma warning(disable : 4512) // assignment operator could not be generated
+#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
+#endif
+
 namespace boost { namespace xpressive { namespace detail
 {
 
@@ -75,7 +83,7 @@
         typedef
             fusion::transform_view<
                 typename fusion::result_of::push_front<
- typename fusion::result_of::pop_front<proto::children<right_type> >::type const
+ typename fusion::result_of::pop_front<right_type>::type const
                   , reference_wrapper<left_type>
>::type const
               , proto::eval_fun<Context>
@@ -91,7 +99,7 @@
             return fusion::invoke<function_type>(
                 proto::arg(proto::arg_c<0>(proto::right(expr)))
               , evaluated_args(
- fusion::push_front(fusion::pop_front(proto::children_of(proto::right(expr))), boost::ref(proto::left(expr)))
+ fusion::push_front(fusion::pop_front(proto::right(expr)), boost::ref(proto::left(expr)))
                   , proto::eval_fun<Context>(ctx)
                 )
             );
@@ -215,7 +223,7 @@
>::type
>::type
             temp_type;
-
+
             typedef typename temp_type::type result_type;
 
             result_type operator ()(Expr const &expr, action_context const &ctx) const
@@ -263,20 +271,20 @@
     ///////////////////////////////////////////////////////////////////////////////
     // subreg_transform
     //
- template<typename Grammar>
- struct subreg_transform
- : Grammar
+ struct subreg_transform : proto::callable
     {
- subreg_transform();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::terminal<sub_match<typename State::iterator> >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef State unref_state;
+ typedef typename proto::terminal<sub_match<typename unref_state::iterator> >::type type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &, State const &state, Visitor &visitor) const
         {
             sub_match<typename State::iterator> const &sub = state.sub_matches_[ visitor ];
             return proto::as_expr(sub);
@@ -286,20 +294,22 @@
     ///////////////////////////////////////////////////////////////////////////////
     // mark_transform
     //
- template<typename Grammar>
- struct mark_transform
- : Grammar
+ struct mark_transform : proto::callable
     {
- mark_transform();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::terminal<sub_match<typename State::iterator> >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef State unref_state;
+ typedef
+ typename proto::terminal<sub_match<typename unref_state::iterator> >::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &) const
         {
             sub_match<typename State::iterator> const &sub = state.sub_matches_[ proto::arg(expr).mark_number_ ];
             return proto::as_expr(sub);
@@ -331,22 +341,23 @@
     ///////////////////////////////////////////////////////////////////////////////
     // attr_transform
     //
- template<typename Grammar>
- struct attr_transform
- : Grammar
+ struct attr_transform : proto::callable
     {
- attr_transform();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::as_expr<
- opt<typename Expr::proto_arg0::matcher_type::value_type::second_type>
- >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename proto::result_of::as_expr<
+ opt<typename Expr::proto_arg0::matcher_type::value_type::second_type>
+ >::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &, State const &state, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &, State const &state, Visitor &) const
         {
             typedef typename Expr::proto_arg0::matcher_type::value_type::second_type attr_type;
             int slot = typename Expr::proto_arg0::nbr_type();
@@ -358,26 +369,28 @@
     ///////////////////////////////////////////////////////////////////////////////
     // attr_with_default_transform
     //
- template<typename Grammar>
- struct attr_with_default_transform
- : Grammar
+ template<typename Grammar, typename Callable = proto::callable>
+ struct attr_with_default_transform : proto::callable
     {
- attr_with_default_transform();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::unary_expr<
- attr_with_default_tag
- , typename Grammar::template apply<Expr, State, Visitor>::type
- >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename proto::unary_expr<
+ attr_with_default_tag
+ , typename Grammar::template result<void(Expr, State, Visitor)>::type
+ >::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
         {
- typename apply<Expr, State, Visitor>::type that = {
- Grammar::call(expr, state, visitor)
+ typename result<void(Expr, State, Visitor)>::type that = {
+ Grammar()(expr, state, visitor)
             };
             return that;
         }
@@ -386,22 +399,24 @@
     ///////////////////////////////////////////////////////////////////////////////
     // by_ref_transform
     //
- template<typename Grammar>
- struct by_ref_transform
- : Grammar
+ struct by_ref_transform : proto::callable
     {
- by_ref_transform();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::terminal<typename proto::result_of::arg<Expr>::const_reference>
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename proto::terminal<typename proto::result_of::arg<Expr>::const_reference>::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &) const
         {
- return apply<Expr, State, Visitor>::type::make(proto::arg(expr));
+ typedef typename result<void(Expr, State, Visitor)>::type that_type;
+ return that_type::make(proto::arg(expr));
         }
     };
 
@@ -410,17 +425,15 @@
     //
     struct BindActionArgs
       : proto::or_<
- subreg_transform<proto::terminal<any_matcher> >
- , mark_transform<proto::terminal<mark_placeholder> >
- , attr_transform<proto::terminal<read_attr<proto::_, proto::_> > >
- , by_ref_transform<proto::terminal<proto::_> >
- , attr_with_default_transform<
- proto::bitwise_or<
- attr_transform<proto::terminal<read_attr<proto::_, proto::_> > >
- , BindActionArgs
- >
+ proto::when<proto::terminal<any_matcher>, subreg_transform>
+ , proto::when<proto::terminal<mark_placeholder>, mark_transform>
+ , proto::when<proto::terminal<read_attr<proto::_, proto::_> >, attr_transform>
+ , proto::when<proto::terminal<proto::_>, by_ref_transform>
+ , proto::when<
+ proto::bitwise_or<proto::terminal<read_attr<proto::_, proto::_> >, BindActionArgs>
+ , attr_with_default_transform<proto::bitwise_or<attr_transform, BindActionArgs> >
>
- , proto::nary_expr<proto::_, proto::vararg<BindActionArgs> >
+ , proto::otherwise<proto::nary_expr<proto::_, proto::vararg<BindActionArgs> > >
>
     {};
 
@@ -444,8 +457,9 @@
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
             // Bind the arguments
- typedef typename BindActionArgs::apply<Actor, match_state<BidiIter>, int>::type action_type;
- action<action_type> actor(BindActionArgs::call(this->actor_, state, this->sub_));
+ int sub = this->sub_; // BUGBUG this is a hack
+ typedef typename BindActionArgs::template result<void(Actor, match_state<BidiIter>, int)>::type action_type;
+ action<action_type> actor(BindActionArgs()(this->actor_, state, sub));
 
             // Put the action in the action list
             actionable const **action_list_tail = state.action_list_tail_;
@@ -468,4 +482,8 @@
 
 }}}
 
+#if BOOST_MSVC
+#pragma warning(pop)
+#endif
+
 #endif

Modified: branches/release/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/alternate_end_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // alternate_end_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/alternate_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/alternate_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/alternate_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // alternate_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/any_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/any_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/any_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // any_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/assert_bol_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // assert_bol_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/assert_bos_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // assert_bos_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/assert_eol_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // assert_eol_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/assert_eos_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // assert_eos_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/assert_line_base.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/assert_line_base.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/assert_line_base.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // assert_line_base.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/assert_word_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // assert_word_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -16,6 +16,7 @@
 #include <boost/assert.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/quant_style.hpp>
+#include <boost/xpressive/detail/utility/ignore_unused.hpp>
 #include <boost/xpressive/detail/core/state.hpp>
 
 namespace boost { namespace xpressive { namespace detail
@@ -24,7 +25,7 @@
     ///////////////////////////////////////////////////////////////////////////////
     // word_boundary
     //
- template<bool IsBoundary>
+ template<typename IsBoundary>
     struct word_boundary
     {
         template<typename BidiIter>
@@ -32,10 +33,10 @@
         {
             if((state.flags_.match_not_bow_ && state.bos()) || (state.flags_.match_not_eow_ && state.eos()))
             {
- return !IsBoundary;
+ return !IsBoundary::value;
             }
 
- return IsBoundary == (prevword != thisword);
+ return IsBoundary::value == (prevword != thisword);
         }
     };
 
@@ -95,6 +96,7 @@
 
         bool is_word(Traits const &traits, char_type ch) const
         {
+ detail::ignore_unused(traits);
             return traits.isctype(traits.translate(ch), this->word_);
         }
 

Modified: branches/release/boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/attr_begin_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // attr_begin_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/attr_end_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/attr_end_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/attr_end_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // attr_end_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/attr_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/attr_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/attr_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,8 +1,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 // attr_matcher.hpp
 //
-// Copyright 2007 Eric Niebler.
-// Copyright 2007 David Jenkins.
+// Copyright 2008 Eric Niebler.
+// Copyright 2008 David Jenkins.
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -41,6 +41,8 @@
         {
             return this->traits_.translate(ch1);
         }
+ private:
+ char_translate &operator =(char_translate const &);
     };
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -60,12 +62,14 @@
         {
             return this->traits_.translate_nocase(ch1);
         }
+ private:
+ char_translate &operator =(char_translate const &);
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // attr_matcher
     // Note: the Matcher is a std::map
- template<typename Matcher, typename Traits, bool ICase>
+ template<typename Matcher, typename Traits, typename ICase>
     struct attr_matcher
       : quant_style<quant_none, 0, false>
     {
@@ -74,7 +78,7 @@
         attr_matcher(int slot, Matcher const &matcher, Traits const& traits)
           : slot_(slot-1)
         {
- char_translate<Traits, ICase> trans(traits);
+ char_translate<Traits, ICase::value> trans(traits);
             this->sym_.load(matcher, trans);
         }
 
@@ -82,7 +86,7 @@
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
             BidiIter tmp = state.cur_;
- char_translate<Traits, ICase> trans(traits_cast<Traits>(state));
+ char_translate<Traits, ICase::value> trans(traits_cast<Traits>(state));
             result_type const &result = this->sym_(state.cur_, state.end_, trans);
             if(result)
             {

Modified: branches/release/boost/xpressive/detail/core/matcher/charset_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/charset_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/charset_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // charset_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -23,13 +23,13 @@
     ///////////////////////////////////////////////////////////////////////////////
     // charset_matcher
     //
- template<typename Traits, bool ICase, typename CharSet>
+ template<typename Traits, typename ICase, typename CharSet>
     struct charset_matcher
       : quant_style_fixed_width<1>
     {
         typedef typename Traits::char_type char_type;
         typedef Traits traits_type;
- typedef mpl::bool_<ICase> icase_type;
+ typedef ICase icase_type;
 
         charset_matcher(CharSet const &charset = CharSet())
           : charset_(charset)

Modified: branches/release/boost/xpressive/detail/core/matcher/end_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/end_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/end_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // end_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -74,6 +74,25 @@
         }
     };
 
+ ///////////////////////////////////////////////////////////////////////////////
+ // independent_end_matcher
+ //
+ struct independent_end_matcher
+ : quant_style_assertion
+ {
+ template<typename BidiIter, typename Next>
+ bool match(match_state<BidiIter> &state, Next const &) const
+ {
+ // Now execute any actions that have been queued
+ for(actionable const *actor = state.action_list_.next; 0 != actor; actor = actor->next)
+ {
+ actor->execute(state.action_args_);
+ }
+
+ return true;
+ }
+ };
+
 }}}
 
 #endif

Modified: branches/release/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/epsilon_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // epsilon_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/keeper_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/keeper_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/keeper_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // keeper_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -71,10 +71,12 @@
 
             if(!this->xpr_.match(state))
             {
+ restore_action_queue(mem, state);
                 reclaim_sub_matches(mem, state, false);
                 return false;
             }
- else if(next.match(state))
+ restore_action_queue(mem, state);
+ if(next.match(state))
             {
                 reclaim_sub_matches(mem, state, true);
                 return true;

Modified: branches/release/boost/xpressive/detail/core/matcher/literal_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/literal_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/literal_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // literal_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -24,18 +24,17 @@
     ///////////////////////////////////////////////////////////////////////////////
     // literal_matcher
     //
- template<typename Traits, bool ICase, bool Not>
+ template<typename Traits, typename ICase, typename Not>
     struct literal_matcher
       : quant_style_fixed_width<1>
     {
         typedef typename Traits::char_type char_type;
- typedef mpl::bool_<Not> not_type;
- typedef mpl::bool_<ICase> icase_type;
+ typedef Not not_type;
+ typedef ICase icase_type;
         char_type ch_;
 
- typedef literal_matcher<Traits, ICase, !Not> inverse_type;
- explicit literal_matcher(inverse_type that)
- : ch_(that.ch_)
+ explicit literal_matcher(char_type ch)
+ : ch_(ch)
         {}
 
         literal_matcher(char_type ch, Traits const &traits)
@@ -45,7 +44,7 @@
         template<typename BidiIter, typename Next>
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
- if(state.eos() || Not ==
+ if(state.eos() || Not::value ==
                 (detail::translate(*state.cur_, traits_cast<Traits>(state), icase_type()) == this->ch_))
             {
                 return false;

Modified: branches/release/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/logical_newline_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // logical_newline_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/lookahead_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // lookahead_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -106,11 +106,13 @@
 
                 if(this->xpr_.match(state))
                 {
+ restore_action_queue(mem, state);
                     restore_sub_matches(mem, state);
                     state.cur_ = tmp;
                     return false;
                 }
- else if(next.match(state))
+ restore_action_queue(mem, state);
+ if(next.match(state))
                 {
                     reclaim_sub_matches(mem, state, true);
                     return true;
@@ -121,10 +123,12 @@
             {
                 if(!this->xpr_.match(state))
                 {
+ restore_action_queue(mem, state);
                     reclaim_sub_matches(mem, state, false);
                     return false;
                 }
                 state.cur_ = tmp;
+ restore_action_queue(mem, state);
                 if(next.match(state))
                 {
                     reclaim_sub_matches(mem, state, true);

Modified: branches/release/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/lookbehind_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // lookbehind_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -120,11 +120,13 @@
 
                 if(this->xpr_.match(state))
                 {
+ restore_action_queue(mem, state);
                     restore_sub_matches(mem, state);
                     BOOST_ASSERT(state.cur_ == tmp);
                     return false;
                 }
                 state.cur_ = tmp;
+ restore_action_queue(mem, state);
                 if(next.match(state))
                 {
                     reclaim_sub_matches(mem, state, true);
@@ -137,10 +139,12 @@
                 if(!this->xpr_.match(state))
                 {
                     state.cur_ = tmp;
+ restore_action_queue(mem, state);
                     reclaim_sub_matches(mem, state, false);
                     return false;
                 }
                 BOOST_ASSERT(state.cur_ == tmp);
+ restore_action_queue(mem, state);
                 if(next.match(state))
                 {
                     reclaim_sub_matches(mem, state, true);

Modified: branches/release/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // mark_begin_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/mark_end_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // mark_end_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/mark_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/mark_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/mark_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // mark_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -28,11 +28,11 @@
     ///////////////////////////////////////////////////////////////////////////////
     // mark_matcher
     //
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     struct mark_matcher
       : quant_style_variable_width
     {
- typedef mpl::bool_<ICase> icase_type;
+ typedef ICase icase_type;
         int mark_number_;
 
         mark_matcher(int mark_number, Traits const &)

Modified: branches/release/boost/xpressive/detail/core/matcher/optional_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/optional_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/optional_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // optional_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -23,7 +23,7 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // optional_matcher
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     struct optional_matcher
       : quant_style<quant_variable_width, unknown_width::value, Xpr::pure>
     {
@@ -37,7 +37,7 @@
         template<typename BidiIter, typename Next>
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
- return this->match_(state, next, mpl::bool_<Greedy>());
+ return this->match_(state, next, Greedy());
         }
 
     private:
@@ -79,7 +79,7 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // optional_mark_matcher
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     struct optional_mark_matcher
       : quant_style<quant_variable_width, unknown_width::value, Xpr::pure>
     {
@@ -95,7 +95,7 @@
         template<typename BidiIter, typename Next>
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
- return this->match_(state, next, mpl::bool_<Greedy>());
+ return this->match_(state, next, Greedy());
         }
 
     private:

Modified: branches/release/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/posix_charset_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // posix_charset_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/predicate_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/predicate_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/predicate_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // predicate_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -122,7 +122,7 @@
         bool match(match_state<BidiIter> &state, Next const &next) const
         {
             // Predicate is check(assertion), where assertion can be
- // a lambda or a function object.
+ // a lambda or a function object.
             return this->match_(state, next, proto::matches<Predicate, AssertionFunctor>());
         }
 

Modified: branches/release/boost/xpressive/detail/core/matcher/range_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/range_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/range_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // range_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -26,12 +26,12 @@
     ///////////////////////////////////////////////////////////////////////////////
     // range_matcher
     //
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     struct range_matcher
       : quant_style_fixed_width<1>
     {
         typedef typename Traits::char_type char_type;
- typedef mpl::bool_<ICase> icase_type;
+ typedef ICase icase_type;
         char_type ch_min_;
         char_type ch_max_;
         bool not_;

Modified: branches/release/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/regex_byref_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // regex_byref_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/regex_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/regex_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/regex_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // regex_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/repeat_begin_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // repeat_end_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/repeat_end_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // repeat_end_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -24,11 +24,11 @@
     ///////////////////////////////////////////////////////////////////////////////
     // repeat_end_matcher
     //
- template<bool Greedy>
+ template<typename Greedy>
     struct repeat_end_matcher
       : quant_style<quant_none, 0, false>
     {
- typedef mpl::bool_<Greedy> greedy_type;
+ typedef Greedy greedy_type;
         int mark_number_;
         unsigned int min_, max_;
         mutable void const *back_;

Modified: branches/release/boost/xpressive/detail/core/matcher/set_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/set_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/set_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // set.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -30,12 +30,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // set_matcher
 //
-template<typename Traits, int Size>
+template<typename Traits, typename Size>
 struct set_matcher
   : quant_style_fixed_width<1>
 {
     typedef typename Traits::char_type char_type;
- char_type set_[ Size ];
+ char_type set_[ Size::value ];
     bool not_;
     bool icase_;
 
@@ -55,7 +55,7 @@
     {
         this->icase_ = true;
 
- for(int i = 0; i < Size; ++i)
+ for(int i = 0; i < Size::value; ++i)
         {
             this->set_[i] = traits.translate_nocase(this->set_[i]);
         }
@@ -63,7 +63,7 @@
 
     bool in_set(Traits const &traits, char_type ch) const
     {
- char_type const *begin = &this->set_[0], *end = begin + Size;
+ char_type const *begin = &this->set_[0], *end = begin + Size::value;
         ch = this->icase_ ? traits.translate_nocase(ch) : traits.translate(ch);
         return end != std::find(begin, end, ch);
     }

Modified: branches/release/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/simple_repeat_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // simple_repeat_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -16,6 +16,7 @@
 #include <boost/assert.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/bool.hpp>
+#include <boost/next_prior.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/quant_style.hpp>
 #include <boost/xpressive/detail/core/state.hpp>
@@ -55,22 +56,24 @@
     ///////////////////////////////////////////////////////////////////////////////
     // simple_repeat_matcher
     //
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     struct simple_repeat_matcher
       : quant_style_variable_width
     {
         typedef Xpr xpr_type;
- typedef mpl::bool_<Greedy> greedy_type;
+ typedef Greedy greedy_type;
 
         Xpr xpr_;
         unsigned int min_, max_;
         std::size_t width_;
+ mutable bool leading_;
 
         simple_repeat_matcher(Xpr const &xpr, unsigned int min, unsigned int max, std::size_t width)
           : xpr_(xpr)
           , min_(min)
           , max_(max)
           , width_(width)
+ , leading_(false)
         {
             // it is the job of the parser to make sure this never happens
             BOOST_ASSERT(min <= max);
@@ -101,6 +104,16 @@
                 ++matches;
             }
 
+ // If this repeater is at the front of the pattern, note
+ // how much of the input we consumed so that a repeated search
+ // doesn't have to cover the same ground again.
+ if(this->leading_)
+ {
+ state.next_search_ = (matches && matches < this->max_)
+ ? state.cur_
+ : (tmp == state.end_) ? tmp : boost::next(tmp);
+ }
+
             if(this->min_ > matches)
             {
                 state.cur_ = tmp;
@@ -126,6 +139,7 @@
         template<typename BidiIter, typename Next>
         bool match_(match_state<BidiIter> &state, Next const &next, non_greedy_tag) const
         {
+ BOOST_ASSERT(!this->leading_);
             BidiIter const tmp = state.cur_;
             unsigned int matches = 0;
 
@@ -161,12 +175,24 @@
             // is there enough room?
             if(this->min_ > diff_to_end)
             {
+ if(this->leading_)
+ {
+ // BUGBUG
+ state.next_search_ = boost::next(tmp);
+ }
                 return false;
             }
 
             BidiIter const min_iter = tmp + this->min_;
             state.cur_ += (std::min)((std::size_t)this->max_, diff_to_end);
 
+ if(this->leading_)
+ {
+ state.next_search_ = (diff_to_end && diff_to_end < this->max_)
+ ? state.cur_
+ : (tmp == state.end_) ? tmp : boost::next(tmp);
+ }
+
             for(;; --state.cur_)
             {
                 if(next.match(state))

Modified: branches/release/boost/xpressive/detail/core/matcher/string_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/string_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/string_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // string_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -26,13 +26,13 @@
     ///////////////////////////////////////////////////////////////////////////////
     // string_matcher
     //
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     struct string_matcher
       : quant_style_fixed_unknown_width
     {
         typedef typename Traits::char_type char_type;
         typedef typename Traits::string_type string_type;
- typedef mpl::bool_<ICase> icase_type;
+ typedef ICase icase_type;
         string_type str_;
         char_type const *end_;
 

Modified: branches/release/boost/xpressive/detail/core/matcher/true_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matcher/true_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matcher/true_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // true_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/matchers.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/matchers.hpp (original)
+++ branches/release/boost/xpressive/detail/core/matchers.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // matchers.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/optimize.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/optimize.hpp (original)
+++ branches/release/boost/xpressive/detail/core/optimize.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // optimize.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -39,6 +39,13 @@
             new line_start_finder<BidiIter, Traits>(traits)
         );
     }
+ else if(peeker.leading_simple_repeat())
+ {
+ return intrusive_ptr<finder<BidiIter> >
+ (
+ new leading_simple_repeat_finder<BidiIter>()
+ );
+ }
     else if(256 != peeker.bitset().count())
     {
         return intrusive_ptr<finder<BidiIter> >
@@ -96,7 +103,7 @@
 
     // "peek" into the compiled regex to see if there are optimization opportunities
     hash_peek_bitset<char_type> bset;
- xpression_peeker<char_type> peeker(bset, traits);
+ xpression_peeker<char_type> peeker(bset, traits, linker.has_backrefs());
     regex->peek(peeker);
 
     // optimization: get the peek chars OR the boyer-moore search string

Modified: branches/release/boost/xpressive/detail/core/peeker.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/peeker.hpp (original)
+++ branches/release/boost/xpressive/detail/core/peeker.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // peeker.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -31,28 +31,7 @@
 {
 
 ///////////////////////////////////////////////////////////////////////////////
-// peek_next
-// tell whether or not to keep looking for a peek optimization
-template<typename Matcher>
-struct peek_next
- : mpl::bool_<Matcher::width == 0>
-{
-};
-
-template<>
-struct peek_next<mark_begin_matcher>
- : mpl::true_
-{
-};
-
-template<>
-struct peek_next<repeat_begin_matcher>
- : mpl::true_
-{
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// xpression_peeker
+// peeker_string
 //
 template<typename Char>
 struct peeker_string
@@ -82,6 +61,8 @@
 
     hash_peek_bitset<char_type> &bset_;
     Traits const &traits_;
+private:
+ char_sink &operator =(char_sink const &);
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -91,12 +72,14 @@
 struct xpression_peeker
 {
     template<typename Traits>
- xpression_peeker(hash_peek_bitset<Char> &bset, Traits const &traits)
+ xpression_peeker(hash_peek_bitset<Char> &bset, Traits const &traits, bool has_backrefs = false)
       : bset_(bset)
       , str_()
       , line_start_(false)
       , traits_(0)
       , traits_type_(0)
+ , leading_simple_repeat_(0)
+ , has_backrefs_(has_backrefs)
     {
         this->set_traits(traits);
     }
@@ -113,6 +96,11 @@
         return this->line_start_;
     }
 
+ bool leading_simple_repeat() const
+ {
+ return 0 < this->leading_simple_repeat_;
+ }
+
     hash_peek_bitset<Char> const &bitset() const
     {
         return this->bset_;
@@ -120,19 +108,31 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // modifiers
- void fail(bool do_fail = true)
+ void fail()
+ {
+ this->bset_.set_all();
+ }
+
+ template<typename Matcher>
+ mpl::false_ accept(Matcher const &)
+ {
+ this->fail();
+ return mpl::false_();
+ }
+
+ mpl::true_ accept(mark_begin_matcher const &)
     {
- if(do_fail)
+ if(this->has_backrefs_)
         {
- this->bset_.set_all();
+ --this->leading_simple_repeat_;
         }
+ return mpl::true_();
     }
 
- template<typename Matcher>
- peek_next<Matcher> accept(Matcher const &)
+ mpl::true_ accept(repeat_begin_matcher const &)
     {
- this->fail(!peek_next<Matcher>::value);
- return peek_next<Matcher>();
+ --this->leading_simple_repeat_;
+ return mpl::true_();
     }
 
     template<typename Traits>
@@ -142,20 +142,20 @@
         return mpl::true_();
     }
 
- template<typename Traits, bool ICase>
- mpl::false_ accept(literal_matcher<Traits, ICase, false> const &xpr)
+ template<typename Traits, typename ICase>
+ mpl::false_ accept(literal_matcher<Traits, ICase, mpl::false_> const &xpr)
     {
- this->bset_.set_char(xpr.ch_, ICase, this->get_traits_<Traits>());
+ this->bset_.set_char(xpr.ch_, ICase(), this->get_traits_<Traits>());
         return mpl::false_();
     }
 
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     mpl::false_ accept(string_matcher<Traits, ICase> const &xpr)
     {
- this->bset_.set_char(xpr.str_[0], ICase, this->get_traits_<Traits>());
+ this->bset_.set_char(xpr.str_[0], ICase(), this->get_traits_<Traits>());
         this->str_.begin_ = detail::data_begin(xpr.str_);
         this->str_.end_ = detail::data_end(xpr.str_);
- this->str_.icase_ = ICase;
+ this->str_.icase_ = ICase::value;
         return mpl::false_();
     }
 
@@ -167,35 +167,35 @@
         return mpl::false_();
     }
 
- template<typename Matcher, typename Traits, bool ICase>
+ template<typename Matcher, typename Traits, typename ICase>
     mpl::false_ accept(attr_matcher<Matcher, Traits, ICase> const &xpr)
     {
- xpr.sym_.peek(char_sink<Traits, ICase>(this->bset_, this->get_traits_<Traits>()));
+ xpr.sym_.peek(char_sink<Traits, ICase::value>(this->bset_, this->get_traits_<Traits>()));
         return mpl::false_();
     }
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     mpl::false_ accept(optional_matcher<Xpr, Greedy> const &)
     {
         this->fail(); // a union of xpr and next
         return mpl::false_();
     }
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     mpl::false_ accept(optional_mark_matcher<Xpr, Greedy> const &)
     {
         this->fail(); // a union of xpr and next
         return mpl::false_();
     }
 
- //template<typename Xpr, bool Greedy>
+ //template<typename Xpr, typename Greedy>
     //mpl::true_ accept(optional_matcher<Xpr, Greedy> const &xpr)
     //{
     // xpr.xpr_.peek(*this); // a union of xpr and next
     // return mpl::true_();
     //}
 
- //template<typename Xpr, bool Greedy>
+ //template<typename Xpr, typename Greedy>
     //mpl::true_ accept(optional_mark_matcher<Xpr, Greedy> const &xpr)
     //{
     // xpr.xpr_.peek(*this); // a union of xpr and next
@@ -209,29 +209,41 @@
         return mpl::false_();
     }
 
- template<bool ICase, typename Traits>
+ template<typename ICase, typename Traits>
     typename enable_if<is_narrow_char<typename Traits::char_type>, mpl::false_>::type
     accept(charset_matcher<Traits, ICase, basic_chset<Char> > const &xpr)
     {
         BOOST_ASSERT(0 != xpr.charset_.base().count());
- this->bset_.set_charset(xpr.charset_, ICase);
+ this->bset_.set_charset(xpr.charset_, ICase());
         return mpl::false_();
     }
 
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     mpl::false_ accept(range_matcher<Traits, ICase> const &xpr)
     {
- this->bset_.set_range(xpr.ch_min_, xpr.ch_max_, xpr.not_, ICase, this->get_traits_<Traits>());
+ this->bset_.set_range(xpr.ch_min_, xpr.ch_max_, xpr.not_, ICase(), this->get_traits_<Traits>());
         return mpl::false_();
     }
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     mpl::false_ accept(simple_repeat_matcher<Xpr, Greedy> const &xpr)
     {
+ if(Greedy() && 1U == xpr.width_)
+ {
+ ++this->leading_simple_repeat_;
+ xpr.leading_ = this->leading_simple_repeat();
+ }
         0 != xpr.min_ ? xpr.xpr_.peek(*this) : this->fail(); // could be a union of xpr and next
         return mpl::false_();
     }
 
+ template<typename Xpr>
+ mpl::false_ accept(keeper_matcher<Xpr> const &xpr)
+ {
+ xpr.xpr_.peek(*this);
+ return mpl::false_();
+ }
+
     template<typename Traits>
     void set_traits(Traits const &traits)
     {
@@ -247,6 +259,8 @@
     }
 
 private:
+ xpression_peeker(xpression_peeker const &);
+ xpression_peeker &operator =(xpression_peeker const &);
 
     template<typename Traits>
     Traits const &get_traits_() const
@@ -261,6 +275,8 @@
     bool line_start_;
     void const *traits_;
     std::type_info const *traits_type_;
+ int leading_simple_repeat_;
+ bool has_backrefs_;
 };
 
 }}} // namespace boost::xpressive::detail

Modified: branches/release/boost/xpressive/detail/core/quant_style.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/quant_style.hpp (original)
+++ branches/release/boost/xpressive/detail/core/quant_style.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // quant_style.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/regex_impl.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/regex_impl.hpp (original)
+++ branches/release/boost/xpressive/detail/core/regex_impl.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // regex_impl.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/results_cache.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/results_cache.hpp (original)
+++ branches/release/boost/xpressive/detail/core/results_cache.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // results_cache.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -14,6 +14,7 @@
 #endif
 
 #include <list>
+#include <boost/detail/workaround.hpp>
 #include <boost/assert.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/access.hpp>

Modified: branches/release/boost/xpressive/detail/core/state.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/state.hpp (original)
+++ branches/release/boost/xpressive/detail/core/state.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // state.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -127,6 +127,7 @@
     actionable const **action_list_tail_;
     action_args_type *action_args_;
     attr_context attr_context_;
+ BidiIter next_search_;
 
     ///////////////////////////////////////////////////////////////////////////////
     //
@@ -151,6 +152,7 @@
       , action_list_tail_(&action_list_.next)
       , action_args_(&core_access<BidiIter>::get_action_args(what))
       , attr_context_() // zero-initializes the fields of attr_context_
+ , next_search_(begin)
     {
         // reclaim any cached memory in the match_results struct
         this->extras_->sub_match_stack_.unwind();
@@ -314,6 +316,7 @@
 {
     sub_match_impl<BidiIter> *old_sub_matches_;
     std::size_t nested_results_count_;
+ actionable const *action_list_head_;
     actionable const **action_list_tail_;
     attr_context attr_context_;
 };
@@ -328,14 +331,28 @@
     {
         state.extras_->sub_match_stack_.push_sequence(state.mark_count_, no_fill)
       , state.context_.results_ptr_->nested_results().size()
+ , state.action_list_.next
       , state.action_list_tail_
       , state.attr_context_
     };
+ state.action_list_.next = 0;
+ state.action_list_tail_ = &state.action_list_.next;
     std::copy(state.sub_matches_, state.sub_matches_ + state.mark_count_, mem.old_sub_matches_);
     return mem;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+// restore_action_queue
+//
+template<typename BidiIter>
+inline void restore_action_queue(memento<BidiIter> const &mem, match_state<BidiIter> &state)
+{
+ state.action_list_.next = mem.action_list_head_;
+ state.action_list_tail_ = mem.action_list_tail_;
+ *state.action_list_tail_ = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
 // restore_sub_matches
 //
 template<typename BidiIter>
@@ -348,8 +365,6 @@
     std::copy(mem.old_sub_matches_, mem.old_sub_matches_ + state.mark_count_, state.sub_matches_);
     state.extras_->sub_match_stack_.unwind_to(mem.old_sub_matches_);
     state.attr_context_ = mem.attr_context_;
- state.action_list_tail_ = mem.action_list_tail_;
- *state.action_list_tail_ = 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -369,8 +384,6 @@
     if(!success)
     {
         state.attr_context_ = mem.attr_context_;
- state.action_list_tail_ = mem.action_list_tail_;
- *state.action_list_tail_ = 0;
     }
 }
 

Modified: branches/release/boost/xpressive/detail/core/sub_match_impl.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/sub_match_impl.hpp (original)
+++ branches/release/boost/xpressive/detail/core/sub_match_impl.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // sub_match_impl.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/core/sub_match_vector.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/core/sub_match_vector.hpp (original)
+++ branches/release/boost/xpressive/detail/core/sub_match_vector.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // sub_match_vector.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/detail_fwd.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/detail_fwd.hpp (original)
+++ branches/release/boost/xpressive/detail/detail_fwd.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // detail_fwd.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -39,6 +39,11 @@
     struct type_info_less;
 
     typedef std::map<std::type_info const *, void *, type_info_less> action_args_type;
+
+ struct action_context;
+
+ template<typename BidiIter>
+ struct replacement_context;
 
     ///////////////////////////////////////////////////////////////////////////////
     // placeholders
@@ -69,6 +74,8 @@
     //
     struct end_matcher;
 
+ struct independent_end_matcher;
+
     struct assert_bos_matcher;
 
     struct assert_eos_matcher;
@@ -95,7 +102,7 @@
     template<typename BidiIter>
     struct sequence;
 
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     struct mark_matcher;
 
     struct mark_begin_matcher;
@@ -111,27 +118,27 @@
     template<typename Traits>
     struct compound_charset;
 
- template<typename Traits, bool ICase, typename CharSet = compound_charset<Traits> >
+ template<typename Traits, typename ICase, typename CharSet = compound_charset<Traits> >
     struct charset_matcher;
 
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     struct range_matcher;
 
- template<typename Traits, int Size>
+ template<typename Traits, typename Size>
     struct set_matcher;
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     struct simple_repeat_matcher;
 
     struct repeat_begin_matcher;
 
- template<bool Greedy>
+ template<typename Greedy>
     struct repeat_end_matcher;
 
- template<typename Traits, bool ICase, bool Not>
+ template<typename Traits, typename ICase, typename Not>
     struct literal_matcher;
 
- template<typename Traits, bool ICase>
+ template<typename Traits, typename ICase>
     struct string_matcher;
 
     template<typename Actor>
@@ -140,13 +147,13 @@
     template<typename Predicate>
     struct predicate_matcher;
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     struct optional_matcher;
 
- template<typename Xpr, bool Greedy>
+ template<typename Xpr, typename Greedy>
     struct optional_mark_matcher;
 
- template<typename Matcher, typename Traits, bool ICase>
+ template<typename Matcher, typename Traits, typename ICase>
     struct attr_matcher;
 
     template<typename Nbr>
@@ -188,7 +195,7 @@
     template<typename Xpr>
     struct lookbehind_matcher;
 
- template<bool IsBoundary>
+ template<typename IsBoundary>
     struct word_boundary;
 
     template<typename BidiIter, typename Matcher>
@@ -264,6 +271,8 @@
 
     typedef static_xpression<alternate_end_matcher, no_next> alternate_end_xpression;
 
+ typedef static_xpression<independent_end_matcher, no_next> independent_end_xpression;
+
     typedef static_xpression<true_matcher, no_next> true_xpression;
 
     template<typename Matcher, typename Next = end_xpression>
@@ -386,6 +395,46 @@
 
 }}} // namespace boost::xpressive::detail
 
+namespace boost { namespace xpressive { namespace grammar_detail
+{
+ using proto::_;
+ using proto::or_;
+ using proto::if_;
+ using proto::call;
+ using proto::when;
+ using proto::otherwise;
+ using proto::switch_;
+ using proto::make;
+ using proto::_arg;
+ using proto::_left;
+ using proto::_right;
+ using proto::not_;
+ using proto::_state;
+ using proto::_visitor;
+ using proto::callable;
+ using proto::fold;
+ using proto::reverse_fold;
+ using proto::fold_tree;
+ using proto::reverse_fold_tree;
+ using proto::terminal;
+ using proto::shift_right;
+ using proto::bitwise_or;
+ using proto::logical_not;
+ using proto::dereference;
+ using proto::posit;
+ using proto::negate;
+ using proto::complement;
+ using proto::comma;
+ using proto::assign;
+ using proto::subscript;
+ using proto::nary_expr;
+ using proto::unary_expr;
+ using proto::binary_expr;
+ using proto::_deep_copy;
+ using proto::vararg;
+ namespace tag = proto::tag;
+}}}
+
 namespace boost { namespace xpressive { namespace op
 {
     struct push;

Modified: branches/release/boost/xpressive/detail/dynamic/dynamic.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/dynamic.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/dynamic.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // dynamic.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -213,12 +213,12 @@
 {
     if(spec.greedy_)
     {
- simple_repeat_matcher<Xpr, true> quant(xpr, spec.min_, spec.max_, seq.width().value());
+ simple_repeat_matcher<Xpr, mpl::true_> quant(xpr, spec.min_, spec.max_, seq.width().value());
         seq = make_dynamic<BidiIter>(quant);
     }
     else
     {
- simple_repeat_matcher<Xpr, false> quant(xpr, spec.min_, spec.max_, seq.width().value());
+ simple_repeat_matcher<Xpr, mpl::false_> quant(xpr, spec.min_, spec.max_, seq.width().value());
         seq = make_dynamic<BidiIter>(quant);
     }
 }
@@ -243,12 +243,12 @@
     seq += make_dynamic<BidiIter>(alternate_end_matcher());
     if(spec.greedy_)
     {
- optional_matcher<xpr_type, true> opt(seq.xpr());
+ optional_matcher<xpr_type, mpl::true_> opt(seq.xpr());
         seq = make_dynamic<BidiIter>(opt);
     }
     else
     {
- optional_matcher<xpr_type, false> opt(seq.xpr());
+ optional_matcher<xpr_type, mpl::false_> opt(seq.xpr());
         seq = make_dynamic<BidiIter>(opt);
     }
 }
@@ -263,12 +263,12 @@
     seq += make_dynamic<BidiIter>(alternate_end_matcher());
     if(spec.greedy_)
     {
- optional_mark_matcher<xpr_type, true> opt(seq.xpr(), mark_nbr);
+ optional_mark_matcher<xpr_type, mpl::true_> opt(seq.xpr(), mark_nbr);
         seq = make_dynamic<BidiIter>(opt);
     }
     else
     {
- optional_mark_matcher<xpr_type, false> opt(seq.xpr(), mark_nbr);
+ optional_mark_matcher<xpr_type, mpl::false_> opt(seq.xpr(), mark_nbr);
         seq = make_dynamic<BidiIter>(opt);
     }
 }
@@ -313,13 +313,13 @@
         repeat_begin_matcher repeat_begin(mark_nbr);
         if(spec.greedy_)
         {
- repeat_end_matcher<true> repeat_end(mark_nbr, min, spec.max_);
+ repeat_end_matcher<mpl::true_> repeat_end(mark_nbr, min, spec.max_);
             seq = make_dynamic<BidiIter>(repeat_begin) + seq
                 + make_dynamic<BidiIter>(repeat_end);
         }
         else
         {
- repeat_end_matcher<false> repeat_end(mark_nbr, min, spec.max_);
+ repeat_end_matcher<mpl::false_> repeat_end(mark_nbr, min, spec.max_);
             seq = make_dynamic<BidiIter>(repeat_begin) + seq
                 + make_dynamic<BidiIter>(repeat_end);
         }

Modified: branches/release/boost/xpressive/detail/dynamic/matchable.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/matchable.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/matchable.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // matchable.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/dynamic/parse_charset.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/parse_charset.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/parse_charset.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // parse_charset.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/dynamic/parser.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/parser.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/parser.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains the definition of regex_compiler, a factory for building regex objects
 /// from strings.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -21,6 +21,7 @@
 #include <boost/xpressive/regex_constants.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/matchers.hpp>
+#include <boost/xpressive/detail/utility/ignore_unused.hpp>
 #include <boost/xpressive/detail/dynamic/dynamic.hpp>
 
 // The Regular Expression grammar, in pseudo BNF:
@@ -57,12 +58,12 @@
 {
     if(0 != (regex_constants::icase_ & flags))
     {
- literal_matcher<Traits, true, false> matcher(ch, traits);
+ literal_matcher<Traits, mpl::true_, mpl::false_> matcher(ch, traits);
         return make_dynamic<BidiIter>(matcher);
     }
     else
     {
- literal_matcher<Traits, false, false> matcher(ch, traits);
+ literal_matcher<Traits, mpl::false_, mpl::false_> matcher(ch, traits);
         return make_dynamic<BidiIter>(matcher);
     }
 }
@@ -79,8 +80,8 @@
 {
     using namespace regex_constants;
     typedef typename iterator_value<BidiIter>::type char_type;
- typedef set_matcher<Traits, 2> set_matcher;
- typedef literal_matcher<Traits, false, true> literal_matcher;
+ typedef detail::set_matcher<Traits, mpl::int_<2> > set_matcher;
+ typedef literal_matcher<Traits, mpl::false_, mpl::true_> literal_matcher;
 
     char_type const newline = traits.widen('\n');
     set_matcher s;
@@ -123,12 +124,12 @@
 
     if(0 != (regex_constants::icase_ & flags))
     {
- string_matcher<Traits, true> matcher(literal, traits);
+ string_matcher<Traits, mpl::true_> matcher(literal, traits);
         return make_dynamic<BidiIter>(matcher);
     }
     else
     {
- string_matcher<Traits, false> matcher(literal, traits);
+ string_matcher<Traits, mpl::false_> matcher(literal, traits);
         return make_dynamic<BidiIter>(matcher);
     }
 }
@@ -148,14 +149,14 @@
     {
         return make_dynamic<BidiIter>
         (
- mark_matcher<Traits, true>(mark_nbr, traits)
+ mark_matcher<Traits, mpl::true_>(mark_nbr, traits)
         );
     }
     else
     {
         return make_dynamic<BidiIter>
         (
- mark_matcher<Traits, false>(mark_nbr, traits)
+ mark_matcher<Traits, mpl::false_>(mark_nbr, traits)
         );
     }
 }
@@ -171,6 +172,7 @@
   , Traits const &traits
 )
 {
+ detail::ignore_unused(traits);
     if(0 != compound.posix_yes())
     {
         typename Traits::char_class_type mask = compound.posix_yes();
@@ -226,13 +228,13 @@
         charset_type charset(chset.base());
         if(icase)
         {
- charset_matcher<Traits, true, charset_type> matcher(charset);
+ charset_matcher<Traits, mpl::true_, charset_type> matcher(charset);
             merge_charset(matcher.charset_, chset, traits);
             return make_dynamic<BidiIter>(matcher);
         }
         else
         {
- charset_matcher<Traits, false, charset_type> matcher(charset);
+ charset_matcher<Traits, mpl::false_, charset_type> matcher(charset);
             merge_charset(matcher.charset_, chset, traits);
             return make_dynamic<BidiIter>(matcher);
         }
@@ -251,12 +253,12 @@
     {
         if(icase)
         {
- charset_matcher<Traits, true> matcher(chset);
+ charset_matcher<Traits, mpl::true_> matcher(chset);
             return make_dynamic<BidiIter>(matcher);
         }
         else
         {
- charset_matcher<Traits, false> matcher(chset);
+ charset_matcher<Traits, mpl::false_> matcher(chset);
             return make_dynamic<BidiIter>(matcher);
         }
     }
@@ -333,6 +335,22 @@
     );
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// make_independent_end_xpression
+//
+template<typename BidiIter>
+inline sequence<BidiIter> make_independent_end_xpression(bool pure)
+{
+ if(pure)
+ {
+ return detail::make_dynamic<BidiIter>(detail::true_matcher());
+ }
+ else
+ {
+ return detail::make_dynamic<BidiIter>(detail::independent_end_matcher());
+ }
+}
+
 }}} // namespace boost::xpressive::detail
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)

Modified: branches/release/boost/xpressive/detail/dynamic/parser_enum.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/parser_enum.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/parser_enum.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // parser_enum.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/dynamic/parser_traits.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/parser_traits.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/parser_traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // detail/dynamic/parser_traits.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/dynamic/sequence.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/dynamic/sequence.hpp (original)
+++ branches/release/boost/xpressive/detail/dynamic/sequence.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // sequence.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/static/compile.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/compile.hpp (original)
+++ branches/release/boost/xpressive/detail/static/compile.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // compile.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -41,7 +41,7 @@
         // "compile" the regex and wrap it in an xpression_adaptor.
         xpression_visitor<BidiIter, mpl::false_, Traits> visitor(traits, impl);
         intrusive_ptr<matchable_ex<BidiIter> const> adxpr = make_adaptor<matchable_ex<BidiIter> >(
- Grammar<char_type>::call(xpr, end_xpression(), visitor)
+ Grammar<char_type>()(xpr, end_xpression(), visitor)
         );
 
         // Link and optimize the regex

Modified: branches/release/boost/xpressive/detail/static/grammar.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/grammar.hpp (original)
+++ branches/release/boost/xpressive/detail/static/grammar.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // grammar.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -16,11 +16,8 @@
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/assert.hpp>
-#include <boost/xpressive/detail/static/is_pure.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
-#include <boost/xpressive/proto/transform/compose.hpp>
+#include <boost/xpressive/detail/static/is_pure.hpp>
 #include <boost/xpressive/detail/static/transforms/as_matcher.hpp>
 #include <boost/xpressive/detail/static/transforms/as_alternate.hpp>
 #include <boost/xpressive/detail/static/transforms/as_sequence.hpp>
@@ -61,7 +58,7 @@
     template<typename Char>
     struct ActionableGrammar;
 
- namespace detail
+ namespace grammar_detail
     {
         ///////////////////////////////////////////////////////////////////////////
         // CharLiteral
@@ -75,43 +72,43 @@
 
         ///////////////////////////////////////////////////////////////////////////
         // as_repeat
- template<typename Char, typename Gram, typename Tag, bool Greedy>
+ template<typename Char, typename Gram, typename Greedy>
         struct as_repeat
- : proto::if_<
- use_simple_repeat<proto::result_of::arg<mpl::_>, Char>
- , as_simple_quantifier<proto::unary_expr<Tag, Gram>, Greedy>
- , as_default_quantifier<proto::unary_expr<Tag, Gram>, Greedy>
+ : if_<
+ make<detail::use_simple_repeat<_arg, Char> >
+ , as_simple_quantifier<Gram, Greedy>
+ , as_default_quantifier<Greedy>
>
         {};
 
         ///////////////////////////////////////////////////////////////////////////
         // NonGreedyRepeatCases
- template<typename Char, typename Gram>
+ template<typename Gram>
         struct NonGreedyRepeatCases
         {
             template<typename Tag, typename Dummy = void>
             struct case_
- : proto::not_<proto::_>
+ : not_<_>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::dereference, Dummy>
- : as_repeat<Char, Gram, proto::tag::dereference, false>
+ struct case_<tag::dereference, Dummy>
+ : dereference<Gram>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::posit, Dummy>
- : as_repeat<Char, Gram, proto::tag::posit, false>
+ struct case_<tag::posit, Dummy>
+ : posit<Gram>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::logical_not, Dummy>
- : as_repeat<Char, Gram, proto::tag::logical_not, false>
+ struct case_<tag::logical_not, Dummy>
+ : logical_not<Gram>
             {};
 
             template<uint_t Min, uint_t Max, typename Dummy>
- struct case_<generic_quant_tag<Min, Max>, Dummy>
- : as_repeat<Char, Gram, generic_quant_tag<Min, Max>, false>
+ struct case_<detail::generic_quant_tag<Min, Max>, Dummy>
+ : unary_expr<detail::generic_quant_tag<Min, Max>, Gram>
             {};
         };
 
@@ -122,42 +119,51 @@
         {
             template<typename Tag, typename Dummy = void>
             struct case_
- : proto::not_<proto::_>
+ : not_<_>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::comma, Dummy>
- : as_list_set<ListSet<Char> >
+ struct case_<tag::comma, Dummy>
+ : when<ListSet<Char>, as_list_set_matcher<Char> >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::assign, Dummy>
- : as_list_set<ListSet<Char> >
+ struct case_<tag::assign, Dummy>
+ : when<ListSet<Char>, as_list_set_matcher<Char> >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::subscript, Dummy>
- : proto::transform::right<proto::subscript<set_initializer_type, as_set<Gram> > >
+ struct case_<tag::subscript, Dummy>
+ : when<subscript<detail::set_initializer_type, Gram>, call<as_set_matcher<Gram>(_right)> >
             {};
 
             template<typename Dummy>
- struct case_<lookahead_tag, Dummy>
- : proto::transform::arg<proto::unary_expr<lookahead_tag, as_lookahead<Gram> > >
+ struct case_<detail::lookahead_tag, Dummy>
+ : when<
+ unary_expr<detail::lookahead_tag, Gram>
+ , as_lookahead<Gram>
+ >
             {};
 
             template<typename Dummy>
- struct case_<lookbehind_tag, Dummy>
- : proto::transform::arg<proto::unary_expr<lookbehind_tag, as_lookbehind<Gram> > >
+ struct case_<detail::lookbehind_tag, Dummy>
+ : when<
+ unary_expr<detail::lookbehind_tag, Gram>
+ , as_lookbehind<Gram>
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::terminal, Dummy>
- : proto::or_<
- as_matcher<CharLiteral<Char> >
- , as_matcher<proto::terminal<posix_charset_placeholder> >
- , as_matcher<proto::terminal<range_placeholder<proto::_> > >
- , as_matcher<proto::terminal<logical_newline_placeholder> >
- , as_matcher<proto::terminal<assert_word_placeholder<word_boundary<true> > > >
+ struct case_<tag::terminal, Dummy>
+ : when<
+ or_<
+ CharLiteral<Char>
+ , terminal<detail::posix_charset_placeholder>
+ , terminal<detail::range_placeholder<_> >
+ , terminal<detail::logical_newline_placeholder>
+ , terminal<detail::assert_word_placeholder<detail::word_boundary<mpl::true_> > >
+ >
+ , as_matcher
>
             {};
         };
@@ -169,102 +175,140 @@
         {
             template<typename Tag, typename Dummy = void>
             struct case_
- : proto::not_<proto::_>
+ : not_<_>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::shift_right, Dummy>
- : proto::transform::reverse_fold<proto::shift_right<Gram, Gram> >
+ struct case_<tag::terminal, Dummy>
+ : when<
+ _
+ , in_sequence<as_matcher>
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::terminal, Dummy>
- : in_sequence<as_matcher<proto::terminal<proto::_> > >
+ struct case_<tag::shift_right, Dummy>
+ : when<
+ shift_right<Gram, Gram>
+ , reverse_fold<_, _state, Gram>
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::bitwise_or, Dummy>
- : in_sequence<as_alternate<proto::bitwise_or<Gram, Gram> > >
+ struct case_<tag::bitwise_or, Dummy>
+ : when<
+ bitwise_or<Gram, Gram>
+ , in_sequence<
+ as_alternate_matcher<
+ reverse_fold_tree<_, make<fusion::nil>, in_alternate_list<Gram> >
+ >
+ >
+ >
             {};
 
- template<typename Dummy, bool Greedy>
+ template<typename Dummy, typename Greedy>
             struct case_<optional_tag<Greedy> , Dummy>
- : in_sequence<proto::transform::arg<proto::unary_expr<optional_tag<Greedy>, as_optional<Gram, Greedy> > > >
+ : when<
+ unary_expr<optional_tag<Greedy>, Gram>
+ , in_sequence<call<as_optional<Gram, Greedy>(_arg)> >
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::dereference, Dummy>
- : proto::transform::compose<as_repeat<Char, Gram, proto::tag::dereference, true>, Gram>
+ struct case_<tag::dereference, Dummy>
+ : when<
+ dereference<Gram>
+ , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::posit, Dummy>
- : proto::transform::compose<as_repeat<Char, Gram, proto::tag::posit, true>, Gram>
+ struct case_<tag::posit, Dummy>
+ : when<
+ posit<Gram>
+ , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::logical_not, Dummy>
- : proto::transform::compose<as_repeat<Char, Gram, proto::tag::logical_not, true>, Gram>
+ struct case_<tag::logical_not, Dummy>
+ : when<
+ logical_not<Gram>
+ , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
+ >
             {};
 
             template<uint_t Min, uint_t Max, typename Dummy>
- struct case_<generic_quant_tag<Min, Max> , Dummy>
- : proto::transform::compose<as_repeat<Char, Gram, generic_quant_tag<Min, Max>, true>, Gram>
+ struct case_<detail::generic_quant_tag<Min, Max>, Dummy>
+ : when<
+ unary_expr<detail::generic_quant_tag<Min, Max>, Gram>
+ , call<Gram(as_repeat<Char, Gram, mpl::true_>)>
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::negate, Dummy>
- : proto::transform::compose<
- proto::transform::arg<proto::negate<proto::switch_<NonGreedyRepeatCases<Char, Gram> > > >
- , Gram
+ struct case_<tag::negate, Dummy>
+ : when<
+ negate<switch_<NonGreedyRepeatCases<Gram> > >
+ , call<Gram(call<as_repeat<Char, Gram, mpl::false_>(_arg)>)>
>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::complement, Dummy>
- : in_sequence<as_inverse<
- proto::transform::arg<proto::complement<proto::switch_<InvertibleCases<Char, Gram> > > >
- > >
+ struct case_<tag::complement, Dummy>
+ : when<
+ complement<switch_<InvertibleCases<Char, Gram> > >
+ , in_sequence<call<as_inverse(call<switch_<InvertibleCases<Char, Gram> >(_arg)>)> >
+ >
             {};
 
             template<typename Dummy>
- struct case_<modifier_tag, Dummy>
- : as_modifier<proto::binary_expr<modifier_tag, proto::_, Gram> >
+ struct case_<detail::modifier_tag, Dummy>
+ : when<binary_expr<detail::modifier_tag, _, Gram>, as_modifier<Gram> >
             {};
 
             template<typename Dummy>
- struct case_<lookahead_tag, Dummy>
- : in_sequence<proto::transform::arg<proto::unary_expr<lookahead_tag, as_lookahead<Gram> > > >
+ struct case_<detail::lookahead_tag, Dummy>
+ : when<
+ unary_expr<detail::lookahead_tag, Gram>
+ , in_sequence<as_lookahead<Gram> >
+ >
             {};
 
             template<typename Dummy>
- struct case_<lookbehind_tag, Dummy>
- : in_sequence<proto::transform::arg<proto::unary_expr<lookbehind_tag, as_lookbehind<Gram> > > >
+ struct case_<detail::lookbehind_tag, Dummy>
+ : when<
+ unary_expr<detail::lookbehind_tag, Gram>
+ , in_sequence<as_lookbehind<Gram> >
+ >
             {};
 
             template<typename Dummy>
- struct case_<keeper_tag, Dummy>
- : in_sequence<proto::transform::arg<proto::unary_expr<keeper_tag, as_keeper<Gram> > > >
+ struct case_<detail::keeper_tag, Dummy>
+ : when<
+ unary_expr<detail::keeper_tag, Gram>
+ , in_sequence<as_keeper<Gram> >
+ >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::comma, Dummy>
- : in_sequence<as_list_set<ListSet<Char> > >
+ struct case_<tag::comma, Dummy>
+ : when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > >
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::assign, Dummy>
- : proto::or_<
- proto::transform::compose<as_marker<proto::assign<basic_mark_tag, Gram> >, Gram>
- , in_sequence<as_list_set<ListSet<Char> > >
+ struct case_<tag::assign, Dummy>
+ : or_<
+ when<assign<detail::basic_mark_tag, Gram>, call<Gram(as_marker)> >
+ , when<ListSet<Char>, in_sequence<as_list_set_matcher<Char> > >
>
             {};
 
             template<typename Dummy>
- struct case_<proto::tag::subscript, Dummy>
- : proto::or_<
- in_sequence<proto::transform::right<proto::subscript<set_initializer_type, as_set<Gram> > > >
- , proto::transform::compose<as_action<proto::subscript<ActionableGrammar<Char>, proto::_> >, ActionableGrammar<Char> >
+ struct case_<tag::subscript, Dummy>
+ : or_<
+ when<subscript<detail::set_initializer_type, Gram>, in_sequence<call<as_set_matcher<Gram>(_right)> > >
+ , when<subscript<ActionableGrammar<Char>, _>, call<ActionableGrammar<Char>(as_action)> >
>
             {};
         };
@@ -282,9 +326,9 @@
             // Only in sub-expressions with actions attached do we allow attribute assignements
             template<typename Dummy>
             struct case_<proto::tag::assign, Dummy>
- : proto::or_<
+ : or_<
                     typename Cases<Char, Gram>::template case_<proto::tag::assign>
- , in_sequence<as_attr_matcher<proto::assign<proto::terminal<attribute_placeholder<proto::_> >, proto::_> > >
+ , when<proto::assign<terminal<detail::attribute_placeholder<_> >, _>, in_sequence<as_attr_matcher> >
>
             {};
         };
@@ -295,12 +339,12 @@
     // Grammar
     template<typename Char>
     struct Grammar
- : proto::switch_<detail::Cases<Char, Grammar<Char> > >
+ : proto::switch_<grammar_detail::Cases<Char, Grammar<Char> > >
     {};
 
     template<typename Char>
     struct ActionableGrammar
- : proto::switch_<detail::ActionableCases<Char, ActionableGrammar<Char> > >
+ : proto::switch_<grammar_detail::ActionableCases<Char, ActionableGrammar<Char> > >
     {};
 
     ///////////////////////////////////////////////////////////////////////////

Modified: branches/release/boost/xpressive/detail/static/is_pure.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/is_pure.hpp (original)
+++ branches/release/boost/xpressive/detail/static/is_pure.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // is_pure.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -105,7 +105,7 @@
     // either (s1 = ...) or (a1 = ...) or (set = ...)
     template<typename Expr, typename Char>
     struct use_simple_repeat_<Expr, Char, proto::tag::assign>
- : use_simple_repeat_assign<typename proto::result_of::arg<typename Expr::proto_arg0>::type>
+ : use_simple_repeat_assign<typename proto::result_of::arg<typename Expr::proto_arg0::proto_base_expr>::type>
     {};
 
     template<typename Expr, typename Char>
@@ -199,6 +199,14 @@
         BOOST_MPL_ASSERT_RELATION(0, !=, (width_of<Expr, Char>::value));
     };
 
+ template<typename Expr, typename Char>
+ struct use_simple_repeat<Expr &, Char>
+ : use_simple_repeat_<Expr, Char>
+ {
+ // should never try to repeat something of 0-width
+ BOOST_MPL_ASSERT_RELATION(0, !=, (width_of<Expr, Char>::value));
+ };
+
 }}} // namespace boost::xpressive::detail
 
 #endif

Modified: branches/release/boost/xpressive/detail/static/modifier.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/modifier.hpp (original)
+++ branches/release/boost/xpressive/detail/static/modifier.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // modifier.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/static/placeholders.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/placeholders.hpp (original)
+++ branches/release/boost/xpressive/detail/static/placeholders.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // placeholders.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/static/static.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/static.hpp (original)
+++ branches/release/boost/xpressive/detail/static/static.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // static.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/static/transforms/as_action.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_action.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_action.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,8 +1,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_action.hpp
 //
-// Copyright 2007 Eric Niebler.
-// Copyright 2007 David Jenkins.
+// Copyright 2008 Eric Niebler.
+// Copyright 2008 David Jenkins.
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -24,89 +24,96 @@
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/detail/static/transforms/as_quantifier.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
     ///////////////////////////////////////////////////////////////////////////////
+ // read_attr
+ // Placeholder that knows the slot number of an attribute as well as the type
+ // of the object stored in it.
+ template<typename Nbr, typename Matcher>
+ struct read_attr
+ {
+ typedef Nbr nbr_type;
+ typedef Matcher matcher_type;
+ };
+
+}}}
+
+namespace boost { namespace xpressive { namespace grammar_detail
+{
+ ///////////////////////////////////////////////////////////////////////////////
     // FindAttr
     // Look for patterns like (a1= terminal<RHS>) and return the type of the RHS.
     template<typename Nbr>
     struct FindAttr
- : proto::or_<
- proto::transform::state< proto::terminal<proto::_> >
- // Ignore nested actions, because attributes are scoped:
- , proto::transform::state< proto::subscript<proto::_, proto::_> >
- , proto::transform::arg<
- proto::transform::right<
- proto::assign<
- proto::terminal<xpressive::detail::attribute_placeholder<Nbr> >
- , proto::_
- >
- >
- >
- , proto::transform::fold<proto::nary_expr<proto::_, proto::vararg<FindAttr<Nbr> > > >
+ : or_<
+ // Ignore nested actions, because attributes are scoped
+ when< subscript<_, _>, _state >
+ , when< terminal<_>, _state >
+ , when< proto::assign<terminal<detail::attribute_placeholder<Nbr> >, _>, call<_arg(_right)> >
+ , otherwise< fold<_, _state, FindAttr<Nbr> > >
>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
- // by_value
- // Store all terminals within an action by value to avoid dangling references.
- template<typename Terminal>
- struct by_value
- : Terminal
+ // as_read_attr
+ // For patterns like (a1 = RHS)[ref(i) = a1], transform to
+ // (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
+ // we know what type is stored in the attribute slot.
+ struct as_read_attr : proto::callable
     {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::as_expr<typename proto::result_of::arg<Expr>::type>
- {};
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename proto::result_of::as_expr<
+ detail::read_attr<
+ typename Expr::proto_arg0::nbr_type
+ , typename FindAttr<typename Expr::proto_arg0::nbr_type>::template result<void(
+ State
+ , mpl::void_
+ , int
+ )>::type
+ >
+ >::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &, State const &, Visitor &) const
         {
- return proto::as_expr(proto::arg(expr));
+ typename result<void(Expr, State, Visitor)>::type that = {{}};
+ return that;
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
- // read_attr
- // Placeholder that knows the slot number of an attribute as well as the type
- // of the object stored in it.
- template<typename Nbr, typename Matcher>
- struct read_attr
+ // by_value
+ // Store all terminals within an action by value to avoid dangling references.
+ struct by_value : proto::callable
     {
- typedef Nbr nbr_type;
- typedef Matcher matcher_type;
- };
+ template<typename Sig> struct result {};
 
- ///////////////////////////////////////////////////////////////////////////////
- // as_read_attr
- // For patterns like (a1 = RHS)[ref(i) = a1], transform to
- // (a1 = RHS)[ref(i) = read_attr<1, RHS>] so that when reading the attribute
- // we know what type is stored in the attribute slot.
- template<typename Grammar>
- struct as_read_attr
- : Grammar
- {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::as_expr<
- read_attr<
- typename Expr::proto_arg0::nbr_type
- , typename FindAttr<typename Expr::proto_arg0::nbr_type>
- ::template apply<State, mpl::void_, int>::type
- >
- >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename proto::result_of::as_expr<
+ typename proto::result_of::arg<Expr>::type
+ >::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &, State const &, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &) const
         {
- typename apply<Expr, State, Visitor>::type that = {{}};
- return that;
+ return proto::as_expr(proto::arg(expr));
         }
     };
 
@@ -115,78 +122,80 @@
     // Turn all refs into values, and also bind all attribute placeholders with
     // the types from which they are being assigned.
     struct DeepCopy
- : proto::or_<
- as_read_attr<proto::terminal<xpressive::detail::attribute_placeholder<proto::_> > >
- , by_value<proto::terminal<proto::_> >
- , proto::nary_expr<proto::_, proto::vararg<DeepCopy> >
+ : or_<
+ when< terminal<detail::attribute_placeholder<_> >, as_read_attr>
+ , when< terminal<_>, by_value >
+ , otherwise< nary_expr<_, vararg<DeepCopy> > >
>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
- // max_attr
- // Take the maximum of the current attr slot number and the state.
- template<typename Grammar>
- struct max_attr
- : Grammar
- {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : mpl::max<State, typename Grammar::template apply<Expr, State, Visitor>::type>
- {};
- };
-
- ///////////////////////////////////////////////////////////////////////////////
     // attr_nbr
     // For an attribute placeholder, return the attribute's slot number.
- template<typename Grammar>
- struct attr_nbr
- : Grammar
+ struct attr_nbr : proto::callable
     {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : Expr::proto_arg0::nbr_type
- {};
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename Expr::proto_arg0::nbr_type::type type;
+ };
     };
 
+ struct max_attr;
+
     ///////////////////////////////////////////////////////////////////////////////
     // MaxAttr
     // In an action (rx)[act], find the largest attribute slot being used.
     struct MaxAttr
- : proto::or_<
- attr_nbr< proto::terminal< xpressive::detail::attribute_placeholder<proto::_> > >
- , proto::transform::state< proto::terminal<proto::_> >
+ : or_<
+ when< terminal<detail::attribute_placeholder<_> >, attr_nbr>
+ , when< terminal<_>, make<mpl::int_<0> > >
             // Ignore nested actions, because attributes are scoped:
- , proto::transform::state< proto::subscript<proto::_, proto::_> >
- , proto::transform::fold<proto::nary_expr<proto::_, max_attr<proto::vararg<MaxAttr> > > >
+ , when< subscript<_, _>, make<mpl::int_<0> > >
+ , otherwise< fold<_, make<mpl::int_<0> >, max_attr> >
>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
+ // max_attr
+ // Take the maximum of the current attr slot number and the state.
+ struct max_attr : proto::callable
+ {
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename mpl::max<State, typename MaxAttr::template result<void(Expr, State, Visitor)>::type >::type type;
+ };
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////
     // as_attr_matcher
     // turn a1=matcher into attr_matcher<Matcher>(1)
- template<typename Grammar>
- struct as_attr_matcher
- : Grammar
+ struct as_attr_matcher : proto::callable
     {
- as_attr_matcher();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
             typedef
- attr_matcher<
+ detail::attr_matcher<
                     typename proto::result_of::arg<typename Expr::proto_arg1>::type
                   , typename Visitor::traits_type
- , Visitor::icase_type::value
+ , typename Visitor::icase_type
>
             type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- return typename apply<Expr, State, Visitor>::type(
+ return typename result<void(Expr, State, Visitor)>::type(
                 Expr::proto_arg0::proto_base_expr::proto_arg0::nbr_type::value
               , proto::arg(proto::right(expr))
               , visitor.traits()
@@ -197,32 +206,33 @@
     ///////////////////////////////////////////////////////////////////////////////
     // add_attrs
     // Wrap an expression in attr_begin_matcher/attr_end_matcher pair
- template<typename Grammar>
- struct add_attrs
- : Grammar
+ struct add_attrs : proto::callable
     {
- add_attrs();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename, typename>
- struct apply
- : proto::shift_right<
- typename proto::terminal<
- attr_begin_matcher<typename MaxAttr::apply<Expr, mpl::int_<0>, int>::type>
- >::type
- , typename proto::shift_right<
- Expr
- , proto::terminal<attr_end_matcher>::type
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename shift_right<
+ typename terminal<
+ detail::attr_begin_matcher<typename MaxAttr::template result<void(Expr, mpl::int_<0>, int)>::type >
+ >::type
+ , typename shift_right<
+ Expr
+ , terminal<detail::attr_end_matcher>::type
+ >::type
>::type
- >
- {};
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &) const
         {
- attr_begin_matcher<typename MaxAttr::apply<Expr, mpl::int_<0>, int>::type> begin;
- attr_end_matcher end;
- typename apply<Expr, State, Visitor>::type that = {{begin}, {expr, {end}}};
+ detail::attr_begin_matcher<typename MaxAttr::template result<void(Expr, mpl::int_<0>, int)>::type > begin;
+ detail::attr_end_matcher end;
+ typename result<void(Expr, State, Visitor)>::type that = {{begin}, {expr, {end}}};
             return that;
         }
     };
@@ -230,19 +240,13 @@
     ///////////////////////////////////////////////////////////////////////////////
     // InsertAttrs
     struct InsertAttrs
- : proto::or_<
- add_attrs<proto::if_<mpl::apply_wrap3<MaxAttr, mpl::_, mpl::int_<0>, int> > >
- , proto::_
- >
+ : if_<MaxAttr, add_attrs, _>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // CheckAssertion
     struct CheckAssertion
- : proto::function<
- proto::terminal<check_tag>
- , proto::_
- >
+ : proto::function<terminal<detail::check_tag>, _>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -251,28 +255,26 @@
     // If A and B use attributes, wrap the above expression in
     // a attr_begin_matcher<Count> / attr_end_matcher pair, where Count is
     // the number of attribute slots used by the pattern/action.
- template<typename Grammar>
- struct as_action
- : Grammar
+ struct as_action : proto::callable
     {
- as_action();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
             typedef typename proto::result_of::left<Expr>::type expr_type;
             typedef typename proto::result_of::right<Expr>::type action_type;
- typedef typename DeepCopy::apply<action_type, expr_type, int>::type action_copy_type;
+ typedef typename DeepCopy::template result<void(action_type, expr_type, int)>::type action_copy_type;
 
             typedef
- typename InsertMark::apply<expr_type, State, Visitor>::type
+ typename InsertMark::template result<void(expr_type, State, Visitor)>::type
             marked_expr_type;
 
             typedef
                 typename mpl::if_<
                     proto::matches<action_type, CheckAssertion>
- , predicate_matcher<action_copy_type>
- , action_matcher<action_copy_type>
+ , detail::predicate_matcher<action_copy_type>
+ , detail::action_matcher<action_copy_type>
>::type
             matcher_type;
 
@@ -284,20 +286,20 @@
             no_attr_type;
 
             typedef
- typename InsertAttrs::apply<no_attr_type, State, Visitor>::type
+ typename InsertAttrs::template result<void(no_attr_type, State, Visitor)>::type
             type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
         {
- typedef apply<Expr, State, Visitor> apply_type;
+ typedef result<void(Expr, State, Visitor)> apply_type;
             typedef typename apply_type::matcher_type matcher_type;
 
             int dummy = 0;
             typename apply_type::marked_expr_type marked_expr =
- InsertMark::call(proto::left(expr), state, visitor);
+ InsertMark()(proto::left(expr), state, visitor);
 
             typename apply_type::no_attr_type that =
             {
@@ -305,13 +307,13 @@
               , {
                     matcher_type
                     (
- DeepCopy::call(proto::right(expr), proto::left(expr), dummy)
+ DeepCopy()(proto::right(expr), proto::left(expr), dummy)
                       , proto::arg(proto::left(marked_expr)).mark_number_
                     )
                 }
             };
 
- return InsertAttrs::call(that, state, visitor);
+ return InsertAttrs()(that, state, visitor);
         }
     };
 

Modified: branches/release/boost/xpressive/detail/static/transforms/as_alternate.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_alternate.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_alternate.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_alternate.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -16,124 +16,104 @@
 #include <boost/config.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/type_traits/is_same.hpp>
-#include <boost/xpressive/proto/traits.hpp>
-#include <boost/xpressive/proto/matches.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
-#include <boost/xpressive/proto/transform/branch.hpp>
-#include <boost/xpressive/proto/transform/fold_tree.hpp>
+#include <boost/xpressive/proto/proto.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/detail/core/matcher/alternate_matcher.hpp>
 #include <boost/xpressive/detail/utility/cons.hpp>
 
-namespace boost { namespace xpressive { namespace detail
+namespace boost { namespace xpressive
 {
-
- ///////////////////////////////////////////////////////////////////////////////
- // alternates_list
- // a fusion-compatible sequence of alternate expressions, that also keeps
- // track of the list's width and purity.
- template<typename Head, typename Tail>
- struct alternates_list
- : fusion::cons<Head, Tail>
- {
- BOOST_STATIC_CONSTANT(std::size_t, width = Head::width == Tail::width ? Head::width : unknown_width::value);
- BOOST_STATIC_CONSTANT(bool, pure = Head::pure && Tail::pure);
-
- alternates_list(Head const &head, Tail const &tail)
- : fusion::cons<Head, Tail>(head, tail)
- {
- }
- };
-
- template<typename Head>
- struct alternates_list<Head, fusion::nil>
- : fusion::cons<Head, fusion::nil>
- {
- BOOST_STATIC_CONSTANT(std::size_t, width = Head::width);
- BOOST_STATIC_CONSTANT(bool, pure = Head::pure);
-
- alternates_list(Head const &head, fusion::nil const &tail)
- : fusion::cons<Head, fusion::nil>(head, tail)
- {
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- // in_alternate
- template<typename Grammar>
- struct in_alternate
- : Grammar
+ namespace detail
     {
- in_alternate();
+ ///////////////////////////////////////////////////////////////////////////////
+ // alternates_list
+ // a fusion-compatible sequence of alternate expressions, that also keeps
+ // track of the list's width and purity.
+ template<typename Head, typename Tail>
+ struct alternates_list
+ : fusion::cons<Head, Tail>
+ {
+ BOOST_STATIC_CONSTANT(std::size_t, width = Head::width == Tail::width ? Head::width : detail::unknown_width::value);
+ BOOST_STATIC_CONSTANT(bool, pure = Head::pure && Tail::pure);
+
+ alternates_list(Head const &head, Tail const &tail)
+ : fusion::cons<Head, Tail>(head, tail)
+ {
+ }
+ };
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef alternates_list<
- typename Grammar::template apply<Expr, alternate_end_xpression, Visitor>::type
- , State
- > type;
+ template<typename Head>
+ struct alternates_list<Head, fusion::nil>
+ : fusion::cons<Head, fusion::nil>
+ {
+ BOOST_STATIC_CONSTANT(std::size_t, width = Head::width);
+ BOOST_STATIC_CONSTANT(bool, pure = Head::pure);
+
+ alternates_list(Head const &head, fusion::nil const &tail)
+ : fusion::cons<Head, fusion::nil>(head, tail)
+ {
+ }
         };
+ }
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, alternate_end_xpression(), visitor)
- , state
- );
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- // as_alternate_matcher
- template<typename Grammar>
- struct as_alternate_matcher
- : Grammar
+ namespace grammar_detail
     {
- as_alternate_matcher();
+ ///////////////////////////////////////////////////////////////////////////////
+ // in_alternate_list
+ template<typename Grammar>
+ struct in_alternate_list : proto::callable
+ {
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef detail::alternates_list<
+ typename Grammar::template result<void(Expr, detail::alternate_end_xpression, Visitor)>::type
+ , State
+ > type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return typename result<void(Expr, State, Visitor)>::type(
+ Grammar()(expr, detail::alternate_end_xpression(), visitor)
+ , state
+ );
+ }
+ };
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef alternate_matcher<
- typename Grammar::template apply<Expr, State, Visitor>::type
- , typename Visitor::traits_type
- > type;
+ ///////////////////////////////////////////////////////////////////////////////
+ // as_alternate_matcher
+ template<typename Grammar>
+ struct as_alternate_matcher : proto::callable
+ {
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef detail::alternate_matcher<
+ typename Grammar::template result<void(Expr, State, Visitor)>::type
+ , typename Visitor::traits_type
+ > type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return typename result<void(Expr, State, Visitor)>::type(
+ Grammar()(expr, state, visitor)
+ );
+ }
         };
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, state, visitor)
- );
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- // as_alternate
- template<typename Grammar>
- struct as_alternate
- : as_alternate_matcher<
- proto::transform::reverse_fold_tree<
- typename Grammar::proto_tag
- , in_alternate<typename Grammar::proto_arg0>
- , fusion::nil
- >
- >
- {
- BOOST_MPL_ASSERT((
- is_same<
- typename Grammar::proto_arg0
- , typename Grammar::proto_arg1
- >
- ));
- };
+ }
 
-}}}
+}}
 
 #endif

Modified: branches/release/boost/xpressive/detail/static/transforms/as_independent.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_independent.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_independent.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_independent.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -17,7 +17,7 @@
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -29,77 +29,170 @@
 
     struct lookbehind_tag
     {};
+}}}
+
+namespace boost { namespace xpressive { namespace grammar_detail
+{
+ // A grammar that only accepts static regexes that
+ // don't have semantic actions.
+ struct NotHasAction
+ : proto::switch_<struct NotHasActionCases>
+ {};
+
+ struct NotHasActionCases
+ {
+ template<typename Tag, int Dummy = 0>
+ struct case_
+ : proto::nary_expr<Tag, proto::vararg<NotHasAction> >
+ {};
+
+ template<int Dummy>
+ struct case_<proto::tag::terminal, Dummy>
+ : not_< or_<
+ proto::terminal<detail::tracking_ptr<detail::regex_impl<_> > >,
+ proto::terminal<reference_wrapper<_> >
+ > >
+ {};
+
+ template<int Dummy>
+ struct case_<proto::tag::comma, Dummy>
+ : proto::_ // because (set='a','b') can't contain an action
+ {};
+
+ template<int Dummy>
+ struct case_<proto::tag::complement, Dummy>
+ : proto::_ // because in ~X, X can't contain an unscoped action
+ {};
+
+ template<int Dummy>
+ struct case_<detail::lookahead_tag, Dummy>
+ : proto::_ // because actions in lookaheads are scoped
+ {};
+
+ template<int Dummy>
+ struct case_<detail::lookbehind_tag, Dummy>
+ : proto::_ // because actions in lookbehinds are scoped
+ {};
+
+ template<int Dummy>
+ struct case_<detail::keeper_tag, Dummy>
+ : proto::_ // because actions in keepers are scoped
+ {};
+
+ template<int Dummy>
+ struct case_<proto::tag::subscript, Dummy>
+ : proto::subscript<detail::set_initializer_type, _>
+ {}; // only accept set[...], not actions!
+ };
+
+ struct IndependentEndXpression
+ : or_<
+ when<NotHasAction, detail::true_xpression()>
+ , otherwise<detail::independent_end_xpression()>
+ >
+ {};
 
     template<typename Grammar>
- struct as_lookahead
- : Grammar
+ struct as_lookahead : proto::callable
     {
- as_lookahead();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef lookahead_matcher<
- typename Grammar::template apply<Expr, true_xpression, Visitor>::type
- > type;
+ typedef typename proto::result_of::arg<Expr>::type arg_type;
+
+ typedef
+ typename Grammar::template result<void(
+ arg_type
+ , typename IndependentEndXpression::result<void(arg_type, int, int)>::type
+ , Visitor
+ )>::type
+ xpr_type;
+ typedef detail::lookahead_matcher<xpr_type> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, true_xpression(), visitor)
+ typedef result<void(Expr, State, Visitor)> result_type;
+ int i = 0;
+ return typename result_type::type(
+ Grammar()(
+ proto::arg(expr)
+ , IndependentEndXpression()(proto::arg(expr), i, i)
+ , visitor
+ )
               , false
             );
         }
     };
 
     template<typename Grammar>
- struct as_lookbehind
- : Grammar
+ struct as_lookbehind : proto::callable
     {
- as_lookbehind();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef lookbehind_matcher<
- typename Grammar::template apply<Expr, true_xpression, Visitor>::type
- > type;
+ typedef typename proto::result_of::arg<Expr>::type arg_type;
+ typedef
+ typename Grammar::template result<void(
+ arg_type
+ , typename IndependentEndXpression::result<void(arg_type, int, int)>::type
+ , Visitor
+ )>::type
+ xpr_type;
+ typedef detail::lookbehind_matcher<xpr_type> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- typename Grammar::template apply<Expr, true_xpression, Visitor>::type const &
- expr2 = Grammar::call(expr, true_xpression(), visitor);
+ typedef typename result<void(Expr, State, Visitor)>::xpr_type xpr_type;
+ int i = 0;
+ xpr_type const &expr2 = Grammar()(
+ proto::arg(expr)
+ , IndependentEndXpression()(proto::arg(expr), i, i)
+ , visitor
+ );
             std::size_t width = expr2.get_width().value();
- return typename apply<Expr, State, Visitor>::type(expr2, width, false);
+ return detail::lookbehind_matcher<xpr_type>(expr2, width, false);
         }
     };
 
     template<typename Grammar>
- struct as_keeper
- : Grammar
+ struct as_keeper : proto::callable
     {
- as_keeper();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef keeper_matcher<
- typename Grammar::template apply<Expr, true_xpression, Visitor>::type
+ typedef typename proto::result_of::arg<Expr>::type arg_type;
+ typedef detail::keeper_matcher<
+ typename Grammar::template result<void(
+ arg_type
+ , typename IndependentEndXpression::result<void(arg_type, int, int)>::type
+ , Visitor
+ )>::type
> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, true_xpression(), visitor)
+ int i = 0;
+ return typename result<void(Expr, State, Visitor)>::type(
+ Grammar()(
+ proto::arg(expr)
+ , IndependentEndXpression()(proto::arg(expr), i, i)
+ , visitor
+ )
             );
         }
     };

Modified: branches/release/boost/xpressive/detail/static/transforms/as_inverse.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_inverse.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_inverse.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_inverse.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -14,11 +14,16 @@
 #endif
 
 #include <boost/mpl/sizeof.hpp>
+#include <boost/mpl/not.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/proto/proto.hpp>
 
-namespace boost { namespace xpressive { namespace detail
+#define UNCV(x) typename remove_const<x>::type
+#define UNREF(x) typename remove_reference<x>::type
+#define UNCVREF(x) UNCV(UNREF(x))
+
+namespace boost { namespace xpressive { namespace grammar_detail
 {
 
     template<typename T>
@@ -32,62 +37,58 @@
         }
     };
 
- template<typename Traits, bool ICase, bool Not>
- struct inverter<literal_matcher<Traits, ICase, Not> >
+ template<typename Traits, typename ICase, typename Not>
+ struct inverter<detail::literal_matcher<Traits, ICase, Not> >
     {
- typedef literal_matcher<Traits, ICase, !Not> type;
- static type call(literal_matcher<Traits, ICase, Not> t)
+ typedef detail::literal_matcher<Traits, ICase, typename mpl::not_<Not>::type> type;
+ static type call(detail::literal_matcher<Traits, ICase, Not> t)
         {
- return type(t);
+ return type(t.ch_);
         }
     };
 
     template<typename Traits>
- struct inverter<logical_newline_matcher<Traits> >
+ struct inverter<detail::logical_newline_matcher<Traits> >
     {
         // ~_ln matches any one character that is not in the "newline" character class
- typedef posix_charset_matcher<Traits> type;
- static type call(logical_newline_matcher<Traits> t)
+ typedef detail::posix_charset_matcher<Traits> type;
+ static type call(detail::logical_newline_matcher<Traits> t)
         {
             return type(t.newline(), true);
         }
     };
 
     template<typename Traits>
- struct inverter<assert_word_matcher<word_boundary<true>, Traits> >
+ struct inverter<detail::assert_word_matcher<detail::word_boundary<mpl::true_>, Traits> >
     {
- typedef assert_word_matcher<word_boundary<false>, Traits> type;
- static type call(assert_word_matcher<word_boundary<true>, Traits> t)
+ typedef detail::assert_word_matcher<detail::word_boundary<mpl::false_>, Traits> type;
+ static type call(detail::assert_word_matcher<detail::word_boundary<mpl::true_>, Traits> t)
         {
             return type(t.word());
         }
     };
 
- template<typename T>
- typename inverter<T>::type invert(T const &t)
+ struct as_inverse : proto::callable
     {
- return inverter<T>::call(t);
- }
+ template<typename Sig>
+ struct result;
 
- template<typename Grammar>
- struct as_inverse
- : Grammar
- {
- as_inverse();
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : inverter<typename Grammar::template apply<Expr, State, Visitor>::type>
+ template<typename This, typename Matcher>
+ struct result<This(Matcher)>
+ : inverter<UNCVREF(Matcher)>
         {};
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ template<typename Matcher>
+ typename inverter<Matcher>::type operator ()(Matcher const &matcher) const
         {
- return detail::invert(Grammar::call(expr, state, visitor));
+ return inverter<Matcher>::call(matcher);
         }
     };
 
 }}}
 
+#undef UNCV
+#undef UNREF
+#undef UNCVREF
+
 #endif

Modified: branches/release/boost/xpressive/detail/static/transforms/as_marker.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_marker.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_marker.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_marker.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -17,67 +17,40 @@
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/proto/proto.hpp>
 
-//#include <boost/xpressive/proto/transform/construct.hpp>
-
-namespace boost { namespace xpressive { namespace detail
+namespace boost { namespace xpressive { namespace grammar_detail
 {
 
- //template<typename Grammar>
- //struct as_marker
- // : proto::transform::construct<
- // proto::transform::identity<Grammar>
- // , proto::shift_right<
- // proto::terminal<mark_begin_matcher>::type
- // , proto::shift_right<
- // proto::transform::right<proto::_>
- // , proto::terminal<mark_end_matcher>::type
- // >
- // >(
- // proto::terminal<mark_begin_matcher>::type(
- // mark_begin_matcher(proto::transform::arg<proto::transform::left<proto::_> > )
- // )
- // , proto::shift_right<
- // proto::transform::right<proto::_>
- // , proto::terminal<mark_end_matcher>::type
- // >(
- // proto::transform::right<proto::_>
- // , proto::terminal<mark_end_matcher>::type(
- // mark_end_matcher(proto::transform::arg<proto::transform::left<proto::_> > )
- // )
- // )
- // )
- // >
- //{};
-
     ///////////////////////////////////////////////////////////////////////////////
     // as_marker
     // Insert mark tags before and after the expression
- template<typename Grammar>
- struct as_marker
- : Grammar
+ struct as_marker : proto::callable
     {
- as_marker();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename, typename>
- struct apply
- : proto::shift_right<
- proto::terminal<mark_begin_matcher>::type
- , typename proto::shift_right<
- typename proto::result_of::right<Expr>::type
- , proto::terminal<mark_end_matcher>::type
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename shift_right<
+ terminal<detail::mark_begin_matcher>::type
+ , typename shift_right<
+ typename proto::result_of::right<Expr>::type
+ , terminal<detail::mark_end_matcher>::type
+ >::type
>::type
- >
- {};
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &) const
         {
- int mark_nbr = get_mark_number(proto::left(expr));
- mark_begin_matcher begin(mark_nbr);
- mark_end_matcher end(mark_nbr);
+ int mark_nbr = detail::get_mark_number(proto::left(expr));
+ detail::mark_begin_matcher begin(mark_nbr);
+ detail::mark_end_matcher end(mark_nbr);
 
- typename apply<Expr, State, Visitor>::type that = {{begin}, {proto::right(expr), {end}}};
+ typename result<void(Expr, State, Visitor)>::type that
+ = {{begin}, {proto::right(expr), {end}}};
             return that;
         }
     };

Modified: branches/release/boost/xpressive/detail/static/transforms/as_matcher.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_matcher.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_matcher.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_matcher.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -14,29 +14,28 @@
 #endif
 
 #include <boost/mpl/assert.hpp>
-#include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 
-namespace boost { namespace xpressive { namespace detail
+namespace boost { namespace xpressive { namespace grammar_detail
 {
-
- template<typename Grammar>
- struct as_matcher
- : Grammar
+ struct as_matcher : proto::callable
     {
- as_matcher();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : Visitor::template apply<
- typename proto::result_of::arg<Expr>::type
- >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename Visitor::template apply<
+ typename proto::result_of::arg<Expr>::type
+ >::type
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
             return visitor.call(proto::arg(expr));
         }

Modified: branches/release/boost/xpressive/detail/static/transforms/as_modifier.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_modifier.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_modifier.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_modifier.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -17,57 +17,53 @@
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
+
+#define UNCV(x) typename remove_const<x>::type
+#define UNREF(x) typename remove_reference<x>::type
+#define UNCVREF(x) UNCV(UNREF(x))
 
 namespace boost { namespace xpressive { namespace detail
 {
-
     ///////////////////////////////////////////////////////////////////////////////
     // regex operator tags
     struct modifier_tag
- {
- };
+ {};
 
- ///////////////////////////////////////////////////////////////////////////////
- // scoped_swap
- // for swapping state back after proto::compile returns
- template<typename Old, typename New>
- struct scoped_swap
- {
- ~scoped_swap() { this->old_->swap(*this->new_); }
- Old *old_;
- New *new_;
- };
+}}}
+
+namespace boost { namespace xpressive { namespace grammar_detail
+{
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_modifier
     template<typename Grammar>
- struct as_modifier
- : Grammar
+ struct as_modifier : proto::callable
     {
- as_modifier();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
             typedef typename proto::result_of::arg<typename proto::result_of::left<Expr>::type>::type modifier_type;
             typedef typename modifier_type::BOOST_NESTED_TEMPLATE apply<Visitor>::type visitor_type;
- typedef typename proto::transform::right<Grammar>::template apply<Expr, State, visitor_type>::type type;
+ typedef typename Grammar::template result<void(typename proto::result_of::right<Expr>::type, State, visitor_type)>::type type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
         {
- typedef typename apply<Expr, State, Visitor>::visitor_type new_visitor_type;
+ typedef result<void(Expr, State, Visitor)> result_;
+ typedef typename result_::visitor_type new_visitor_type;
             new_visitor_type new_visitor(proto::arg(proto::left(expr)).call(visitor));
- new_visitor.swap(visitor);
- scoped_swap<Visitor, new_visitor_type> const undo = {&visitor, &new_visitor};
- detail::ignore_unused(undo);
- return proto::transform::right<Grammar>::call(expr, state, new_visitor);
+ return Grammar()(proto::right(expr), state, new_visitor);
         }
     };
 
 }}}
 
+#undef UNCV
+#undef UNREF
+#undef UNCVREF
+
 #endif

Modified: branches/release/boost/xpressive/detail/static/transforms/as_quantifier.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_quantifier.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_quantifier.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_quantifier.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -17,12 +17,10 @@
 #include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/compose.hpp>
+#include <boost/xpressive/proto/proto.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
-
     ///////////////////////////////////////////////////////////////////////////////
     // generic_quant_tag
     template<uint_t Min, uint_t Max>
@@ -31,6 +29,11 @@
         typedef mpl::integral_c<uint_t, Min> min_type;
         typedef mpl::integral_c<uint_t, Max> max_type;
     };
+}}}
+
+namespace boost { namespace xpressive { namespace grammar_detail
+{
+ using detail::uint_t;
 
     ///////////////////////////////////////////////////////////////////////////////
     // min_type / max_type
@@ -60,67 +63,67 @@
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_simple_quantifier
- template<typename Grammar, bool Greedy>
- struct as_simple_quantifier
- : Grammar
+ template<typename Grammar, typename Greedy>
+ struct as_simple_quantifier : proto::callable
     {
- typedef proto::transform::arg<Grammar> grammar_type;
- as_simple_quantifier();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef typename grammar_type::template apply<Expr, true_xpression, Visitor>::type xpr_type;
- typedef simple_repeat_matcher<xpr_type, Greedy> matcher_type;
+ typedef typename proto::result_of::arg<Expr>::type arg_type;
+ typedef typename Grammar::template result<void(arg_type, detail::true_xpression, Visitor)>::type xpr_type;
+ typedef detail::simple_repeat_matcher<xpr_type, Greedy> matcher_type;
             typedef typename proto::terminal<matcher_type>::type type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- typename apply<Expr, State, Visitor>::xpr_type const &xpr =
- grammar_type::call(expr, true_xpression(), visitor);
- return apply<Expr, State, Visitor>::type::make(
- typename apply<Expr, State, Visitor>::matcher_type(
- xpr
- , min_type<typename Expr::proto_tag>::value
- , max_type<typename Expr::proto_tag>::value
- , xpr.get_width().value()
- )
- );
+ typedef result<void(Expr, State, Visitor)> result_;
+ typedef typename result_::arg_type arg_type;
+ typedef typename result_::xpr_type xpr_type;
+ typedef typename result_::matcher_type matcher_type;
+ typedef typename Expr::proto_tag tag;
+
+ xpr_type const &xpr = Grammar()(proto::arg(expr), detail::true_xpression(), visitor);
+ matcher_type matcher(xpr, (uint_t)min_type<tag>(), (uint_t)max_type<tag>(), xpr.get_width().value());
+ return proto::terminal<matcher_type>::type::make(matcher);
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // add_hidden_mark
- template<typename Grammar>
- struct add_hidden_mark
- : Grammar
+ struct add_hidden_mark : proto::callable
     {
- add_hidden_mark();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename, typename>
- struct apply
- : proto::shift_right<
- proto::terminal<mark_begin_matcher>::type
- , typename proto::shift_right<
- Expr
- , proto::terminal<mark_end_matcher>::type
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename shift_right<
+ terminal<detail::mark_begin_matcher>::type
+ , typename shift_right<
+ Expr
+ , terminal<detail::mark_end_matcher>::type
+ >::type
>::type
- >
- {};
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
             // we're inserting a hidden mark ... so grab the next hidden mark number.
             int mark_nbr = visitor.get_hidden_mark();
- mark_begin_matcher begin(mark_nbr);
- mark_end_matcher end(mark_nbr);
+ detail::mark_begin_matcher begin(mark_nbr);
+ detail::mark_end_matcher end(mark_nbr);
 
- typename apply<Expr, State, Visitor>::type that = {{begin}, {expr, {end}}};
+ typename result<void(Expr, State, Visitor)>::type that
+ = {{begin}, {expr, {end}}};
             return that;
         }
     };
@@ -128,109 +131,116 @@
     ///////////////////////////////////////////////////////////////////////////////
     // InsertMark
     struct InsertMark
- : proto::or_<
- proto::assign<basic_mark_tag, proto::_>
- , add_hidden_mark<proto::_>
+ : or_<
+ when<proto::assign<detail::basic_mark_tag, _>, _>
+ , otherwise<add_hidden_mark>
>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_quantifier_impl
- template<bool Greedy, uint_t Min, uint_t Max>
- struct as_default_quantifier_impl
+ template<typename Greedy, uint_t Min, uint_t Max>
+ struct as_default_quantifier_impl : proto::callable
     {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::shift_right<
- proto::terminal<repeat_begin_matcher>::type
- , typename proto::shift_right<
- typename InsertMark::apply<typename proto::result_of::arg<Expr>::type, State, Visitor>::type
- , typename proto::terminal<repeat_end_matcher<Greedy> >::type
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename InsertMark::template result<void(typename proto::result_of::arg<Expr>::type, State, Visitor)>::type
+ marked_sub_type;
+
+ typedef
+ typename shift_right<
+ terminal<detail::repeat_begin_matcher>::type
+ , typename shift_right<
+ marked_sub_type
+ , typename terminal<detail::repeat_end_matcher<Greedy> >::type
+ >::type
>::type
- >
- {};
+ type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
         {
             // Ensure this sub-expression is book-ended with mark matchers
- typedef typename proto::result_of::arg<Expr>::type arg_type;
- typename InsertMark::apply<arg_type, State, Visitor>::type const &
- marked_sub = InsertMark::call(proto::arg(expr), state, visitor);
+ typename result<void(Expr, State, Visitor)>::marked_sub_type const &
+ marked_sub = InsertMark()(proto::arg(expr), state, visitor);
 
             // Get the mark_number from the begin_mark_matcher
             int mark_number = proto::arg(proto::left(marked_sub)).mark_number_;
             BOOST_ASSERT(0 != mark_number);
 
- unsigned min_ = min_type<typename Expr::proto_tag>::value;
- unsigned max_ = max_type<typename Expr::proto_tag>::value;
+ uint_t min_ = (uint_t)min_type<typename Expr::proto_tag>();
+ uint_t max_ = (uint_t)max_type<typename Expr::proto_tag>();
 
- repeat_begin_matcher begin(mark_number);
- repeat_end_matcher<Greedy> end(mark_number, min_, max_);
+ detail::repeat_begin_matcher begin(mark_number);
+ detail::repeat_end_matcher<Greedy> end(mark_number, min_, max_);
 
- typename apply<Expr, State, Visitor>::type that = {{begin}, {marked_sub, {end}}};
+ typename result<void(Expr, State, Visitor)>::type that
+ = {{begin}, {marked_sub, {end}}};
             return that;
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // optional_tag
- template<bool Greedy>
+ template<typename Greedy>
     struct optional_tag
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_optional
- template<typename Grammar, bool Greedy>
- struct as_default_optional
- : Grammar
+ template<typename Grammar, typename Greedy>
+ struct as_default_optional : proto::callable
     {
- as_default_optional();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef optional_matcher<
- typename Grammar::template apply<Expr, alternate_end_xpression, Visitor>::type
+ typedef detail::optional_matcher<
+ typename Grammar::template result<void(Expr, detail::alternate_end_xpression, Visitor)>::type
               , Greedy
> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, alternate_end_xpression(), visitor)
+ return typename result<void(Expr, State, Visitor)>::type(
+ Grammar()(expr, detail::alternate_end_xpression(), visitor)
             );
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_mark_optional
- template<typename Grammar, bool Greedy>
- struct as_mark_optional
- : Grammar
+ template<typename Grammar, typename Greedy>
+ struct as_mark_optional : proto::callable
     {
- as_mark_optional();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef optional_mark_matcher<
- typename Grammar::template apply<Expr, alternate_end_xpression, Visitor>::type
+ typedef detail::optional_mark_matcher<
+ typename Grammar::template result<void(Expr, detail::alternate_end_xpression, Visitor)>::type
               , Greedy
> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
             int mark_number = proto::arg(proto::left(expr)).mark_number_;
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, alternate_end_xpression(), visitor)
+ return typename result<void(Expr, State, Visitor)>::type(
+ Grammar()(expr, detail::alternate_end_xpression(), visitor)
               , mark_number
             );
         }
@@ -239,90 +249,88 @@
     ///////////////////////////////////////////////////////////////////////////////
     // IsMarkerOrRepeater
     struct IsMarkerOrRepeater
- : proto::or_<
- proto::shift_right<proto::terminal<repeat_begin_matcher>, proto::_>
- , proto::assign<proto::terminal<mark_placeholder>, proto::_>
+ : or_<
+ shift_right<terminal<detail::repeat_begin_matcher>, _>
+ , assign<terminal<detail::mark_placeholder>, _>
>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_optional
- template<typename Grammar, bool Greedy>
+ template<typename Grammar, typename Greedy>
     struct as_optional
- : proto::if_<
- proto::matches<mpl::_, IsMarkerOrRepeater>
- , as_mark_optional<Grammar, Greedy>
- , as_default_optional<Grammar, Greedy>
+ : or_<
+ when<IsMarkerOrRepeater, as_mark_optional<Grammar, Greedy> >
+ , otherwise<as_default_optional<Grammar, Greedy> >
>
- {
- as_optional();
- };
+ {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // make_optional_
- template<bool Greedy>
- struct make_optional_
+ template<typename Greedy>
+ struct make_optional_ : proto::callable
     {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::unary_expr<optional_tag<Greedy>, Expr>
- {};
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename unary_expr<optional_tag<Greedy>, Expr>::type type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &)
+ typename unary_expr<optional_tag<Greedy>, Expr>::type
+ operator ()(Expr const &expr, State const &, Visitor &) const
         {
- typename apply<Expr, State, Visitor>::type that = {expr};
+ typename unary_expr<optional_tag<Greedy>, Expr>::type that = {expr};
             return that;
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_quantifier_impl
- template<bool Greedy, uint_t Max>
+ template<typename Greedy, uint_t Max>
     struct as_default_quantifier_impl<Greedy, 0, Max>
- : proto::transform::compose<
- as_default_quantifier_impl<Greedy, 1, Max>
- , make_optional_<Greedy>
- >
+ : call<make_optional_<Greedy>(as_default_quantifier_impl<Greedy, 1, Max>)>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_quantifier_impl
- template<bool Greedy>
+ template<typename Greedy>
     struct as_default_quantifier_impl<Greedy, 0, 1>
- : proto::transform::compose<
- proto::transform::arg<proto::_>
- , make_optional_<Greedy>
- >
+ : call<make_optional_<Greedy>(_arg)>
     {};
 
     ///////////////////////////////////////////////////////////////////////////////
     // as_default_quantifier
- template<typename Grammar, bool Greedy>
- struct as_default_quantifier
- : Grammar
+ template<typename Greedy>
+ struct as_default_quantifier : proto::callable
     {
- as_default_quantifier();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : as_default_quantifier_impl<
- Greedy
- , min_type<typename Expr::proto_tag>::value
- , max_type<typename Expr::proto_tag>::value
- >::template apply<Expr, State, Visitor>
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ as_default_quantifier_impl<
+ Greedy
+ , min_type<typename Expr::proto_tag>::value
+ , max_type<typename Expr::proto_tag>::value
+ >
+ impl;
+
+ typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
+ };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
         {
             return as_default_quantifier_impl<
                 Greedy
               , min_type<typename Expr::proto_tag>::value
               , max_type<typename Expr::proto_tag>::value
- >::call(expr, state, visitor);
+ >()(expr, state, visitor);
         }
     };
 

Modified: branches/release/boost/xpressive/detail/static/transforms/as_sequence.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_sequence.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_sequence.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_sequence.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -18,30 +18,28 @@
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 
-namespace boost { namespace xpressive { namespace detail
+namespace boost { namespace xpressive { namespace grammar_detail
 {
-
     template<typename Grammar>
- struct in_sequence
- : Grammar
+ struct in_sequence : proto::callable
     {
- in_sequence();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef static_xpression<
- typename Grammar::template apply<Expr, State, Visitor>::type
+ typedef detail::static_xpression<
+ typename Grammar::template result<void(Expr, State, Visitor)>::type
               , State
> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
         {
- return typename apply<Expr, State, Visitor>::type(
- Grammar::call(expr, state, visitor)
+ return typename result<void(Expr, State, Visitor)>::type(
+ Grammar()(expr, state, visitor)
               , state
             );
         }

Modified: branches/release/boost/xpressive/detail/static/transforms/as_set.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transforms/as_set.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transforms/as_set.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // as_set.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -15,214 +15,152 @@
 
 #include <boost/mpl/assert.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/apply.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/static/static.hpp>
 #include <boost/xpressive/detail/utility/chset/chset.hpp>
 #include <boost/xpressive/detail/utility/traits_utils.hpp>
 
-namespace boost { namespace xpressive { namespace detail
+namespace boost { namespace xpressive { namespace grammar_detail
 {
 
- template<typename I>
- typename I::next next_(I)
- {
- return typename I::next();
- }
-
- template<typename Grammar>
- struct next
- : Grammar
- {
- next();
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : Grammar::template apply<Expr, State, Visitor>::type::next
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return detail::next_(Grammar::call(expr, state, visitor));
- }
- };
-
- template<typename Grammar>
- struct push_back
- : Grammar
- {
- push_back();
-
- template<typename Expr, typename State, typename Visitor>
- static typename Grammar::template apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- visitor.accept(proto::arg(expr));
- return Grammar::call(expr, state, visitor);
- }
- };
-
     ///////////////////////////////////////////////////////////////////////////
     // CharLiteral
     template<typename Char>
     struct CharLiteral
- : proto::or_<
- proto::terminal<char>
- , proto::terminal<Char>
+ : or_<
+ terminal<char>
+ , terminal<Char>
>
     {};
 
     template<>
     struct CharLiteral<char>
- : proto::terminal<char>
+ : terminal<char>
     {};
 
     ///////////////////////////////////////////////////////////////////////////
     // ListSet
     // matches expressions like (set= 'a','b','c')
     // calculates the size of the set
- // populates an array of characters
     template<typename Char>
     struct ListSet
- : proto::transform::left<
- proto::or_<
- proto::comma<
- next<ListSet<Char> >
- , push_back<CharLiteral<Char> >
- >
- , proto::assign<
- proto::transform::always<set_initializer_type, mpl::int_<1> >
- , push_back<CharLiteral<Char> >
- >
+ : or_<
+ when<
+ comma<ListSet<Char>, CharLiteral<Char> >
+ , make<mpl::next<call<ListSet<Char>(_left)> > > // TODO make a custom transform for this...
+ >
+ , when<
+ assign<detail::set_initializer_type, CharLiteral<Char> >
+ , make<mpl::int_<1> >
>
>
     {};
 
- ///////////////////////////////////////////////////////////////////////////
- // set_fill_visitor
- template<typename Traits>
- struct set_fill_visitor
- {
- typedef typename Traits::char_type char_type;
-
- set_fill_visitor(char_type *buffer, Traits const &traits)
- : buffer_(buffer)
- , traits_(traits)
- {}
-
- template<typename Char>
- void accept(Char ch)
- {
- *this->buffer_++ = this->traits_.translate(
- char_cast<typename Traits::char_type>(ch, this->traits_)
- );
- }
+ template<typename Char, typename Traits>
+ void fill_list_set(Char *&, detail::set_initializer_type, Traits const &)
+ {}
 
- char_type *buffer_;
- Traits const &traits_;
- };
+ template<typename Char, typename Expr, typename Traits>
+ void fill_list_set(Char *&buffer, Expr const &expr, Traits const &traits)
+ {
+ fill_list_set(buffer, proto::left(expr), traits);
+ *buffer++ = traits.translate(detail::char_cast<Char>(proto::arg(proto::right(expr)), traits));
+ }
 
     ///////////////////////////////////////////////////////////////////////////////
- // as_list_set
- template<typename Grammar>
- struct as_list_set
- : Grammar
+ // as_list_set_matcher
+ template<typename Char>
+ struct as_list_set_matcher
     {
- as_list_set();
+ template<typename Sig> struct result {};
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
- typedef typename Visitor::traits_type traits_type;
- typedef set_matcher<
- traits_type
- , Grammar::template apply<Expr, State, set_fill_visitor<traits_type> >::type::value
+ typedef detail::set_matcher<
+ typename Visitor::traits_type
+ , typename ListSet<Char>::template result<void(Expr, State, Visitor)>::type
> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- typename apply<Expr, State, Visitor>::type set;
- set_fill_visitor<typename Visitor::traits_type> filler(set.set_, visitor.traits());
- Grammar::call(expr, state, filler);
+ detail::set_matcher<
+ typename Visitor::traits_type
+ , typename ListSet<Char>::template result<void(Expr, State, Visitor)>::type
+ > set;
+ typename Visitor::char_type *buffer = set.set_;
+ fill_list_set(buffer, expr, visitor.traits());
             return set;
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////////
- // charset_context
+ // merge_charset
     //
     template<typename Grammar, typename CharSet, typename Visitor>
- struct charset_context
+ struct merge_charset
     {
- template<typename Expr, typename Tag>
- struct eval_
- {
- typedef void result_type;
- void operator()(Expr const &expr, charset_context const &ctx) const
- {
- ctx.set(Grammar::call(expr, end_xpression(), ctx.visitor_));
- }
- };
-
- template<typename Expr>
- struct eval_<Expr, proto::tag::bitwise_or>
- {
- typedef void result_type;
- void operator()(Expr const &expr, charset_context const &ctx) const
- {
- proto::eval(proto::left(expr), ctx);
- proto::eval(proto::right(expr), ctx);
- }
- };
-
- // Gah, this is to work around a MSVC bug.
- template<typename Expr>
- struct eval
- : eval_<Expr, typename Expr::proto_tag>
- {};
-
         typedef typename Visitor::traits_type traits_type;
         typedef typename CharSet::char_type char_type;
         typedef typename CharSet::icase_type icase_type;
 
- explicit charset_context(CharSet &charset, Visitor &visitor)
+ merge_charset(CharSet &charset, Visitor &visitor)
           : charset_(charset)
           , visitor_(visitor)
         {}
 
- template<bool Not>
- void set(literal_matcher<traits_type, icase_type::value, Not> const &ch) const
+ template<typename Expr>
+ void operator ()(Expr const &expr) const
+ {
+ this->call_(expr, typename Expr::proto_tag());
+ }
+
+ private:
+ merge_charset &operator =(merge_charset const &);
+
+ template<typename Expr, typename Tag>
+ void call_(Expr const &expr, Tag) const
+ {
+ this->set_(Grammar()(expr, detail::end_xpression(), this->visitor_));
+ }
+
+ template<typename Expr>
+ void call_(Expr const &expr, tag::bitwise_or) const
+ {
+ (*this)(proto::left(expr));
+ (*this)(proto::right(expr));
+ }
+
+ template<typename Not>
+ void set_(detail::literal_matcher<traits_type, icase_type, Not> const &ch) const
         {
             // BUGBUG fixme!
- BOOST_MPL_ASSERT_NOT((mpl::bool_<Not>));
+ BOOST_MPL_ASSERT_NOT((Not));
             set_char(this->charset_.charset_, ch.ch_, this->visitor_.traits(), icase_type());
         }
 
- void set(range_matcher<traits_type, icase_type::value> const &rg) const
+ void set_(detail::range_matcher<traits_type, icase_type> const &rg) const
         {
             // BUGBUG fixme!
             BOOST_ASSERT(!rg.not_);
             set_range(this->charset_.charset_, rg.ch_min_, rg.ch_max_, this->visitor_.traits(), icase_type());
         }
 
- template<int Size>
- void set(set_matcher<traits_type, Size> const &set_) const
+ template<typename Size>
+ void set_(detail::set_matcher<traits_type, Size> const &set_) const
         {
             // BUGBUG fixme!
             BOOST_ASSERT(!set_.not_);
- for(int i=0; i<Size; ++i)
+ for(int i = 0; i < Size::value; ++i)
             {
- set_char(this->charset_.charset_, set_.set_[i], this->visitor_.traits(), icase_type::value);
+ set_char(this->charset_.charset_, set_.set_[i], this->visitor_.traits(), icase_type());
             }
         }
 
- void set(posix_charset_matcher<traits_type> const &posix) const
+ void set_(detail::posix_charset_matcher<traits_type> const &posix) const
         {
             set_class(this->charset_.charset_, posix.mask_, posix.not_, this->visitor_.traits());
         }
@@ -234,40 +172,38 @@
     ///////////////////////////////////////////////////////////////////////////////
     //
     template<typename Grammar>
- struct as_set
- : Grammar
+ struct as_set_matcher : proto::callable
     {
- as_set();
+ template<typename Sig> struct result {};
 
- template<typename, typename, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
             typedef typename Visitor::char_type char_type;
 
             // if sizeof(char_type)==1, merge everything into a basic_chset
             // BUGBUG this is not optimal.
             typedef typename mpl::if_<
- is_narrow_char<char_type>
- , basic_chset<char_type>
- , compound_charset<typename Visitor::traits_type>
+ detail::is_narrow_char<char_type>
+ , detail::basic_chset<char_type>
+ , detail::compound_charset<typename Visitor::traits_type>
>::type charset_type;
 
- typedef charset_matcher<
+ typedef detail::charset_matcher<
                 typename Visitor::traits_type
- , Visitor::icase_type::value
+ , typename Visitor::icase_type
               , charset_type
> type;
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &, Visitor &visitor) const
         {
- typedef typename apply<Expr, State, Visitor>::type set_type;
+ typedef typename result<void(Expr, State, Visitor)>::type set_type;
             set_type matcher;
- charset_context<Grammar, set_type, Visitor> ctx(matcher, visitor);
- // Walks the tree and fills in the charset
- proto::eval(expr, ctx);
+ merge_charset<Grammar, set_type, Visitor> merge(matcher, visitor);
+ merge(expr); // Walks the tree and fills in the charset
             return matcher;
         }
     };

Modified: branches/release/boost/xpressive/detail/static/transmogrify.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/transmogrify.hpp (original)
+++ branches/release/boost/xpressive/detail/static/transmogrify.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // transmogrify.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -44,8 +44,8 @@
         typedef typename mpl::if_
         <
             is_char_literal<Matcher, char_type>
- , literal_matcher<Traits, ICase::value, false>
- , string_matcher<Traits, ICase::value>
+ , literal_matcher<Traits, ICase, mpl::false_>
+ , string_matcher<Traits, ICase>
>::type type;
 
         template<typename Matcher2, typename Visitor>
@@ -128,7 +128,7 @@
         // By design, we don't widen character ranges.
         typedef typename iterator_value<BidiIter>::type char_type;
         BOOST_MPL_ASSERT((is_same<Char, char_type>));
- typedef range_matcher<Traits, ICase::value> type;
+ typedef range_matcher<Traits, ICase> type;
 
         template<typename Matcher2, typename Visitor>
         static type call(Matcher2 const &m, Visitor &visitor)
@@ -140,7 +140,7 @@
     template<typename BidiIter, typename ICase, typename Traits>
     struct transmogrify<BidiIter, ICase, Traits, mark_placeholder >
     {
- typedef mark_matcher<Traits, ICase::value> type;
+ typedef mark_matcher<Traits, ICase> type;
 
         template<typename Matcher2, typename Visitor>
         static type call(Matcher2 const &m, Visitor &visitor)
@@ -162,7 +162,7 @@
         }
     };
 
- template<typename BidiIter, typename Traits, int Size>
+ template<typename BidiIter, typename Traits, typename Size>
     struct transmogrify<BidiIter, mpl::true_, Traits, set_matcher<Traits, Size> >
     {
         typedef set_matcher<Traits, Size> type;

Modified: branches/release/boost/xpressive/detail/static/type_traits.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/type_traits.hpp (original)
+++ branches/release/boost/xpressive/detail/static/type_traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // type_traits.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/static/visitor.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/visitor.hpp (original)
+++ branches/release/boost/xpressive/detail/static/visitor.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // visitor.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/static/width_of.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/static/width_of.hpp (original)
+++ branches/release/boost/xpressive/detail/static/width_of.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // width_of.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -147,7 +147,7 @@
     // either (s1 = ...) or (a1 = ...) or (set = ...)
     template<typename Expr, typename Char>
     struct width_of<Expr, Char, proto::tag::assign>
- : width_of_assign<Expr, Char, typename proto::result_of::arg<typename Expr::proto_arg0>::type>
+ : width_of_assign<Expr, Char, typename proto::result_of::arg<typename Expr::proto_arg0::proto_base_expr>::type>
     {};
 
     template<typename Expr, typename Char>

Modified: branches/release/boost/xpressive/detail/utility/algorithm.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/algorithm.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/algorithm.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // algorithm.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/any.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/any.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/any.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // any.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/boyer_moore.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/boyer_moore.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/boyer_moore.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
 /// purpose boyer-moore implementation. It truncates the search string at
 /// 256 characters, but it is sufficient for the needs of xpressive.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/chset/chset.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/chset/chset.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/chset/chset.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // chset.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/cons.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/cons.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/cons.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // cons.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/dont_care.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/dont_care.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/dont_care.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // dont_care.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/hash_peek_bitset.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/hash_peek_bitset.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/hash_peek_bitset.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // hash_peek_bitset.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/ignore_unused.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/ignore_unused.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/ignore_unused.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // ignore_unused.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/literals.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/literals.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/literals.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // literals.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/never_true.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/never_true.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/never_true.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // never_true.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/save_restore.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/save_restore.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/save_restore.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // save_restore.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/sequence_stack.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/sequence_stack.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/sequence_stack.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // sequence_stack.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/symbols.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/symbols.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/symbols.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -21,6 +21,7 @@
 # pragma once
 #endif
 
+#include <boost/noncopyable.hpp>
 #include <boost/range/begin.hpp>
 #include <boost/range/end.hpp>
 #include <boost/range/value_type.hpp>

Modified: branches/release/boost/xpressive/detail/utility/tracking_ptr.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/tracking_ptr.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/tracking_ptr.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // tracking_ptr.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -24,6 +24,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/intrusive_ptr.hpp>
+#include <boost/detail/workaround.hpp>
 #include <boost/detail/atomic_count.hpp>
 #include <boost/iterator/iterator_facade.hpp>
 #include <boost/iterator/filter_iterator.hpp>

Modified: branches/release/boost/xpressive/detail/utility/traits_utils.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/traits_utils.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/traits_utils.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // traits_utils.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/detail/utility/width.hpp
==============================================================================
--- branches/release/boost/xpressive/detail/utility/width.hpp (original)
+++ branches/release/boost/xpressive/detail/utility/width.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // width.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/match_results.hpp
==============================================================================
--- branches/release/boost/xpressive/match_results.hpp (original)
+++ branches/release/boost/xpressive/match_results.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,11 +4,11 @@
 /// The match_results type holds the results of a regex_match() or
 /// regex_search() operation.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
-// Acknowledgements: Thanks to Markus Sch\:opflin for helping to track down
+// Acknowledgements: Thanks to Markus Schoepflin for helping to track down
 // a tricky formatting bug on HP Tru64, and to Steven Watanabe for suggesting
 // the fix.
 
@@ -21,6 +21,7 @@
 #endif
 
 #include <map>
+#include <string>
 #include <vector>
 #include <utility>
 #include <iterator>
@@ -29,11 +30,21 @@
 #include <boost/config.hpp>
 #include <boost/assert.hpp>
 #include <boost/integer.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/size_t.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/intrusive_ptr.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/iterator_adaptors.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/detail/workaround.hpp>
 #include <boost/numeric/conversion/converter.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/as_literal.hpp>
+#include <boost/range/const_iterator.hpp>
+#include <boost/type_traits/is_function.hpp>
 #if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
 # include <boost/iterator/filter_iterator.hpp>
 #endif
@@ -46,6 +57,8 @@
 #include <boost/xpressive/detail/utility/literals.hpp>
 #include <boost/xpressive/detail/utility/algorithm.hpp>
 #include <boost/xpressive/detail/utility/counted_base.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/eval.hpp>
 
 namespace boost { namespace xpressive { namespace detail
 {
@@ -212,6 +225,111 @@
     }
 };
 
+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<typename T>
+unary_type check_is_formatter(T const &, binary_type, ternary_type);
+
+template<typename T>
+binary_type check_is_formatter(unary_type, T const &, ternary_type);
+
+template<typename T, typename U>
+binary_type check_is_formatter(T const &, U const &, ternary_type);
+
+template<typename T>
+ternary_type check_is_formatter(unary_type, binary_type, T const &);
+
+template<typename T, typename U>
+ternary_type check_is_formatter(T const &, binary_type, U const &);
+
+template<typename T, typename U>
+ternary_type check_is_formatter(unary_type, T const &, U const &);
+
+template<typename T, typename U, typename V>
+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<typename Formatter, bool IsFunction = is_function<Formatter>::value>
+struct formatter_wrapper
+ : Formatter
+ , unary_binary_ternary
+{
+ formatter_wrapper();
+};
+
+template<typename Formatter>
+struct formatter_wrapper<Formatter, true>
+ : unary_binary_ternary
+{
+ operator Formatter *();
+};
+
+template<typename Formatter>
+struct formatter_wrapper<Formatter *, false>
+ : unary_binary_ternary
+{
+ operator Formatter *();
+};
+
+template<typename Formatter, typename What, typename Out, typename Void = void>
+struct formatter_arity
+{
+ static formatter_wrapper<Formatter> &formatter;
+ static What &what;
+ static Out &out;
+ BOOST_STATIC_CONSTANT(
+ std::size_t
+ , value = sizeof(
+ check_is_formatter(
+ formatter(what)
+ , formatter(what, out)
+ , formatter(what, out, regex_constants::format_default)
+ )
+ ) - 1
+ );
+ typedef mpl::size_t<value> type;
+};
+
+template<typename Formatter, typename What, typename Out>
+struct formatter_arity<Formatter, What, Out, typename Formatter::proto_is_expr_>
+ : mpl::size_t<4>
+{};
+
+template<typename T>
+struct is_char_ptr
+ : mpl::false_
+{};
+
+template<typename T>
+struct is_char_ptr<T *>
+ : mpl::not_<is_function<T> >
+{};
+
+#if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
+// work around gcc-4.0.1 compiler bug wrt function references
+template<typename T>
+typename mpl::if_<is_function<T>, T *, T const &>::type
+as_callable(T const &t)
+{
+ return t;
+}
+#endif
+
 } // detail
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -324,8 +442,8 @@
         return *this;
     }
 
- /// Returns one plus the number of marked sub-expressions in the regular
- /// expression that was matched if *this represents the result of a
+ /// Returns one plus the number of marked sub-expressions in the regular
+ /// expression that was matched if *this represents the result of a
     /// successful match. Otherwise returns 0.
     size_type size() const
     {
@@ -432,50 +550,95 @@
         return this->nested_results_;
     }
 
- /// 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 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
+ /// If \c Format models \c ForwardRange or is a null-terminated string, this function
+ /// copies the character sequence in \c fmt to \c OutputIterator \c out. For each format
+ /// specifier or escape sequence in \c fmt, replace that sequence with either the character(s) it
+ /// represents, or the sequence within <tt>*this</tt> 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.
- template<typename OutputIterator>
+ ///
+ /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator, regex_constants::match_flag_type\></tt>,
+ /// this function returns <tt>fmt(*this, out, flags)</tt>.
+ ///
+ /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator\></tt>, this function
+ /// returns <tt>fmt(*this, out)</tt>.
+ ///
+ /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\> \></tt>, this function
+ /// returns <tt>std::copy(x.begin(), x.end(), out)</tt>, where \c x is the result of
+ /// calling <tt>fmt(*this)</tt>.
+ template<typename Format, typename OutputIterator>
     OutputIterator format
     (
         OutputIterator out
- , const string_type &fmt
+ , Format const &fmt
       , regex_constants::match_flag_type flags = regex_constants::format_default
+ , typename disable_if<detail::is_char_ptr<Format> >::type * = 0
     ) const
     {
- typename string_type::const_iterator cur = fmt.begin(), end = fmt.end();
+ // Is this a formatter object, or a format string?
+ typedef
+ typename detail::formatter_arity<
+ Format
+ , match_results<BidiIter>
+ , OutputIterator
+ >::type
+ arity;
 
- if(0 != (regex_constants::format_literal & flags))
- {
- return std::copy(cur, end, out);
- }
- else if(0 != (regex_constants::format_perl & flags))
- {
- return this->format_perl_(cur, end, out);
- }
- else if(0 != (regex_constants::format_sed & flags))
- {
- return this->format_sed_(cur, end, out);
- }
- else if(0 != (regex_constants::format_all & flags))
- {
- return this->format_all_(cur, end, out);
- }
+ return this->format_(out, fmt, flags, arity());
+ }
 
- return this->format_ecma_262_(cur, end, out);
+ /// \overload
+ ///
+ template<typename OutputIterator>
+ OutputIterator format
+ (
+ OutputIterator out
+ , char_type const *fmt
+ , regex_constants::match_flag_type flags = regex_constants::format_default
+ ) const
+ {
+ return this->format_(out, boost::as_literal(fmt), flags, mpl::size_t<0>());
     }
 
- /// Returns a copy of the string fmt. For each format specifier or escape sequence in fmt,
+ /// If \c Format models \c ForwardRange or is a null-terminated string, this function
+ /// returns a copy of the character sequence \c fmt. For each format specifier or escape sequence in \c fmt,
     /// replace that sequence with either the character(s) it represents, or the sequence 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,
+ /// <tt>*this</tt> to which it refers. The bitmasks specified in \c 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.
- string_type format(string_type const &fmt, regex_constants::match_flag_type flags = regex_constants::format_default) const
+ ///
+ /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator, regex_constants::match_flag_type\></tt>,
+ /// this function returns a \c string_type object \c x populated by calling <tt>fmt(*this, out, flags)</tt>,
+ /// where \c out is a \c back_insert_iterator into \c x.
+ ///
+ /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\>, OutputIterator\></tt>, this function
+ /// returns a \c string_type object \c x populated by calling <tt>fmt(*this, out)</tt>,
+ /// where \c out is a \c back_insert_iterator into \c x.
+ ///
+ /// Otherwise, if \c Format models <tt>Callable\<match_results\<BidiIter\> \></tt>, this function
+ /// returns <tt>fmt(*this)</tt>.
+ template<typename Format, typename OutputIterator>
+ string_type format
+ (
+ Format const &fmt
+ , regex_constants::match_flag_type flags = regex_constants::format_default
+ , typename disable_if<detail::is_char_ptr<Format> >::type * = 0
+ ) const
+ {
+ string_type result;
+ this->format(std::back_inserter(result), fmt, flags);
+ return result;
+ }
+
+ /// \overload
+ ///
+ string_type format
+ (
+ char_type const *fmt
+ , regex_constants::match_flag_type flags = regex_constants::format_default
+ ) const
     {
         string_type result;
- result.reserve(fmt.length() * 2);
         this->format(std::back_inserter(result), fmt, flags);
         return result;
     }
@@ -655,6 +818,131 @@
 
     /// INTERNAL ONLY
     ///
+ template<typename OutputIterator, typename ForwardRange>
+ OutputIterator format2_(OutputIterator out, ForwardRange const &result) const
+ {
+ return std::copy(boost::begin(result), boost::end(result), out);
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename OutputIterator, typename Char>
+ OutputIterator format2_(OutputIterator out, Char const *const &result) const
+ {
+ Char const *tmp = result;
+ BOOST_ASSERT(0 != tmp);
+ for(; 0 != *tmp; ++tmp, ++out)
+ {
+ *out = *tmp;
+ }
+ return out;
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename OutputIterator, typename ForwardRange>
+ OutputIterator format_
+ (
+ OutputIterator out
+ , ForwardRange const &format
+ , regex_constants::match_flag_type flags
+ , mpl::size_t<0>
+ ) const
+ {
+ typedef typename range_const_iterator<ForwardRange>::type iterator;
+ iterator cur = boost::begin(format), end = boost::end(format);
+
+ if(0 != (regex_constants::format_literal & flags))
+ {
+ return std::copy(cur, end, out);
+ }
+ else if(0 != (regex_constants::format_perl & flags))
+ {
+ return this->format_perl_(cur, end, out);
+ }
+ else if(0 != (regex_constants::format_sed & flags))
+ {
+ return this->format_sed_(cur, end, out);
+ }
+ else if(0 != (regex_constants::format_all & flags))
+ {
+ return this->format_all_(cur, end, out);
+ }
+
+ return this->format_ecma_262_(cur, end, out);
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename OutputIterator, typename Callable1>
+ OutputIterator format_
+ (
+ OutputIterator out
+ , Callable1 const &format
+ , regex_constants::match_flag_type
+ , mpl::size_t<1>
+ ) const
+ {
+ #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
+ return this->format2_(out, detail::as_callable(format)(*this));
+ #else
+ return this->format2_(out, format(*this));
+ #endif
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename OutputIterator, typename Callable2>
+ OutputIterator format_
+ (
+ OutputIterator out
+ , Callable2 const &format
+ , regex_constants::match_flag_type
+ , mpl::size_t<2>
+ ) const
+ {
+ #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
+ return detail::as_callable(format)(*this, out);
+ #else
+ return format(*this, out);
+ #endif
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename OutputIterator, typename Callable3>
+ OutputIterator format_
+ (
+ OutputIterator out
+ , Callable3 const &format
+ , regex_constants::match_flag_type flags
+ , mpl::size_t<3>
+ ) const
+ {
+ #if BOOST_WORKAROUND(__GNUC__, == 4) && (__GNUC_MINOR__ == 0)
+ return detail::as_callable(format)(*this, out, flags);
+ #else
+ return format(*this, out, flags);
+ #endif
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename OutputIterator, typename Expr>
+ OutputIterator format_
+ (
+ OutputIterator out
+ , Expr const &format
+ , regex_constants::match_flag_type flags
+ , mpl::size_t<4>
+ ) const
+ {
+ detail::replacement_context<BidiIter> ctx(*this);
+ return this->format2_(out, proto::eval(format, ctx));
+ }
+
+ /// INTERNAL ONLY
+ ///
     template<typename ForwardIterator, typename OutputIterator>
     OutputIterator format_ecma_262_(ForwardIterator cur, ForwardIterator end, OutputIterator out) const
     {
@@ -822,11 +1110,11 @@
 
     /// INTERNAL ONLY
     ///
- template<typename OutputIterator>
+ template<typename ForwardIterator, typename OutputIterator>
     OutputIterator format_backref_
     (
- typename string_type::const_iterator &cur
- , typename string_type::const_iterator end
+ ForwardIterator &cur
+ , ForwardIterator end
       , OutputIterator out
     ) const
     {
@@ -872,16 +1160,16 @@
 
     /// INTERNAL ONLY
     ///
- template<typename OutputIterator>
+ template<typename ForwardIterator, typename OutputIterator>
     OutputIterator format_escape_
     (
- typename string_type::const_iterator &cur
- , typename string_type::const_iterator end
+ ForwardIterator &cur
+ , ForwardIterator end
       , OutputIterator out
     ) const
     {
         using namespace regex_constants;
- typename string_type::const_iterator tmp;
+ ForwardIterator tmp;
         // define an unsigned type the same size as char_type
         typedef typename boost::uint_t<CHAR_BIT * sizeof(char_type)>::least uchar_t;
         BOOST_MPL_ASSERT_RELATION(sizeof(uchar_t), ==, sizeof(char_type));
@@ -1013,18 +1301,18 @@
 
     /// INTERNAL ONLY
     ///
- template<typename OutputIterator>
+ template<typename ForwardIterator, typename OutputIterator>
     OutputIterator format_named_backref_
     (
- typename string_type::const_iterator &cur
- , typename string_type::const_iterator end
+ ForwardIterator &cur
+ , ForwardIterator end
       , OutputIterator out
     ) const
     {
         using namespace regex_constants;
         detail::ensure(cur != end && BOOST_XPR_CHAR_(char_type, '<') == *cur++
             , error_badmark, "invalid named back-reference");
- typename string_type::const_iterator begin = cur;
+ ForwardIterator begin = cur;
         for(; cur != end && BOOST_XPR_CHAR_(char_type, '>') != *cur; ++cur)
         {}
         detail::ensure(cur != begin && cur != end && BOOST_XPR_CHAR_(char_type, '>') == *cur

Modified: branches/release/boost/xpressive/proto/args.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/args.hpp (original)
+++ branches/release/boost/xpressive/proto/args.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
     /// \file args.hpp
     /// Contains definition of args\<\> class template.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/proto/context.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/context.hpp (original)
+++ branches/release/boost/xpressive/proto/context.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file context.hpp
 /// Includes all the context classes in the context/ sub-directory.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/proto/context/callable.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/context/callable.hpp (original)
+++ branches/release/boost/xpressive/proto/context/callable.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,10 +4,10 @@
     /// Definintion of callable_context\<\>, an evaluation context for
     /// proto::eval() that explodes each node and calls the derived context
     /// type with the expressions constituents. If the derived context doesn't
- /// have an overload that handles this node, fall-back to the default_context.
- /// TODO: make the fall-back configurable!
+ /// have an overload that handles this node, fall back to some other
+ /// context.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -20,8 +20,10 @@
     #include <boost/preprocessor/cat.hpp>
     #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
     #include <boost/preprocessor/repetition/enum_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
     #include <boost/preprocessor/arithmetic/inc.hpp>
     #include <boost/preprocessor/selection/max.hpp>
     #include <boost/mpl/if.hpp>
@@ -55,19 +57,110 @@
 
         namespace context
         {
- /// callable_eval
+ /// \brief A BinaryFunction that accepts a Proto expression and a
+ /// callable context and calls the context with the expression tag
+ /// and children as arguments, effectively fanning the expression
+ /// out.
             ///
- template<typename Expr, typename Context, long Arity>
+ /// <tt>callable_eval\<\></tt> requires that \c Context is a
+ /// PolymorphicFunctionObject that can be invoked with \c Expr's
+ /// tag and children as expressions, as follows:
+ ///
+ /// \code
+ /// context(Expr::proto_tag(), arg_c<0>(expr), arg_c<1>(expr), ...)
+ /// \endcode
+ template<
+ typename Expr
+ , typename Context
+ , long Arity BOOST_PROTO_FOR_DOXYGEN_ONLY(= Expr::proto_arity::value)
+ >
             struct callable_eval
             {};
 
- /// callable_context
+ /// \brief An evaluation context adaptor that makes authoring a
+ /// context a simple matter of writing function overloads, rather
+ /// then writing template specializations.
+ ///
+ /// <tt>callable_context\<\></tt> is a base class that implements
+ /// the context protocol by passing fanned-out expression nodes to
+ /// the derived context, making it easy to customize the handling
+ /// of expression types by writing function overloads. Only those
+ /// expression types needing special handling require explicit
+ /// handling. All others are dispatched to a user-specified
+ /// default context, \c DefaultCtx.
+ ///
+ /// <tt>callable_context\<\></tt> is defined simply as:
+ ///
+ /// \code
+ /// template<typename Context, typename DefaultCtx = default_context>
+ /// struct callable_context
+ /// {
+ /// template<typename Expr, typename ThisContext = Context>
+ /// struct eval
+ /// : mpl::if_<
+ /// is_expr_handled_<Expr, Context> // For exposition
+ /// , callable_eval<Expr, ThisContext>
+ /// , typename DefaultCtx::template eval<Expr, Context>
+ /// >::type
+ /// {};
+ /// };
+ /// \endcode
+ ///
+ /// The Boolean metafunction <tt>is_expr_handled_\<\></tt> uses
+ /// metaprogramming tricks to determine whether \c Context has
+ /// an overloaded function call operator that accepts the
+ /// fanned-out constituents of an expression of type \c Expr.
+ /// If so, the handling of the expression is dispatched to
+ /// <tt>callable_eval\<\></tt>. If not, it is dispatched to
+ /// the user-specified \c DefaultCtx.
+ ///
+ /// Below is an example of how to use <tt>callable_context\<\></tt>:
+ ///
+ /// \code
+ /// // An evaluation context that increments all
+ /// // integer terminals in-place.
+ /// struct increment_ints
+ /// : callable_context<
+ /// increment_ints const // derived context
+ /// , null_context const // fall-back context
+ /// >
+ /// {
+ /// typedef void result_type;
+ ///
+ /// // Handle int terminals here:
+ /// void operator()(proto::tag::terminal, int &i) const
+ /// {
+ /// ++i;
+ /// }
+ /// };
+ /// \endcode
             ///
- template<typename Context, typename DefaultCtx>
+ /// With \c increment_ints, we can do the following:
+ ///
+ /// \code
+ /// literal<int> i = 0, j = 10;
+ /// proto::eval( i - j * 3.14, increment_ints() );
+ ///
+ /// assert( i.get() == 1 && j.get() == 11 );
+ /// \endcode
+ template<
+ typename Context
+ , typename DefaultCtx BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_context)
+ >
             struct callable_context
             {
- /// callable_context::eval
+ /// A BinaryFunction that accepts an \c Expr and a
+ /// \c Context, and either fans out the expression and passes
+ /// it to the context, or else hands off the expression to
+ /// \c DefaultCtx.
                 ///
+ /// If \c Context is a PolymorphicFunctionObject such that
+ /// it can be invoked with the tag and children of \c Expr,
+ /// as <tt>ctx(Expr::proto_tag(), arg_c\<0\>(expr), arg_c\<1\>(expr)...)</tt>,
+ /// then <tt>eval\<Expr, ThisContext\></tt> inherits from
+ /// <tt>callable_eval\<Expr, ThisContext\></tt>. Otherwise,
+ /// <tt>eval\<Expr, ThisContext\></tt> inherits from
+ /// <tt>DefaultCtx::eval\<Expr, Context\></tt>.
                 template<typename Expr, typename ThisContext = Context>
                 struct eval
                   : mpl::if_<
@@ -80,7 +173,7 @@
         }
 
     #define BOOST_PROTO_ARG_N_TYPE(Z, N, Expr) \
- typename proto::result_of::arg_c<Expr, N>::const_reference \
+ typedef typename proto::result_of::arg_c<Expr, N>::const_reference BOOST_PP_CAT(arg, N); \
         /**/
 
     #define BOOST_PROTO_ARG_N(Z, N, expr) \
@@ -113,8 +206,14 @@
               : remove_cv<Context>::type
             {
                 callable_context_wrapper();
- typedef private_type_ const &(*pointer_to_function)(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(ARG_COUNT), detail::dont_care BOOST_PP_INTERCEPT));
- operator pointer_to_function() const;
+ typedef
+ private_type_ const &fun_type(
+ BOOST_PP_ENUM_PARAMS(
+ BOOST_PP_INC(ARG_COUNT)
+ , detail::dont_care BOOST_PP_INTERCEPT
+ )
+ );
+ operator fun_type *() const;
             };
             #endif
 
@@ -123,6 +222,7 @@
             {
                 static callable_context_wrapper<Context, ARG_COUNT> &sctx_;
                 static Expr &sexpr_;
+ static typename Expr::proto_tag &stag_;
 
                 BOOST_STATIC_CONSTANT(bool, value =
                 (
@@ -130,7 +230,7 @@
                     sizeof(
                         detail::check_is_expr_handled(
                             (sctx_(
- typename Expr::proto_tag()
+ stag_
                                 BOOST_PP_ENUM_TRAILING(ARG_COUNT, BOOST_PROTO_ARG_N, sexpr_)
                             ), 0)
                         )
@@ -142,18 +242,35 @@
 
         namespace context
         {
+ /// \brief A BinaryFunction that accepts a Proto expression and a
+ /// callable context and calls the context with the expression tag
+ /// and children as arguments, effectively fanning the expression
+ /// out.
+ ///
+ /// <tt>callable_eval\<\></tt> requires that \c Context is a
+ /// PolymorphicFunctionObject that can be invoked with \c Expr's
+ /// tag and children as expressions, as follows:
+ ///
+ /// \code
+ /// context(Expr::proto_tag(), arg_c\<0\>(expr), arg_c\<1\>(expr), ...)
+ /// \endcode
             template<typename Expr, typename Context>
             struct callable_eval<Expr, Context, N>
             {
+ BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_ARG_N_TYPE, Expr)
+
                 typedef
                     typename boost::result_of<
                         Context(
                             typename Expr::proto_tag
- BOOST_PP_ENUM_TRAILING(ARG_COUNT, BOOST_PROTO_ARG_N_TYPE, Expr)
+ BOOST_PP_ENUM_TRAILING_PARAMS(ARG_COUNT, arg)
                         )
>::type
                 result_type;
 
+ /// \param expr The current expression
+ /// \param context The callable evaluation context
+ /// \return <tt>context(Expr::proto_tag(), arg_c\<0\>(expr), arg_c\<1\>(expr), ...)</tt>
                 result_type operator ()(Expr &expr, Context &context) const
                 {
                     return context(

Modified: branches/release/boost/xpressive/proto/context/default.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/context/default.hpp (original)
+++ branches/release/boost/xpressive/proto/context/default.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -5,7 +5,7 @@
     /// proto::eval() that uses Boost.Typeof to deduce return types
     /// of the built-in operators.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -14,33 +14,30 @@
 
     #include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
     #include <boost/config.hpp>
- #include <boost/detail/workaround.hpp>
     #include <boost/preprocessor/cat.hpp>
     #include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
     #include <boost/preprocessor/repetition/enum_shifted.hpp>
- #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing.hpp>
- #include <boost/preprocessor/arithmetic/inc.hpp>
- #include <boost/preprocessor/tuple/elem.hpp>
+ #include <boost/preprocessor/selection/max.hpp>
     #include <boost/mpl/if.hpp>
     #include <boost/typeof/typeof.hpp>
     #include <boost/utility/result_of.hpp>
     #include <boost/type_traits/is_const.hpp>
     #include <boost/type_traits/is_function.hpp>
- #include <boost/type_traits/remove_cv.hpp>
+ #include <boost/type_traits/remove_reference.hpp>
     #include <boost/xpressive/proto/proto_fwd.hpp>
     #include <boost/xpressive/proto/tags.hpp>
     #include <boost/xpressive/proto/eval.hpp>
     #include <boost/xpressive/proto/traits.hpp> // for proto::arg_c()
     #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
 
+ namespace boost { namespace proto
+ {
     // If we're generating doxygen documentation, hide all the nasty
     // Boost.Typeof gunk.
     #ifndef BOOST_PROTO_DOXYGEN_INVOKED
         #define BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_(Nested, Expr)\
             BOOST_TYPEOF_NESTED_TYPEDEF_TPL(BOOST_PP_CAT(nested_and_hidden_, Nested), Expr)\
- static int const sz = sizeof(detail::check_reference(Expr)); \
+ static int const sz = sizeof(proto::detail::check_reference(Expr));\
             struct Nested\
               : mpl::if_c<\
                     1==sz\
@@ -62,8 +59,10 @@
             typedef detail::unspecified Type;
     #endif
 
- namespace boost { namespace proto
- {
+ /// INTERNAL ONLY
+ ///
+ #define UNREF(x) typename boost::remove_reference<x>::type
+
         namespace detail
         {
             template<typename T> T make();
@@ -77,7 +76,7 @@
             template<typename A0, typename A1>
             struct comma_result
             {
- BOOST_PROTO_DECLTYPE_((detail::make<A0>(), detail::make<A1>()), type)
+ BOOST_PROTO_DECLTYPE_((proto::detail::make<A0>(), proto::detail::make<A1>()), type)
             };
 
             template<typename A0>
@@ -129,18 +128,16 @@
             //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(* const &)()>::type>));
             //BOOST_MPL_ASSERT((is_same<void(*)(), result_of_fixup<void(&)()>::type>));
 
- #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
- template<typename T> T &make_ref_(T &t);
- template<typename T> T const &make_ref_(T const &t);
- #define BOOST_PROTO_REF(x) detail::make_ref_(x)
- #else
- #define BOOST_PROTO_REF(x) x
- #endif
- }
+ } // namespace detail
 
         namespace context
         {
- template<typename Expr, typename Context, typename Tag, long Arity>
+ template<
+ typename Expr
+ , typename Context
+ , typename Tag BOOST_PROTO_FOR_DOXYGEN_ONLY(= typename Expr::proto_tag)
+ , long Arity BOOST_PROTO_FOR_DOXYGEN_ONLY(= Expr::proto_arity::value)
+ >
             struct default_eval
             {};
 
@@ -151,11 +148,11 @@
             struct default_eval<Expr, Context, Tag, 1> \
             { \
             private: \
- static Expr &sexpr; \
- static Context &sctx; \
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0; \
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0; \
             public: \
- BOOST_PROTO_DECLTYPE_(Op proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx), result_type)\
- result_type operator()(Expr &expr, Context &ctx) const \
+ BOOST_PROTO_DECLTYPE_(Op proto::detail::make<r0>(), result_type) \
+ result_type operator ()(Expr &expr, Context &ctx) const \
                 { \
                     return Op proto::eval(proto::arg_c<0>(expr), ctx); \
                 } \
@@ -169,11 +166,13 @@
             struct default_eval<Expr, Context, Tag, 2> \
             { \
             private: \
- static Expr &sexpr; \
- static Context &sctx; \
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0; \
+ typedef typename proto::result_of::arg_c<Expr, 1>::type e1; \
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0; \
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1; \
             public: \
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) Op proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx), result_type)\
- result_type operator()(Expr &expr, Context &ctx) const \
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() Op proto::detail::make<r1>(), result_type)\
+ result_type operator ()(Expr &expr, Context &ctx) const \
                 { \
                     return proto::eval(proto::arg_c<0>(expr), ctx) Op proto::eval(proto::arg_c<1>(expr), ctx);\
                 } \
@@ -221,6 +220,9 @@
             BOOST_PROTO_BINARY_OP_RESULT(|=, proto::tag::bitwise_or_assign)
             BOOST_PROTO_BINARY_OP_RESULT(^=, proto::tag::bitwise_xor_assign)
 
+ #undef BOOST_PROTO_UNARY_OP_RESULT
+ #undef BOOST_PROTO_BINARY_OP_RESULT
+
             template<typename Expr, typename Context>
             struct default_eval<Expr, Context, proto::tag::terminal, 0>
             {
@@ -232,7 +234,7 @@
>::type
                 result_type;
 
- result_type operator()(Expr &expr, Context &) const
+ result_type operator ()(Expr &expr, Context &) const
                 {
                     return proto::arg(expr);
                 }
@@ -243,11 +245,11 @@
             struct default_eval<Expr, Context, proto::tag::post_inc, 1>
             {
             private:
- static Expr &sexpr;
- static Context &sctx;
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
             public:
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) ++, result_type)
- result_type operator()(Expr &expr, Context &ctx) const
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() ++, result_type)
+ result_type operator ()(Expr &expr, Context &ctx) const
                 {
                     return proto::eval(proto::arg_c<0>(expr), ctx) ++;
                 }
@@ -258,11 +260,11 @@
             struct default_eval<Expr, Context, proto::tag::post_dec, 1>
             {
             private:
- static Expr &sexpr;
- static Context &sctx;
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
             public:
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx) --, result_type)
- result_type operator()(Expr &expr, Context &ctx) const
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>() --, result_type)
+ result_type operator ()(Expr &expr, Context &ctx) const
                 {
                     return proto::eval(proto::arg_c<0>(expr), ctx) --;
                 }
@@ -273,11 +275,13 @@
             struct default_eval<Expr, Context, proto::tag::subscript, 2>
             {
             private:
- static Expr &sexpr;
- static Context &sctx;
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::arg_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
             public:
- BOOST_PROTO_DECLTYPE_(proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)[proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)], result_type)
- result_type operator()(Expr &expr, Context &ctx) const
+ BOOST_PROTO_DECLTYPE_(proto::detail::make<r0>()[proto::detail::make<r1>()], result_type)
+ result_type operator ()(Expr &expr, Context &ctx) const
                 {
                     return proto::eval(proto::arg_c<0>(expr), ctx)[proto::eval(proto::arg_c<1>(expr), ctx)];
                 }
@@ -288,16 +292,20 @@
             struct default_eval<Expr, Context, proto::tag::if_else_, 3>
             {
             private:
- static Expr &sexpr;
- static Context &sctx;
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::arg_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::arg_c<Expr, 2>::type e2;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ typedef typename proto::result_of::eval<UNREF(e2), Context>::type r2;
             public:
                 BOOST_PROTO_DECLTYPE_(
- proto::eval(BOOST_PROTO_REF(proto::arg_c<0>(sexpr)), sctx)
- ? proto::eval(BOOST_PROTO_REF(proto::arg_c<1>(sexpr)), sctx)
- : proto::eval(BOOST_PROTO_REF(proto::arg_c<2>(sexpr)), sctx)
+ proto::detail::make<r0>()
+ ? proto::detail::make<r1>()
+ : proto::detail::make<r2>()
                   , result_type
                 )
- result_type operator()(Expr &expr, Context &ctx) const
+ result_type operator ()(Expr &expr, Context &ctx) const
                 {
                     return proto::eval(proto::arg_c<0>(expr), ctx)
                          ? proto::eval(proto::arg_c<1>(expr), ctx)
@@ -309,29 +317,34 @@
             template<typename Expr, typename Context>
             struct default_eval<Expr, Context, proto::tag::comma, 2>
             {
- typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 0>::type, Context>::type proto_arg0;
- typedef typename proto::result_of::eval<typename proto::result_of::arg_c<Expr, 1>::type, Context>::type proto_arg1;
- typedef typename detail::comma_result<proto_arg0, proto_arg1>::type result_type;
- result_type operator()(Expr &expr, Context &ctx) const
+ private:
+ typedef typename proto::result_of::arg_c<Expr, 0>::type e0;
+ typedef typename proto::result_of::arg_c<Expr, 1>::type e1;
+ typedef typename proto::result_of::eval<UNREF(e0), Context>::type r0;
+ typedef typename proto::result_of::eval<UNREF(e1), Context>::type r1;
+ public:
+ typedef typename proto::detail::comma_result<r0, r1>::type result_type;
+ result_type operator ()(Expr &expr, Context &ctx) const
                 {
                     return proto::eval(proto::arg_c<0>(expr), ctx), proto::eval(proto::arg_c<1>(expr), ctx);
                 }
             };
 
- #define BOOST_PROTO_EVAL_N_TYPE(Z, N, Data)\
- typename proto::result_of::eval<\
- typename proto::result_of::arg_c<BOOST_PP_TUPLE_ELEM(2, 0, Data), N>::type\
- , BOOST_PP_TUPLE_ELEM(2, 1, Data)\
- >::type
+ // Handle function specially
+ #define EVAL_TYPE(Z, N, DATA) \
+ typename proto::result_of::eval< \
+ typename remove_reference<typename proto::result_of::arg_c<DATA, N>::type>::type\
+ , Context \
+ >::type
 
- #define BOOST_PROTO_EVAL_N(Z, N, Data)\
- proto::eval(proto::arg_c<N>(BOOST_PP_TUPLE_ELEM(2, 0, Data)), BOOST_PP_TUPLE_ELEM(2, 1, Data))
+ #define EVAL(Z, N, DATA) \
+ proto::eval(proto::arg_c<N>(DATA), context)
 
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/context/default.hpp>))
- #include BOOST_PP_ITERATE()
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/context/default.hpp>))
+ #include BOOST_PP_ITERATE()
 
- #undef BOOST_PROTO_EVAL_N_TYPE
- #undef BOOST_PROTO_EVAL_N
+ #undef EVAL_TYPE
+ #undef EVAL
 
             /// default_context
             ///
@@ -349,8 +362,7 @@
 
     }} // namespace boost::proto
 
- #undef BOOST_PROTO_DECLTYPE_NESTED_TYPEDEF_TPL_
- #undef BOOST_PROTO_DECLTYPE_
+ #undef UNREF
 
     #endif
 
@@ -358,29 +370,22 @@
 
     #define N BOOST_PP_ITERATION()
 
- // Handle function specially
         template<typename Expr, typename Context>
         struct default_eval<Expr, Context, proto::tag::function, N>
         {
             typedef
- typename detail::result_of_fixup<
- BOOST_PROTO_EVAL_N_TYPE(1, 0, (Expr, Context))
- >::type
+ typename proto::detail::result_of_fixup<EVAL_TYPE(~, 0, Expr)>::type
             function_type;
 
             typedef
                 typename boost::result_of<
- function_type(
- BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_EVAL_N_TYPE, (Expr, Context))
- )
+ function_type(BOOST_PP_ENUM_SHIFTED(BOOST_PP_MAX(N, 1), EVAL_TYPE, Expr))
>::type
             result_type;
 
             result_type operator ()(Expr &expr, Context &context) const
             {
- return BOOST_PROTO_EVAL_N(1, 0, (expr, context))(
- BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_EVAL_N, (expr, context))
- );
+ return EVAL(~, 0, expr)(BOOST_PP_ENUM_SHIFTED(BOOST_PP_MAX(N, 1), EVAL, expr));
             }
         };
 

Modified: branches/release/boost/xpressive/proto/context/null.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/context/null.hpp (original)
+++ branches/release/boost/xpressive/proto/context/null.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -5,7 +5,7 @@
     /// proto::eval() that simply evaluates each child expression, doesn't
     /// combine the results at all, and returns void.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -23,7 +23,11 @@
     namespace boost { namespace proto { namespace context
     {
 
- template<typename Expr, typename Context, long Arity>
+ template<
+ typename Expr
+ , typename Context
+ , long Arity BOOST_PROTO_FOR_DOXYGEN_ONLY(= Expr::proto_arity::value)
+ >
         struct null_eval
         {};
 
@@ -74,7 +78,7 @@
 
             void operator ()(Expr &expr, Context &ctx) const
             {
- BOOST_PP_REPEAT(N, BOOST_PROTO_EVAL_N, ~)
+ BOOST_PP_REPEAT(N, BOOST_PROTO_EVAL_N, ~)
             }
         };
 

Modified: branches/release/boost/xpressive/proto/debug.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/debug.hpp (original)
+++ branches/release/boost/xpressive/proto/debug.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,8 +1,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file debug.hpp
-/// Utilities for debugging proto expression trees
+/// Utilities for debugging Proto expression trees
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -54,17 +54,19 @@
             {};
         }
 
+ /// INTERNAL ONLY
         template<typename Tag>
         inline typename hidden_detail_::printable_tag<Tag>::type proto_tag_name(Tag)
         {
             return hidden_detail_::printable_tag<Tag>::call();
         }
 
- #define BOOST_PROTO_DEFINE_TAG_NAME(Tag)\
- inline char const *proto_tag_name(tag::Tag)\
- {\
- return #Tag;\
- }\
+ #define BOOST_PROTO_DEFINE_TAG_NAME(Tag) \
+ /** \brief INTERNAL ONLY */ \
+ inline char const *proto_tag_name(tag::Tag) \
+ { \
+ return #Tag; \
+ } \
         /**/
 
         BOOST_PROTO_DEFINE_TAG_NAME(posit)
@@ -117,17 +119,30 @@
 
     namespace functional
     {
- // Display a proto expression tree
+ /// \brief Pretty-print a Proto expression tree.
+ ///
+ /// A PolymorphicFunctionObject which accepts a Proto expression
+ /// tree and pretty-prints it to an \c ostream for debugging
+ /// purposes.
         struct display_expr
         {
+ typedef void result_type;
+
+ /// \param depth The starting indentation depth for this node.
+ /// Children nodes will be displayed at a starting
+ /// depth of <tt>depth+4</tt>.
+ /// \param sout The \c ostream to which the expression tree
+ /// will be written.
             display_expr(int depth = 0, std::ostream &sout = std::cout)
               : depth_(depth)
               , first_(true)
               , sout_(sout)
             {}
 
+ /// \brief Pretty-print the current node in a Proto expression
+ /// tree.
             template<typename Args>
- void operator()(expr<tag::terminal, Args, 0> const &expr) const
+ void operator()(proto::expr<tag::terminal, Args, 0> const &expr) const
             {
                 this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ")
                     << "terminal(" << proto::arg(expr) << ")\n";
@@ -139,8 +154,9 @@
             /**/
 
         #define BOOST_PP_LOCAL_MACRO(N) \
+ /** \overload */ \
             template<typename Tag, typename Args> \
- void operator()(expr<Tag, Args, N> const &expr) const \
+ void operator()(proto::expr<Tag, Args, N> const &expr) const \
             { \
                 using namespace tag; \
                 this->sout_ << std::setw(this->depth_) << (this->first_? "" : ", ") \
@@ -156,6 +172,8 @@
         #include BOOST_PP_LOCAL_ITERATE()
         #undef BOOST_PROTO_ARG
 
+ /// \overload
+ ///
             template<typename T>
             void operator()(T const &t) const
             {
@@ -163,22 +181,32 @@
             }
 
         private:
+ display_expr &operator =(display_expr const &);
             int depth_;
             mutable bool first_;
             std::ostream &sout_;
         };
     }
 
+ /// \brief Pretty-print a Proto expression tree.
+ ///
+ /// \note Equivalent to <tt>functional::display_expr(0, sout)(expr)</tt>
+ /// \param expr The Proto expression tree to pretty-print
+ /// \param sout The \c ostream to which the output should be
+ /// written. If not specified, defaults to
+ /// <tt>std::cout</tt>.
     template<typename Expr>
- void display_expr(Expr const &expr)
+ void display_expr(Expr const &expr, std::ostream &sout)
     {
- functional::display_expr()(expr);
+ functional::display_expr(0, sout)(expr);
     }
 
+ /// \overload
+ ///
     template<typename Expr>
- void display_expr(Expr const &expr, std::ostream &sout)
+ void display_expr(Expr const &expr)
     {
- functional::display_expr(0, sout)(expr);
+ functional::display_expr()(expr);
     }
 
 }}

Modified: branches/release/boost/xpressive/proto/deep_copy.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/deep_copy.hpp (original)
+++ branches/release/boost/xpressive/proto/deep_copy.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
     /// \file deep_copy.hpp
     /// Replace all nodes stored by reference by nodes stored by value.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -12,12 +12,12 @@
 
     #include <boost/xpressive/proto/detail/prefix.hpp>
     #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/enum.hpp>
- #include <boost/preprocessor/iterate.hpp>
- #include <boost/call_traits.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/type_traits/is_function.hpp>
     #include <boost/xpressive/proto/proto_fwd.hpp>
     #include <boost/xpressive/proto/expr.hpp>
- #include <boost/xpressive/proto/generate.hpp>
     #include <boost/xpressive/proto/detail/suffix.hpp>
 
     namespace boost { namespace proto
@@ -30,7 +30,16 @@
             template<typename Expr>
             struct deep_copy_impl<Expr, 0>
             {
- typedef typename terminal<typename result_of::arg<Expr>::type>::type expr_type;
+ typedef BOOST_PROTO_UNCVREF(typename Expr::proto_arg0) raw_terminal_type;
+ // can't store a function type in a terminal.
+ typedef
+ typename mpl::if_<
+ is_function<raw_terminal_type>
+ , typename Expr::proto_arg0
+ , raw_terminal_type
+ >::type
+ actual_terminal_type;
+ typedef typename terminal<actual_terminal_type>::type expr_type;
                 typedef typename Expr::proto_domain::template apply<expr_type>::type type;
 
                 template<typename Expr2>
@@ -43,33 +52,74 @@
 
         namespace result_of
         {
+ /// \brief A metafunction for calculating the return type
+ /// of \c proto::deep_copy().
+ ///
+ /// A metafunction for calculating the return type
+ /// of \c proto::deep_copy(). The type parameter \c Expr
+ /// should be the type of a Proto expression tree.
+ /// It should not be a reference type, nor should it
+ /// be cv-qualified.
             template<typename Expr>
             struct deep_copy
- : detail::deep_copy_impl<Expr>
- {};
+ {
+ typedef typename detail::deep_copy_impl<Expr>::type type;
+ };
         }
 
         namespace functional
         {
+ /// \brief A PolymorphicFunctionObject type for deep-copying
+ /// Proto expression trees.
+ ///
+ /// A PolymorphicFunctionObject type for deep-copying
+ /// Proto expression trees. When a tree is deep-copied,
+ /// all internal nodes and most terminals held by reference
+ /// are instead held by value.
+ ///
+ /// \attention Terminals of reference-to-function type are
+ /// left unchanged. Terminals of reference-to-array type are
+ /// stored by value, which can cause a large amount of data
+ /// to be passed by value and stored on the stack.
             struct deep_copy
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
                 struct result;
 
                 template<typename This, typename Expr>
                 struct result<This(Expr)>
- : result_of::deep_copy<typename detail::remove_cv_ref<Expr>::type>
- {};
-
+ {
+ typedef
+ typename result_of::deep_copy<BOOST_PROTO_UNCVREF(Expr)>::type
+ type;
+ };
+
+ /// \brief Deep-copies a Proto expression tree, turning all
+ /// nodes and terminals held by reference into ones held by
+ /// value.
                 template<typename Expr>
                 typename result_of::deep_copy<Expr>::type
                 operator()(Expr const &expr) const
                 {
- return result_of::deep_copy<Expr>::call(expr);
+ return proto::detail::deep_copy_impl<Expr>::call(expr);
                 }
             };
         }
 
+ /// \brief A PolymorphicFunctionObject for deep-copying
+ /// Proto expression trees.
+ ///
+ /// A PolymorphicFunctionObject for deep-copying
+ /// Proto expression trees. When a tree is deep-copied,
+ /// all internal nodes and most terminals held by reference
+ /// are instead held by value.
+ ///
+ /// \attention Terminals of reference-to-array type and of
+ /// reference-to-function type are left unchanged.
+ ///
+ /// \sa proto::functional::deep_copy.
         functional::deep_copy const deep_copy = {};
 
         namespace detail
@@ -98,9 +148,15 @@
             template<typename Expr>
             struct deep_copy_impl<Expr, N>
             {
- typedef expr<typename Expr::proto_tag, BOOST_PP_CAT(args, N)<
- BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
- > > expr_type;
+ typedef
+ proto::expr<
+ typename Expr::proto_tag
+ , BOOST_PP_CAT(args, N)<
+ BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
+ >
+ >
+ expr_type;
+
                 typedef typename Expr::proto_domain::template apply<expr_type>::type type;
 
                 template<typename Expr2>
@@ -109,6 +165,7 @@
                     expr_type that = {
                         BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~)
                     };
+
                     return Expr::proto_domain::make(that);
                 }
             };

Added: branches/release/boost/xpressive/proto/detail/as_lvalue.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/detail/as_lvalue.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,36 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file as_lvalue.hpp
+/// Contains definition the as_lvalue() and uncv() functions.
+//
+// Copyright 2008 Eric Niebler. 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)
+
+#ifndef BOOST_PROTO_TRANSFORM_AS_LVALUE_HPP_EAN_12_27_2007
+#define BOOST_PROTO_TRANSFORM_AS_LVALUE_HPP_EAN_12_27_2007
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename T>
+ T &as_lvalue(T &t)
+ {
+ return t;
+ }
+
+ template<typename T>
+ T const &as_lvalue(T const &t)
+ {
+ return t;
+ }
+
+ template<typename T>
+ T &uncv(T const &t)
+ {
+ return const_cast<T &>(t);
+ }
+ }
+}}
+
+#endif

Added: branches/release/boost/xpressive/proto/detail/dont_care.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/detail/dont_care.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file dont_care.hpp
+/// Definintion of dont_care, a dummy parameter
+//
+// Copyright 2008 Eric Niebler. 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)
+
+#ifndef BOOST_PROTO_DETAIL_DONT_CARE_HPP_EAN_11_07_2007
+#define BOOST_PROTO_DETAIL_DONT_CARE_HPP_EAN_11_07_2007
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ struct dont_care
+ {
+ dont_care(...);
+ };
+ }
+}}
+
+#endif

Modified: branches/release/boost/xpressive/proto/detail/funop.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/detail/funop.hpp (original)
+++ branches/release/boost/xpressive/proto/detail/funop.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 // funop.hpp
 // Contains definition of funop[n]\<\> class template.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -10,10 +10,12 @@
 #error Do not include this file directly
 #endif
 
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
     template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A)>
     struct BOOST_PP_CAT(funop, BOOST_PP_ITERATION())
     {
- typedef expr<
+ typedef proto::expr<
             tag::function
           , BOOST_PP_CAT(args, BOOST_PP_INC(BOOST_PP_ITERATION()))<
                 ref_<Expr>
@@ -38,6 +40,8 @@
         }
     };
 
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
     template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A), typename This>
     struct funop<Expr(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), This>
       : BOOST_PP_CAT(funop, BOOST_PP_ITERATION())<
@@ -50,6 +54,8 @@
>
     {};
 
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
     template<typename Expr BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename A), typename This>
     struct funop<Expr const(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), A)), This>
       : BOOST_PP_CAT(funop, BOOST_PP_ITERATION())<

Added: branches/release/boost/xpressive/proto/detail/ignore_unused.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/detail/ignore_unused.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+/// \file ignore_unused.hpp
+/// Definintion of ignore_unused, a dummy function for suppressing compiler
+/// warnings
+//
+// Copyright 2008 Eric Niebler. 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)
+
+#ifndef BOOST_PROTO_DETAIL_IGNORE_UNUSED_HPP_EAN_03_03_2008
+#define BOOST_PROTO_DETAIL_IGNORE_UNUSED_HPP_EAN_03_03_2008
+
+namespace boost { namespace proto
+{
+ namespace detail
+ {
+ template<typename T>
+ inline void ignore_unused(T const &)
+ {}
+ }
+}}
+
+#endif

Added: branches/release/boost/xpressive/proto/detail/pop_front.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/detail/pop_front.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,43 @@
+/*=============================================================================
+ Copyright (c) 2001-2006 Joel de Guzman
+ Copyright (c) 2008 Eric Niebler
+
+ 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)
+==============================================================================*/
+#ifndef BOOST_PROTO_DETAIL_FUSION_POP_FRONT_EAH_01_22_2008
+#define BOOST_PROTO_DETAIL_FUSION_POP_FRONT_EAH_01_22_2008
+
+#include <boost/spirit/fusion/sequence/range.hpp>
+#include <boost/spirit/fusion/sequence/begin.hpp>
+#include <boost/spirit/fusion/sequence/end.hpp>
+#include <boost/spirit/fusion/iterator/next.hpp>
+
+namespace boost { namespace fusion
+{
+ namespace meta
+ {
+ template <typename Sequence>
+ struct pop_front
+ {
+ typedef
+ range<
+ typename next<
+ typename begin<Sequence>::type
+ >::type
+ , typename end<Sequence>::type
+ >
+ type;
+ };
+ }
+
+ template <typename Sequence>
+ inline typename meta::pop_front<Sequence const>::type
+ pop_front(Sequence const& seq)
+ {
+ typedef typename meta::pop_front<Sequence const>::type result;
+ return result(fusion::next(fusion::begin(seq)), fusion::end(seq));
+ }
+}}
+
+#endif

Modified: branches/release/boost/xpressive/proto/detail/prefix.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/detail/prefix.hpp (original)
+++ branches/release/boost/xpressive/proto/detail/prefix.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 ///////////////////////////////////////////////////////////////////////////////

Added: branches/release/boost/xpressive/proto/detail/reverse.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/detail/reverse.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,189 @@
+/*=============================================================================
+ Copyright (c) 2001-2006 Joel de Guzman
+ Copyright (c) 2008 Eric Niebler
+
+ 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)
+==============================================================================*/
+#ifndef BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
+#define BOOST_PROTO_DETAIL_FUSION_REVERSE_EAH_01_22_2008
+
+#include <boost/spirit/fusion/detail/access.hpp>
+#include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
+#include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
+#include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
+#include <boost/spirit/fusion/iterator/next.hpp>
+#include <boost/spirit/fusion/iterator/prior.hpp>
+#include <boost/spirit/fusion/iterator/deref.hpp>
+#include <boost/spirit/fusion/iterator/value_of.hpp>
+#include <boost/spirit/fusion/sequence/begin.hpp>
+#include <boost/spirit/fusion/sequence/end.hpp>
+
+namespace boost { namespace fusion
+{
+ struct reverse_view_tag;
+ struct reverse_view_iterator_tag;
+
+ template <typename First>
+ struct reverse_view_iterator
+ : iterator_base<reverse_view_iterator<First> >
+ {
+ typedef as_fusion_iterator<First> converter;
+ typedef typename converter::type first_type;
+ typedef reverse_view_iterator_tag tag;
+
+ reverse_view_iterator(First const& first)
+ : first(converter::convert(first)) {}
+
+ first_type first;
+ };
+
+ template <typename Sequence>
+ struct reverse_view : sequence_base<reverse_view<Sequence> >
+ {
+ typedef as_fusion_sequence<Sequence> seq_converter;
+ typedef typename seq_converter::type seq;
+
+ typedef reverse_view_tag tag;
+ typedef typename meta::begin<seq>::type first_type;
+ typedef typename meta::end<seq>::type last_type;
+
+ reverse_view(Sequence& seq)
+ : first(fusion::begin(seq))
+ , last(fusion::end(seq))
+ {}
+
+ first_type first;
+ last_type last;
+ };
+
+ namespace meta
+ {
+ template <>
+ struct deref_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename
+ meta::deref<
+ typename meta::prior<
+ typename Iterator::first_type
+ >::type
+ >::type
+ type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return *fusion::prior(i.first);
+ }
+ };
+ };
+
+ template <>
+ struct prior_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename Iterator::first_type first_type;
+ typedef typename next_impl<typename first_type::tag>::
+ template apply<first_type>
+ wrapped;
+
+ typedef reverse_view_iterator<typename wrapped::type> type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return type(wrapped::call(i.first));
+ }
+ };
+ };
+
+ template <>
+ struct next_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename Iterator::first_type first_type;
+ typedef typename prior_impl<typename first_type::tag>::
+ template apply<first_type>
+ wrapped;
+
+ typedef reverse_view_iterator<typename wrapped::type> type;
+
+ static type
+ call(Iterator const& i)
+ {
+ return type(wrapped::call(i.first));
+ }
+ };
+ };
+
+ template <>
+ struct value_impl<reverse_view_iterator_tag>
+ {
+ template <typename Iterator>
+ struct apply
+ {
+ typedef typename
+ meta::value_of<
+ typename meta::prior<
+ typename Iterator::first_type
+ >::type
+ >::type
+ type;
+ };
+ };
+
+ template <>
+ struct begin_impl<reverse_view_tag>
+ {
+ template <typename Sequence>
+ struct apply
+ {
+ typedef reverse_view_iterator<typename Sequence::last_type> type;
+
+ static type
+ call(Sequence const& s)
+ {
+ return type(s.last);
+ }
+ };
+ };
+
+ template <>
+ struct end_impl<reverse_view_tag>
+ {
+ template <typename Sequence>
+ struct apply
+ {
+ typedef reverse_view_iterator<typename Sequence::first_type> type;
+
+ static type
+ call(Sequence const& s)
+ {
+ return type(s.first);
+ }
+ };
+ };
+
+ template <typename Sequence>
+ struct reverse
+ {
+ typedef reverse_view<Sequence> type;
+ };
+ }
+
+ template <typename Sequence>
+ inline reverse_view<Sequence const>
+ reverse(Sequence const& view)
+ {
+ return reverse_view<Sequence const>(view);
+ }
+}}
+
+#endif

Modified: branches/release/boost/xpressive/proto/detail/suffix.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/detail/suffix.hpp (original)
+++ branches/release/boost/xpressive/proto/detail/suffix.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/release/boost/xpressive/proto/domain.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/domain.hpp (original)
+++ branches/release/boost/xpressive/proto/domain.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,9 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file domain.hpp
-/// Contains definition of domain\<\> class template, for defining domains
-/// with a grammar for controlling operator overloading.
+/// Contains definition of domain\<\> class template and helpers for
+/// defining domains with a generator and a grammar for controlling
+/// operator overloading.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -11,6 +12,7 @@
 #define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
 
 #include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/ref.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/xpressive/proto/proto_fwd.hpp>
 #include <boost/xpressive/proto/generate.hpp>
@@ -30,21 +32,75 @@
 
     namespace domainns_
     {
- template<typename Generator, typename Grammar>
+ /// \brief For use in defining domain tags to be used
+ /// with \c proto::extends\<\>. A \e Domain associates
+ /// an expression type with a \e Generator, and optionally
+ /// a \e Grammar.
+ ///
+ /// The Generator determines how new expressions in the
+ /// domain are constructed. Typically, a generator wraps
+ /// all new expressions in a wrapper that imparts
+ /// domain-specific behaviors to expressions within its
+ /// domain. (See \c proto::extends\<\>.)
+ ///
+ /// The Grammar determines whether a given expression is
+ /// valid within the domain, and automatically disables
+ /// any operator overloads which would cause an invalid
+ /// expression to be created. By default, the Grammar
+ /// parameter defaults to the wildcard, \c proto::_, which
+ /// makes all expressions valid within the domain.
+ ///
+ /// Example:
+ /// \code
+ /// template<typename Expr>
+ /// struct MyExpr;
+ ///
+ /// struct MyGrammar
+ /// : or_< terminal<_>, plus<MyGrammar, MyGrammar> >
+ /// {};
+ ///
+ /// // Define MyDomain, in which all expressions are
+ /// // wrapped in MyExpr<> and only expressions that
+ /// // conform to MyGrammar are allowed.
+ /// struct MyDomain
+ /// : domain<generator<MyExpr>, MyGrammar>
+ /// {};
+ ///
+ /// // Use MyDomain to define MyExpr
+ /// template<typename Expr>
+ /// struct MyExpr
+ /// : extends<Expr, MyExpr<Expr>, MyDomain>
+ /// {
+ /// // ...
+ /// };
+ /// \endcode
+ ///
+ template<
+ typename Generator BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_generator)
+ , typename Grammar BOOST_PROTO_FOR_DOXYGEN_ONLY(= proto::_)
+ >
         struct domain
           : Generator
         {
- typedef Grammar grammar;
-
- /// INTERNAL ONLY
- ///
+ typedef Grammar proto_grammar;
             typedef void proto_is_domain_;
         };
 
+ /// \brief The domain expressions have by default, if
+ /// \c proto::extends\<\> has not been used to associate
+ /// a domain with an expression.
+ ///
         struct default_domain
           : domain<>
         {};
 
+ /// \brief A pseudo-domain for use in functions and
+ /// metafunctions that require a domain parameter. It
+ /// indicates that the domain of the parent node should
+ /// be inferred from the domains of the children nodes.
+ ///
+ /// \attention \c deduce_domain is not itself a valid domain.
+ ///
         struct deduce_domain
           : domain<detail::not_a_generator, detail::not_a_grammar>
         {};
@@ -52,27 +108,65 @@
 
     namespace result_of
     {
- template<typename T, typename EnableIf>
+ /// A metafunction that returns \c mpl::true_
+ /// if the type \c T is the type of a Proto domain;
+ /// \c mpl::false_ otherwise. If \c T inherits from
+ /// \c proto::domain\<\>, \c is_domain\<T\> is
+ /// \c mpl::true_.
+ template<typename T, typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)>
         struct is_domain
           : mpl::false_
         {};
 
+ /// INTERNAL ONLY
+ ///
         template<typename T>
         struct is_domain<T, typename T::proto_is_domain_>
           : mpl::true_
         {};
 
- template<typename T, typename EnableIf>
+ /// A metafunction that returns the domain of
+ /// a given type. If \c T is a Proto expression
+ /// type, it returns that expression's associated
+ /// domain. If not, it returns
+ /// \c proto::default_domain.
+ template<typename T, typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)>
         struct domain_of
         {
             typedef default_domain type;
         };
 
+ /// INTERNAL ONLY
+ ///
         template<typename T>
         struct domain_of<T, typename T::proto_is_expr_>
         {
             typedef typename T::proto_domain type;
         };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<T &, void>
+ {
+ typedef typename domain_of<T>::type type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<boost::reference_wrapper<T>, void>
+ {
+ typedef typename domain_of<T>::type type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct domain_of<boost::reference_wrapper<T> const, void>
+ {
+ typedef typename domain_of<T>::type type;
+ };
     }
 }}
 

Modified: branches/release/boost/xpressive/proto/eval.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/eval.hpp (original)
+++ branches/release/boost/xpressive/proto/eval.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file eval.hpp
 /// Contains the eval() expression evaluator.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -10,6 +10,7 @@
 #define BOOST_PROTO_EVAL_HPP_EAN_03_29_2007
 
 #include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
+#include <boost/xpressive/proto/proto_fwd.hpp> // BOOST_PROTO_CALLABLE
 #include <boost/type_traits/remove_reference.hpp>
 #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
 
@@ -18,6 +19,13 @@
 
     namespace result_of
     {
+ /// \brief A metafunction for calculating the return type
+ /// of \c proto::eval() given a certain \c Expr and \c Context
+ /// types.
+ ///
+ /// \note The types \c Expr and \c Context should not be
+ /// reference types. They may be cv-qualified, but the
+ /// cv-qualification on the \c Context parameter is ignored.
         template<typename Expr, typename Context>
         struct eval
         {
@@ -27,19 +35,33 @@
 
     namespace functional
     {
+ /// \brief A PolymorphicFunctionObject type for
+ /// evaluating a given Proto expression with a given
+ /// context.
         struct eval
         {
+ BOOST_PROTO_CALLABLE()
+
             template<typename Sig>
             struct result;
 
             template<typename This, typename Expr, typename Context>
             struct result<This(Expr, Context)>
- : proto::result_of::eval<
- typename remove_reference<Expr>::type
- , typename remove_reference<Context>::type
- >
- {};
-
+ {
+ typedef
+ typename proto::result_of::eval<
+ typename remove_reference<Expr>::type
+ , typename remove_reference<Context>::type
+ >::type
+ type;
+ };
+
+ /// \brief Evaluate a given Proto expression with a given
+ /// context.
+ /// \param expr The Proto expression to evaluate
+ /// \param context The context in which the expression should be
+ /// evaluated.
+ /// \return <tt>typename Context::template eval<Expr>()(expr, context)</tt>
             template<typename Expr, typename Context>
             typename proto::result_of::eval<Expr, Context>::type
             operator ()(Expr &expr, Context &context) const
@@ -47,6 +69,8 @@
                 return typename Context::template eval<Expr>()(expr, context);
             }
 
+ /// \overload
+ ///
             template<typename Expr, typename Context>
             typename proto::result_of::eval<Expr, Context>::type
             operator ()(Expr &expr, Context const &context) const
@@ -56,6 +80,11 @@
         };
     }
 
+ /// \brief A PolymorphicFunctionObject for
+ /// evaluating a given Proto expression with
+ /// a given context.
+ ///
+ /// \sa proto::functional::eval.
     functional::eval const eval = {};
 }}
 

Modified: branches/release/boost/xpressive/proto/expr.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/expr.hpp (original)
+++ branches/release/boost/xpressive/proto/expr.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
     /// \file expr.hpp
     /// Contains definition of expr\<\> class template.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -12,11 +12,9 @@
 
     #include <boost/xpressive/proto/detail/prefix.hpp>
     #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/arithmetic/inc.hpp>
     #include <boost/preprocessor/arithmetic/dec.hpp>
     #include <boost/preprocessor/selection/max.hpp>
     #include <boost/preprocessor/iteration/iterate.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
     #include <boost/preprocessor/repetition/repeat_from_to.hpp>
     #include <boost/preprocessor/repetition/enum_trailing.hpp>
@@ -24,7 +22,6 @@
     #include <boost/preprocessor/repetition/enum_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
- #include <boost/utility/result_of.hpp>
     #include <boost/utility/addressof.hpp>
     #include <boost/xpressive/proto/proto_fwd.hpp>
     #include <boost/xpressive/proto/ref.hpp>
@@ -41,39 +38,40 @@
 
     namespace boost { namespace proto
     {
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_ARG(z, n, data)\
- typedef typename Args::BOOST_PP_CAT(arg, n) BOOST_PP_CAT(proto_arg, n);\
- BOOST_PP_CAT(proto_arg, n) BOOST_PP_CAT(arg, n);\
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_VOID(z, n, data)\
- typedef void BOOST_PP_CAT(proto_arg, n);\
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_AS_OP(z, n, data)\
- proto::as_arg(BOOST_PP_CAT(a,n))\
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_UNREF_ARG_TYPE(z, n, data)\
- typename result_of::unref<typename Args::BOOST_PP_CAT(arg, n)>::const_reference\
- /**/
-
- /// INTERNAL ONLY
- ///
- #define BOOST_PROTO_UNREF_ARG(z, n, data)\
- proto::unref(this->BOOST_PP_CAT(arg, n))\
- /**/
 
         namespace detail
         {
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_ARG(z, n, data) \
+ typedef typename Args::BOOST_PP_CAT(arg, n) BOOST_PP_CAT(proto_arg, n); \
+ BOOST_PP_CAT(proto_arg, n) BOOST_PP_CAT(arg, n); \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_VOID(z, n, data) \
+ typedef void BOOST_PP_CAT(proto_arg, n); \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_AS_OP(z, n, data) \
+ proto::as_arg(BOOST_PP_CAT(a,n)) \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNREF_ARG_TYPE(z, n, data) \
+ typename result_of::unref<typename Args::BOOST_PP_CAT(arg, n)>::const_reference \
+ /**/
+
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNREF_ARG(z, n, data) \
+ proto::unref(this->BOOST_PP_CAT(arg, n)) \
+ /**/
+
             template<typename Tag, typename Arg>
             struct address_of_hack
             {
@@ -81,7 +79,7 @@
             };
 
             template<typename Expr>
- struct address_of_hack<tag::address_of, ref_<Expr> >
+ struct address_of_hack<proto::tag::address_of, ref_<Expr> >
             {
                 typedef Expr *type;
             };
@@ -108,24 +106,26 @@
 
         namespace result_of
         {
+ /// \brief A helper metafunction for computing the
+ /// return type of \c proto::expr\<\>::operator().
             template<typename Sig, typename This>
             struct funop;
 
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY), <boost/xpressive/proto/detail/funop.hpp>))
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/xpressive/proto/detail/funop.hpp>))
         #include BOOST_PP_ITERATE()
         }
 
         namespace exprns_
         {
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/expr.hpp>))
- #include BOOST_PP_ITERATE()
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/expr.hpp>))
+ #include BOOST_PP_ITERATE()
         }
 
- #undef BOOST_PROTO_ARG
- #undef BOOST_PROTO_VOID
- #undef BOOST_PROTO_AS_OP
- #undef BOOST_PROTO_UNREF_ARG_TYPE
- #undef BOOST_PROTO_UNREF_ARG
+ #undef BOOST_PROTO_ARG
+ #undef BOOST_PROTO_VOID
+ #undef BOOST_PROTO_AS_OP
+ #undef BOOST_PROTO_UNREF_ARG_TYPE
+ #undef BOOST_PROTO_UNREF_ARG
     }}
 
     #if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -140,11 +140,11 @@
     #define IS_TERMINAL 0 == BOOST_PP_ITERATION()
 
         /// \brief Representation of a node in an expression tree.
- ///
+ ///
         /// \c proto::expr\<\> is a node in an expression template tree. It
         /// is a container for its children sub-trees. It also serves as
         /// the terminal nodes of the tree.
- ///
+ ///
         /// \c Tag is type that represents the operation encoded by
         /// this expression. It is typically one of the structs
         /// in the \c boost::proto::tag namespace, but it doesn't
@@ -154,12 +154,15 @@
         ///
         /// \c Args is a type list representing the type of the children
         /// of this expression. It is an instantiation of one
- /// of \c proto::args1\<\>, \c proto::args2\<\>, etc. The
+ /// of \c proto::args1\<\>, \c proto::args2\<\>, etc. The
         /// children types must all themselves be either \c expr\<\>
         /// or \c proto::ref_\<proto::expr\<\>\>, unless the \c Tag
         /// type is \c boost::proto::tag::terminal, in which case
- /// \c Args must be \c proto::args1\<T\>, where \c T can be any
+ /// \c Args must be \c proto::args0\<T\>, where \c T can be any
         /// type.
+ ///
+ /// \c proto::expr\<\> is a valid Fusion random-access sequence, where
+ /// the elements of the sequence are the children expressions.
         template<typename Tag, typename Args>
         struct expr<Tag, Args, BOOST_PP_ITERATION() >
         {
@@ -168,11 +171,10 @@
             typedef expr proto_base_expr;
             typedef Args proto_args;
             typedef default_domain proto_domain;
- typedef tag::proto_expr fusion_tag;
+ BOOST_PROTO_DEFINE_FUSION_TAG(proto::tag::proto_expr)
             typedef void proto_is_expr_;
             typedef expr proto_derived_expr;
 
- BOOST_PROTO_IDENTITY_TRANSFORM();
             BOOST_PP_REPEAT(ARG_COUNT, BOOST_PROTO_ARG, ~)
             BOOST_PP_REPEAT_FROM_TO(ARG_COUNT, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_VOID, ~)
 
@@ -255,20 +257,20 @@
             /// \param a The rhs.
             /// \return A new \c expr\<\> node representing an assignment of \c a to \c *this.
             template<typename A>
- expr<tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > const
+ proto::expr<proto::tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > const
             operator =(A &a) const
             {
- expr<tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
 
             /// \overload
             ///
             template<typename A>
- expr<tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > const
+ proto::expr<proto::tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > const
             operator =(A const &a) const
             {
- expr<tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::assign, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
 
@@ -276,20 +278,20 @@
             /// \overload
             ///
             template<typename A>
- expr<tag::assign, args2<ref_<expr>, typename result_of::as_arg<A>::type> > const
+ proto::expr<proto::tag::assign, args2<ref_<expr>, typename result_of::as_arg<A>::type> > const
             operator =(A &a)
             {
- expr<tag::assign, args2<ref_<expr>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::assign, args2<ref_<expr>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
 
             /// \overload
             ///
             template<typename A>
- expr<tag::assign, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > const
+ proto::expr<proto::tag::assign, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > const
             operator =(A const &a)
             {
- expr<tag::assign, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::assign, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
         #endif
@@ -299,20 +301,20 @@
             /// \param a The rhs.
             /// \return A new \c expr\<\> node representing \c *this subscripted with \c a.
             template<typename A>
- expr<tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > const
+ proto::expr<proto::tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > const
             operator [](A &a) const
             {
- expr<tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
 
             /// \overload
             ///
             template<typename A>
- expr<tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > const
+ proto::expr<proto::tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > const
             operator [](A const &a) const
             {
- expr<tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::subscript, args2<ref_<expr const>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
 
@@ -320,20 +322,20 @@
             /// \overload
             ///
             template<typename A>
- expr<tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A>::type> > const
+ proto::expr<proto::tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A>::type> > const
             operator [](A &a)
             {
- expr<tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
 
             /// \overload
             ///
             template<typename A>
- expr<tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > const
+ proto::expr<proto::tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > const
             operator [](A const &a)
             {
- expr<tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
+ proto::expr<proto::tag::subscript, args2<ref_<expr>, typename result_of::as_arg<A const>::type> > that = {{*this}, proto::as_arg(a)};
                 return that;
             }
         #endif
@@ -349,25 +351,25 @@
             /// Function call
             ///
             /// \return A new \c expr\<\> node representing the function invocation of \c (*this)().
- expr<tag::function, args1<ref_<expr const> > > const
+ proto::expr<proto::tag::function, args1<ref_<expr const> > > const
             operator ()() const
             {
- expr<tag::function, args1<ref_<expr const> > > that = {{*this}};
+ proto::expr<proto::tag::function, args1<ref_<expr const> > > that = {{*this}};
                 return that;
             }
 
         #if IS_TERMINAL
             /// \overload
             ///
- expr<tag::function, args1<ref_<expr> > > const
+ proto::expr<proto::tag::function, args1<ref_<expr> > > const
             operator ()()
             {
- expr<tag::function, args1<ref_<expr> > > that = {{*this}};
+ proto::expr<proto::tag::function, args1<ref_<expr> > > that = {{*this}};
                 return that;
             }
         #endif
 
- #define BOOST_PP_ITERATION_PARAMS_2 (3, (1, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY), <boost/xpressive/proto/expr.hpp>))
+ #define BOOST_PP_ITERATION_PARAMS_2 (3, (1, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY), <boost/xpressive/proto/expr.hpp>))
     #include BOOST_PP_ITERATE()
         };
 

Modified: branches/release/boost/xpressive/proto/extends.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/extends.hpp (original)
+++ branches/release/boost/xpressive/proto/extends.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file extends.hpp
 /// Macros and a base class for defining end-user expression types
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -15,9 +15,10 @@
 #include <boost/preprocessor/arithmetic/inc.hpp>
 #include <boost/preprocessor/arithmetic/dec.hpp>
 #include <boost/preprocessor/iteration/local.hpp>
-#include <boost/preprocessor/facilities/intercept.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
 #include <boost/mpl/apply_wrap.hpp>
 #include <boost/xpressive/proto/proto_fwd.hpp>
@@ -48,175 +49,266 @@
 
     /// INTERNAL ONLY
     ///
- #define BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, Data, Const)\
- BOOST_PP_IF(N, BOOST_PROTO_TEMPLATE_YES_, BOOST_PROTO_TEMPLATE_NO_)(Z, N)\
- typename boost::mpl::apply_wrap1<\
- BOOST_PP_TUPLE_ELEM(3, 2, Data)\
- , typename boost::proto::result_of::BOOST_PP_CAT(funop, N)<\
- BOOST_PP_TUPLE_ELEM(3, 1, Data) BOOST_PROTO_CONST ## Const\
- BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A)\
- >::type\
- >::type const\
- operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) BOOST_PROTO_CONST ## Const\
- {\
- typedef boost::proto::result_of::BOOST_PP_CAT(funop, N)<\
- BOOST_PP_TUPLE_ELEM(3, 1, Data) BOOST_PROTO_CONST ## Const\
- BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A)\
- > funop;\
- return BOOST_PP_TUPLE_ELEM(3, 2, Data)::make(\
- funop::call(*static_cast<BOOST_PP_TUPLE_ELEM(3, 1, Data) BOOST_PROTO_CONST ## Const *>(this) BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, a))\
- );\
- }\
+ #define BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, Data, Const) \
+ BOOST_PP_IF(N, BOOST_PROTO_TEMPLATE_YES_, BOOST_PROTO_TEMPLATE_NO_)(Z, N) \
+ typename boost::mpl::apply_wrap1< \
+ BOOST_PP_TUPLE_ELEM(3, 2, Data) \
+ , typename boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
+ BOOST_PP_TUPLE_ELEM(3, 1, Data) BOOST_PROTO_CONST ## Const \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
+ >::type \
+ >::type const \
+ operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::result_of::BOOST_PP_CAT(funop, N)< \
+ BOOST_PP_TUPLE_ELEM(3, 1, Data) BOOST_PROTO_CONST ## Const \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, const A) \
+ > funop; \
+ return BOOST_PP_TUPLE_ELEM(3, 2, Data)::make( \
+ funop::call( \
+ *static_cast<BOOST_PP_TUPLE_ELEM(3, 1, Data) BOOST_PROTO_CONST ## Const *>(this)\
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, a) \
+ ) \
+ ); \
+ } \
         /**/
 
     /// INTERNAL ONLY
     ///
- #define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, Data)\
+ #define BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, Data) \
         BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, Data, 1)
 
     /// INTERNAL ONLY
     ///
- #define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, Data)\
+ #define BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, Data) \
         BOOST_PROTO_DEFINE_FUN_OP_IMPL_(Z, N, Data, 0)
 
     /// INTERNAL ONLY
     ///
- #define BOOST_PROTO_DEFINE_FUN_OP(Z, N, Data)\
- BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, Data)\
- BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, Data)\
+ #define BOOST_PROTO_DEFINE_FUN_OP(Z, N, Data) \
+ BOOST_PROTO_DEFINE_FUN_OP_CONST(Z, N, Data) \
+ BOOST_PROTO_DEFINE_FUN_OP_NON_CONST(Z, N, Data) \
         /**/
 
     /// INTERNAL ONLY
     ///
- #define BOOST_PROTO_EXTENDS_ARG(z, n, Expr)\
- typedef\
- typename Expr::BOOST_PP_CAT(proto_arg, n)\
- BOOST_PP_CAT(proto_arg, n);\
- /**/
-
- #define BOOST_PROTO_EXTENDS(Expr, Derived, Domain)\
- Expr expr;\
- \
- typedef Expr proto_base_expr;\
- typedef Domain proto_domain;\
- typedef Derived proto_derived_expr;\
- typedef typename Expr::proto_tag proto_tag;\
- typedef typename Expr::proto_args proto_args;\
- typedef typename Expr::proto_arity proto_arity;\
- typedef void proto_is_expr_;\
- typedef boost::proto::tag::proto_expr fusion_tag;\
- \
- BOOST_PROTO_IDENTITY_TRANSFORM();\
- BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_ARG, Expr)\
- \
- static Derived const make(Expr const &expr)\
- {\
- Derived that = {expr};\
- return that;\
- }\
- \
- Expr &proto_base()\
- {\
- return this->expr;\
- }\
- \
- Expr const &proto_base() const\
- {\
- return this->expr;\
- }\
+ #define BOOST_PROTO_EXTENDS_ARG(z, n, Expr) \
+ typedef \
+ typename Expr::BOOST_PP_CAT(proto_arg, n) \
+ BOOST_PP_CAT(proto_arg, n); \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS(Expr, Derived, Domain) \
+ Expr expr; \
+ \
+ typedef Expr proto_base_expr; \
+ typedef Domain proto_domain; \
+ typedef Derived proto_derived_expr; \
+ typedef typename Expr::proto_tag proto_tag; \
+ typedef typename Expr::proto_args proto_args; \
+ typedef typename Expr::proto_arity proto_arity; \
+ typedef void proto_is_expr_; \
+ BOOST_PROTO_DEFINE_FUSION_TAG(boost::proto::tag::proto_expr) \
+ BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_ARG, Expr) \
+ \
+ static Derived const make(Expr const &expr) \
+ { \
+ Derived that = {expr}; \
+ return that; \
+ } \
+ \
+ Expr &proto_base() \
+ { \
+ return this->expr; \
+ } \
+ \
+ Expr const &proto_base() const \
+ { \
+ return this->expr; \
+ } \
         /**/
 
         /// INTERNAL ONLY
         ///
- #define BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, Const)\
- template<typename A>\
- typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::assign, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A>::type> > >::type const\
- operator =(A &a) BOOST_PROTO_CONST ## Const\
- {\
- typedef boost::proto::expr<boost::proto::tag::assign, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A>::type> > that_type;\
- that_type that = {{*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)}, boost::proto::as_arg(a)};\
- return Domain::make(that);\
- }\
- \
- template<typename A>\
- typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::assign, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A const>::type> > >::type const\
- operator =(A const &a) BOOST_PROTO_CONST ## Const\
- {\
- typedef boost::proto::expr<boost::proto::tag::assign, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A const>::type> > that_type;\
- that_type that = {{*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)}, boost::proto::as_arg(a)};\
- return Domain::make(that);\
- }\
+ #define BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, Const) \
+ template<typename A> \
+ typename boost::mpl::apply_wrap1< \
+ Domain \
+ , boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A>::type \
+ > \
+ > \
+ >::type const \
+ operator =(A &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ {*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)} \
+ , boost::proto::as_arg(a) \
+ }; \
+ return Domain::make(that); \
+ } \
+ \
+ template<typename A> \
+ typename boost::mpl::apply_wrap1< \
+ Domain \
+ , boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A const>::type \
+ > \
+ > \
+ >::type const \
+ operator =(A const &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::assign \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A const>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ {*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)} \
+ , boost::proto::as_arg(a) \
+ }; \
+ return Domain::make(that); \
+ } \
         /**/
 
- #define BOOST_PROTO_EXTENDS_ASSIGN_CONST(Expr, Derived, Domain)\
+ #define BOOST_PROTO_EXTENDS_ASSIGN_CONST(Expr, Derived, Domain) \
         BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, 1)
 
- #define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST(Expr, Derived, Domain)\
+ #define BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST(Expr, Derived, Domain) \
         BOOST_PROTO_EXTENDS_ASSIGN_IMPL_(Expr, Derived, Domain, 0)
 
- #define BOOST_PROTO_EXTENDS_ASSIGN(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_ASSIGN_CONST(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST(Expr, Derived, Domain)\
+ #define BOOST_PROTO_EXTENDS_ASSIGN(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_ASSIGN_CONST(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_ASSIGN_NON_CONST(Expr, Derived, Domain) \
         /**/
 
         /// INTERNAL ONLY
         ///
- #define BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, Const)\
- template<typename A>\
- typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::subscript, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A>::type> > >::type const\
- operator [](A &a) BOOST_PROTO_CONST ## Const\
- {\
- typedef boost::proto::expr<boost::proto::tag::subscript, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A>::type> > that_type;\
- that_type that = {{*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)}, boost::proto::as_arg(a)};\
- return Domain::make(that);\
- }\
- \
- template<typename A>\
- typename boost::mpl::apply_wrap1<Domain, boost::proto::expr<boost::proto::tag::subscript, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A const>::type> > >::type const\
- operator [](A const &a) BOOST_PROTO_CONST ## Const\
- {\
- typedef boost::proto::expr<boost::proto::tag::subscript, boost::proto::args2<boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const>, typename boost::proto::result_of::as_arg<A const>::type> > that_type;\
- that_type that = {{*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)}, boost::proto::as_arg(a)};\
- return Domain::make(that);\
- }\
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, Const) \
+ template<typename A> \
+ typename boost::mpl::apply_wrap1< \
+ Domain \
+ , boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A>::type \
+ > \
+ > \
+ >::type const \
+ operator [](A &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ {*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)} \
+ , boost::proto::as_arg(a) \
+ }; \
+ return Domain::make(that); \
+ } \
+ \
+ template<typename A> \
+ typename boost::mpl::apply_wrap1< \
+ Domain \
+ , boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A const>::type \
+ > \
+ > \
+ >::type const \
+ operator [](A const &a) BOOST_PROTO_CONST ## Const \
+ { \
+ typedef boost::proto::expr< \
+ boost::proto::tag::subscript \
+ , boost::proto::args2< \
+ boost::proto::ref_<Derived BOOST_PROTO_CONST ## Const> \
+ , typename boost::proto::result_of::as_arg<A const>::type \
+ > \
+ > that_type; \
+ that_type that = { \
+ {*static_cast<Derived BOOST_PROTO_CONST ## Const *>(this)} \
+ , boost::proto::as_arg(a) \
+ }; \
+ return Domain::make(that); \
+ } \
         /**/
 
- #define BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST(Expr, Derived, Domain)\
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST(Expr, Derived, Domain) \
         BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, 1)
 
- #define BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST(Expr, Derived, Domain)\
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST(Expr, Derived, Domain) \
         BOOST_PROTO_EXTENDS_SUBSCRIPT_IMPL_(Expr, Derived, Domain, 0)
 
- #define BOOST_PROTO_EXTENDS_SUBSCRIPT(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST(Expr, Derived, Domain)\
+ #define BOOST_PROTO_EXTENDS_SUBSCRIPT(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_SUBSCRIPT_NON_CONST(Expr, Derived, Domain) \
         /**/
 
         /// INTERNAL ONLY
         ///
- #define BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain)\
- template<typename Sig>\
- struct result\
- {\
- typedef\
- typename boost::mpl::apply_wrap1<Domain, typename boost::proto::result_of::funop<Sig, Derived >::type>::type\
- type;\
- };\
- /**/
-
- #define BOOST_PROTO_EXTENDS_FUNCTION_CONST(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain)\
- BOOST_PP_REPEAT_FROM_TO(0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY), BOOST_PROTO_DEFINE_FUN_OP_CONST, (Expr, Derived, Domain))\
- /**/
-
- #define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain)\
- BOOST_PP_REPEAT_FROM_TO(0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY), BOOST_PROTO_DEFINE_FUN_OP_NON_CONST, (Expr, Derived, Domain))\
- /**/
-
- #define BOOST_PROTO_EXTENDS_FUNCTION(Expr, Derived, Domain)\
- BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain)\
- BOOST_PP_REPEAT_FROM_TO(0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY), BOOST_PROTO_DEFINE_FUN_OP, (Expr, Derived, Domain))\
+ #define BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain) \
+ template<typename Sig> \
+ struct result \
+ { \
+ typedef \
+ typename boost::mpl::apply_wrap1< \
+ Domain \
+ , typename boost::proto::result_of::funop<Sig, Derived >::type \
+ >::type \
+ type; \
+ }; \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION_CONST(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain) \
+ BOOST_PP_REPEAT_FROM_TO( \
+ 0 \
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY) \
+ , BOOST_PROTO_DEFINE_FUN_OP_CONST \
+ , (Expr, Derived, Domain) \
+ ) \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION_NON_CONST(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain) \
+ BOOST_PP_REPEAT_FROM_TO( \
+ 0 \
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY) \
+ , BOOST_PROTO_DEFINE_FUN_OP_NON_CONST \
+ , (Expr, Derived, Domain) \
+ ) \
+ /**/
+
+ #define BOOST_PROTO_EXTENDS_FUNCTION(Expr, Derived, Domain) \
+ BOOST_PROTO_EXTENDS_FUNCTION_(Expr, Derived, Domain) \
+ BOOST_PP_REPEAT_FROM_TO( \
+ 0 \
+ , BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY) \
+ , BOOST_PROTO_DEFINE_FUN_OP \
+ , (Expr, Derived, Domain) \
+ ) \
         /**/
 
     namespace exprns_
@@ -249,9 +341,14 @@
         struct is_proto_expr
         {};
 
- /// \brief extends\<\> class template for adding behaviors to a proto expression template
+ /// \brief extends\<\> class template for adding behaviors to a Proto expression template
         ///
- template<typename Expr, typename Derived, typename Domain, typename Tag>
+ template<
+ typename Expr
+ , typename Derived
+ , typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain)
+ , typename Tag BOOST_PROTO_FOR_DOXYGEN_ONLY(= typename Expr::proto_tag)
+ >
         struct extends
         {
             extends()
@@ -277,17 +374,17 @@
 
             /// INTERNAL ONLY
             ///
- #define BOOST_PP_LOCAL_MACRO(N) \
- BOOST_PROTO_DEFINE_FUN_OP_CONST(1, N, (Expr, Derived, Domain))\
+ #define BOOST_PP_LOCAL_MACRO(N) \
+ BOOST_PROTO_DEFINE_FUN_OP_CONST(1, N, (Expr, Derived, Domain)) \
             /**/
 
             /// INTERNAL ONLY
             ///
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY))
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY))
         #include BOOST_PP_LOCAL_ITERATE()
         };
 
- /// \brief extends\<\> class template for adding behaviors to a proto expression template
+ /// \brief extends\<\> class template for adding behaviors to a Proto expression template
         ///
         template<typename Expr, typename Derived, typename Domain>
         struct extends<Expr, Derived, Domain, tag::terminal>
@@ -315,13 +412,13 @@
 
             /// INTERNAL ONLY
             ///
- #define BOOST_PP_LOCAL_MACRO(N) \
- BOOST_PROTO_DEFINE_FUN_OP(1, N, (Expr, Derived, Domain))\
+ #define BOOST_PP_LOCAL_MACRO(N) \
+ BOOST_PROTO_DEFINE_FUN_OP(1, N, (Expr, Derived, Domain)) \
             /**/
 
             /// INTERNAL ONLY
             ///
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_ARITY))
+ #define BOOST_PP_LOCAL_LIMITS (0, BOOST_PP_DEC(BOOST_PROTO_MAX_FUNCTION_CALL_ARITY))
         #include BOOST_PP_LOCAL_ITERATE()
         };
 

Modified: branches/release/boost/xpressive/proto/fusion.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/fusion.hpp (original)
+++ branches/release/boost/xpressive/proto/fusion.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,97 +1,272 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file fusion.hpp
-/// Make any Proto parse tree a valid Fusion sequence
+/// Make any Proto expression a valid Fusion sequence
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
-#ifndef BOOST_PROTO_FUSION_HPP_EAN_04_29_2006
-#define BOOST_PROTO_FUSION_HPP_EAN_04_29_2006
+#ifndef BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
+#define BOOST_PROTO_FUSION_HPP_EAN_11_04_2006
 
 #include <boost/xpressive/proto/detail/prefix.hpp>
-#include <boost/xpressive/proto/proto.hpp>
-#include <boost/mpl/if.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/size.hpp>
-#include <boost/mpl/deref.hpp>
-#include <boost/mpl/advance.hpp>
-#include <boost/mpl/distance.hpp>
-#include <boost/mpl/begin_end.hpp>
-#include <boost/mpl/next_prior.hpp>
-#include <boost/type_traits/remove_const.hpp>
+#include <boost/config.hpp>
+#include <boost/version.hpp>
 #include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/long.hpp>
+#if BOOST_VERSION >= 103500
 #include <boost/fusion/include/is_view.hpp>
 #include <boost/fusion/include/tag_of_fwd.hpp>
 #include <boost/fusion/include/category_of.hpp>
 #include <boost/fusion/include/iterator_base.hpp>
-#include <boost/fusion/include/mpl.hpp>
 #include <boost/fusion/include/intrinsic.hpp>
+#include <boost/fusion/include/pop_front.hpp>
+#include <boost/fusion/include/reverse.hpp>
 #include <boost/fusion/include/single_view.hpp>
 #include <boost/fusion/include/transform_view.hpp>
 #include <boost/fusion/support/ext_/is_segmented.hpp>
 #include <boost/fusion/sequence/intrinsic/ext_/segments.hpp>
 #include <boost/fusion/sequence/intrinsic/ext_/size_s.hpp>
 #include <boost/fusion/view/ext_/segmented_iterator.hpp>
+#else
+#include <boost/spirit/fusion/sequence/is_sequence.hpp>
+#include <boost/spirit/fusion/sequence/begin.hpp>
+#include <boost/spirit/fusion/sequence/end.hpp>
+#include <boost/spirit/fusion/sequence/at.hpp>
+#include <boost/spirit/fusion/sequence/value_at.hpp>
+#include <boost/spirit/fusion/sequence/single_view.hpp>
+#include <boost/spirit/fusion/sequence/transform_view.hpp>
+#include <boost/xpressive/proto/detail/reverse.hpp>
+#include <boost/xpressive/proto/detail/pop_front.hpp>
+#endif
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/traits.hpp>
+#include <boost/xpressive/proto/eval.hpp>
 #include <boost/xpressive/proto/detail/suffix.hpp>
 
-#define UNREF(x) typename remove_reference<x>::type
-#define UNCVREF(x) typename remove_cv<typename remove_reference<x>::type>::type
+#if BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4510) // default constructor could not be generated
+#pragma warning(disable : 4512) // assignment operator could not be generated
+#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
+#endif
 
 namespace boost { namespace proto
 {
+
+/// INTERNAL ONLY
+///
+#define UNREF(x) typename boost::remove_reference<x>::type
+
     namespace detail
     {
- template<typename Expr, int Pos>
- struct ref_iterator
- : fusion::iterator_base<ref_iterator<Expr, Pos> >
+
+ template<typename Expr, long Pos>
+ struct expr_iterator
+ : fusion::iterator_base<expr_iterator<Expr, Pos> >
         {
             typedef Expr expr_type;
- typedef mpl::long_<Pos> index;
- typedef fusion::forward_traversal_tag category;
- typedef tag::proto_ref_iterator fusion_tag;
+ BOOST_STATIC_CONSTANT(long, index = Pos);
+ BOOST_PROTO_DEFINE_FUSION_CATEGORY(fusion::random_access_traversal_tag)
+ BOOST_PROTO_DEFINE_FUSION_TAG(tag::proto_expr_iterator)
 
- ref_iterator(Expr const &expr)
+ expr_iterator(Expr const &e)
+ : expr(e)
+ {}
+
+ Expr const &expr;
+ };
+
+ template<typename Expr>
+ struct flat_view
+ {
+ typedef Expr expr_type;
+ typedef typename Expr::proto_tag proto_tag;
+ BOOST_PROTO_DEFINE_FUSION_CATEGORY(fusion::forward_traversal_tag)
+ BOOST_PROTO_DEFINE_FUSION_TAG(tag::proto_flat_view)
+
+ explicit flat_view(Expr &expr)
               : expr_(expr)
             {}
 
- Expr expr_;
+ Expr &expr_;
+ };
+
+ template<typename Tag>
+ struct as_element
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ : mpl::if_<
+ is_same<Tag, UNREF(Expr)::proto_tag>
+ , flat_view<UNREF(Expr) const>
+ , fusion::single_view<UNREF(Expr) const &>
+ >
+ {};
+
+ template<typename Expr>
+ typename result<as_element(Expr const &)>::type
+ operator ()(Expr const &expr) const
+ {
+ return typename result<as_element(Expr const &)>::type(expr);
+ }
         };
+
     }
 
- template<typename Expr>
- struct children
- : proto::ref_<Expr>
+ namespace functional
     {
- children(Expr &expr)
- : proto::ref_<Expr>(proto::ref_<Expr>::make(expr))
- {}
- };
+ /// \brief A PolymorphicFunctionObject type that returns a "flattened"
+ /// view of a Proto expression tree.
+ ///
+ /// A PolymorphicFunctionObject type that returns a "flattened"
+ /// view of a Proto expression tree. For a tree with a top-most node
+ /// tag of type \c T, the elements of the flattened sequence are
+ /// determined by recursing into each child node with the same
+ /// tag type and returning those nodes of different type. So for
+ /// instance, the Proto expression tree corresponding to the
+ /// expression <tt>a | b | c</tt> has a flattened view with elements
+ /// [a, b, c], even though the tree is grouped as
+ /// <tt>((a | b) | c)</tt>.
+ struct flatten
+ {
+ BOOST_PROTO_CALLABLE()
 
- template<typename Expr>
- children<Expr> children_of(Expr &expr)
- {
- return children<Expr>(expr);
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef proto::detail::flat_view<UNREF(Expr) const> type;
+ };
+
+ template<typename Expr>
+ proto::detail::flat_view<Expr const> operator ()(Expr const &expr) const
+ {
+ return proto::detail::flat_view<Expr const>(expr);
+ }
+ };
+
+ /// \brief A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::pop_front() algorithm on its argument.
+ ///
+ /// A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::pop_front() algorithm on its argument. This is
+ /// useful for defining a CallableTransform like \c pop_front(_)
+ /// which removes the first child from a Proto expression node.
+ /// Such a transform might be used as the first argument to the
+ /// \c proto::transform::fold\<\> transform; that is, fold all but
+ /// the first child.
+ struct pop_front
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::pop_front<UNREF(Expr) const>::type
+ type;
+ };
+
+ template<typename Expr>
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::pop_front<Expr const>::type
+ operator ()(Expr const &expr) const
+ {
+ return fusion::pop_front(expr);
+ }
+ };
+
+ /// \brief A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::reverse() algorithm on its argument.
+ ///
+ /// A PolymorphicFunctionObject type that invokes the
+ /// \c fusion::reverse() algorithm on its argument. This is
+ /// useful for defining a CallableTransform like \c reverse(_)
+ /// which reverses the order of the children of a Proto
+ /// expression node.
+ struct reverse
+ {
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::reverse<UNREF(Expr) const>::type
+ type;
+ };
+
+ template<typename Expr>
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::reverse<Expr const>::type
+ operator ()(Expr const &expr) const
+ {
+ return fusion::reverse(expr);
+ }
+ };
     }
 
+ /// \brief A PolymorphicFunctionObject type that returns a "flattened"
+ /// view of a Proto expression tree.
+ ///
+ /// \sa boost::proto::functional::flatten
+ functional::flatten const flatten = {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functional::flatten>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functional::pop_front>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<functional::reverse>
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
     template<typename Context>
     struct eval_fun
     {
- eval_fun(Context &ctx)
+ explicit eval_fun(Context &ctx)
           : ctx_(ctx)
         {}
 
         template<typename Sig>
- struct result {};
+ struct result;
 
         template<typename This, typename Expr>
         struct result<This(Expr)>
- : proto::result_of::eval<UNREF(Expr), Context>
- {};
+ {
+ typedef
+ typename proto::result_of::eval<UNREF(Expr), Context>::type
+ type;
+ };
 
         template<typename Expr>
         typename proto::result_of::eval<Expr, Context>::type
- operator()(Expr &expr) const
+ operator ()(Expr &expr) const
         {
             return proto::eval(expr, this->ctx_);
         }
@@ -101,17 +276,35 @@
     };
 }}
 
+// Don't bother emitting all this into the Doxygen-generated
+// reference section. It's enough to say that Proto expressions
+// are valid Fusion sequence without showing all this gunk.
+#ifndef BOOST_PROTO_DOXYGEN_INVOKED
+
 namespace boost { namespace fusion
 {
- namespace extension
+ #if BOOST_VERSION < 103500
+ template<typename Tag, typename Args, long Arity>
+ struct is_sequence<proto::expr<Tag, Args, Arity> >
+ : mpl::true_
+ {};
+
+ template<typename Tag, typename Args, long Arity>
+ struct is_sequence<proto::expr<Tag, Args, Arity> const>
+ : mpl::true_
+ {};
+ #endif
+
+ namespace BOOST_PROTO_FUSION_EXTENSION
     {
+
         template<typename Tag>
         struct is_view_impl;
 
         template<>
- struct is_view_impl<proto::tag::proto_ref>
+ struct is_view_impl<proto::tag::proto_flat_view>
         {
- template<typename Iterator>
+ template<typename Sequence>
             struct apply
               : mpl::true_
             {};
@@ -120,7 +313,7 @@
         template<>
         struct is_view_impl<proto::tag::proto_expr>
         {
- template<typename Iterator>
+ template<typename Sequence>
             struct apply
               : mpl::false_
             {};
@@ -130,31 +323,56 @@
         struct value_of_impl;
 
         template<>
- struct value_of_impl<proto::tag::proto_ref_iterator>
+ struct value_of_impl<proto::tag::proto_expr_iterator>
         {
- template<typename Iterator>
+ template<
+ typename Iterator
+ , typename Value = typename proto::result_of::arg_c<
+ typename Iterator::expr_type
+ , Iterator::index
+ >::wrapped_type
+ >
             struct apply
- : proto::result_of::arg<typename Iterator::expr_type, typename Iterator::index>
- {};
+ {
+ typedef Value type;
+ };
+
+ template<typename Iterator, typename Expr>
+ struct apply<Iterator, proto::ref_<Expr> >
+ {
+ typedef Expr &type;
+ };
         };
 
+ #if BOOST_VERSION < 103500
+ template<typename Tag>
+ struct value_impl;
+
+ template<>
+ struct value_impl<proto::tag::proto_expr_iterator>
+ : value_of_impl<proto::tag::proto_expr_iterator>
+ {};
+ #endif
+
         template<typename Tag>
         struct deref_impl;
 
         template<>
- struct deref_impl<proto::tag::proto_ref_iterator>
+ struct deref_impl<proto::tag::proto_expr_iterator>
         {
             template<typename Iterator>
             struct apply
             {
- typedef typename proto::result_of::arg<
- typename Iterator::expr_type
- , typename Iterator::index
- >::type const &type;
+ typedef
+ typename proto::result_of::arg_c<
+ typename Iterator::expr_type const
+ , Iterator::index
+ >::type const &
+ type;
 
                 static type call(Iterator const &iter)
                 {
- return proto::arg<typename Iterator::index>(iter.expr_);
+ return proto::arg_c<Iterator::index>(iter.expr);
                 }
             };
         };
@@ -163,19 +381,21 @@
         struct advance_impl;
 
         template<>
- struct advance_impl<proto::tag::proto_ref_iterator>
+ struct advance_impl<proto::tag::proto_expr_iterator>
         {
             template<typename Iterator, typename N>
             struct apply
             {
- typedef typename proto::detail::ref_iterator<
- typename Iterator::expr_type
- , Iterator::index::value + N::value
- > type;
+ typedef
+ typename proto::detail::expr_iterator<
+ typename Iterator::expr_type
+ , Iterator::index + N::value
+ >
+ type;
 
                 static type call(Iterator const &iter)
                 {
- return type(iter.expr_);
+ return type(iter.expr);
                 }
             };
         };
@@ -184,11 +404,11 @@
         struct distance_impl;
 
         template<>
- struct distance_impl<proto::tag::proto_ref_iterator>
+ struct distance_impl<proto::tag::proto_expr_iterator>
         {
             template<typename IteratorFrom, typename IteratorTo>
             struct apply
- : mpl::long_<IteratorTo::index::value - IteratorFrom::index::value>
+ : mpl::long_<IteratorTo::index - IteratorFrom::index>
             {};
         };
 
@@ -196,11 +416,11 @@
         struct next_impl;
 
         template<>
- struct next_impl<proto::tag::proto_ref_iterator>
+ struct next_impl<proto::tag::proto_expr_iterator>
         {
             template<typename Iterator>
             struct apply
- : advance_impl<proto::tag::proto_ref_iterator>::template apply<Iterator, mpl::long_<1> >
+ : advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<1> >
             {};
         };
 
@@ -208,19 +428,20 @@
         struct prior_impl;
 
         template<>
- struct prior_impl<proto::tag::proto_ref_iterator>
+ struct prior_impl<proto::tag::proto_expr_iterator>
         {
             template<typename Iterator>
             struct apply
- : advance_impl<proto::tag::proto_ref_iterator>::template apply<Iterator, mpl::long_<-1> >
+ : advance_impl<proto::tag::proto_expr_iterator>::template apply<Iterator, mpl::long_<-1> >
             {};
         };
 
+ #if BOOST_VERSION >= 103500
         template<typename Tag>
         struct category_of_impl;
 
         template<>
- struct category_of_impl<proto::tag::proto_ref>
+ struct category_of_impl<proto::tag::proto_expr>
         {
             template<typename Sequence>
             struct apply
@@ -228,16 +449,17 @@
                 typedef random_access_traversal_tag type;
             };
         };
+ #endif
 
         template<typename Tag>
         struct size_impl;
 
         template<>
- struct size_impl<proto::tag::proto_ref>
+ struct size_impl<proto::tag::proto_expr>
         {
             template<typename Sequence>
             struct apply
- : Sequence::proto_arity
+ : mpl::long_<0 == Sequence::proto_arity::value ? 1 : Sequence::proto_arity::value>
             {};
         };
 
@@ -245,14 +467,14 @@
         struct begin_impl;
 
         template<>
- struct begin_impl<proto::tag::proto_ref>
+ struct begin_impl<proto::tag::proto_expr>
         {
             template<typename Sequence>
             struct apply
             {
- typedef proto::detail::ref_iterator<Sequence const, 0> type;
+ typedef proto::detail::expr_iterator<Sequence, 0> type;
 
- static type call(Sequence& seq)
+ static type call(Sequence const &seq)
                 {
                     return type(seq);
                 }
@@ -263,14 +485,19 @@
         struct end_impl;
 
         template<>
- struct end_impl<proto::tag::proto_ref>
+ struct end_impl<proto::tag::proto_expr>
         {
             template<typename Sequence>
             struct apply
             {
- typedef proto::detail::ref_iterator<Sequence const, Sequence::proto_arity::value> type;
+ typedef
+ proto::detail::expr_iterator<
+ Sequence
+ , 0 == Sequence::proto_arity::value ? 1 : Sequence::proto_arity::value
+ >
+ type;
 
- static type call(Sequence& seq)
+ static type call(Sequence const &seq)
                 {
                     return type(seq);
                 }
@@ -281,12 +508,31 @@
         struct value_at_impl;
 
         template<>
- struct value_at_impl<proto::tag::proto_ref>
+ struct value_at_impl<proto::tag::proto_expr>
         {
- template<typename Sequence, typename N>
+ template<
+ typename Sequence
+ , typename Index
+ , typename Value = typename proto::result_of::arg_c<
+ Sequence
+ , Index::value
+ >::wrapped_type
+ >
             struct apply
             {
- typedef typename proto::result_of::arg<Sequence, N>::type type;
+ typedef Value type;
+ };
+
+ template<typename Sequence, typename Index, typename Expr>
+ struct apply<Sequence, Index, proto::ref_<Expr> >
+ {
+ typedef Expr &type;
+ };
+
+ template<typename Sequence, typename Index, typename Expr>
+ struct apply<Sequence, Index, Expr &>
+ {
+ typedef Expr &type;
             };
         };
 
@@ -294,25 +540,47 @@
         struct at_impl;
 
         template<>
- struct at_impl<proto::tag::proto_ref>
+ struct at_impl<proto::tag::proto_expr>
         {
- template<typename Sequence, typename N>
+ template<typename Sequence, typename Index>
             struct apply
             {
- typedef typename proto::result_of::arg<Sequence, N>::type const &type;
+ typedef
+ typename proto::result_of::arg_c<
+ Sequence
+ , Index::value
+ >::reference
+ type;
 
                 static type call(Sequence &seq)
                 {
- return proto::arg_c<N::value>(seq);
+ return proto::arg_c<Index::value>(seq);
+ }
+ };
+
+ template<typename Sequence, typename Index>
+ struct apply<Sequence const, Index>
+ {
+ typedef
+ typename proto::result_of::arg_c<
+ Sequence
+ , Index::value
+ >::const_reference
+ type;
+
+ static type call(Sequence const &seq)
+ {
+ return proto::arg_c<Index::value>(seq);
                 }
             };
         };
 
+ #if BOOST_VERSION >= 103500
         template<typename Tag>
         struct is_segmented_impl;
 
         template<>
- struct is_segmented_impl<proto::tag::proto_expr>
+ struct is_segmented_impl<proto::tag::proto_flat_view>
         {
             template<typename Iterator>
             struct apply
@@ -321,33 +589,10 @@
         };
 
         template<typename Tag>
- struct as_element
- {
- template<typename Sig>
- struct result {};
-
- template<typename This, typename Expr>
- struct result<This(Expr)>
- : mpl::if_<
- is_same<Tag, UNREF(Expr)::proto_tag>
- , UNCVREF(Expr) const &
- , fusion::single_view<UNCVREF(Expr) const &>
- >
- {};
-
- template<typename Expr>
- typename result<as_element(Expr)>::type
- operator()(Expr &expr) const
- {
- return typename result<as_element(Expr)>::type(expr);
- }
- };
-
- template<typename Tag>
         struct segments_impl;
 
         template<>
- struct segments_impl<proto::tag::proto_expr>
+ struct segments_impl<proto::tag::proto_flat_view>
         {
             template<typename Sequence>
             struct apply
@@ -355,20 +600,19 @@
                 typedef typename Sequence::proto_tag proto_tag;
 
                 typedef fusion::transform_view<
- proto::ref_<Sequence>
- , as_element<proto_tag>
+ typename Sequence::expr_type
+ , proto::detail::as_element<proto_tag>
> type;
 
                 static type call(Sequence &sequence)
                 {
- proto::ref_<Sequence> r = {sequence};
- return type(r, as_element<proto_tag>());
+ return type(sequence.expr_, proto::detail::as_element<proto_tag>());
                 }
             };
         };
 
         template<>
- struct category_of_impl<proto::tag::proto_expr>
+ struct category_of_impl<proto::tag::proto_flat_view>
         {
             template<typename Sequence>
             struct apply
@@ -378,7 +622,7 @@
         };
 
         template<>
- struct begin_impl<proto::tag::proto_expr>
+ struct begin_impl<proto::tag::proto_flat_view>
         {
             template<typename Sequence>
             struct apply
@@ -387,7 +631,7 @@
         };
 
         template<>
- struct end_impl<proto::tag::proto_expr>
+ struct end_impl<proto::tag::proto_flat_view>
         {
             template<typename Sequence>
             struct apply
@@ -396,159 +640,25 @@
         };
 
         template<>
- struct size_impl<proto::tag::proto_expr>
+ struct size_impl<proto::tag::proto_flat_view>
         {
             template<typename Sequence>
             struct apply
               : fusion::segmented_size<Sequence>
             {};
         };
+ #endif
+
     }
+
 }}
 
-//namespace boost { namespace mpl
-//{
- //template<>
- //struct begin_impl<proto::tag::proto_expr>
- //{
- // template<typename Sequence>
- // struct apply
- // : begin_impl<typename sequence_tag<typename Sequence::proto_args>::type>
- // ::template apply<typename Sequence::proto_args>
- // {};
- //};
-
- //template<>
- //struct end_impl<proto::tag::proto_expr>
- //{
- // template<typename Sequence>
- // struct apply
- // : end_impl<typename sequence_tag<typename Sequence::proto_args>::type>
- // ::template apply<typename Sequence::proto_args>
- // {};
- //};
-
- //template<>
- //struct size_impl<proto::tag::proto_expr>
- //{
- // template<typename Sequence>
- // struct apply
- // {
- // typedef typename Sequence::proto_arity type;
- // };
- //};
-
- //template<>
- //struct at_impl<proto::tag::proto_expr>
- //{
- // template<typename Sequence, typename N>
- // struct apply
- // : at_impl<typename sequence_tag<typename Sequence::proto_args>::type>
- // ::template apply<typename Sequence::proto_args, N>
- // {};
- //};
-
-
- //template<>
- //struct begin_impl<proto::tag::proto_ref>
- //{
- // template<typename Sequence>
- // struct apply
- // : begin_impl<typename sequence_tag<typename Sequence::proto_args>::type>
- // ::template apply<typename Sequence::proto_args>
- // {};
- //};
-
- //template<>
- //struct end_impl<proto::tag::proto_ref>
- //{
- // template<typename Sequence>
- // struct apply
- // : end_impl<typename sequence_tag<typename Sequence::proto_args>::type>
- // ::template apply<typename Sequence::proto_args>
- // {};
- //};
-
- //template<>
- //struct size_impl<proto::tag::proto_ref>
- //{
- // template<typename Sequence>
- // struct apply
- // {
- // typedef typename Sequence::proto_arity type;
- // };
- //};
-
- //template<>
- //struct at_impl<proto::tag::proto_ref>
- //{
- // template<typename Sequence, typename N>
- // struct apply
- // : at_impl<typename sequence_tag<typename Sequence::proto_args>::type>
- // ::template apply<typename Sequence::proto_args, N>
- // {};
- //};
-
-
-//}} // namespace boost::mpl
-
-//namespace boost { namespace mpl
-//{
-// template<typename Tag, typename Args, long Arity>
-// struct sequence_tag<proto::expr<Tag, Args, Arity> >
-// {
-// typedef proto::tag::proto_expr type;
-// };
-//
-// template<typename Expr>
-// struct sequence_tag<proto::ref_<Expr> >
-// {
-// typedef proto::tag::proto_expr type;
-// };
-//
-// template<>
-// struct begin_impl<proto::tag::proto_expr>
-// {
-// template<typename Sequence>
-// struct apply
-// : begin_impl<typename sequence_tag<typename Sequence::proto_args>::type>
-// ::template apply<typename Sequence::proto_args>
-// {};
-// };
-//
-// template<>
-// struct end_impl<proto::tag::proto_expr>
-// {
-// template<typename Sequence>
-// struct apply
-// : end_impl<typename sequence_tag<typename Sequence::proto_args>::type>
-// ::template apply<typename Sequence::proto_args>
-// {};
-// };
-//
-// template<>
-// struct size_impl<proto::tag::proto_expr>
-// {
-// template<typename Sequence>
-// struct apply
-// {
-// typedef typename Sequence::proto_arity type;
-// };
-// };
-//
-// template<>
-// struct at_impl<proto::tag::proto_expr>
-// {
-// template<typename Sequence, typename N>
-// struct apply
-// : at_impl<typename sequence_tag<typename Sequence::proto_args>::type>
-// ::template apply<typename Sequence::proto_args, N>
-// {};
-// };
-//
-//}} // namespace boost::mpl
+#endif // BOOST_PROTO_DOXYGEN_INVOKED
 
 #undef UNREF
-#undef UNCVREF
+
+#if BOOST_MSVC
+#pragma warning(pop)
+#endif
 
 #endif

Modified: branches/release/boost/xpressive/proto/generate.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/generate.hpp (original)
+++ branches/release/boost/xpressive/proto/generate.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
     /// Contains definition of generate\<\> class template, which end users can
     /// specialize for generating domain-specific expression wrappers.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -29,7 +29,7 @@
             template<typename Domain, typename Expr>
             struct generate_if
               : lazy_enable_if<
- matches<Expr, typename Domain::grammar>
+ matches<Expr, typename Domain::proto_grammar>
                   , typename Domain::template apply<Expr>
>
             {};
@@ -42,36 +42,21 @@
             };
 
             template<typename Expr>
- struct arity_;
+ struct expr_traits;
 
             template<typename Tag, typename Args, long N>
- struct arity_<expr<Tag, Args, N> >
- : mpl::long_<N>
- {};
-
- template<typename Expr>
- struct tag_;
-
- template<typename Tag, typename Args, long N>
- struct tag_<expr<Tag, Args, N> >
- {
- typedef Tag type;
- };
-
- template<typename Expr>
- struct args_;
-
- template<typename Tag, typename Args, long N>
- struct args_<expr<Tag, Args, N> >
+ struct expr_traits<proto::expr<Tag, Args, N> >
             {
- typedef Args type;
+ typedef Tag tag;
+ typedef Args args;
+ BOOST_STATIC_CONSTANT(long, arity = N);
             };
 
- template<typename Expr, long Arity = detail::arity_<Expr>::value>
+ template<typename Expr, long Arity = expr_traits<Expr>::arity>
             struct by_value_generator_;
 
         #define BOOST_PROTO_DEFINE_BY_VALUE_TYPE(Z, N, Expr)\
- typename result_of::unref<typename args_<Expr>::type::BOOST_PP_CAT(arg, N) >::type
+ typename result_of::unref<typename expr_traits<Expr>::args::BOOST_PP_CAT(arg, N) >::type
 
         #define BOOST_PROTO_DEFINE_BY_VALUE(Z, N, expr)\
             proto::unref(expr.BOOST_PP_CAT(arg, N))
@@ -86,6 +71,14 @@
 
         namespace generatorns_
         {
+ /// \brief A simple generator that passes an expression
+ /// through unchanged.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// The \c default_generator makes no modifications to the expressions
+ /// passed to it.
             struct default_generator
             {
                 template<typename Expr>
@@ -94,6 +87,8 @@
                     typedef Expr type;
                 };
 
+ /// \param expr A Proto expression
+ /// \return expr
                 template<typename Expr>
                 static Expr const &make(Expr const &expr)
                 {
@@ -101,6 +96,14 @@
                 }
             };
 
+ /// \brief A generator that wraps expressions passed
+ /// to it in the specified extension wrapper.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c generator\<\> wraps each expression passed to it in
+ /// the \c Extends\<\> wrapper.
             template<template<typename> class Extends>
             struct generator
             {
@@ -110,6 +113,8 @@
                     typedef Extends<Expr> type;
                 };
 
+ /// \param expr A Proto expression
+ /// \return Extends<Expr>(expr)
                 template<typename Expr>
                 static Extends<Expr> make(Expr const &expr)
                 {
@@ -117,6 +122,16 @@
                 }
             };
 
+ /// \brief A generator that wraps expressions passed
+ /// to it in the specified extension wrapper and uses
+ /// aggregate initialization for the wrapper.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c pod_generator\<\> wraps each expression passed to it in
+ /// the \c Extends\<\> wrapper, and uses aggregate initialzation
+ /// for the wrapped object.
             template<template<typename> class Extends>
             struct pod_generator
             {
@@ -126,6 +141,8 @@
                     typedef Extends<Expr> type;
                 };
 
+ /// \param expr The expression to wrap
+ /// \return Extends<Expr> that = {expr}; return that;
                 template<typename Expr>
                 static Extends<Expr> make(Expr const &expr)
                 {
@@ -134,16 +151,32 @@
                 }
             };
 
- template<typename Generator>
+ /// \brief A composite generator that first replaces
+ /// child nodes held by reference with ones held by value
+ /// and then forwards the result on to another generator.
+ ///
+ /// Generators are intended for use as the first template parameter
+ /// to the \c domain\<\> class template and control if and how
+ /// expressions within that domain are to be customized.
+ /// \c by_value_generator\<\> ensures all children nodes are
+ /// held by value before forwarding the expression on to
+ /// another generator for further processing. The \c Generator
+ /// parameter defaults to \c default_generator.
+ template<typename Generator BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_generator)>
             struct by_value_generator
             {
                 template<typename Expr>
                 struct apply
- : Generator::template apply<
- typename detail::by_value_generator_<Expr>::type
- >
- {};
+ {
+ typedef
+ typename Generator::template apply<
+ typename detail::by_value_generator_<Expr>::type
+ >::type
+ type;
+ };
 
+ /// \param expr The expression to modify.
+ /// \return Generator::make(deep_copy(expr))
                 template<typename Expr>
                 static typename apply<Expr>::type make(Expr const &expr)
                 {
@@ -163,10 +196,10 @@
             template<typename Expr>
             struct by_value_generator_<Expr, N>
             {
- typedef expr<
- typename tag_<Expr>::type
+ typedef proto::expr<
+ typename expr_traits<Expr>::tag
                   , BOOST_PP_CAT(args, N)<
- // typename result_of::unref<typename args_<Expr>::type::arg0>::type, ...
+ // typename result_of::unref<typename expr_traits<Expr>::args::arg0>::type, ...
                         BOOST_PP_ENUM(BOOST_PP_MAX(N, 1), BOOST_PROTO_DEFINE_BY_VALUE_TYPE, Expr)
>
> type;

Modified: branches/release/boost/xpressive/proto/literal.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/literal.hpp (original)
+++ branches/release/boost/xpressive/proto/literal.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// The literal\<\> terminal wrapper, and the proto::lit() function for
 /// creating literal\<\> wrappers.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -11,6 +11,7 @@
 #define BOOST_PROTO_LITERAL_HPP_EAN_01_03_2007
 
 #include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/config.hpp>
 #include <boost/xpressive/proto/proto_fwd.hpp>
 #include <boost/xpressive/proto/expr.hpp>
 #include <boost/xpressive/proto/traits.hpp>
@@ -21,13 +22,31 @@
 {
     namespace utility
     {
- template<typename T, typename Domain>
+ /// \brief A simple wrapper for a terminal, provided for
+ /// ease of use.
+ ///
+ /// A simple wrapper for a terminal, provided for
+ /// ease of use. In all cases, <tt>literal\<X\> l(x);</tt>
+ /// is equivalent to <tt>terminal\<X\>::::type l = {x};</tt>.
+ ///
+ /// The \c Domain template parameter defaults to
+ /// \c proto::default_domain.
+ template<
+ typename T
+ , typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain)
+ >
         struct literal
           : extends<typename terminal<T>::type, literal<T, Domain>, Domain>
         {
+ private:
             typedef typename terminal<T>::type terminal_type;
             typedef extends<terminal_type, literal<T, Domain>, Domain> base_type;
 
+ public:
+ typedef typename proto::result_of::arg<terminal_type>::type value_type;
+ typedef typename proto::result_of::arg<terminal_type>::reference reference;
+ typedef typename proto::result_of::arg<terminal_type>::const_reference const_reference;
+
             template<typename U>
             literal(U &u)
               : base_type(terminal_type::make(u))
@@ -44,11 +63,24 @@
             {}
 
             using base_type::operator =;
+
+ reference get()
+ {
+ return proto::arg(*this);
+ }
+
+ const_reference get() const
+ {
+ return proto::arg(*this);
+ }
         };
     }
 
- /// lit
- ///
+ /// \brief A helper function for creating a \c literal\<\> wrapper.
+ /// \param t The object to wrap.
+ /// \return literal\<T &\>(t)
+ /// \attention The returned value holds the argument by reference.
+ /// \throw nothrow
     template<typename T>
     inline literal<T &> lit(T &t)
     {
@@ -60,14 +92,14 @@
     template<typename T>
     inline literal<T const &> lit(T const &t)
     {
- #ifdef _MSC_VER
+ #ifdef BOOST_MSVC
         #pragma warning(push)
         #pragma warning(disable: 4180) // warning C4180: qualifier applied to function type has no meaning; ignored
         #endif
 
         return literal<T const &>(t);
 
- #ifdef _MSC_VER
+ #ifdef BOOST_MSVC
         #pragma warning(pop)
         #endif
     }

Modified: branches/release/boost/xpressive/proto/make_expr.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/make_expr.hpp (original)
+++ branches/release/boost/xpressive/proto/make_expr.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,10 +1,11 @@
 #ifndef BOOST_PP_IS_ITERATING
     ///////////////////////////////////////////////////////////////////////////////
     /// \file make_expr.hpp
- /// Given a Fusion sequence of arguments and the type of a proto Expression,
- /// unpacks the sequence into the Expression.
+ /// Definition of the \c make_expr() and \c unpack_expr() utilities for
+ /// building Proto expression nodes from children nodes or from a Fusion
+ /// sequence of children nodes, respectively.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -20,7 +21,7 @@
     #include <boost/preprocessor/arithmetic/dec.hpp>
     #include <boost/preprocessor/arithmetic/sub.hpp>
     #include <boost/preprocessor/punctuation/comma_if.hpp>
- #include <boost/preprocessor/iterate.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/facilities/intercept.hpp>
     #include <boost/preprocessor/comparison/greater.hpp>
     #include <boost/preprocessor/tuple/elem.hpp>
@@ -33,6 +34,7 @@
     #include <boost/preprocessor/repetition/enum_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+ #include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
     #include <boost/preprocessor/repetition/repeat_from_to.hpp>
     #include <boost/preprocessor/seq/size.hpp>
@@ -45,9 +47,12 @@
     #include <boost/preprocessor/seq/push_front.hpp>
     #include <boost/preprocessor/list/for_each_i.hpp>
     #include <boost/ref.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/mpl/eval_if.hpp>
     #include <boost/mpl/apply_wrap.hpp>
     #include <boost/utility/enable_if.hpp>
     #include <boost/type_traits/is_same.hpp>
+ #include <boost/type_traits/add_const.hpp>
     #include <boost/type_traits/add_reference.hpp>
     #include <boost/type_traits/remove_reference.hpp>
     #include <boost/xpressive/proto/proto_fwd.hpp>
@@ -58,71 +63,79 @@
     # include <boost/fusion/include/at.hpp>
     # include <boost/fusion/include/value_at.hpp>
     # include <boost/fusion/include/size.hpp>
- namespace boost { namespace proto { namespace detail
- {
- namespace fusion_ = fusion;
- }}}
     #else
     # include <boost/spirit/fusion/sequence/at.hpp>
     # include <boost/spirit/fusion/sequence/value_at.hpp>
     # include <boost/spirit/fusion/sequence/size.hpp>
- namespace boost { namespace proto { namespace detail { namespace fusion_
- {
- namespace result_of = fusion::meta;
- template<int N, typename Seq>
- typename result_of::at_c<Seq, N>::type at_c(Seq &seq) { return fusion::at<N>(seq); }
- template<int N, typename Seq>
- typename result_of::at_c<Seq const, N>::type at_c(Seq const &seq) { return fusion::at<N>(seq); }
- }}}}
     #endif
     #include <boost/xpressive/proto/detail/suffix.hpp>
 
+ namespace boost
+ {
+ /// INTERNAL ONLY
+ ///
+ namespace fusion
+ {
+ /// INTERNAL ONLY
+ ///
+ template<typename Function>
+ class unfused_generic;
+ }
+ }
+
+ namespace boost { namespace proto
+ {
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG_TYPE(Z, N, DATA) \
- typename boost::proto::result_of::as_arg< \
- BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, DATA), N) \
- , BOOST_PP_TUPLE_ELEM(2, 1, DATA) \
+ typename boost::proto::detail::protoify_< \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
>::type \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG(Z, N, DATA) \
- boost::proto::as_arg<BOOST_PP_TUPLE_ELEM(2, 1, DATA) >( \
- BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(2, 0, DATA), N) \
- ) \
+ boost::proto::detail::protoify_< \
+ BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
+ >::call(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N)) \
         /**/
 
     /// INTERNAL ONLY
     ///
     # define BOOST_PROTO_AT_TYPE(Z, N, DATA) \
- typename remove_reference< \
- typename detail::fusion_::result_of::value_at_c<BOOST_PP_TUPLE_ELEM(2, 0, DATA), N >::type \
+ typename add_const< \
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c< \
+ BOOST_PP_TUPLE_ELEM(3, 0, DATA) \
+ , N \
+ >::type \
>::type \
         /**/
 
     /// INTERNAL ONLY
     ///
     # define BOOST_PROTO_AT(Z, N, DATA) \
- detail::fusion_::at_c<N >(BOOST_PP_TUPLE_ELEM(2, 0, DATA)) \
+ fusion::BOOST_PROTO_FUSION_AT_C(N, BOOST_PP_TUPLE_ELEM(3, 1, DATA)) \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG_AT_TYPE(Z, N, DATA) \
- typename boost::proto::result_of::as_arg< \
+ typename boost::proto::detail::protoify_< \
             BOOST_PROTO_AT_TYPE(Z, N, DATA) \
- , BOOST_PP_TUPLE_ELEM(2, 1, DATA) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
>::type \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_ARG_AT(Z, N, DATA) \
- boost::proto::as_arg<BOOST_PP_TUPLE_ELEM(2, 1, DATA) >( \
- BOOST_PROTO_AT(Z, N, DATA) \
- ) \
+ boost::proto::detail::protoify_< \
+ BOOST_PROTO_AT_TYPE(Z, N, DATA) \
+ , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
+ >::call(BOOST_PROTO_AT(Z, N, DATA)) \
         /**/
 
     /// INTERNAL ONLY
@@ -264,11 +277,11 @@
                   , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
                 ) \
             ) \
- BOOST_PP_ENUM_TRAILING_PARAMS(N, const A) \
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
>::type const \
- BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, const A, &a)) \
+ BOOST_PP_TUPLE_ELEM(4, 0, DATA)(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, const &a)) \
         { \
- return boost::proto::result_of::make_expr< \
+ return boost::proto::detail::make_expr_< \
                 BOOST_PP_SEQ_FOR_EACH_I( \
                     BOOST_PROTO_VARARG_TYPE_, ~ \
                   , BOOST_PP_SEQ_PUSH_FRONT( \
@@ -279,7 +292,7 @@
                       , BOOST_PP_TUPLE_ELEM(4, 1, DATA) \
                     ) \
                 ) \
- BOOST_PP_ENUM_TRAILING_PARAMS(N, const A) \
+ BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(Z, N, A, const & BOOST_PP_INTERCEPT) \
>::call( \
                 BOOST_PP_SEQ_ENUM( \
                     BOOST_PP_SEQ_FOR_EACH_I( \
@@ -332,16 +345,50 @@
         ) \
         /**/
 
- namespace boost { namespace fusion
- {
- template<typename Function>
- class unfused_generic;
- }}
-
- namespace boost { namespace proto
- {
         namespace detail
         {
+ template<typename T, typename Domain>
+ struct protoify_
+ {
+ typedef
+ typename boost::unwrap_reference<T>::type
+ unref_type;
+
+ typedef
+ typename mpl::eval_if<
+ boost::is_reference_wrapper<T>
+ , proto::result_of::as_arg<unref_type, Domain>
+ , proto::result_of::as_expr<unref_type, Domain>
+ >::type
+ type;
+
+ static type call(T &t)
+ {
+ return typename mpl::if_<
+ is_reference_wrapper<T>
+ , functional::as_arg<Domain>
+ , functional::as_expr<Domain>
+ >::type()(static_cast<unref_type &>(t));
+ }
+ };
+
+ template<typename T, typename Domain>
+ struct protoify_<T &, Domain>
+ {
+ typedef
+ typename boost::unwrap_reference<T>::type
+ unref_type;
+
+ typedef
+ typename proto::result_of::as_arg<unref_type, Domain>::type
+ type;
+
+ static type call(T &t)
+ {
+ return functional::as_arg<Domain>()(static_cast<unref_type &>(t));
+ }
+ };
+
             template<
                 typename Domain
                 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
@@ -379,17 +426,25 @@
             template<typename Domain, typename Sequence>
             struct unpack_expr_<tag::terminal, Domain, Sequence, 1u>
             {
- typedef expr<
- tag::terminal
- , args0<typename fusion_::result_of::value_at_c<Sequence, 0>::type>
- > expr_type;
+ typedef
+ typename add_const<
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::value_at_c<
+ Sequence
+ , 0
+ >::type
+ >::type
+ terminal_type;
 
- typedef typename Domain::template apply<expr_type>::type type;
+ typedef
+ typename proto::detail::protoify_<
+ terminal_type
+ , Domain
+ >::type
+ type;
 
                 static type const call(Sequence const &sequence)
                 {
- expr_type that = {fusion_::at_c<0>(sequence)};
- return Domain::make(that);
+ return proto::detail::protoify_<terminal_type, Domain>::call(fusion::BOOST_PROTO_FUSION_AT_C(0, sequence));
                 }
             };
 
@@ -415,17 +470,20 @@
             struct make_expr_<tag::terminal, Domain, A
                 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
             {
- typedef typename add_reference<A>::type reference;
- typedef expr<tag::terminal, args0<reference> > expr_type;
- typedef typename Domain::template apply<expr_type>::type type;
+ typedef typename proto::detail::protoify_<A, Domain>::type type;
 
- static type const call(reference a)
+ static type const call(typename add_reference<A>::type a)
                 {
- expr_type that = {a};
- return Domain::make(that);
+ return proto::detail::protoify_<A, Domain>::call(a);
                 }
             };
 
+ template<typename A>
+ struct make_expr_<tag::terminal, deduce_domain, A
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
+ : make_expr_<tag::terminal, default_domain, A>
+ {};
+
         #define BOOST_PP_ITERATION_PARAMS_1 \
             (4, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/make_expr.hpp>, 1)) \
             /**/
@@ -435,40 +493,51 @@
 
         namespace result_of
         {
- template<typename Tag, typename Sequence, typename, typename>
- struct unpack_expr
- : detail::unpack_expr_<
- Tag
- , deduce_domain
- , Sequence
- , detail::fusion_::result_of::size<Sequence>::type::value
- >
- {};
-
- template<typename Tag, typename Domain, typename Sequence>
- struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
- : detail::unpack_expr_<
- Tag
- , Domain
- , Sequence
- , detail::fusion_::result_of::size<Sequence>::type::value
- >
- {};
-
+ /// \brief Metafunction that computes the return type of the
+ /// \c make_expr() function, with a domain deduced from the
+ /// domains of the children.
+ ///
+ /// Use the <tt>result_of::make_expr\<\></tt> metafunction to
+ /// compute the return type of the \c make_expr() function.
+ ///
+ /// In this specialization, the domain is deduced from the
+ /// domains of the children types. (If
+ /// <tt>is_domain\<A0\>::::value</tt> is \c true, then another
+ /// specialization is selected.)
             template<
                 typename Tag
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
- , typename
- , typename
+ , typename A0
+ , BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(
+ BOOST_PROTO_MAX_ARITY
+ , typename A
+ , BOOST_PROTO_FOR_DOXYGEN_ONLY(= void) BOOST_PP_INTERCEPT
+ )
+ , typename Void1 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)
+ , typename Void2 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)
>
             struct make_expr
- : make_expr<
- Tag
- , deduce_domain
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
- >
- {};
+ {
+ /// Same as <tt>result_of::make_expr\<Tag, D, A0, ... AN\>::::type</tt>
+ /// where \c D is the deduced domain, which is calculated as follows:
+ ///
+ /// For each \c x in <tt>[0,N)</tt> (proceeding in order beginning with
+ /// <tt>x=0</tt>), if <tt>domain_of\<Ax\>::::type</tt> is not
+ /// \c default_domain, then \c D is <tt>domain_of\<Ax\>::::type</tt>.
+ /// Otherwise, \c D is \c default_domain.
+ typedef
+ typename detail::make_expr_<
+ Tag
+ , deduce_domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ >::type
+ type;
+ };
 
+ /// \brief Metafunction that computes the return type of the
+ /// \c make_expr() function, within the specified domain.
+ ///
+ /// Use the <tt>result_of::make_expr\<\></tt> metafunction to compute
+ /// the return type of the \c make_expr() function.
             template<
                 typename Tag
               , typename Domain
@@ -480,177 +549,385 @@
                 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
               , typename Domain::proto_is_domain_
>
- : detail::make_expr_<
- Tag
- , Domain
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
- >
- {};
+ {
+ /// If \c Tag is <tt>tag::terminal</tt>, then \c type is a
+ /// typedef for <tt>Domain::apply\<expr\<tag::terminal,
+ /// args0\<A0\> \> \>::::type</tt>.
+ ///
+ /// Otherwise, \c type is a typedef for <tt>Domain::apply\<expr\<Tag,
+ /// argsN\< as_child\<A0\>::::type, ... as_child\<AN\>::::type \>
+ /// \>::::type</tt>, where \c N is the number of non-void template
+ /// arguments, and <tt>as_child\<A\>::::type</tt> is evaluated as
+ /// follows:
+ ///
+ /// \li If <tt>is_expr\<A\>::::value</tt> is \c true, then the
+ /// child type is \c A.
+ /// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
+ /// and <tt>is_expr\<B\>::::value</tt> is \c true, then the
+ /// child type is <tt>ref_\<B\></tt>.
+ /// \li If <tt>is_expr\<A\>::::value</tt> is \c false, then the
+ /// child type is <tt>Domain::apply\<expr\<tag::terminal, args0\<A\> \>
+ /// \>::::type</tt>.
+ /// \li If \c A is <tt>B &</tt> or <tt>cv boost::reference_wrapper\<B\></tt>,
+ /// and <tt>is_expr\<B\>::::value</tt> is \c false, then the
+ /// child type is <tt>Domain::apply\<expr\<tag::terminal, args0\<B &\> \>
+ /// \>::::type</tt>.
+ typedef
+ typename detail::make_expr_<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ >::type
+ type;
+ };
 
+ /// \brief Metafunction that computes the return type of the
+ /// \c unpack_expr() function, with a domain deduced from the
+ /// domains of the children.
+ ///
+ /// Use the <tt>result_of::unpack_expr\<\></tt> metafunction to
+ /// compute the return type of the \c unpack_expr() function.
+ ///
+ /// \c Sequence is a Fusion Random Access Sequence.
+ ///
+ /// In this specialization, the domain is deduced from the
+ /// domains of the children types. (If
+ /// <tt>is_domain\<Sequence>::::value</tt> is \c true, then another
+ /// specialization is selected.)
             template<
                 typename Tag
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, typename A)
- >
- struct make_expr<
- Tag
- , deduce_domain
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
- , void
+ , typename Sequence
+ , typename Void1 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)
+ , typename Void2 BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)
>
- : detail::make_expr_<
- Tag
- , typename detail::deduce_domain_<
- typename domain_of<A0>::type
- , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PROTO_MAX_ARITY, A)
+ struct unpack_expr
+ {
+ /// Same as <tt>result_of::make_expr\<Tag,
+ /// fusion::value_at\<Sequence, 0\>::::type, ...
+ /// fusion::value_at\<Sequence, N-1\>::::type\>::::type</tt>,
+ /// where \c N is the size of \c Sequence.
+ typedef
+ typename detail::unpack_expr_<
+ Tag
+ , deduce_domain
+ , Sequence
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
>::type
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, A)
- >
- {};
+ type;
+ };
+
+ /// \brief Metafunction that computes the return type of the
+ /// \c unpack_expr() function, within the specified domain.
+ ///
+ /// Use the <tt>result_of::make_expr\<\></tt> metafunction to compute
+ /// the return type of the \c make_expr() function.
+ template<typename Tag, typename Domain, typename Sequence>
+ struct unpack_expr<Tag, Domain, Sequence, typename Domain::proto_is_domain_>
+ {
+ /// Same as <tt>result_of::make_expr\<Tag, Domain,
+ /// fusion::value_at\<Sequence, 0\>::::type, ...
+ /// fusion::value_at\<Sequence, N-1\>::::type\>::::type</tt>,
+ /// where \c N is the size of \c Sequence.
+ typedef
+ typename detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::type
+ type;
+ };
         }
 
         namespace functional
         {
- template<typename Tag, typename Domain>
+ /// \brief A callable function object equivalent to the
+ /// \c proto::make_expr() function.
+ ///
+ /// In all cases, <tt>functional::make_expr\<Tag, Domain\>()(a0, ... aN)</tt>
+ /// is equivalent to <tt>proto::make_expr\<Tag, Domain\>(a0, ... aN)</tt>.
+ ///
+ /// <tt>functional::make_expr\<Tag\>()(a0, ... aN)</tt>
+ /// is equivalent to <tt>proto::make_expr\<Tag\>(a0, ... aN)</tt>.
+ template<typename Tag, typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= deduce_domain)>
             struct make_expr
             {
- template<typename Sig>
- struct result
- {};
-
- template<typename A>
- typename result_of::make_expr<Tag, Domain, A>::type const
- operator ()(A &a) const
- {
- return result_of::make_expr<Tag, Domain, A>::call(a);
- }
-
- #define BOOST_PP_ITERATION_PARAMS_1 \
- (4, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/make_expr.hpp>, 2)) \
- /**/
-
- #include BOOST_PP_ITERATE()
- };
+ BOOST_PROTO_CALLABLE()
 
- template<typename Domain>
- struct make_expr<tag::terminal, Domain>
- {
                 template<typename Sig>
- struct result
- {};
+ struct result;
 
- template<typename This, typename A>
- struct result<This(A)>
- : result_of::make_expr<tag::terminal, Domain, A>
- {};
-
- template<typename A>
- typename result_of::make_expr<tag::terminal, Domain, A>::type
- operator ()(A &a) const
+ template<typename This, typename A0>
+ struct result<This(A0)>
                 {
- return result_of::make_expr<tag::terminal, Domain, A>::call(a);
- }
+ typedef
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ , A0
+ >::type
+ type;
+ };
 
- template<typename A>
- typename result_of::make_expr<tag::terminal, Domain, A const>::type
- operator ()(A const &a) const
+ /// Construct an expression node with tag type \c Tag
+ /// and in the domain \c Domain.
+ ///
+ /// \return <tt>proto::make_expr\<Tag, Domain\>(a0,...aN)</tt>
+ template<typename A0>
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ , A0 const
+ >::type const
+ operator ()(A0 const &a0) const
                 {
- return result_of::make_expr<tag::terminal, Domain, A const>::call(a);
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ , A0 const
+ >::call(a0);
                 }
+
+ // Additional overloads generated by the preprocessor ...
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (4, (2, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/make_expr.hpp>, 2)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
             };
 
- template<typename Tag, typename Domain>
+ /// \brief A callable function object equivalent to the
+ /// \c proto::unpack_expr() function.
+ ///
+ /// In all cases, <tt>functional::unpack_expr\<Tag, Domain\>()(seq)</tt>
+ /// is equivalent to <tt>proto::unpack_expr\<Tag, Domain\>(seq)</tt>.
+ ///
+ /// <tt>functional::unpack_expr\<Tag\>()(seq)</tt>
+ /// is equivalent to <tt>proto::unpack_expr\<Tag\>(seq)</tt>.
+ template<typename Tag, typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= deduce_domain)>
             struct unpack_expr
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
                 struct result
                 {};
 
                 template<typename This, typename Sequence>
                 struct result<This(Sequence)>
- : result_of::unpack_expr<
- Tag
- , Domain
- , typename detail::remove_cv_ref<Sequence>::type
- >
- {};
+ {
+ typedef
+ typename result_of::unpack_expr<
+ Tag
+ , Domain
+ , typename remove_reference<Sequence>::type
+ >::type
+ type;
+ };
 
+ /// Construct an expression node with tag type \c Tag
+ /// and in the domain \c Domain.
+ ///
+ /// \param sequence A Fusion Random Access Sequence
+ /// \return <tt>proto::unpack_expr\<Tag, Domain\>(sequence)</tt>
                 template<typename Sequence>
- typename result_of::unpack_expr<Tag, Domain, Sequence>::type
+ typename result_of::unpack_expr<Tag, Domain, Sequence const>::type const
                 operator ()(Sequence const &sequence) const
                 {
- return result_of::unpack_expr<Tag, Domain, Sequence>::call(sequence);
+ return proto::detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::call(sequence);
                 }
             };
 
+ /// INTERNAL ONLY
+ ///
             template<typename Tag, typename Domain>
             struct unfused_expr_fun
             {
- template<typename Sequence>
- struct result
- : result_of::unpack_expr<Tag, Domain, Sequence>
- {};
+ BOOST_PROTO_CALLABLE()
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Sequence>
+ struct result<This(Sequence)>
+ {
+ typedef
+ typename result_of::unpack_expr<
+ Tag
+ , Domain
+ , typename remove_reference<Sequence>::type
+ >::type
+ type;
+ };
 
                 template<typename Sequence>
- typename proto::result_of::unpack_expr<Tag, Domain, Sequence>::type
+ typename proto::result_of::unpack_expr<Tag, Domain, Sequence const>::type const
                 operator ()(Sequence const &sequence) const
                 {
- return result_of::unpack_expr<Tag, Domain, Sequence>::call(sequence);
+ return proto::detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::call(sequence);
                 }
             };
 
+ /// INTERNAL ONLY
+ ///
             template<typename Tag, typename Domain>
             struct unfused_expr
               : fusion::unfused_generic<unfused_expr_fun<Tag, Domain> >
- {};
+ {
+ BOOST_PROTO_CALLABLE()
+ };
         }
 
- /// unpack_expr
+ /// \brief Construct an expression of the requested tag type
+ /// with a domain and with the specified arguments as children.
         ///
- template<typename Tag, typename Sequence>
+ /// This function template may be invoked either with or without
+ /// specifying a \c Domain argument. If no domain is specified,
+ /// the domain is deduced by examining in order the domains of
+ /// the given arguments and taking the first that is not
+ /// \c default_domain, if any such domain exists, or
+ /// \c default_domain otherwise.
+ ///
+ /// Let \c wrap_(x) be defined such that:
+ /// \li If \c x is a <tt>boost::reference_wrapper\<\></tt>,
+ /// \c wrap_(x) is equivalent to <tt>as_arg\<Domain\>(x.get())</tt>.
+ /// \li Otherwise, \c wrap_(x) is equivalent to
+ /// <tt>as_expr\<Domain\>(x)</tt>.
+ ///
+ /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
+ /// <tt>expr\<Tag, argsN\<B0,...BN\> \>::::make(b0,...bN)</tt>
+ /// where \c Bx is the type of \c bx.
+ ///
+ /// \return <tt>Domain::make(make_\<Tag\>(wrap_(a0),...wrap_(aN)))</tt>.
+ template<typename Tag, typename A0>
         typename lazy_disable_if<
- is_domain<Sequence>
- , result_of::unpack_expr<Tag, Sequence>
+ is_domain<A0>
+ , result_of::make_expr<
+ Tag
+ , A0 const
+ >
>::type const
- unpack_expr(Sequence const &sequence)
+ make_expr(A0 const &a0)
         {
- return result_of::unpack_expr<Tag, Sequence>::call(sequence);
+ return proto::detail::make_expr_<
+ Tag
+ , deduce_domain
+ , A0 const
+ >::call(a0);
         }
 
         /// \overload
         ///
- template<typename Tag, typename Domain, typename Sequence2>
- typename result_of::unpack_expr<Tag, Domain, Sequence2>::type const
- unpack_expr(Sequence2 const &sequence2)
+ template<typename Tag, typename Domain, typename B0>
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ , B0 const
+ >::type const
+ make_expr(B0 const &b0)
         {
- return result_of::unpack_expr<Tag, Domain, Sequence2>::call(sequence2);
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ , B0 const
+ >::call(b0);
         }
 
- /// make_expr
+ // Additional overloads generated by the preprocessor...
+
+ #define BOOST_PP_ITERATION_PARAMS_1 \
+ (4, (2, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/make_expr.hpp>, 3)) \
+ /**/
+
+ #include BOOST_PP_ITERATE()
+
+ /// \brief Construct an expression of the requested tag type
+ /// with a domain and with childres from the specified Fusion
+ /// Random Access Sequence.
         ///
- template<typename Tag, typename A0>
+ /// This function template may be invoked either with or without
+ /// specifying a \c Domain argument. If no domain is specified,
+ /// the domain is deduced by examining in order the domains of the
+ /// elements of \c sequence and taking the first that is not
+ /// \c default_domain, if any such domain exists, or
+ /// \c default_domain otherwise.
+ ///
+ /// Let <tt>wrap_\<N\>(s)</tt>, where \c s has type \c S, be defined
+ /// such that:
+ /// \li If <tt>fusion::value_at\<S,N\>::::type</tt> is a reference,
+ /// <tt>wrap_\<N\>(s)</tt> is equivalent to
+ /// <tt>as_arg\<Domain\>(fusion::at_c\<N\>(s))</tt>.
+ /// \li Otherwise, <tt>wrap_\<N\>(s)</tt> is equivalent to
+ /// <tt>as_expr\<Domain\>(fusion::at_c\<N\>(s))</tt>.
+ ///
+ /// Let <tt>make_\<Tag\>(b0,...bN)</tt> be defined as
+ /// <tt>expr\<Tag, argsN\<B0,...BN\> \>::::make(b0,...bN)</tt>
+ /// where \c Bx is the type of \c bx.
+ ///
+ /// \param sequence a Fusion Random Access Sequence.
+ /// \return <tt>Domain::make(make_\<Tag\>(wrap_\<0\>(s),...wrap_\<N-1\>(S)))</tt>,
+ /// where N is the size of \c Sequence.
+ template<typename Tag, typename Sequence>
         typename lazy_disable_if<
- is_domain<A0>
- , result_of::make_expr<Tag, A0>
+ is_domain<Sequence>
+ , result_of::unpack_expr<Tag, Sequence const>
>::type const
- make_expr(A0 &a0 BOOST_PROTO_DISABLE_IF_IS_CONST(A0))
+ unpack_expr(Sequence const &sequence)
         {
- return result_of::make_expr<Tag, A0>::call(a0);
+ return proto::detail::unpack_expr_<
+ Tag
+ , deduce_domain
+ , Sequence const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence>::type::value
+ >::call(sequence);
         }
 
         /// \overload
         ///
- template<typename Tag, typename Domain, typename B0>
- typename result_of::make_expr<Tag, Domain, B0>::type const
- make_expr(B0 &b0 BOOST_PROTO_DISABLE_IF_IS_CONST(B0))
+ template<typename Tag, typename Domain, typename Sequence2>
+ typename result_of::unpack_expr<Tag, Domain, Sequence2 const>::type const
+ unpack_expr(Sequence2 const &sequence2)
         {
- return result_of::make_expr<Tag, Domain, B0>::call(b0);
+ return proto::detail::unpack_expr_<
+ Tag
+ , Domain
+ , Sequence2 const
+ , fusion::BOOST_PROTO_FUSION_RESULT_OF::size<Sequence2>::type::value
+ >::call(sequence2);
         }
 
- #define BOOST_PP_ITERATION_PARAMS_1 \
- (4, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/make_expr.hpp>, 3)) \
- /**/
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functional::make_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functional::unpack_expr<Tag, Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Tag, typename Domain>
+ struct is_callable<functional::unfused_expr<Tag, Domain> >
+ : mpl::true_
+ {};
 
- #include BOOST_PP_ITERATE()
     }}
 
     #undef BOOST_PROTO_AT
@@ -669,29 +946,45 @@
         struct make_expr_<Tag, Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
             BOOST_PP_ENUM_TRAILING_PARAMS(M, void BOOST_PP_INTERCEPT), void>
         {
- typedef expr<
+ typedef proto::expr<
                 Tag
- , BOOST_PP_CAT(args, N)<BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_TYPE, (A, Domain)) >
+ , BOOST_PP_CAT(args, N)<BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_TYPE, (A, ~, Domain)) >
> expr_type;
 
             typedef typename Domain::template apply<expr_type>::type type;
 
- static type const call(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a))
+ static type const call(BOOST_PP_ENUM_BINARY_PARAMS(N, typename add_reference<A, >::type a))
             {
                 expr_type that = {
- BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG, (a, Domain))
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG, (A, a, Domain))
                 };
                 return Domain::make(that);
             }
         };
 
+ template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make_expr_<Tag, deduce_domain BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ BOOST_PP_ENUM_TRAILING_PARAMS(M, void BOOST_PP_INTERCEPT), void>
+ : make_expr_<
+ Tag
+ , typename detail::deduce_domain_<
+ typename domain_of<
+ A0
+ >::type
+ BOOST_PP_COMMA_IF(BOOST_PP_DEC(N))
+ BOOST_PP_ENUM_SHIFTED_PARAMS(N, A)
+ >::type
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ >
+ {};
+
         template<typename Tag, typename Domain, typename Sequence>
         struct unpack_expr_<Tag, Domain, Sequence, N>
         {
- typedef expr<
+ typedef proto::expr<
                 Tag
               , BOOST_PP_CAT(args, N)<
- BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT_TYPE, (Sequence const, Domain))
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT_TYPE, (Sequence const, ~, Domain))
>
> expr_type;
 
@@ -700,7 +993,7 @@
             static type const call(Sequence const &sequence)
             {
                 expr_type that = {
- BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT, (sequence, Domain))
+ BOOST_PP_ENUM(N, BOOST_PROTO_AS_ARG_AT, (Sequence const, sequence, Domain))
                 };
                 return Domain::make(that);
             }
@@ -712,10 +1005,10 @@
                 Tag
               , typename detail::deduce_domain_<
                     typename domain_of<
- BOOST_PROTO_AT_TYPE(~, 0, (Sequence const, ~))
+ BOOST_PROTO_AT_TYPE(~, 0, (Sequence const, ~, ~))
>::type
                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(N))
- BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_AT_TYPE, (Sequence const, ~))
+ BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_AT_TYPE, (Sequence const, ~, ~))
>::type
               , Sequence
               , N
@@ -731,17 +1024,18 @@
 
         template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
         struct result<This(BOOST_PP_ENUM_PARAMS(N, A))>
- : result_of::make_expr<
- Tag
- , Domain
- BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
- N
- , typename remove_reference<A
- , >::type BOOST_PP_INTERCEPT
- )
- >
- {};
+ {
+ typedef
+ typename result_of::make_expr<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
+ >::type
+ type;
+ };
 
+ /// \overload
+ ///
         template<BOOST_PP_ENUM_PARAMS(N, typename A)>
         typename result_of::make_expr<
             Tag
@@ -750,8 +1044,11 @@
>::type const
         operator ()(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a)) const
         {
- return result_of::make_expr<Tag, Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)>
- ::call(BOOST_PP_ENUM_PARAMS(N, a));
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::call(BOOST_PP_ENUM_PARAMS(N, a));
         }
 
     #undef N
@@ -765,12 +1062,18 @@
         template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
         typename lazy_disable_if<
             is_domain<A0>
- , result_of::make_expr<Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)>
+ , result_of::make_expr<
+ Tag
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >
>::type const
         make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const A, &a))
         {
- return result_of::make_expr<Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)>
- ::call(BOOST_PP_ENUM_PARAMS(N, a));
+ return proto::detail::make_expr_<
+ Tag
+ , deduce_domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const A)
+ >::call(BOOST_PP_ENUM_PARAMS(N, a));
         }
 
         /// \overload
@@ -783,8 +1086,11 @@
>::type const
         make_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, const B, &b))
         {
- return result_of::make_expr<Tag, Domain BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)>
- ::call(BOOST_PP_ENUM_PARAMS(N, b));
+ return proto::detail::make_expr_<
+ Tag
+ , Domain
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, const B)
+ >::call(BOOST_PP_ENUM_PARAMS(N, b));
         }
 
     #undef N

Modified: branches/release/boost/xpressive/proto/matches.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/matches.hpp (original)
+++ branches/release/boost/xpressive/proto/matches.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
     /// Contains definition of matches\<\> metafunction for determining if
     /// a given expression matches a given pattern.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -12,6 +12,7 @@
     #define BOOST_PROTO_MATCHES_HPP_EAN_11_03_2006
 
     #include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
+ #include <boost/detail/workaround.hpp>
     #include <boost/preprocessor/cat.hpp>
     #include <boost/preprocessor/arithmetic/dec.hpp>
     #include <boost/preprocessor/arithmetic/sub.hpp>
@@ -30,17 +31,19 @@
     #include <boost/mpl/aux_/template_arity.hpp>
     #include <boost/mpl/aux_/lambda_arity_param.hpp>
     #include <boost/utility/enable_if.hpp>
+ #include <boost/type_traits/is_array.hpp>
     #include <boost/type_traits/is_convertible.hpp>
     #include <boost/type_traits/is_reference.hpp>
     #include <boost/type_traits/is_pointer.hpp>
     #include <boost/xpressive/proto/proto_fwd.hpp>
     #include <boost/xpressive/proto/traits.hpp>
+ #include <boost/xpressive/proto/transform/when.hpp>
     #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
 
     // Some compilers (like GCC) need extra help figuring out a template's arity.
     // I use MPL's BOOST_MPL_AUX_LAMBDA_ARITY_PARAM() macro to disambiguate, which
     // which is controlled by the BOOST_MPL_LIMIT_METAFUNCTION_ARITY macro. If
- // You define BOOST_PROTO_MAX_ARITY to be greater than
+ // You define BOOST_PROTO_MAX_ARITY to be greater than
     // BOOST_MPL_LIMIT_METAFUNCTION_ARITY on these compilers, things don't work.
     // You must define BOOST_MPL_LIMIT_METAFUNCTION_ARITY to be greater.
     #ifdef BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
@@ -59,10 +62,10 @@
 
         namespace detail
         {
- struct _;
+ struct ignore;
 
             template<typename Expr, typename Grammar>
- struct matches_impl;
+ struct matches_;
 
             // and_ and or_ implementation
             template<bool B, typename Expr, typename G0>
@@ -83,6 +86,26 @@
             template<typename And>
             struct last;
 
+ template<typename T, typename U>
+ struct array_matches
+ : mpl::false_
+ {};
+
+ template<typename T, std::size_t M>
+ struct array_matches<T[M], T *>
+ : mpl::true_
+ {};
+
+ template<typename T, std::size_t M>
+ struct array_matches<T[M], T const *>
+ : mpl::true_
+ {};
+
+ template<typename T, std::size_t M>
+ struct array_matches<T[M], T[proto::N]>
+ : mpl::true_
+ {};
+
             template<typename T, typename U
                 BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<U>::value)
>
@@ -100,6 +123,16 @@
               : mpl::true_
             {};
 
+ template<typename T, std::size_t M, typename U>
+ struct lambda_matches<T[M], U BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : array_matches<T[M], U>
+ {};
+
+ template<typename T, std::size_t M>
+ struct lambda_matches<T[M], T[M] BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(-1)>
+ : mpl::true_
+ {};
+
             template<template<typename> class T, typename Expr0, typename Grammar0>
             struct lambda_matches<T<Expr0>, T<Grammar0> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(1) >
               : lambda_matches<Expr0, Grammar0>
@@ -110,20 +143,20 @@
             struct vararg_matches_impl;
 
             // vararg_matches
- template<typename Args1, typename Args2, typename Back, bool Can, bool Zero, typename EnableIf = void>
+ template<typename Args1, typename Args2, typename Back, bool Can, bool Zero, typename Void = void>
             struct vararg_matches
               : mpl::false_
             {};
 
             template<typename Args1, typename Args2, typename Back>
             struct vararg_matches<Args1, Args2, Back, true, true, typename Back::proto_is_vararg_>
- : matches_impl<expr<_, Args1, Args1::size>, expr<_, Args2, Args1::size> >
+ : matches_<proto::expr<ignore, Args1, Args1::size>, proto::expr<ignore, Args2, Args1::size> >
             {};
 
             template<typename Args1, typename Args2, typename Back>
             struct vararg_matches<Args1, Args2, Back, true, false, typename Back::proto_is_vararg_>
               : and2<
- matches_impl<expr<_, Args1, Args2::size>, expr<_, Args2, Args2::size> >::value
+ matches_<proto::expr<ignore, Args1, Args2::size>, proto::expr<ignore, Args2, Args2::size> >::value
                   , vararg_matches_impl<Args1, typename Back::proto_base_expr, Args2::size + 1, Args1::size>
>
             {};
@@ -165,7 +198,7 @@
             template<
                 typename T
               , typename U
- , bool B = is_array<typename remove_cv_ref<T>::type>::value
+ , bool B = is_array<BOOST_PROTO_UNCVREF(T)>::value
>
             struct terminal_array_matches
               : mpl::false_
@@ -193,8 +226,8 @@
                     mpl::and_<
                         is_cv_ref_compatible<T, U>
                       , lambda_matches<
- typename remove_cv_ref<T>::type
- , typename remove_cv_ref<U>::type
+ BOOST_PROTO_UNCVREF(T)
+ , BOOST_PROTO_UNCVREF(U)
>
>
                   , terminal_array_matches<T, U>
@@ -207,8 +240,8 @@
               : mpl::and_<
                     is_cv_ref_compatible<T, U>
                   , lambda_matches<
- typename remove_cv_ref<T>::type
- , typename remove_cv_ref<U>::type
+ BOOST_PROTO_UNCVREF(T)
+ , BOOST_PROTO_UNCVREF(U)
>
>
             {};
@@ -254,55 +287,55 @@
               : is_convertible<T, U>
             {};
 
- // matches_impl
+ // matches_
             template<typename Expr, typename Grammar>
- struct matches_impl
+ struct matches_
               : mpl::false_
             {};
 
             template<typename Expr>
- struct matches_impl< Expr, proto::_ >
+ struct matches_< Expr, proto::_ >
               : mpl::true_
             {};
 
             template<typename Tag, typename Args1, long N1, typename Args2, long N2>
- struct matches_impl< expr<Tag, Args1, N1>, expr<Tag, Args2, N2> >
+ struct matches_< proto::expr<Tag, Args1, N1>, proto::expr<Tag, Args2, N2> >
               : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
             {};
 
             template<typename Tag, typename Args1, long N1, typename Args2, long N2>
- struct matches_impl< expr<Tag, Args1, N1>, expr<proto::_, Args2, N2> >
+ struct matches_< proto::expr<Tag, Args1, N1>, proto::expr<proto::_, Args2, N2> >
               : vararg_matches< Args1, Args2, typename Args2::back_, (N1+2 > N2), (N2 > N1) >
             {};
 
             template<typename Args1, typename Args2, long N2>
- struct matches_impl< expr<tag::terminal, Args1, 0>, expr<proto::_, Args2, N2> >
+ struct matches_< proto::expr<tag::terminal, Args1, 0>, proto::expr<proto::_, Args2, N2> >
               : mpl::false_
             {};
 
             template<typename Tag, typename Args1, typename Args2>
- struct matches_impl< expr<Tag, Args1, 1>, expr<Tag, Args2, 1> >
- : matches_impl<typename Args1::arg0::proto_base_expr, typename Args2::arg0::proto_base_expr>
+ struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<Tag, Args2, 1> >
+ : matches_<typename Args1::arg0::proto_base_expr, typename Args2::arg0::proto_base_expr>
             {};
 
             template<typename Tag, typename Args1, typename Args2>
- struct matches_impl< expr<Tag, Args1, 1>, expr<proto::_, Args2, 1> >
- : matches_impl<typename Args1::arg0::proto_base_expr, typename Args2::arg0::proto_base_expr>
+ struct matches_< proto::expr<Tag, Args1, 1>, proto::expr<proto::_, Args2, 1> >
+ : matches_<typename Args1::arg0::proto_base_expr, typename Args2::arg0::proto_base_expr>
             {};
 
             template<typename Args1, typename Args2>
- struct matches_impl< expr<tag::terminal, Args1, 0>, expr<tag::terminal, Args2, 0> >
+ struct matches_< proto::expr<tag::terminal, Args1, 0>, proto::expr<tag::terminal, Args2, 0> >
               : terminal_matches<typename Args1::arg0, typename Args2::arg0>
             {};
 
         #define BOOST_PROTO_MATCHES_N_FUN(z, n, data)\
- matches_impl<\
+ matches_<\
                 typename Args1::BOOST_PP_CAT(arg, n)::proto_base_expr\
               , typename Args2::BOOST_PP_CAT(arg, n)::proto_base_expr\
>
 
         #define BOOST_PROTO_DEFINE_MATCHES(z, n, data)\
- matches_impl<\
+ matches_<\
                 typename Expr::proto_base_expr\
               , typename BOOST_PP_CAT(G, n)::proto_base_expr\
>
@@ -328,21 +361,30 @@
         #undef BOOST_PROTO_DEFINE_LAMBDA_MATCHES
 
             // handle proto::if_
- template<typename Expr, typename Condition>
- struct matches_impl<Expr, if_<Condition> >
- : mpl::apply1<Condition, Expr>::type
+ template<typename Expr, typename If, typename Then, typename Else>
+ struct matches_<Expr, proto::if_<If, Then, Else> >
+ : mpl::eval_if<
+ typename when<_, If>::template result<void(Expr, int, int)>::type
+ , matches_<Expr, typename Then::proto_base_expr>
+ , matches_<Expr, typename Else::proto_base_expr>
+ >::type
+ {};
+
+ template<typename Expr, typename If>
+ struct matches_<Expr, proto::if_<If> >
+ : when<_, If>::template result<void(Expr, int, int)>::type
             {};
 
             // handle proto::not_
             template<typename Expr, typename Grammar>
- struct matches_impl<Expr, not_<Grammar> >
- : mpl::not_<matches_impl<Expr, typename Grammar::proto_base_expr> >
+ struct matches_<Expr, not_<Grammar> >
+ : mpl::not_<matches_<Expr, typename Grammar::proto_base_expr> >
             {};
 
             // handle proto::switch_
             template<typename Expr, typename Cases>
- struct matches_impl<Expr, switch_<Cases> >
- : matches_impl<
+ struct matches_<Expr, switch_<Cases> >
+ : matches_<
                     Expr
                   , typename Cases::template case_<typename Expr::proto_tag>::proto_base_expr
>
@@ -351,127 +393,446 @@
 
         namespace result_of
         {
+ /// \brief A Boolean metafunction that evaluates whether a given
+ /// expression type matches a grammar.
+ ///
+ /// <tt>matches\<Expr,Grammar\></tt> inherits (indirectly) from
+ /// \c mpl::true_ if <tt>Expr::proto_base_expr</tt> matches
+ /// <tt>Grammar::proto_base_expr</tt>, and from \c mpl::false_
+ /// otherwise.
+ ///
+ /// Non-terminal expressions are matched against a grammar
+ /// according to the following rules:
+ ///
+ /// \li The wildcard pattern, \c _, matches any expression.
+ /// \li An expression <tt>expr\<AT, argsN\<A0,A1,...An\> \></tt>
+ /// matches a grammar <tt>expr\<BT, argsN\<B0,B1,...Bn\> \></tt>
+ /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx for
+ /// each \c x in <tt>[0,n)</tt>.
+ /// \li An expression <tt>expr\<AT, argsN\<A0,...An,U0,...Um\> \></tt>
+ /// matches a grammar <tt>expr\<BT, argsM\<B0,...Bn,vararg\<V\> \> \></tt>
+ /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx
+ /// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V
+ /// for each \c x in <tt>[0,m)</tt>.
+ /// \li An expression \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E
+ /// matches some \c Bx for \c x in <tt>[0,n)</tt>.
+ /// \li An expression \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
+ /// matches all \c Bx for \c x in <tt>[0,n)</tt>.
+ /// \li An expression \c E matches <tt>if_\<T,U,V\></tt> if
+ /// <tt>when\<_,T\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c true and \c E matches \c U; or, if
+ /// <tt>when\<_,T\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c false and \c E matches \c V. (Note: \c U defaults to \c _
+ /// and \c V defaults to \c not_\<_\>.)
+ /// \li An expression \c E matches <tt>not_\<T\></tt> if \c E does
+ /// not match \c T.
+ /// \li An expression \c E matches <tt>switch_\<C\></tt> if
+ /// \c E matches <tt>C::case_\<E::proto_tag\></tt>.
+ ///
+ /// A terminal expression <tt>expr\<tag::terminal,args0\<A\> \></tt> matches
+ /// a grammar <tt>expr\<BT,args0\<B\> \></tt> if \c BT is \c _ or
+ /// \c tag::terminal and one of the following is true:
+ ///
+ /// \li \c B is the wildcard pattern, \c _
+ /// \li \c A is \c B
+ /// \li \c A is <tt>B &</tt>
+ /// \li \c A is <tt>B const &</tt>
+ /// \li \c B is <tt>exact\<A\></tt>
+ /// \li \c B is <tt>convertible_to\<X\></tt> and
+ /// <tt>is_convertible\<A,X\>::::value</tt> is \c true.
+ /// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
+ /// \c B is <tt>X[proto::N]</tt>.
+ /// \li \c A is <tt>X(&)[M]</tt> and \c B is <tt>X(&)[proto::N]</tt>.
+ /// \li \c A is <tt>X[M]</tt> or <tt>X(&)[M]</tt> and
+ /// \c B is <tt>X*</tt>.
+ /// \li \c B lambda-matches \c A (see below).
+ ///
+ /// A type \c B lambda-matches \c A if one of the following is true:
+ ///
+ /// \li \c B is \c A
+ /// \li \c B is the wildcard pattern, \c _
+ /// \li \c B is <tt>T\<B0,B1,...Bn\></tt> and \c A is
+ /// <tt>T\<A0,A1,...An\></tt> and for each \c x in
+ /// <tt>[0,n)</tt>, \c Ax and \c Bx are types
+ /// such that \c Ax lambda-matches \c Bx
             template<typename Expr, typename Grammar>
             struct matches
- : detail::matches_impl<typename Expr::proto_base_expr, typename Grammar::proto_base_expr>
+ : detail::matches_<
+ typename Expr::proto_base_expr
+ , typename Grammar::proto_base_expr
+ >
             {};
         }
 
         namespace wildcardns_
         {
- struct _
- : has_identity_transform
+ /// \brief A wildcard grammar element that matches any expression,
+ /// and a transform that returns the current expression unchanged.
+ ///
+ /// The wildcard type, \c _, is a grammar element such that
+ /// <tt>matches\<E,_\>::::value</tt> is \c true for any expression
+ /// type \c E.
+ ///
+ /// The wildcard can also be used as a stand-in for a template
+ /// argument when matching terminals. For instance, the following
+ /// is a grammar that will match any <tt>std::complex\<\></tt>
+ /// terminal:
+ ///
+ /// \code
+ /// BOOST_MPL_ASSERT((
+ /// matches<
+ /// terminal<std::complex<double> >::type
+ /// , terminal<std::complex< _ > >
+ /// >
+ /// ));
+ /// \endcode
+ ///
+ /// When used as a transform, \c _ returns the current expression
+ /// unchanged. For instance, in the following, \c _ is used with
+ /// the \c fold\<\> transform to fold the children of a node:
+ ///
+ /// \code
+ /// struct CountChildren
+ /// : or_<
+ /// // Terminals have no children
+ /// when<terminal<_>, mpl::int_<0>()>
+ /// // Use fold<> to count the children of non-terminals
+ /// , otherwise<
+ /// fold<
+ /// _ // <-- fold the current expression
+ /// , mpl::int_<0>()
+ /// , mpl::plus<_state, mpl::int_<1> >()
+ /// >
+ /// >
+ /// >
+ /// {};
+ /// \endcode
+ struct _ : proto::callable
             {
                 typedef _ proto_base_expr;
- typedef void proto_is_wildcard_;
- };
 
- template<typename T>
- transform::detail::yes_type is_wildcard_expression_fun(T const *);
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef Expr type;
+ };
+
+ /// \param expr An expression
+ /// \return \c expr
+ template<typename Expr, typename State, typename Visitor>
+ Expr const &operator ()(Expr const &expr, State const &, Visitor &) const
+ {
+ return expr;
+ }
+ };
         }
 
         namespace control
         {
- // not_
+ /// \brief Inverts the set of expressions matched by a grammar. When
+ /// used as a transform, \c not_\<\> returns the current expression
+ /// unchanged.
+ ///
+ /// If an expression type \c E does not match a grammar \c G, then
+ /// \c E \e does match <tt>not_\<G\></tt>. For example,
+ /// <tt>not_\<terminal\<_\> \></tt> will match any non-terminal.
             template<typename Grammar>
- struct not_
- : has_identity_transform
+ struct not_ : proto::callable
             {
                 typedef not_ proto_base_expr;
- };
 
- // if_
- template<typename Condition, typename Then, typename Else>
- struct if_
- : or_<
- and_<if_<Condition>, Then>
- , and_<not_<if_<Condition> >, Else>
- >
- {};
+ template<typename Sig>
+ struct result;
 
- template<typename Condition, typename Then>
- struct if_<Condition, Then, void>
- : and_<if_<Condition>, Then>
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef Expr type;
+ };
 
- template<typename Condition>
- struct if_<Condition, void, void>
- : has_identity_transform
+ /// \param expr An expression
+ /// \pre <tt>matches\<Expr,not_\>::::value</tt> is \c true.
+ /// \return \c expr
+ template<typename Expr, typename State, typename Visitor>
+ Expr const &operator ()(Expr const &expr, State const &, Visitor &) const
+ {
+ return expr;
+ }
+ };
+
+ /// \brief Used to select one grammar or another based on the result
+ /// of a compile-time Boolean. When used as a transform, \c if_\<\>
+ /// selects between two transforms based on a compile-time Boolean.
+ ///
+ /// When <tt>if_\<If,Then,Else\></tt> is used as a grammar, \c If
+ /// must be a Proto transform and \c Then and \c Else must be grammars.
+ /// An expression type \c E matches <tt>if_\<If,Then,Else\></tt> if
+ /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c true and \c E matches \c U; or, if
+ /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c false and \c E matches \c V.
+ ///
+ /// The template parameter \c Then defaults to \c _
+ /// and \c Else defaults to \c not\<_\>, so an expression type \c E
+ /// will match <tt>if_\<If\></tt> if and only if
+ /// <tt>when\<_,If\>::::result\<void(E,int,int)\>::::type::value</tt>
+ /// is \c true.
+ ///
+ /// \code
+ /// // A grammar that only matches integral terminals,
+ /// // using is_integral<> from Boost.Type_traits.
+ /// struct IsIntegral
+ /// : and_<
+ /// terminal<_>
+ /// , if_< is_integral<_arg>() >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// When <tt>if_\<If,Then,Else\></tt> is used as a transform, \c If,
+ /// \c Then and \c Else must be Proto transforms. When applying
+ /// the transform to an expression \c E, state \c S and visitor \c V,
+ /// if <tt>when\<_,If\>::::result\<void(E,S,V)\>::::type::value</tt>
+ /// is \c true then the \c Then transform is applied; otherwise
+ /// the \c Else transform is applied.
+ ///
+ /// \code
+ /// // Match a terminal. If the terminal is integral, return
+ /// // mpl::true_; otherwise, return mpl::false_.
+ /// struct IsIntegral2
+ /// : when<
+ /// terminal<_>
+ /// , if_<
+ /// is_integral<_arg>()
+ /// , mpl::true_()
+ /// , mpl::false_()
+ /// >
+ /// >
+ /// {};
+ /// \endcode
+ template<
+ typename If
+ , typename Then BOOST_PROTO_FOR_DOXYGEN_ONLY(= _)
+ , typename Else BOOST_PROTO_FOR_DOXYGEN_ONLY(= not_<_>)
+ >
+ struct if_ : proto::callable
             {
                 typedef if_ proto_base_expr;
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename when<_, If>::template result<void(Expr, State, Visitor)>::type
+ condition;
+
+ typedef
+ typename mpl::if_<
+ condition
+ , when<_, Then>
+ , when<_, Else>
+ >::type
+ which;
+
+ typedef typename which::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param visitor A visitor of arbitrary type
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::which()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ typename result<void(Expr, State, Visitor)>::which
+ which;
+
+ return which()(expr, state, visitor);
+ }
             };
 
- // or_
+ /// \brief For matching one of a set of alternate grammars. Alternates
+ /// tried in order to avoid ambiguity. When used as a transform, \c or_\<\>
+ /// applies the transform associated with the first grammar that matches
+ /// the expression.
+ ///
+ /// An expression type \c E matches <tt>or_\<B0,B1,...Bn\></tt> if \c E
+ /// matches any \c Bx for \c x in <tt>[0,n)</tt>.
+ ///
+ /// When applying <tt>or_\<B0,B1,...Bn\></tt> as a transform with an
+ /// expression \c e of type \c E, state \c s and visitor \c v, it is
+ /// equivalent to <tt>Bx()(e, s, v)</tt>, where \c x is the lowest
+ /// number such that <tt>matches\<E,Bx\>::::value</tt> is \c true.
             template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
- struct or_
+ struct or_ : proto::callable
             {
                 typedef or_ proto_base_expr;
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
                 {
- typedef typename detail::matches_impl<Expr, or_>::which which;
- typedef typename which::template apply<Expr, State, Visitor>::type type;
+ typedef typename detail::matches_<Expr, or_>::which which;
+ typedef typename which::template result<void(Expr, State, Visitor)>::type type;
                 };
 
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param visitor A visitor of arbitrary type
+ /// \pre <tt>matches\<Expr,or_\>::::value</tt> is \c true.
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::which()(expr, state, visitor)</tt>
                 template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
                 {
- typedef typename detail::matches_impl<Expr, or_>::which which;
- return which::call(expr, state, visitor);
+ typedef typename detail::matches_<Expr, or_>::which which;
+ return which()(expr, state, visitor);
                 }
             };
 
- // and_
+ /// \brief For matching all of a set of grammars. When used as a
+ /// transform, \c and_\<\> applies the transform associated with
+ /// the last grammar in the set.
+ ///
+ /// An expression type \c E matches <tt>and_\<B0,B1,...Bn\></tt> if \c E
+ /// matches all \c Bx for \c x in <tt>[0,n)</tt>.
+ ///
+ /// When applying <tt>and_\<B0,B1,...Bn\></tt> as a transform with an
+ /// expression \c e, state \c s and visitor \c v, it is
+ /// equivalent to <tt>Bn()(e, s, v)</tt>.
             template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
- struct and_
+ struct and_ : proto::callable
             {
                 typedef and_ proto_base_expr;
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
                 {
                     typedef typename detail::last<and_>::type which;
- typedef typename which::template apply<Expr, State, Visitor>::type type;
+ typedef typename which::template result<void(Expr, State, Visitor)>::type type;
                 };
 
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param visitor A visitor of arbitrary type
+ /// \pre <tt>matches\<Expr,and_\>::::value</tt> is \c true.
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::which()(expr, state, visitor)</tt>
                 template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
                 {
                     typedef typename detail::last<and_>::type which;
- return which::call(expr, state, visitor);
+ return which()(expr, state, visitor);
                 }
             };
 
- // switch_
+ /// \brief For matching one of a set of alternate grammars, which
+ /// are looked up based on an expression's tag type. When used as a
+ /// transform, \c switch_\<\> applies the transform associated with
+ /// the grammar that matches the expression.
+ ///
+ /// \note \c switch_\<\> is functionally identical to \c or_\<\> but
+ /// is often more efficient. It does a fast, O(1) lookup based on an
+ /// expression's tag type to find a sub-grammar that may potentially
+ /// match the expression.
+ ///
+ /// An expression type \c E matches <tt>switch_\<C\></tt> if \c E
+ /// matches <tt>C::case_\<E::proto_tag\></tt>.
+ ///
+ /// When applying <tt>switch_\<C\></tt> as a transform with an
+ /// expression \c e of type \c E, state \c s and visitor \c v, it is
+ /// equivalent to <tt>C::case_\<E::proto_tag\>()(e, s, v)</tt>.
             template<typename Cases>
- struct switch_
+ struct switch_ : proto::callable
             {
                 typedef switch_ proto_base_expr;
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : Cases::template case_<typename Expr::proto_tag>::template apply<Expr, State, Visitor>
- {};
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename Cases::template case_<typename Expr::proto_tag> which;
+ typedef typename which::template result<void(Expr, State, Visitor)>::type type;
+ };
 
+ /// \param expr An expression
+ /// \param state The current state
+ /// \param visitor A visitor of arbitrary type
+ /// \pre <tt>matches\<Expr,switch_\>::::value</tt> is \c true.
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::which()(expr, state, visitor)</tt>
                 template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
                 {
- return Cases::template case_<typename Expr::proto_tag>::call(expr, state, visitor);
+ typedef typename Cases::template case_<typename Expr::proto_tag> which;
+ return which()(expr, state, visitor);
                 }
             };
 
+ /// \brief For forcing exact matches of terminal types.
+ ///
+ /// By default, matching terminals ignores references and
+ /// cv-qualifiers. For instance, a terminal expression of
+ /// type <tt>terminal\<int const &\>::::type</tt> will match
+ /// the grammar <tt>terminal\<int\></tt>. If that is not
+ /// desired, you can force an exact match with
+ /// <tt>terminal\<exact\<int\> \></tt>. This will only
+ /// match integer terminals where the terminal is held by
+ /// value.
             template<typename T>
             struct exact
             {};
 
+ /// \brief For matching terminals that are convertible to
+ /// a type.
+ ///
+ /// Use \c convertible_to\<\> to match a terminal that is
+ /// convertible to some type. For example, the grammar
+ /// <tt>terminal\<convertible_to\<int\> \></tt> will match
+ /// any terminal whose argument is convertible to an integer.
+ ///
+ /// \note The trait \c is_convertible\<\> from Boost.Type_traits
+ /// is used to determinal convertibility.
             template<typename T>
             struct convertible_to
             {};
 
+ /// \brief For matching a Grammar to a variable number of
+ /// sub-expressions.
+ ///
+ /// An expression type <tt>expr\<AT, argsN\<A0,...An,U0,...Um\> \></tt>
+ /// matches a grammar <tt>expr\<BT, argsM\<B0,...Bn,vararg\<V\> \> \></tt>
+ /// if \c BT is \c _ or \c AT, and if \c Ax matches \c Bx
+ /// for each \c x in <tt>[0,n)</tt> and if \c Ux matches \c V
+ /// for each \c x in <tt>[0,m)</tt>.
+ ///
+ /// For example:
+ ///
+ /// \code
+ /// // Match any function call expression, irregardless
+ /// // of the number of function arguments:
+ /// struct Function
+ /// : function< vararg<_> >
+ /// {};
+ /// \endcode
+ ///
+ /// When used as a transform, <tt>vararg\<G\></tt> applies
+ /// <tt>G</tt>'s transform.
             template<typename Grammar>
             struct vararg
               : Grammar
@@ -479,6 +840,42 @@
                 typedef void proto_is_vararg_;
             };
         }
+
+ /// INTERNAL ONLY
+ ///
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
+ struct is_callable<or_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, typename G)>
+ struct is_callable<and_<BOOST_PP_ENUM_PARAMS(BOOST_PROTO_MAX_LOGICAL_ARITY, G)> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Grammar>
+ struct is_callable<not_<Grammar> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename If, typename Then, typename Else>
+ struct is_callable<if_<If, Then, Else> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Grammar>
+ struct is_callable<vararg<Grammar> >
+ : mpl::true_
+ {};
+
     }}
 
     #if defined(_MSC_VER) && (_MSC_VER >= 1020)
@@ -514,7 +911,7 @@
             template<bool B, typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
             struct BOOST_PP_CAT(or, N)
               : BOOST_PP_CAT(or, BOOST_PP_DEC(N))<
- matches_impl<Expr, typename G1::proto_base_expr>::value
+ matches_<Expr, typename G1::proto_base_expr>::value
                   , Expr, BOOST_PP_ENUM_SHIFTED_PARAMS(N, G)
>
             {};
@@ -528,16 +925,16 @@
 
             // handle proto::or_
             template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
- struct matches_impl<Expr, proto::or_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ struct matches_<Expr, proto::or_<BOOST_PP_ENUM_PARAMS(N, G)> >
               : BOOST_PP_CAT(or, N)<
- matches_impl<typename Expr::proto_base_expr, typename G0::proto_base_expr>::value,
+ matches_<typename Expr::proto_base_expr, typename G0::proto_base_expr>::value,
                     typename Expr::proto_base_expr, BOOST_PP_ENUM_PARAMS(N, G)
>
             {};
 
             // handle proto::and_
             template<typename Expr, BOOST_PP_ENUM_PARAMS(N, typename G)>
- struct matches_impl<Expr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
+ struct matches_<Expr, proto::and_<BOOST_PP_ENUM_PARAMS(N, G)> >
               : detail::BOOST_PP_CAT(and, N)<
                     BOOST_PROTO_DEFINE_MATCHES(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_DEFINE_MATCHES, ~)
@@ -554,14 +951,14 @@
             template<typename Args, typename Back, long To>
             struct vararg_matches_impl<Args, Back, N, To>
               : and2<
- matches_impl<typename Args::BOOST_PP_CAT(arg, BOOST_PP_DEC(N))::proto_base_expr, Back>::value
+ matches_<typename Args::BOOST_PP_CAT(arg, BOOST_PP_DEC(N))::proto_base_expr, Back>::value
                   , vararg_matches_impl<Args, Back, N + 1, To>
>
             {};
 
             template<typename Args, typename Back>
             struct vararg_matches_impl<Args, Back, N, N>
- : matches_impl<typename Args::BOOST_PP_CAT(arg, BOOST_PP_DEC(N))::proto_base_expr, Back>
+ : matches_<typename Args::BOOST_PP_CAT(arg, BOOST_PP_DEC(N))::proto_base_expr, Back>
             {};
 
             template<
@@ -577,7 +974,7 @@
             {};
 
             template<typename Tag, typename Args1, typename Args2>
- struct matches_impl< expr<Tag, Args1, N>, expr<Tag, Args2, N> >
+ struct matches_< proto::expr<Tag, Args1, N>, proto::expr<Tag, Args2, N> >
               : BOOST_PP_CAT(and, N)<
                     BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)
@@ -585,7 +982,7 @@
             {};
 
             template<typename Tag, typename Args1, typename Args2>
- struct matches_impl< expr<Tag, Args1, N>, expr<proto::_, Args2, N> >
+ struct matches_< proto::expr<Tag, Args1, N>, proto::expr<proto::_, Args2, N> >
               : BOOST_PP_CAT(and, N)<
                     BOOST_PROTO_MATCHES_N_FUN(~, 0, ~)::value,
                     BOOST_PP_ENUM_SHIFTED(N, BOOST_PROTO_MATCHES_N_FUN, ~)

Modified: branches/release/boost/xpressive/proto/operators.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/operators.hpp (original)
+++ branches/release/boost/xpressive/proto/operators.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,9 +1,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file operators.hpp
 /// Contains all the overloaded operators that make it possible to build
-/// expression templates using proto components
+/// Proto expression trees.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -35,17 +35,17 @@
         struct as_expr_if2<Tag, Left, Right, typename Left::proto_is_expr_, void>
           : generate_if<
                 typename Left::proto_domain
- , expr<
+ , proto::expr<
                     Tag
                   , args2<
                         ref_<Left>
- , typename Left::proto_domain::template apply<expr<tag::terminal, args0<Right &> > >::type
+ , typename Left::proto_domain::template apply<proto::expr<tag::terminal, args0<Right &> > >::type
>
>
>
         {
- typedef expr<tag::terminal, args0<Right &> > term_type;
- typedef expr<Tag, args2<ref_<Left>, typename Left::proto_domain::template apply<term_type>::type> > expr_type;
+ typedef proto::expr<tag::terminal, args0<Right &> > term_type;
+ typedef proto::expr<Tag, args2<ref_<Left>, typename Left::proto_domain::template apply<term_type>::type> > expr_type;
 
             static typename Left::proto_domain::template apply<expr_type>::type
             make(Left &left, Right &right)
@@ -60,17 +60,17 @@
         struct as_expr_if2<Tag, Left, Right, void, typename Right::proto_is_expr_>
           : generate_if<
                 typename Right::proto_domain
- , expr<
+ , proto::expr<
                     Tag
                   , args2<
- typename Right::proto_domain::template apply<expr<tag::terminal, args0<Left &> > >::type
+ typename Right::proto_domain::template apply<proto::expr<tag::terminal, args0<Left &> > >::type
                       , ref_<Right>
>
>
>
         {
- typedef expr<tag::terminal, args0<Left &> > term_type;
- typedef expr<Tag, args2<typename Right::proto_domain::template apply<term_type>::type, ref_<Right> > > expr_type;
+ typedef proto::expr<tag::terminal, args0<Left &> > term_type;
+ typedef proto::expr<Tag, args2<typename Right::proto_domain::template apply<term_type>::type, ref_<Right> > > expr_type;
 
             static typename Right::proto_domain::template apply<expr_type>::type
             make(Left &left, Right &right)
@@ -90,10 +90,10 @@
         struct as_expr_if<Tag, Left, Right, typename Left::proto_is_expr_, typename Right::proto_is_expr_>
           : generate_if<
                 typename Left::proto_domain
- , expr<Tag, args2<ref_<Left>, ref_<Right> > >
+ , proto::expr<Tag, args2<ref_<Left>, ref_<Right> > >
>
         {
- typedef expr<Tag, args2<ref_<Left>, ref_<Right> > > expr_type;
+ typedef proto::expr<Tag, args2<ref_<Left>, ref_<Right> > > expr_type;
             BOOST_MPL_ASSERT((is_same<typename Left::proto_domain, typename Right::proto_domain>));
 
             static typename Left::proto_domain::template apply<expr_type>::type
@@ -119,7 +119,7 @@
         template<typename Domain, typename Trait, typename Arg, typename Expr>
         struct enable_unary
           : boost::enable_if<
- boost::mpl::and_<Trait, boost::proto::matches<Expr, typename Domain::grammar> >
+ boost::mpl::and_<Trait, boost::proto::matches<Expr, typename Domain::proto_grammar> >
               , Expr
>
         {};
@@ -129,7 +129,7 @@
           : boost::enable_if<
                 boost::mpl::and_<
                     Trait
- , boost::proto::matches<Expr, typename domain_of<Arg>::type::grammar>
+ , boost::proto::matches<Expr, typename domain_of<Arg>::type::proto_grammar>
>
               , Expr
>
@@ -145,7 +145,7 @@
           : boost::enable_if<
                 boost::mpl::and_<
                     mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
- , boost::proto::matches<Expr, typename Domain::grammar>
+ , boost::proto::matches<Expr, typename Domain::proto_grammar>
>
               , Expr
>
@@ -156,7 +156,7 @@
           : boost::enable_if<
                 boost::mpl::and_<
                     mpl::bool_<(3 <= (arg_weight<Arg1, Trait1>::value + arg_weight<Arg2, Trait2>::value))>
- , boost::proto::matches<Expr, typename deduce_domain_<typename domain_of<Arg1>::type, Arg2>::type::grammar>
+ , boost::proto::matches<Expr, typename deduce_domain_<typename domain_of<Arg1>::type, Arg2>::type::proto_grammar>
>
               , Expr
>
@@ -179,22 +179,22 @@
     template<typename Arg> \
     typename detail::generate_if< \
         typename Arg::proto_domain \
- , expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > \
+ , proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > \
>::type const \
     operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
     { \
- typedef expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > that_type; \
+ typedef proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr> > > that_type; \
         that_type that = {{arg}}; \
         return Arg::proto_domain::make(that); \
     } \
     template<typename Arg> \
     typename detail::generate_if< \
         typename Arg::proto_domain \
- , expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > \
+ , proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > \
>::type const \
     operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
     { \
- typedef expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > that_type; \
+ typedef proto::expr<TAG, args1<ref_<typename Arg::proto_derived_expr const> > > that_type; \
         that_type that = {{arg}}; \
         return Arg::proto_domain::make(that); \
     } \
@@ -291,58 +291,54 @@
 #define BOOST_PROTO_DEFINE_UNARY_OPERATOR(OP, TAG, TRAIT, DOMAIN, POST) \
     template<typename Arg> \
     typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
- , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg>::type \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg &>::type \
>::type const \
     operator OP(Arg &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
     { \
- return boost::proto::result_of::make_expr<TAG, DOMAIN, Arg>::call(arg); \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg)); \
     } \
     template<typename Arg> \
     typename boost::proto::detail::enable_unary<DOMAIN, TRAIT<Arg>, Arg \
- , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const>::type \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const &>::type \
>::type const \
     operator OP(Arg const &arg BOOST_PROTO_UNARY_OP_IS_POSTFIX_ ## POST) \
     { \
- return boost::proto::result_of::make_expr<TAG, DOMAIN, Arg const>::call(arg); \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(arg)); \
     } \
     /**/
 
 #define BOOST_PROTO_DEFINE_BINARY_OPERATOR(OP, TAG, TRAIT, DOMAIN) \
     template<typename Left, typename Right> \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
- , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right>::type \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right &>::type \
>::type const \
     operator OP(Left &left, Right &right) \
     { \
- return boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right> \
- ::call(left, right); \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
     } \
     template<typename Left, typename Right> \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
- , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right const>::type \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left &, Right const &>::type \
>::type const \
     operator OP(Left &left, Right const &right) \
     { \
- return boost::proto::result_of::make_expr<TAG, DOMAIN, Left, Right const> \
- ::call(left, right); \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
     } \
     template<typename Left, typename Right> \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
- , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right>::type \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right &>::type \
>::type const \
     operator OP(Left const &left, Right &right) \
     { \
- return boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right> \
- ::call(left, right); \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
     } \
     template<typename Left, typename Right> \
     typename boost::proto::detail::enable_binary<DOMAIN, TRAIT<Left>, Left, TRAIT<Right>, Right \
- , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right const>::type \
+ , typename boost::proto::result_of::make_expr<TAG, DOMAIN, Left const &, Right const &>::type\
>::type const \
     operator OP(Left const &left, Right const &right) \
     { \
- return boost::proto::result_of::make_expr<TAG, DOMAIN, Left const, Right const> \
- ::call(left, right); \
+ return boost::proto::make_expr<TAG, DOMAIN>(boost::ref(left), boost::ref(right)); \
     } \
     /**/
 

Modified: branches/release/boost/xpressive/proto/proto.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/proto.hpp (original)
+++ branches/release/boost/xpressive/proto/proto.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,8 +1,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file proto.hpp
-/// The proto expression template compiler and supporting utilities.
+/// Includes the core of Proto. Not included are the contexts, transforms and
+/// debugging utilities.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -18,6 +19,7 @@
 #include <boost/xpressive/proto/expr.hpp>
 #include <boost/xpressive/proto/traits.hpp>
 #include <boost/xpressive/proto/domain.hpp>
+#include <boost/xpressive/proto/fusion.hpp>
 #include <boost/xpressive/proto/matches.hpp>
 #include <boost/xpressive/proto/extends.hpp>
 #include <boost/xpressive/proto/literal.hpp>

Modified: branches/release/boost/xpressive/proto/proto_fwd.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/proto_fwd.hpp (original)
+++ branches/release/boost/xpressive/proto/proto_fwd.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file proto_fwd.hpp
 /// Forward declarations of all of proto's public types and functions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -13,12 +13,14 @@
 #include <cstddef>
 #include <climits>
 #include <boost/config.hpp>
+#include <boost/version.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
 #include <boost/mpl/long.hpp>
-#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_const.hpp>
 #include <boost/type_traits/remove_reference.hpp>
 
 #ifndef BOOST_PROTO_MAX_ARITY
@@ -29,6 +31,14 @@
 # define BOOST_PROTO_MAX_LOGICAL_ARITY 8
 #endif
 
+#ifndef BOOST_PROTO_MAX_FUNCTION_CALL_ARITY
+# define BOOST_PROTO_MAX_FUNCTION_CALL_ARITY BOOST_PROTO_MAX_ARITY
+#endif
+
+#if BOOST_PROTO_MAX_FUNCTION_CALL_ARITY > BOOST_PROTO_MAX_ARITY
+# error BOOST_PROTO_MAX_FUNCTION_CALL_ARITY cannot be larger than BOOST_PROTO_MAX_ARITY
+#endif
+
 #if BOOST_WORKAROUND(__GNUC__, == 3) \
  || BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(306))
 # define BOOST_PROTO_BROKEN_CONST_OVERLOADS
@@ -38,13 +48,58 @@
 # include <boost/utility/enable_if.hpp>
 # include <boost/type_traits/is_const.hpp>
 # define BOOST_PROTO_DISABLE_IF_IS_CONST(T)\
- , typename boost::disable_if<boost::is_const<T> >::type * = 0
+ , typename boost::disable_if<boost::is_const<T>, boost::proto::detail::undefined>::type * = 0
 #else
 # define BOOST_PROTO_DISABLE_IF_IS_CONST(T)
 #endif
 
+#if BOOST_VERSION < 103500
+#define BOOST_PROTO_DEFINE_FUSION_TAG(X) typedef X tag;
+#define BOOST_PROTO_DEFINE_FUSION_CATEGORY(X)
+#define BOOST_PROTO_FUSION_RESULT_OF meta
+#define BOOST_PROTO_FUSION_EXTENSION meta
+#define BOOST_PROTO_FUSION_AT_C(N, X) at<N>(X)
+#else
+#define BOOST_PROTO_DEFINE_FUSION_TAG(X) typedef X fusion_tag;
+#define BOOST_PROTO_DEFINE_FUSION_CATEGORY(X) typedef X category;
+#define BOOST_PROTO_FUSION_RESULT_OF result_of
+#define BOOST_PROTO_FUSION_EXTENSION extension
+#define BOOST_PROTO_FUSION_AT_C(N, X) at_c<N>(X)
+#endif
+
 #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
 
+#ifdef BOOST_PROTO_DOXYGEN_INVOKED
+// HACKHACK so Doxygen shows inheritance from mpl::true_ and mpl::false_
+namespace boost
+{
+ /// INTERNAL ONLY
+ ///
+ namespace mpl
+ {
+ /// INTERNAL ONLY
+ ///
+ struct true_ {};
+ /// INTERNAL ONLY
+ ///
+ struct false_ {};
+ }
+
+ /// INTERNAL ONLY
+ ///
+ namespace fusion
+ {
+ /// INTERNAL ONLY
+ ///
+ template<typename Function>
+ class unfused_generic {};
+ }
+}
+#define BOOST_PROTO_FOR_DOXYGEN_ONLY(x) x
+#else
+#define BOOST_PROTO_FOR_DOXYGEN_ONLY(x)
+#endif
+
 namespace boost { namespace proto
 {
     namespace detail
@@ -52,15 +107,13 @@
         typedef char yes_type;
         typedef char (&no_type)[2];
 
- struct dont_care
- {
- dont_care(...);
- };
+ struct dont_care;
+ struct undefined; // leave this undefined
 
- template<typename T>
- struct remove_cv_ref
- : remove_cv<typename remove_reference<T>::type>
- {};
+ /// INTERNAL ONLY
+ ///
+ #define BOOST_PROTO_UNCVREF(X) \
+ typename boost::remove_const<typename boost::remove_reference<X>::type>::type
     }
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -117,8 +170,8 @@
 
         // Fusion tags
         struct proto_expr;
- struct proto_ref;
- struct proto_ref_iterator;
+ struct proto_expr_iterator;
+ struct proto_flat_view;
     }
 
     namespace wildcardns_
@@ -194,26 +247,34 @@
         template<
             typename Grammar0
           , typename Grammar1
- , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2), typename G, void)
+ , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2)
+ , typename G
+ , void
+ )
>
         struct or_;
 
         template<
             typename Grammar0
           , typename Grammar1
- , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2), typename G, void)
+ , BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
+ BOOST_PP_SUB(BOOST_PROTO_MAX_LOGICAL_ARITY,2)
+ , typename G
+ , void
+ )
>
         struct and_;
 
- template<typename Condition, typename Then = void, typename Else = void>
+ template<typename Grammar>
+ struct not_;
+
+ template<typename Condition, typename Then = _, typename Else = not_<_> >
         struct if_;
 
         template<typename Cases>
         struct switch_;
 
- template<typename Grammar>
- struct not_;
-
         template<typename T>
         struct exact;
 
@@ -272,10 +333,10 @@
 
     namespace result_of
     {
- template<typename T, typename Domain = default_domain, typename EnableIf = void>
+ template<typename T, typename Domain = default_domain, typename Void = void>
         struct as_expr;
 
- template<typename T, typename Domain = default_domain, typename EnableIf = void>
+ template<typename T, typename Domain = default_domain, typename Void = void>
         struct as_arg;
 
         template<typename Expr, typename N = mpl::long_<0> >
@@ -301,37 +362,34 @@
 
         template<
             typename Tag
+ , typename DomainOrA0
             BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(
                 BOOST_PROTO_MAX_ARITY
               , typename A
               , = void BOOST_PP_INTERCEPT
             )
- , typename _1 = void
- , typename _2 = void
+ , typename Void = void
>
         struct make_expr;
 
- template<typename Tag, typename DomainOrSequence, typename SequenceOrVoid = void, typename _ = void>
+ template<typename Tag, typename DomainOrSequence, typename SequenceOrVoid = void, typename Void = void>
         struct unpack_expr;
 
- template<typename T, typename EnableIf = void>
+ template<typename T, typename Void = void>
         struct is_ref;
 
- template<typename T, typename EnableIf = void>
+ template<typename T, typename Void = void>
         struct is_expr;
 
- template<typename T, typename EnableIf = void>
+ template<typename T, typename Void = void>
         struct is_domain;
 
         template<typename Expr>
         struct tag_of;
 
- template<typename T, typename EnableIf = void>
+ template<typename T, typename Void = void>
         struct domain_of;
 
- template<typename Expr>
- struct id;
-
         template<typename Expr, typename Grammar>
         struct matches;
     }
@@ -341,7 +399,6 @@
     using proto::result_of::is_domain;
     using proto::result_of::tag_of;
     using proto::result_of::domain_of;
- using proto::result_of::id;
     using proto::result_of::matches;
 
     namespace op
@@ -415,6 +472,7 @@
         struct left;
         struct right;
         struct unref;
+ struct eval;
         struct deep_copy;
 
         template<typename Domain = default_domain>
@@ -440,124 +498,214 @@
 
         template<typename Tag, typename Domain = deduce_domain>
         struct unfused_expr;
- }
-
-#define BOOST_PROTO_IDENTITY_TRANSFORM()\
- template<typename Expr_, typename State_, typename Visitor_>\
- static Expr_ const &call(Expr_ const &expr_, State_ const &, Visitor_ &)\
- {\
- return expr_;\
- }\
- template<typename Expr_, typename, typename>\
- struct apply\
- {\
- typedef Expr_ type;\
- }
 
- namespace transform
- {
- namespace detail
- {
- using proto::detail::yes_type;
- using proto::detail::no_type;
-
- struct default_factory;
-
- no_type is_wildcard_expression_fun(...);
-
- template<typename T>
- struct is_wildcard_expression;
- }
+ typedef make_expr<tag::terminal> make_terminal;
+ typedef make_expr<tag::posit> make_posit;
+ typedef make_expr<tag::negate> make_negate;
+ typedef make_expr<tag::dereference> make_dereference;
+ typedef make_expr<tag::complement> make_complement;
+ typedef make_expr<tag::address_of> make_address_of;
+ typedef make_expr<tag::logical_not> make_logical_not;
+ typedef make_expr<tag::pre_inc> make_pre_inc;
+ typedef make_expr<tag::pre_dec> make_pre_dec;
+ typedef make_expr<tag::post_inc> make_post_inc;
+ typedef make_expr<tag::post_dec> make_post_dec;
+ typedef make_expr<tag::shift_left> make_shift_left;
+ typedef make_expr<tag::shift_right> make_shift_right;
+ typedef make_expr<tag::multiplies> make_multiplies;
+ typedef make_expr<tag::divides> make_divides;
+ typedef make_expr<tag::modulus> make_modulus;
+ typedef make_expr<tag::plus> make_plus;
+ typedef make_expr<tag::minus> make_minus;
+ typedef make_expr<tag::less> make_less;
+ typedef make_expr<tag::greater> make_greater;
+ typedef make_expr<tag::less_equal> make_less_equal;
+ typedef make_expr<tag::greater_equal> make_greater_equal;
+ typedef make_expr<tag::equal_to> make_equal_to;
+ typedef make_expr<tag::not_equal_to> make_not_equal_to;
+ typedef make_expr<tag::logical_or> make_logical_or;
+ typedef make_expr<tag::logical_and> make_logical_and;
+ typedef make_expr<tag::bitwise_and> make_bitwise_and;
+ typedef make_expr<tag::bitwise_or> make_bitwise_or;
+ typedef make_expr<tag::bitwise_xor> make_bitwise_xor;
+ typedef make_expr<tag::comma> make_comma;
+ typedef make_expr<tag::mem_ptr> make_mem_ptr;
+ typedef make_expr<tag::assign> make_assign;
+ typedef make_expr<tag::shift_left_assign> make_shift_left_assign;
+ typedef make_expr<tag::shift_right_assign> make_shift_right_assign;
+ typedef make_expr<tag::multiplies_assign> make_multiplies_assign;
+ typedef make_expr<tag::divides_assign> make_divides_assign;
+ typedef make_expr<tag::modulus_assign> make_modulus_assign;
+ typedef make_expr<tag::plus_assign> make_plus_assign;
+ typedef make_expr<tag::minus_assign> make_minus_assign;
+ typedef make_expr<tag::bitwise_and_assign> make_bitwise_and_assign;
+ typedef make_expr<tag::bitwise_or_assign> make_bitwise_or_assign;
+ typedef make_expr<tag::bitwise_xor_assign> make_bitwise_xor_assign;
+ typedef make_expr<tag::subscript> make_subscript;
+ typedef make_expr<tag::if_else_> make_if_else;
+ typedef make_expr<tag::function> make_function;
+
+ struct flatten;
+ struct pop_front;
+ struct reverse;
+ }
+
+ typedef functional::make_terminal _make_terminal;
+ typedef functional::make_posit _make_posit;
+ typedef functional::make_negate _make_negate;
+ typedef functional::make_dereference _make_dereference;
+ typedef functional::make_complement _make_complement;
+ typedef functional::make_address_of _make_address_of;
+ typedef functional::make_logical_not _make_logical_not;
+ typedef functional::make_pre_inc _make_pre_inc;
+ typedef functional::make_pre_dec _make_pre_dec;
+ typedef functional::make_post_inc _make_post_inc;
+ typedef functional::make_post_dec _make_post_dec;
+ typedef functional::make_shift_left _make_shift_left;
+ typedef functional::make_shift_right _make_shift_right;
+ typedef functional::make_multiplies _make_multiplies;
+ typedef functional::make_divides _make_divides;
+ typedef functional::make_modulus _make_modulus;
+ typedef functional::make_plus _make_plus;
+ typedef functional::make_minus _make_minus;
+ typedef functional::make_less _make_less;
+ typedef functional::make_greater _make_greater;
+ typedef functional::make_less_equal _make_less_equal;
+ typedef functional::make_greater_equal _make_greater_equal;
+ typedef functional::make_equal_to _make_equal_to;
+ typedef functional::make_not_equal_to _make_not_equal_to;
+ typedef functional::make_logical_or _make_logical_or;
+ typedef functional::make_logical_and _make_logical_and;
+ typedef functional::make_bitwise_and _make_bitwise_and;
+ typedef functional::make_bitwise_or _make_bitwise_or;
+ typedef functional::make_bitwise_xor _make_bitwise_xor;
+ typedef functional::make_comma _make_comma;
+ typedef functional::make_mem_ptr _make_mem_ptr;
+ typedef functional::make_assign _make_assign;
+ typedef functional::make_shift_left_assign _make_shift_left_assign;
+ typedef functional::make_shift_right_assign _make_shift_right_assign;
+ typedef functional::make_multiplies_assign _make_multiplies_assign;
+ typedef functional::make_divides_assign _make_divides_assign;
+ typedef functional::make_modulus_assign _make_modulus_assign;
+ typedef functional::make_plus_assign _make_plus_assign;
+ typedef functional::make_minus_assign _make_minus_assign;
+ typedef functional::make_bitwise_and_assign _make_bitwise_and_assign;
+ typedef functional::make_bitwise_or_assign _make_bitwise_or_assign;
+ typedef functional::make_bitwise_xor_assign _make_bitwise_xor_assign;
+ typedef functional::make_subscript _make_subscript;
+ typedef functional::make_if_else _make_if_else;
+ typedef functional::make_function _make_function;
+
+ typedef functional::flatten _flatten;
+ typedef functional::pop_front _pop_front;
+ typedef functional::reverse _reverse;
+ typedef functional::deep_copy _eval;
+ typedef functional::deep_copy _deep_copy;
 
- template<typename Grammar, typename N = mpl::long_<0> >
- struct arg;
-
- template<typename Grammar, long N>
- struct arg_c;
-
- template<typename Grammar>
- struct left;
-
- template<typename Grammar>
- struct right;
+ template<typename T>
+ struct is_callable;
 
- template<typename Grammar>
- struct state;
+ template<typename T>
+ struct is_aggregate;
 
- template<typename Grammar>
- struct visitor;
+ namespace transform
+ {
+ #define BOOST_PROTO_CALLABLE() typedef void proto_is_callable_;
 
- template<typename Grammar>
- struct identity;
+ struct callable
+ {
+ BOOST_PROTO_CALLABLE()
+ };
 
- template<typename Grammar, typename Always, typename Factory = detail::default_factory>
- struct always;
+ template<typename Grammar, typename Fun = Grammar>
+ struct when;
 
- template<typename Grammar, typename Lambda, typename Factory = detail::default_factory>
- struct apply1;
+ template<typename Fun>
+ struct otherwise;
 
- template<typename Grammar, typename Lambda, typename Factory = detail::default_factory>
- struct apply2;
+ template<typename Fun>
+ struct call;
 
- template<typename Grammar, typename Lambda, typename Factory = detail::default_factory>
- struct apply3;
+ template<typename Fun>
+ struct make;
 
- template<typename Grammar, typename State>
- struct branch;
+ template<typename Fun>
+ struct bind;
 
- template<typename Grammar, typename State = void>
+ template<typename Sequence, typename State, typename Fun>
         struct fold;
 
- template<typename Grammar, typename State = void>
+ template<typename Sequence, typename State, typename Fun>
         struct reverse_fold;
 
- template<typename Tag, typename Grammar, typename State = void>
+ // BUGBUG can we replace fold_tree with fold<flatten(_), state, fun> ?
+ template<typename Sequence, typename State, typename Fun>
         struct fold_tree;
 
- template<typename Tag, typename Grammar, typename State = void>
+ template<typename Sequence, typename State, typename Fun>
         struct reverse_fold_tree;
 
- template<typename Grammar, typename Function1>
- struct function1;
-
- template<typename Grammar, typename Function2>
- struct function2;
-
- template<typename Grammar, typename Function3>
- struct function3;
-
- template<typename Grammar>
- struct list;
-
- template<typename Grammar>
- struct tail;
-
         template<typename Grammar>
         struct pass_through;
 
- template<typename Grammar, typename ConstructorFun>
- struct construct;
-
- template<typename Grammar, typename ConstructorFun>
- struct pod_construct;
- }
+ struct expr;
+ struct state;
+ struct visitor;
 
- namespace has_transformns_
- {
- template<typename Grammar>
- struct has_pass_through_transform;
+ template<int I>
+ struct arg_c;
 
- struct has_identity_transform
- {
- BOOST_PROTO_IDENTITY_TRANSFORM();
- };
- }
+ typedef arg_c<0> arg0;
+ typedef arg_c<1> arg1;
+ typedef arg_c<2> arg2;
+ typedef arg_c<3> arg3;
+ typedef arg_c<4> arg4;
+ typedef arg_c<5> arg5;
+ typedef arg_c<6> arg6;
+ typedef arg_c<7> arg7;
+ typedef arg_c<8> arg8;
+ typedef arg_c<9> arg9;
+
+ typedef arg0 arg;
+ typedef arg0 left;
+ typedef arg1 right;
+
+ struct _ref;
+ }
+
+ using transform::when;
+ using transform::call;
+ using transform::make;
+ using transform::bind;
+ using transform::fold;
+ using transform::otherwise;
+ using transform::reverse_fold;
+ using transform::fold_tree;
+ using transform::reverse_fold_tree;
+ using transform::callable;
+ using transform::pass_through;
+
+ typedef transform::expr _expr;
+ typedef transform::state _state;
+ typedef transform::visitor _visitor;
+ typedef transform::arg0 _arg0;
+ typedef transform::arg1 _arg1;
+ typedef transform::arg2 _arg2;
+ typedef transform::arg3 _arg3;
+ typedef transform::arg4 _arg4;
+ typedef transform::arg5 _arg5;
+ typedef transform::arg6 _arg6;
+ typedef transform::arg7 _arg7;
+ typedef transform::arg8 _arg8;
+ typedef transform::arg9 _arg9;
+ typedef transform::arg _arg;
+ typedef transform::left _left;
+ typedef transform::right _right;
 
- using has_transformns_::has_identity_transform;
- using has_transformns_::has_pass_through_transform;
+ template<int I>
+ struct _arg_c;
 
- template<typename T>
- struct is_transform;
+ using transform::_ref;
 
     template<typename T>
     struct is_extension;
@@ -565,6 +713,10 @@
     namespace exops
     {}
 
+ typedef void ignore_();
+ inline void ignore()
+ {}
+
 }} // namespace boost::proto
 
 #endif

Modified: branches/release/boost/xpressive/proto/proto_typeof.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/proto_typeof.hpp (original)
+++ branches/release/boost/xpressive/proto/proto_typeof.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Type registrations so that proto expression templates can be used together
 /// with the Boost.Typeof library.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/proto/ref.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/ref.hpp (original)
+++ branches/release/boost/xpressive/proto/ref.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file ref.hpp
 /// Utility for storing a sub-expr by reference
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -27,14 +27,24 @@
 namespace boost { namespace proto
 {
 
-#define BOOST_PROTO_ARG(z, n, data)\
- typedef\
- typename Expr::BOOST_PP_CAT(proto_arg, n)\
- BOOST_PP_CAT(proto_arg, n);\
+#define BOOST_PROTO_ARG(z, n, data) \
+ typedef \
+ typename Expr::BOOST_PP_CAT(proto_arg, n) \
+ BOOST_PP_CAT(proto_arg, n); \
     /**/
 
     namespace refns_
     {
+ /// \brief A simple reference wrapper for a Proto expression type,
+ /// used by <tt>expr\<\></tt> to hold children expressions by reference.
+ ///
+ /// <tt>ref_\<\></tt> is used by <tt>expr\<\></tt> to hold children
+ /// expression types by reference. It forwards enough of the child
+ /// expression's interface so that <tt>expr\<\></tt> can handle children
+ /// uniformly regardless of whether it is stored by reference or by
+ /// value.
+ ///
+ /// This type is largely an implementation detail.
         template<typename Expr>
         struct ref_
         {
@@ -43,14 +53,17 @@
             typedef typename Expr::proto_args proto_args;
             typedef typename Expr::proto_arity proto_arity;
             typedef typename Expr::proto_domain proto_domain;
- typedef tag::proto_ref fusion_tag;
             typedef void proto_is_ref_;
             typedef void proto_is_expr_;
             typedef Expr proto_derived_expr;
 
             BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, _)
 
- typename mpl::if_<is_const<Expr>, proto_base_expr const &, proto_base_expr &>::type
+ typename mpl::if_c<
+ is_const<Expr>::value
+ , proto_base_expr const &
+ , proto_base_expr &
+ >::type
             proto_base() const
             {
                 return this->expr.proto_base();
@@ -66,6 +79,7 @@
         };
 
         // ref_-to-ref_ is not allowed. this will cause a compile error.
+ /// INTERNAL ONLY
         template<typename Expr>
         struct ref_<ref_<Expr> >
         {};
@@ -75,93 +89,125 @@
 
     namespace result_of
     {
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T>
         struct unref
         {
- typedef T type;
- typedef T &reference;
- typedef T const &const_reference;
+ typedef T type; ///< Suitable for return by value
+ typedef T &reference; ///< Suitable for return by reference
+ typedef T const &const_reference; ///< Suitable for return by const reference
         };
 
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T>
         struct unref<ref_<T> >
         {
- typedef T type;
- typedef T &reference;
- typedef T &const_reference;
+ typedef T type; ///< Suitable for return by value
+ typedef T &reference; ///< Suitable for return by reference
+ typedef T &const_reference; ///< Suitable for return by const reference
         };
 
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T>
         struct unref<ref_<T const> >
         {
- typedef T type;
- typedef T const &reference;
- typedef T const &const_reference;
+ typedef T type; ///< Suitable for return by value
+ typedef T const &reference; ///< Suitable for return by reference
+ typedef T const &const_reference; ///< Suitable for return by const reference
         };
 
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T>
         struct unref<T &>
         {
- typedef T type;
- typedef T &reference;
- typedef T &const_reference;
+ typedef T type; ///< Suitable for return by value
+ typedef T &reference; ///< Suitable for return by reference
+ typedef T &const_reference; ///< Suitable for return by const reference
         };
 
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T>
         struct unref<T const &>
         {
- typedef T type;
- typedef T const &reference;
- typedef T const &const_reference;
+ typedef T type; ///< Suitable for return by value
+ typedef T const &reference; ///< Suitable for return by reference
+ typedef T const &const_reference; ///< Suitable for return by const reference
         };
 
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T, std::size_t N>
         struct unref<T (&)[N]>
         {
- typedef T (&type)[N];
- typedef T (&reference)[N];
- typedef T (&const_reference)[N];
+ typedef T (&type)[N]; ///< Suitable for return by value
+ typedef T (&reference)[N]; ///< Suitable for return by reference
+ typedef T (&const_reference)[N]; ///< Suitable for return by const reference
         };
 
+ /// \brief Trait for stripping top-level references
+ /// and reference wrappers.
         template<typename T, std::size_t N>
         struct unref<T const (&)[N]>
         {
- typedef T const (&type)[N];
- typedef T const (&reference)[N];
- typedef T const (&const_reference)[N];
+ typedef T const (&type)[N]; ///< Suitable for return by value
+ typedef T const (&reference)[N]; ///< Suitable for return by reference
+ typedef T const (&const_reference)[N]; ///< Suitable for return by const reference
         };
     }
 
     namespace functional
     {
+ /// \brief A callable PolymorphicFunctionObject equivalent
+ /// to the <tt>proto::unref()</tt> function that removes
+ /// top-level reference wrappers.
         struct unref
         {
+ BOOST_PROTO_CALLABLE()
+
             template<typename T>
- struct result {};
+ struct result;
 
             template<typename This, typename T>
             struct result<This(T)>
- : result_of::unref<typename detail::remove_cv_ref<T>::type>
- {};
-
+ {
+ typedef BOOST_PROTO_UNCVREF(T) uncvref_type;
+ typedef typename result_of::unref<uncvref_type>::type type;
+ };
+
+ /// \brief Remove a top-level <tt>ref_\<\></tt> reference wrapper,
+ /// if it exists.
+ /// \param t The object to unwrap
+ /// \return If \c T t is a <tt>ref_\<\></tt>, return <tt>t.expr</tt>.
+ /// Otherwise, return \c t.
             template<typename T>
             T &operator()(T &t) const
             {
                 return t;
             }
 
+ /// \overload
+ ///
             template<typename T>
             T const &operator()(T const &t) const
             {
                 return t;
             }
 
+ /// \overload
+ ///
             template<typename T>
             T &operator()(ref_<T> &t) const
             {
                 return t.expr;
             }
 
+ /// \overload
+ ///
             template<typename T>
             T &operator()(ref_<T> const &t) const
             {
@@ -170,7 +216,41 @@
         };
     }
 
- functional::unref const unref = {};
+ /// \brief Remove a top-level <tt>ref_\<\></tt> reference wrapper, if
+ /// it exists.
+ /// \param t The object to unwrap
+ /// \throw nothrow
+ /// \return If \c T t is a <tt>ref_\<\></tt>, return <tt>t.expr</tt>.
+ /// Otherwise, return \c t.
+ template<typename T>
+ T &unref(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
+ {
+ return t;
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ T const &unref(T const &t)
+ {
+ return t;
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ T &unref(ref_<T> &t)
+ {
+ return t.expr;
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ T &unref(ref_<T> const &t)
+ {
+ return t.expr;
+ }
 }}
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1020)

Modified: branches/release/boost/xpressive/proto/tags.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/tags.hpp (original)
+++ branches/release/boost/xpressive/proto/tags.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file tags.hpp
 /// Contains the tags for all the overloadable operators in C++
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -20,7 +20,7 @@
     struct terminal {};
 
     /// Tag type for the unary + operator.
- struct posit {};
+ struct posit {};
 
     /// Tag type for the unary - operator.
     struct negate {};

Modified: branches/release/boost/xpressive/proto/traits.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/traits.hpp (original)
+++ branches/release/boost/xpressive/proto/traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,10 +2,10 @@
     ///////////////////////////////////////////////////////////////////////////////
     /// \file traits.hpp
     /// Contains definitions for arg\<\>, arg_c\<\>, left\<\>,
- /// right\<\>, tag\<\>, and the helper functions arg(), arg_c(),
+ /// right\<\>, tag_of\<\>, and the helper functions arg(), arg_c(),
     /// left() and right().
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -29,8 +29,12 @@
     #include <boost/mpl/or.hpp>
     #include <boost/mpl/bool.hpp>
     #include <boost/mpl/eval_if.hpp>
+ #include <boost/mpl/aux_/template_arity.hpp>
+ #include <boost/mpl/aux_/lambda_arity_param.hpp>
     #include <boost/static_assert.hpp>
     #include <boost/utility/result_of.hpp>
+ #include <boost/type_traits/is_pod.hpp>
+ #include <boost/type_traits/is_same.hpp>
     #include <boost/type_traits/is_array.hpp>
     #include <boost/type_traits/is_function.hpp>
     #include <boost/type_traits/remove_cv.hpp>
@@ -56,313 +60,2092 @@
 
     namespace boost { namespace proto
     {
+ namespace detail
+ {
+ template<typename T, typename Void = void>
+ struct if_vararg
+ {};
+
+ template<typename T>
+ struct if_vararg<T, typename T::proto_is_vararg_>
+ : T
+ {};
+
+ template<typename T, typename Void = void>
+ struct is_callable2_
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_callable2_<T, typename T::proto_is_callable_>
+ : mpl::true_
+ {};
+
+ template<typename T BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<T>::value)>
+ struct is_callable_
+ : is_callable2_<T>
+ {};
+ }
+
+ /// \brief Boolean metafunction which detects whether a type is
+ /// a callable function object type or not.
+ ///
+ /// <tt>is_callable\<\></tt> is used by the <tt>when\<\></tt> transform
+ /// to determine whether a function type <tt>R(A1,A2,...AN)</tt> is a
+ /// callable transform or an object transform. (The former are evaluated
+ /// using <tt>call\<\></tt> and the later with <tt>make\<\></tt>.) If
+ /// <tt>is_callable\<R\>::::value</tt> is \c true, the function type is
+ /// a callable transform; otherwise, it is an object transform.
+ ///
+ /// Unless specialized for a type \c T, <tt>is_callable\<T\>::::value</tt>
+ /// is computed as follows:
+ ///
+ /// \li If \c T is a template type <tt>X\<Y0,Y1,...YN\></tt>, where all \c Yx
+ /// are types for \c x in <tt>[0,N]</tt>, <tt>is_callable\<T\>::::value</tt>
+ /// is <tt>is_same\<YN, proto::callable\>::::value</tt>.
+ /// \li If \c T has a nested type \c proto_is_callable_ that is a typedef
+ /// for \c void, <tt>is_callable\<T\>::::value</tt> is \c true. (Note: this is
+ /// the case for any type that derives from \c proto::callable.)
+ /// \li Otherwise, <tt>is_callable\<T\>::::value</tt> is \c false.
         template<typename T>
- struct is_transform
- : mpl::false_
+ struct is_callable
+ : proto::detail::is_callable_<T>
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<proto::_>
+ : mpl::true_
         {};
 
+ /// INTERNAL ONLY
+ ///
         template<>
- struct is_transform<proto::_>
+ struct is_callable<proto::callable>
+ : mpl::false_
+ {};
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3)
+ // work around GCC bug
+ template<typename Tag, typename Args, long N>
+ struct is_callable<proto::expr<Tag, Args, N> >
+ : mpl::false_
+ {};
+ #endif
+
+ /// \brief A Boolean metafunction that indicates whether a type requires
+ /// aggregate initialization.
+ ///
+ /// <tt>is_aggregate\<\></tt> is used by the <tt>make\<\></tt> transform
+ /// to determine how to construct an object of some type \c T, given some
+ /// initialization arguments <tt>a0,a1,...aN</tt>.
+ /// If <tt>is_aggregate\<T\>::::value</tt> is \c true, then an object of
+ /// type T will be initialized as <tt>T t = {a0,a1,...aN};</tt>. Otherwise,
+ /// it will be initialized as <tt>T t(a0,a1,...aN)</tt>.
+ template<typename T>
+ struct is_aggregate
+ : is_pod<T>
+ {};
+
+ /// \brief Specialization of <tt>is_aggregate\<\></tt> that indicates
+ /// that objects of <tt>expr\<\></tt> type require aggregate initialization.
+ template<typename Tag, typename Args, long N>
+ struct is_aggregate<proto::expr<Tag, Args, N> >
           : mpl::true_
         {};
 
         namespace result_of
         {
- // is_ref
- template<typename T, typename EnableIf>
+ /// \brief A Boolean metafunction that indicates whether a given
+ /// type \c T is a Proto expression type.
+ ///
+ /// If \c T has a nested type \c proto_is_expr_ that is a typedef
+ /// for \c void, <tt>is_expr\<T\>::::value</tt> is \c true. (Note, this
+ /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
+ /// from <tt>proto::extends\<\></tt> or that uses the
+ /// <tt>BOOST_PROTO_EXTENDS()</tt> macro.) Otherwise,
+ /// <tt>is_expr\<T\>::::value</tt> is \c false.
+ template<typename T, typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)>
+ struct is_expr
+ : mpl::false_
+ {};
+
+ /// \brief A Boolean metafunction that indicates whether a given
+ /// type \c T is a Proto expression type.
+ ///
+ /// If \c T has a nested type \c proto_is_expr_ that is a typedef
+ /// for \c void, <tt>is_expr\<T\>::::value</tt> is \c true. (Note, this
+ /// is the case for <tt>proto::expr\<\></tt>, any type that is derived
+ /// from <tt>proto::extends\<\></tt> or that uses the
+ /// <tt>BOOST_PROTO_EXTENDS()</tt> macro.) Otherwise,
+ /// <tt>is_expr\<T\>::::value</tt> is \c false.
+ template<typename T>
+ struct is_expr<T, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+ /// \brief A metafunction that returns the tag type of a
+ /// Proto expression.
+ template<typename Expr>
+ struct tag_of
+ {
+ typedef typename Expr::proto_tag type;
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T, typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)>
             struct is_ref
               : mpl::false_
             {};
 
- template<typename T>
- struct is_ref<T, typename T::proto_is_ref_>
- : mpl::true_
- {};
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct is_ref<T, typename T::proto_is_ref_>
+ : mpl::true_
+ {};
+
+ /// \brief A metafunction that computes the return type of the \c as_expr()
+ /// function.
+ ///
+ /// The <tt>as_expr\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by value if
+ /// possible. Types which are already Proto types are left alone.
+ ///
+ /// This specialization is selected when the type is not yet a Proto type.
+ /// The resulting terminal type is calculated as follows:
+ ///
+ /// If \c T is an array type or a function type, let \c A be <tt>T &</tt>.
+ /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
+ /// Then, the result type <tt>as_expr\<T, Domain\>::::type</tt> is
+ /// <tt>Domain::apply\< expr\< tag::terminal, args0\<A\> \> \>::::type</tt>.
+ template<
+ typename T
+ , typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain)
+ , typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)
+ >
+ struct as_expr
+ {
+ typedef mpl::or_<BOOST_PROTO_IS_ARRAY_(T), is_function<T> > is_unstorable_;
+ typedef typename mpl::eval_if<is_unstorable_, add_reference<T>, remove_cv<T> >::type arg0_;
+ typedef proto::expr<proto::tag::terminal, args0<arg0_> > expr_;
+ typedef typename Domain::template apply<expr_>::type type;
+ typedef type const reference;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static reference call(T2 &t)
+ {
+ return Domain::make(expr_::make(t));
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_expr()
+ /// function.
+ ///
+ /// The <tt>as_expr\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by value if
+ /// possible. Types which are already Proto types are left alone.
+ ///
+ /// This specialization is selected when the type is already a Proto type.
+ /// The result type <tt>as_expr\<T, Domain\>::::type</tt> is \c T stripped
+ /// of cv-qualifiers.
+ template<typename T, typename Domain>
+ struct as_expr<T, Domain, typename T::proto_is_expr_>
+ {
+ typedef typename T::proto_derived_expr type;
+ typedef T &reference;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static reference call(T2 &t)
+ {
+ return t;
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_arg()
+ /// function.
+ ///
+ /// The <tt>as_arg\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by reference.
+ /// Types which are already Proto types are wrapped in <tt>proto::ref_\<\></tt>.
+ ///
+ /// This specialization is selected when the type is not yet a Proto type.
+ /// The result type <tt>as_arg\<T, Domain\>::::type</tt> is
+ /// <tt>Domain::apply\< expr\< tag::terminal, args0\<T &\> \> \>::::type</tt>.
+ template<
+ typename T
+ , typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain)
+ , typename Void BOOST_PROTO_FOR_DOXYGEN_ONLY(= void)
+ >
+ struct as_arg
+ {
+ typedef proto::expr<proto::tag::terminal, args0<T &> > expr_;
+ typedef typename Domain::template apply<expr_>::type type;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static type call(T2 &t)
+ {
+ return Domain::make(expr_::make(t));
+ }
+ };
+
+ /// \brief A metafunction that computes the return type of the \c as_arg()
+ /// function.
+ ///
+ /// The <tt>as_arg\<\></tt> metafunction turns types into Proto types, if
+ /// they are not already, by making them Proto terminals held by reference.
+ /// Types which are already Proto types are wrapped in <tt>proto::ref_\<\></tt>.
+ ///
+ /// This specialization is selected when the type is already a Proto type.
+ /// The result type <tt>as_arg\<T, Domain\>::::type</tt> is
+ /// <tt>proto::ref_\<T\></tt>.
+ template<typename T, typename Domain>
+ struct as_arg<T, Domain, typename T::proto_is_expr_>
+ {
+ typedef ref_<T> type;
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T2>
+ static type call(T2 &t)
+ {
+ return type::make(t);
+ }
+ };
+
+ /// \brief A metafunction that returns the type of the Nth child
+ /// of a Proto expression, where N is an MPL Integral Constant.
+ ///
+ /// <tt>result_of::arg\<Expr, N\></tt> is equivalent to
+ /// <tt>result_of::arg_c\<Expr, N::value\></tt>.
+ template<typename Expr, typename N BOOST_PROTO_FOR_DOXYGEN_ONLY(= mpl::long_<0>) >
+ struct arg
+ : arg_c<Expr, N::value>
+ {};
+
+ // TODO left<> and right<> force the instantiation of Expr.
+ // Couldn't we partially specialize them on proto::expr< T, A >
+ // and ref_< proto::expr< T, A > > and return A::arg0 / A::arg1?
+
+ /// \brief A metafunction that returns the type of the left child
+ /// of a binary Proto expression.
+ ///
+ /// <tt>result_of::left\<Expr\></tt> is equivalent to
+ /// <tt>result_of::arg_c\<Expr, 0\></tt>.
+ template<typename Expr>
+ struct left
+ {
+ typedef typename Expr::proto_arg0 wrapped_type;
+ typedef typename unref<wrapped_type>::type type;
+ typedef typename unref<wrapped_type>::reference reference;
+ typedef typename unref<wrapped_type>::const_reference const_reference;
+ };
+
+ /// \brief A metafunction that returns the type of the right child
+ /// of a binary Proto expression.
+ ///
+ /// <tt>result_of::right\<Expr\></tt> is equivalent to
+ /// <tt>result_of::arg_c\<Expr, 1\></tt>.
+ template<typename Expr>
+ struct right
+ {
+ typedef typename Expr::proto_arg1 wrapped_type;
+ typedef typename unref<wrapped_type>::type type;
+ typedef typename unref<wrapped_type>::reference reference;
+ typedef typename unref<wrapped_type>::const_reference const_reference;
+ };
+
+ } // namespace result_of
+
+ namespace op
+ {
+ /// \brief A metafunction for generating terminal expression types,
+ /// a grammar element for matching terminal expressions, and a
+ /// PrimitiveTransform that returns the current expression unchanged.
+ template<typename T>
+ struct terminal
+ {
+ typedef proto::expr<proto::tag::terminal, args0<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef Expr type;
+ };
+
+ /// \param expr The current expression
+ /// \pre <tt>matches\<Expr, terminal\<T\> \>::::value</tt> is \c true.
+ /// \return \c expr
+ /// \throw nothrow
+ template<typename Expr, typename State, typename Visitor>
+ Expr const &operator ()(Expr const &expr, State const &, Visitor &) const
+ {
+ return expr;
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::terminal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating ternary conditional expression types,
+ /// a grammar element for matching ternary conditional expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U, typename V>
+ struct if_else_
+ {
+ typedef proto::expr<proto::tag::if_else_, args3<T, U, V> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<if_else_>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, if_else_\<T,U,V\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<if_else_\<T,U,V\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<if_else_>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::if_else_ proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ /// INTERNAL ONLY
+ typedef V proto_arg2;
+ };
+
+ /// \brief A metafunction for generating unary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching unary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>unary_expr\<_, _\></tt> as a grammar element to match any
+ /// unary expression.
+ template<typename Tag, typename T>
+ struct unary_expr
+ {
+ typedef proto::expr<Tag, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<unary_expr>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, unary_expr\<Tag, T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<unary_expr\<Tag, T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<unary_expr>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating binary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching binary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>binary_expr\<_, _, _\></tt> as a grammar element to match any
+ /// binary expression.
+ template<typename Tag, typename T, typename U>
+ struct binary_expr
+ {
+ typedef proto::expr<Tag, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<binary_expr>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, binary_expr\<Tag,T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<binary_expr\<Tag,T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<binary_expr>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef Tag proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating unary plus expression types,
+ /// a grammar element for matching unary plus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct posit
+ {
+ typedef proto::expr<proto::tag::posit, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<posit>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, posit\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<posit\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<posit>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::posit proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating unary minus expression types,
+ /// a grammar element for matching unary minus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct negate
+ {
+ typedef proto::expr<proto::tag::negate, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<negate>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, negate\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<negate\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<negate>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::negate proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating defereference expression types,
+ /// a grammar element for matching dereference expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct dereference
+ {
+ typedef proto::expr<proto::tag::dereference, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<dereference>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, dereference\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<dereference\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<dereference>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::dereference proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating complement expression types,
+ /// a grammar element for matching complement expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct complement
+ {
+ typedef proto::expr<proto::tag::complement, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<complement>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, complement\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<complement\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<complement>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::complement proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating address_of expression types,
+ /// a grammar element for matching address_of expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct address_of
+ {
+ typedef proto::expr<proto::tag::address_of, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<address_of>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, address_of\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<address_of\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<address_of>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::address_of proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating logical_not expression types,
+ /// a grammar element for matching logical_not expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct logical_not
+ {
+ typedef proto::expr<proto::tag::logical_not, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<logical_not>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, logical_not\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<logical_not\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<logical_not>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::logical_not proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating pre-increment expression types,
+ /// a grammar element for matching pre-increment expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct pre_inc
+ {
+ typedef proto::expr<proto::tag::pre_inc, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<pre_inc>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, pre_inc\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<pre_inc\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<pre_inc>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::pre_inc proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating pre-decrement expression types,
+ /// a grammar element for matching pre-decrement expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct pre_dec
+ {
+ typedef proto::expr<proto::tag::pre_dec, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<pre_dec>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, pre_dec\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<pre_dec\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<pre_dec>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::pre_dec proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating post-increment expression types,
+ /// a grammar element for matching post-increment expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct post_inc
+ {
+ typedef proto::expr<proto::tag::post_inc, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<post_inc>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, post_inc\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<post_inc\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<post_inc>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::post_inc proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating post-decrement expression types,
+ /// a grammar element for matching post-decrement expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T>
+ struct post_dec
+ {
+ typedef proto::expr<proto::tag::post_dec, args1<T> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<post_dec>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, post_dec\<T\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<post_dec\<T\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<post_dec>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::post_dec proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ };
+
+ /// \brief A metafunction for generating left-shift expression types,
+ /// a grammar element for matching left-shift expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_left
+ {
+ typedef proto::expr<proto::tag::shift_left, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<shift_left>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, shift_left\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<shift_left\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<shift_left>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_left proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating right-shift expression types,
+ /// a grammar element for matching right-shift expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_right
+ {
+ typedef proto::expr<proto::tag::shift_right, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<shift_right>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, shift_right\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<shift_right\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<shift_right>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_right proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating multiplies expression types,
+ /// a grammar element for matching multiplies expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct multiplies
+ {
+ typedef proto::expr<proto::tag::multiplies, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<multiplies>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, multiplies\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<multiplies\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<multiplies>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::multiplies proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating divides expression types,
+ /// a grammar element for matching divides expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct divides
+ {
+ typedef proto::expr<proto::tag::divides, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<divides>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, divides\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<divides\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<divides>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::divides proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating modulus expression types,
+ /// a grammar element for matching modulus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct modulus
+ {
+ typedef proto::expr<proto::tag::modulus, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<modulus>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, modulus\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<modulus\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<modulus>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::modulus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating binary plus expression types,
+ /// a grammar element for matching binary plus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct plus
+ {
+ typedef proto::expr<proto::tag::plus, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<plus>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, plus\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<plus\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<plus>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::plus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating binary minus expression types,
+ /// a grammar element for matching binary minus expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct minus
+ {
+ typedef proto::expr<proto::tag::minus, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<minus>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, minus\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<minus\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<minus>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::minus proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating less expression types,
+ /// a grammar element for matching less expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct less
+ {
+ typedef proto::expr<proto::tag::less, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<less>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, less\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<less\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<less>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::less proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating greater expression types,
+ /// a grammar element for matching greater expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct greater
+ {
+ typedef proto::expr<proto::tag::greater, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<greater>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, greater\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<greater\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<greater>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::greater proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating less-or-equal expression types,
+ /// a grammar element for matching less-or-equal expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct less_equal
+ {
+ typedef proto::expr<proto::tag::less_equal, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<less_equal>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, less_equal\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<less_equal\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<less_equal>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::less_equal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating greater-or-equal expression types,
+ /// a grammar element for matching greater-or-equal expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct greater_equal
+ {
+ typedef proto::expr<proto::tag::greater_equal, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<greater_equal>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, greater_equal\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<greater_equal\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<greater_equal>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::greater_equal proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating equal-to expression types,
+ /// a grammar element for matching equal-to expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct equal_to
+ {
+ typedef proto::expr<proto::tag::equal_to, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<equal_to>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, equal_to\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<equal_to\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<equal_to>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::equal_to proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating not-equal-to expression types,
+ /// a grammar element for matching not-equal-to expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct not_equal_to
+ {
+ typedef proto::expr<proto::tag::not_equal_to, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<not_equal_to>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, not_equal_to\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<not_equal_to\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<not_equal_to>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::not_equal_to proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating logical-or expression types,
+ /// a grammar element for matching logical-or expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct logical_or
+ {
+ typedef proto::expr<proto::tag::logical_or, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<logical_or>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, logical_or\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<logical_or\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<logical_or>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::logical_or proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating logical-and expression types,
+ /// a grammar element for matching logical-and expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct logical_and
+ {
+ typedef proto::expr<proto::tag::logical_and, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<logical_and>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, logical_and\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<logical_and\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<logical_and>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::logical_and proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating bitwise-and expression types,
+ /// a grammar element for matching bitwise-and expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_and
+ {
+ typedef proto::expr<proto::tag::bitwise_and, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<bitwise_and>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, bitwise_and\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<bitwise_and\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<bitwise_and>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_and proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating bitwise-or expression types,
+ /// a grammar element for matching bitwise-or expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_or
+ {
+ typedef proto::expr<proto::tag::bitwise_or, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<bitwise_or>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, bitwise_or\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<bitwise_or\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<bitwise_or>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_or proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
 
- // is_expr
- template<typename T, typename EnableIf>
- struct is_expr
- : mpl::false_
- {};
+ /// \brief A metafunction for generating bitwise-xor expression types,
+ /// a grammar element for matching bitwise-xor expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_xor
+ {
+ typedef proto::expr<proto::tag::bitwise_xor, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- template<typename T>
- struct is_expr<T, typename T::proto_is_expr_>
- : mpl::true_
- {};
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<bitwise_xor>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, bitwise_xor\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<bitwise_xor\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<bitwise_xor>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_xor proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
 
- // tag_of
- template<typename Expr>
- struct tag_of
+ /// \brief A metafunction for generating comma expression types,
+ /// a grammar element for matching comma expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct comma
             {
- typedef typename Expr::proto_tag type;
+ typedef proto::expr<proto::tag::comma, args2<T, U> > type;
+ typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<comma>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, comma\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<comma\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<comma>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::comma proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- // id
- template<typename Expr>
- struct id
- : result_of::deep_copy<Expr>
- {};
+ template<typename T, typename U>
+ struct mem_ptr
+ {
+ typedef proto::expr<proto::tag::mem_ptr, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- // as_expr
- template<typename T, typename Domain, typename EnableIf>
- struct as_expr
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<mem_ptr>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, mem_ptr\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<mem_ptr\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<mem_ptr>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::mem_ptr proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating assignment expression types,
+ /// a grammar element for matching assignment expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct assign
             {
- typedef typename mpl::eval_if<
- mpl::or_<BOOST_PROTO_IS_ARRAY_(T), is_function<T> >
- , add_reference<T>
- , remove_cv<T>
- >::type proto_arg0;
-
- typedef expr<proto::tag::terminal, args0<proto_arg0> > expr_type;
- typedef typename Domain::template apply<expr_type>::type type;
- typedef type const result_type;
+ typedef proto::expr<proto::tag::assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- template<typename T2>
- static result_type call(T2 &t)
+ template<typename Sig>
+ struct result
                 {
- return Domain::make(expr_type::make(t));
- }
+ typedef
+ typename pass_through<assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- template<typename T, typename Domain>
- struct as_expr<T, Domain, typename T::proto_is_expr_>
+ /// \brief A metafunction for generating left-shift-assign expression types,
+ /// a grammar element for matching left-shift-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_left_assign
             {
- typedef typename T::proto_derived_expr type;
- typedef T &result_type;
+ typedef proto::expr<proto::tag::shift_left_assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- template<typename T2>
- static result_type call(T2 &t)
+ template<typename Sig>
+ struct result
                 {
- return t;
- }
+ typedef
+ typename pass_through<shift_left_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, shift_left_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<shift_left_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<shift_left_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_left_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- // as_arg
- template<typename T, typename Domain, typename EnableIf>
- struct as_arg
+ /// \brief A metafunction for generating right-shift-assign expression types,
+ /// a grammar element for matching right-shift-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct shift_right_assign
             {
- typedef expr<proto::tag::terminal, args0<T &> > expr_type;
- typedef typename Domain::template apply<expr_type>::type type;
+ typedef proto::expr<proto::tag::shift_right_assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- template<typename T2>
- static type call(T2 &t)
+ template<typename Sig>
+ struct result
                 {
- return Domain::make(expr_type::make(t));
- }
+ typedef
+ typename pass_through<shift_right_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, shift_right_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<shift_right_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<shift_right_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::shift_right_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- template<typename T, typename Domain>
- struct as_arg<T, Domain, typename T::proto_is_expr_>
+ /// \brief A metafunction for generating multiplies-assign expression types,
+ /// a grammar element for matching multiplies-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct multiplies_assign
             {
- typedef ref_<T> type;
+ typedef proto::expr<proto::tag::multiplies_assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- template<typename T2>
- static type call(T2 &t)
+ template<typename Sig>
+ struct result
                 {
- return type::make(t);
- }
+ typedef
+ typename pass_through<multiplies_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, multiplies_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<multiplies_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<multiplies_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::multiplies_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- template<typename Expr, typename N>
- struct arg
- : arg_c<Expr, N::value>
- {};
+ /// \brief A metafunction for generating divides-assign expression types,
+ /// a grammar element for matching divides-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct divides_assign
+ {
+ typedef proto::expr<proto::tag::divides_assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- // left
- // BUGBUG this forces the instantiation of Expr. Couldn't we
- // partially specialize left<> on expr< T, A > and
- // ref_< expr< T, A > > and return A::arg0 ?
- template<typename Expr>
- struct left
- : unref<typename Expr::proto_arg0>
- {};
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<divides_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, divides_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<divides_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<divides_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::divides_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
 
- // right
- template<typename Expr>
- struct right
- : unref<typename Expr::proto_arg1>
- {};
- }
+ /// \brief A metafunction for generating modulus-assign expression types,
+ /// a grammar element for matching modulus-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct modulus_assign
+ {
+ typedef proto::expr<proto::tag::modulus_assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- namespace detail
- {
- template<typename T, typename EnableIf = void>
- struct if_vararg
- {};
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<modulus_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, modulus_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<modulus_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<modulus_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::modulus_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
 
- template<typename T>
- struct if_vararg<T, typename T::proto_is_vararg_>
- : T
- {};
- }
+ /// \brief A metafunction for generating plus-assign expression types,
+ /// a grammar element for matching plus-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct plus_assign
+ {
+ typedef proto::expr<proto::tag::plus_assign, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- namespace op
- {
- // terminal
- template<typename T>
- struct terminal : has_identity_transform
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<plus_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, plus_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<plus_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<plus_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::plus_assign proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
+
+ /// \brief A metafunction for generating minus-assign expression types,
+ /// a grammar element for matching minus-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct minus_assign
             {
- terminal();
- typedef expr<proto::tag::terminal, args0<T> > type;
+ typedef proto::expr<proto::tag::minus_assign, args2<T, U> > type;
                 typedef type proto_base_expr;
- typedef proto::tag::terminal proto_tag;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<minus_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, minus_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<minus_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<minus_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::minus_assign proto_tag;
+ /// INTERNAL ONLY
                 typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- // if_else
- template<typename T, typename U, typename V>
- struct if_else_ : has_pass_through_transform<if_else_<T, U, V> >
+ /// \brief A metafunction for generating bitwise-and-assign expression types,
+ /// a grammar element for matching bitwise-and-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_and_assign
             {
- if_else_();
- typedef expr<proto::tag::if_else_, args3<T, U, V> > type;
+ typedef proto::expr<proto::tag::bitwise_and_assign, args2<T, U> > type;
                 typedef type proto_base_expr;
- typedef proto::tag::if_else_ proto_tag;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<bitwise_and_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, bitwise_and_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<bitwise_and_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<bitwise_and_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_and_assign proto_tag;
+ /// INTERNAL ONLY
                 typedef T proto_arg0;
+ /// INTERNAL ONLY
                 typedef U proto_arg1;
- typedef V proto_arg2;
             };
 
- // unary_expr
- template<typename Tag, typename T>
- struct unary_expr : has_pass_through_transform<unary_expr<Tag, T> >
+ /// \brief A metafunction for generating bitwise-or-assign expression types,
+ /// a grammar element for matching bitwise-or-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_or_assign
             {
- unary_expr();
- typedef expr<Tag, args1<T> > type;
+ typedef proto::expr<proto::tag::bitwise_or_assign, args2<T, U> > type;
                 typedef type proto_base_expr;
- typedef Tag proto_tag;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<bitwise_or_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, bitwise_or_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<bitwise_or_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<bitwise_or_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_or_assign proto_tag;
+ /// INTERNAL ONLY
                 typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
             };
 
- // binary_expr
- template<typename Tag, typename T, typename U>
- struct binary_expr : has_pass_through_transform<binary_expr<Tag, T, U> >
+ /// \brief A metafunction for generating bitwise-xor-assign expression types,
+ /// a grammar element for matching bitwise-xor-assign expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct bitwise_xor_assign
             {
- binary_expr();
- typedef expr<Tag, args2<T, U> > type;
+ typedef proto::expr<proto::tag::bitwise_xor_assign, args2<T, U> > type;
                 typedef type proto_base_expr;
- typedef Tag proto_tag;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<bitwise_xor_assign>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, bitwise_xor_assign\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<bitwise_xor_assign\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<bitwise_xor_assign>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::bitwise_xor_assign proto_tag;
+ /// INTERNAL ONLY
                 typedef T proto_arg0;
+ /// INTERNAL ONLY
                 typedef U proto_arg1;
             };
 
- #define BOOST_PROTO_UNARY_GENERATOR(Name) \
- template<typename T> \
- struct Name : has_pass_through_transform<Name<T> > \
- { \
- Name(); \
- typedef expr<proto::tag::Name, args1<T> > type; \
- typedef type proto_base_expr; \
- typedef proto::tag::Name proto_tag; \
- typedef T proto_arg0; \
- }; \
- /**/
-
- #define BOOST_PROTO_BINARY_GENERATOR(Name) \
- template<typename T, typename U> \
- struct Name : has_pass_through_transform<Name<T, U> > \
- { \
- Name(); \
- typedef expr<proto::tag::Name, args2<T, U> > type; \
- typedef type proto_base_expr; \
- typedef proto::tag::Name proto_tag; \
- typedef T proto_arg0; \
- typedef U proto_arg1; \
- }; \
- /**/
-
- BOOST_PROTO_UNARY_GENERATOR(posit)
- BOOST_PROTO_UNARY_GENERATOR(negate)
- BOOST_PROTO_UNARY_GENERATOR(dereference)
- BOOST_PROTO_UNARY_GENERATOR(complement)
- BOOST_PROTO_UNARY_GENERATOR(address_of)
- BOOST_PROTO_UNARY_GENERATOR(logical_not)
- BOOST_PROTO_UNARY_GENERATOR(pre_inc)
- BOOST_PROTO_UNARY_GENERATOR(pre_dec)
- BOOST_PROTO_UNARY_GENERATOR(post_inc)
- BOOST_PROTO_UNARY_GENERATOR(post_dec)
-
- BOOST_PROTO_BINARY_GENERATOR(shift_left)
- BOOST_PROTO_BINARY_GENERATOR(shift_right)
- BOOST_PROTO_BINARY_GENERATOR(multiplies)
- BOOST_PROTO_BINARY_GENERATOR(divides)
- BOOST_PROTO_BINARY_GENERATOR(modulus)
- BOOST_PROTO_BINARY_GENERATOR(plus)
- BOOST_PROTO_BINARY_GENERATOR(minus)
- BOOST_PROTO_BINARY_GENERATOR(less)
- BOOST_PROTO_BINARY_GENERATOR(greater)
- BOOST_PROTO_BINARY_GENERATOR(less_equal)
- BOOST_PROTO_BINARY_GENERATOR(greater_equal)
- BOOST_PROTO_BINARY_GENERATOR(equal_to)
- BOOST_PROTO_BINARY_GENERATOR(not_equal_to)
- BOOST_PROTO_BINARY_GENERATOR(logical_or)
- BOOST_PROTO_BINARY_GENERATOR(logical_and)
- BOOST_PROTO_BINARY_GENERATOR(bitwise_and)
- BOOST_PROTO_BINARY_GENERATOR(bitwise_or)
- BOOST_PROTO_BINARY_GENERATOR(bitwise_xor)
- BOOST_PROTO_BINARY_GENERATOR(comma)
- BOOST_PROTO_BINARY_GENERATOR(mem_ptr)
-
- BOOST_PROTO_BINARY_GENERATOR(assign)
- BOOST_PROTO_BINARY_GENERATOR(shift_left_assign)
- BOOST_PROTO_BINARY_GENERATOR(shift_right_assign)
- BOOST_PROTO_BINARY_GENERATOR(multiplies_assign)
- BOOST_PROTO_BINARY_GENERATOR(divides_assign)
- BOOST_PROTO_BINARY_GENERATOR(modulus_assign)
- BOOST_PROTO_BINARY_GENERATOR(plus_assign)
- BOOST_PROTO_BINARY_GENERATOR(minus_assign)
- BOOST_PROTO_BINARY_GENERATOR(bitwise_and_assign)
- BOOST_PROTO_BINARY_GENERATOR(bitwise_or_assign)
- BOOST_PROTO_BINARY_GENERATOR(bitwise_xor_assign)
- BOOST_PROTO_BINARY_GENERATOR(subscript)
-
- } // namespace op
+ /// \brief A metafunction for generating subscript expression types,
+ /// a grammar element for matching subscript expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ template<typename T, typename U>
+ struct subscript
+ {
+ typedef proto::expr<proto::tag::subscript, args2<T, U> > type;
+ typedef type proto_base_expr;
 
- #undef BOOST_PROTO_UNARY_GENERATOR
- #undef BOOST_PROTO_BINARY_GENERATOR
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<subscript>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, subscript\<T,U\> \>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<subscript\<T,U\> \>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<subscript>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
+ typedef proto::tag::subscript proto_tag;
+ /// INTERNAL ONLY
+ typedef T proto_arg0;
+ /// INTERNAL ONLY
+ typedef U proto_arg1;
+ };
 
- #define BOOST_PROTO_ARG(z, n, data)\
- typedef BOOST_PP_CAT(data, n) BOOST_PP_CAT(proto_arg, n);\
- /**/
+ } // namespace op
 
- #define BOOST_PROTO_IMPLICIT_ARG(z, n, data)\
- BOOST_PP_CAT(data, n) &BOOST_PP_CAT(a, n);\
+ #define BOOST_PROTO_ARG(z, n, data) \
+ /** INTERNAL ONLY */ \
+ typedef BOOST_PP_CAT(data, n) BOOST_PP_CAT(proto_arg, n); \
         /**/
 
- #define BOOST_PROTO_ARG_N_TYPE(z, n, data)\
- typename proto::result_of::unref<\
- typename Expr::BOOST_PP_CAT(proto_arg, n)\
- >::const_reference\
+ #define BOOST_PROTO_IMPLICIT_ARG(z, n, data) \
+ BOOST_PP_CAT(data, n) &BOOST_PP_CAT(a, n); \
         /**/
 
     #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/traits.hpp>))
     #include BOOST_PP_ITERATE()
 
     #undef BOOST_PROTO_ARG
- #undef BOOST_PROTO_ARG_N_TYPE
     #undef BOOST_PROTO_IMPLICIT_ARG
 
         namespace functional
         {
- template<typename Domain>
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c as_expr() function.
+ template<typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain)>
             struct as_expr
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
- struct result {};
+ struct result;
 
                 template<typename This, typename T>
                 struct result<This(T)>
- : result_of::as_expr<typename remove_reference<T>::type, Domain>
- {};
-
+ {
+ typedef typename remove_reference<T>::type unref_type;
+ typedef typename result_of::as_expr<unref_type, Domain>::type type;
+ };
+
+ /// \brief Wrap an object in a Proto terminal if it isn't a
+ /// Proto expression already.
+ /// \param t The object to wrap.
+ /// \return <tt>proto::as_expr\<Domain\>(t)</tt>
                 template<typename T>
- typename result_of::as_expr<T, Domain>::result_type
+ typename result_of::as_expr<T, Domain>::reference
                 operator ()(T &t) const
                 {
                     return result_of::as_expr<T, Domain>::call(t);
                 }
 
+ /// \overload
+ ///
                 template<typename T>
- typename result_of::as_expr<T const, Domain>::result_type
+ typename result_of::as_expr<T const, Domain>::reference
                 operator ()(T const &t) const
                 {
                     return result_of::as_expr<T const, Domain>::call(t);
@@ -370,14 +2153,14 @@
 
                 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
                 template<typename T, std::size_t N_>
- typename result_of::as_expr<T(&)[N_], Domain>::result_type
+ typename result_of::as_expr<T(&)[N_], Domain>::reference
                 operator ()(T (&t)[N_]) const
                 {
                     return result_of::as_expr<T(&)[N_], Domain>::call(t);
                 }
 
                 template<typename T, std::size_t N_>
- typename result_of::as_expr<T const(&)[N_], Domain>::result_type
+ typename result_of::as_expr<T const(&)[N_], Domain>::reference
                 operator ()(T const (&t)[N_]) const
                 {
                     return result_of::as_expr<T const(&)[N_], Domain>::call(t);
@@ -385,17 +2168,27 @@
                 #endif
             };
 
- template<typename Domain>
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c as_arg() function.
+ template<typename Domain BOOST_PROTO_FOR_DOXYGEN_ONLY(= default_domain)>
             struct as_arg
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
- struct result {};
+ struct result;
 
                 template<typename This, typename T>
                 struct result<This(T)>
- : result_of::as_arg<typename remove_reference<T>::type, Domain>
- {};
-
+ {
+ typedef typename remove_reference<T>::type unref_type;
+ typedef typename result_of::as_arg<unref_type, Domain>::type type;
+ };
+
+ /// \brief Wrap an object in a Proto terminal if it isn't a
+ /// Proto expression already.
+ /// \param t The object to wrap.
+ /// \return <tt>proto::as_arg\<Domain\>(t)</tt>
                 template<typename T>
                 typename result_of::as_arg<T, Domain>::type
                 operator ()(T &t) const
@@ -403,6 +2196,8 @@
                     return result_of::as_arg<T, Domain>::call(t);
                 }
 
+ /// \overload
+ ///
                 template<typename T>
                 typename result_of::as_arg<T const, Domain>::type
                 operator ()(T const &t) const
@@ -411,47 +2206,82 @@
                 }
             };
 
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c arg_c() function.
             template<long N>
             struct arg_c
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
- struct result {};
+ struct result;
 
                 template<typename This, typename Expr>
                 struct result<This(Expr)>
- : result_of::arg_c<typename detail::remove_cv_ref<Expr>::type, N>
- {};
-
+ {
+ typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type;
+ typedef typename result_of::arg_c<uncvref_type, N>::type type;
+ };
+
+ /// \brief Return the Nth child of the given expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>N == 0 || N \< Expr::proto_arity::value</tt>
+ /// \return <tt>proto::arg_c\<N\>(expr)</tt>
+ /// \throw nothrow
                 template<typename Expr>
- typename result_of::arg_c<Expr, N>::reference operator ()(Expr &expr) const
+ typename result_of::arg_c<Expr, N>::reference
+ operator ()(Expr &expr) const
                 {
                     return result_of::arg_c<Expr, N>::call(expr);
                 }
 
+ /// \overload
+ ///
                 template<typename Expr>
- typename result_of::arg_c<Expr, N>::const_reference operator ()(Expr const &expr) const
+ typename result_of::arg_c<Expr, N>::const_reference
+ operator ()(Expr const &expr) const
                 {
                     return result_of::arg_c<Expr, N>::call(expr);
                 }
             };
 
- template<typename N>
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c arg() function.
+ ///
+ /// A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c arg() function. \c N is required
+ /// to be an MPL Integral Constant.
+ template<typename N BOOST_PROTO_FOR_DOXYGEN_ONLY(= mpl::long_<0>) >
             struct arg
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
- struct result {};
+ struct result;
 
                 template<typename This, typename Expr>
                 struct result<This(Expr)>
- : result_of::arg<typename detail::remove_cv_ref<Expr>::type, N>
- {};
-
+ {
+ typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type;
+ typedef typename result_of::arg<uncvref_type, N>::type type;
+ };
+
+ /// \brief Return the Nth child of the given expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>N::value == 0 || N::value \< Expr::proto_arity::value</tt>
+ /// \return <tt>proto::arg\<N\>(expr)</tt>
+ /// \throw nothrow
                 template<typename Expr>
- typename result_of::arg<Expr, N>::reference operator ()(Expr &expr) const
+ typename result_of::arg<Expr, N>::reference
+ operator ()(Expr &expr) const
                 {
                     return result_of::arg<Expr, N>::call(expr);
                 }
 
+ /// \overload
+ ///
                 template<typename Expr>
                 typename result_of::arg<Expr, N>::const_reference operator ()(Expr const &expr) const
                 {
@@ -459,47 +2289,77 @@
                 }
             };
 
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c left() function.
             struct left
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
- struct result {};
+ struct result;
 
                 template<typename This, typename Expr>
                 struct result<This(Expr)>
- : result_of::left<typename detail::remove_cv_ref<Expr>::type>
- {};
-
+ {
+ typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type;
+ typedef typename result_of::left<uncvref_type>::type type;
+ };
+
+ /// \brief Return the left child of the given binary expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::left(expr)</tt>
+ /// \throw nothrow
                 template<typename Expr>
- typename result_of::left<Expr>::reference operator ()(Expr &expr) const
+ typename result_of::left<Expr>::reference
+ operator ()(Expr &expr) const
                 {
                     return proto::unref(expr.proto_base().arg0);
                 }
 
+ /// \overload
+ ///
                 template<typename Expr>
- typename result_of::left<Expr>::const_reference operator ()(Expr const &expr) const
+ typename result_of::left<Expr>::const_reference
+ operator ()(Expr const &expr) const
                 {
                     return proto::unref(expr.proto_base().arg0);
                 }
             };
 
+ /// \brief A callable PolymorphicFunctionObject that is
+ /// equivalent to the \c right() function.
             struct right
             {
+ BOOST_PROTO_CALLABLE()
+
                 template<typename Sig>
- struct result {};
+ struct result;
 
                 template<typename This, typename Expr>
                 struct result<This(Expr)>
- : result_of::right<typename detail::remove_cv_ref<Expr>::type>
- {};
-
+ {
+ typedef BOOST_PROTO_UNCVREF(Expr) uncvref_type;
+ typedef typename result_of::right<uncvref_type>::type type;
+ };
+
+ /// \brief Return the right child of the given binary expression.
+ /// \param expr The expression node.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \return <tt>proto::right(expr)</tt>
+ /// \throw nothrow
                 template<typename Expr>
- typename result_of::right<Expr>::reference operator ()(Expr &expr) const
+ typename result_of::right<Expr>::reference
+ operator ()(Expr &expr) const
                 {
                     return proto::unref(expr.proto_base().arg1);
                 }
 
                 template<typename Expr>
- typename result_of::right<Expr>::const_reference operator ()(Expr const &expr) const
+ typename result_of::right<Expr>::const_reference
+ operator ()(Expr const &expr) const
                 {
                     return proto::unref(expr.proto_base().arg1);
                 }
@@ -507,13 +2367,30 @@
 
         }
 
- functional::left const left = {};
- functional::right const right = {};
-
- /// as_expr
+ /// \brief A function that wraps non-Proto expression types in Proto
+ /// terminals and leaves Proto expression types alone.
+ ///
+ /// The <tt>as_expr()</tt> function turns objects into Proto terminals if
+ /// they are not Proto expression types already. Non-Proto types are
+ /// held by value, if possible. Types which are already Proto types are
+ /// left alone and returned by reference.
+ ///
+ /// This function can be called either with an explicitly specified
+ /// \c Domain parameter (i.e., <tt>as_expr\<Domain\>(t)</tt>), or
+ /// without (i.e., <tt>as_expr(t)</tt>). If no domain is
+ /// specified, \c default_domain is assumed.
+ ///
+ /// If <tt>is_expr\<T\>::::value</tt> is \c true, then the argument is
+ /// returned unmodified, by reference. Otherwise, the argument is wrapped
+ /// in a Proto terminal expression node according to the following rules.
+ /// If \c T is an array type or a function type, let \c A be <tt>T &</tt>.
+ /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
+ /// Then, \c as_expr() returns
+ /// <tt>Domain::make(terminal\<A\>::::type::make(t))</tt>.
         ///
+ /// \param t The object to wrap.
         template<typename T>
- typename result_of::as_expr<T>::result_type
+ typename result_of::as_expr<T>::reference
         as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
         {
             return result_of::as_expr<T>::call(t);
@@ -522,7 +2399,7 @@
         /// \overload
         ///
         template<typename T>
- typename result_of::as_expr<T const>::result_type
+ typename result_of::as_expr<T const>::reference
         as_expr(T const &t)
         {
             return result_of::as_expr<T const>::call(t);
@@ -531,7 +2408,7 @@
         /// \overload
         ///
         template<typename Domain, typename T>
- typename result_of::as_expr<T, Domain>::result_type
+ typename result_of::as_expr<T, Domain>::reference
         as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
         {
             return result_of::as_expr<T, Domain>::call(t);
@@ -540,14 +2417,32 @@
         /// \overload
         ///
         template<typename Domain, typename T>
- typename result_of::as_expr<T const, Domain>::result_type
+ typename result_of::as_expr<T const, Domain>::reference
         as_expr(T const &t)
         {
             return result_of::as_expr<T const, Domain>::call(t);
         }
 
- /// as_arg
+ /// \brief A function that wraps non-Proto expression types in Proto
+ /// terminals (by reference) and wraps Proto expression types in
+ /// <tt>ref_\<\></tt>.
         ///
+ /// The <tt>as_arg()</tt> function turns objects into Proto terminals if
+ /// they are not Proto expression types already. Non-Proto types are
+ /// held by reference. Types which are already Proto types are wrapped
+ /// in <tt>ref_\<\></tt>.
+ ///
+ /// This function can be called either with an explicitly specified
+ /// \c Domain parameter (i.e., <tt>as_arg\<Domain\>(t)</tt>), or
+ /// without (i.e., <tt>as_arg(t)</tt>). If no domain is
+ /// specified, \c default_domain is assumed.
+ ///
+ /// If <tt>is_expr\<T\>::::value</tt> is \c true, then the argument is
+ /// wrapped in <tt>ref_\<\></tt>, which holds the argument by reference.
+ /// Otherwise, \c as_arg() returns
+ /// <tt>Domain::make(terminal\<T &\>::::type::make(t))</tt>.
+ ///
+ /// \param t The object to wrap.
         template<typename T>
         typename result_of::as_arg<T>::type
         as_arg(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T))
@@ -582,44 +2477,65 @@
             return result_of::as_arg<T const, Domain>::call(t);
         }
 
- /// arg
+ /// \brief Return the Nth child of the specified Proto expression.
+ ///
+ /// Return the Nth child of the specified Proto expression. If
+ /// \c N is not specified, as in \c arg(expr), then \c N is assumed
+ /// to be <tt>mpl::long_\<0\></tt>. The child is returned by
+ /// reference. If the expression is holding the child in a
+ /// <tt>ref_\<\></tt> wrapper, it is unwrapped before it is returned.
         ///
- template<typename Expr>
- typename result_of::unref<typename Expr::proto_base_expr::proto_arg0>::reference
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre \c N is an MPL Integral Constant.
+ /// \pre <tt>N::value == 0 || N::value \< Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the Nth child
+ template<typename N, typename Expr>
+ typename result_of::arg<Expr, N>::reference
         arg(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
         {
- return proto::unref(expr.proto_base().arg0);
+ return result_of::arg<Expr, N>::call(expr);
         }
 
         /// \overload
         ///
- template<typename Expr>
- typename result_of::unref<typename Expr::proto_base_expr::proto_arg0>::const_reference
+ template<typename N, typename Expr>
+ typename result_of::arg<Expr, N>::const_reference
         arg(Expr const &expr)
         {
- return proto::unref(expr.proto_base().arg0);
+ return result_of::arg<Expr, N>::call(expr);
         }
 
         /// \overload
         ///
- template<typename N, typename Expr>
- typename result_of::arg<Expr, N>::reference
- arg(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ template<typename Expr2>
+ typename result_of::unref<typename Expr2::proto_base_expr::proto_arg0>::reference
+ arg(Expr2 &expr2 BOOST_PROTO_DISABLE_IF_IS_CONST(Expr2))
         {
- return result_of::arg<Expr, N>::call(expr);
+ return proto::unref(expr2.proto_base().arg0);
         }
 
         /// \overload
         ///
- template<typename N, typename Expr>
- typename result_of::arg<Expr, N>::const_reference
- arg(Expr const &expr)
+ template<typename Expr2>
+ typename result_of::unref<typename Expr2::proto_base_expr::proto_arg0>::const_reference
+ arg(Expr2 const &expr2)
         {
- return result_of::arg<Expr, N>::call(expr);
+ return proto::unref(expr2.proto_base().arg0);
         }
 
- /// arg_c
+ /// \brief Return the Nth child of the specified Proto expression.
+ ///
+ /// Return the Nth child of the specified Proto expression. The child
+ /// is returned by reference. If the expression is holding the child in
+ /// a <tt>ref_\<\></tt> wrapper, it is unwrapped before it is returned.
         ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>N == 0 || N \< Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the Nth child
         template<long N, typename Expr>
         typename result_of::arg_c<Expr, N>::reference
         arg_c(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
@@ -630,11 +2546,98 @@
         /// \overload
         ///
         template<long N, typename Expr>
- typename result_of::arg_c<Expr, N>::const_reference arg_c(Expr const &expr)
+ typename result_of::arg_c<Expr, N>::const_reference
+ arg_c(Expr const &expr)
         {
             return result_of::arg_c<Expr, N>::call(expr);
         }
 
+ /// \brief Return the left child of the specified binary Proto
+ /// expression.
+ ///
+ /// Return the left child of the specified binary Proto expression. The
+ /// child is returned by reference. If the expression is holding the
+ /// child in a <tt>ref_\<\></tt> wrapper, it is unwrapped before it is
+ /// returned.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the left child
+ template<typename Expr>
+ typename result_of::left<Expr>::reference
+ left(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return proto::unref(expr.proto_base().arg0);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::left<Expr>::const_reference
+ left(Expr const &expr)
+ {
+ return proto::unref(expr.proto_base().arg0);
+ }
+
+ /// \brief Return the right child of the specified binary Proto
+ /// expression.
+ ///
+ /// Return the right child of the specified binary Proto expression. The
+ /// child is returned by reference. If the expression is holding the
+ /// child in a <tt>ref_\<\></tt> wrapper, it is unwrapped before it is
+ /// returned.
+ ///
+ /// \param expr The Proto expression.
+ /// \pre <tt>is_expr\<Expr\>::::value</tt> is \c true.
+ /// \pre <tt>2 == Expr::proto_arity::value</tt>
+ /// \throw nothrow
+ /// \return A reference to the right child
+ template<typename Expr>
+ typename result_of::right<Expr>::reference
+ right(Expr &expr BOOST_PROTO_DISABLE_IF_IS_CONST(Expr))
+ {
+ return proto::unref(expr.proto_base().arg1);
+ }
+
+ /// \overload
+ ///
+ template<typename Expr>
+ typename result_of::right<Expr>::const_reference
+ right(Expr const &expr)
+ {
+ return proto::unref(expr.proto_base().arg1);
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functional::as_expr<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Domain>
+ struct is_callable<functional::as_arg<Domain> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<long N>
+ struct is_callable<functional::arg_c<N> >
+ : mpl::true_
+ {};
+
+ /// INTERNAL ONLY
+ ///
+ template<typename N>
+ struct is_callable<functional::arg<N> >
+ : mpl::true_
+ {};
+
     }}
 
     #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
@@ -649,45 +2652,99 @@
     #if N > 0
         namespace op
         {
+ /// \brief A metafunction for generating function-call expression types,
+ /// a grammar element for matching function-call expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
             template<BOOST_PP_ENUM_PARAMS(N, typename A)>
             struct function<
                 BOOST_PP_ENUM_PARAMS(N, A)
                 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void
>
- : has_pass_through_transform<
- function<
- BOOST_PP_ENUM_PARAMS(N, A)
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void
- >
- >
             {
- typedef expr<proto::tag::function, BOOST_PP_CAT(args, N)<BOOST_PP_ENUM_PARAMS(N, A)> > type;
+ typedef proto::expr<proto::tag::function, BOOST_PP_CAT(args, N)<BOOST_PP_ENUM_PARAMS(N, A)> > type;
                 typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<function>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, function\>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<function\>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<function>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
                 typedef proto::tag::function proto_tag;
                 BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, A)
- BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT)
+ BOOST_PP_REPEAT_FROM_TO(
+ N
+ , BOOST_PROTO_MAX_ARITY
+ , BOOST_PROTO_ARG
+ , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
+ )
             };
 
+ /// \brief A metafunction for generating n-ary expression types with a
+ /// specified tag type,
+ /// a grammar element for matching n-ary expressions, and a
+ /// PrimitiveTransform that dispatches to the <tt>pass_through\<\></tt>
+ /// transform.
+ ///
+ /// Use <tt>nary_expr\<_, vararg\<_\> \></tt> as a grammar element to match any
+ /// n-ary expression; that is, any non-terminal.
             template<typename Tag BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
             struct nary_expr<
                 Tag
                 BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
                 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void
>
- : has_pass_through_transform<
- nary_expr<
- Tag
- BOOST_PP_ENUM_TRAILING_PARAMS(N, A)
- BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_SUB(BOOST_PROTO_MAX_ARITY, N), void BOOST_PP_INTERCEPT), void
- >
- >
             {
- typedef expr<Tag, BOOST_PP_CAT(args, N)<BOOST_PP_ENUM_PARAMS(N, A)> > type;
+ typedef proto::expr<Tag, BOOST_PP_CAT(args, N)<BOOST_PP_ENUM_PARAMS(N, A)> > type;
                 typedef type proto_base_expr;
+
+ template<typename Sig>
+ struct result
+ {
+ typedef
+ typename pass_through<nary_expr>::template result<Sig>::type
+ type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, nary_expr\>::::value</tt> is \c true.
+ /// \return <tt>pass_through\<nary_expr\>()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return pass_through<nary_expr>()(expr, state, visitor);
+ }
+
+ /// INTERNAL ONLY
                 typedef Tag proto_tag;
                 BOOST_PP_REPEAT(N, BOOST_PROTO_ARG, A)
- BOOST_PP_REPEAT_FROM_TO(N, BOOST_PROTO_MAX_ARITY, BOOST_PROTO_ARG, detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT)
+ BOOST_PP_REPEAT_FROM_TO(
+ N
+ , BOOST_PROTO_MAX_ARITY
+ , BOOST_PROTO_ARG
+ , detail::if_vararg<BOOST_PP_CAT(A, BOOST_PP_DEC(N))> BOOST_PP_INTERCEPT
+ )
             };
+
         } // namespace op
 
         namespace detail
@@ -698,14 +2755,23 @@
                 BOOST_PP_REPEAT(N, BOOST_PROTO_IMPLICIT_ARG, A)
 
                 template<typename Tag, typename Args, long Arity>
- operator expr<Tag, Args, Arity> () const
+ operator proto::expr<Tag, Args, Arity> () const
                 {
- expr<Tag, Args, Arity> that = {BOOST_PP_ENUM_PARAMS(N, a)};
+ proto::expr<Tag, Args, Arity> that = {BOOST_PP_ENUM_PARAMS(N, a)};
                     return that;
                 }
             };
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
+ , BOOST_PP_ENUM_PARAMS(N, typename A)
+ >
+ struct is_callable_<T<BOOST_PP_ENUM_PARAMS(N, A)> BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)>
+ : is_same<BOOST_PP_CAT(A, BOOST_PP_DEC(N)), callable>
+ {};
         }
 
+ /// INTERNAL ONLY
         template<BOOST_PP_ENUM_PARAMS(N, typename A)>
         detail::BOOST_PP_CAT(implicit_expr_, N)<BOOST_PP_ENUM_PARAMS(N, A)>
         implicit_expr(BOOST_PP_ENUM_BINARY_PARAMS(N, A, &a))
@@ -719,25 +2785,70 @@
 
         namespace result_of
         {
+ /// \brief A metafunction that returns the type of the Nth child
+ /// of a Proto expression.
+ ///
+ /// A metafunction that returns the type of the Nth child
+ /// of a Proto expression. \c N must be 0 or less than
+ /// \c Expr::proto_arity::value.
             template<typename Expr>
             struct arg_c<Expr, N>
- : unref<typename Expr::BOOST_PP_CAT(proto_arg, N)>
             {
- static typename arg_c<Expr, N>::reference call(Expr &expr)
+ /// The raw type of the Nth child as it is stored within
+ /// \c Expr. This may be a value, a reference, or a Proto
+ /// <tt>ref_\<\></tt> wrapper.
+ typedef typename Expr::BOOST_PP_CAT(proto_arg, N) wrapped_type;
+
+ /// The "value" type of the child, suitable for return by value,
+ /// computed as follows:
+ /// \li <tt>ref_\<T const\></tt> becomes <tt>T</tt>
+ /// \li <tt>ref_\<T\></tt> becomes <tt>T</tt>
+ /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ /// \li <tt>T const &</tt> becomes <tt>T</tt>
+ /// \li <tt>T &</tt> becomes <tt>T</tt>
+ /// \li <tt>T</tt> becomes <tt>T</tt>
+ typedef typename unref<wrapped_type>::type type;
+
+ /// The "reference" type of the child, suitable for return by
+ /// reference, computed as follows:
+ /// \li <tt>ref_\<T const\></tt> becomes <tt>T const &</tt>
+ /// \li <tt>ref_\<T\></tt> becomes <tt>T &</tt>
+ /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ /// \li <tt>T</tt> becomes <tt>T &</tt>
+ typedef typename unref<wrapped_type>::reference reference;
+
+ /// The "const reference" type of the child, suitable for return by
+ /// const reference, computed as follows:
+ /// \li <tt>ref_\<T const\></tt> becomes <tt>T const &</tt>
+ /// \li <tt>ref_\<T\></tt> becomes <tt>T &</tt>
+ /// \li <tt>T const(&)[N]</tt> becomes <tt>T const(&)[N]</tt>
+ /// \li <tt>T(&)[N]</tt> becomes <tt>T(&)[N]</tt>
+ /// \li <tt>R(&)(A0,...)</tt> becomes <tt>R(&)(A0,...)</tt>
+ /// \li <tt>T const &</tt> becomes <tt>T const &</tt>
+ /// \li <tt>T &</tt> becomes <tt>T &</tt>
+ /// \li <tt>T</tt> becomes <tt>T const &</tt>
+ typedef typename unref<wrapped_type>::const_reference const_reference;
+
+ /// INTERNAL ONLY
+ ///
+ static reference call(typename Expr::proto_derived_expr &expr)
                 {
                     return proto::unref(expr.proto_base().BOOST_PP_CAT(arg, N));
                 }
 
- static typename arg_c<Expr, N>::const_reference call(Expr const &expr)
+ /// INTERNAL ONLY
+ ///
+ static const_reference call(typename Expr::proto_derived_expr const &expr)
                 {
                     return proto::unref(expr.proto_base().BOOST_PP_CAT(arg, N));
                 }
             };
-
- template<typename Expr>
- struct arg_c<Expr const, N>
- : arg_c<Expr, N>
- {};
         }
 
     #undef N

Modified: branches/release/boost/xpressive/proto/transform.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform.hpp (original)
+++ branches/release/boost/xpressive/proto/transform.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file transform.hpp
 /// Includes all the transforms in the transform/ sub-directory.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -10,16 +10,14 @@
 #define BOOST_PROTO_TRANSFORM_HPP_EAN_06_23_2007
 
 #include <boost/xpressive/proto/detail/prefix.hpp> // must be first include
-#include <boost/xpressive/proto/transform/apply.hpp>
 #include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/branch.hpp>
-#include <boost/xpressive/proto/transform/compose.hpp>
-#include <boost/xpressive/proto/transform/construct.hpp>
+#include <boost/xpressive/proto/transform/bind.hpp>
+#include <boost/xpressive/proto/transform/call.hpp>
 #include <boost/xpressive/proto/transform/fold.hpp>
 #include <boost/xpressive/proto/transform/fold_tree.hpp>
-#include <boost/xpressive/proto/transform/function.hpp>
-#include <boost/xpressive/proto/transform/list.hpp>
+#include <boost/xpressive/proto/transform/make.hpp>
 #include <boost/xpressive/proto/transform/pass_through.hpp>
+#include <boost/xpressive/proto/transform/when.hpp>
 #include <boost/xpressive/proto/detail/suffix.hpp> // must be last include
 
 #endif

Deleted: branches/release/boost/xpressive/proto/transform/apply.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/apply.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
+++ (empty file)
@@ -1,167 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file apply.hpp
-/// Proto transforms for applying MPL placeholder expressions.
-//
-// Copyright 2007 Eric Niebler. 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)
-
-#ifndef BOOST_PROTO_TRANSFORM_APPLY_HPP_EAN_06_23_2007
-#define BOOST_PROTO_TRANSFORM_APPLY_HPP_EAN_06_23_2007
-
-#include <boost/xpressive/proto/detail/prefix.hpp>
-#include <boost/mpl/apply.hpp>
-#include <boost/xpressive/proto/proto_fwd.hpp> // is_transform
-#include <boost/xpressive/proto/detail/suffix.hpp>
-
-namespace boost { namespace proto { namespace transform
-{
- namespace detail
- {
- struct any
- {
- template<typename T>
- any(T const &)
- {}
- };
-
- struct default_factory
- {
- default_factory()
- {}
-
- default_factory const &operator()() const
- {
- return *this;
- }
-
- default_factory const &operator()(any) const
- {
- return *this;
- }
-
- default_factory const &operator()(any, any) const
- {
- return *this;
- }
-
- default_factory const &operator()(any, any, any) const
- {
- return *this;
- }
-
- template<typename T>
- operator T() const
- {
- return T();
- }
- };
- }
-
- // Always return the specified type/object
- template<typename Grammar, typename Always, typename Factory>
- struct always
- : Grammar
- {
- always() {}
-
- template<typename, typename, typename>
- struct apply
- {
- typedef Always type;
- };
-
- template<typename Expr, typename State, typename Visitor>
- static Always
- call(Expr const &, State const &, Visitor &)
- {
- return Factory()();
- }
- };
-
- // Apply an MPL lambda, passing just Expr
- template<typename Grammar, typename Lambda, typename Factory>
- struct apply1
- : Grammar
- {
- apply1() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : mpl::apply1<Lambda, typename Grammar::template apply<Expr, State, Visitor>::type>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Factory()(Grammar::call(expr, state, visitor));
- }
- };
-
- // Apply an MPL lambda, passing Expr and State
- template<typename Grammar, typename Lambda, typename Factory>
- struct apply2
- : Grammar
- {
- apply2() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : mpl::apply2<Lambda, typename Grammar::template apply<Expr, State, Visitor>::type, State>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Factory()(Grammar::call(expr, state, visitor), state);
- }
- };
-
- // Apply an MPL lambda, passing Expr, State and Visitor
- template<typename Grammar, typename Lambda, typename Factory>
- struct apply3
- : Grammar
- {
- apply3() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : mpl::apply3<Lambda, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Factory()(Grammar::call(expr, state, visitor), state, visitor);
- }
- };
-
-}}}
-
-namespace boost { namespace proto
-{
- template<typename Grammar, typename Always, typename Factory>
- struct is_transform<transform::always<Grammar, Always, Factory> >
- : mpl::true_
- {};
-
- template<typename Grammar, typename Lambda, typename Factory>
- struct is_transform<transform::apply1<Grammar, Lambda, Factory> >
- : mpl::true_
- {};
-
- template<typename Grammar, typename Lambda, typename Factory>
- struct is_transform<transform::apply2<Grammar, Lambda, Factory> >
- : mpl::true_
- {};
-
- template<typename Grammar, typename Lambda, typename Factory>
- struct is_transform<transform::apply3<Grammar, Lambda, Factory> >
- : mpl::true_
- {};
-}}
-
-#endif

Modified: branches/release/boost/xpressive/proto/transform/arg.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/arg.hpp (original)
+++ branches/release/boost/xpressive/proto/transform/arg.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,192 +1,211 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file arg.hpp
-/// Proto transforms for extracting arguments from expressions.
+/// Contains definition of the argN transforms.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
-#ifndef BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_12_16_2006
-#define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_12_16_2006
+#ifndef BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
+#define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
 
 #include <boost/xpressive/proto/detail/prefix.hpp>
 #include <boost/xpressive/proto/proto_fwd.hpp>
 #include <boost/xpressive/proto/traits.hpp>
 #include <boost/xpressive/proto/detail/suffix.hpp>
 
-namespace boost { namespace proto { namespace transform
+namespace boost { namespace proto
 {
- // A transform that simply extracts the arg from an expression
- template<typename Grammar, typename N>
- struct arg
- : Grammar
- {
- arg() {}
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::arg<typename Grammar::template apply<Expr, State, Visitor>::type, N>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type //reference
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- // NOTE Grammar::call could return a temporary!
- // Don't return a dangling reference
- return proto::arg<N>(Grammar::call(expr, state, visitor));
- }
- };
-
- // A transform that simply extracts the arg from an expression
- template<typename Grammar, long N>
- struct arg_c
- : Grammar
- {
- arg_c() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::arg_c<typename Grammar::template apply<Expr, State, Visitor>::type, N>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type //const &
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return proto::arg_c<N>(Grammar::call(expr, state, visitor));
- }
- };
-
- // A transform that simply extracts the left arg from an expression
- template<typename Grammar>
- struct left
- : Grammar
- {
- left() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::left<typename Grammar::template apply<Expr, State, Visitor>::type>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type //const &
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return proto::left(Grammar::call(expr, state, visitor));
- }
- };
-
- // A transform that simply extracts the right arg from an expression
- template<typename Grammar>
- struct right
- : Grammar
- {
- right() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::result_of::right<typename Grammar::template apply<Expr, State, Visitor>::type>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type //const &
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return proto::right(Grammar::call(expr, state, visitor));
- }
- };
-
- // Just return the passed in Expr
- template<typename Grammar>
- struct identity
- : Grammar
- {
- identity() {}
- BOOST_PROTO_IDENTITY_TRANSFORM();
- };
-
- // Just return the state
- template<typename Grammar>
- struct state
- : Grammar
+ namespace transform
     {
- state() {}
 
- template<typename, typename State, typename>
- struct apply
- {
- typedef State type;
+ /// \brief A PrimitiveTransform that returns the current expression
+ /// unmodified
+ struct expr : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef Expr type;
+ };
+
+ /// \param expr_ The current expression.
+ /// \return \c expr_
+ /// \throw nothrow
+ template<typename Expr, typename State, typename Visitor>
+ Expr const &
+ operator ()(Expr const &expr_, State const &, Visitor &) const
+ {
+ return expr_;
+ }
         };
 
- template<typename Expr, typename State, typename Visitor>
- static State const &
- call(Expr const &, State const &state_, Visitor &)
- {
- return state_;
- }
- };
-
- // Just return the visitor
- template<typename Grammar>
- struct visitor
- : Grammar
- {
- visitor() {}
+ /// \brief A PrimitiveTransform that returns the current state
+ /// unmodified
+ struct state : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef State type;
+ };
+
+ /// \param state_ The current state.
+ /// \return \c state_
+ /// \throw nothrow
+ template<typename Expr, typename State, typename Visitor>
+ State const &
+ operator ()(Expr const &, State const &state_, Visitor &) const
+ {
+ return state_;
+ }
+ };
 
- template<typename, typename, typename Visitor>
- struct apply
- {
- typedef Visitor type;
+ /// \brief A PrimitiveTransform that returns the current visitor
+ /// unmodified
+ struct visitor : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef Visitor type;
+ };
+
+ /// \param visitor_ The current visitor
+ /// \return \c visitor_
+ /// \throw nothrow
+ template<typename Expr, typename State, typename Visitor>
+ Visitor &
+ operator ()(Expr const &, State const &, Visitor &visitor_) const
+ {
+ return visitor_;
+ }
         };
 
- template<typename Expr, typename State, typename Visitor>
- static Visitor &
- call(Expr const &, State const &, Visitor &visitor_)
- {
- return visitor_;
- }
- };
+ /// \brief A PrimitiveTransform that returns I-th child of the current
+ /// expression.
+ template<int I>
+ struct arg_c : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename proto::result_of::arg_c<Expr, I>::type type;
+ };
+
+ /// \param expr The current expression.
+ /// \return <tt>proto::arg_c\<I\>(expr)</tt>
+ /// \throw nothrow
+ template<typename Expr, typename State, typename Visitor>
+ typename proto::result_of::arg_c<Expr, I>::const_reference
+ operator ()(Expr const &expr, State const &, Visitor &) const
+ {
+ return proto::arg_c<I>(expr);
+ }
+ };
 
-}}}
+ /// \brief A unary CallableTransform that wraps its argument
+ /// in a \c boost::reference_wrapper\<\>.
+ struct _ref : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename T>
+ struct result<This(T)>
+ {
+ typedef boost::reference_wrapper<T const> type;
+ };
+
+ template<typename This, typename T>
+ struct result<This(T &)>
+ {
+ typedef boost::reference_wrapper<T> type;
+ };
+
+ /// \param t The object to wrap
+ /// \return <tt>boost::ref(t)</tt>
+ /// \throw nothrow
+ template<typename T>
+ boost::reference_wrapper<T>
+ operator ()(T &t) const
+ {
+ return boost::reference_wrapper<T>(t);
+ }
+
+ /// \overload
+ ///
+ template<typename T>
+ boost::reference_wrapper<T const>
+ operator ()(T const &t) const
+ {
+ return boost::reference_wrapper<T const>(t);
+ }
+ };
+ }
 
-namespace boost { namespace proto
-{
- template<typename Grammar, typename N>
- struct is_transform<transform::arg<Grammar, N> >
- : mpl::true_
+ /// \brief A PrimitiveTransform that returns I-th child of the current
+ /// expression.
+ template<int I>
+ struct _arg_c
+ : transform::arg_c<I>
     {};
 
- template<typename Grammar, long N>
- struct is_transform<transform::arg_c<Grammar, N> >
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<transform::expr>
       : mpl::true_
     {};
 
- template<typename Grammar>
- struct is_transform<transform::left<Grammar> >
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<transform::state>
       : mpl::true_
     {};
 
- template<typename Grammar>
- struct is_transform<transform::right<Grammar> >
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<transform::visitor>
       : mpl::true_
     {};
 
- template<typename Grammar>
- struct is_transform<transform::identity<Grammar> >
+ /// INTERNAL ONLY
+ ///
+ template<int I>
+ struct is_callable<transform::arg_c<I> >
       : mpl::true_
     {};
 
- template<typename Grammar>
- struct is_transform<transform::state<Grammar> >
+ /// INTERNAL ONLY
+ ///
+ template<int I>
+ struct is_callable<_arg_c<I> >
       : mpl::true_
     {};
 
- template<typename Grammar>
- struct is_transform<transform::visitor<Grammar> >
+ /// INTERNAL ONLY
+ ///
+ template<>
+ struct is_callable<transform::_ref>
       : mpl::true_
     {};
+
 }}
 
 #endif

Added: branches/release/boost/xpressive/proto/transform/bind.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/transform/bind.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,123 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file bind.hpp
+ /// Contains definition of the bind<> transform.
+ //
+ // Copyright 2008 Eric Niebler. 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)
+
+ #ifndef BOOST_PROTO_TRANSFORM_BIND_HPP_EAN_12_02_2007
+ #define BOOST_PROTO_TRANSFORM_BIND_HPP_EAN_12_02_2007
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/transform/make.hpp>
+ #include <boost/xpressive/proto/transform/call.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+
+ namespace transform
+ {
+ /// \brief A PrimitiveTransform that uses <tt>make\<\></tt> to build
+ /// a CallableTransform, and then uses <tt>call\<\></tt> to apply it.
+ ///
+ /// <tt>bind\<\></tt> is useful as a higher-order transform, when the
+ /// transform to be applied depends on the current state of the
+ /// transformation. The invocation of the <tt>make\<\></tt> transform
+ /// evaluates any nested transforms, and the resulting type is treated
+ /// as a CallableTransform, which is evaluated with <tt>call\<\></tt>.
+ template<typename Object>
+ struct bind : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename make<Object>::template result<void(Expr, State, Visitor)>::type fun;
+ typedef call<fun> impl;
+ typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ /// Build a CallableTransform by applying <tt>make\<\></tt>
+ /// and evaluate it with <tt>call\<\></tt>
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::impl()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return typename result<void(Expr, State, Visitor)>::impl()(expr, state, visitor);
+ }
+ };
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/bind.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Object>
+ struct is_callable<transform::bind<Object> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief A PrimitiveTransform that uses <tt>make\<\></tt> to build
+ /// a CallableTransform, and then uses <tt>call\<\></tt> to apply it.
+ ///
+ /// <tt>bind\<\></tt> is useful as a higher-order transform, when the
+ /// transform to be applied depends on the current state of the
+ /// transformation. The invocation of the <tt>make\<\></tt> transform
+ /// evaluates any nested transforms, and the resulting type is treated
+ /// as a CallableTransform, which is evaluated with <tt>call\<\></tt>.
+ template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct bind<Object(BOOST_PP_ENUM_PARAMS(N, A))> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename make<Object>::template result<void(Expr, State, Visitor)>::type fun;
+ typedef call<fun(BOOST_PP_ENUM_PARAMS(N, A))> impl;
+ typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ /// Build a CallableTransform by applying <tt>make\<\></tt>
+ /// and evaluate it with <tt>call\<\></tt>
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::impl()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return typename result<void(Expr, State, Visitor)>::impl()(expr, state, visitor);
+ }
+ };
+
+ #undef N
+
+#endif

Deleted: branches/release/boost/xpressive/proto/transform/branch.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/branch.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
+++ (empty file)
@@ -1,52 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file branch.hpp
-/// A special-purpose proto transform for transforming one branch of the expression
-/// tree separately from the rest. Given an expression and a new state, it
-/// transforms the expression using the new state.
-//
-// Copyright 2007 Eric Niebler. 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)
-
-#ifndef BOOST_PROTO_TRANSFORM_BRANCH_HPP_EAN_12_16_2006
-#define BOOST_PROTO_TRANSFORM_BRANCH_HPP_EAN_12_16_2006
-
-#include <boost/xpressive/proto/detail/prefix.hpp>
-#include <boost/mpl/bool.hpp>
-#include <boost/xpressive/proto/proto_fwd.hpp>
-#include <boost/xpressive/proto/detail/suffix.hpp>
-
-namespace boost { namespace proto { namespace transform
-{
-
- // A branch compiler, for compiling a sub-tree with a specified state
- template<typename Grammar, typename BranchState>
- struct branch
- : Grammar
- {
- branch() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : Grammar::template apply<Expr, BranchState, Visitor>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &visitor)
- {
- return Grammar::call(expr, BranchState(), visitor);
- }
- };
-
-}}}
-
-namespace boost { namespace proto
-{
- template<typename Grammar, typename BranchState>
- struct is_transform<transform::branch<Grammar, BranchState> >
- : mpl::true_
- {};
-}}
-
-#endif

Added: branches/release/boost/xpressive/proto/transform/call.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/transform/call.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,525 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file call.hpp
+ /// Contains definition of the call<> transform.
+ //
+ // Copyright 2008 Eric Niebler. 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)
+
+ #ifndef BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007
+ #define BOOST_PROTO_TRANSFORM_CALL_HPP_EAN_11_02_2007
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/repeat.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/traits.hpp>
+ #include <boost/xpressive/proto/detail/dont_care.hpp>
+ #include <boost/xpressive/proto/detail/as_lvalue.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+
+ namespace transform
+ {
+ namespace detail
+ {
+ using proto::detail::uncv;
+ using proto::detail::as_lvalue;
+ using proto::detail::dont_care;
+ typedef char (&yes_type)[2];
+ typedef char no_type;
+
+ struct private_type_
+ {
+ private_type_ const &operator ,(int) const;
+ };
+
+ template<typename T>
+ yes_type check_fun_arity(T const &);
+
+ no_type check_fun_arity(private_type_ const &);
+
+ template<typename Fun>
+ struct callable0_wrap : Fun
+ {
+ callable0_wrap();
+ typedef private_type_ const &(*pfun0)();
+ operator pfun0() const;
+ };
+
+ template<typename Fun>
+ struct callable1_wrap : Fun
+ {
+ callable1_wrap();
+ typedef private_type_ const &(*pfun1)(dont_care);
+ operator pfun1() const;
+ };
+
+ template<typename Fun>
+ struct callable2_wrap : Fun
+ {
+ callable2_wrap();
+ typedef private_type_ const &(*pfun2)(dont_care, dont_care);
+ operator pfun2() const;
+ };
+
+ template<typename Fun>
+ struct arity0
+ {
+ static callable0_wrap<Fun> &fun;
+
+ static int const value =
+ sizeof(yes_type) == sizeof(check_fun_arity((fun(), 0)))
+ ? 0
+ : 3;
+ };
+
+ template<typename Fun, typename A0>
+ struct arity1
+ {
+ static callable1_wrap<Fun> &fun;
+ static A0 &a0;
+
+ static int const value =
+ sizeof(yes_type) == sizeof(check_fun_arity((fun(a0), 0)))
+ ? 1
+ : 3;
+ };
+
+ template<typename Fun, typename A0, typename A1>
+ struct arity2
+ {
+ static callable2_wrap<Fun> &fun;
+ static A0 &a0;
+ static A1 &a1;
+
+ static int const value =
+ sizeof(yes_type) == sizeof(check_fun_arity((fun(a0, a1), 0)))
+ ? 2
+ : 3;
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor>
+ struct call3
+ {
+ typedef typename boost::result_of<Fun(Expr, State, Visitor)>::type type;
+
+ template<typename Expr2, typename State2, typename Visitor2>
+ static type call(Expr2 &expr, State2 &state, Visitor2 &visitor)
+ {
+ Fun f;
+ return f(expr, state, visitor);
+ }
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor
+ , int Arity = arity0<Fun>::value>
+ struct call0
+ : call3<Fun, Expr, State, Visitor>
+ {};
+
+ template<typename Fun, typename Expr, typename State, typename Visitor>
+ struct call0<Fun, Expr, State, Visitor, 0>
+ {
+ typedef typename boost::result_of<Fun()>::type type;
+
+ template<typename Expr2, typename State2, typename Visitor2>
+ static type call(Expr2 &, State2 &, Visitor2 &)
+ {
+ Fun f;
+ return f();
+ }
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor
+ , int Arity = arity1<Fun, Expr>::value>
+ struct call1
+ : call3<Fun, Expr, State, Visitor>
+ {};
+
+ template<typename Fun, typename Expr, typename State, typename Visitor>
+ struct call1<Fun, Expr, State, Visitor, 1>
+ {
+ typedef typename boost::result_of<Fun(Expr)>::type type;
+
+ template<typename Expr2, typename State2, typename Visitor2>
+ static type call(Expr2 &expr, State2 &, Visitor2 &)
+ {
+ Fun f;
+ return f(expr);
+ }
+ };
+
+ template<typename Fun, typename Expr, typename State, typename Visitor
+ , int Arity = arity2<Fun, Expr, State>::value>
+ struct call2
+ : call3<Fun, Expr, State, Visitor>
+ {};
+
+ template<typename Fun, typename Expr, typename State, typename Visitor>
+ struct call2<Fun, Expr, State, Visitor, 2>
+ {
+ typedef typename boost::result_of<Fun(Expr, State)>::type type;
+
+ template<typename Expr2, typename State2, typename Visitor2>
+ static type call(Expr2 &expr, State2 &state, Visitor2 &)
+ {
+ Fun f;
+ return f(expr, state);
+ }
+ };
+ } // namespace detail
+
+ /// \brief Wrap \c PrimitiveTransform so that <tt>when\<\></tt> knows
+ /// it is callable. Requires that the parameter is actually a
+ /// PrimitiveTransform.
+ ///
+ /// This form of <tt>call\<\></tt> is useful for annotating an
+ /// arbitrary PrimitiveTransform as callable when using it with
+ /// <tt>when\<\></tt>. Consider the following transform, which
+ /// is parameterized with another transform.
+ ///
+ /// \code
+ /// template<typename Grammar>
+ /// struct Foo
+ /// : when<
+ /// posit<Grammar>
+ /// , Grammar(_arg) // May or may not work.
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// The problem with the above is that <tt>when\<\></tt> may or
+ /// may not recognize \c Grammar as callable, depending on how
+ /// \c Grammar is implemented. (See <tt>is_callable\<\></tt> for
+ /// a discussion of this issue.) The above code can guard against
+ /// the issue by wrapping \c Grammar in <tt>call\<\></tt>, such
+ /// as:
+ ///
+ /// \code
+ /// template<typename Grammar>
+ /// struct Foo
+ /// : when<
+ /// posit<Grammar>
+ /// , call<Grammar>(_arg) // OK, this works
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// The above could also have been written as:
+ ///
+ /// \code
+ /// template<typename Grammar>
+ /// struct Foo
+ /// : when<
+ /// posit<Grammar>
+ /// , call<Grammar(_arg)> // OK, this works, too
+ /// >
+ /// {};
+ /// \endcode
+ template<typename PrimitiveTransform>
+ struct call : PrimitiveTransform
+ {
+ BOOST_PROTO_CALLABLE()
+ };
+
+ /// \brief Either call the PolymorphicFunctionObject with 0
+ /// arguments, or invoke the PrimitiveTransform with 3
+ /// arguments.
+ template<typename Fun>
+ struct call<Fun()> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// If \c Fun is a nullary PolymorphicFunctionObject, \c type is a typedef
+ /// for <tt>boost::result_of\<Fun()\>::::type</tt>. Otherwise, it is
+ /// a typedef for <tt>boost::result_of\<Fun(Expr, State, Visitor)\>::::type</tt>.
+ typedef
+ typename detail::call0<
+ Fun
+ , Expr
+ , State
+ , Visitor
+ >::type
+ type;
+ };
+
+ /// Either call the PolymorphicFunctionObject \c Fun with 0 arguments; or
+ /// invoke the PrimitiveTransform \c Fun with 3 arguments: the current
+ /// expression, state, and visitor.
+ ///
+ /// If \c Fun is a nullary PolymorphicFunctionObject, return <tt>Fun()()</tt>.
+ /// Otherwise, return <tt>Fun()(expr, state, visitor)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::call0<
+ Fun
+ , Expr
+ , State
+ , Visitor
+ >
+ impl;
+
+ return impl::call(expr, state, visitor);
+ }
+ };
+
+ /// \brief Either call the PolymorphicFunctionObject with 1
+ /// argument, or invoke the PrimitiveTransform with 3
+ /// arguments.
+ template<typename Fun, typename A0>
+ struct call<Fun(A0)> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, visitor)</tt> and \c X
+ /// be the type of \c x.
+ /// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
+ /// then \c type is a typedef for <tt>boost::result_of\<Fun(X)\>::::type</tt>.
+ /// Otherwise, it is a typedef for <tt>boost::result_of\<Fun(X, State, Visitor)\>::::type</tt>.
+ typedef
+ typename detail::call1<
+ Fun
+ , typename when<_, A0>::template result<void(Expr, State, Visitor)>::type
+ , State
+ , Visitor
+ >::type
+ type;
+ };
+
+ /// Either call the PolymorphicFunctionObject with 1 argument:
+ /// the result of applying the \c A0 transform; or
+ /// invoke the PrimitiveTransform with 3 arguments:
+ /// result of applying the \c A0 transform, the state, and the
+ /// visitor.
+ ///
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, visitor)</tt>.
+ /// If \c Fun is a unary PolymorphicFunctionObject that accepts \c x,
+ /// then return <tt>Fun()(x)</tt>. Otherwise, return
+ /// <tt>Fun()(x, state, visitor)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::call1<
+ Fun
+ , typename when<_, A0>::template result<void(Expr, State, Visitor)>::type
+ , State
+ , Visitor
+ >
+ impl;
+
+ return impl::call(
+ detail::as_lvalue(when<_, A0>()(expr, state, visitor))
+ , state
+ , visitor
+ );
+ }
+ };
+
+ /// \brief Either call the PolymorphicFunctionObject with 2
+ /// arguments, or invoke the PrimitiveTransform with 3
+ /// arguments.
+ template<typename Fun, typename A0, typename A1>
+ struct call<Fun(A0, A1)> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, visitor)</tt> and \c X
+ /// be the type of \c x.
+ /// Let \c y be <tt>when\<_, A1\>()(expr, state, visitor)</tt> and \c Y
+ /// be the type of \c y.
+ /// If \c Fun is a binary PolymorphicFunction object that accepts \c x
+ /// and \c y, then \c type is a typedef for
+ /// <tt>boost::result_of\<Fun(X, Y)\>::::type</tt>. Otherwise, it is
+ /// a typedef for <tt>boost::result_of\<Fun(X, Y, Visitor)\>::::type</tt>.
+ typedef
+ typename detail::call2<
+ Fun
+ , typename when<_, A0>::template result<void(Expr, State, Visitor)>::type
+ , typename when<_, A1>::template result<void(Expr, State, Visitor)>::type
+ , Visitor
+ >::type
+ type;
+ };
+
+ /// Either call the PolymorphicFunctionObject with 2 arguments:
+ /// the result of applying the \c A0 transform, and the
+ /// result of applying the \c A1 transform; or invoke the
+ /// PrimitiveTransform with 3 arguments: the result of applying
+ /// the \c A0 transform, the result of applying the \c A1
+ /// transform, and the visitor.
+ ///
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, visitor)</tt>.
+ /// Let \c y be <tt>when\<_, A1\>()(expr, state, visitor)</tt>.
+ /// If \c Fun is a binary PolymorphicFunction object that accepts \c x
+ /// and \c y, return <tt>Fun()(x, y)</tt>. Otherwise, return
+ /// <tt>Fun()(x, y, visitor)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::call2<
+ Fun
+ , typename when<_, A0>::template result<void(Expr, State, Visitor)>::type
+ , typename when<_, A1>::template result<void(Expr, State, Visitor)>::type
+ , Visitor
+ >
+ impl;
+
+ return impl::call(
+ detail::as_lvalue(when<_, A0>()(expr, state, visitor))
+ , detail::as_lvalue(when<_, A1>()(expr, state, visitor))
+ , visitor
+ );
+ }
+ };
+
+ /// \brief Call the PolymorphicFunctionObject or the
+ /// PrimitiveTransform with the current expression, state
+ /// and visitor, transformed according to \c A0, \c A1, and
+ /// \c A2, respectively.
+ template<typename Fun, typename A0, typename A1, typename A2>
+ struct call<Fun(A0, A1, A2)> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename when<_, A0>::template result<void(Expr, State, Visitor)>::type a0;
+ typedef typename when<_, A1>::template result<void(Expr, State, Visitor)>::type a1;
+ typedef typename when<_, A2>::template result<void(Expr, State, Visitor)>::type a2;
+ typedef typename boost::result_of<Fun(a0, a1, a2)>::type type;
+ };
+
+ /// Let \c x be <tt>when\<_, A0\>()(expr, state, visitor)</tt>.
+ /// Let \c y be <tt>when\<_, A1\>()(expr, state, visitor)</tt>.
+ /// Let \c z be <tt>when\<_, A2\>()(expr, state, visitor)</tt>.
+ /// Return <tt>Fun()(x, y, z)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ Fun f;
+ return f(
+ detail::as_lvalue(when<_, A0>()(expr, state, visitor))
+ , detail::as_lvalue(when<_, A1>()(expr, state, visitor))
+ , detail::uncv(when<_, A2>()(expr, state, visitor)) // HACK
+ );
+ }
+ };
+
+ #if BOOST_PROTO_MAX_ARITY > 3
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (4, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/call.hpp>))
+ #include BOOST_PP_ITERATE()
+ #endif
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Fun>
+ struct is_callable<transform::call<Fun> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief Call the PolymorphicFunctionObject \c Fun with the
+ /// current expression, state and visitor, transformed according
+ /// to \c A0 through \c AN.
+ template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct call<Fun(BOOST_PP_ENUM_PARAMS(N, A))> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ #define TMP(Z, M, DATA) \
+ typedef \
+ typename when<_, BOOST_PP_CAT(A, M)> \
+ ::template result<void(Expr, State, Visitor)> \
+ ::type \
+ BOOST_PP_CAT(a, M); \
+ /**/
+ BOOST_PP_REPEAT(N, TMP, ~)
+ #undef TMP
+
+ typedef
+ typename boost::result_of<
+ Fun(BOOST_PP_ENUM_PARAMS(N, a))
+ >::type
+ type;
+ };
+
+ /// Let \c ax be <tt>when\<_, Ax\>()(expr, state, visitor)</tt>
+ /// for each \c x in <tt>[0,N]</tt>.
+ /// Return <tt>Fun()(a0, a1,... aN)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ Fun f;
+ #define TMP(Z, M, DATA) when<_, BOOST_PP_CAT(A, M)>()(expr, state, visitor)
+ return f(BOOST_PP_ENUM(N, TMP, ~));
+ #undef TMP
+ }
+ };
+
+ #undef N
+
+#endif

Deleted: branches/release/boost/xpressive/proto/transform/compose.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/compose.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
+++ (empty file)
@@ -1,58 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file compose.hpp
-/// A special-purpose proto transform for composing two transfomations. Given
-/// two Grammars, expressions that match the first grammar are transformed
-/// according to that grammar, and the result is forwarded to the second
-/// for further transformation.
-//
-// Copyright 2007 Eric Niebler. 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)
-
-#ifndef BOOST_PROTO_TRANSFORM_COMPOSE_HPP_EAN_04_01_2007
-#define BOOST_PROTO_TRANSFORM_COMPOSE_HPP_EAN_04_01_2007
-
-#include <boost/xpressive/proto/detail/prefix.hpp>
-#include <boost/mpl/bool.hpp> // mpl::true_
-#include <boost/xpressive/proto/proto_fwd.hpp>
-#include <boost/xpressive/proto/detail/suffix.hpp>
-
-namespace boost { namespace proto { namespace transform
-{
-
- // Composes two transforms
- template<typename Grammar1, typename Grammar2>
- struct compose
- : Grammar1
- {
- compose() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef typename Grammar2::template apply<
- typename Grammar1::template apply<Expr, State, Visitor>::type
- , State
- , Visitor
- >::type type;
- };
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Grammar2::call(Grammar1::call(expr, state, visitor), state, visitor);
- }
- };
-
-}}}
-
-namespace boost { namespace proto
-{
- template<typename Grammar1, typename Grammar2>
- struct is_transform<transform::compose<Grammar1, Grammar2> >
- : mpl::true_
- {};
-}}
-
-#endif

Deleted: branches/release/boost/xpressive/proto/transform/construct.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/construct.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
+++ (empty file)
@@ -1,270 +0,0 @@
-#ifndef BOOST_PP_IS_ITERATING
- ///////////////////////////////////////////////////////////////////////////////
- /// \file construct.hpp
- /// For constructing an arbitrary type from a bunch of transforms.
- //
- // Copyright 2007 Eric Niebler. 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)
-
- #ifndef BOOST_PROTO_TRANSFORM_CONSTRUCT_HPP_EAN_12_26_2006
- #define BOOST_PROTO_TRANSFORM_CONSTRUCT_HPP_EAN_12_26_2006
-
- #include <boost/xpressive/proto/detail/prefix.hpp>
- #include <boost/preprocessor/iterate.hpp>
- #include <boost/preprocessor/facilities/intercept.hpp>
- #include <boost/preprocessor/repetition/enum.hpp>
- #include <boost/preprocessor/repetition/enum_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing.hpp>
- #include <boost/preprocessor/repetition/enum_binary_params.hpp>
- #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/mpl/aux_/has_type.hpp>
- #include <boost/mpl/aux_/lambda_arity_param.hpp>
- #include <boost/type_traits/is_pod.hpp>
- #include <boost/type_traits/is_function.hpp>
- #include <boost/type_traits/remove_pointer.hpp>
- #include <boost/xpressive/proto/proto_fwd.hpp>
- #include <boost/xpressive/proto/detail/suffix.hpp>
-
- namespace boost { namespace proto { namespace transform
- {
- namespace detail
- {
- template<typename T>
- struct is_aggregate
- : is_pod<T>
- {};
-
- template<typename Tag, typename Args, long N>
- struct is_aggregate<expr<Tag, Args, N> >
- : mpl::true_
- {};
-
- template<typename T, bool HasType = mpl::aux::has_type<T>::value>
- struct nested_type
- {
- typedef typename T::type type;
- };
-
- template<typename T>
- struct nested_type<T, false>
- {
- typedef T type;
- };
-
- template<typename T BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PROTO_MAX_ARITY, typename A, = no_type BOOST_PP_INTERCEPT)>
- struct nested_type_if
- : nested_type<T>
- {
- typedef yes_type proto_transform_applied;
- };
-
- template<typename T>
- struct nested_type_if<T BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, no_type BOOST_PP_INTERCEPT)>
- {
- typedef T type;
- typedef no_type proto_transform_applied;
- };
-
- template<typename Arg, bool IsFunction = is_function<typename remove_pointer<Arg>::type>::value>
- struct as_transform
- {
- typedef Arg type;
- };
-
- template<typename Arg>
- struct as_transform<Arg, true>
- {
- typedef construct<_, typename remove_pointer<Arg>::type> type;
- };
-
- template<typename Arg, bool IsFunction = is_function<typename remove_pointer<Arg>::type>::value>
- struct as_pod_transform
- {
- typedef Arg type;
- };
-
- template<typename Arg>
- struct as_pod_transform<Arg, true>
- {
- typedef pod_construct<_, typename remove_pointer<Arg>::type> type;
- };
-
- template<typename R, typename Expr, typename State, typename Visitor
- BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
- >
- struct apply_aux_
- {
- typedef R type;
- typedef no_type proto_transform_applied;
- };
-
- template<typename R, typename Expr, typename State, typename Visitor, bool IsTransform = is_transform<R>::value>
- struct apply_
- : apply_aux_<R, Expr, State, Visitor>
- {};
-
- template<typename R, typename Expr, typename State, typename Visitor>
- struct apply_<R, Expr, State, Visitor, true>
- : nested_type<typename R::template apply<Expr, State, Visitor>::type>
- {
- typedef yes_type proto_transform_applied;
- };
-
- // work around GCC bug
- template<typename Tag, typename Args, long N, typename Expr, typename State, typename Visitor>
- struct apply_<expr<Tag, Args, N>, Expr, State, Visitor, false>
- {
- typedef expr<Tag, Args, N> type;
- typedef no_type proto_transform_applied;
- };
-
- template<typename T>
- void ignore_unused(T const &)
- {}
- }
-
- template<typename Grammar, typename ConstructorFun>
- struct construct
- : Grammar
- {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : ConstructorFun::template apply<typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return ConstructorFun::call(Grammar::call(expr, state, visitor), state, visitor);
- }
- };
-
- #define BOOST_PROTO_APPLY_(Z, N, DATA) \
- typename apply_<BOOST_PP_CAT(DATA, N), Expr, State, Visitor>::type \
- /**/
-
- #define BOOST_PROTO_IS_APPLIED_(Z, N, DATA) \
- typename apply_<BOOST_PP_CAT(DATA, N), Expr, State, Visitor>::proto_transform_applied \
- /**/
-
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/construct.hpp>))
- #include BOOST_PP_ITERATE()
-
- #undef BOOST_PROTO_APPLY_
- #undef BOOST_PROTO_IS_APPLIED_
-
- }}}
-
- namespace boost { namespace proto
- {
- template<typename Grammar, typename ConstructorFun>
- struct is_transform<transform::construct<Grammar, ConstructorFun> >
- : mpl::true_
- {};
-
- template<typename Grammar, typename ConstructorFun>
- struct is_transform<transform::pod_construct<Grammar, ConstructorFun> >
- : mpl::true_
- {};
- }}
-
- #endif
-
-#else
-
- #define N BOOST_PP_ITERATION()
-
- #if N > 0
- namespace detail
- {
- template<
- template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class T
- BOOST_PP_ENUM_TRAILING_PARAMS(N, typename G),
- typename Expr, typename State, typename Visitor
- >
- struct apply_aux_<T<BOOST_PP_ENUM_PARAMS(N, G)>, Expr, State, Visitor BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)>
- : nested_type_if<
- T<BOOST_PP_ENUM(N, BOOST_PROTO_APPLY_, G)>
- BOOST_PP_ENUM_TRAILING(N, BOOST_PROTO_IS_APPLIED_, G)
- >
- {};
- }
- #endif
-
- template<typename Grammar, typename Result BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg)>
- struct construct<Grammar, Result(BOOST_PP_ENUM_PARAMS(N, Arg))>
- : Grammar
- {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : detail::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- typedef typename apply<Expr, State, Visitor>::type result_type;
- return construct::call_(expr, state, visitor, detail::is_aggregate<result_type>());
- }
-
- private:
- /// INTERNAL ONLY
- ///
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call_(Expr const &expr, State const &state, Visitor &visitor, mpl::true_)
- {
- typename Grammar::template apply<Expr, State, Visitor>::type const &expr2
- = Grammar::call(expr, state, visitor);
- detail::ignore_unused(expr2);
- typename apply<Expr, State, Visitor>::type that = {
- BOOST_PP_ENUM_BINARY_PARAMS(N, detail::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
- };
- return that;
- }
-
- /// INTERNAL ONLY
- ///
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call_(Expr const &expr, State const &state, Visitor &visitor, mpl::false_)
- {
- typename Grammar::template apply<Expr, State, Visitor>::type const &expr2
- = Grammar::call(expr, state, visitor);
- detail::ignore_unused(expr2);
- return typename apply<Expr, State, Visitor>::type(
- BOOST_PP_ENUM_BINARY_PARAMS(N, detail::as_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
- );
- }
- };
-
- template<typename Grammar, typename Result BOOST_PP_ENUM_TRAILING_PARAMS(N, typename Arg)>
- struct pod_construct<Grammar, Result(BOOST_PP_ENUM_PARAMS(N, Arg))>
- : Grammar
- {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : detail::apply_<Result, typename Grammar::template apply<Expr, State, Visitor>::type, State, Visitor>
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- typename Grammar::template apply<Expr, State, Visitor>::type const &expr2
- = Grammar::call(expr, state, visitor);
- detail::ignore_unused(expr2);
- typename apply<Expr, State, Visitor>::type that = {
- BOOST_PP_ENUM_BINARY_PARAMS(N, detail::as_pod_transform<Arg, >::type::call(expr2, state, visitor) BOOST_PP_INTERCEPT)
- };
- return that;
- }
- };
-
- #undef N
-
-#endif

Modified: branches/release/boost/xpressive/proto/transform/fold.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/fold.hpp (original)
+++ branches/release/boost/xpressive/proto/transform/fold.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,145 +1,338 @@
 #ifndef BOOST_PP_IS_ITERATING
     ///////////////////////////////////////////////////////////////////////////////
     /// \file fold.hpp
- /// A special-purpose proto transform for merging sequences of binary operations.
- /// It transforms the right operand and passes the result as state while transforming
- /// the left. Or, it might do the left first, if you choose.
+ /// Contains definition of the fold<> and reverse_fold<> transforms.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
- #ifndef BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_12_16_2006
- #define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_12_16_2006
+ #ifndef BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
+ #define BOOST_PROTO_TRANSFORM_FOLD_HPP_EAN_11_04_2007
 
     #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/version.hpp>
     #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/arithmetic/inc.hpp>
     #include <boost/preprocessor/arithmetic/sub.hpp>
- #include <boost/preprocessor/iteration/iterate.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
+ #if BOOST_VERSION >= 103500
+ #include <boost/fusion/include/fold.hpp>
+ #else
+ #include <boost/spirit/fusion/algorithm/fold.hpp>
+ #endif
     #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/fusion.hpp>
     #include <boost/xpressive/proto/traits.hpp>
- #include <boost/xpressive/proto/transform/branch.hpp>
+ #include <boost/xpressive/proto/transform/call.hpp>
     #include <boost/xpressive/proto/detail/suffix.hpp>
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
-
- namespace detail
+ namespace transform
         {
- template<typename Grammar, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
- struct fold_impl
- {};
 
- template<typename Grammar, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
- struct reverse_fold_impl
- {};
+ namespace detail
+ {
 
- #define BOOST_PROTO_ARG_N_TYPE(n)\
- BOOST_PP_CAT(proto_arg, n)\
- /**/
-
- #define BOOST_PROTO_FOLD_STATE_TYPE(z, n, data)\
- typedef typename Grammar::BOOST_PROTO_ARG_N_TYPE(n)::template\
- apply<typename Expr::BOOST_PROTO_ARG_N_TYPE(n)::proto_base_expr, BOOST_PP_CAT(state, n), Visitor>::type\
- BOOST_PP_CAT(state, BOOST_PP_INC(n));\
- /**/
-
- #define BOOST_PROTO_FOLD_STATE(z, n, data)\
- BOOST_PP_CAT(state, BOOST_PP_INC(n)) const &BOOST_PP_CAT(s, BOOST_PP_INC(n)) =\
- Grammar::BOOST_PROTO_ARG_N_TYPE(n)::call(expr.BOOST_PP_CAT(arg, n).proto_base(), BOOST_PP_CAT(s, n), visitor);\
- /**/
-
- #define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(z, n, data)\
- typedef typename Grammar::BOOST_PROTO_ARG_N_TYPE(BOOST_PP_SUB(data, BOOST_PP_INC(n)))::template\
- apply<typename Expr::BOOST_PROTO_ARG_N_TYPE(BOOST_PP_SUB(data, BOOST_PP_INC(n)))::proto_base_expr, BOOST_PP_CAT(state, BOOST_PP_SUB(data, n)), Visitor>::type\
- BOOST_PP_CAT(state, BOOST_PP_SUB(data, BOOST_PP_INC(n)));\
- /**/
-
- #define BOOST_PROTO_REVERSE_FOLD_STATE(z, n, data)\
- BOOST_PP_CAT(state, BOOST_PP_SUB(data, BOOST_PP_INC(n))) const &BOOST_PP_CAT(s, BOOST_PP_SUB(data, BOOST_PP_INC(n))) =\
- Grammar::BOOST_PROTO_ARG_N_TYPE(BOOST_PP_SUB(data, BOOST_PP_INC(n)))::call(expr.BOOST_PP_CAT(arg, BOOST_PP_SUB(data, BOOST_PP_INC(n))).proto_base(), BOOST_PP_CAT(s, BOOST_PP_SUB(data, n)), visitor);\
- /**/
-
- #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/fold.hpp>))
- #include BOOST_PP_ITERATE()
-
- #undef BOOST_PROTO_REVERSE_FOLD_STATE
- #undef BOOST_PROTO_REVERSE_FOLD_STATE_TYPE
- #undef BOOST_PROTO_FOLD_STATE
- #undef BOOST_PROTO_FOLD_STATE_TYPE
- #undef BOOST_PROTO_ARG_N_TYPE
- }
+ template<typename Transform, typename Visitor>
+ struct as_callable
+ {
+ as_callable(Visitor &v)
+ : v_(v)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State>
+ struct result<This(Expr, State)>
+ {
+ typedef
+ typename when<_, Transform>::template result<void(
+ BOOST_PROTO_UNCVREF(Expr)
+ , BOOST_PROTO_UNCVREF(State)
+ , Visitor
+ )>::type
+ type;
+ };
+
+ #if BOOST_VERSION < 103500
+ template<typename Expr, typename State>
+ struct apply : result<void(Expr, State)> {};
+ #endif
+
+ template<typename Expr, typename State>
+ typename when<_, Transform>::template result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state) const
+ {
+ return when<_, Transform>()(expr, state, this->v_);
+ }
+
+ private:
+ Visitor &v_;
+ };
+
+ #if BOOST_VERSION < 103500
+ template<typename Sequence, typename Void = void>
+ struct as_fusion_sequence_type
+ {
+ typedef Sequence const type;
+ };
 
- // A fold transform that transforms the left sub-tree and
- // uses the result as state while transforming the right.
- template<typename Grammar>
- struct fold<Grammar, void>
- : Grammar
- {
- fold() {}
+ template<typename Sequence>
+ Sequence const &as_fusion_sequence(Sequence const &sequence, ...)
+ {
+ return sequence;
+ }
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : detail::fold_impl<Grammar, typename Expr::proto_base_expr, State, Visitor>
- {};
+ template<typename Sequence>
+ struct as_fusion_sequence_type<Sequence, typename Sequence::proto_is_expr_>
+ {
+ typedef typename Sequence::proto_base_expr const type;
+ };
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
- }
- };
-
- // A reverse_fold compiler that compiles the right sub-tree and
- // uses the result as state while compiling the left.
- template<typename Grammar>
- struct reverse_fold<Grammar, void>
- : Grammar
- {
- reverse_fold() {}
+ template<typename Sequence>
+ typename Sequence::proto_base_expr const &as_fusion_sequence(Sequence const &sequence, int)
+ {
+ return sequence.proto_base();
+ }
+
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) typename detail::as_fusion_sequence_type<X>::type
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE(X) detail::as_fusion_sequence(X, 0)
+ #else
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(X) X
+ #define BOOST_PROTO_AS_FUSION_SEQUENCE(X) X
+ #endif
+
+ template<typename Fun, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
+ struct fold_impl
+ {};
+
+ template<typename Fun, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
+ struct reverse_fold_impl
+ {};
+
+ #define BOOST_PROTO_ARG_N_TYPE(n)\
+ BOOST_PP_CAT(proto_arg, n)\
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE_TYPE(z, n, data)\
+ typedef\
+ typename when<_, Fun>::template result<void(\
+ typename Expr::BOOST_PROTO_ARG_N_TYPE(n)::proto_base_expr\
+ , BOOST_PP_CAT(state, n)\
+ , Visitor\
+ )>::type\
+ BOOST_PP_CAT(state, BOOST_PP_INC(n));\
+ /**/
+
+ #define BOOST_PROTO_FOLD_STATE(z, n, data)\
+ BOOST_PP_CAT(state, BOOST_PP_INC(n)) const &BOOST_PP_CAT(s, BOOST_PP_INC(n)) =\
+ when<_, Fun>()(expr.BOOST_PP_CAT(arg, n).proto_base(), BOOST_PP_CAT(s, n), visitor);\
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE_TYPE(z, n, data)\
+ typedef\
+ typename when<_, Fun>::template result<void(\
+ typename Expr::BOOST_PROTO_ARG_N_TYPE(BOOST_PP_SUB(data, BOOST_PP_INC(n)))::proto_base_expr\
+ , BOOST_PP_CAT(state, BOOST_PP_SUB(data, n))\
+ , Visitor\
+ )>::type\
+ BOOST_PP_CAT(state, BOOST_PP_SUB(data, BOOST_PP_INC(n)));\
+ /**/
+
+ #define BOOST_PROTO_REVERSE_FOLD_STATE(z, n, data)\
+ BOOST_PP_CAT(state, BOOST_PP_SUB(data, BOOST_PP_INC(n))) const &BOOST_PP_CAT(s, BOOST_PP_SUB(data, BOOST_PP_INC(n))) =\
+ when<_, Fun>()(expr.BOOST_PP_CAT(arg, BOOST_PP_SUB(data, BOOST_PP_INC(n))).proto_base(), BOOST_PP_CAT(s, BOOST_PP_SUB(data, n)), visitor);\
+ /**/
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/fold.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE
+ #undef BOOST_PROTO_REVERSE_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_FOLD_STATE
+ #undef BOOST_PROTO_FOLD_STATE_TYPE
+ #undef BOOST_PROTO_ARG_N_TYPE
+
+ } // namespace detail
+
+ /// \brief A PrimitiveTransform that invokes the <tt>fusion::fold\<\></tt>
+ /// algorithm to accumulate
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold : proto::callable
+ {
+ template<typename Sig>
+ struct result;
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : detail::reverse_fold_impl<Grammar, typename Expr::proto_base_expr, State, Visitor>
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// \brief A Fusion sequence.
+ typedef
+ typename when<_, Sequence>::template result<void(Expr, State, Visitor)>::type
+ sequence;
+
+ /// \brief An initial state for the fold.
+ typedef
+ typename when<_, State0>::template result<void(Expr, State, Visitor)>::type
+ state0;
+
+ /// \brief <tt>fun(v)(e,s) == when\<_,Fun\>()(e,s,v)</tt>
+ typedef
+ detail::as_callable<Fun, Visitor>
+ fun;
+
+ typedef
+ typename fusion::BOOST_PROTO_FUSION_RESULT_OF::fold<
+ BOOST_PROTO_AS_FUSION_SEQUENCE_TYPE(sequence)
+ , state0
+ , fun
+ >::type
+ type;
+ };
+
+ /// Let \c seq be <tt>when\<_, Sequence\>()(expr, state, visitor)</tt>, let
+ /// \c state0 be <tt>when\<_, State0\>()(expr, state, visitor)</tt>, and
+ /// let \c fun(visitor) be an object such that <tt>fun(visitor)(expr, state)</tt>
+ /// is equivalent to <tt>when\<_, Fun\>()(expr, state, visitor)</tt>. Then, this
+ /// function returns <tt>fusion::fold(seq, state0, fun(visitor))</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ when<_, Sequence> sequence;
+ detail::as_callable<Fun, Visitor> fun(visitor);
+ return fusion::fold(
+ BOOST_PROTO_AS_FUSION_SEQUENCE(sequence(expr, state, visitor))
+ , when<_, State0>()(expr, state, visitor)
+ , fun
+ );
+ }
+ };
+
+ /// \brief A PrimitiveTransform that is the same as the
+ /// <tt>fold\<\></tt> transform, except that it folds
+ /// back-to-front instead of front-to-back. It uses
+ /// the \c _reverse callable PolymorphicFunctionObject
+ /// to create a <tt>fusion::reverse_view\<\></tt> of the
+ /// sequence before invoking <tt>fusion::fold\<\></tt>.
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold
+ : fold<call<_reverse(Sequence)>, State0, Fun>
             {};
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
- }
- };
-
- // Causes Doxygen to crash. Sigh.
- #ifndef BOOST_PROTO_DOXYGEN_INVOKED
- template<typename Grammar, typename State>
- struct fold
- : branch<fold<Grammar, void>, State>
- {};
+ // This specialization is only for improved compile-time performance
+ // in the commom case when the Sequence transform is \c proto::_.
+ //
+ /// INTERNAL ONLY
+ ///
+ template<typename State0, typename Fun>
+ struct fold<_, State0, Fun> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
 
- template<typename Grammar, typename State>
- struct reverse_fold
- : branch<reverse_fold<Grammar, void>, State>
- {};
- #endif
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename detail::fold_impl<
+ Fun
+ , typename Expr::proto_base_expr
+ , typename when<_, State0>::template result<void(Expr, State, Visitor)>::type
+ , Visitor
+ >::type
+ type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::fold_impl<
+ Fun
+ , typename Expr::proto_base_expr
+ , typename when<_, State0>::template result<void(Expr, State, Visitor)>::type
+ , Visitor
+ >
+ impl;
+
+ return impl::call(
+ expr.proto_base()
+ , when<_, State0>()(expr, state, visitor)
+ , visitor
+ );
+ }
+ };
 
- }}}
+ // This specialization is only for improved compile-time performance
+ // in the commom case when the Sequence transform is \c proto::_.
+ //
+ /// INTERNAL ONLY
+ ///
+ template<typename State0, typename Fun>
+ struct reverse_fold<_, State0, Fun> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
 
- namespace boost { namespace proto
- {
- template<typename Grammar, typename State>
- struct is_transform<transform::fold<Grammar, State> >
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename detail::reverse_fold_impl<
+ Fun
+ , typename Expr::proto_base_expr
+ , typename when<_, State0>::template result<void(Expr, State, Visitor)>::type
+ , Visitor
+ >::type
+ type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::reverse_fold_impl<
+ Fun
+ , typename Expr::proto_base_expr
+ , typename when<_, State0>::template result<void(Expr, State, Visitor)>::type
+ , Visitor
+ >
+ impl;
+
+ return impl::call(
+ expr.proto_base()
+ , when<_, State0>()(expr, state, visitor)
+ , visitor
+ );
+ }
+ };
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State, typename Fun>
+ struct is_callable<transform::fold<Sequence, State, Fun> >
           : mpl::true_
         {};
 
- template<typename Grammar, typename State>
- struct is_transform<transform::reverse_fold<Grammar, State> >
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State, typename Fun>
+ struct is_callable<transform::reverse_fold<Sequence, State, Fun> >
           : mpl::true_
         {};
+
     }}
 
     #endif
@@ -148,8 +341,8 @@
 
     #define N BOOST_PP_ITERATION()
 
- template<typename Grammar, typename Expr, typename state0, typename Visitor>
- struct fold_impl<Grammar, Expr, state0, Visitor, N>
+ template<typename Fun, typename Expr, typename state0, typename Visitor>
+ struct fold_impl<Fun, Expr, state0, Visitor, N>
             {
                 BOOST_PP_REPEAT(N, BOOST_PROTO_FOLD_STATE_TYPE, N)
                 typedef BOOST_PP_CAT(state, N) type;
@@ -161,8 +354,8 @@
                 }
             };
 
- template<typename Grammar, typename Expr, typename BOOST_PP_CAT(state, N), typename Visitor>
- struct reverse_fold_impl<Grammar, Expr, BOOST_PP_CAT(state, N), Visitor, N>
+ template<typename Fun, typename Expr, typename BOOST_PP_CAT(state, N), typename Visitor>
+ struct reverse_fold_impl<Fun, Expr, BOOST_PP_CAT(state, N), Visitor, N>
             {
                 BOOST_PP_REPEAT(N, BOOST_PROTO_REVERSE_FOLD_STATE_TYPE, N)
                 typedef state0 type;
@@ -173,6 +366,7 @@
                     return s0;
                 }
             };
+
     #undef N
 
 #endif

Modified: branches/release/boost/xpressive/proto/transform/fold_tree.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/fold_tree.hpp (original)
+++ branches/release/boost/xpressive/proto/transform/fold_tree.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,76 +1,203 @@
 ///////////////////////////////////////////////////////////////////////////////
 /// \file fold_tree.hpp
-/// A higher-level transform that uses the fold, and branch transforms
-/// to recursively fold a tree.
+/// Contains definition of the fold_tree<> and reverse_fold_tree<> transforms.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
-#ifndef BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_06_18_2007
-#define BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_06_18_2007
+#ifndef BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
+#define BOOST_PROTO_TRANSFORM_FOLD_TREE_HPP_EAN_11_05_2007
 
 #include <boost/xpressive/proto/detail/prefix.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/xpressive/proto/proto_fwd.hpp>
+#include <boost/xpressive/proto/traits.hpp>
+#include <boost/xpressive/proto/matches.hpp>
 #include <boost/xpressive/proto/transform/fold.hpp>
 #include <boost/xpressive/proto/detail/suffix.hpp>
 
-namespace boost { namespace proto { namespace transform
+namespace boost { namespace proto
 {
-
- namespace detail
+ namespace transform
     {
- template<typename Tag, typename Grammar>
- struct fold_tree_
- : or_<
- transform::fold<
- nary_expr<Tag, vararg<fold_tree_<Tag, Grammar> > >
- >
- , Grammar
- >
- {};
-
- template<typename Tag, typename Grammar>
- struct reverse_fold_tree_
- : or_<
- transform::reverse_fold<
- nary_expr<Tag, vararg<reverse_fold_tree_<Tag, Grammar> > >
- >
- , Grammar
- >
- {};
+ namespace detail
+ {
+ template<typename Tag>
+ struct has_tag : proto::callable
+ {
+ template<typename Sig, typename EnableIf = Tag>
+ struct result
+ : mpl::false_
+ {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor), typename Expr::proto_tag>
+ : mpl::true_
+ {};
+ };
+
+ template<typename Tag, typename Fun>
+ struct fold_tree_
+ : if_<has_tag<Tag>, fold<_, _state, fold_tree_<Tag, Fun> >, Fun>
+ {};
+
+ template<typename Tag, typename Fun>
+ struct reverse_fold_tree_
+ : if_<has_tag<Tag>, reverse_fold<_, _state, reverse_fold_tree_<Tag, Fun> >, Fun>
+ {};
+ }
+
+ /// \brief A PrimitiveTransform that recursively applies the
+ /// <tt>fold\<\></tt> transform to sub-trees that all share a common
+ /// tag type.
+ ///
+ /// <tt>fold_tree\<\></tt> is useful for flattening trees into lists;
+ /// for example, you might use <tt>fold_tree\<\></tt> to flatten an
+ /// expression tree like <tt>a | b | c</tt> into a Fusion list like
+ /// <tt>cons(c, cons(b, cons(a)))</tt>.
+ ///
+ /// <tt>fold_tree\<\></tt> is easily understood in terms of a
+ /// <tt>recurse_if_\<\></tt> helper, defined as follows:
+ ///
+ /// \code
+ /// template<typename Tag, typename Fun>
+ /// struct recurse_if_
+ /// : if_<
+ /// // If the current node has type type "Tag" ...
+ /// is_same<tag_of<_>, Tag>()
+ /// // ... recurse, otherwise ...
+ /// , fold<_, _state, recurse_if_<Tag, Fun> >
+ /// // ... apply the Fun transform.
+ /// , Fun
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// With <tt>recurse_if_\<\></tt> as defined above,
+ /// <tt>fold_tree\<Sequence, State0, Fun\>()(expr, state, visitor)</tt> is
+ /// equivalent to
+ /// <tt>fold<Sequence, State0, recurse_if_<Expr::proto_tag, Fun> >()(expr, state, visitor).</tt>
+ /// It has the effect of folding a tree front-to-back, recursing into
+ /// child nodes that share a tag type with the parent node.
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold_tree
+ : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// \brief <tt>recurse_if_\<Expr::proto_tag, Fun\></tt>, as described below.
+ typedef
+ detail::fold_tree_<typename Expr::proto_tag, Fun>
+ recurse_if_;
+
+ typedef fold<Sequence, State0, recurse_if_> impl;
+ typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ /// Let \c R be <tt>recurse_if_\<Expr::proto_tag,Fun\></tt> as described below.
+ /// This function returns <tt>fold\<Sequence, State0, R\>()(expr, state, visitor)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::fold_tree_<typename Expr::proto_tag, Fun>
+ recurse_if_;
+
+ return fold<Sequence, State0, recurse_if_>()(expr, state, visitor);
+ }
+ };
+
+ /// \brief A PrimitiveTransform that recursively applies the
+ /// <tt>reverse_fold\<\></tt> transform to sub-trees that all share
+ /// a common tag type.
+ ///
+ /// <tt>reverse_fold_tree\<\></tt> is useful for flattening trees into
+ /// lists; for example, you might use <tt>reverse_fold_tree\<\></tt> to
+ /// flatten an expression tree like <tt>a | b | c</tt> into a Fusion list
+ /// like <tt>cons(a, cons(b, cons(c)))</tt>.
+ ///
+ /// <tt>reverse_fold_tree\<\></tt> is easily understood in terms of a
+ /// <tt>recurse_if_\<\></tt> helper, defined as follows:
+ ///
+ /// \code
+ /// template<typename Tag, typename Fun>
+ /// struct recurse_if_
+ /// : if_<
+ /// // If the current node has type type "Tag" ...
+ /// is_same<tag_of<_>, Tag>()
+ /// // ... recurse, otherwise ...
+ /// , reverse_fold<_, _state, recurse_if_<Tag, Fun> >
+ /// // ... apply the Fun transform.
+ /// , Fun
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// With <tt>recurse_if_\<\></tt> as defined above,
+ /// <tt>reverse_fold_tree\<Sequence, State0, Fun\>()(expr, state, visitor)</tt> is
+ /// equivalent to
+ /// <tt>reverse_fold<Sequence, State0, recurse_if_<Expr::proto_tag, Fun> >()(expr, state, visitor).</tt>
+ /// It has the effect of folding a tree back-to-front, recursing into
+ /// child nodes that share a tag type with the parent node.
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold_tree
+ : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// \brief <tt>recurse_if_\<Expr::proto_tag, Fun\></tt>, as described below.
+ typedef
+ detail::reverse_fold_tree_<typename Expr::proto_tag, Fun>
+ recurse_if_;
+
+ typedef reverse_fold<Sequence, State0, recurse_if_> impl;
+ typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ /// Let \c R be <tt>recurse_if_\<Expr::proto_tag,Fun\></tt> as described below.
+ /// This function returns <tt>reverse_fold\<Sequence, State0, R\>()(expr, state, visitor)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef
+ detail::reverse_fold_tree_<typename Expr::proto_tag, Fun>
+ recurse_if_;
+
+ return reverse_fold<Sequence, State0, recurse_if_>()(expr, state, visitor);
+ }
+ };
     }
 
- /// fold_tree
- ///
- template<typename Tag, typename Grammar, typename State>
- struct fold_tree
- : transform::fold<
- nary_expr<Tag, vararg<detail::fold_tree_<Tag, Grammar> > >
- , State
- >
- {};
-
- /// reverse_fold_tree
+ /// INTERNAL ONLY
     ///
- template<typename Tag, typename Grammar, typename State>
- struct reverse_fold_tree
- : transform::reverse_fold<
- nary_expr<Tag, vararg<detail::reverse_fold_tree_<Tag, Grammar> > >
- , State
- >
- {};
-
-}}}
-
-namespace boost { namespace proto
-{
- template<typename Tag, typename Grammar, typename State>
- struct is_transform<transform::fold_tree<Tag, Grammar, State> >
+ template<typename Sequence, typename State0, typename Fun>
+ struct is_callable<transform::fold_tree<Sequence, State0, Fun> >
       : mpl::true_
     {};
 
- template<typename Tag, typename Grammar, typename State>
- struct is_transform<transform::reverse_fold_tree<Tag, Grammar, State> >
+ /// INTERNAL ONLY
+ ///
+ template<typename Sequence, typename State0, typename Fun>
+ struct is_callable<transform::reverse_fold_tree<Sequence, State0, Fun> >
       : mpl::true_
     {};
 }}

Deleted: branches/release/boost/xpressive/proto/transform/function.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/function.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
+++ (empty file)
@@ -1,115 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file function.hpp
-/// Proto transforms for applying a function object.
-//
-// Copyright 2007 Eric Niebler. 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)
-
-#ifndef BOOST_PROTO_TRANSFORM_FUNCTION_HPP_EAN_06_23_2007
-#define BOOST_PROTO_TRANSFORM_FUNCTION_HPP_EAN_06_23_2007
-
-#include <boost/xpressive/proto/detail/prefix.hpp>
-#include <boost/utility/result_of.hpp>
-#include <boost/xpressive/proto/proto_fwd.hpp>
-#include <boost/xpressive/proto/detail/suffix.hpp>
-
-namespace boost { namespace proto { namespace transform
-{
-
- // Apply a function object, passing just Expr
- template<typename Grammar, typename Function1>
- struct function1
- : Grammar
- {
- function1() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : boost::result_of<
- Function1(
- typename Grammar::template apply<Expr, State, Visitor>::type
- )
- >
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Function1()(Grammar::call(expr, state, visitor));
- }
- };
-
- // Apply a function object, passing Expr and State
- template<typename Grammar, typename Function2>
- struct function2
- : Grammar
- {
- function2() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : boost::result_of<
- Function2(
- typename Grammar::template apply<Expr, State, Visitor>::type
- , State const &
- )
- >
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Function2()(Grammar::call(expr, state, visitor), state);
- }
- };
-
- // Apply a function object, passing Expr, State and Visitor
- template<typename Grammar, typename Function3>
- struct function3
- : Grammar
- {
- function3() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : boost::result_of<
- Function3(
- typename Grammar::template apply<Expr, State, Visitor>::type
- , State const &
- , Visitor &
- )
- >
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Function3()(Grammar::call(expr, state, visitor), state, visitor);
- }
- };
-
-}}}
-
-namespace boost { namespace proto
-{
- template<typename Grammar, typename Function1>
- struct is_transform<transform::function1<Grammar, Function1> >
- : mpl::true_
- {};
-
- template<typename Grammar, typename Function2>
- struct is_transform<transform::function2<Grammar, Function2> >
- : mpl::true_
- {};
-
- template<typename Grammar, typename Function3>
- struct is_transform<transform::function3<Grammar, Function3> >
- : mpl::true_
- {};
-}}
-
-#endif

Deleted: branches/release/boost/xpressive/proto/transform/list.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/list.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
+++ (empty file)
@@ -1,87 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-/// \file list.hpp
-/// A special-purpose proto transform for putting things into a
-/// fusion::cons<> list.
-//
-// Copyright 2007 Eric Niebler. 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)
-
-#ifndef BOOST_PROTO_TRANSFORM_LIST_HPP_EAN_12_16_2006
-#define BOOST_PROTO_TRANSFORM_LIST_HPP_EAN_12_16_2006
-
-#include <boost/xpressive/proto/detail/prefix.hpp>
-#include <boost/version.hpp>
-#if BOOST_VERSION < 103500
-# include <boost/spirit/fusion/sequence/cons.hpp>
-#else
-# include <boost/fusion/include/cons.hpp>
-#endif
-#include <boost/xpressive/proto/proto_fwd.hpp>
-#include <boost/xpressive/proto/detail/suffix.hpp>
-
-namespace boost { namespace proto { namespace transform
-{
-
- // A list transform, that puts elements into a fusion cons-list
- template<typename Grammar>
- struct list
- : Grammar
- {
- list() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef fusion::cons<
- typename Grammar::template apply<Expr, State, Visitor>::type
- , State
- > type;
- };
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return typename apply<Expr, State, Visitor>::type
- (Grammar::call(expr, state, visitor), state);
- }
- };
-
- // A tail transform, that returns the tail of a fusion cons-list
- template<typename Grammar>
- struct tail
- : Grammar
- {
- tail() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef typename Grammar::template apply<Expr, State, Visitor>::type::cdr_type type;
- };
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return Grammar::call(expr, state, visitor).cdr;
- }
- };
-
-}}}
-
-namespace boost { namespace proto
-{
- template<typename Grammar>
- struct is_transform<transform::list<Grammar> >
- : mpl::true_
- {};
-
- template<typename Grammar>
- struct is_transform<transform::tail<Grammar> >
- : mpl::true_
- {};
-}}
-
-#endif

Added: branches/release/boost/xpressive/proto/transform/make.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/transform/make.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,366 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file make.hpp
+ /// Contains definition of the make<> transform.
+ //
+ // Copyright 2008 Eric Niebler. 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)
+
+ #ifndef BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
+ #define BOOST_PROTO_TRANSFORM_MAKE_HPP_EAN_12_02_2007
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/detail/workaround.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/repetition/enum_binary_params.hpp>
+ #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+ #include <boost/preprocessor/repetition/repeat_from_to.hpp>
+ #include <boost/preprocessor/facilities/intercept.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/preprocessor/selection/max.hpp>
+ #include <boost/preprocessor/arithmetic/inc.hpp>
+ #include <boost/mpl/aux_/has_type.hpp>
+ #include <boost/mpl/aux_/template_arity.hpp>
+ #include <boost/mpl/aux_/lambda_arity_param.hpp>
+ #include <boost/utility/result_of.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/traits.hpp>
+ #include <boost/xpressive/proto/args.hpp>
+ #include <boost/xpressive/proto/detail/as_lvalue.hpp>
+ #include <boost/xpressive/proto/detail/ignore_unused.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto
+ {
+
+ namespace transform
+ {
+ namespace detail
+ {
+ using proto::detail::as_lvalue;
+
+ template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PROTO_MAX_ARITY, typename A, void)>
+ struct typelist
+ {
+ typedef void type;
+ };
+
+ template<typename T, bool HasType = mpl::aux::has_type<T>::value>
+ struct nested_type
+ {
+ typedef typename T::type type;
+ };
+
+ template<typename T>
+ struct nested_type<T, false>
+ {
+ typedef T type;
+ };
+
+ template<typename T, typename Args, typename Void = void>
+ struct nested_type_if
+ : nested_type<T>
+ {};
+
+ template<typename R, typename Expr, typename State, typename Visitor
+ , bool IsTransform = is_callable<R>::value
+ >
+ struct make_if_;
+
+ template<typename R, typename Expr, typename State, typename Visitor
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(long Arity = mpl::aux::template_arity<R>::value)
+ >
+ struct make_
+ {
+ typedef R type;
+ typedef void not_applied_;
+ };
+
+ template<typename R, typename Expr, typename State, typename Visitor>
+ struct make_if_<R, Expr, State, Visitor, false>
+ : make_<R, Expr, State, Visitor>
+ {};
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3)
+ // work around GCC bug
+ template<typename Tag, typename Args, long N, typename Expr, typename State, typename Visitor>
+ struct make_if_<proto::expr<Tag, Args, N>, Expr, State, Visitor, false>
+ {
+ typedef proto::expr<Tag, Args, N> type;
+ typedef void not_applied_;
+ };
+ #endif
+
+ template<typename R, typename Expr, typename State, typename Visitor>
+ struct make_if_<R, Expr, State, Visitor, true>
+ : boost::result_of<R(Expr, State, Visitor)>
+ {};
+
+ template<typename Type, bool IsAggregate = is_aggregate<Type>::value>
+ struct construct_
+ {
+ typedef Type result_type;
+
+ Type operator ()() const
+ {
+ return Type();
+ }
+
+ #define TMP(Z, N, DATA) \
+ template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
+ Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
+ { \
+ return Type(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
+ #undef TMP
+ };
+
+ template<typename Type>
+ struct construct_<Type, true>
+ {
+ typedef Type result_type;
+
+ Type operator ()() const
+ {
+ return Type();
+ }
+
+ #define TMP(Z, N, DATA) \
+ template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename A)> \
+ Type operator ()(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) const \
+ { \
+ Type that = {BOOST_PP_ENUM_PARAMS_Z(Z, N, a)}; \
+ return that; \
+ }
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_PROTO_MAX_ARITY), TMP, ~)
+ #undef TMP
+ };
+
+ #define TMP(Z, N, DATA) \
+ template<typename Type BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename A)> \
+ Type construct(BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, A, &a)) \
+ { \
+ return construct_<Type>()(BOOST_PP_ENUM_PARAMS_Z(Z, N, a)); \
+ }
+ BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, TMP, ~)
+ #undef TMP
+ }
+
+ /// \brief A PrimitiveTransform which computes a type by evaluating any
+ /// nested transforms and then constructs an object of that type.
+ ///
+ /// The <tt>make\<\></tt> transform checks to see if \c Object is a template.
+ /// If it is, the template type is disassembled to find nested transforms.
+ /// Proto considers the following types to represent transforms:
+ ///
+ /// \li Function types
+ /// \li Function pointer types
+ /// \li Types for which <tt>proto::is_callable\< type \>::::value</tt> is \c true
+ ///
+ /// <tt>make\<T\<X0,X1,...\> \>::::result\<void(Expr, State, Visitor)\>::::type</tt>
+ /// is evaluated as follows. For each \c X in <tt>X0,X1,...</tt>, do:
+ ///
+ /// \li If \c X is a template like <tt>U\<Y0,Y1,...\></tt>, then let <tt>X'</tt>
+ /// be <tt>make\<U\<Y0,Y1,...\> \>::::result\<void(Expr, State, Visitor)\>::::type</tt>
+ /// (which evaluates this procedure recursively). Note whether any
+ /// substitutions took place during this operation.
+ /// \li Otherwise, if \c X is a transform, then let <tt>X'</tt> be
+ /// <tt>when\<_, X\>::::result\<void(Expr, State, Visitor)\>::::type</tt>.
+ /// Note that a substitution took place.
+ /// \li Otherwise, let <tt>X'</tt> be \c X, and note that no substitution
+ /// took place.
+ /// \li If any substitutions took place in any of the above steps and
+ /// <tt>T\<X0',X1',...\></tt> has a nested <tt>::type</tt> typedef,
+ /// the result type is <tt>T\<X0',X1',...\>::::type</tt>.
+ /// \li Otherwise, the result type is <tt>T\<X0',X1',...\></tt>.
+ ///
+ /// Note that <tt>when\<\></tt> is implemented in terms of <tt>call\<\></tt>
+ /// and <tt>make\<\></tt>, so the above procedure is evaluated recursively.
+ template<typename Object>
+ struct make : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef typename detail::make_if_<Object, Expr, State, Visitor>::type type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::type()</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &, State const &, Visitor &) const
+ {
+ typedef typename result<void(Expr, State, Visitor)>::type result_type;
+ return result_type();
+ }
+ };
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/make.hpp>))
+ #include BOOST_PP_ITERATE()
+ }
+
+ /// INTERNAL ONLY
+ ///
+ template<typename Object>
+ struct is_callable<transform::make<Object> >
+ : mpl::true_
+ {};
+
+ }}
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ namespace detail
+ {
+ #if N > 0
+ template<typename T BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct nested_type_if<
+ T
+ , typelist<BOOST_PP_ENUM_PARAMS(N, A)>
+ , typename typelist<
+ BOOST_PP_ENUM_BINARY_PARAMS(N, typename A, ::not_applied_ BOOST_PP_INTERCEPT)
+ >::type
+ >
+ {
+ typedef T type;
+ typedef void not_applied_;
+ };
+
+ template<
+ template<BOOST_PP_ENUM_PARAMS(N, typename BOOST_PP_INTERCEPT)> class R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ , typename Expr, typename State, typename Visitor
+ >
+ struct make_<R<BOOST_PP_ENUM_PARAMS(N, A)>, Expr, State, Visitor
+ BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(N)
+ >
+ : nested_type_if<
+ #define TMP0(Z, M, DATA) make_if_<BOOST_PP_CAT(A, M), Expr, State, Visitor>
+ #define TMP1(Z, M, DATA) typename TMP0(Z, M, DATA) ::type
+ R<BOOST_PP_ENUM(N, TMP1, ~)>
+ , typelist<BOOST_PP_ENUM(N, TMP0, ~) >
+ #undef TMP0
+ #undef TMP1
+ >
+ {};
+ #endif
+
+ template<
+ typename R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ , typename Expr, typename State, typename Visitor
+ >
+ struct make_if_<R(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Visitor, false>
+ {
+ typedef typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ template<
+ typename R
+ BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)
+ , typename Expr, typename State, typename Visitor
+ >
+ struct make_if_<R(*)(BOOST_PP_ENUM_PARAMS(N, A)), Expr, State, Visitor, false>
+ {
+ typedef typename when<_, R(BOOST_PP_ENUM_PARAMS(N, A))>::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ template<typename T, typename A>
+ struct construct_<proto::expr<T, A, N>, true>
+ {
+ typedef proto::expr<T, A, N> result_type;
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), typename A)>
+ result_type operator ()(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_MAX(N, 1), A, &a)) const
+ {
+ return result_type::make(BOOST_PP_ENUM_PARAMS(BOOST_PP_MAX(N, 1), a));
+ }
+ };
+ }
+
+ /// \brief A PrimitiveTransform which computes a type by evaluating any
+ /// nested transforms and then constructs an object of that type with the
+ /// current expression, state and visitor, transformed according
+ /// to \c A0 through \c AN.
+ template<typename Object BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make<Object(BOOST_PP_ENUM_PARAMS(N, A))> : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ /// \brief <tt>make\<Object\>::::result\<void(Expr, State, Visitor)\>::::type</tt>
+ typedef typename detail::make_if_<Object, Expr, State, Visitor>::type type;
+ };
+
+ /// Let \c ax be <tt>when\<_, Ax\>()(expr, state, visitor)</tt>
+ /// for each \c x in <tt>[0,N]</tt>.
+ /// Let \c T be <tt>result\<void(Expr, State, Visitor)\>::::type</tt>.
+ /// Return <tt>T(a0, a1,... aN)</tt>.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ typedef typename result<void(Expr, State, Visitor)>::type result_type;
+ proto::detail::ignore_unused(expr);
+ proto::detail::ignore_unused(state);
+ proto::detail::ignore_unused(visitor);
+ return detail::construct<result_type>(
+ #define TMP(Z, M, DATA) detail::as_lvalue(when<_, BOOST_PP_CAT(A, M)>()(expr, state, visitor))
+ BOOST_PP_ENUM(N, TMP, DATA)
+ #undef TMP
+ );
+ }
+ };
+
+ #if BOOST_WORKAROUND(__GNUC__, == 3)
+ // work around GCC bug
+ template<typename Tag, typename Args, long Arity BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct make<proto::expr<Tag, Args, Arity>(BOOST_PP_ENUM_PARAMS(N, A))>
+ : proto::callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef proto::expr<Tag, Args, Arity> type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ proto::expr<Tag, Args, Arity> operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return proto::expr<Tag, Args, Arity>::make(
+ #define TMP(Z, M, DATA) detail::as_lvalue(when<_, BOOST_PP_CAT(A, M)>()(expr, state, visitor))
+ BOOST_PP_ENUM(N, TMP, DATA)
+ #undef TMP
+ );
+ }
+ };
+ #endif
+
+ #undef N
+
+#endif

Modified: branches/release/boost/xpressive/proto/transform/pass_through.hpp
==============================================================================
--- branches/release/boost/xpressive/proto/transform/pass_through.hpp (original)
+++ branches/release/boost/xpressive/proto/transform/pass_through.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,9 +1,12 @@
 #ifndef BOOST_PP_IS_ITERATING
     ///////////////////////////////////////////////////////////////////////////////
     /// \file pass_through.hpp
- /// TODO
+ ///
+ /// Definition of the pass_through transform, which is the default transform
+ /// of all of the expression generator metafunctions such as posit<>, plus<>
+ /// and nary_expr<>.
     //
- // Copyright 2007 Eric Niebler. Distributed under the Boost
+ // Copyright 2008 Eric Niebler. 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)
 
@@ -12,9 +15,9 @@
 
     #include <boost/xpressive/proto/detail/prefix.hpp>
     #include <boost/preprocessor/cat.hpp>
- #include <boost/preprocessor/enum.hpp>
- #include <boost/preprocessor/iterate.hpp>
- #include <boost/mpl/if.hpp>
+ #include <boost/preprocessor/repetition/enum.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/mpl/bool.hpp>
     #include <boost/xpressive/proto/proto_fwd.hpp>
     #include <boost/xpressive/proto/args.hpp>
     #include <boost/xpressive/proto/detail/suffix.hpp>
@@ -23,17 +26,26 @@
     {
         namespace detail
         {
- template<typename Grammar, typename Expr, typename State, typename Visitor, long Arity = Expr::proto_arity::value>
- struct pass_through_impl {};
+ template<
+ typename Grammar
+ , typename Expr
+ , typename State
+ , typename Visitor
+ , long Arity = Expr::proto_arity::value
+ >
+ struct pass_through_impl
+ {};
 
- #define BOOST_PROTO_DEFINE_TRANSFORM_TYPE(z, n, data)\
- typename Grammar::BOOST_PP_CAT(proto_arg, n)\
- ::template apply<typename Expr::BOOST_PP_CAT(proto_arg, n)::proto_base_expr, State, Visitor>\
- ::type
-
- #define BOOST_PROTO_DEFINE_TRANSFORM(z, n, data)\
- Grammar::BOOST_PP_CAT(proto_arg, n)::call(\
- expr.BOOST_PP_CAT(arg, n).proto_base(), state, visitor\
+ #define BOOST_PROTO_DEFINE_TRANSFORM_TYPE(z, n, data) \
+ typename Grammar::BOOST_PP_CAT(proto_arg, n)::template result<void( \
+ typename Expr::BOOST_PP_CAT(proto_arg, n)::proto_base_expr \
+ , State \
+ , Visitor \
+ )>::type
+
+ #define BOOST_PROTO_DEFINE_TRANSFORM(z, n, data) \
+ typename Grammar::BOOST_PP_CAT(proto_arg, n)()( \
+ expr.BOOST_PP_CAT(arg, n).proto_base(), state, visitor \
                 )
 
             #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/pass_through.hpp>))
@@ -52,67 +64,104 @@
                     return expr;
                 }
             };
+
         } // namespace detail
 
+ /// \brief A PrimitiveTransform that transforms the children expressions
+ /// of an expression node according to the corresponding children of
+ /// a Grammar.
+ ///
+ /// Given a Grammar such as <tt>plus\<T0, T1\></tt>, an expression type
+ /// that matches the grammar such as <tt>plus\<E0, E1\>::::type</tt>, a
+ /// state \c S and a visitor \c V, the result of applying the
+ /// <tt>pass_through\<plus\<T0, T1\> \></tt> transform is:
+ ///
+ /// \code
+ /// plus<
+ /// T0::result<void(E0, S, V)>::type
+ /// , T1::result<void(E1, S, V)>::type
+ /// >::type
+ /// \endcode
+ ///
+ /// The above demonstrates how children transforms and children expressions
+ /// are applied pairwise, and how the results are reassembled into a new
+ /// expression node with the same tag type as the original.
+ ///
+ /// The explicit use of <tt>pass_through\<\></tt> is not usually needed,
+ /// since the expression generator metafunctions such as
+ /// <tt>plus\<\></tt> have <tt>pass_through\<\></tt> as their default
+ /// transform. So, for instance, these are equivalent:
+ ///
+ /// \code
+ /// // Within a grammar definition, these are equivalent:
+ /// when< plus<X, Y>, pass_through< plus<X, Y> > >
+ /// when< plus<X, Y>, plus<X, Y> >
+ /// when< plus<X, Y> > // because of when<class X, class Y=X>
+ /// plus<X, Y> // because plus<> is both a
+ /// // grammar and a transform
+ /// \endcode
+ ///
+ /// For example, consider the following transform that promotes all
+ /// \c float terminals in an expression to \c double.
+ ///
+ /// \code
+ /// // This transform finds all float terminals in an expression and promotes
+ /// // them to doubles.
+ /// struct Promote
+ /// : or_<
+ /// when<terminal<float>, terminal<double>::type(_arg) >
+ /// // terminal<>'s default transform is a no-op:
+ /// , terminal<_>
+ /// // nary_expr<> has a pass_through<> transform:
+ /// , nary_expr<_, vararg<Promote> >
+ /// >
+ /// {};
+ /// \endcode
         template<typename Grammar>
         struct pass_through
- : Grammar
+ : proto::callable
         {
- pass_through() {}
+ template<typename Sig>
+ struct result;
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : detail::pass_through_impl<
- Grammar
- , typename Expr::proto_base_expr
- , State
- , Visitor
- , Expr::proto_arity::value
- >
- {};
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ transform::detail::pass_through_impl<
+ Grammar
+ , typename Expr::proto_base_expr
+ , State
+ , Visitor
+ , Expr::proto_arity::value
+ >
+ impl;
 
+ typedef typename impl::type type;
+ };
+
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, Grammar\>::::value</tt> is \c true.
             template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
             {
- return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
+ return result<void(Expr, State, Visitor)>::impl
+ ::call(expr.proto_base(), state, visitor);
             }
         };
+
     } // namespace transform
 
+ /// INTERNAL ONLY
+ ///
     template<typename Grammar>
- struct is_transform<transform::pass_through<Grammar> >
+ struct is_callable<transform::pass_through<Grammar> >
       : mpl::true_
     {};
 
- namespace has_transformns_
- {
- template<typename Grammar>
- struct has_pass_through_transform
- {
- has_pass_through_transform() {}
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : transform::detail::pass_through_impl<
- Grammar
- , typename Expr::proto_base_expr
- , State
- , Visitor
- , Expr::proto_arity::value
- >
- {};
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return apply<Expr, State, Visitor>::call(expr.proto_base(), state, visitor);
- }
- };
-
- } // namespace has_transformns_
-
     }} // namespace boost::proto
 
     #endif
@@ -124,7 +173,7 @@
             template<typename Grammar, typename Expr, typename State, typename Visitor>
             struct pass_through_impl<Grammar, Expr, State, Visitor, N>
             {
- typedef expr<
+ typedef proto::expr<
                     typename Expr::proto_tag
                   , BOOST_PP_CAT(args, N)<
                         BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_TRANSFORM_TYPE, ~)

Added: branches/release/boost/xpressive/proto/transform/when.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/xpressive/proto/transform/when.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,189 @@
+#ifndef BOOST_PP_IS_ITERATING
+ ///////////////////////////////////////////////////////////////////////////////
+ /// \file when.hpp
+ /// Definition of when transform.
+ //
+ // Copyright 2008 Eric Niebler. 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)
+
+ #ifndef BOOST_PROTO_TRANSFORM_WHEN_HPP_EAN_10_29_2007
+ #define BOOST_PROTO_TRANSFORM_WHEN_HPP_EAN_10_29_2007
+
+ #include <boost/xpressive/proto/detail/prefix.hpp>
+ #include <boost/preprocessor/cat.hpp>
+ #include <boost/preprocessor/repetition/enum_params.hpp>
+ #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/preprocessor/iteration/iterate.hpp>
+ #include <boost/mpl/if.hpp>
+ #include <boost/xpressive/proto/proto_fwd.hpp>
+ #include <boost/xpressive/proto/traits.hpp>
+ #include <boost/xpressive/proto/transform/call.hpp>
+ #include <boost/xpressive/proto/transform/make.hpp>
+ #include <boost/xpressive/proto/detail/suffix.hpp>
+
+ namespace boost { namespace proto { namespace transform
+ {
+ /// \brief A grammar element and a PrimitiveTransform that associates
+ /// a transform with the grammar.
+ ///
+ /// Use <tt>when\<\></tt> to override a grammar's default transform
+ /// with a custom transform. It is for used when composing larger
+ /// transforms by associating smaller transforms with individual
+ /// rules in your grammar, as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// In <tt>when\<G, T\></tt>, when \c T is a class type it is a
+ /// PrimitiveTransform and the following equivalencies hold:
+ ///
+ /// <tt>when\<G,T\>::::result\<void(E,S,V)\>::::type</tt> is the same as
+ /// <tt>T::result\<void(E,S,V)\>::::type</tt>.
+ ///
+ /// <tt>when\<G,T\>()(e,s,v)</tt> is the same as
+ /// <tt>T()(e,s,v)</tt>.
+ template<typename Grammar, typename PrimitiveTransform BOOST_PROTO_FOR_DOXYGEN_ONLY(= Grammar)>
+ struct when
+ : PrimitiveTransform
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+ };
+
+ /// \brief A specialization that treats function pointer Transforms as
+ /// if they were function type Transforms.
+ ///
+ /// This specialization requires that \c Fun is actually a function type.
+ ///
+ /// This specialization is required for nested transforms such as
+ /// <tt>when\<G, T0(T1(_))\></tt>. In C++, functions that are used as
+ /// parameters to other functions automatically decay to funtion
+ /// pointer types. In other words, the type <tt>T0(T1(_))</tt> is
+ /// indistinguishable from <tt>T0(T1(*)(_))</tt>. This specialization
+ /// is required to handle these nested function pointer type transforms
+ /// properly.
+ template<typename Grammar, typename Fun>
+ struct when<Grammar, Fun *>
+ : when<Grammar, Fun>
+ {};
+
+ /// \brief Syntactic sugar for <tt>when\<_, Fun\></tt>, for use
+ /// in grammars to handle all the cases not yet handled.
+ ///
+ /// Use <tt>otherwise\<T\></tt> in your grammars as a synonym for
+ /// <tt>when\<_, T\></tt> as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ template<typename Fun>
+ struct otherwise
+ : when<_, Fun>
+ {};
+
+ #define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PROTO_MAX_ARITY, <boost/xpressive/proto/transform/when.hpp>))
+ #include BOOST_PP_ITERATE()
+
+ }}} // namespace boost::proto::transform
+
+ #endif
+
+#else
+
+ #define N BOOST_PP_ITERATION()
+
+ /// \brief A grammar element and a PrimitiveTransform that associates
+ /// a transform with the grammar.
+ ///
+ /// Use <tt>when\<\></tt> to override a grammar's default transform
+ /// with a custom transform. It is for used when composing larger
+ /// transforms by associating smaller transforms with individual
+ /// rules in your grammar, as in the following transform which
+ /// counts the number of terminals in an expression.
+ ///
+ /// \code
+ /// // Count the terminals in an expression tree.
+ /// // Must be invoked with initial state == mpl::int_<0>().
+ /// struct CountLeaves
+ /// : or_<
+ /// when<terminal<_>, mpl::next<_state>()>
+ /// , otherwise<fold<_, _state, CountLeaves> >
+ /// >
+ /// {};
+ /// \endcode
+ ///
+ /// The <tt>when\<G, R(A0,A1,...)\></tt> form accepts either a
+ /// CallableTransform or an ObjectTransform as its second parameter.
+ /// <tt>when\<\></tt> uses <tt>is_callable\<R\>::::value</tt> to
+ /// distinguish between the two, and uses <tt>call\<\></tt> to
+ /// evaluate CallableTransforms and <tt>make\<\></tt> to evaluate
+ /// ObjectTransforms.
+ template<typename Grammar, typename R BOOST_PP_ENUM_TRAILING_PARAMS(N, typename A)>
+ struct when<Grammar, R(BOOST_PP_ENUM_PARAMS(N, A))>
+ : proto::callable
+ {
+ typedef typename Grammar::proto_base_expr proto_base_expr;
+
+ // Note: do not evaluate is_callable<R> in this scope.
+ // R may be an incomplete type at this point.
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef call<R(BOOST_PP_ENUM_PARAMS(N, A))> call_;
+ typedef make<R(BOOST_PP_ENUM_PARAMS(N, A))> make_;
+
+ typedef
+ typename mpl::if_c<
+ // OK to evaluate is_callable<R> here.
+ // R should be compete by now.
+ is_callable<R>::value
+ , call_ // "R" is a function to call
+ , make_ // "R" is an object to construct
+ >::type
+ impl;
+
+ typedef typename impl::template result<void(Expr, State, Visitor)>::type type;
+ };
+
+ /// Evaluate <tt>R(A0,A1,...)</tt> as a transform either with
+ /// <tt>call\<\></tt> or with <tt>make\<\></tt> depending on
+ /// whether <tt>is_callable\<R\>::::value</tt> is \c true or
+ /// \c false.
+ ///
+ /// \param expr The current expression
+ /// \param state The current state
+ /// \param visitor An arbitrary visitor
+ /// \pre <tt>matches\<Expr, Grammar\>::::value</tt> is \c true
+ /// \return <tt>result\<void(Expr, State, Visitor)\>::::impl()(expr, state, visitor)</tt>
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return typename result<void(Expr, State, Visitor)>::impl()(expr, state, visitor);
+ }
+ };
+
+ #undef N
+
+#endif

Modified: branches/release/boost/xpressive/regex_actions.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_actions.hpp (original)
+++ branches/release/boost/xpressive/regex_actions.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file regex_actions.hpp
 /// Defines the syntax elements of xpressive's action expressions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -14,6 +14,7 @@
 # pragma once
 #endif
 
+#include <boost/config.hpp>
 #include <boost/ref.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/or.hpp>
@@ -40,7 +41,7 @@
 
 // Doxygen can't handle proto :-(
 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-# include <boost/xpressive/proto/transform/fold.hpp>
+# include <boost/xpressive/proto/transform.hpp>
 # include <boost/xpressive/detail/core/matcher/action_matcher.hpp>
 #endif
 
@@ -52,6 +53,13 @@
 ///
 #define UNCVREF(x) typename remove_cv<typename remove_reference<x>::type>::type
 
+#if BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable : 4510) // default constructor could not be generated
+#pragma warning(disable : 4512) // assignment operator could not be generated
+#pragma warning(disable : 4610) // can never be instantiated - user defined constructor required
+#endif
+
 namespace boost { namespace xpressive
 {
 
@@ -86,21 +94,15 @@
         struct check_tag
         {};
 
- template<typename Grammar>
- struct BindArg
- : Grammar
+ struct BindArg : proto::callable
         {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef State type;
- };
+ typedef int result_type;
 
- template<typename Expr, typename State, typename Visitor>
- static State call(Expr const &expr, State const &state, Visitor &visitor)
+ template<typename Visitor, typename Expr>
+ int operator ()(Visitor &visitor, Expr const &expr) const
             {
                 visitor.let(expr);
- return state;
+ return 0;
             }
         };
 
@@ -108,10 +110,15 @@
         {};
 
         struct BindArgs
- : boost::proto::transform::fold<
- boost::proto::function<
- boost::proto::transform::state<boost::proto::terminal<let_tag> >
- , boost::proto::vararg< BindArg< boost::proto::assign<boost::proto::_, boost::proto::_> > >
+ : proto::when<
+ // let(_a = b, _c = d)
+ proto::function<
+ proto::terminal<let_tag>
+ , proto::vararg<proto::assign<proto::_, proto::_> >
+ >
+ , proto::function<
+ proto::_state // no-op
+ , proto::vararg<proto::call<BindArg(proto::_visitor, proto::_)> >
>
>
         {};
@@ -130,8 +137,56 @@
         template<typename Args, typename BidiIter>
         void bind_args(let_<Args> const &args, match_results<BidiIter> &what)
         {
- BindArgs::call(args, 0, what);
+ BindArgs()(args, 0, what);
         }
+
+ template<typename BidiIter>
+ struct replacement_context
+ : proto::callable_context<replacement_context<BidiIter> const>
+ {
+ replacement_context(match_results<BidiIter> const &what)
+ : what_(what)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This>
+ struct result<This(proto::tag::terminal, mark_placeholder const &)>
+ {
+ typedef sub_match<BidiIter> const &type;
+ };
+
+ template<typename This>
+ struct result<This(proto::tag::terminal, any_matcher const &)>
+ {
+ typedef sub_match<BidiIter> const &type;
+ };
+
+ template<typename This, typename T>
+ struct result<This(proto::tag::terminal, reference_wrapper<T> const &)>
+ {
+ typedef T &type;
+ };
+
+ sub_match<BidiIter> const &operator ()(proto::tag::terminal, mark_placeholder m) const
+ {
+ return this->what_[m.mark_number_];
+ }
+
+ sub_match<BidiIter> const &operator ()(proto::tag::terminal, any_matcher) const
+ {
+ return this->what_[0];
+ }
+
+ template<typename T>
+ T &operator ()(proto::tag::terminal, reference_wrapper<T> r) const
+ {
+ return r;
+ }
+ private:
+ match_results<BidiIter> const &what_;
+ };
     }
 
     namespace op
@@ -819,4 +874,8 @@
 #undef UNREF
 #undef UNCVREF
 
+#if BOOST_MSVC
+#pragma warning(pop)
+#endif
+
 #endif // BOOST_XPRESSIVE_ACTIONS_HPP_EAN_03_22_2007

Modified: branches/release/boost/xpressive/regex_algorithms.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_algorithms.hpp (original)
+++ branches/release/boost/xpressive/regex_algorithms.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file regex_algorithms.hpp
 /// Contains the regex_match(), regex_search() and regex_replace() algorithms.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -14,13 +14,17 @@
 # pragma once
 #endif
 
+#include <string>
 #include <iterator>
+#include <boost/mpl/or.hpp>
 #include <boost/range/end.hpp>
 #include <boost/range/begin.hpp>
 #include <boost/mpl/identity.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/add_const.hpp>
 #include <boost/type_traits/is_pointer.hpp>
 #include <boost/type_traits/remove_const.hpp>
+#include <boost/xpressive/match_results.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/state.hpp>
 #include <boost/xpressive/detail/utility/save_restore.hpp>
@@ -38,24 +42,24 @@
 
 /// \brief See if a regex matches a sequence from beginning to end.
 ///
-/// Determines whether there is an exact match between the regular expression re,
-/// and all of the sequence [begin, end).
+/// Determines whether there is an exact match between the regular expression \c re,
+/// and all of the sequence <tt>[begin, end)</tt>.
 ///
-/// \pre Types BidiIter and OtherBidiIter meet the requirements of a Bidirectional Iterator (24.1.4).
-/// \pre OtherBidiIter is convertible to BidiIter.
-/// \pre [begin,end) denotes a valid iterator range.
+/// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
+/// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
 /// \param begin The beginning of the sequence.
 /// \param end The end of the sequence.
-/// \param what The match_results struct into which the sub_matches will be written
+/// \param what The \c match_results struct into which the sub_matches will be written
 /// \param re The regular expression object to use
-/// \param flags Optional match flags, used to control how the expression is matched against the sequence. (See match_flag_type.)
-/// \return true if a match is found, false otherwise
-/// \throw regex_error on stack exhaustion
-template<typename OtherBidiIter, typename BidiIter>
+/// \param flags Optional match flags, used to control how the expression is matched
+/// against the sequence. (See \c match_flag_type.)
+/// \return \c true if a match is found, \c false otherwise
+/// \throw \c regex_error on stack exhaustion
+template<typename BidiIter>
 inline bool regex_match
 (
- OtherBidiIter begin
- , OtherBidiIter end
+ BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
   , match_results<BidiIter> &what
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
@@ -92,18 +96,18 @@
 
 /// \overload
 ///
-template<typename OtherBidiIter, typename BidiIter>
+template<typename BidiIter>
 inline bool regex_match
 (
- OtherBidiIter begin
- , OtherBidiIter end
+ BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return regex_match(begin, end, what, re, flags);
+ return xpressive::regex_match(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -120,7 +124,7 @@
     // BUGBUG this is inefficient
     typedef typename remove_const<Char>::type char_type;
     Char *end = begin + std::char_traits<char_type>::length(begin);
- return regex_match(begin, end, what, re, flags);
+ return xpressive::regex_match(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -132,13 +136,13 @@
   , match_results<BidiIter> &what
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return regex_match(begin, end, what, re, flags);
+ return xpressive::regex_match(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -150,13 +154,13 @@
   , match_results<BidiIter> &what
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return regex_match(begin, end, what, re, flags);
+ return xpressive::regex_match(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -171,7 +175,7 @@
 {
     // BUGBUG this is inefficient
     match_results<Char *> what;
- return regex_match(begin, what, re, flags);
+ return xpressive::regex_match(begin, what, re, flags);
 }
 
 /// \overload
@@ -182,12 +186,12 @@
     BidiRange &rng
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return regex_match(rng, what, re, flags);
+ return xpressive::regex_match(rng, what, re, flags);
 }
 
 /// \overload
@@ -198,12 +202,12 @@
     BidiRange const &rng
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return regex_match(rng, what, re, flags);
+ return xpressive::regex_match(rng, what, re, flags);
 }
 
 
@@ -326,25 +330,27 @@
 } // namespace detail
 
 
-/// \brief Determines whether there is some sub-sequence within [begin,end) that matches the regular expression re.
+/// \brief Determines whether there is some sub-sequence within <tt>[begin,end)</tt>
+/// that matches the regular expression \c re.
 ///
-/// Determines whether there is some sub-sequence within [begin,end) that matches the regular expression re.
+/// Determines whether there is some sub-sequence within <tt>[begin,end)</tt> that matches
+/// the regular expression \c re.
 ///
-/// \pre Types BidiIter and OtherBidiIter meet the requirements of a Bidirectional Iterator (24.1.4).
-/// \pre OtherBidiIter is convertible to BidiIter.
-/// \pre [begin,end) denotes a valid iterator range.
+/// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
+/// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
 /// \param begin The beginning of the sequence
 /// \param end The end of the sequence
-/// \param what The match_results struct into which the sub_matches will be written
+/// \param what The \c match_results struct into which the sub_matches will be written
 /// \param re The regular expression object to use
-/// \param flags Optional match flags, used to control how the expression is matched against the sequence. (See match_flag_type.)
-/// \return true if a match is found, false otherwise
-/// \throw regex_error on stack exhaustion
-template<typename OtherBidiIter, typename BidiIter>
+/// \param flags Optional match flags, used to control how the expression is matched against
+/// the sequence. (See \c match_flag_type.)
+/// \return \c true if a match is found, \c false otherwise
+/// \throw \c regex_error on stack exhaustion
+template<typename BidiIter>
 inline bool regex_search
 (
- OtherBidiIter begin
- , OtherBidiIter end
+ BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
   , match_results<BidiIter> &what
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
@@ -367,18 +373,18 @@
 
 /// \overload
 ///
-template<typename OtherBidiIter, typename BidiIter>
+template<typename BidiIter>
 inline bool regex_search
 (
- OtherBidiIter begin
- , OtherBidiIter end
+ BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return regex_search(begin, end, what, re, flags);
+ return xpressive::regex_search(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -395,7 +401,7 @@
     // BUGBUG this is inefficient
     typedef typename remove_const<Char>::type char_type;
     Char *end = begin + std::char_traits<char_type>::length(begin);
- return regex_search(begin, end, what, re, flags);
+ return xpressive::regex_search(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -407,13 +413,13 @@
   , match_results<BidiIter> &what
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return regex_search(begin, end, what, re, flags);
+ return xpressive::regex_search(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -425,13 +431,13 @@
   , match_results<BidiIter> &what
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // Note that the result iterator of the range must be convertible
     // to BidiIter here.
     BidiIter begin = boost::begin(rng), end = boost::end(rng);
- return regex_search(begin, end, what, re, flags);
+ return xpressive::regex_search(begin, end, what, re, flags);
 }
 
 /// \overload
@@ -446,7 +452,7 @@
 {
     // BUGBUG this is inefficient
     match_results<Char *> what;
- return regex_search(begin, what, re, flags);
+ return xpressive::regex_search(begin, what, re, flags);
 }
 
 /// \overload
@@ -457,12 +463,12 @@
     BidiRange &rng
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return regex_search(rng, what, re, flags);
+ return xpressive::regex_search(rng, what, re, flags);
 }
 
 /// \overload
@@ -473,12 +479,12 @@
     BidiRange const &rng
   , basic_regex<BidiIter> const &re
   , regex_constants::match_flag_type flags = regex_constants::match_default
- , typename disable_if<is_pointer<BidiRange> >::type * = 0
+ , typename disable_if<detail::is_char_ptr<BidiRange> >::type * = 0
 )
 {
     // BUGBUG this is inefficient
     match_results<BidiIter> what;
- return regex_search(rng, what, re, flags);
+ return xpressive::regex_search(rng, what, re, flags);
 }
 
 
@@ -486,39 +492,18 @@
 // regex_replace
 ///////////////////////////////////////////////////////////////////////////////
 
-
-/// \brief Build an output sequence given an input sequence, a regex, and a format string.
-///
-/// Constructs a regex_iterator object: regex_iterator\< BidiIter \> i(begin, end, re, flags),
-/// and uses i to enumerate through all of the matches m of type match_results\< BidiIter \> that
-/// occur within the sequence [begin, end). If no such matches are found and !(flags \& format_no_copy)
-/// then calls std::copy(begin, end, out). Otherwise, for each match found, if !(flags \& format_no_copy)
-/// calls std::copy(m.prefix().first, m.prefix().second, out), and then calls m.format(out, fmt, flags).
-/// Finally if !(flags \& format_no_copy) calls std::copy(last_m.suffix().first, last_m.suffix().second, out)
-/// where last_m is a copy of the last match found. If flags \& format_first_only is non-zero then only
-/// the first match found is replaced.
-///
-/// \pre Types BidiIter and OtherBidiIter meet the requirements of a Bidirectional Iterator (24.1.4).
-/// \pre Type OutIter meets the requirements of an Output Iterator (24.1.2).
-/// \pre OtherBidiIter is convertible to BidiIter.
-/// \pre [begin,end) denotes a valid iterator range.
-///
-/// \param out An output iterator into which the output sequence is written.
-/// \param begin The beginning of the input sequence.
-/// \param end The end of the input sequence.
-/// \param re The regular expression object to use.
-/// \param fmt The format string used to format the replacement sequence.
-/// \param flags Optional match flags, used to control how the expression is matched against the sequence. (See match_flag_type.)
-/// \return The value of the output iterator after the output sequence has been written to it.
-/// \throw regex_error on stack exhaustion or invalid format string.
-template<typename OutIter, typename OtherBidiIter, typename BidiIter>
-inline OutIter regex_replace
+namespace detail
+{
+///////////////////////////////////////////////////////////////////////////////
+// regex_replace_impl
+template<typename OutIter, typename BidiIter, typename Formatter>
+inline OutIter regex_replace_impl
 (
     OutIter out
- , OtherBidiIter begin
- , OtherBidiIter end
+ , BidiIter begin
+ , BidiIter end
   , basic_regex<BidiIter> const &re
- , std::basic_string<typename iterator_value<BidiIter>::type> const &fmt
+ , Formatter const &format
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
@@ -537,8 +522,8 @@
             out = std::copy(cur, what[0].first, out);
         }
 
- out = what.format(out, fmt, flags);
- cur = state.cur_ = what[0].second;
+ out = what.format(out, format, flags);
+ cur = state.cur_ = state.next_search_ = what[0].second;
 
         if(0 == (flags & format_first_only))
         {
@@ -552,8 +537,8 @@
                 }
 
                 access::set_prefix_suffix(what, begin, end);
- out = what.format(out, fmt, flags);
- cur = state.cur_ = what[0].second;
+ out = what.format(out, format, flags);
+ cur = state.cur_ = state.next_search_ = what[0].second;
                 not_null = (0 == what.length());
                 state.reset(what, *access::get_regex_impl(re));
             }
@@ -562,26 +547,189 @@
 
     if(yes_copy)
     {
- out = std::copy(cur, static_cast<BidiIter>(end), out);
+ out = std::copy(cur, end, out);
     }
 
     return out;
 }
+} // namespace detail
+
+/// \brief Build an output sequence given an input sequence, a regex, and a format string or
+/// a formatter object, function, or expression.
+///
+/// Constructs a \c regex_iterator object: <tt>regex_iterator\< BidiIter \> i(begin, end, re, flags)</tt>,
+/// and uses \c i to enumerate through all of the matches m of type <tt>match_results\< BidiIter \></tt> that
+/// occur within the sequence <tt>[begin, end)</tt>. If no such matches are found and <tt>!(flags \& format_no_copy)</tt>
+/// then calls <tt>std::copy(begin, end, out)</tt>. Otherwise, for each match found, if <tt>!(flags \& format_no_copy)</tt>
+/// calls <tt>std::copy(m.prefix().first, m.prefix().second, out)</tt>, and then calls <tt>m.format(out, format, flags)</tt>.
+/// Finally if <tt>!(flags \& format_no_copy)</tt> calls <tt>std::copy(last_m.suffix().first, last_m.suffix().second, out)</tt>
+/// where \c last_m is a copy of the last match found.
+///
+/// If <tt>flags \& format_first_only</tt> is non-zero then only the first match found is replaced.
+///
+/// \pre Type \c BidiIter meets the requirements of a Bidirectional Iterator (24.1.4).
+/// \pre Type \c OutIter meets the requirements of an Output Iterator (24.1.2).
+/// \pre Type \c Formatter models \c ForwardRange, <tt>Callable\<match_results\<BidiIter\> \></tt>,
+/// <tt>Callable\<match_results\<BidiIter\>, OutIter\></tt>, or
+/// <tt>Callable\<match_results\<BidiIter\>, OutIter, regex_constants::match_flag_type\></tt>;
+/// or else it is a null-terminated format string, or an expression template
+/// representing a formatter lambda expression.
+/// \pre <tt>[begin,end)</tt> denotes a valid iterator range.
+/// \param out An output iterator into which the output sequence is written.
+/// \param begin The beginning of the input sequence.
+/// \param end The end of the input sequence.
+/// \param re The regular expression object to use.
+/// \param format The format string used to format the replacement sequence,
+/// or a formatter function, function object, or expression.
+/// \param flags Optional match flags, used to control how the expression is matched against
+/// the sequence. (See \c match_flag_type.)
+/// \return The value of the output iterator after the output sequence has been written to it.
+/// \throw \c regex_error on stack exhaustion or invalid format string.
+template<typename OutIter, typename BidiIter, typename Formatter>
+inline OutIter regex_replace
+(
+ OutIter out
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
+ , basic_regex<BidiIter> const &re
+ , Formatter const &format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
+)
+{
+ return detail::regex_replace_impl(out, begin, end, re, format, flags);
+}
+
+/// \overload
+///
+template<typename OutIter, typename BidiIter>
+inline OutIter regex_replace
+(
+ OutIter out
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) begin
+ , BOOST_XPR_NONDEDUCED_TYPE_(BidiIter) end
+ , basic_regex<BidiIter> const &re
+ , typename iterator_value<BidiIter>::type const *format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+)
+{
+ return detail::regex_replace_impl(out, begin, end, re, format, flags);
+}
+
+/// \overload
+///
+template<typename BidiContainer, typename BidiIter, typename Formatter>
+inline BidiContainer regex_replace
+(
+ BidiContainer &str
+ , basic_regex<BidiIter> const &re
+ , Formatter const &format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
+)
+{
+ BidiContainer result;
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(str), end = boost::end(str);
+ xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+ return result;
+}
+
+/// \overload
+///
+template<typename BidiContainer, typename BidiIter, typename Formatter>
+inline BidiContainer regex_replace
+(
+ BidiContainer const &str
+ , basic_regex<BidiIter> const &re
+ , Formatter const &format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ , typename disable_if<mpl::or_<detail::is_char_ptr<BidiContainer>, detail::is_char_ptr<Formatter> > >::type * = 0
+)
+{
+ BidiContainer result;
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(str), end = boost::end(str);
+ xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+ return result;
+}
+
+/// \overload
+///
+template<typename Char, typename Formatter>
+inline std::basic_string<typename remove_const<Char>::type> regex_replace
+(
+ BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
+ , basic_regex<Char *> const &re
+ , Formatter const &format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ , typename disable_if<detail::is_char_ptr<Formatter> >::type * = 0
+)
+{
+ typedef typename remove_const<Char>::type char_type;
+ std::basic_string<char_type> result;
+ Char *end = str + std::char_traits<char_type>::length(str);
+ xpressive::regex_replace(std::back_inserter(result), str, end, re, format, flags);
+ return result;
+}
+
+/// \overload
+///
+template<typename BidiContainer, typename BidiIter>
+inline BidiContainer regex_replace
+(
+ BidiContainer &str
+ , basic_regex<BidiIter> const &re
+ , typename iterator_value<BidiIter>::type const *format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
+)
+{
+ BidiContainer result;
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(str), end = boost::end(str);
+ xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+ return result;
+}
+
+/// \overload
+///
+template<typename BidiContainer, typename BidiIter>
+inline BidiContainer regex_replace
+(
+ BidiContainer const &str
+ , basic_regex<BidiIter> const &re
+ , typename iterator_value<BidiIter>::type const *format
+ , regex_constants::match_flag_type flags = regex_constants::match_default
+ , typename disable_if<detail::is_char_ptr<BidiContainer> >::type * = 0
+)
+{
+ BidiContainer result;
+ // Note that the result iterator of the range must be convertible
+ // to BidiIter here.
+ BidiIter begin = boost::begin(str), end = boost::end(str);
+ xpressive::regex_replace(std::back_inserter(result), begin, end, re, format, flags);
+ return result;
+}
 
 /// \overload
 ///
 template<typename Char>
-inline std::basic_string<Char> regex_replace
+inline std::basic_string<typename remove_const<Char>::type> regex_replace
 (
- std::basic_string<Char> const &str
- , basic_regex<typename std::basic_string<Char>::const_iterator> const &re
- , std::basic_string<BOOST_XPR_NONDEDUCED_TYPE_(Char)> const &fmt
+ BOOST_XPR_NONDEDUCED_TYPE_(Char) *str
+ , basic_regex<Char *> const &re
+ , typename add_const<Char>::type *format
   , regex_constants::match_flag_type flags = regex_constants::match_default
 )
 {
- std::basic_string<Char> result;
- result.reserve(fmt.length() * 2);
- regex_replace(std::back_inserter(result), str.begin(), str.end(), re, fmt, flags);
+ typedef typename remove_const<Char>::type char_type;
+ std::basic_string<char_type> result;
+ Char *end = str + std::char_traits<char_type>::length(str);
+ xpressive::regex_replace(std::back_inserter(result), str, end, re, format, flags);
     return result;
 }
 

Modified: branches/release/boost/xpressive/regex_compiler.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_compiler.hpp (original)
+++ branches/release/boost/xpressive/regex_compiler.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains the definition of regex_compiler, a factory for building regex objects
 /// from strings.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -106,7 +106,7 @@
     /// represented by the character range.
     /// \pre InputIter is a model of the InputIterator concept.
     /// \pre [begin,end) is a valid range.
- /// \pre The range of characters specified by [begin,end) contains a
+ /// \pre The range of characters specified by [begin,end) contains a
     /// valid string-based representation of a regular expression.
     /// \throw regex_error when the range of characters has invalid regular
     /// expression syntax.
@@ -320,19 +320,16 @@
             negative = true; // fall-through
         case token_positive_lookahead:
             lookahead = true;
- seq_end = detail::make_dynamic<BidiIter>(detail::true_matcher());
             break;
 
         case token_negative_lookbehind:
             negative = true; // fall-through
         case token_positive_lookbehind:
             lookbehind = true;
- seq_end = detail::make_dynamic<BidiIter>(detail::true_matcher());
             break;
 
         case token_independent_sub_expression:
             keeper = true;
- seq_end = detail::make_dynamic<BidiIter>(detail::true_matcher());
             break;
 
         case token_comment:
@@ -430,16 +427,19 @@
         typedef detail::shared_matchable<BidiIter> xpr_type;
         if(lookahead)
         {
+ seq += detail::make_independent_end_xpression<BidiIter>(seq.pure());
             detail::lookahead_matcher<xpr_type> lookahead(seq.xpr(), negative, seq.pure());
             seq = detail::make_dynamic<BidiIter>(lookahead);
         }
         else if(lookbehind)
         {
+ seq += detail::make_independent_end_xpression<BidiIter>(seq.pure());
             detail::lookbehind_matcher<xpr_type> lookbehind(seq.xpr(), seq.width().value(), negative, seq.pure());
             seq = detail::make_dynamic<BidiIter>(lookbehind);
         }
         else if(keeper) // independent sub-expression
         {
+ seq += detail::make_independent_end_xpression<BidiIter>(seq.pure());
             detail::keeper_matcher<xpr_type> keeper(seq.xpr(), seq.pure());
             seq = detail::make_dynamic<BidiIter>(keeper);
         }
@@ -502,10 +502,10 @@
             return detail::make_assert_end_line<BidiIter>(this->traits_.flags(), this->rxtraits());
 
         case token_assert_word_boundary:
- return detail::make_assert_word<BidiIter>(detail::word_boundary<true>(), this->rxtraits());
+ return detail::make_assert_word<BidiIter>(detail::word_boundary<mpl::true_>(), this->rxtraits());
 
         case token_assert_not_word_boundary:
- return detail::make_assert_word<BidiIter>(detail::word_boundary<false>(), this->rxtraits());
+ return detail::make_assert_word<BidiIter>(detail::word_boundary<mpl::false_>(), this->rxtraits());
 
         case token_assert_word_begin:
             return detail::make_assert_word<BidiIter>(detail::word_begin(), this->rxtraits());

Modified: branches/release/boost/xpressive/regex_constants.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_constants.hpp (original)
+++ branches/release/boost/xpressive/regex_constants.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains definitions for the syntax_option_type, match_flag_type and
 /// error_type enumerations.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/regex_error.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_error.hpp (original)
+++ branches/release/boost/xpressive/regex_error.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file regex_error.hpp
 /// Contains the definition of the regex_error exception class.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/regex_iterator.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_iterator.hpp (original)
+++ branches/release/boost/xpressive/regex_iterator.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains the definition of the regex_iterator type, an STL-compatible iterator
 /// for stepping through all the matches in a sequence.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -39,6 +39,7 @@
         BidiIter begin
       , BidiIter cur
       , BidiIter end
+ , BidiIter next_search
       , basic_regex<BidiIter> const *rex
       , regex_constants::match_flag_type flags
       , bool not_null = false
@@ -50,6 +51,7 @@
       , not_null_(not_null)
     {
         this->state_.cur_ = cur;
+ this->state_.next_search_ = next_search;
     }
 
     bool next()
@@ -63,7 +65,7 @@
         // Report position() correctly by setting the base different from prefix().first
         access::set_base(this->what_, this->state_.begin_);
 
- this->state_.cur_ = this->what_[0].second;
+ this->state_.cur_ = this->state_.next_search_ = this->what_[0].second;
         this->not_null_ = (0 == this->what_.length());
 
         return true;
@@ -116,7 +118,7 @@
       , basic_regex<BidiIter> const &rex
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, &rex, flags))
+ : impl_(new impl_type_(begin, begin, end, begin, &rex, flags))
     {
         this->next_();
     }
@@ -130,7 +132,7 @@
       , detail::let_<LetExpr> const &args
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, &rex, flags))
+ : impl_(new impl_type_(begin, begin, end, begin, &rex, flags))
     {
         detail::bind_args(args, this->impl_->what_);
         this->next_();
@@ -222,6 +224,7 @@
                 that->state_.begin_
               , that->state_.cur_
               , that->state_.end_
+ , that->state_.next_search_
               , that->rex_
               , that->flags_
               , that->not_null_

Modified: branches/release/boost/xpressive/regex_primitives.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_primitives.hpp (original)
+++ branches/release/boost/xpressive/regex_primitives.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file regex_primitives.hpp
 /// Contains the syntax elements for writing static regular expressions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -11,9 +11,11 @@
 
 #include <vector>
 #include <climits>
+#include <boost/config.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/mpl/and.hpp>
 #include <boost/mpl/assert.hpp>
+#include <boost/detail/workaround.hpp>
 #include <boost/preprocessor/cat.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/core/matchers.hpp>
@@ -22,7 +24,7 @@
 // Doxygen can't handle proto :-(
 #ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
 # include <boost/xpressive/proto/proto.hpp>
-# include <boost/xpressive/proto/transform/arg.hpp>
+# include <boost/xpressive/proto/transform.hpp>
 # include <boost/xpressive/detail/core/icase.hpp>
 # include <boost/xpressive/detail/static/compile.hpp>
 # include <boost/xpressive/detail/static/modifier.hpp>
@@ -31,7 +33,7 @@
 namespace boost { namespace xpressive { namespace detail
 {
 
- typedef assert_word_placeholder<word_boundary<true> > assert_word_boundary;
+ typedef assert_word_placeholder<word_boundary<mpl::true_> > assert_word_boundary;
     typedef assert_word_placeholder<word_begin> assert_word_begin;
     typedef assert_word_placeholder<word_end> assert_word_end;
 
@@ -52,33 +54,44 @@
         using proto::extends<basic_mark_tag, mark_tag>::operator =;
     };
 
- template<typename Grammar>
- struct push_back_sub
- : proto::transform::identity<Grammar>
+ // workaround msvc-7.1 bug with function pointer types
+ // within function types:
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ #define mark_number(x) proto::call<mark_number(x)>
+ #define minus_one() proto::make<minus_one()>
+ #endif
+
+ struct push_back : proto::callable
     {
- template<typename Sub>
- static int to_sub(Sub const &sub, proto::tag::terminal)
- {
- return proto::arg(sub).mark_number_;
- }
+ typedef int result_type;
 
- template<typename Sub>
- static int to_sub(Sub const &, proto::tag::negate)
+ template<typename Subs>
+ int operator ()(Subs &subs, int i) const
         {
- return -1;
+ subs.push_back(i);
+ return i;
         }
+ };
 
- template<typename Expr, typename State, typename Visitor>
- static Expr const &call(Expr const &expr, State const &, Visitor &subs)
+ struct mark_number : proto::callable
+ {
+ typedef int result_type;
+
+ template<typename Expr>
+ int operator ()(Expr const &expr) const
         {
- subs.push_back(push_back_sub::to_sub(expr, typename Expr::proto_tag()));
- return expr;
+ return expr.mark_number_;
         }
     };
 
+ typedef mpl::int_<-1> minus_one;
+
     // s1 or -s1
     struct SubMatch
- : push_back_sub<proto::or_<basic_mark_tag, proto::negate<basic_mark_tag > > >
+ : proto::or_<
+ proto::when<basic_mark_tag, push_back(proto::_visitor, mark_number(proto::_arg)) >
+ , proto::when<proto::negate<basic_mark_tag>, push_back(proto::_visitor, minus_one()) >
+ >
     {};
 
     struct SubMatchList
@@ -93,10 +106,106 @@
     to_vector(Subs const &subs)
     {
         std::vector<int> subs_;
- SubMatchList::call(subs, 0, subs_);
+ SubMatchList()(subs, 0, subs_);
         return subs_;
     }
 
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ #undef mark_number
+ #undef minus_one
+ #endif
+
+ // replace "Expr" with "keep(*State) >> Expr"
+ struct skip_primitives : proto::callable
+ {
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef
+ typename proto::shift_right<
+ typename proto::unary_expr<
+ keeper_tag
+ , typename proto::dereference<State>::type
+ >::type
+ , Expr
+ >::type
+ type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator ()(Expr const &expr, State const &state, Visitor &) const
+ {
+ typedef typename result<void(Expr, State, Visitor)>::type type;
+ type that = {{{state}}, expr};
+ return that;
+ }
+ };
+
+ struct Primitives
+ : proto::or_<
+ proto::terminal<proto::_>
+ , proto::comma<proto::_, proto::_>
+ , proto::subscript<proto::terminal<set_initializer>, proto::_>
+ , proto::assign<proto::terminal<set_initializer>, proto::_>
+ , proto::assign<proto::terminal<attribute_placeholder<proto::_> >, proto::_>
+ , proto::complement<Primitives>
+ >
+ {};
+
+ struct SkipGrammar
+ : proto::or_<
+ proto::when<Primitives, skip_primitives>
+ , proto::assign<proto::terminal<mark_placeholder>, SkipGrammar> // don't "skip" mark tags
+ , proto::subscript<SkipGrammar, proto::_> // don't put skips in actions
+ , proto::binary_expr<modifier_tag, proto::_, SkipGrammar> // don't skip modifiers
+ , proto::unary_expr<lookbehind_tag, proto::_> // don't skip lookbehinds
+ , proto::nary_expr<proto::_, proto::vararg<SkipGrammar> > // everything else is fair game!
+ >
+ {};
+
+ template<typename Skip>
+ struct skip_directive
+ {
+ typedef typename proto::result_of::as_expr<Skip>::type skip_type;
+
+ skip_directive(Skip const &skip)
+ : skip_(proto::as_expr(skip))
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr>
+ struct result<This(Expr)>
+ {
+ typedef
+ typename proto::shift_right<
+ typename SkipGrammar::result<void(
+ typename proto::result_of::as_expr<Expr>::type
+ , skip_type
+ , mpl::void_
+ )>::type
+ , typename proto::dereference<skip_type>::type
+ >::type
+ type;
+ };
+
+ template<typename Expr>
+ typename result<skip_directive(Expr)>::type
+ operator ()(Expr const &expr) const
+ {
+ mpl::void_ ignore;
+ typedef typename result<skip_directive(Expr)>::type result_type;
+ result_type result = {SkipGrammar()(proto::as_expr(expr), this->skip_, ignore), {skip_}};
+ return result;
+ }
+
+ private:
+ skip_type skip_;
+ };
 
 /*
 ///////////////////////////////////////////////////////////////////////////////
@@ -499,11 +608,19 @@
 /// \brief Make a sub-expression optional. Equivalent to !as_xpr(expr).
 ///
 /// \param expr The sub-expression to make optional.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified optional(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<proto::tag::logical_not, proto::default_domain> const optional = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+ proto::tag::logical_not
+ , proto::default_domain
+ , Expr const &
+>::type const
+optional(Expr const &expr)
+{
+ return proto::make_expr<
+ proto::tag::logical_not
+ , proto::default_domain
+ >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Repeat a sub-expression multiple times.
@@ -517,19 +634,33 @@
 ///
 /// \param expr The sub-expression to repeat.
 template<unsigned int Min, unsigned int Max, typename Expr>
-typename proto::result_of::make_expr<detail::generic_quant_tag<Min, Max>, proto::default_domain, Expr const>::type const
+typename proto::result_of::make_expr<
+ detail::generic_quant_tag<Min, Max>
+ , proto::default_domain
+ , Expr const &
+>::type const
 repeat(Expr const &expr)
 {
- return proto::make_expr<detail::generic_quant_tag<Min, Max>, proto::default_domain>(expr);
+ return proto::make_expr<
+ detail::generic_quant_tag<Min, Max>
+ , proto::default_domain
+ >(boost::ref(expr));
 }
 
 /// \overload
 ///
 template<unsigned int Count, typename Expr2>
-typename proto::result_of::make_expr<detail::generic_quant_tag<Count, Count>, proto::default_domain, Expr2 const>::type const
+typename proto::result_of::make_expr<
+ detail::generic_quant_tag<Count, Count>
+ , proto::default_domain
+ , Expr2 const &
+>::type const
 repeat(Expr2 const &expr2)
 {
- return proto::make_expr<detail::generic_quant_tag<Count, Count>, proto::default_domain>(expr2);
+ return proto::make_expr<
+ detail::generic_quant_tag<Count, Count>
+ , proto::default_domain
+ >(boost::ref(expr2));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -542,11 +673,19 @@
 /// \attention keep(expr) is equivalent to the perl (?>...) extension.
 ///
 /// \param expr The sub-expression to modify.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified keep(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<detail::keeper_tag, proto::default_domain> const keep = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+ detail::keeper_tag
+ , proto::default_domain
+ , Expr const &
+>::type const
+keep(Expr const &expr)
+{
+ return proto::make_expr<
+ detail::keeper_tag
+ , proto::default_domain
+ >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Look-ahead assertion.
@@ -561,11 +700,19 @@
 /// perl (?!...) extension.
 ///
 /// \param expr The sub-expression to put in the look-ahead assertion.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified before(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<detail::lookahead_tag, proto::default_domain> const before = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+ detail::lookahead_tag
+ , proto::default_domain
+ , Expr const &
+>::type const
+before(Expr const &expr)
+{
+ return proto::make_expr<
+ detail::lookahead_tag
+ , proto::default_domain
+ >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Look-behind assertion.
@@ -582,11 +729,19 @@
 /// \param expr The sub-expression to put in the look-ahead assertion.
 ///
 /// \pre expr cannot match a variable number of characters.
-#ifdef BOOST_XPRESSIVE_DOXYGEN_INVOKED
-template<typename Expr> detail::unspecified after(Expr const &expr) { return 0; }
-#else
-proto::functional::make_expr<detail::lookbehind_tag, proto::default_domain> const after = {};
-#endif
+template<typename Expr>
+typename proto::result_of::make_expr<
+ detail::lookbehind_tag
+ , proto::default_domain
+ , Expr const &
+>::type const
+after(Expr const &expr)
+{
+ return proto::make_expr<
+ detail::lookbehind_tag
+ , proto::default_domain
+ >(boost::ref(expr));
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 /// \brief Specify a regex traits or a std::locale.
@@ -620,6 +775,48 @@
 proto::terminal<detail::attribute_placeholder<mpl::int_<8> > >::type const a8 = {{}};
 proto::terminal<detail::attribute_placeholder<mpl::int_<9> > >::type const a9 = {{}};
 
+///////////////////////////////////////////////////////////////////////////////
+/// \brief Specify which characters to skip when matching a regex.
+///
+/// <tt>skip()</tt> instructs the regex engine to skip certain characters when matching
+/// a regex. It is most useful for writing regexes that ignore whitespace.
+/// For instance, the following specifies a regex that skips whitespace and
+/// punctuation:
+///
+/// \code
+/// // A sentence is one or more words separated by whitespace
+/// // and punctuation.
+/// sregex word = +alpha;
+/// sregex sentence = skip(set[_s | punct])( +word );
+/// \endcode
+///
+/// The way it works in the above example is to insert
+/// <tt>keep(*set[_s | punct])</tt> before each primitive within the regex.
+/// A "primitive" includes terminals like strings, character sets and nested
+/// regexes. A final <tt>*set[_s | punct]</tt> is added to the end of the
+/// regex. The regex <tt>sentence</tt> specified above is equivalent to
+/// the following:
+///
+/// \code
+/// sregex sentence = +( keep(*set[_s | punct]) >> word )
+/// >> *set[_s | punct];
+/// \endcode
+///
+/// \attention Skipping does not affect how nested regexes are handled because
+/// they are treated atomically. String literals are also treated
+/// atomically; that is, no skipping is done within a string literal. So
+/// <tt>skip(_s)("this that")</tt> is not the same as
+/// <tt>skip(_s)("this" >> as_xpr("that"))</tt>. The first will only match
+/// when there is only one space between "this" and "that". The second will
+/// skip any and all whitespace between "this" and "that".
+///
+/// \param skip A regex that specifies which characters to skip.
+template<typename Skip>
+detail::skip_directive<Skip> skip(Skip const &skip)
+{
+ return detail::skip_directive<Skip>(skip);
+}
+
 namespace detail
 {
     inline void ignore_unused_regex_primitives()
@@ -664,10 +861,6 @@
         ignore_unused(a8);
         ignore_unused(a9);
         ignore_unused(as_xpr);
- ignore_unused(optional);
- ignore_unused(before);
- ignore_unused(after);
- ignore_unused(keep);
     }
 }
 

Modified: branches/release/boost/xpressive/regex_token_iterator.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_token_iterator.hpp (original)
+++ branches/release/boost/xpressive/regex_token_iterator.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains the definition of regex_token_iterator, and STL-compatible iterator
 /// for tokenizing a string using a regular expression.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -39,13 +39,14 @@
         BidiIter begin
       , BidiIter cur
       , BidiIter end
+ , BidiIter next_search
       , basic_regex<BidiIter> const *rex
       , regex_constants::match_flag_type flags = regex_constants::match_default
       , std::vector<int> subs = std::vector<int>(1, 0)
       , int n = -2
       , bool not_null = false
     )
- : iter_(begin, cur, end, rex, flags, not_null)
+ : iter_(begin, cur, end, next_search, rex, flags, not_null)
       , result_()
       , n_((-2 == n) ? (int)subs.size() - 1 : n)
       , subs_()
@@ -158,7 +159,7 @@
       , BidiIter end
       , basic_regex<BidiIter> const &rex
     )
- : impl_(new impl_type_(begin, begin, end, &rex))
+ : impl_(new impl_type_(begin, begin, end, begin, &rex))
     {
         this->next_();
     }
@@ -176,7 +177,7 @@
       , basic_regex<BidiIter> const &rex
       , detail::let_<LetExpr> const &args
     )
- : impl_(new impl_type_(begin, begin, end, &rex))
+ : impl_(new impl_type_(begin, begin, end, begin, &rex))
     {
         detail::bind_args(args, this->impl_->iter_.what_);
         this->next_();
@@ -198,7 +199,7 @@
       , Subs const &subs
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, &rex, flags, detail::to_vector(subs)))
+ : impl_(new impl_type_(begin, begin, end, begin, &rex, flags, detail::to_vector(subs)))
     {
         this->next_();
     }
@@ -221,7 +222,7 @@
       , detail::let_<LetExpr> const &args
       , regex_constants::match_flag_type flags = regex_constants::match_default
     )
- : impl_(new impl_type_(begin, begin, end, &rex, flags, detail::to_vector(subs)))
+ : impl_(new impl_type_(begin, begin, end, begin, &rex, flags, detail::to_vector(subs)))
     {
         detail::bind_args(args, this->impl_->iter_.what_);
         this->next_();
@@ -307,6 +308,7 @@
                 this->impl_->iter_.state_.begin_
               , this->impl_->iter_.state_.cur_
               , this->impl_->iter_.state_.end_
+ , this->impl_->iter_.state_.next_search_
               , this->impl_->iter_.rex_
               , this->impl_->iter_.flags_
               , this->impl_->subs_

Modified: branches/release/boost/xpressive/regex_traits.hpp
==============================================================================
--- branches/release/boost/xpressive/regex_traits.hpp (original)
+++ branches/release/boost/xpressive/regex_traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Includes the C regex traits or the CPP regex traits header file depending on the
 /// BOOST_XPRESSIVE_USE_C_TRAITS macro.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/sub_match.hpp
==============================================================================
--- branches/release/boost/xpressive/sub_match.hpp (original)
+++ branches/release/boost/xpressive/sub_match.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Contains the definition of the class template sub_match\<\>
 /// and associated helper functions
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/traits/c_regex_traits.hpp
==============================================================================
--- branches/release/boost/xpressive/traits/c_regex_traits.hpp (original)
+++ branches/release/boost/xpressive/traits/c_regex_traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
 /// wrapper for the C locale functions that can be used to customize the
 /// behavior of static and dynamic regexes.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/traits/cpp_regex_traits.hpp
==============================================================================
--- branches/release/boost/xpressive/traits/cpp_regex_traits.hpp (original)
+++ branches/release/boost/xpressive/traits/cpp_regex_traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
 /// wrapper for std::locale that can be used to customize the behavior of
 /// static and dynamic regexes.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -24,6 +24,7 @@
 #include <boost/assert.hpp>
 #include <boost/integer.hpp>
 #include <boost/mpl/assert.hpp>
+#include <boost/detail/workaround.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/detail/detail_fwd.hpp>
 #include <boost/xpressive/detail/utility/literals.hpp>

Modified: branches/release/boost/xpressive/traits/detail/c_ctype.hpp
==============================================================================
--- branches/release/boost/xpressive/traits/detail/c_ctype.hpp (original)
+++ branches/release/boost/xpressive/traits/detail/c_ctype.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // c_ctype.hpp
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/traits/null_regex_traits.hpp
==============================================================================
--- branches/release/boost/xpressive/traits/null_regex_traits.hpp (original)
+++ branches/release/boost/xpressive/traits/null_regex_traits.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -4,7 +4,7 @@
 /// stub regex traits implementation that can be used by static and dynamic
 /// regexes for searching non-character data.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/xpressive.hpp
==============================================================================
--- branches/release/boost/xpressive/xpressive.hpp (original)
+++ branches/release/boost/xpressive/xpressive.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Includes all of xpressive including support for both static and
 /// dynamic regular expressions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/xpressive_dynamic.hpp
==============================================================================
--- branches/release/boost/xpressive/xpressive_dynamic.hpp (original)
+++ branches/release/boost/xpressive/xpressive_dynamic.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file xpressive_dynamic.hpp
 /// Includes everything you need to write and use dynamic regular expressions.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/xpressive_fwd.hpp
==============================================================================
--- branches/release/boost/xpressive/xpressive_fwd.hpp (original)
+++ branches/release/boost/xpressive/xpressive_fwd.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file xpressive_fwd.hpp
 /// Forward declarations for all of xpressive's public data types.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/xpressive_static.hpp
==============================================================================
--- branches/release/boost/xpressive/xpressive_static.hpp (original)
+++ branches/release/boost/xpressive/xpressive_static.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -3,7 +3,7 @@
 /// Includes everything you need to write static regular expressions and use
 /// them.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/boost/xpressive/xpressive_typeof.hpp
==============================================================================
--- branches/release/boost/xpressive/xpressive_typeof.hpp (original)
+++ branches/release/boost/xpressive/xpressive_typeof.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 /// \file xpressive_typeof.hpp
 /// Type registrations so that xpressive can be used with the Boost.Typeof library.
 //
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -24,6 +24,8 @@
 
 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
 
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::mpl::bool_, (bool))
+
 ///////////////////////////////////////////////////////////////////////////////
 // Misc.
 //
@@ -38,7 +40,7 @@
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::word_end)
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::generic_quant_tag, (unsigned int)(unsigned int))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::basic_regex, (typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::word_boundary, (bool))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::word_boundary, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::value, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::reference, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::local, (typename))
@@ -70,6 +72,7 @@
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::epsilon_matcher)
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::true_matcher)
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::end_matcher)
+BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::independent_end_matcher)
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::any_matcher)
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::assert_bos_matcher)
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::assert_eos_matcher)
@@ -80,28 +83,28 @@
 BOOST_TYPEOF_REGISTER_TYPE(boost::xpressive::detail::attr_end_matcher)
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::assert_bol_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::assert_eol_matcher, (typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::literal_matcher, (typename)(bool)(bool))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::string_matcher, (typename)(bool))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::charset_matcher, (typename)(bool)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::literal_matcher, (typename)(typename)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::string_matcher, (typename)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::charset_matcher, (typename)(typename)(typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::logical_newline_matcher, (typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::mark_matcher, (typename)(bool))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::repeat_end_matcher, (bool))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::mark_matcher, (typename)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::repeat_end_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::alternate_matcher, (typename)(typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::optional_matcher, (typename)(bool))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::optional_mark_matcher, (typename)(bool))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::simple_repeat_matcher, (typename)(bool))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::optional_matcher, (typename)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::optional_mark_matcher, (typename)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::simple_repeat_matcher, (typename)(typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::regex_byref_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::regex_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::posix_charset_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::assert_word_matcher, (typename)(typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::range_matcher, (typename)(bool))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::range_matcher, (typename)(typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::keeper_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::lookahead_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::lookbehind_matcher, (typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::set_matcher, (typename)(int))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::set_matcher, (typename)(typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::predicate_matcher, (typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::action_matcher, (typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::attr_matcher, (typename)(typename)(bool))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::attr_matcher, (typename)(typename)(typename))
 BOOST_TYPEOF_REGISTER_TEMPLATE(boost::xpressive::detail::attr_begin_matcher, (typename))
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/release/libs/xpressive/doc/acknowledgements.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/acknowledgements.qbk (original)
+++ branches/release/libs/xpressive/doc/acknowledgements.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -8,14 +8,15 @@
 [section Acknowledgments]
 
 I am indebted to [@http://boost.org/people/joel_de_guzman.htm Joel de Guzman]
-and [@http://boost.org/people/hartmut_kaiser.htm Hartmut Kaiser] for their
+and [@http://boost.org/people/hartmut_kaiser.htm Hartmut Kaiser] for their
 expert advice during the early states of xpressive's development. Much of
 static xpressive's syntax is owes a large debt to _spirit_, including the
-syntax for xpressive's semantic actions. I am thankful for
+syntax for xpressive's semantic actions. I am thankful for
 [@http://boost.org/people/john_maddock.htm John Maddock]'s excellent work on
-his proposal to add regular expressions to the standard library. I'd also like
+his proposal to add regular expressions to the standard library, and for
+various ideas borrowed liberally from his regex implementation. I'd also like
 to thank [@http://moderncppdesign.com/ Andrei Alexandrescu] for his input
-regarding the behavior of nested regex objects, and
+regarding the behavior of nested regex objects, and
 [@http://boost.org/people/dave_abrahams.htm Dave Abrahams] for his suggestions
 regarding the regex domain-specific embedded language. Noel Belcourt helped
 porting xpressive to the Metrowerks CodeWarrior compiler. Markus

Modified: branches/release/libs/xpressive/doc/actions.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/actions.qbk (original)
+++ branches/release/libs/xpressive/doc/actions.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -10,7 +10,7 @@
 [h2 Overview]
 
 Imagine you want to parse an input string and build a `std::map<>` from it. For
-something like that, matching a regular expression isn't enough. You want to
+something like that, matching a regular expression isn't enough. You want to
 /do something/ when parts of your regular expression match. Xpressive lets
 you attach semantic actions to parts of your static regular expressions. This
 section shows you how.
@@ -31,12 +31,12 @@
     {
         std::map<std::string, int> result;
         std::string str("aaa=>1 bbb=>23 ccc=>456");
-
+
         // Match a word and an integer, separated by =>,
         // and then stuff the result into a std::map<>
         sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
             [ ref(result)[s1] = as<int>(s2) ];
-
+
         // Match one or more word/integer pairs, separated
         // by whitespace.
         sregex rx = pair >> *(+_s >> pair);
@@ -47,7 +47,7 @@
             std::cout << result["bbb"] << '\n';
             std::cout << result["ccc"] << '\n';
         }
-
+
         return 0;
     }
 
@@ -59,7 +59,7 @@
 456
 ]
 
-The regular expression `pair` has two parts: the pattern and the action. The
+The regular expression `pair` has two parts: the pattern and the action. The
 pattern says to match a word, capturing it in sub-match 1, and an integer,
 capturing it in sub-match 2, separated by `"=>"`. The action is the part in
 square brackets: `[ ref(result)[s1] = as<int>(s2) ]`. It says to take sub-match
@@ -73,15 +73,15 @@
 between brackets is an expression template. It encodes the action and executes
 it later. The expression `ref(result)` creates a lazy reference to the `result`
 object. The larger expression `ref(result)[s1]` is a lazy map index operation.
-Later, when this action is getting executed, `s1` gets replaced with the
+Later, when this action is getting executed, `s1` gets replaced with the
 first _sub_match_. Likewise, when `as<int>(s2)` gets executed, `s2` is replaced
-with the second _sub_match_. The `as<>` action converts its argument to the
+with the second _sub_match_. The `as<>` action converts its argument to the
 requested type using Boost.Lexical_cast. The effect of the whole action is to
 insert a new word/integer pair into the map.
 
 [note There is an important difference between the function `boost::ref()` in
-`<boost/ref.hpp>` and `boost::xpressive::ref()` in
-`<boost/xpressive/regex_actions.hpp>`. The first returns a plain
+`<boost/ref.hpp>` and `boost::xpressive::ref()` in
+`<boost/xpressive/regex_actions.hpp>`. The first returns a plain
 `reference_wrapper<>` which behaves in many respects like an ordinary
 reference. By contrast, `boost::xpressive::ref()` returns a /lazy/ reference
 that you can use in expressions that are executed lazily. That is why we can
@@ -137,7 +137,7 @@
 operators. But what if you want to be able to call a function from a semantic
 action? Xpressive provides a mechanism to do this.
 
-The first step is to define a function object type. Here, for instance, is a
+The first step is to define a function object type. Here, for instance, is a
 function object type that calls `push()` on its argument:
 
     struct push_impl
@@ -158,7 +158,7 @@
     // Global "push" function object.
     function<push_impl>::type const push = {{}};
 
-The initialization looks a bit odd, but this is because `push` is being
+The initialization looks a bit odd, but this is because `push` is being
 statically initialized. That means it doesn't need to be constructed
 at runtime. We can use `push` in semantic actions as follows:
 
@@ -182,7 +182,7 @@
 `result_type` typedef. Here, for example, is a `first` function object
 that returns the `first` member of a `std::pair<>` or _sub_match_:
 
- // Function object that returns the
+ // Function object that returns the
     // first element of a pair.
     struct first_impl
     {
@@ -204,7 +204,7 @@
     };
 
     // OK, use as first(s1) to get the begin iterator
- // of the sub-match referred to by s1.
+ // of the sub-match referred to by s1.
     function<first_impl>::type const first = {{}};
 
 [h3 Referring to Local Variables]
@@ -238,7 +238,7 @@
     }
 
 In the above code, we use `xpressive::val()` to hold the shared pointer by
-value. That's not normally necessary because local variables appearing in
+value. That's not normally necessary because local variables appearing in
 actions are held by value by default, but in this case, it is necessary. Had
 we written the action as `++*pi`, it would have executed immediately. That's
 because `++*pi` is not an expression template, but `++*val(pi)` is.
@@ -263,7 +263,7 @@
 
 As you can see, when using `reference<>`, you need to first declare a local
 variable and then declare a `reference<>` to it. These two steps can be combined
-into one using `local<>`.
+into one using `local<>`.
 
 [table local<> vs. reference<>
 [[This ...][... is equivalent to this ...]]
@@ -301,15 +301,15 @@
 that in the semantic action instead of the map itself. Later, when we
 call one of the regex algorithms, we can bind the reference to an actual
 map object. The following code shows how.
-
+
     // Define a placeholder for a map object:
     placeholder<std::map<std::string, int> > _map;
-
+
     // Match a word and an integer, separated by =>,
     // and then stuff the result into a std::map<>
     sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
         [ _map[s1] = as<int>(s2) ];
-
+
     // Match one or more word/integer pairs, separated
     // by whitespace.
     sregex rx = pair >> *(+_s >> pair);
@@ -319,7 +319,7 @@
 
     // Here is the actual map to fill in:
     std::map<std::string, int> result;
-
+
     // Bind the _map placeholder to the actual map
     smatch what;
     what.let( _map = result );
@@ -340,10 +340,10 @@
 456
 ]
 
-We use `placeholder<>` here to define `_map`, which stands in for a
+We use `placeholder<>` here to define `_map`, which stands in for a
 `std::map<>` variable. We can use the placeholder in the semantic action as if
 it were a map. Then, we define a _match_results_ struct and bind an actual map
-to the placeholder with "`what.let( _map = result );`". The _regex_match_ call
+to the placeholder with "`what.let( _map = result );`". The _regex_match_ call
 behaves as if the placeholder in the semantic action had been replaced with a
 reference to `result`.
 
@@ -360,27 +360,27 @@
 
     // Define a placeholder for a map object:
     placeholder<std::map<std::string, int> > _map;
-
+
     // Match a word and an integer, separated by =>,
     // and then stuff the result into a std::map<>
     sregex pair = ( (s1= +_w) >> "=>" >> (s2= +_d) )
         [ _map[s1] = as<int>(s2) ];
-
+
     // The string to parse
     std::string str("aaa=>1 bbb=>23 ccc=>456");
-
+
     // Here is the actual map to fill in:
     std::map<std::string, int> result;
-
+
     // Create a regex_iterator to find all the matches
     sregex_iterator it(str.begin(), str.end(), pair, let(_map=result));
     sregex_iterator end;
-
+
     // step through all the matches, and fill in
     // the result map
     while(it != end)
         ++it;
-
+
     std::cout << result["aaa"] << '\n';
     std::cout << result["bbb"] << '\n';
     std::cout << result["ccc"] << '\n';
@@ -397,7 +397,7 @@
 
 You are probably already familiar with regular expression /assertions/. In
 Perl, some examples are the [^^] and [^$] assertions, which you can use to
-match the beginning and end of a string, respectively. Xpressive lets you
+match the beginning and end of a string, respectively. Xpressive lets you
 define your own assertions. A custom assertion is a contition which must be
 true at a point in the match in order for the match to succeed. You can check
 a custom assertion with xpressive's _check_ function.
@@ -438,7 +438,7 @@
     sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ;
 
 In the above, `length()` is a lazy function that calls the `length()` member
-function of its argument, and `_` is a placeholder that receives the
+function of its argument, and `_` is a placeholder that receives the
 `sub_match`.
 
 Once you get the hang of writing custom assertions inline, they can be
@@ -451,7 +451,7 @@
 
     mark_tag month(1), day(2);
     // find a valid date of the form month/day/year.
- sregex date =
+ sregex date =
         (
             // Month must be between 1 and 12 inclusive
             (month= _d >> !_d) [ check(as<int>(_) >= 1

Modified: branches/release/libs/xpressive/doc/concepts.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/concepts.qbk (original)
+++ branches/release/libs/xpressive/doc/concepts.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/dynamic_regexes.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/dynamic_regexes.qbk (original)
+++ branches/release/libs/xpressive/doc/dynamic_regexes.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -20,7 +20,7 @@
 There are two ways to create a dynamic regex: with the _regex_compile_
 function or with the _regex_compiler_ class template. Use _regex_compile_
 if you want the default locale. Use _regex_compiler_ if you need to
-specify a different locale. In the section on
+specify a different locale. In the section on
 [link boost_xpressive.user_s_guide.grammars_and_nested_matches regex grammars],
 we'll see another use for _regex_compiler_.
 

Modified: branches/release/libs/xpressive/doc/examples.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/examples.qbk (original)
+++ branches/release/libs/xpressive/doc/examples.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/grammars.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/grammars.qbk (original)
+++ branches/release/libs/xpressive/doc/grammars.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/history.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/history.qbk (original)
+++ branches/release/libs/xpressive/doc/history.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -7,6 +7,27 @@
 
 [section Appendix 1: History]
 
+[h2 Version 2.1.0 6/12/2008]
+
+New Features:
+
+* `skip()` primitive for static regexes, which allows you to specify parts of
+ the input string to ignore during regex matching.
+* Range-based `regex_replace()` algorithm interface.
+* `regex_replace()` accepts formatter objects and formatter lambda expressions
+ in addition to format strings.
+
+Bugs Fixed:
+
+* Semantic actions in look-aheads, look-behinds and independent sub-expressions
+ execute eagerly instead of causing a crash.
+
+[h2 Version 2.0.1 10/23/2007]
+
+Bugs Fixed:
+
+* `sub_match<>` constructor copies singular iterator causing debug assert.
+
 [h2 Version 2.0.0, 10/12/2007]
 
 New Features:
@@ -66,7 +87,7 @@
 
 [h2 Version 0.0.1, November 16, 2003]
 
-Announcement of xpressive:
+Announcement of xpressive:
 [@http://lists.boost.org/Archives/boost/2003/11/56312.php]
 
 [endsect]

Modified: branches/release/libs/xpressive/doc/installation.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/installation.qbk (original)
+++ branches/release/libs/xpressive/doc/installation.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -16,7 +16,7 @@
 The second way is by downloading xpressive.zip at the
 [@http://www.boost-consulting.com/vault/index.php?directory=Strings%20-%20Text%20Processing
 Boost File Vault] in the ["Strings - Text Processing] directory. In addition to
-the source code and the Boost license, this archive contains a copy of this
+the source code and the Boost license, this archive contains a copy of this
 documentation in PDF format. This version will always be stable and at least as
 current as the version in the latest Boost release. It may be more recent. The
 version in the File Vault is always guaranteed to work with the latest official

Modified: branches/release/libs/xpressive/doc/introduction.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/introduction.qbk (original)
+++ branches/release/libs/xpressive/doc/introduction.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -15,7 +15,7 @@
 [@http://www.osl.iu.edu/~tveldhui/papers/Expression-Templates/exprtmpl.html
 Expression Templates]] that are parsed at compile-time (static regexes).
 Dynamic regexes have the advantage that they can be accepted from the user
-as input at runtime or read from an initialization file. Static regexes
+as input at runtime or read from an initialization file. Static regexes
 have several advantages. Since they are C++ expressions instead of
 strings, they can be syntax-checked at compile-time. Also, they can naturally
 refer to code and data elsewhere in your program, giving you the ability to call

Modified: branches/release/libs/xpressive/doc/matching.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/matching.qbk (original)
+++ branches/release/libs/xpressive/doc/matching.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -23,8 +23,8 @@
 algorithm.]
 
 The input can be a bidirectional range such as `std::string`, a C-style null-terminated string or a pair of
-iterators. In all cases, the type of the iterator used to traverse the input sequence must match the iterator
-type used to declare the regex object. (You can use the table in the
+iterators. In all cases, the type of the iterator used to traverse the input sequence must match the iterator
+type used to declare the regex object. (You can use the table in the
 [link boost_xpressive.user_s_guide.quick_start.know_your_iterator_type Quick Start] to find the correct regex
 type for your iterator.)
 
@@ -78,8 +78,8 @@
 
 In all other regards, _regex_search_ behaves like _regex_match_ ['(see above)]. In particular, it can operate
 on a bidirectional range such as `std::string`, C-style null-terminated strings or iterator ranges. The same
-care must be taken to ensure that the iterator type of your regex matches the iterator type of your input
-sequence. As with _regex_match_, you can optionally provide a _match_results_ struct to receive the results
+care must be taken to ensure that the iterator type of your regex matches the iterator type of your input
+sequence. As with _regex_match_, you can optionally provide a _match_results_ struct to receive the results
 of the search, and a _match_flag_type_ bitmask to control how the match is evaluated.
 
 Click [link boost_xpressive.user_s_guide.examples.see_if_a_string_contains_a_sub_string_that_matches_a_regex here]

Modified: branches/release/libs/xpressive/doc/nyi.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/nyi.qbk (original)
+++ branches/release/libs/xpressive/doc/nyi.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -10,7 +10,7 @@
 The following features are planned for xpressive 2.X:
 
 * `syntax_option_type::collate`
-* Collation sequences such as [^'''[.a.]''']
+* Collation sequences such as [^'''[.a.]''']
 * Equivalence classes like [^'''[=a=]''']
 * Control of nested results generation with `syntax_option_type::nosubs`,
   and a `nosubs()` modifier for static xpressive.

Modified: branches/release/libs/xpressive/doc/perf.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/perf.qbk (original)
+++ branches/release/libs/xpressive/doc/perf.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/preface.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/preface.qbk (original)
+++ branches/release/libs/xpressive/doc/preface.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/quick_start.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/quick_start.qbk (original)
+++ branches/release/libs/xpressive/doc/quick_start.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/regexpp_diffs.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/regexpp_diffs.qbk (original)
+++ branches/release/libs/xpressive/doc/regexpp_diffs.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/results.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/results.qbk (original)
+++ branches/release/libs/xpressive/doc/results.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/static_regexes.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/static_regexes.qbk (original)
+++ branches/release/libs/xpressive/doc/static_regexes.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/substitutions.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/substitutions.qbk (original)
+++ branches/release/libs/xpressive/doc/substitutions.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -14,10 +14,12 @@
 [h2 regex_replace()]
 
 Performing search-and-replace using _regex_replace_ is simple. All you need is an input sequence, a regex object,
-and a format string. There are two versions of the _regex_replace_ algorithm. The first accepts the input
-sequence as `std::basic_string<>` and returns the result in a new `std::basic_string<>`. The second accepts
-the input sequence as a pair of iterators, and writes the result into an output iterator. Below are examples of
-each.
+and a format string or a formatter object. There are several versions of the _regex_replace_ algorithm. Some accept
+the input sequence as a bidirectional container such as `std::string` and returns the result in a new container
+of the same type. Others accept the input as a null terminated string and return a `std::string`. Still others
+accept the input sequence as a pair of iterators and writes the result into an output iterator. The substitution
+may be specified as a string with format sequences or as a formatter object. Below are some simple examples of
+using string-based substitutions.
 
     std::string input("This is his face");
     sregex re = as_xpr("his"); // find all occurrences of "his" ...
@@ -63,11 +65,13 @@
                                  Boost-specific format sequences.]]
 ]
 
-These flags live in the `regex_constants` namespace.
+These flags live in the `xpressive::regex_constants` namespace. If the substitution parameter is
+a function object instead of a string, the flags `format_literal`, `format_perl`, `format_sed`, and
+`format_all` are ignored.
 
 [h2 The ECMA-262 Format Sequences]
 
-When you haven't specified a substitution string dialect with one of the format flags above,
+When you haven't specified a substitution string dialect with one of the format flags above,
 you get the dialect defined by ECMA-262, the standard for ECMAScript. The table below shows
 the escape sequences recognized in ECMA-262 mode.
 
@@ -150,4 +154,161 @@
 it is /false-expression/. In this mode, you can use parens [^()] for grouping. If you
 want a literal paren, you must escape it as [^\\(].
 
+[h2 Formatter Objects]
+
+Format strings are not always expressive enough for all your text substitution
+needs. Consider the simple example of wanting to map input strings to output
+strings, as you may want to do with environment variables. Rather than a format
+/string/, for this you would use a formatter /object/. Consider the following
+code, which finds embedded environment variables of the form `"$(XYZ)"` and
+computes the substitution string by looking up the environment variable in a
+map.
+
+ #include <map>
+ #include <string>
+ #include <iostream>
+ #include <boost/xpressive/xpressive.hpp>
+ using namespace boost;
+ using namespace xpressive;
+
+ std::map<std::string, std::string> env;
+
+ std::string const &format_fun(smatch const &what)
+ {
+ return env[what[1].str()];
+ }
+
+ int main()
+ {
+ env["X"] = "this";
+ env["Y"] = "that";
+
+ std::string input("\"$(X)\" has the value \"$(Y)\"");
+
+ // replace strings like "$(XYZ)" with the result of env["XYZ"]
+ sregex envar = "$(" >> (s1 = +_w) >> ')';
+ std::string output = regex_replace(input, envar, format_fun);
+ std::cout << output << std::endl;
+ }
+
+In this case, we use a function, `format_fun()` to compute the substitution string
+on the fly. It accepts a _match_results_ object which contains the results of the
+current match. `format_fun()` uses the first submatch as a key into the global `env`
+map. The above code displays:
+
+[pre
+"this" has the value "that"
+]
+
+The formatter need not be an ordinary function. It may be an object of class type.
+And rather than return a string, it may accept an output iterator into which it
+writes the substitution. Consider the following, which is functionally equivalent
+to the above.
+
+ #include <map>
+ #include <string>
+ #include <iostream>
+ #include <boost/xpressive/xpressive.hpp>
+ using namespace boost;
+ using namespace xpressive;
+
+ struct formatter
+ {
+ typedef std::map<std::string, std::string> env_map;
+ env_map env;
+
+ template<typename Out>
+ Out operator()(smatch const &what, Out out) const
+ {
+ env_map::const_iterator where = env.find(what[1]);
+ if(where != env.end())
+ {
+ std::string const &sub = where->second;
+ out = std::copy(sub.begin(), sub.end(), out);
+ }
+ return out;
+ }
+
+ };
+
+ int main()
+ {
+ formatter fmt;
+ fmt.env["X"] = "this";
+ fmt.env["Y"] = "that";
+
+ std::string input("\"$(X)\" has the value \"$(Y)\"");
+
+ sregex envar = "$(" >> (s1 = +_w) >> ')';
+ std::string output = regex_replace(input, envar, fmt);
+ std::cout << output << std::endl;
+ }
+
+The formatter must be a callable object -- a function or a function object --
+that has one of three possible signatures, detailed in the table below. For
+the table, `fmt` is a function pointer or function object, `what` is a
+_match_results_ object, `out` is an OutputIterator, and `flags` is a value
+of `regex_constants::match_flag_type`:
+
+[table Formatter Signatures
+[
+ [Formatter Invocation]
+ [Return Type]
+ [Semantics]
+]
+[
+ [`fmt(what)`]
+ [Range of characters (e.g. `std::string`) or null-terminated string]
+ [The string matched by the regex is replaced with the string returned by
+ the formatter.]
+]
+[
+ [`fmt(what, out)`]
+ [OutputIterator]
+ [The formatter writes the replacement string into `out` and returns `out`.]
+]
+[
+ [`fmt(what, out, flags)`]
+ [OutputIterator]
+ [The formatter writes the replacement string into `out` and returns `out`.
+ The `flags` parameter is the value of the match flags passed to the
+ _regex_replace_ algorithm.]
+]
+]
+
+[h2 Formatter Expressions]
+
+In addition to format /strings/ and formatter /objects/, _regex_replace_ also
+accepts formatter /expressions/. A formatter expression is a lambda expression
+that generates a string. It uses the same syntax as that for
+[link boost_xpressive.user_s_guide.semantic_actions_and_user_defined_assertions
+Semantic Actions], which are covered later. The above example, which uses
+_regex_replace_ to substitute strings for environment variables, is repeated
+here using a formatter expression.
+
+ #include <map>
+ #include <string>
+ #include <iostream>
+ #include <boost/xpressive/xpressive.hpp>
+ #include <boost/xpressive/regex_actions.hpp>
+ using namespace boost::xpressive;
+
+ int main()
+ {
+ std::map<std::string, std::string> env;
+ env["X"] = "this";
+ env["Y"] = "that";
+
+ std::string input("\"$(X)\" has the value \"$(Y)\"");
+
+ sregex envar = "$(" >> (s1 = +_w) >> ')';
+ std::string output = regex_replace(input, envar, ref(env)[s1]);
+ std::cout << output << std::endl;
+ }
+
+In the above, the formatter expression is `ref(env)[s1]`. This means to use the
+value of the first submatch, `s1`, as a key into the `env` map. The purpose of
+`xpressive::ref()` here is to make the reference to the `env` local variable /lazy/
+so that the index operation is deferred until we know what to replace `s1` with.
+
 [endsect]

Modified: branches/release/libs/xpressive/doc/symbols.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/symbols.qbk (original)
+++ branches/release/libs/xpressive/doc/symbols.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -9,7 +9,7 @@
 
 [h2 Overview]
 
-Symbol tables can be built into xpressive regular expressions with just a
+Symbol tables can be built into xpressive regular expressions with just a
 `std::map<>`. The map keys are the strings to be matched and the map values are
 the data to be returned to your semantic action. Xpressive attributes, named
 `a1`, `a2`, through `a9`, hold the value corresponding to a matching key so
@@ -83,7 +83,7 @@
 ninety nine million nine hundred ninety nine thousand nine hundred ninety nine"
 along with some special number names like "dozen".
 
-Symbol table matches are case sensitive by default, but they can be made
+Symbol table matches are case sensitive by default, but they can be made
 case-insensitive by enclosing the expression in `icase()`.
 
 [h2 Attributes]

Modified: branches/release/libs/xpressive/doc/tips_n_tricks.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/tips_n_tricks.qbk (original)
+++ branches/release/libs/xpressive/doc/tips_n_tricks.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/tokenization.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/tokenization.qbk (original)
+++ branches/release/libs/xpressive/doc/tokenization.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Added: branches/release/libs/xpressive/doc/tracking_ptr.qbk
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/doc/tracking_ptr.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,172 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / 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)
+ /]
+
+[section Cycle collection with [^tracking_ptr<>]]
+
+In xpressive, regex objects can refer to each other and themselves by value or by reference.
+In addition, they ref-count their referenced regexes to keep them alive. This creates the possibility
+for cyclic reference counts, and raises the possibility of memory leaks. xpressive avoids leaks
+by using a type called `tracking_ptr<>`. This doc describes at a high level how `tracking_ptr<>`
+works.
+
+[h2 Constraints]
+
+Our solution must meet the following design constraints:
+
+* No dangling references: All objects referred to directly or indirectly must be kept alive
+ as long as the references are needed.
+* No leaks: all objects must be freed eventually.
+* No user intervention: The solution must not require users to explicitly invoke some cycle
+ collection routine.
+* Clean-up is no-throw: The collection phase will likely be called from a destructor, so it
+ must never throw an exception under any circumstance.
+
+[h2 Handle-Body Idiom]
+
+To use `tracking_ptr<>`, you must separate your type into a handle and a body. In the case of
+xpressive, the handle type is called `basic_regex<>` and the body is called `regex_impl<>`. The
+handle will store a `tracking_ptr<>` to the body.
+
+The body type must inherit from `enable_reference_tracking<>`. This gives the body the bookkeeping
+data structures that `tracking_ptr<>` will use. In particular, it gives the body:
+
+# `std::set<shared_ptr<body> > refs_` : collection of bodies to which this body refers, and
+# `std::set<weak_ptr<body> > deps_` : collection of bodies which refer to this body.
+
+[h2 References and Dependencies]
+
+We refer to (1) above as the "references" and (2) as the "dependencies". It is crucial to the
+understanding of `tracking_ptr<>` to recognize that the set of references includes both those
+objects that are referred to directly as well as those that are referred to indirectly (that
+is, through another reference). The same is true for the set of dependencies. In other words,
+each body holds a ref-count directly to every other body that it needs.
+
+Why is this important? Because it means that when a body no longer has a handle referring
+to it, all its references can be released immediately without fear of creating dangling references.
+
+References and dependencies cross-pollinate. Here's how it works:
+
+# When one object acquires another as a reference, the second object acquires the first as
+ a dependency.
+# In addition, the first object acquires all of the second object's references, and the second
+ object acquires all of the first object's dependencies.
+# When an object picks up a new reference, the reference is also added to all dependent objects.
+# When an object picks up a new dependency, the dependency is also added to all referenced
+ objects.
+# An object is never allowed to have itself as a dependency. Objects may have themselves as
+ references, and often do.
+
+Consider the following code:
+
+ sregex expr;
+ {
+ sregex group = '(' >> by_ref(expr) >> ')'; // (1)
+ sregex fact = +_d | group; // (2)
+ sregex term = fact >> *(('*' >> fact) | ('/' >> fact)); // (3)
+ expr = term >> *(('+' >> term) | ('-' >> term)); // (4)
+ } // (5)
+
+Here is how the references and dependencies propagate, line by line:
+
+[table
+[[Expression][Effects]]
+[[1) `sregex group = '(' >> by_ref(expr) >> ')';`]
+[[^group: cnt=1 refs={expr} deps={}\n
+expr: cnt=2 refs={} deps={group}]]]
+
+[[2) `sregex fact = +_d | group;`]
+[[^group: cnt=2 refs={expr} deps={fact}\n
+expr: cnt=3 refs={} deps={group,fact}\n
+fact: cnt=1 refs={expr,group} deps={}]]]
+
+[[3) `sregex term = fact >> *(('*' >> fact) | ('/' >> fact));`]
+[[^group: cnt=3 refs={expr} deps={fact,term}\n
+expr: cnt=4 refs={} deps={group,fact,term}\n
+fact: cnt=2 refs={expr,group} deps={term}\n
+term: cnt=1 refs={expr,group,fact} deps={}]]]
+
+[[4) `expr = term >> *(('+' >> term) | ('-' >> term));`]
+[[^group: cnt=5 refs={expr,group,fact,term} deps={expr,fact,term}\n
+expr: cnt=5 refs={expr,group,fact,term} deps={group,fact,term}\n
+fact: cnt=5 refs={expr,group,fact,term} deps={expr,group,term}\n
+term: cnt=5 refs={expr,group,fact,term} deps={expr,group,fact}]]]
+
+[[5) `}`]
+[[^expr: cnt=2 refs={expr,group,fact,term} deps={group,fact,term}]]]
+]
+
+This shows how references and dependencies propagate when creating cycles of objects. After
+line (4), which closes the cycle, every object has a ref-count on every other object, even
+to itself. So how does this not leak? Read on.
+
+[h2 Cycle Breaking]
+
+Now that the bodies have their sets of references and dependencies, the hard part is done.
+All that remains is to decide when and where to break the cycle. That is the job of `tracking_ptr<>`,
+which is part of the handle. The `tracking_ptr<>` holds 2 `shared_ptr`s. The first, obviously,
+is the `shared_ptr<body>` -- the reference to the body to which this handle refers. The other
+`shared_ptr` is used to break the cycle. It ensures that when all the handles to a body go out
+of scope, the body's set of references is cleared.
+
+This suggests that more than one handle can refer to a body. In fact, `tracking_ptr<>` gives
+you copy-on-write semantics -- when you copy a handle, the body is shared. That makes copies
+very efficient. Eventually, all the handles to a particular body go out of scope. When that
+happens, the ref count to the body might still be greater than 0 because some other body (or
+this body itself!) might be holding a reference to it. However, we are certain that the cycle-breaker's
+ref-count goes to 0 because the cycle-breaker only lives in handles. No more handles, no more
+cycle-breakers.
+
+What does the cycle-breaker do? Recall that the body has a set of references of type
+`std::set<shared_ptr<body> >`. Let's call this type "references_type". The cycle-breaker is a
+`shared_ptr<references_type>`. It uses a custom deleter, which is defined as follows:
+
+ template<typename DerivedT>
+ struct reference_deleter
+ {
+ void operator ()(std::set<shared_ptr<DerivedT> > *refs) const
+ {
+ refs->clear();
+ }
+ };
+
+The job of to the cycle breaker is to ensure that when the last handle to a body goes away,
+the body's set of references is cleared. That's it.
+
+We can clearly see how this guarantees that all bodies are cleaned up eventually. Once every
+handle has gone out of scope, all the bodies' sets of references will be cleared, leaving none
+with a non-zero ref-count. No leaks, guaranteed.
+
+It's a bit harder to see how this guarantees no dangling references. Imagine that there are 3
+bodies: A, B and C. A refers to B which refers to C. Now all the handles to B go out of scope,
+so B's set of references is cleared. Doesn't this mean that C gets deleted, even though it
+is being used (indirectly) by A? It doesn't. This situation can never occur because we propagated
+the references and dependencies above such that A will be holding a reference directly to C
+in addition to B. When B's set of references is cleared, no bodies get deleted, because they
+are all still in use by A.
+
+[h2 Future Work]
+
+All these `std::set`s and `shared_ptr`s and `weak_ptr`s! Very inefficient. I used them because
+they were handy. I could probably do better.
+
+Also, some objects stick around longer than they need to. Consider:
+
+ sregex b;
+ {
+ sregex a = _;
+ b = by_ref(a);
+ b = _;
+ }
+ // a is still alive here!
+
+Due to the way references and dependencies are propagated, the `std::set` of references can only
+grow. It never shrinks, even when some references are no longer needed. For xpressive this
+isn't an issue. The graphs of referential objects generally stay small and isolated. If someone
+were to try to use `tracking_ptr<>` as a general ref-count-cycle-collection mechanism, this problem
+would have to be addressed.
+
+[endsect]

Modified: branches/release/libs/xpressive/doc/traits.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/traits.qbk (original)
+++ branches/release/libs/xpressive/doc/traits.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/doc/xpressive.qbk
==============================================================================
--- branches/release/libs/xpressive/doc/xpressive.qbk (original)
+++ branches/release/libs/xpressive/doc/xpressive.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -122,5 +122,11 @@
 
 [include perf.qbk]
 
+[section Appendix 5: Implementation Notes]
+
+[include tracking_ptr.qbk]
+
+[endsect]
+
 [endsect]
 

Modified: branches/release/libs/xpressive/example/numbers.cpp
==============================================================================
--- branches/release/libs/xpressive/example/numbers.cpp (original)
+++ branches/release/libs/xpressive/example/numbers.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
-// main.hpp
+// numbers.cpp
 //
-// Copyright 2007 David Jenkins. Distributed under the Boost
+// Copyright 2008 David Jenkins. 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)
 
@@ -11,7 +11,7 @@
 #endif
 
 #include <iostream>
-#include <string>
+#include <string>
 #include <map>
 #include <boost/assign/list_of.hpp> // for 'map_list_of()'
 #include <boost/xpressive/xpressive.hpp>
@@ -34,20 +34,20 @@
     using namespace boost::assign;
 
     // initialize the maps for named numbers
- std::map< std::string, int > ones_map =
+ std::map< std::string, int > ones_map =
         map_list_of("one",1)("two",2)("three",3)("four",4)("five",5)
         ("six",6)("seven",7)("eight",8)("nine",9);
 
- std::map< std::string, int > teens_map =
+ std::map< std::string, int > teens_map =
         map_list_of("ten",10)("eleven",11)("twelve",12)("thirteen",13)
         ("fourteen",14)("fifteen",15)("sixteen",16)("seventeen",17)
         ("eighteen",18)("nineteen",19);
 
- std::map< std::string, int > tens_map =
+ std::map< std::string, int > tens_map =
         map_list_of("twenty",20)("thirty",30)("fourty",40)
         ("fifty",50)("sixty",60)("seventy",70)("eighty",80)("ninety",90);
 
- std::map< std::string, int > specials_map =
+ std::map< std::string, int > specials_map =
         map_list_of("zero",0)("dozen",12)("score",20);
 
     // n is the integer result
@@ -55,76 +55,70 @@
     // temp stores intermediate values
     local<long> temp(0);
 
- // delimiters between words must be spaces, end-of-sequence, or punctuation
- sregex delim =
- +_s | eos | +punct;
-
     // initialize the regular expressions for named numbers
- sregex ones_rx =
- ( a1 = ones_map ) [ n += a1 ] >> delim;
-
     sregex tens_rx =
- ones_rx
- |
+ // use skip directive to skip whitespace between words
+ skip(_s)
         (
- ( a1 = tens_map ) [ n += a1 ] >> delim
- >> !ones_rx
+ ( a3 = teens_map )
+ |
+ ( a2 = tens_map ) >> !( a1 = ones_map )
+ |
+ ( a1 = ones_map )
         )
- |
- ( ( a1 = teens_map ) [ n += a1 ] >> delim
- );
+ [ n += (a3|0) + (a2|0) + (a1|0) ];
 
     sregex hundreds_rx =
- ( ( tens_rx >> "hundred" >> delim )
- [ n *= 100 ]
- >> !tens_rx
- )
- | tens_rx;
-
- sregex thousands_rx =
- ( ( hundreds_rx >> "thousand" >> delim )
- [ temp += n * 1000, n = 0 ]
- >> !hundreds_rx
+ skip(_s)
+ (
+ tens_rx >>
+ !(
+ as_xpr("hundred") [ n *= 100 ]
+ >> !tens_rx
+ )
         )
- | hundreds_rx
         ;
 
- sregex millions_rx =
- ( ( hundreds_rx >> "million" >> delim )
- [ temp += n * 1000000, n = 0 ]
- >> !thousands_rx
+ sregex specials_rx = // regex for special number names like dozen
+ skip(_s)
+ (
+ // Note: this uses two attribues, a1 and a2, and it uses
+ // a default attribute value of 1 for a1.
+ ( !( a1 = ones_map ) >> ( a2 = specials_map ) )
+ [ n = (a1|1) * a2 ]
+ >> !( "and" >> tens_rx )
         )
- | thousands_rx;
+ ;
 
- // Note: this uses two attribues, a1 and a2, and it uses
- // a default attribute value of 1 for a1.
- sregex specials_rx =
- ( !((a1 = ones_map) >> delim) >> (a2 = specials_map) )
- [ n = (a1 | 1) * a2 ]
- >> delim
- >> !("and" >> +_s >> ones_rx);
-
- sregex number_rx =
- bow
- >>
- ( specials_rx
- |
- millions_rx
- [n += temp, temp = 0 ]
+ sregex number_rx =
+ bow
+ >>
+ skip(_s|punct)
+ (
+ specials_rx // special numbers
+ |
+ ( // normal numbers
+ !( hundreds_rx >> "million" ) [ temp += n * 1000000, n = 0 ]
+ >>
+ !( hundreds_rx >> "thousand" ) [ temp += n * 1000, n = 0 ]
+ >>
+ !hundreds_rx
+ )
+ [n += temp, temp = 0 ]
         );
 
     // this is the input string
     std::string str( "one two three eighteen twenty two "
- "nine hundred ninety nine twelve "
+ "nine hundred ninety nine twelve "
         "eight hundred sixty three thousand ninety five "
         "sixty five hundred ten "
         "two million eight hundred sixty three thousand ninety five "
         "zero sixty five hundred thousand "
- "extra stuff -- skip me "
+ "extra stuff "
         "two dozen "
- "four score and seven ");
+ "four score and seven");
 
- // the results of iterating through the string are:
+ // the MATCHING results of iterating through the string are:
     // one = 1
     // two = 2
     // three = 3
@@ -144,10 +138,20 @@
 
     for( ; cur != end; ++cur )
     {
- std::cout << *cur << " = " << n.get() << '\n';
+ if ((*cur).length() > 0)
+ std::cout << *cur << " = " << n.get() << '\n';
         n.get() = 0;
     }
     std::cout << '\n';
+ // the NON-MATCHING results of iterating through the string are:
+ // extra = unmatched
+ // stuff = unmatched
+ sregex_token_iterator cur2( str.begin(), str.end(), number_rx, -1 );
+ for( ; cur2 != end; ++cur2 )
+ {
+ if ((*cur2).length() > 0)
+ std::cout << *cur2 << " = unmatched" << '\n';
+ }
 }
 
 ///////////////////////////////////////////////////////////////////////////////

Added: branches/release/libs/xpressive/proto/doc/CallableTransform.xml
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/doc/CallableTransform.xml 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,90 @@
+<?xml version="1.0" ?>
+<concept name="CallableTransform" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ 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)
+ -->
+ <param name="Fn" role="polymorphic-function-object-type" />
+ <param name="Tn" role="transform-type" />
+ <param name="Expr" role="expression-type" />
+ <param name="State" role="state-type" />
+ <param name="Visitor" role="visitor-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <conceptname name="PolymorphicFunctionObject"/>.
+ The type <arg num="2" /> must be a model of <conceptname name="Transform"/>.
+ </models-sentence>
+
+ <description>
+ <para>
+ A CallableTransform is a function type or a function
+ pointer type where the return type Fn is a
+ PolymorphicFunctionObject and the arguments are
+ Transforms. is_callable&lt; Fn &gt;::value
+ must be true.
+ </para>
+ </description>
+
+ <notation variables="fn">
+ <sample-value>
+ <type name="Fn" />
+ </sample-value>
+ </notation>
+
+ <notation variables="expr">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ </notation>
+
+ <notation variables="state">
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ </notation>
+
+ <notation variables="visitor">
+ <sample-value>
+ <type name="Visitor" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="boost::result_of">
+ <type name="Fn(Transform&lt;Tn, Expr, State, Visitor&gt;::result_type...)"/>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The result of applying the CallableTransform.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Apply Transform">
+ <apply-function name="when&lt; _, Fn(Tn...)&gt;()">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ <sample-value>
+ <type name="Visitor" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Applies the transform.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="boost::proto::transform::arg(boost::proto::transform::left)" />
+ </example-model>
+
+</concept>

Modified: branches/release/libs/xpressive/proto/doc/Jamfile.v2
==============================================================================
--- branches/release/libs/xpressive/proto/doc/Jamfile.v2 (original)
+++ branches/release/libs/xpressive/proto/doc/Jamfile.v2 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -8,56 +8,55 @@
 
 wave-command = [ path.native ../../../../dist/bin/wave ] ;
 
-## Generate reference section using Doxygen
-#doxygen protodoc
-# :
-# ../../../../boost/xpressive/proto/args.hpp
-# ../../../../boost/xpressive/proto/context.hpp
-# ../../../../boost/xpressive/proto/debug.hpp
-# ../../../../boost/xpressive/proto/deep_copy.hpp
-# ../../../../boost/xpressive/proto/domain.hpp
-# ../../../../boost/xpressive/proto/eval.hpp
-# ../../../../boost/xpressive/proto/expr.hpp
-# ../../../../boost/xpressive/proto/extends.hpp
-# ../../../../boost/xpressive/proto/fusion.hpp
-# ../../../../boost/xpressive/proto/generate.hpp
-# ../../../../boost/xpressive/proto/literal.hpp
-# ../../../../boost/xpressive/proto/make_expr.hpp
-# ../../../../boost/xpressive/proto/matches.hpp
-# ../../../../boost/xpressive/proto/operators.hpp
-# ../../../../boost/xpressive/proto/proto.hpp
-# ../../../../boost/xpressive/proto/proto_fwd.hpp
-## ../../../../boost/xpressive/proto/proto_typeof.hpp
-# ../../../../boost/xpressive/proto/ref.hpp
-# ../../../../boost/xpressive/proto/tags.hpp
-# ../../../../boost/xpressive/proto/traits.hpp
-# ../../../../boost/xpressive/proto/transform.hpp
-# ../../../../boost/xpressive/proto/context/callable.hpp
-# ../../../../boost/xpressive/proto/context/default.hpp
-# ../../../../boost/xpressive/proto/context/null.hpp
-# ../../../../boost/xpressive/proto/transform/arg.hpp
-# ../../../../boost/xpressive/proto/transform/apply.hpp
-# ../../../../boost/xpressive/proto/transform/branch.hpp
-# ../../../../boost/xpressive/proto/transform/compose.hpp
-# ../../../../boost/xpressive/proto/transform/construct.hpp
-# ../../../../boost/xpressive/proto/transform/fold.hpp
-# ../../../../boost/xpressive/proto/transform/fold_tree.hpp
-# ../../../../boost/xpressive/proto/transform/function.hpp
-# ../../../../boost/xpressive/proto/transform/list.hpp
-# ../../../../boost/xpressive/proto/transform/pass_through.hpp
-# :
-# <doxygen:param>EXTRACT_ALL=YES
-# <doxygen:param>HIDE_UNDOC_MEMBERS=NO
-# # Use Boost.Wave to preprocess Proto's source
-# <doxygen:param>"INPUT_FILTER=\"$(wave-command) \\
-# -S ../../../.. \\
-# -S \\\"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\vc7\\include\\\" \\
-# -D _WIN32 \\
-# -D BOOST_PROTO_DOXYGEN_INVOKED \\
-# -p 1 \""
-# # This ensures that Wave is actually built before we try to execute it
-# <dependency>../../../../tools/wave/build release
-# ;
+# Generate reference section using Doxygen
+doxygen protodoc
+ :
+ ../../../../boost/xpressive/proto/args.hpp
+ ../../../../boost/xpressive/proto/context.hpp
+ ../../../../boost/xpressive/proto/debug.hpp
+ ../../../../boost/xpressive/proto/deep_copy.hpp
+ ../../../../boost/xpressive/proto/domain.hpp
+ ../../../../boost/xpressive/proto/eval.hpp
+ ../../../../boost/xpressive/proto/expr.hpp
+ ../../../../boost/xpressive/proto/extends.hpp
+ ../../../../boost/xpressive/proto/fusion.hpp
+ ../../../../boost/xpressive/proto/generate.hpp
+ ../../../../boost/xpressive/proto/literal.hpp
+ ../../../../boost/xpressive/proto/make_expr.hpp
+ ../../../../boost/xpressive/proto/matches.hpp
+ ../../../../boost/xpressive/proto/operators.hpp
+ ../../../../boost/xpressive/proto/proto.hpp
+ ../../../../boost/xpressive/proto/proto_fwd.hpp
+# ../../../../boost/xpressive/proto/proto_typeof.hpp
+ ../../../../boost/xpressive/proto/ref.hpp
+ ../../../../boost/xpressive/proto/tags.hpp
+ ../../../../boost/xpressive/proto/traits.hpp
+ ../../../../boost/xpressive/proto/transform.hpp
+ ../../../../boost/xpressive/proto/context/callable.hpp
+ ../../../../boost/xpressive/proto/context/default.hpp
+ ../../../../boost/xpressive/proto/context/null.hpp
+ ../../../../boost/xpressive/proto/transform/arg.hpp
+ ../../../../boost/xpressive/proto/transform/bind.hpp
+ ../../../../boost/xpressive/proto/transform/call.hpp
+ ../../../../boost/xpressive/proto/transform/fold.hpp
+ ../../../../boost/xpressive/proto/transform/fold_tree.hpp
+ ../../../../boost/xpressive/proto/transform/make.hpp
+ ../../../../boost/xpressive/proto/transform/pass_through.hpp
+ ../../../../boost/xpressive/proto/transform/when.hpp
+ :
+ <doxygen:param>EXTRACT_ALL=YES
+ <doxygen:param>HIDE_UNDOC_MEMBERS=NO
+ # Use Boost.Wave to preprocess Proto's source
+# <doxygen:param>INPUT_FILTER=./wave.sh
+ <doxygen:param>"INPUT_FILTER=\"$(wave-command) \\
+ -S ../../../.. \\
+ -S \\\"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\vc7\\include\\\" \\
+ -D _WIN32 \\
+ -D BOOST_PROTO_DOXYGEN_INVOKED \\
+ -p 1 \""
+ # This ensures that Wave is actually built before we try to execute it
+ <dependency>../../../../tools/wave/build release
+ ;
 
 xml proto
     :
@@ -82,28 +81,29 @@
         # How far down we go with TOC's
         <xsl:param>generate.section.toc.level=10
         # Set the path to the boost-root so we find our graphics:
- #<xsl:param>boost.root=../../../../..
+ #<xsl:param>boost.root=$(BOOST_ROOT)
         # location of the main index file so our links work:
- #<xsl:param>boost.libraries=../../../../../libs/libraries.htm
+ #<xsl:param>boost.libraries=$(BOOST_ROOT)/libs/libraries.htm
 
         # PDF Options:
         # TOC Generation: this is needed for FOP-0.9 and later:
         # <xsl:param>fop1.extensions=1
- <xsl:param>xep.extensions=1
+ <format>pdf:<xsl:param>fop1.extensions=0
+ <format>pdf:<xsl:param>xep.extensions=1
         # TOC generation: this is needed for FOP 0.2, but must not be set to zero for FOP-0.9!
- <xsl:param>fop.extensions=0
+ <format>pdf:<xsl:param>fop.extensions=0
         # No indent on body text:
- <xsl:param>body.start.indent=0pt
+ <format>pdf:<xsl:param>body.start.indent=0pt
         # Margin size:
- <xsl:param>page.margin.inner=0.5in
+ <format>pdf:<xsl:param>page.margin.inner=0.5in
         # Margin size:
- <xsl:param>page.margin.outer=0.5in
+ <format>pdf:<xsl:param>page.margin.outer=0.5in
         # Yes, we want graphics for admonishments:
- <xsl:param>admon.graphics=1
+ <format>pdf:<xsl:param>admon.graphics=1
         # Set this one for PDF generation *only*:
- # default pnd graphics are awful in PDF form,
+ # default png graphics are awful in PDF form,
         # better use SVG's instead:
- # <xsl:param>admon.graphics.extension=".svg"
+ # <format>pdf:<xsl:param>admon.graphics.extension=".svg"
 
 # <dependency>protodoc
     ;

Modified: branches/release/libs/xpressive/proto/doc/acknowledgements.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/acknowledgements.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/acknowledgements.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/proto/doc/calculator.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/calculator.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/calculator.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -19,7 +19,7 @@
 [heading Defining Terminals]
 
 The first order of business is to define the placeholders `_1` and `_2`. For
-that, we'll use the _terminal_ expression generator.
+that, we'll use the _terminal_ metafunction.
 
     // Define some placeholder types
     struct placeholder1 {};
@@ -138,7 +138,7 @@
 You might notice that the `calculator_context` has a lot of boilerplate. It
 is fairly common for addition nodes to be handled by evaluating the left and
 right children and then adding the result, for instance. For this purpose,
-proto provides the _default_context_, which gives the operators their usual
+Boost.Proto provides the _default_context_, which gives the operators their usual
 meanings, and uses Boost.Typeof to deduce return types. In fact, the
 _callable_context_ from which our `calculator_context` inherits uses
 _default_context_ as a fall-back for any expression types you don't handle

Added: branches/release/libs/xpressive/proto/doc/concepts/PolymorphicFunctionObject.xml
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/doc/concepts/PolymorphicFunctionObject.xml 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,66 @@
+<?xml version="1.0" ?>
+<concept name="PolymorphicFunctionObject" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ 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)
+ -->
+ <param name="Fn" role="polymorphic-function-object-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <self/>.
+ </models-sentence>
+
+ <description>
+ <para>
+ A type that can be called and that follows the TR1 ResultOf
+ protocol for return type calculation.
+ </para>
+ </description>
+
+ <notation variables="fn">
+ <sample-value>
+ <type name="Fn" />
+ </sample-value>
+ </notation>
+
+ <notation variables="a0,...an">
+ <sample-value>
+ <type name="A0,...An" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="result_of">
+ <apply-function name="Fn">
+ <type name="A0,...An" />
+ </apply-function>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The result of calling the Polymorphic Function Object.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Function Call">
+ <apply-function name="fn">
+ <sample-value>
+ <type name="A0,...An" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Calls the function object.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="std::plus&lt;int&gt;" />
+ </example-model>
+
+</concept>

Added: branches/release/libs/xpressive/proto/doc/concepts/PrimitiveTransform.xml
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/doc/concepts/PrimitiveTransform.xml 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,90 @@
+<?xml version="1.0" ?>
+<concept name="PrimitiveTransform" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ 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)
+ -->
+ <param name="Fn" role="primitive-transform-type" />
+ <param name="Expr" role="expression-type" />
+ <param name="State" role="state-type" />
+ <param name="Visitor" role="visitor-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <self/>.
+ </models-sentence>
+
+ <description>
+ <para>A PrimitiveTransform is class type that
+ has an overloaded function call operator and
+ uses a narrow subset of the TR1.ResultOf protocol
+ for return type calculation. It takes three
+ parameters: expression, state and visitor.</para>
+ </description>
+
+ <notation variables="fn">
+ <sample-value>
+ <type name="Fn" />
+ </sample-value>
+ </notation>
+
+ <notation variables="expr">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ </notation>
+
+ <notation variables="state">
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ </notation>
+
+ <notation variables="visitor">
+ <sample-value>
+ <type name="Visitor" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="typename Fn::template result">
+ <apply-function name="Fn">
+ <type name="Expr"/>
+ <type name="State"/>
+ <type name="Visitor"/>
+ </apply-function>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The return type of the overloaded function call operator.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Function Call">
+ <apply-function name="fn">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ <sample-value>
+ <type name="Visitor" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Applies the transform.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="boost::proto::transform::arg_c&lt; 0 &gt;" />
+ </example-model>
+
+</concept>

Added: branches/release/libs/xpressive/proto/doc/concepts/Transform.xml
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/doc/concepts/Transform.xml 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,79 @@
+<?xml version="1.0" ?>
+<concept name="Transform" category="utility">
+ <!--
+ Copyright 2008 Eric Niebler
+
+ 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)
+ -->
+ <param name="Tn" role="transform-type" />
+ <param name="Expr" role="expression-type" />
+ <param name="State" role="state-type" />
+ <param name="Visitor" role="visitor-type" />
+
+ <models-sentence>
+ The type <arg num="1" /> must be a model of <self/>.
+ </models-sentence>
+
+ <description>
+ <para>
+ A Transform is a PrimitiveTransform, a CallableTransform
+ or an ObjectTransform.
+ </para>
+ </description>
+
+ <notation variables="expr">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ </notation>
+
+ <notation variables="state">
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ </notation>
+
+ <notation variables="visitor">
+ <sample-value>
+ <type name="Visitor" />
+ </sample-value>
+ </notation>
+
+ <associated-type name="result_type">
+ <get-member-type name="type">
+ <apply-template name="boost::result_of">
+ <type name="when&lt; _, Tn &gt;(Expr, State, Visitor)"/>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>The result of applying the Transform.</simpara>
+ </description>
+ </associated-type>
+
+ <valid-expression name="Apply Transform">
+ <apply-function name="when&lt; _, Tn &gt;()">
+ <sample-value>
+ <type name="Expr" />
+ </sample-value>
+ <sample-value>
+ <type name="State" />
+ </sample-value>
+ <sample-value>
+ <type name="Visitor" />
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>Applies the transform.</semantics>
+ </valid-expression>
+
+ <example-model>
+ <type name="boost::proto::transform::arg(boost::proto::transform::left)" />
+ </example-model>
+
+</concept>

Modified: branches/release/libs/xpressive/proto/doc/construction.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/construction.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/construction.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -5,7 +5,11 @@
  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  /]
 
+[def __implelemtation_defined__ [~implementation-defined]]
+
+[/=======================================================================================]
 [section:expression_construction Expression Construction: Building Proto Expression Trees]
+[/=======================================================================================]
 
 We've seen some simple examples of how to use Proto, but we haven't really said
 much about what is going on under the hood. How exactly does Proto build and
@@ -26,7 +30,7 @@
 The _expr_ template is the most important type in Proto. Although you will
 rarely need to deal with it directly, it's always there behind the scenes
 holding your expression trees together. In fact, _expr_ /is/ the expression
-tree -- braches, leaves and all.
+tree -- branches, leaves and all.
 
 The _expr_ template makes up the nodes in expression trees. The first template
 parameter is the node type; in this case, `proto::tag::terminal`. That means
@@ -55,7 +59,9 @@
 is of type `placeholder1`. Note that we use braces to initialize `_1.arg0`
 because `placeholder1` is also an aggregate.
 
+[/====================================================]
 [section:operator_overloads Proto's Operator Overloads]
+[/====================================================]
 
 Once we have some Proto terminals, expressions involving those terminals build
 expression trees for us, as if by magic. It's not magic; Proto defines
@@ -80,7 +86,9 @@
 
 [endsect]
 
+[/=================================================]
 [section:expression_trees Building Expression Trees]
+[/=================================================]
 
 The `_1` node is an _expr_ type, and new nodes created with this type are
 also _expr_ types. They look like this:
@@ -129,13 +137,191 @@
 
 [endsect]
 
+[/==============================================]
 [section:left_right_arg Accessing Children Nodes]
+[/==============================================]
+
+After assembling an expression into a tree, you'll naturally want to be
+able to do the reverse, and access its children.
+You may even want to be able to iterate over the children with algorithms
+from the Boost.Fusion library. This section shows how.
+
+[heading [^tag_of<>]]
+
+A node in an expression tree is nothing more than a collection of children
+nodes and a tag type. You can access the tag type of any Proto expression type
+`Expr` directly as `typename Expr::proto_tag`, or you can use the _tag_of_
+metafunction, as shown below:
+
+ template<typename Expr>
+ typename proto::result_of::tag_of<Expr>::type
+ get_tag_of(Expr const &)
+ {
+ // Tag types are required to be default-constructible
+ return typename proto::result_of::tag_of<Expr>::type();
+ }
+
+ proto::terminal<int>::type const i = {0};
+
+ // Addition nodes have the "plus" tag type:
+ proto::tag::plus plus_tag = get_tag_of( i + 2 );
+
+[heading [^arg_c()]]
+
+Each node in an expression tree corresponds to an operator in an expression,
+and the children correspond to the operands, or arguments of the operator.
+To access them, you can use the _arg_c_ function template, as demonstrated
+below:
+
+ proto::terminal<int>::type i = {0};
+
+ // Get the 0-th operand of an addition operation:
+ proto::terminal<int>::type &ri = proto::arg_c<0>( i + 2 );
+
+ // Assert that we got back what we put in:
+ assert( &i == &ri );
+
+You can use the `result_of::arg_c<>` metafunction to get the type of the Nth
+child of an expression node. The nested `::type` of the `arg_c<>` metafunction
+gives you the type after references and cv-qualifiers have been stripped from
+the child's type.
+
+ template<typename Expr>
+ void test_result_of_arg_c(Expr const &expr)
+ {
+ typedef typename proto::result_of::arg_c<Expr, 0>::type type;
+
+ // ::type is a non-cv qualified, non-reference
+ BOOST_MPL_ASSERT((is_same< type, terminal<int>::type>));
+ }
+
+ // ...
+ terminal<int>::type i = {0};
+ test_result_of_arg_c( i + 2 );
+
+Why does the `arg_c<>` metafunction strip cv-qualifiers and references? The
+reason is one of practicality. Because expression trees are most typically
+built by holding references to temporary objects, lifetime management of these
+children nodes can be problematic. If `arg_c<>::type` were a reference, it
+would be very simple to create dangling references. Avoiding dangling
+references results in tedious and verbose applications of `remove_reference<>`
+and `remove_const<>`. This is especially problematic when building transforms
+that operate on ephemeral constelations of temporary objects. The current
+behavior of the `arg_c<>` metafunction makes it much simpler to write correct
+code.
+
+If you would like to know exactly the type of the Nth argument, including
+references and cv-qualifiers, you can use
+`fusion::result_of::value_at<Expr, N>::type`. This way, you can tell whether
+a child is stored by value or by reference. And if you would like to know
+the exact type that _arg_c_ returns, you can use
+`fusion::result_of::at_c<Expr, N>::type`. It will always be a reference type,
+and its cv-qualification depends on the cv-qualification of `Expr` and
+whether the child is stored by reference or not.
+
+[heading [^arg()], [^left()], and [^right()]]
+
+Most operators in C++ are unary or binary. For that reason, accessing the
+only operand, or the left and right operands, are very common operations. For
+this reason, Proto provides the _arg_, _left_, and _right_ functions. _arg_
+and _left_ are synonomous with `arg_c<0>()`, and _right_ is synonomous with
+`arg_c<1>()`.
+
+There are also `result_of::arg<>`, `result_of::left<>`, and `result_of::right<>`
+metafunctions that merely forward to their `result_of::arg_c<>` counterparts.
+
+[heading Expression Nodes as Fusion Sequences]
+
+Proto expression nodes are valid Fusion random-access sequences of their
+children nodes. That means you can apply Fusion algorithms to them,
+transform them, apply Fusion filters and views to them, and access their
+elements using `fusion::at()`. The things Fusion can do to heterogeneous
+sequences is beyond the scope of this users' guide, but below is a simple
+example. It takes a lazy function invocation like `fun(1,2,3,4)` and uses
+Fusion to print the function arguments in order.
+
+ struct display
+ {
+ template<typename T>
+ void operator()(T const &t) const
+ {
+ std::cout << t << std::endl;
+ }
+ };
+
+ struct fun_t {};
+ terminal<fun_t>::type const fun = {{}};
+
+ // ...
+ fusion::for_each(
+ fusion::transform(
+ // pop_front() removes the "fun" child
+ fusion::pop_front(fun(1,2,3,4))
+ // Extract the ints from the terminal nodes
+ , functional::arg<>()
+ )
+ , display()
+ );
+
+The above invocation of `fusion::for_each()` displays the following:
+
+[pre
+1
+2
+3
+4
+]
 
-// TODO describe tag_of, arg, arg_c, left and right. Maybe also children_of and Fusion.
+[heading Flattening Proto Expression Tress]
+
+Imagine a slight variation of the above example where, instead of iterating
+over the arguments of a lazy function invocation, we would like to iterate
+over the terminals in an addition expression:
+
+ terminal<int>::type const _1 = {1};
+
+ // ERROR: this doesn't work! Why?
+ fusion::for_each(
+ fusion::transform(
+ _1 + 2 + 3 + 4
+ , functional::arg<>()
+ )
+ , display()
+ );
+
+The reason this doesn't work is because the expression `_1 + 2 + 3 + 4` does
+not describe a flat sequence of terminals --- it describes a binary tree. We
+can treat it as a flat sequence of terminals, however, using Proto's _flatten_
+function. _flatten_ returns a view which makes a tree appear as a flat Fusion
+sequence. If the top-most node has a tag type `T`, then the elements of the
+flattened sequence are the children nodes that do *not* have tag type `T`. This
+process is evaluated recursively. So the above can correctly be written as:
+
+ terminal<int>::type const _1 = {1};
+
+ // OK, iterate over a flattened view
+ fusion::for_each(
+ fusion::transform(
+ proto::flatten(_1 + 2 + 3 + 4)
+ , functional::arg<>()
+ )
+ , display()
+ );
+
+The above invocation of `fusion::for_each()` displays the following:
+
+[pre
+1
+2
+3
+4
+]
 
 [endsect]
 
+[/===============================================================]
 [section:tags_and_meta_functions Operator Tags and Meta-Functions]
+[/===============================================================]
 
 The following table lists the overloadable C++ operators, the Proto tag types
 for each, and the name of the Proto meta-function for generating the
@@ -327,9 +513,512 @@
 
 [endsect]
 
+[/===========================================================]
 [section:construction_utils Expression Construction Utilities]
+[/===========================================================]
+
+Proto gives you many other ways of creating expression trees besides the operator
+overloads. These are useful for building nodes with custom tag types that don't
+correspond to any C++ operator. They're also useful when writing tree transforms
+that manipulate the structure of the expression tree, as we'll see.
+
+Below are the tools and a brief description of each.
+
+[variablelist
+[ [_make_expr_]
+ [A function that takes a tag type and children nodes and
+ builds a parent node of the requested type.]]
+[ [_unpack_expr_]
+ [A function that does the same as _make_expr_ except
+ the children nodes are specified as a Fusion sequence.]]
+[ [`BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`]
+ [A macro that generates a number of overloads of a
+ user-specified function template that behaves like
+ _make_expr_.]]
+]
+
+[/====================================================]
+[heading Building Expression Trees With [^make_expr()]]
+[/====================================================]
 
-// TODO describe make_expr, unpack_expr and BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE
+[:[*Synopsys:]]
+
+ namespace proto
+ {
+ namespace result_of
+ {
+ // Metafunction for calculating the return type
+ // of the make_expr() function
+ template<
+ typename Tag
+ , typename DomainOrArg
+ , typename... A
+ >
+ struct make_expr
+ {
+ typedef __implelemtation_defined__ type;
+ };
+ }
+
+ namespace functional
+ {
+ // A callable function object equivalent of the
+ // make_expr() function.
+ template<typename Tag, typename Domain = default_domain>
+ struct make_expr : callable
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename... A>
+ struct result<This(A...)>
+ : result_of::make_expr<Tag, Domain, A...>
+ {};
+
+ template<typename... A>
+ typename result_of::make_expr<Tag, Domain, const A...>::type
+ operator ()(A const &... a) const;
+ };
+ }
+
+ // The make_expr() function
+ template<typename Tag, typename Domain, typename... A>
+ typename result_of::make_expr<Tag, Domain, A...>::type
+ make_expr(A const &... a);
+ }
+
+You can use the _make_expr_ function to build an expression tree node with
+a specified tag type, as follows.
+
+ // Some user-defined tag type
+ struct MyTag {};
+
+ // Construct a node with MyTag tag type, and
+ // two terminals as children.
+ int i = 0;
+ proto::make_expr<MyTag, default_domain>(i, 'a');
+
+You are not required to specify a domain. If you choose not to, `default_domain`
+is assumed. So the above is equivalent to:
+
+ // Construct a node with MyTag tag type, and
+ // two terminals as children.
+ int i = 0;
+ proto::make_expr<MyTag>(i, 'a');
+
+The return type of the above function invocation can be calculated with the
+`result_of::make_expr<>` metafunction.
+
+ // Use result_of::make_expr<> to compute the return type:
+ int i = 0;
+ typedef
+ proto::result_of::make_expr<
+ MyTag
+ , int
+ , char
+ >::type
+ expr_type;
+
+ expr_type expr = proto::make_expr<MyTag>(i, 'a');
+
+ // expr_type is the same as this type:
+ typedef
+ proto::binary_expr<
+ MyTag
+ , proto::terminal<int>::type
+ , proto::terminal<char>::type
+ >::type
+ expr_type2;
+
+ BOOST_MPL_ASSERT((is_same<expr_type2, expr_type>));
+
+Notice that the children, an int and a char, are wrapped in terminal
+nodes and held by value. If you would like an argument to be beld by
+reference in the resulting tree node, you can use `boost::ref()`:
+
+ // One terminal held by reference:
+ int i = 0;
+
+ typedef
+ proto::result_of::make_expr<
+ MyTag
+ , int & // <-- Note reference here
+ , char
+ >::type
+ expr_type;
+
+ expr_type expr = proto::make_expr<MyTag>(boost::ref(i), 'a');
+
+In the return type calculation, we can specify by-ref with
+`int &`, but we need `boost::ref()` in the actual function invocation.
+That's because the _make_expr_ function can't tell from the function
+arguments whether you want to store the arguments by value or by
+reference.
+
+Non-terminals are handled similarly. Given the non-terminal `expr` as
+defined above, we could wrap it in a unary plus node by value or by
+reference as follows:
+
+ // Make "expr" a child node of a new unary plus node, where
+ // "expr" is held by-value:
+ typedef
+ proto::result_of::make_expr<
+ proto::tag::posit
+ , expr_type
+ >::type
+ posit_val_type;
+
+ posit_val_type p1 = proto::make_expr<proto::tag::posit>(expr);
+
+ // Same as above, except "expr" is held by-reference:
+ typedef
+ proto::result_of::make_expr<
+ proto::tag::posit
+ , expr_type & // <-- Note reference here
+ >::type
+ posit_ref_type;
+
+ posit_ref_type p2 = proto::make_expr<proto::tag::posit>(boost::ref(expr));
+
+ // Equivalent to "by-ref" line directly above:
+ posit_ref_type p3 = +expr;
+
+The application of unary `operator+` on the last line is equivalent to
+the by-ref invocation of _make_expr_ because Proto's operator overloads
+always build trees by holding nodes by reference.
+
+If you specify a domain when invoking _make_expr_, then _make_expr_
+will use that domain's generator to wrap the resulting node in a
+domain-specific wrapper. In the example below, expressions within the
+`MyDomain` domain are wrapped in a `MyExpr<>` wrapper.
+
+ template<typename Expr>
+ struct MyExpr;
+
+ struct MyDomain
+ : proto::domain<proto::generator<MyExpr> >
+ {};
+
+ // ...
+
+ // Use result_of::make_expr<> to compute the return type:
+ int i = 0;
+ typedef
+ proto::result_of::make_expr<
+ MyTag
+ , MyDomain // <-- Note second template
+ , int // param can be a domain.
+ , char
+ >::type
+ expr_type;
+
+ // Construct an expression within MyDomain:
+ expr_type expr = proto::make_expr<MyTag, MyDomain>(i, 'a');
+
+ // expr_type is the same as this type:
+ typedef
+ // New node is wrapped in MyExpr<>
+ MyExpr<proto::binary_expr<
+ MyTag
+ // Terminals are also wrapped.
+ , MyExpr<proto::terminal<int>::type>
+ , MyExpr<proto::terminal<char>::type>
+ >::type>
+ expr_type2;
+
+ BOOST_MPL_ASSERT((is_same<expr_type2, expr_type>));
+
+[/======================================================]
+[heading Building Expression Trees With [^unpack_expr()]]
+[/======================================================]
+
+[:[*Synopsys:]]
+
+ namespace proto
+ {
+ namespace result_of
+ {
+ // Metafunction for calculating the return type
+ // of the unpack_expr() function
+ template<
+ typename Tag
+ , typename DomainOrSequence
+ , typename SequenceOrVoid = void
+ >
+ struct unpack_expr
+ {
+ typedef __implelemtation_defined__ type;
+ };
+ }
+
+ namespace functional
+ {
+ // A callable function object equivalent of the
+ // unpack_expr() function.
+ template<typename Tag, typename Domain = default_domain>
+ struct unpack_expr : callable
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename Sequence>
+ struct result<This(Sequence)>
+ : result_of::unpack_expr<Tag, Domain, Sequence>
+ {};
+
+ template<typename Sequence>
+ typename result_of::unpack_expr<Tag, Domain, Sequence>::type
+ operator ()(Sequence const &sequence) const;
+ };
+ }
+
+ // The unpack_expr() function
+ template<typename Tag, typename Domain, typename Sequence>
+ typename result_of::unpack_expr<Tag, Domain, Sequence>::type
+ unpack_expr(Sequence const &sequence);
+ }
+
+Once you understand _make_expr_, understanding _unpack_expr_ is
+simple. It behaves exactly the same way, except that rather than
+passing children individually, you pass the children as a Fusion
+sequence. So for instance, the following are equivalent:
+
+ // Build an expression with make_expr():
+ int i = 0;
+ proto::make_expr<Tag>(i, 'a');
+
+ // Build the same expression with unpack_expr():
+ proto::unpack_expr<Tag>(fusion::make_tuple(i, 'a'));
+
+ // Also the same as the above:
+ fusion::tuple<int, char> args(i, 'a');
+ proto::unpack_expr<Tag>(args);
+
+If you would like the arguments to be stored by reference, you can
+use `boost::ref()`, just as with _make_expr_.
+
+ // Hold one argument by reference:
+ int i = 0;
+ proto::unpack_expr<Tag>(fusion::make_tuple(boost::ref(i), 'a'));
+
+ // Also the same as the above:
+ fusion::tuple<int &, char> args(i, 'a');
+ proto::unpack_expr<Tag>(args);
+
+As with _make_expr_, _unpack_expr_ has a corresponding metafunction
+in the `proto::result_of` namespace for calculating its return type, as
+well as a callable function object form in the `proto::functional`
+namespace.
+
+One last interesting point about _unpack_expr_: Proto expression
+nodes are themselves valid Fusion sequences. Here, for instance, is
+a clever way to use _unpack_expr_ to turn a binary plus node into
+a binary minus node:
+
+ // Use unpack_expr() to turn an addition into a subtraction
+ proto::literal<int> i(8), j(42);
+ proto::unpack_expr<proto::tag::minus>( i + j );
+
+The expression `i + j` creates an expression tree which _unpack_expr_
+interprets as a sequence of its children `i` and `j`. The result is a
+new node with the `tag::minus` tag and `i` and `j` as children.
+
+[/=====================================================]
+[heading Generating Custom Expression Factory Functions]
+[/=====================================================]
+
+[:[*Synopsys:]]
+
+ // Generate BOOST_PROTO_MAX_ARITY overloads of a
+ // function template named NAME within a particular
+ // DOMAIN that generates expressions with a given
+ // TAG and optionally has some arguments bound.
+ #define BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ NAME \
+ , DOMAIN \
+ , TAG \
+ , BOUNDARGS \
+ )
+
+The `proto::functional::make_expr<>` function object makes it very simple
+to create something that behaves like an expression factory function. For
+instance, the following defines a factory named `invert()` that
+"complements" its argument; that is, it builds a new node with type
+`tag::complement` as if Proto's `operator~` had been applied:
+
+ // invert(x) is now a synonym for ~proto::as_expr(x)
+ proto::functional::make_expr<proto::tag::complement> const invert = {};
+
+Such named "operators" are very important for domain-specific embedded
+languages. What's more, when defined as above, the `invert()` factory can
+accept up to `BOOST_PROTO_MAX_ARITY` arguments, although in this case
+that wouldn't be particularly meaningful.
+
+But imagine if you have a custom tag type `foo_tag<>` that is a template.
+You would like to define a `foo()` factory function that itself was a template,
+like this:
+
+ template<typename T, typename A0>
+ typename proto::result_of::make_expr<
+ foo_tag<T>
+ , A0 const &
+ >::type foo(A0 const &a0)
+ {
+ return proto::make_expr<foo_tag<T> >(boost::ref(a0));
+ }
+
+Now, users of your function can invoke it like this: `foo<int>("foo!")`. If
+you want to seamlessly handle up to /N/ argument, you have to write all /N/
+overloads yourself --- `functional::make_expr<>` can't help you. For this
+situation, Proto provides the `BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`
+macro. You can invoke it as follows:
+
+ // Generate overloads of the foo() function template
+ // like the one above
+ BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ foo \
+ , proto::default_domain \
+ , (foo_tag)(typename) \
+ , BOOST_PP_SEQ_NIL \
+ )
+
+The first macro parameter specified the name of the function template, `foo`.
+The second parameter is the domain of the resulting expression. The third
+parameter is the tag type, specified as a Boost.Preprocessor sequence. A
+tag template like `foo_tag<typename>` is represented as a PP sequence like
+`(foo_tag)(typename)`. Had `foo_tag<>` been defined instead as
+`template<typename, int> struct foo_tag`, that would be a PP sequence like
+`(foo_tag)(typename)(int)`.
+
+The last macro parammeter, `BOOST_PP_SEQ_NIL`, is used for specifying any
+additional implicit arguments. There are none in this case, so
+`BOOST_PP_SEQ_NIL` is used to represent an empty sequence.
+
+As another example, consider a DSEL like the Boost Lambda Library, for
+which you might want a function named `construct()` for doing deferred
+construction of objects. You might want users to be able to use it like
+this:
+
+ std::vector<S> buffer;
+
+ // Use a lambda to construct S objects using two
+ // sequences as constructor arguments:
+ std::transform(
+ sequence1.begin()
+ , sequence1.end()
+ , sequence2.begin()
+ , std::back_inserter(buffer)
+ , construct<S>(_1, _2) // From a hypothetical lambda DSEL
+ );
+
+How might the `construct()` function be defined? We would like it to return
+a lazy function invocation that, when evaluated with two arguments, causes
+`S` objects to be constructed. Lazy functions in Proto look like this:
+
+ // The type of a Proto lazy function
+ proto::function<
+ TheFunctionToCall
+ , Argument1
+ , Argument2
+ , ...
+ >::type
+
+In the above, `TheFunctionToCall` might be an ordinary function object, so
+let's define a `construct_helper<>` function object that constructs an object.
+
+ template<typename T>
+ struct construct_helper
+ {
+ typedef T result_type; // for TR1 result_of
+
+ T operator()() const { return T(); }
+
+ template<typename A0>
+ T operator()(A0 const &a0) const { return T(a0); }
+
+ // ... other overloads ...
+ };
+
+With such a function object, we can say `construct_helper<S>()(1, 'a')` to
+immediately construct an `S` object using `1` and `'a'` as constructor
+arguments. We want this to be lazy, so we can wrap `construct_helper<S>` in
+a Proto terminal.
+
+ // A lazy S constructor
+ terminal<construct_helper<S> >::type const construct_S = {{}};
+
+ // OK, make a lazy function invocation but don't call it.
+ construct_S(1, 'a');
+
+ // Calls the lazy function and constructs an S
+ proto::default_context ctx;
+ S s = proto::eval( construct_S(1, 'a'), ctx );
+
+We're closer, but this is not the syntax we want. Recall that we want
+users to create objects lazily with `construct<S>(_1, _2)`. We can
+get that syntax with the following:
+
+ // Define the construct() function template that
+ // constructs an object lazily.
+ template<typename T, typename A0, typename A1>
+ typename proto::result_of::make_expr<
+ proto::tag::function
+ , construct_helper<T> const
+ , A0 const &
+ , A1 const &
+ >::type const
+ construct(A0 const &a0, A1 const &a1)
+ {
+ return proto::make_expr<proto::tag::function>(
+ construct_helper<T>()
+ , boost::ref(a0)
+ , boost::ref(a1)
+ );
+ }
+
+Now users can say `construct<S>(_1, _2)` and get the lazy object
+construction they want. (Making it work with `std::transform()`
+takes a little more effort, but that's covered in the
+[link boost_proto.users_guide.examples.lambda Lambda] example.)
+Now we need /N/ overloads to handle up to /N/ arguments. That's a lot
+of boiler plate, so we can use the `BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()`
+macro to simplify our job.
+
+ // Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
+ // construct function template like the one defined above.
+ BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ construct \
+ , MyLambdaDomain \
+ , (proto::tag::function) \
+ , ((construct_helper)(typename)) \
+ )
+
+What is new in this case is the fourth macro argument, which specifies
+that there is an implicit first argument to `construct()` of type
+`construct_helper<X>`, where `X` is a template parameter of the function.
+The fourth argument to the macro is actually a PP sequence of PP
+sequences. Each sequence describes one implicit argument.
+
+To see `BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE()` and `construct()` in
+action, please check out the
+[link boost_proto.users_guide.examples.lambda Lambda] example.
+
+[blurb [*Ugly Macros]
+
+You may find this use of the preprocessor distasteful and decide to
+write out the overloads yourself. That's fine, but there are some good
+reasons to consider the macro.
+
+1) You may not be able to anticipate the maximum number of arguments
+ your users will require. If users decide to increase
+ `BOOST_PROTO_MAX_ARITY`, the macro will automatically generate
+ the additional overloads for you.
+
+2) On compilers that support variadic templates, you'd rather this
+ generated just one variadic function instead of /N/ overloads,
+ but you'd like your code to be portable to compilers that don't
+ support variadic templates. This is possible if you use the macro,
+ but not otherwise. (Proto doesn't yet support variadic templates
+ but it will in the future.)
+]
 
 [endsect]
 

Modified: branches/release/libs/xpressive/proto/doc/evaluation.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/evaluation.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/evaluation.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -7,35 +7,550 @@
 
 [section:expression_evaluation Expression Evaluation: Imparting Behaviors Within A Context]
 
+Once you have constructed a Proto expression tree, either by using Proto's
+operator overloads or with _make_expr_ and friends, you probably want to
+actually /do/ something with it. The simplest option is to use `proto::eval()`,
+a generic expression evaluator. To use _eval_, you'll need to define a
+/context/ that tells _eval_ how each node should be evaluated. This section
+goes through the nuts and bolts of using _eval_, defining evaluation contexts,
+and using the contexts that Proto provides.
+
+[note `proto::eval()` is a less powerful but easier-to-use evaluation technique
+than Proto transforms, which are covered later. Although very powerful,
+transforms have a steep learning curve and can be more difficult to debug.
+`proto::eval()` is a rather weak tree traversal algorithm. Dan Marsden has
+been working on a more general and powerful tree traversal library. When it is
+ready, I anticipate that it will eliminate the need for `proto::eval()`.]
+
+[/================================================================]
 [section:proto_eval Evaluating An Expression with [^proto::eval()]]
+[/================================================================]
+
+[:[*Synopsis:]]
 
-TODO
+ namespace proto
+ {
+ namespace result_of
+ {
+ // A metafunction for calculating the return
+ // type of proto::eval() given certain Expr
+ // and Context types.
+ template<typename Expr, typename Context>
+ struct eval
+ {
+ typedef
+ typename Context::template eval<Expr>::result_type
+ type;
+ };
+ }
+
+ namespace functional
+ {
+ // A callable function object type for evaluating
+ // a Proto expression with a certain context.
+ struct eval : callable
+ {
+ template<typename Sig>
+ struct result;
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr, Context &context) const;
+
+ template<typename Expr, typename Context>
+ typename proto::result_of::eval<Expr, Context>::type
+ operator ()(Expr &expr, Context const &context) const;
+ };
+ }
+
+ functional::eval const eval = {};
+ }
+
+Given an expression and an evaluation context, using _eval_ is quite simple.
+Simply pass the expression and the context to _eval_ and it does the rest and
+returns the result. You can use the `eval<>` metafunction in the
+`proto::result_of` namespace to compute the return type of _eval_. The
+following demonstrates a use of _eval_:
+
+ template<typename Expr>
+ typename proto::result_of::eval<Expr const, MyContext>::type
+ MyEvaluate(Expr const &expr)
+ {
+ // Some user-defined context type
+ MyContext ctx;
+
+ // Evaluate an expression with the context
+ return proto::eval(expr, ctx);
+ }
+
+What _eval_ does is also very simple. It defers most of the work to the
+context itself. Here essentially is the implementation of _eval_:
+
+ // eval() dispatches to a nested "eval<>" function
+ // object within the Context:
+ template<typename Expr, typename Context>
+ typename Context::template eval<Expr>::result_type
+ eval(Expr &expr, Context &ctx)
+ {
+ typename Context::template eval<Expr> eval_fun;
+ return eval_fun(expr, ctx);
+ }
+
+Really, _eval_ is nothing more than a thin wrapper that dispatches to the
+appropriate handler within the context class. In the next section, we'll see
+how to implement a context class from scratch.
 
 [endsect]
 
+[/==============================================]
 [section:contexts Defining an Evaluation Context]
+[/==============================================]
 
-TODO
+As we saw in the previous section, there is really not much to the _eval_
+function. Rather, all the interesting expression evaluation goes on within
+a context class. This sections shows how to implement one from scratch.
+
+All context classes have roughly the following form:
+
+ // A prototypical user-defined context.
+ struct MyContext
+ {
+ // A nested eval<> class template
+ template<
+ typename Expr
+ , typename Tag = typename Expr::proto_tag
+ >
+ struct eval;
+
+ // Handle terminal nodes here...
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal>
+ {
+ // Must have a nested result_type typedef.
+ typedef ... result_type;
+
+ // Must have a function call operator that takes
+ // an expression and the context.
+ result_type operator()(Expr &expr, MyContext &ctx) const
+ {
+ return ...;
+ }
+ };
+
+ // ... other specializations of struct eval<> ...
+ };
+
+Context classes are nothing more than a collection of specializations of a
+nested `eval<>` class template. Each specialization handles a different
+expression type.
+
+In the [link boost_proto.users_guide.hello_calculator Hello Calculator]
+section, we saw an example of a user-defined context class for evaluating
+calculator expressions. That context class was implemented with the help
+of Proto's _callable_context_. If we were to implement it from scratch, it
+would look something like this:
+
+ // The calculator_contest from the "Hello Calculator" section,
+ // implemented from scratch.
+ struct calculator_context
+ {
+ // The values for the _1 and _2 placeholders are
+ // passed to the calculator_context constructor.
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ template<
+ typename Expr
+ // defaulted template parameters, so we can
+ // specialize on the expressions that need
+ // special handling.
+ , typename Tag = typename tag_of<Expr>::type
+ , typename Arg0 = typename arg_c<Expr, 0>::type
+ >
+ struct eval;
+
+ // Handle placeholder1 terminals here...
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal, placeholder1>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &, MyContext &ctx) const
+ {
+ // replaces _1 with the value in ctx.d1_
+ return ctx.d1_;
+ }
+ };
+
+ // Handle placeholder2 terminals here...
+ template<typename Expr>
+ struct eval<Expr, proto::tag::terminal, placeholder2>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &, MyContext &ctx) const
+ {
+ // replaces _1 with the value in ctx.d2_
+ return ctx.d2_;
+ }
+ };
+
+ // Handle other terminals here...
+ template<typename Expr, typename Arg0>
+ struct eval<Expr, proto::tag::terminal, Arg0>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &expr, MyContext &) const
+ {
+ return proto::arg(expr);
+ }
+ };
+
+ // Handle addition here...
+ template<typename Expr, typename Arg0>
+ struct eval<Expr, proto::tag::plus, Arg0>
+ {
+ typedef double result_type;
+
+ result_type operator()(Expr &expr, MyContext &ctx) const
+ {
+ return proto::eval(proto::left(expr), ctx)
+ + proto::eval(proto::right(expr), ctx);
+ }
+ };
+
+ // ... other eval<> specializations for other node types ...
+
+ double d1_, d2_;
+ };
+
+Now we can use _eval_ with the context class above to evaluate calculator
+expressions as follows:
+
+ // Evaluate an expression with a calculator_context
+ double d = proto::eval(_1 + _2, calculator_context(5, 6));
+ assert(11 == d);
+
+Defining a context from scratch this way is tedious and verbose, but it gives
+you complete control over how the expression is evaluated. The context class in
+the [link boost_proto.users_guide.hello_calculator Hello Calculator] example
+was much simpler. In the next section we'll see the helper class Proto provides
+to ease the job of implementing context classes.
 
 [endsect]
 
+[/======================================]
 [section:canned_contexts Canned Contexts]
+[/======================================]
+
+Proto provides some ready-made context classes that you can use as-is, or that
+you can use to help while implementing your own contexts. They are:
 
+[variablelist
+ [ [[link boost_proto.users_guide.expression_evaluation.canned_contexts.default_context [^default_context]]]
+ [An evaluation context that assigns the usual C++ meanings to all the
+ operators. For example, addition nodes are handled by evaluating the
+ left and right children and then adding the results. The _default_context_
+ uses Boost.Typeof to deduce the types of the expressions it evaluates.] ]
+ [ [[link boost_proto.users_guide.expression_evaluation.canned_contexts.null_context [^null_context]]]
+ [A simple context that recursively evaluates children but does not combine
+ the results in any way and returns void.] ]
+ [ [[link boost_proto.users_guide.expression_evaluation.canned_contexts.callable_context [^callable_context<>]]]
+ [A helper that simplifies the job of writing context classes. Rather than
+ writing template specializations, with _callable_context_ you write a
+ function object with an overloaded function call operator. Any expressions
+ not handled by an overload are automatically dispatched to a default
+ evaluation context that you can specify.] ]
+]
+
+[/=========================================]
 [section:default_context [^default_context]]
+[/=========================================]
 
-TODO
+The _default_context_ is an evaluation context that assigns the usual C++
+meanings to all the operators. For example, addition nodes are handled by
+evaluating the left and right children and then adding the results. The
+_default_context_ uses Boost.Typeof to deduce the types of the expressions it
+evaluates.
+
+For example, consider the following "Hello World" example:
+
+ #include <iostream>
+ #include <boost/xpressive/proto/proto.hpp>
+ #include <boost/xpressive/proto/context.hpp>
+ #include <boost/typeof/std/ostream.hpp>
+ using namespace boost;
+
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ // Evaluate the expression with default_context,
+ // to give the operators their C++ meanings:
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+ }
+
+ int main()
+ {
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+ }
+
+This program outputs the following:
+
+[pre
+hello, world
+]
+
+_default_context_ is trivially defined in terms of a `default_eval<>`
+template, as follows:
+
+ // Definition of default_context
+ struct default_context
+ {
+ template<typename Expr>
+ struct eval
+ : default_eval<Expr, default_context const, typename Expr::proto_tag>
+ {};
+ };
+
+There are a bunch of `default_eval<>` specializations, each of which handles
+a different C++ operator. Here, for instance, is the specialization for binary
+addition:
+
+ // A default expression evaluator for binary addition
+ template<typename Expr, typename Context>
+ struct default_eval<Expr, Context, proto::tag::plus>
+ {
+ private:
+ static Expr & s_expr;
+ static Context & s_ctx;
+
+ public:
+ typedef
+ decltype(
+ proto::eval(proto::arg_c<0>(s_expr), s_ctx)
+ + proto::eval(proto::arg_c<1>(s_expr), s_ctx)
+ )
+ result_type;
+
+ result_type operator ()(Expr &expr, Context &ctx) const
+ {
+ return proto::eval(proto::arg_c<0>(expr), ctx)
+ + proto::eval(proto::arg_c<1>(expr), ctx);
+ }
+ };
+
+The above code uses `decltype` to calculate the return type of the function
+call operator. `decltype` is a new keyword in the next version of C++ that gets
+the type of any expression. Most compilers do not yet support `decltype`
+directly, so `default_eval<>` uses the Boost.Typeof library to emulate it. On
+some compilers, that may mean that `default_context` either doesn't work or
+that it requires you to register your types with the Boost.Typeof library.
+Check the documentation for Boost.Typeof to see.
 
 [endsect]
 
+[/===================================]
 [section:null_context [^null_context]]
+[/===================================]
+
+The _null_context_ is a simple context that recursively evaluates children
+but does not combine the results in any way and returns void. It is useful
+in conjunction with `callable_context<>`, or when defining your own contexts
+which mutate an expression tree in-place rather than accumulate a result, as
+we'll see below.
+
+_null_context_ is trivially implemented in terms of `null_eval<>` as follows:
+
+ // Definition of null_context
+ struct null_context
+ {
+ template<typename Expr>
+ struct eval
+ : null_eval<Expr, null_context const, Expr::proto_arity::value>
+ {};
+ };
+
+And `null_eval<>` is also trivially implemented. Here, for instance is
+a binary `null_eval<>`:
+
+ // Binary null_eval<>
+ template<typename Expr, typename Context>
+ struct null_eval<Expr, Context, 2>
+ {
+ typedef void result_type;
+
+ void operator()(Expr &expr, Context &ctx) const
+ {
+ proto::eval(proto::arg_c<0>(expr), ctx);
+ proto::eval(proto::arg_c<1>(expr), ctx);
+ }
+ };
+
+When would such classes be useful? Imagine you have an expression tree with
+integer terminals, and you would like to increment each integer in-place. You
+might define an evaluation context as follows:
+
+ struct increment_ints
+ {
+ // By default, just evaluate all children by defering
+ // to the null_eval<>
+ template<typename Expr, typename Arg = proto::result_of::arg<Expr>::type>
+ struct eval
+ : null_eval<Expr, increment_ints const>
+ {};
+
+ // Increment integer terminals
+ template<typename Expr>
+ struct eval<Expr, int>
+ {
+ typedef void result_type;
+
+ void operator()(Expr &expr, increment_ints const &) const
+ {
+ ++proto::arg(expr);
+ }
+ };
+ };
 
-TODO
+In the next section on _callable_context_, we'll see an even simpler way to
+achieve the same thing.
 
 [endsect]
 
+[/=============================================]
 [section:callable_context [^callable_context<>]]
+[/=============================================]
 
-TODO
+The _callable_context_ is a helper that simplifies the job of writing context
+classes. Rather than writing template specializations, with _callable_context_
+you write a function object with an overloaded function call operator. Any
+expressions not handled by an overload are automatically dispatched to a
+default evaluation context that you can specify.
+
+Rather than an evaluation context in its own right, _callable_context_ is more
+properly thought of as a context adaptor. To use it, you must define your own
+context that inherits from _callable_context_.
+
+In the [link boost_proto.users_guide.expression_evaluation.canned_contexts.null_context [^null_context]]
+section, we saw how to implement an evaluation context that increments all the
+integers within an expression tree. Here is how to do the same thing with the
+_callable_context_:
+
+ // An evaluation context that increments all
+ // integer terminals in-place.
+ struct increment_ints
+ : callable_context<
+ increment_ints const // derived context
+ , null_context const // fall-back context
+ >
+ {
+ typedef void result_type;
+
+ // Handle int terminals here:
+ void operator()(proto::tag::terminal, int &i) const
+ {
+ ++i;
+ }
+ };
+
+With such a context, we can do the following:
+
+ literal<int> i = 0, j = 10;
+ proto::eval( i - j * 3.14, increment_ints() );
+
+ std::cout << "i = " << i.get() << std::endl;
+ std::cout << "j = " << j.get() << std::endl;
+
+This program outputs the following, which shows that the integers `i` and `j`
+have been incremented by `1`:
+
+[pre
+i = 1
+j = 11
+]
+
+In the `increment_ints` context, we didn't have to define any nested `eval<>`
+templates. That's because _callable_context_ implements them for us.
+_callable_context_ takes two template parameters: the derived context and a
+fall-back context. For each node in the expression tree being evaluated,
+_callable_context_ checks to see if there is an overloaded `operator()` in the
+derived context that accepts it. Given some expression `expr` of type `Expr`,
+and a context `ctx`, it attempts to call:
+
+ ctx(
+ typename Expr::proto_tag()
+ , proto::arg_c<0>(expr)
+ , proto::arg_c<1>(expr)
+ ...
+ );
+
+Using function overloading and metaprogramming tricks, _callable_context_ can
+detect at compile-time whether such a function exists or not. If so, that
+function is called. If not, the current expression is passed to the fall-back
+evaluation context to be processed.
+
+We saw another example of the _callable_context_ when we looked at the simple
+calculator expression evaluator. There, we wanted to customize the evaluation
+of placeholder terminals, and delegate the handling of all other nodes to the
+_default_context_. We did that as follows:
+
+ // An evaluation context for calculator expressions that
+ // explicitly handles placeholder terminals, but defers the
+ // processing of all other nodes to the default_context.
+ struct calculator_context
+ : proto::callable_context< calculator_context const >
+ {
+ calculator_context(double d1, double d2)
+ : d1_(d1), d2_(d2)
+ {}
+
+ // Define the result type of the calculator.
+ typedef double result_type;
+
+ // Handle the placeholders:
+ double operator()(proto::tag::terminal, placeholder1) const
+ {
+ return this->d1_;
+ }
+
+ double operator()(proto::tag::terminal, placeholder2) const
+ {
+ return this->d2_;
+ }
+
+ private:
+ double d1_, d2_;
+ };
+
+In this case, we didn't specify a fall-back context. In that case,
+_callable_context_ uses the _default_context_. With the above
+`calculator_context` and a couple of appropriately defined placeholder
+terminals, we can evaluate calculator expressions, as demonstrated
+below:
+
+ struct placeholder1 {};
+ struct placeholder2 {};
+ terminal<placeholder1>::type const _1 = {{}};
+ terminal<placeholder2>::type const _2 = {{}};
+ // ...
+
+ double j = proto::eval(
+ (_2 - _1) / _2 * 100
+ , calculator_context(4, 5)
+ );
+ std::cout << "j = " << j << std::endl;
+
+The above code displays the following:
+
+[pre
+j = 20
+]
 
 [endsect]
 

Modified: branches/release/libs/xpressive/proto/doc/examples.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/examples.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/examples.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -15,71 +15,178 @@
 [import ../example/tarray.cpp]
 [import ../example/vec3.cpp]
 [import ../example/vector.cpp]
+[import ../example/map_assign.cpp]
+[import ../example/futures.cpp]
+[import ../example/lambda.cpp]
 
+[/===============]
 [section Examples]
+[/===============]
 
-[section Hello World]
+A code example is worth a thousand words ...
 
-blah blah blah
+[/=================================================================================]
+[section:hello_world Hello World: Building An Expression Template and Evaluating It]
+[/=================================================================================]
 
-[HelloWorld]
+A trivial example which builds and expression template
+and evaluates it.
 
-blah blah blah
+[HelloWorld]
 
 [endsect]
 
-[section Calc1]
+[/==================================================]
+[section:calc1 Calc1: Defining An Evaluation Context]
+[/==================================================]
+
+A simple example which builds a miniature domain-specific
+embedded language for lazy arithmetic expressions, with
+TR1 bind-style argument placeholders.
 
 [Calc1]
 
 [endsect]
 
-[section Calc2]
+[/============================================================]
+[section:calc2 Calc2: Adding Members Using [^proto::extends<>]]
+[/============================================================]
+
+An extension of the Calc1 example that uses _extends_ to
+make calculator expressions valid function objects that
+can be used with STL algorithms.
 
 [Calc2]
 
 [endsect]
 
-[section Calc3]
+[/===============================================]
+[section:calc3 Calc3: Defining A Simple Transform]
+[/===============================================]
+
+An extension of the Calc2 example that uses a Proto transform
+to calculate the arity of a calculator expression and statically
+assert that the correct number of argument are passed.
 
 [Calc3]
 
 [endsect]
 
-[section Lazy Vector]
+[/==============================================================]
+[section:lazy_vector Lazy Vector: Controlling Operator Overloads]
+[/==============================================================]
+
+This example constructs a mini-library for linear algebra, using
+expression templates to eliminate the need for temporaries when
+adding vectors of numbers.
+
+This example uses a domain with a grammar to prune the set
+of overloaded operators. Only those operators that produce
+valid lazy vector expressions are allowed.
 
 [LazyVector]
 
 [endsect]
 
-[section RGB]
+[/========================================================]
+[section:rgb RGB: Type Manipulations With Proto Transforms]
+[/========================================================]
+
+This is a simple example of doing arbitrary type manipulations with Proto
+transforms. It takes some expression involving primiary colors and combines
+the colors according to arbitrary rules. It is a port of the RGB example
+from _PETE_.
 
 [RGB]
 
 [endsect]
 
-[section TArray]
+[/=====================================================]
+[section:tarray TArray: A Simple Linear Algebra Library]
+[/=====================================================]
+
+This example constructs a mini-library for linear algebra, using
+expression templates to eliminate the need for temporaries when
+adding arrays of numbers. It duplicates the TArray example from
+_PETE_.
 
 [TArray]
 
 [endsect]
 
-[section Vec3]
+[/========================================================]
+[section:vec3 Vec3: Computing With Transforms And Contexts]
+[/========================================================]
+
+This is a simple example using `proto::extends<>` to extend a terminal type
+with additional behaviors, and using custom contexts and `proto::eval()` for
+evaluating expressions. It is a port of the Vec3 example from
+_PETE_.
 
 [Vec3]
 
 [endsect]
 
-[section Vector]
+[/========================================================]
+[section:vector Vector: Adapting A Non-Proto Terminal Type]
+[/========================================================]
+
+This is an example of using `BOOST_PROTO_DEFINE_OPERATORS()` to Proto-ify
+expressions using `std::vector<>`, a non-Proto type. It is a port of the
+Vector example from _PETE_.
 
 [Vector]
 
 [endsect]
 
-[section Mixed]
+[/=============================================================]
+[section:mixed Mixed: Adapting Several Non-Proto Terminal Types]
+[/=============================================================]
+
+This is an example of using `BOOST_PROTO_DEFINE_OPERATORS()` to Proto-ify
+expressions using `std::vector<>` and `std::list<>`, non-Proto types. It is a
+port of the Mixed example from _PETE_.
 
 [Mixed]
 
 [endsect]
 
+[/=======================================================]
+[section:map_assign Map Assign: An Intermediate Transform]
+[/=======================================================]
+
+A demonstration of how to implement `map_list_of()` from the Boost.Assign
+library using Proto. `map_list_assign()` is used to conveniently initialize a
+`std::map<>`. By using Proto, we can avoid any dynamic allocation while
+building the intermediate representation.
+
+[MapAssign]
+
+[endsect]
+
+[/===========================================================]
+[section:future_group Future Group: A More Advanced Transform]
+[/===========================================================]
+
+An advanced example of a Proto transform that implements
+Howard Hinnant's design for /future groups/ that block
+for all or some asynchronous operations to complete and
+returns their results in a tuple of the appropriate type.
+
+[FutureGroup]
+
+[endsect]
+
+[/========================================================]
+[section:lambda Lambda: A Simple Lambda Library with Proto]
+[/========================================================]
+
+This is an advanced example that shows how to implement a simple
+lambda DSEL with Proto, like the Boost.Lambda_library. It uses
+contexts, transforms and expression extension.
+
+[Lambda]
+
+[endsect]
+
 [endsect]

Modified: branches/release/libs/xpressive/proto/doc/extensibility.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/extensibility.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/extensibility.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/proto/doc/grammars.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/grammars.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/grammars.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -268,8 +268,9 @@
 and logically negates it; `not_<Grammar>` will match any expression that
 `Grammar` does /not/ match.
 
-The _if_ template is used together with an MPL lambda expression, which is
-evaluated against expression types to find matches.
+The _if_ template is used together with a Proto transform that is evaluated
+against expression types to find matches. (Proto transforms will be described
+later.)
 
 The _and_ template is like _or_, except that each argument of the _and_ must
 match in order for the _and_ to match. As an example, consider the definition
@@ -279,34 +280,19 @@
     struct CharString
       : and_<
             terminal< _ >
- , if_< is_same< result_of::arg< mpl::_ >, char const * > >
+ , if_< is_same< _arg, char const * >() >
>
     {};
 
 This says that a `CharString` must be a terminal, /and/ its argument must be
 the same as `char const *`. Notice the template argument of _if_:
-`is_same< result_of::arg< mpl::_ >, char const * >`. This is an MPL lambda
-expression because it has the MPL placeholder `mpl::_` in it.
-
-[warning Do not confuse `mpl::_` with `proto::_`. The first is only useful in
-MPL lambda expressions. The second is Proto's grammar wildcard. The only place
-`mpl::_` should appear in your grammars is in an _if_, or in tranform::applyN<>,
-as we'll see later. Elsewhere in your grammars you should be using `proto::_`.]
+`is_same< _arg, char const * >()`. This is Proto transform that compares the
+argument of a terminal to `char const *`.
 
 The _if_ template has a couple of variants. In additon to `if_<Condition>` you
 can also say `if_<Condition, ThenGrammar>` and
 `if_<Condition, ThenGrammar, ElseGrammar>`. These let you select one sub-grammar
-or another based on the `Condition`. The following table shows their
-equivalencies:
-
-[table If-Then-Else Equivalencies
-[[Short-Cut Grammar][Equivalent Grammar]]
-[[`if_<Condition, ThenGrammar>`][`and_<if_<Condition>, ThenGrammar>`]]
-[[`if_<Condition, ThenGrammar, ElseGrammar>`][``or_<
- and_<if_<Condition>, ThenGrammar>
- , and_<not_<if_<Condition> >, ElseGrammar>
->``]]
-]
+or another based on the `Condition`.
 
 [endsect]
 

Modified: branches/release/libs/xpressive/proto/doc/history.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/history.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/history.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -9,6 +9,11 @@
 
 [variablelist
 [
+ [January 11, 2008]
+ [Boost.Proto v3 brings separation of grammars and transforms and a
+ "round" lambda syntax for defining transforms in-place.]
+]
+[
     [April 15, 2007]
     [Boost.Xpressive is ported from Proto compilers to Proto transforms.
      Support for old Proto compilers is dropped.]

Modified: branches/release/libs/xpressive/proto/doc/implementation.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/implementation.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/implementation.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -7,6 +7,166 @@
 
 [section:implementation Appendix C: Implementation Notes]
 
+[section:sfinae Quick-n-Dirty Type Categorization]
+
+Much has already been written about dispatching on type traits using
+SFINAE (Substitution Failure Is Not An Error) techniques in C++. There
+is a Boost library, Boost.Enable_if, to make the technique idiomatic.
+Proto dispatches on type traits extensively, but it doesn't use
+`enable_if<>` very often. Rather, it dispatches based on the presence
+or absence of nested types, often typedefs for void.
+
+Consider the implementation of `is_expr<>`. It could have been written
+as something like this:
+
+ template<typename T>
+ struct is_expr
+ : is_base_and_derived<proto::some_expr_base, T>
+ {};
+
+Rather, it is implemented as this:
+
+ template<typename T, typename Void = void>
+ struct is_expr
+ : mpl::false_
+ {};
+
+ template<typename T>
+ struct is_expr<T, typename T::proto_is_expr_>
+ : mpl::true_
+ {};
+
+This relies on the fact that the specialization will be preferred
+if `T` has a nested `proto_is_expr_` that is a typedef for `void`.
+All Proto expression types have such a nested typedef.
+
+Why does Proto do it this way? The reason is because, after running
+extensive benchmarks while trying to improve compile times, I have
+found that this approach compiles faster. It requires exactly one
+template instantiation. The other approach requires at least 2:
+`is_expr<>` and `is_base_and_derived<>`, plus whatever templates
+`is_base_and_derived<>` may instantiate.
+
+[endsect]
+
+[section:function_arity Detecting the Arity of Function Objects]
+
+In several places, Proto needs to know whether or not a function
+object `Fun` can be called with certain parameters and take a
+fallback action if not. This happens in _callable_context_ and
+in the _call_ transform. How does Proto know? It involves some
+tricky metaprogramming. Here's how.
+
+Another way of framing the question is by trying to implement
+the following `can_be_called<>` Boolean metafunction, which
+checks to see if a function object `Fun` can be called with
+parameters of type `A` and `B`:
+
+ template<typename Fun, typename A, typename B>
+ struct can_be_called;
+
+First, we define the following `dont_care` struct, which has an
+implicit conversion from anything. And not just any implicit
+conversion; it has a ellipsis conversion, which is the worst possible
+conversion for the purposes of overload resolution:
+
+ struct dont_care
+ {
+ dont_care(...);
+ };
+
+We also need some private type known only to us with an overloaded
+comma operator (!), and some functions that detect the presence of
+this type and return types with different sizes, as follows:
+
+ struct private_type
+ {
+ private_type const &operator,(int) const;
+ };
+
+ typedef char yes_type; // sizeof(yes_type) == 1
+ typedef char (&no_type)[2]; // sizeof(no_type) == 2
+
+ template<typename T>
+ no_type is_private_type(T const &);
+
+ yes_type is_private_type(private_type const &);
+
+Next, we implement a binary function object wrapper with a very
+strange conversion operator, whose meaning will become clear later.
+
+ template<typename Fun>
+ struct funwrap2 : Fun
+ {
+ funwrap2();
+ typedef private_type const &(*pointer_to_function)(dont_care, dont_care);
+ operator pointer_to_function() const;
+ };
+
+With all of these bits and pieces, we can implement `can_be_called<>` as
+follows:
+
+ template<typename Fun, typename A, typename B>
+ struct can_be_called
+ {
+ static funwrap2<Fun> &fun;
+ static A &a;
+ static B &b;
+
+ static bool const value = (
+ sizeof(no_type) == sizeof(is_private_type( (fun(a,b), 0) ))
+ );
+
+ typedef mpl::bool_<value> type;
+ };
+
+The idea is to make it so that `fun(a,b)` will always compile by adding
+our own binary function overload, but doing it in such a way that we can
+detect whether our overload was selected or not. And we rig it so that
+our overload is selected if there is really no better option. What follows
+is a description of how `can_be_called<>` works.
+
+We wrap `Fun` in a type that has an implicit conversion to a pointer to
+a binary function. An object `fun` of class type can be invoked as
+`fun(a, b)` if it has such a conversion operator, but since it involves
+a user-defined conversion operator, it is less preferred than an
+overloaded `operator()`, which requires no such conversion.
+
+The function pointer can accept any two arguments by virtue
+of the `dont_care` type. The conversion sequence for each argument is
+guaranteed to be the worst possible conversion sequence: an implicit
+conversion through an ellipsis, and a user-defined conversion to
+`dont_care`. In total, it means that `funwrap2<Fun>()(a, b)` will
+always compile, but it will select our overload only if there really is
+no better option.
+
+If there is a better option --- for example if `Fun` has an overloaded
+function call operator such as `void operator()(A a, B b)` --- then
+`fun(a, b)` will resolve to that one instead. The question now is how
+to detect which function got picked by overload resolution.
+
+Notice how `fun(a, b)` appears in `can_be_called<>`: `(fun(a, b), 0)`.
+Why do we use the comma operator there? The reason is because we are
+using this expression as the argument to a function. If the return type
+of `fun(a, b)` is `void`, it cannot legally be used as an argument to
+a function. The comma operator sidesteps the issue.
+
+This should also make plain the purpose of the overloaded comma operator
+in `private_type`. The return type of the pointer to function is
+`private_type`. If overload resolution selects our overload, then the
+type of `(fun(a, b), 0)` is `private_type`. Otherwise, it is `int`.
+That fact is used to dispatch to either overload of `is_private_type()`,
+which encodes its answer in the size of its return type.
+
+That's how it works with binary functions. Now repeat the above process
+for functions up to some predefined function arity, and you're done.
+
+[endsect]
+
+[section:ppmp_vs_tmp Avoiding Template Instiations With The Preprocessor]
+
 TODO
 
 [endsect]
+
+[endsect]

Modified: branches/release/libs/xpressive/proto/doc/installation.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/installation.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/installation.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -9,9 +9,11 @@
 
 [heading Getting Proto]
 
-Currently the only way to get Proto is through CVS via the boost project on
-SourceForge.net. Just go to [@http://sf.net/projects/boost] and follow the
-instructions there for anonymous CVS access.
+You can get Proto by downloading [^proto.zip] from
+[@http://www.boost-consulting.com/vault/index.php?directory=Template%20Metaprogramming]
+or by accessing Boost's SVN repository on SourceForge.net. Just go to
+[@http://svn.boost.org/trac/boost/wiki/BoostSubversion]
+and follow the instructions there for anonymous SVN access.
 
 [heading Building with Proto]
 
@@ -19,19 +21,22 @@
 your build scripts or link to any separate lib file to use it. All you need
 to do is `#include <boost/xpressive/proto/proto.hpp>`. This will include the
 core of Proto. If you want to use any transforms, you must include the
-appropriate header from the [^boost\/xpressive\/proto\/transform\/] directory.
+appropriate header from the [^boost\/proto\/transform\/] directory.
+Likewise for any evaluation contexts, which live in the
+[^boost\/proto\/context\/] directory.
 
 [heading Requirements]
 
-Proto depends on Boost. You must use the version in CVS HEAD.
+Proto depends on Boost. You must use either Boost version 1.34.1 or the
+version in SVN trunk.
 
 [heading Supported Compilers]
 
 Currently, Boost.Proto is known to work on the following compilers:
 
 * Visual C++ 7.1 and higher
-* GNU C++ 3.2 and higher
-* Intel on Linun 8.1 and higher
+* GNU C++ 3.4 and higher
+* Intel on Linux 8.1 and higher
 * Intel on Windows 9.1 and higher
 
 [note Please send any questions, comments and bug reports to eric <at> boost-consulting <dot> com.]

Modified: branches/release/libs/xpressive/proto/doc/preface.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/preface.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/preface.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -7,8 +7,8 @@
 
 [section Preface]
 
-[:Something witty.]
-[:[*['-- Someone Famous]]]
+[:["There are more things in heaven and earth, Horatio, than are dreamt of in your philosophy.]]
+[:[*['-- William Shakespeare]]]
 
 [heading Description]
 
@@ -61,6 +61,14 @@
 with Fusion's iterators and algorithms.
 
 The syntax for the grammar-matching features of `proto::matches<>` is inspired
-by MPL's lambda expressions.
+by MPL's lambda expressions, and by Aleksey Gurtovoy's
+[@http://lists.boost.org/Archives/boost/2002/11/39718.php "round" lambda] notation.
+
+[heading Further Reading]
+
+A technical paper about an earlier version of Proto was accepted into the
+[@http://lcsd.cs.tamu.edu/2007/ ACM SIGPLAN Symposium on Library-Centric Software Design LCSD'07],
+and can be found at [@http://lcsd.cs.tamu.edu/2007/final/1/1_Paper.pdf]. The
+tree transforms described in that paper differ from what exists today.
 
 [endsect]

Modified: branches/release/libs/xpressive/proto/doc/proto.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/proto.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/proto.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -2,7 +2,7 @@
 [library Boost.Proto
     [quickbook 1.3]
     [authors [Niebler, Eric]]
- [copyright 2006 Eric Niebler]
+ [copyright 2008 Eric Niebler]
     [category template]
     [id proto]
     [dirname proto]
@@ -18,7 +18,7 @@
 ]
 
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -35,40 +35,46 @@
 
 [/ Links ]
 
+[def _PETE_ [@http://www.codesourcery.com/pooma/download.html PETE]]
 [def _spirit_fx_ [@http://spirit.sourceforge.net Spirit Parser Framework]]
 [def _spirit_ [@http://spirit.sourceforge.net Spirit]]
 [def _xpressive_ [@../../../libs/xpressive/doc/index.html Boost.Xpressive]]
-[def _expr_ [classref boost::proto::exprns_::expr<Tag,Args,1> `expr<>`]]
-[def _ref_ [classref boost::proto::refns_::ref_ `ref_<>`]]
-[def _unref_ [classref boost::proto::functional::unref `unref()`]]
-[def _deep_copy_ [classref boost::proto::functional::deep_copy `deep_copy()`]]
-[def _extends_ [classref boost::proto::exprns_::extends `extends<>`]]
-[def _as_expr_ [classref boost::proto::functional::as_expr `as_expr()`]]
-[def _as_arg_ [classref boost::proto::functional::as_arg `as_arg()`]]
-[def _make_expr_ [funcref boost::proto::make_expr `make_expr()`]]
-[def _unpack_expr_ [funcref boost::proto::unpack_expr `unpack_expr()`]]
-[def _matches_ [classref boost::proto::result_of::matches `matches<>`]]
-[def _or_ [classref boost::proto::control::or_ `or_<>`]]
-[def _and_ [classref boost::proto::control::and_ `and_<>`]]
-[def _if_ [classref boost::proto::control::if_ `if_<>`]]
-[def _not_ [classref boost::proto::control::not_ `not_<>`]]
-[def _exact_ [classref boost::proto::control::exact `exact<>`]]
-[def _convertible_to_ [classref boost::proto::control::convertible_to `convertible_to<>`]]
-[def _is_expr_ [classref boost::proto::result_if::is_expr `is_expr<>`]]
-[def _tag_of_ [classref boost::proto::result_if::tag_of `tag_of<>`]]
-[def _arg_ [funcref boost::proto::arg `arg()`]]
-[def _arg_c_ [funcref boost::proto::arg_c `arg_c()`]]
-[def _eval_ [classref boost::proto::functional::eval `eval()`]]
-[def _left_ [classref boost::proto::functional::left `left()`]]
-[def _right_ [classref boost::proto::functional::right `right()`]]
-[def _terminal_ [classref boost::proto::op::terminal `terminal<>`]]
-[def _unary_expr_ [classref boost::proto::op::unary_expr `unary_expr<>`]]
-[def _binary_expr_ [classref boost::proto::op::binary_expr `binary_expr<>`]]
-[def _literal_ [classref boost::proto::utility::literal `literal<>`]]
-[def _lit_ [funcref boost::proto::lit `lit()`]]
-[def _vararg_ [classref boost::proto::control::vararg `vararg<>`]]
-[def _default_context_ [classref boost::proto::context::default_context `default_context`]]
-[def _callable_context_ [classref boost::proto::context::callable_context `callable_context<>`]]
+[def _expr_ [classref boost::proto::exprns_::expr<Tag,Args,1> `expr<>`]]
+[def _ref_ [classref boost::proto::refns_::ref_ `ref_<>`]]
+[def _unref_ [classref boost::proto::functional::unref `unref()`]]
+[def _deep_copy_ [classref boost::proto::functional::deep_copy `deep_copy()`]]
+[def _extends_ [classref boost::proto::exprns_::extends `extends<>`]]
+[def _as_expr_ [funcref boost::proto::as_expr `as_expr()`]]
+[def _as_arg_ [funcref boost::proto::as_arg `as_arg()`]]
+[def _make_expr_ [funcref boost::proto::make_expr `make_expr()`]]
+[def _unpack_expr_ [funcref boost::proto::unpack_expr `unpack_expr()`]]
+[def _matches_ [classref boost::proto::result_of::matches `matches<>`]]
+[def _or_ [classref boost::proto::control::or_ `or_<>`]]
+[def _and_ [classref boost::proto::control::and_ `and_<>`]]
+[def _if_ [classref boost::proto::control::if_ `if_<>`]]
+[def _not_ [classref boost::proto::control::not_ `not_<>`]]
+[def _exact_ [classref boost::proto::control::exact `exact<>`]]
+[def _convertible_to_ [classref boost::proto::control::convertible_to `convertible_to<>`]]
+[def _is_expr_ [classref boost::proto::result_if::is_expr `is_expr<>`]]
+[def _tag_of_ [classref boost::proto::result_if::tag_of `tag_of<>`]]
+[def _arg_ [funcref boost::proto::arg `arg()`]]
+[def _arg_c_ [funcref boost::proto::arg_c `arg_c()`]]
+[def _eval_ [memberref boost::proto::eval `eval()`]]
+[def _left_ [classref boost::proto::functional::left `left()`]]
+[def _right_ [classref boost::proto::functional::right `right()`]]
+[def _terminal_ [classref boost::proto::op::terminal `terminal<>`]]
+[def _unary_expr_ [classref boost::proto::op::unary_expr `unary_expr<>`]]
+[def _binary_expr_ [classref boost::proto::op::binary_expr `binary_expr<>`]]
+[def _literal_ [classref boost::proto::utility::literal `literal<>`]]
+[def _lit_ [funcref boost::proto::lit `lit()`]]
+[def _vararg_ [classref boost::proto::control::vararg `vararg<>`]]
+[def _default_context_ [classref boost::proto::context::default_context `default_context`]]
+[def _callable_context_ [classref boost::proto::context::callable_context `callable_context<>`]]
+[def _null_context_ [classref boost::proto::context::null_context `null_context<>`]]
+[def _when_ [classref boost::proto::transform::when `when<>`]]
+[def _call_ [classref boost::proto::transform::call `call<>`]]
+[def _make_ [classref boost::proto::transform::make `make<>`]]
+[def _flatten_ [funcref boost::proto::flatten `flatten()`]]
 
 [include preface.qbk]
 
@@ -85,7 +91,7 @@
     [Describes the tools Proto provides for making your expression trees do
      something useful.]]
 [[[link boost_proto.users_guide.expression_introspection Expression Introspection]]
- [Describes Proto's grammar matching faciities, which make
+ [Describes Proto's grammar matching facilities, which make
      it easy to discover the structure of an expression tree.]]
 [[[link boost_proto.users_guide.expression_transformation Expression Transformation]]
     [Describes how to write expression transforms that turn an expression tree
@@ -118,7 +124,7 @@
 
 [endsect]
 
-[xinclude protodoc.xml]
+[xinclude proto.xml]
 
 [section Appendices]
 

Added: branches/release/libs/xpressive/proto/doc/proto.xml
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/doc/proto.xml 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,9 @@
+<?xml version="1.0" standalone="yes"?>
+<library-reference id="reference" xmlns:xi="http://www.w3.org/2001/XInclude">
+ <title>Reference</title>
+ <xi:include href="concepts/CallableTransform.xml"/>
+ <xi:include href="concepts/PrimitiveTransform.xml"/>
+ <xi:include href="concepts/Transform.xml"/>
+ <xi:include href="concepts/PolymorphicFunctionObject.xml"/>
+ <xi:include href="protodoc.xml" xpointer="xpointer(//header)"/>
+</library-reference>

Modified: branches/release/libs/xpressive/proto/doc/protodoc.xml
==============================================================================
--- branches/release/libs/xpressive/proto/doc/protodoc.xml (original)
+++ branches/release/libs/xpressive/proto/doc/protodoc.xml 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,27 +1,27 @@
 <?xml version="1.0" standalone="yes"?>
 <library-reference><header name="boost/xpressive/proto/args.hpp"><para>Contains definition of args&lt;&gt; class template. </para><namespace name="boost"><namespace name="proto"><namespace name="argsns_"><struct name="args0"><template>
       <template-type-parameter name="Arg0"/>
- </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>mpl::void_</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args1"><template>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="size" specifiers="static"><type>const long</type></data-member><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>mpl::void_</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef></struct><struct name="args1"><template>
       <template-type-parameter name="Arg0"/>
- </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>mpl::void_</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args2"><template>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="size" specifiers="static"><type>const long</type></data-member><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>mpl::void_</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef></struct><struct name="args2"><template>
       <template-type-parameter name="Arg0"/>
       <template-type-parameter name="Arg1"/>
- </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args3"><template>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="size" specifiers="static"><type>const long</type></data-member><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>mpl::void_</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef></struct><struct name="args3"><template>
       <template-type-parameter name="Arg0"/>
       <template-type-parameter name="Arg1"/>
       <template-type-parameter name="Arg2"/>
- </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args4"><template>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="size" specifiers="static"><type>const long</type></data-member><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>mpl::void_</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef></struct><struct name="args4"><template>
       <template-type-parameter name="Arg0"/>
       <template-type-parameter name="Arg1"/>
       <template-type-parameter name="Arg2"/>
       <template-type-parameter name="Arg3"/>
- </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>Arg3</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct><struct name="args5"><template>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="size" specifiers="static"><type>const long</type></data-member><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>Arg3</type></typedef><typedef name="arg4"><type>mpl::void_</type></typedef></struct><struct name="args5"><template>
       <template-type-parameter name="Arg0"/>
       <template-type-parameter name="Arg1"/>
       <template-type-parameter name="Arg2"/>
       <template-type-parameter name="Arg3"/>
       <template-type-parameter name="Arg4"/>
- </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>Arg3</type></typedef><typedef name="arg4"><type>Arg4</type></typedef><data-member name="size" specifiers="static"><type>const long</type></data-member></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context.hpp"><para>Includes all the context classes in the context/ sub-directory. </para></header><header name="boost/xpressive/proto/context/callable.hpp"><para>Definintion of callable_context&lt;&gt;, an evaluation co
ntext for proto::eval() that explodes each node and calls the derived context type with the expressions constituents. If the derived context doesn't have an overload that handles this node, fall-back to the default_context. TODO: make the fall-back configurable! </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="callable_eval"><template>
+ </template><purpose>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. </purpose><description><para>A type sequence, for use as the 2nd parameter to the <computeroutput>expr&lt;&gt;</computeroutput> class template. The types in the sequence correspond to the children of a node in an expression tree. </para></description><data-member name="size" specifiers="static"><type>const long</type></data-member><typedef name="arg0"><type>Arg0</type></typedef><typedef name="arg1"><type>Arg1</type></typedef><typedef name="arg2"><type>Arg2</type></typedef><typedef name="arg3"><type>Arg3</type></typedef><typedef name="arg4"><type>Arg4</type></typedef></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context.hpp"><para>Includes all the context classes in the context/ sub-directory. </para></header><header name="boost/xpressive/proto/context/callable.hpp"><para>Definintion of callable_context&lt;&gt;, an evaluation co
ntext for proto::eval() that explodes each node and calls the derived context type with the expressions constituents. If the derived context doesn't have an overload that handles this node, fall-back to the default_context. TODO: make the fall-back configurable! </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="callable_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
       <template-nontype-parameter name="Arity"><type>long</type></template-nontype-parameter>
@@ -54,10 +54,7 @@
       <template-type-parameter name="Context"/>
       <template-type-parameter name="Tag"/>
       <template-nontype-parameter name="Arity"><type>long</type></template-nontype-parameter>
- </template></struct><struct name="default_context"><description><para>default_context </para></description><struct name="eval"><template>
- <template-type-parameter name="Expr"/>
- <template-type-parameter name="ThisContext"><default>default_context const</default></template-type-parameter>
- </template><inherit access="public">boost::proto::context::default_eval&lt; Expr, ThisContext &gt;</inherit><description><para>default_context::eval </para></description></struct></struct><struct-specialization name="default_eval"><template>
+ </template></struct><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::posit</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
@@ -150,7 +147,7 @@
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::shift_right_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::multilpies_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::multiplies_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::divides_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
@@ -174,7 +171,7 @@
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::bitwise_xor_assign</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::terminal</template-arg><template-arg>0</template-arg></specialization><typedef name="result_type"><type>mpl::if_&lt; is_const &lt; Expr &gt;, typename <classname>proto::result_of::arg</classname>&lt; Expr &gt;::const_reference, typename <classname>proto::result_of::arg</classname>&lt; Expr &gt;::reference &gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name=""><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::terminal</template-arg><template-arg>0</template-arg></specialization><typedef name="result_type"><type>mpl::if_&lt; is_const&lt; Expr &gt;, typename <classname>proto::result_of::arg</classname>&lt; Expr &gt;::const_reference, typename <classname>proto::result_of::arg</classname>&lt; Expr &gt;::reference &gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name=""><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::post_inc</template-arg><template-arg>1</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
@@ -189,22 +186,28 @@
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::if_else_</template-arg><template-arg>3</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::comma</template-arg><template-arg>2</template-arg></specialization><typedef name="proto_arg0"><type><classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 0 &gt;::type, Context &gt;::type</type></typedef><typedef name="proto_arg1"><type><classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type, Context &gt;::type</type></typedef><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::comma</template-arg><template-arg>2</template-arg></specialization><typedef name="result_type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="Context"/>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>0</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type()&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>1</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type()&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>2</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>2</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>3</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 2 &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>3</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 2 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specializat
ion><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>4</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 2 &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 3 &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></
parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>4</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 2 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 3 &gt;::type &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><paramete
r name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="default_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>5</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 2 &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 3 &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename proto::result_of::arg_c&lt; Expr, 4 &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</t
ype><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context/null.hpp"><para>Definintion of null_context&lt;&gt;, an evaluation context for proto::eval() that simply evaluates each child expression, doesn't combine the results at all, and returns void. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="null_eval"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>proto::tag::function</template-arg><template-arg>5</template-arg></specialization><typedef name="function_type"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="result_type"><type>boost::result_of&lt; function_type(typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 1 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 2 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 3 &gt;::type &gt;::type, Context &gt;::type, typename <classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; typename proto::result_of::arg_c&lt; Expr, 4 &gt;::t
ype &gt;::type, Context &gt;::type)&gt;::type</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result_type</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct name="default_context"><description><para>default_context </para></description><struct name="eval"><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="ThisContext"><default>default_context const</default></template-type-parameter>
+ </template><inherit access="public">boost::proto::context::default_eval&lt; Expr, ThisContext &gt;</inherit><description><para>default_context::eval </para></description></struct></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/context/null.hpp"><para>Definintion of null_context&lt;&gt;, an evaluation context for proto::eval() that simply evaluates each child expression, doesn't combine the results at all, and returns void. </para><namespace name="boost"><namespace name="proto"><namespace name="context"><struct name="null_eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
       <template-nontype-parameter name="Arity"><type>long</type></template-nontype-parameter>
@@ -229,75 +232,99 @@
     </template><specialization><template-arg>Expr</template-arg><template-arg>Context</template-arg><template-arg>5</template-arg></specialization><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></method></method-group></struct-specialization><struct name="null_context"><description><para>null_context </para></description><struct name="eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="ThisContext"><default>null_context const</default></template-type-parameter>
- </template><inherit access="public">boost::proto::context::null_eval&lt; Expr, ThisContext &gt;</inherit><description><para>null_context::eval </para></description></struct></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/debug.hpp"><para>Utilities for debugging proto expression trees </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="display_expr"><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><template>
+ </template><inherit access="public">boost::proto::context::null_eval&lt; Expr, ThisContext &gt;</inherit><description><para>null_context::eval </para></description></struct></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/debug.hpp"><para>Utilities for debugging Proto expression trees </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="display_expr"><purpose>Pretty-print a Proto expression tree. </purpose><description><para>A PolymorphicFunctionObject which accepts a Proto expression tree and pretty-prints it to an <computeroutput>ostream</computeroutput> for debugging purposes. </para></description><typedef name="result_type"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>void</type><template>
           <template-type-parameter name="Args"/>
- </template><parameter name="expr"><paramtype>expr&lt; <classname>tag::terminal</classname>, Args, 0 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; <classname>tag::terminal</classname>, Args, 0 &gt; const &amp;</paramtype></parameter><purpose>Pretty-print the current node in a Proto expression tree. </purpose></method><method name="operator()" cv="const"><type>void</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="Args"/>
- </template><parameter name="expr"><paramtype>expr&lt; Tag, Args, 1 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 1 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="Args"/>
- </template><parameter name="expr"><paramtype>expr&lt; Tag, Args, 0 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
+ </template><parameter name="expr"><paramtype>proto::expr&lt; Tag, Args, 0 &gt; const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>void</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></method></method-group><constructor><parameter name="depth"><paramtype>int</paramtype><default>0</default></parameter><parameter name="sout"><paramtype>std::ostream &amp;</paramtype><default>std::cout</default></parameter></constructor></struct></namespace><namespace name="tag"><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::posit</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::negate</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::dereference</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::complement</classname></paramtype></parameter></function><function name="proto_t
ag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::address_of</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_not</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classna
me>tag::shift_left</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus</classname></paramtype></parameter></function><function name
="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::not_equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramt
ype><classname>tag::logical_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::comma</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::mem_ptr</classname></paramtype></parameter></
function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multilpies_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus_assign</classname></paramtype></parameter></function><function name="proto_tag_na
me"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::subscript</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><paramete
r name=""><paramtype><classname>tag::if_else_</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::function</classname></paramtype></parameter></function><data-member name="proto_tag_name"><type><classname>hidden_detail_::printable_tag</classname>&lt; Tag &gt;::type</type></data-member></namespace><function name="display_expr"><type>void</type><template>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group><constructor><parameter name="depth"><paramtype>int</paramtype><default>0</default><description><para>The starting indentation depth for this node. Children nodes will be displayed at a starting depth of <computeroutput>depth+4</computeroutput>. </para></description></parameter><parameter name="sout"><paramtype>std::ostream &amp;</paramtype><default>std::cout</default><description><para>The <computeroutput>ostream</computeroutput> to which the expression tree will be written. </para></description></parameter><description><para>
+</para></description></constructor><method-group name="private member functions"/><copy-assignment><parameter name=""><paramtype><classname>display_expr</classname> const &amp;</paramtype></parameter></copy-assignment></struct></namespace><namespace name="tag"><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::posit</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::negate</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::dereference</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::complement</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::address_of</classname></pa
ramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_not</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::pre_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_inc</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::post_dec</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left</classname></paramtype></parameter></function><function name="proto_tag_name"><type>cha
r const *</type><parameter name=""><paramtype><classname>tag::shift_right</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less</classname><
/paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::less_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::greater_equal</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::not_equal_to</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_or</classname></paramtype></parameter></function><function name="proto_tag_nam
e"><type>char const *</type><parameter name=""><paramtype><classname>tag::logical_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::comma</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::mem_ptr</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname
>tag::assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_left_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::shift_right_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::multiplies_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::divides_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::modulus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::plus_assign</classname></paramt
ype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::minus_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_and_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_or_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::bitwise_xor_assign</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::subscript</classname></paramtype></parameter></function><function name="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::if_else_</classname></paramtype></parameter></function><function name
="proto_tag_name"><type>char const *</type><parameter name=""><paramtype><classname>tag::function</classname></paramtype></parameter></function></namespace><overloaded-function name="display_expr"><signature><type>void</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></function><function name="display_expr"><type>void</type><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The Proto expression tree to pretty-print </para></description></parameter><parameter name="sout"><paramtype>std::ostream &amp;</paramtype><description><para>The <computeroutput>ostream</computeroutput> to which the output should be written. </para></description></parameter></signature><signature><type>void</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="sout"><paramtype>std::ostream &amp;</paramtype></parameter></function></namespace></namespace></header><header name="boost/xpressive/proto/deep_copy.hpp"><para>Replace all nodes stored by reference by nodes stored by value. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="deep_copy"><struct-specialization name="result"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><purpose>Pretty-print a Proto expression tree. </purpose><description><para>
+
+</para></description><notes><para>Equivalent to <computeroutput>functional::display_expr(0, sout)(expr)</computeroutput> </para></notes></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/deep_copy.hpp"><para>Replace all nodes stored by reference by nodes stored by value. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="deep_copy"><purpose>A PolymorphicFunctionObject type for deep-copying Proto expression trees. </purpose><description><para>A PolymorphicFunctionObject type for deep-copying Proto expression trees. When a tree is deep-copied, all internal nodes and most terminals held by reference are instead held by value.</para><para>
+</para></description><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::deep_copy</classname>&lt; Expr &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type><classname>result_of::deep_copy</classname>&lt; typename boost::remove_const&lt; typename boost::remove_reference&lt; Expr &gt;::type &gt;::type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::deep_copy</classname>&lt; Expr &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="result_of"><struct name="deep_copy"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><purpose>Deep-copies a Proto expression tree, turning all nodes and terminals held by reference into ones held by value. </purpose></method></method-group></struct></namespace><namespace name="result_of"><struct name="deep_copy"><template>
       <template-type-parameter name="Expr"/>
- </template></struct></namespace><data-member name="deep_copy"><type><classname>functional::deep_copy</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/domain.hpp"><para>Contains definition of domain&lt;&gt; class template, for defining domains with a grammar for controlling operator overloading. </para><namespace name="boost"><namespace name="proto"><namespace name="domainns_"><struct name="domain"><template>
+ </template><purpose>A metafunction for calculating the return type of <computeroutput>proto::deep_copy()</computeroutput>. </purpose><description><para>A metafunction for calculating the return type of <computeroutput>proto::deep_copy()</computeroutput>. The type parameter <computeroutput>Expr</computeroutput> should be the type of a Proto expression tree. It should not be a reference type, nor should it be cv-qualified. </para></description><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct></namespace><data-member name="deep_copy"><type><classname>functional::deep_copy</classname> const</type><purpose>A PolymorphicFunctionObject for deep-copying Proto expression trees. </purpose><description><para>A PolymorphicFunctionObject for deep-copying Proto expression trees. When a tree is deep-copied, all internal nodes and most terminals held by reference are instead held by value.</para><para>
+<para>proto::functional::deep_copy. </para>
+</para></description></data-member></namespace></namespace></header><header name="boost/xpressive/proto/domain.hpp"><para>Contains definition of domain&lt;&gt; class template and helpers for defining domains with a generator and a grammar for controlling operator overloading. </para><namespace name="boost"><namespace name="proto"><namespace name="domainns_"><struct name="domain"><template>
       <template-type-parameter name="Generator"/>
       <template-type-parameter name="Grammar"/>
- </template><inherit access="public">Generator</inherit><typedef name="grammar"><type>Grammar</type></typedef></struct><struct name="default_domain"><inherit access="public">boost::proto::domainns_::domain&lt; &gt;</inherit></struct><struct name="deduce_domain"/></namespace><namespace name="result_of"><struct name="is_domain"><template>
+ </template><inherit access="public">Generator</inherit><purpose>For use in defining domain tags to be used with <computeroutput>proto::extends&lt;&gt;</computeroutput>. A Domain associates an expression type with a Generator, and optionally a Grammar. </purpose><description><para>The Generator determines how new expressions in the domain are constructed. Typically, a generator wraps all new expressions in a wrapper that imparts domain-specific behaviors to expressions within its domain. (See <computeroutput>proto::extends&lt;&gt;</computeroutput>.)</para><para>The Grammar determines whether a given expression is valid within the domain, and automatically disables any operator overloads which would cause an invalid expression to be created. By default, the Grammar parameter defaults to the wildcard, <computeroutput>proto::_</computeroutput>, which makes all expressions valid within the domain.</para><para>Example: <programlisting> template&lt;typename Expr&gt;
+ struct MyExpr;
+
+ struct MyGrammar
+ : or_&lt; terminal&lt;_&gt;, plus&lt;MyGrammar, MyGrammar&gt; &gt;
+ {};
+
+ // Define MyDomain, in which all expressions are
+ // wrapped in MyExpr&lt;&gt; and only expressions that
+ // conform to MyGrammar are allowed.
+ struct MyDomain
+ : domain&lt;generator&lt;MyExpr&gt;, MyGrammar&gt;
+ {};
+
+ // Use MyDomain to define MyExpr
+ template&lt;typename Expr&gt;
+ struct MyExpr
+ : extends&lt;Expr, MyExpr&lt;Expr&gt;, MyDomain&gt;
+ {
+ // ...
+ };
+</programlisting> </para></description><typedef name="proto_grammar"><type>Grammar</type></typedef></struct><struct name="default_domain"><inherit access="public">boost::proto::domainns_::domain&lt; &gt;</inherit><purpose>The domain expressions have by default, if <computeroutput>proto::extends&lt;&gt;</computeroutput> has not been used to associate a domain with an expression. </purpose></struct><struct name="deduce_domain"><inherit access="public">boost::proto::domainns_::domain&lt; Generator, Grammar &gt;</inherit><purpose>A pseudo-domain for use in functions and metafunctions that require a domain parameter. It indicates that the domain of the parent node should be inferred from the domains of the children nodes. </purpose><description><para>
+</para></description></struct></namespace><namespace name="result_of"><struct name="is_domain"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="EnableIf"/>
- </template></struct><struct name="domain_of"><template>
+ </template><inherit access="public">boost::mpl::false_</inherit><description><para>A metafunction that returns <computeroutput>mpl::true_</computeroutput> if the type <computeroutput>T</computeroutput> is the type of a Proto domain; <computeroutput>mpl::false_</computeroutput> otherwise. If <computeroutput>T</computeroutput> inherits from <computeroutput>proto::domain&lt;&gt;</computeroutput>, <computeroutput>is_domain&lt;T&gt;</computeroutput> is <computeroutput>mpl::true_</computeroutput>. </para></description></struct><struct name="domain_of"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="EnableIf"/>
- </template><typedef name="type"><type><classname>default_domain</classname></type></typedef></struct><struct-specialization name="is_domain"><template>
- <template-type-parameter name="T"/>
- </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_domain_</template-arg></specialization></struct-specialization><struct-specialization name="domain_of"><template>
- <template-type-parameter name="T"/>
- </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>T::proto_domain</type></typedef></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/eval.hpp"><para>Contains the eval() expression evaluator. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="eval"><struct-specialization name="result"><template>
+ </template><description><para>A metafunction that returns the domain of a given type. If <computeroutput>T</computeroutput> is a Proto expression type, it returns that expression's associated domain. If not, it returns <computeroutput>proto::default_domain</computeroutput>. </para></description><typedef name="type"><type>default_domain</type></typedef></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/eval.hpp"><para>Contains the eval() expression evaluator. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="eval"><purpose>A PolymorphicFunctionObject type for evaluating a given Proto expression with a given context. </purpose><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><specialization><template-arg>This(Expr</template-arg><template-arg>Context)</template-arg></specialization><inherit access="public">boost::proto::result_of::eval&lt; remove_reference&lt; Expr &gt;::type, remove_reference&lt; Context &gt;::type &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>Context)</template-arg></specialization><typedef name="type"><type><classname>proto::result_of::eval</classname>&lt; typename remove_reference&lt; Expr &gt;::type, typename remove_reference&lt; Context &gt;::type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="Context"/>
- </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype><description><para>The Proto expression to evaluate </para></description></parameter><parameter name="context"><paramtype>Context &amp;</paramtype><description><para>The context in which the expression should be evaluated. </para></description></parameter><purpose>Evaluate a given Proto expression with a given context. </purpose><description><para>
+
+</para></description><returns><para><computeroutput>typename Context::template eval&lt;Expr&gt;()(expr, context)</computeroutput> </para></returns></method><method name="operator()" cv="const"><type><classname>proto::result_of::eval</classname>&lt; Expr, Context &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="Context"/>
- </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="result_of"><struct name="eval"><template>
+ </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="context"><paramtype>Context const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct></namespace><namespace name="result_of"><struct name="eval"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Context"/>
- </template><typedef name="type"><type>Context::template <classname>eval</classname>&lt; Expr &gt;::result_type</type></typedef></struct></namespace><data-member name="eval"><type><classname>functional::eval</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/expr.hpp"><para>Contains definition of expr&lt;&gt; class template. </para><namespace name="boost"><namespace name="proto"><namespace name="exprns_"><struct-specialization name="expr"><template>
+ </template><purpose>A metafunction for calculating the return type of <computeroutput>proto::eval()</computeroutput> given a certain <computeroutput>Expr</computeroutput> and <computeroutput>Context</computeroutput> types. </purpose><description><para>
+</para></description><typedef name="type"><type>Context::template <classname>eval</classname>&lt; Expr &gt;::result_type</type></typedef></struct></namespace><data-member name="eval"><type><classname>functional::eval</classname> const</type><purpose>A PolymorphicFunctionObject for evaluating a given Proto expression with a given context. </purpose><description><para><para>proto::functional::eval. </para>
+</para></description></data-member></namespace></namespace></header><header name="boost/xpressive/proto/expr.hpp"><para>Contains definition of expr&lt;&gt; class template. </para><namespace name="boost"><namespace name="proto"><namespace name="exprns_"><struct-specialization name="expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Args"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>0</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>0</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args0&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the children expressions. </para></description><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 0 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>void</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</
type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
-</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 0 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type>default_domain</type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>void</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</type></typedef><
typedef name="proto_arg4"><type>void</type></typedef><data-member name="arg0"><type>proto_arg0</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
 
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+ </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv=""><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv=""><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr &gt; &gt; &gt; const</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv=""><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr &gt; &gt; &gt; const</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const , const A0, const A1 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
@@ -321,11 +348,7 @@
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method><method name="make" cv=""><type>static expr</type><template>
@@ -339,22 +362,18 @@
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name=""><paramtype><emphasis>unspecified</emphasis></paramtype><default>0</default></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct-specialization><struct-specialization name="expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Args"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>1</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>1</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args0&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the children expressions. </para></description><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 1 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>void</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</
type></typedef><typedef name="proto_arg4"><type>void</type></typedef><typedef name="address_of_hack_type_"><description><para>If <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput> and <computeroutput>proto_arg0</computeroutput> is <computeroutput>proto::ref_&lt;T&gt;</computeroutput>, then <computeroutput>address_of_hack_type_</computeroutput> is <computeroutput>T*</computeroutput>. Otherwise, it is some undefined type. </para></description><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 1 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type>default_domain</type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>void</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</type></typedef><
typedef name="proto_arg4"><type>void</type></typedef><typedef name="address_of_hack_type_"><description><para>If <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput> and <computeroutput>proto_arg0</computeroutput> is <computeroutput>proto::ref_&lt;T&gt;</computeroutput>, then <computeroutput>address_of_hack_type_</computeroutput> is <computeroutput>T*</computeroutput>. Otherwise, it is some undefined type. </para></description><type><emphasis>unspecified</emphasis></type></typedef><data-member name="arg0"><type>proto_arg0</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
 </para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="conversion-operator" cv="const"><type>address_of_hack_type_</type><description><para>
 
-</para></description><returns><para>The address of <computeroutput>this-&gt;arg0</computeroutput> if <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput>. Otherwise, this function will fail to compile.</para></returns><notes><para>Proto overloads <computeroutput>operator&amp;</computeroutput>, which means that proto-ified objects cannot have their addresses taken, unless we use the following hack to make <computeroutput>&amp;x</computeroutput> implicitly convertible to <computeroutput>X*</computeroutput>. </para></notes></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>The address of <computeroutput>this-&gt;arg0</computeroutput> if <computeroutput>Tag</computeroutput> is <computeroutput>boost::proto::tag::address_of</computeroutput>. Otherwise, this function will fail to compile.</para></returns><notes><para>Proto overloads <computeroutput>operator&amp;</computeroutput>, which means that proto-ified objects cannot have their addresses taken, unless we use the following hack to make <computeroutput>&amp;x</computeroutput> implicitly convertible to <computeroutput>X*</computeroutput>. </para></notes></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
 
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const , const A0, const A1 &gt;::type const</type><template>
@@ -375,30 +394,22 @@
 
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Args"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>2</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>2</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args0&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the children expressions. </para></description><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 2 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>
void</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
-</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 2 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type>default_domain</type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>void</type></typedef><typedef name="proto_arg3"><type>void</type></typ
edef><typedef name="proto_arg4"><type>void</type></typedef><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
 
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const , const A0, const A1 &gt;::type const</type><template>
@@ -419,31 +430,23 @@
 
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><description><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Args"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>3</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>3</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args0&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the children expressions. </para></description><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 3 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3">
<type>void</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
-</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 3 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type>default_domain</type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3"><type>void</type
></typedef><typedef name="proto_arg4"><type>void</type></typedef><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
 
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const , const A0, const A1 &gt;::type const</type><template>
@@ -464,11 +467,7 @@
 
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
@@ -476,20 +475,16 @@
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Args"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>4</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>4</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args0&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the children expressions. </para></description><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 4 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3">
<type>Args::arg3</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
-</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 4 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type>default_domain</type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3"><type>Args::arg3
</type></typedef><typedef name="proto_arg4"><type>void</type></typedef><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><data-member name="arg3"><type>proto_arg3</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
 
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const , const A0, const A1 &gt;::type const</type><template>
@@ -510,11 +505,7 @@
 
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><data-member name="arg3"><type>proto_arg3</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
@@ -523,20 +514,16 @@
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization><struct-specialization name="expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Args"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>5</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args1&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type. </para></description><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Args</template-arg><template-arg>5</template-arg></specialization><purpose>Representation of a node in an expression tree. </purpose><description><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a node in an expression template tree. It is a container for its children sub-trees. It also serves as the terminal nodes of the tree.</para><para><computeroutput>Tag</computeroutput> is type that represents the operation encoded by this expression. It is typically one of the structs in the <computeroutput>boost::proto::tag</computeroutput> namespace, but it doesn't have to be. If the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput> then this <computeroutput>expr&lt;&gt;</computeroutput> type represents a leaf in the expression tree.</para><para><computeroutput>Args</computeroutput> is a type list representing the type of the children of this expression. It is an instanti
ation of one of <computeroutput>proto::args1&lt;&gt;</computeroutput>, <computeroutput>proto::args2&lt;&gt;</computeroutput>, etc. The children types must all themselves be either <computeroutput>expr&lt;&gt;</computeroutput> or <computeroutput>proto::ref_&lt;proto::expr&lt;&gt;&gt;</computeroutput>, unless the <computeroutput>Tag</computeroutput> type is <computeroutput>boost::proto::tag::terminal</computeroutput>, in which case <computeroutput>Args</computeroutput> must be <computeroutput>proto::args0&lt;T&gt;</computeroutput>, where <computeroutput>T</computeroutput> can be any type.</para><para><computeroutput>proto::expr&lt;&gt;</computeroutput> is a valid Fusion random-access sequence, where the elements of the sequence are the children expressions. </para></description><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 5 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type><classname>default_domain</classname></type></typedef><typedef name="fusion_tag"><type>tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3">
<type>Args::arg3</type></typedef><typedef name="proto_arg4"><type>Args::arg4</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
-</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
+ </template><description><para>Encodes the return type of <computeroutput>expr&lt;&gt;operator()</computeroutput>, for use with <computeroutput>boost::result_of&lt;&gt;</computeroutput> </para></description><typedef name="type"><type>result_of::funop&lt; Sig, expr &gt;::type</type></typedef></struct><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arity"><type>mpl::long_&lt; 5 &gt;</type></typedef><typedef name="proto_base_expr"><type>expr</type></typedef><typedef name="proto_args"><type>Args</type></typedef><typedef name="proto_domain"><type>default_domain</type></typedef><typedef name="fusion_tag"><type>proto::tag::proto_expr</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>expr</type></typedef><typedef name="proto_arg0"><type>Args::arg0</type></typedef><typedef name="proto_arg1"><type>Args::arg1</type></typedef><typedef name="proto_arg2"><type>Args::arg2</type></typedef><typedef name="proto_arg3"><type>Args::arg3
</type></typedef><typedef name="proto_arg4"><type>Args::arg4</type></typedef><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><data-member name="arg3"><type>proto_arg3</type></data-member><data-member name="arg4"><type>proto_arg4</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>expr const &amp;</type><description><para>
+</para></description><returns><para>*this </para></returns></method><method name="proto_base" cv=""><type>expr &amp;</type><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype><description><para>The rhs. </para></description></parameter><description><para>Subscript</para><para>
 
-</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>expr&lt; <classname>tag::subscript</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
+</para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing <computeroutput>*this</computeroutput> subscripted with <computeroutput>a</computeroutput>. </para></returns></method><method name="operator[]" cv="const"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; ref_&lt; expr const &gt;, typename <classname>result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; const</type><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; expr const &gt; &gt; &gt; const</type><description><para>Function call</para><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing the function invocation of <computeroutput/>(*this)(). </para></returns></method><method name="operator()" cv="const"><type><classname>result_of::funop1</classname>&lt; expr const , const A0 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::funop2</classname>&lt; expr const , const A0, const A1 &gt;::type const</type><template>
@@ -557,11 +544,7 @@
 
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> node representing an assignment of <computeroutput>a</computeroutput> to <computeroutput>*this</computeroutput>. </para></returns></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><data-member name="arg0"><type>proto_arg0</type></data-member><data-member name="arg1"><type>proto_arg1</type></data-member><data-member name="arg2"><type>proto_arg2</type></data-member><data-member name="arg3"><type>proto_arg3</type></data-member><data-member name="arg4"><type>proto_arg4</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static expr</type><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static expr</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
@@ -570,100 +553,95 @@
         </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 const &amp;</paramtype></parameter><parameter name="a4"><paramtype>A4 const &amp;</paramtype></parameter><description><para>
 </para></description><returns><para>A new <computeroutput>expr&lt;&gt;</computeroutput> object initialized with the specified arguments. </para></returns></method></method-group></struct-specialization></namespace><namespace name="result_of"><struct name="funop0"><template>
       <template-type-parameter name="Expr"/>
- </template><typedef name="type"><type>expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;&gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>args1</classname>&lt; ref_&lt; Expr &gt;&gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr()</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0&lt; This &gt;</inherit></struct-specialization><struct-specialization name="funop"><template>
+ </template><specialization><template-arg>Expr()</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0&lt; This &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr const ()</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0&lt; This const &gt;</inherit></struct-specialization><struct name="funop1"><template>
+ </template><specialization><template-arg>Expr const ()</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop0&lt; Expr &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop1"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
- </template><typedef name="type"><type>expr&lt; <classname>tag::function</classname>, <classname>args2</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>args2</classname>&lt; ref_&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr(A0)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1&lt; This, remove_reference&lt; A0 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="funop"><template>
+ </template><specialization><template-arg>Expr(A0)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1&lt; This, remove_reference&lt; A0 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr const (A0)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1&lt; This const , remove_reference&lt; A0 &gt;::type &gt;</inherit></struct-specialization><struct name="funop2"><template>
+ </template><specialization><template-arg>Expr const (A0)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop1&lt; Expr, A0 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop2"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
- </template><typedef name="type"><type>expr&lt; <classname>tag::function</classname>, <classname>args3</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A1 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>args3</classname>&lt; ref_&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A1 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2&lt; This, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="funop"><template>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2&lt; This, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2&lt; This const , remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type &gt;</inherit></struct-specialization><struct name="funop3"><template>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop2&lt; Expr, A0, A1 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop3"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
- </template><typedef name="type"><type>expr&lt; <classname>tag::function</classname>, <classname>args4</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A1 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A2 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>args4</classname>&lt; ref_&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A1 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A2 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3&lt; This, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="funop"><template>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3&lt; This, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3&lt; This const , remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type &gt;</inherit></struct-specialization><struct name="funop4"><template>
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop3&lt; Expr, A0, A1, A2 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct name="funop4"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
- </template><typedef name="type"><type>expr&lt; <classname>tag::function</classname>, <classname>args5</classname>&lt; <classname>ref_</classname>&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A1 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A2 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A3 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="funop"><template>
+ </template><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose><typedef name="type"><type>proto::expr&lt; <classname>tag::function</classname>, <classname>args5</classname>&lt; ref_&lt; Expr &gt;, typename <classname>result_of::as_arg</classname>&lt; A0 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A1 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A2 &gt;::type, typename <classname>result_of::as_arg</classname>&lt; A3 &gt;::type &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type const</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>A3 &amp;</paramtype></parameter></method><
/method-group></struct><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4&lt; This, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type, remove_reference&lt; A3 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="funop"><template>
+ </template><specialization><template-arg>Expr(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4&lt; This, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type, remove_reference&lt; A3 &gt;::type &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization><struct-specialization name="funop"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="This"/>
- </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4&lt; This const , remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type, remove_reference&lt; A3 &gt;::type &gt;</inherit></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/extends.hpp"><para>Macros and a base class for defining end-user expression types </para><namespace name="boost"><namespace name="proto"><namespace name="exprns_"><struct name="is_proto_expr"><purpose>Empty type to be used as a dummy template parameter of POD expression wrappers. It allows argument-dependent lookup to find Proto's operator overloads. </purpose><description><para><computeroutput>proto::is_proto_expr</computeroutput> allows argument-dependent lookup
 to find Proto's operator overloads. For example:</para><para><programlisting>
-
-
-
-
-
-
-
-
-
-
-
-
-///
+ </template><specialization><template-arg>Expr const (A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg><template-arg>This</template-arg></specialization><inherit access="public">boost::proto::result_of::funop4&lt; Expr, A0, A1, A2, A3 &gt;</inherit><purpose>A helper metafunction for computing the return type of <computeroutput>proto::expr&lt;&gt;operator()</computeroutput>. </purpose></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/extends.hpp"><para>Macros and a base class for defining end-user expression types </para><namespace name="boost"><namespace name="proto"><namespace name="exprns_"><struct name="is_proto_expr"><purpose>Empty type to be used as a dummy template parameter of POD expression wrappers. It allows argument-dependent lookup to find Proto's operator overloads. </purpose><description><para><computeroutput>proto::is_proto_expr</computeroutput> allows argument-dependent loo
kup to find Proto's operator overloads. For example:</para><para><programlisting> template&lt;typename T, typename Dummy = proto::is_proto_expr&gt;
+ struct my_terminal
+ {
+ BOOST_PROTO_EXTENDS(
+ typename proto::terminal&lt;T&gt;::type
+ , my_terminal&lt;T&gt;
+ , default_domain
+ )
+ };
+
+ // ...
+ my_terminal&lt;int&gt; _1, _2;
+ _1 + _2; // OK, uses proto::operator+
 </programlisting></para><para>Without the second <computeroutput>Dummy</computeroutput> template parameter, Proto's operator overloads would not be considered by name lookup. </para></description></struct><struct name="extends"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Derived"/>
       <template-type-parameter name="Domain"/>
       <template-type-parameter name="Tag"/>
- </template><purpose>extends&lt;&gt; class template for adding behaviors to a proto expression template </purpose><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><purpose>extends&lt;&gt; class template for adding behaviors to a Proto expression template </purpose><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><typedef name="type"><type>boost::mpl::apply_wrap1&lt; Domain, typename boost::proto::result_of::funop&lt; Sig, Derived &gt;::type &gt;::type</type></typedef></struct><typedef name="proto_base_expr"><type>Expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></t
ypedef><method-group name="public member functions"><method name="proto_base" cv=""><type>Expr &amp;</type></method><method name="proto_base" cv="const"><type>Expr const &amp;</type></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1&lt; Domain, boost::proto::expr&lt; <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>&lt; boost::proto::ref_&lt; Derived const &gt;, typename <classname>boost::proto::result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; &gt;::type const</type><template>
+ </template><typedef name="type"><type>boost::mpl::apply_wrap1&lt; Domain, typename boost::proto::result_of::funop&lt; Sig, Derived &gt;::type &gt;::type</type></typedef></struct><data-member name="expr"><type>Expr</type></data-member><typedef name="proto_base_expr"><type>Expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><ty
pedef name="proto_arg4"><type>Expr::proto_arg4</type></typedef><method-group name="public member functions"><method name="proto_base" cv=""><type>Expr &amp;</type></method><method name="proto_base" cv="const"><type>Expr const &amp;</type></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1&lt; Domain, boost::proto::expr&lt; <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>&lt; boost::proto::ref_&lt; Derived const &gt;, typename <classname>boost::proto::result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; &gt;::type const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1&lt; Domain, boost::proto::expr&lt; <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>&lt; boost::proto::ref_&lt; Derived const &gt;, typename <classname>boost::proto::result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; &gt;::type const</type><template>
           <template-type-parameter name="A"/>
@@ -685,21 +663,13 @@
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter></copy-assignment><data-member name="expr"><type>Expr</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static Derived const</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="extends"><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static Derived const</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="extends"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Derived"/>
       <template-type-parameter name="Domain"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>Derived</template-arg><template-arg>Domain</template-arg><template-arg>tag::terminal</template-arg></specialization><purpose>extends&lt;&gt; class template for adding behaviors to a proto expression template </purpose><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><struct name="result"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>Derived</template-arg><template-arg>Domain</template-arg><template-arg>tag::terminal</template-arg></specialization><purpose>extends&lt;&gt; class template for adding behaviors to a Proto expression template </purpose><struct name="result"><template>
       <template-type-parameter name="Sig"/>
- </template><typedef name="type"><type>boost::mpl::apply_wrap1&lt; Domain, typename boost::proto::result_of::funop&lt; Sig, Derived &gt;::type &gt;::type</type></typedef></struct><typedef name="proto_base_expr"><type>Expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></t
ypedef><method-group name="public member functions"><method name="extends" cv=""><type/></method><method name="extends" cv=""><type/><parameter name="that"><paramtype><classname>extends</classname> const &amp;</paramtype></parameter></method><method name="extends" cv=""><type/><parameter name="expr_"><paramtype>Expr const &amp;</paramtype></parameter></method><method name="proto_base" cv=""><type>Expr &amp;</type></method><method name="proto_base" cv="const"><type>Expr const &amp;</type></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1&lt; Domain, boost::proto::expr&lt; <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>&lt; boost::proto::ref_&lt; Derived const &gt;, typename <classname>boost::proto::result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; &gt;::type const</type><template>
+ </template><typedef name="type"><type>boost::mpl::apply_wrap1&lt; Domain, typename boost::proto::result_of::funop&lt; Sig, Derived &gt;::type &gt;::type</type></typedef></struct><data-member name="expr"><type>Expr</type></data-member><typedef name="proto_base_expr"><type>Expr</type></typedef><typedef name="proto_domain"><type>Domain</type></typedef><typedef name="proto_derived_expr"><type>Derived</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="fusion_tag"><type>boost::proto::tag::proto_expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><ty
pedef name="proto_arg4"><type>Expr::proto_arg4</type></typedef><method-group name="public member functions"><method name="extends" cv=""><type/></method><method name="extends" cv=""><type/><parameter name="that"><paramtype><classname>extends</classname> const &amp;</paramtype></parameter></method><method name="extends" cv=""><type/><parameter name="expr_"><paramtype>Expr const &amp;</paramtype></parameter></method><method name="proto_base" cv=""><type>Expr &amp;</type></method><method name="proto_base" cv="const"><type>Expr const &amp;</type></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1&lt; Domain, boost::proto::expr&lt; <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>&lt; boost::proto::ref_&lt; Derived const &gt;, typename <classname>boost::proto::result_of::as_arg</classname>&lt; A &gt;::type &gt; &gt; &gt;::type const</type><template>
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter></method><method name="operator[]" cv="const"><type>boost::mpl::apply_wrap1&lt; Domain, boost::proto::expr&lt; <classname>boost::proto::tag::subscript</classname>, <classname>boost::proto::args2</classname>&lt; boost::proto::ref_&lt; Derived const &gt;, typename <classname>boost::proto::result_of::as_arg</classname>&lt; A const &gt;::type &gt; &gt; &gt;::type const</type><template>
           <template-type-parameter name="A"/>
@@ -743,174 +713,118 @@
           <template-type-parameter name="A"/>
         </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter></copy-assignment><copy-assignment><template>
           <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter></copy-assignment><data-member name="expr"><type>Expr</type></data-member><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method><method name="make" cv=""><type>static Derived const</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/fusion.hpp"><para>Make any Proto parse tree a valid Fusion sequence </para><namespace name="boost"><namespace name="fusion"><namespace name="extension"><struct name="as_element"><template>
- <template-type-parameter name="Tag"/>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter></copy-assignment><method-group name="public static functions"><method name="make" cv=""><type>static Derived const</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/fusion.hpp"><para>Make any Proto expression a valid Fusion sequence </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="flatten"><purpose>A PolymorphicFunctionObject type that returns a "flattened" view of a Proto expression tree. </purpose><description><para>A PolymorphicFunctionObject type that returns a "flattened" view of a Proto expression tree. For a tree with a top-most node tag of type <computeroutput>T</computeroutput>, the elements of the flattened sequence are determined by recursing into each child node with the same tag type and returning those
nodes of different type. So for instance, the Proto expression tree corresponding to the expression <computeroutput>a | b | c</computeroutput> has a flattened view with elements [a, b, c], even though the tree is grouped as <computeroutput>((a | b) | c)</computeroutput>. </para></description><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization></struct><struct-specialization name="is_view_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template></struct></struct-specialization><struct-specialization name="is_view_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template></struct></struct-specialization><struct-specialization name="value_of_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template><inherit access="public">boost::proto::result_of::arg&lt; Iterator::expr_type, Iterator::index &gt;</inherit></struct></struct-specialization><struct-specialization name="deref_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template><typedef name="type"><type><classname>proto::result_of::arg</classname>&lt; typename Iterator::expr_type, typename Iterator::index &gt;::type const &amp;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><parameter name="iter"><paramtype>Iterator const &amp;</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="advance_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- <template-type-parameter name="N"/>
- </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><parameter name="iter"><paramtype>Iterator const &amp;</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="distance_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="IteratorFrom"/>
- <template-type-parameter name="IteratorTo"/>
- </template></struct></struct-specialization><struct-specialization name="next_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template></struct></struct-specialization><struct-specialization name="prior_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref_iterator</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template></struct></struct-specialization><struct-specialization name="category_of_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template><typedef name="type"><type>random_access_traversal_tag</type></typedef></struct></struct-specialization><struct-specialization name="size_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template></struct></struct-specialization><struct-specialization name="begin_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><parameter name="seq"><paramtype>Sequence &amp;</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="end_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><parameter name="seq"><paramtype>Sequence &amp;</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="value_at_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- <template-type-parameter name="N"/>
- </template><typedef name="type"><type><classname>proto::result_of::arg</classname>&lt; Sequence, N &gt;::type</type></typedef></struct></struct-specialization><struct-specialization name="at_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_ref</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- <template-type-parameter name="N"/>
- </template><typedef name="type"><type><classname>proto::result_of::arg</classname>&lt; Sequence, N &gt;::type const &amp;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><parameter name="seq"><paramtype>Sequence &amp;</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="is_segmented_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Iterator"/>
- </template></struct></struct-specialization><struct-specialization name="segments_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template><typedef name="proto_tag"><type>Sequence::proto_tag</type></typedef><typedef name="type"><type>fusion::transform_view&lt; proto::ref_&lt; Sequence &gt;, <classname>as_element</classname>&lt; proto_tag &gt;&gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><parameter name="sequence"><paramtype>Sequence &amp;</paramtype></parameter></method></method-group></struct></struct-specialization><struct-specialization name="category_of_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template><typedef name="type"><type>forward_traversal_tag</type></typedef></struct></struct-specialization><struct-specialization name="begin_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template></struct></struct-specialization><struct-specialization name="end_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template></struct></struct-specialization><struct-specialization name="size_impl"><template>
- </template><specialization><template-arg>proto::tag::proto_expr</template-arg></specialization><struct name="apply"><template>
- <template-type-parameter name="Sequence"/>
- </template></struct></struct-specialization></namespace></namespace><namespace name="proto"><struct name="children"><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><emphasis>unspecified</emphasis></type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="pop_front"><purpose>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::pop_front()</computeroutput> algorithm on its argument. </purpose><description><para>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::pop_front()</computeroutput> algorithm on its argument. This is useful for defining a CallableTransform like <computeroutput>pop_front(_)</computeroutput> which removes the first child from a Proto expression node. Such a transform might be used as the first argument to the <computeroutput>proto::transform::fold&lt;&gt;</computeroutput> transform; that is, fold all but the first child. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><method-group name="public member functions"/><constructor><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></constructor></struct><struct name="eval_fun"><template>
- <template-type-parameter name="Context"/>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>fusion::result_of::pop_front&lt; typename boost::remove_reference&lt; Expr &gt;::type const &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>fusion::result_of::pop_front&lt; Expr const &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="reverse"><purpose>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::reverse()</computeroutput> algorithm on its argument. </purpose><description><para>A PolymorphicFunctionObject type that invokes the <computeroutput>fusion::reverse()</computeroutput> algorithm on its argument. This is useful for defining a CallableTransform like <computeroutput>reverse(_)</computeroutput> which reverses the order of the children of a Proto expression node. </para></description><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>Context::template eval&lt; typename remove_reference&lt; Expr &gt;::type &gt;::result_type</type></typedef></struct-specialization><method-group name="public member functions"/><constructor><parameter name="ctx"><paramtype>Context &amp;</paramtype></parameter></constructor></struct><function name="children_of"><type><classname>children</classname>&lt; Expr &gt;</type><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><typedef name="type"><type>fusion::result_of::reverse&lt; typename boost::remove_reference&lt; Expr &gt;::type const &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>fusion::result_of::reverse&lt; Expr const &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></function></namespace></namespace></header><header name="boost/xpressive/proto/generate.hpp"><para>Contains definition of generate&lt;&gt; class template, which end users can specialize for generating domain-specific expression wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="generatorns_"><struct name="default_generator"><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct></namespace><data-member name="flatten"><type><classname>functional::flatten</classname> const</type><purpose>A PolymorphicFunctionObject type that returns a "flattened" view of a Proto expression tree. </purpose><description><para><para>boost::proto::functional::flatten </para>
+</para></description></data-member></namespace></namespace></header><header name="boost/xpressive/proto/generate.hpp"><para>Contains definition of generate&lt;&gt; class template, which end users can specialize for generating domain-specific expression wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="generatorns_"><struct name="default_generator"><purpose>A simple generator that passes an expression through unchanged. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. The <computeroutput>default_generator</computeroutput> makes no modifications to the expressions passed to it. </para></description><struct name="apply"><template>
       <template-type-parameter name="Expr"/>
     </template><typedef name="type"><type>Expr</type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static Expr const &amp;</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="generator"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>A Proto expression </para></description></parameter><description><para>
+
+</para></description><returns><para>expr </para></returns></method></method-group></struct><struct name="generator"><template>
       <template-nontype-parameter name="Extends"><type>template&lt; typename &gt; class</type></template-nontype-parameter>
- </template><struct name="apply"><template>
+ </template><purpose>A generator that wraps expressions passed to it in the specified extension wrapper. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>generator&lt;&gt;</computeroutput> wraps each expression passed to it in the <computeroutput>Extends&lt;&gt;</computeroutput> wrapper. </para></description><struct name="apply"><template>
       <template-type-parameter name="Expr"/>
     </template><typedef name="type"><type>Extends&lt; Expr &gt;</type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static Extends&lt; Expr &gt;</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="pod_generator"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>A Proto expression </para></description></parameter><description><para>
+
+</para></description><returns><para>Extends&lt;Expr&gt;(expr) </para></returns></method></method-group></struct><struct name="pod_generator"><template>
       <template-nontype-parameter name="Extends"><type>template&lt; typename &gt; class</type></template-nontype-parameter>
- </template><struct name="apply"><template>
+ </template><purpose>A generator that wraps expressions passed to it in the specified extension wrapper and uses aggregate initialization for the wrapper. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>pod_generator&lt;&gt;</computeroutput> wraps each expression passed to it in the <computeroutput>Extends&lt;&gt;</computeroutput> wrapper, and uses aggregate initialzation for the wrapped object. </para></description><struct name="apply"><template>
       <template-type-parameter name="Expr"/>
     </template><typedef name="type"><type>Extends&lt; Expr &gt;</type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static Extends&lt; Expr &gt;</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/literal.hpp"><para>The literal&lt;&gt; terminal wrapper, and the proto::lit() function for creating literal&lt;&gt; wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="utility"><struct name="literal"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The expression to wrap </para></description></parameter><description><para>
+
+</para></description><returns><para>Extends&lt;Expr&gt; that = {expr}; return that; </para></returns></method></method-group></struct><struct name="by_value_generator"><template>
+ <template-type-parameter name="Generator"/>
+ </template><purpose>A composite generator that first replaces child nodes held by reference with ones held by value and then forwards the result on to another generator. </purpose><description><para>Generators are intended for use as the first template parameter to the <computeroutput>domain&lt;&gt;</computeroutput> class template and control if and how expressions within that domain are to be customized. <computeroutput>by_value_generator&lt;&gt;</computeroutput> ensures all children nodes are held by value before forwarding the expression on to another generator for further processing. The <computeroutput>Generator</computeroutput> parameter defaults to <computeroutput>default_generator</computeroutput>. </para></description><struct name="apply"><template>
+ <template-type-parameter name="Expr"/>
+ </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct><method-group name="public static functions"><method name="make" cv=""><type>static <classname>apply</classname>&lt; Expr &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>The expression to modify. </para></description></parameter><description><para>
+
+</para></description><returns><para>Generator::make(deep_copy(expr)) </para></returns></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/literal.hpp"><para>The literal&lt;&gt; terminal wrapper, and the proto::lit() function for creating literal&lt;&gt; wrappers. </para><namespace name="boost"><namespace name="proto"><namespace name="utility"><struct name="literal"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="Domain"/>
- </template><inherit access="public">boost::proto::exprns_::extends&lt; Expr, Derived, Domain, Tag &gt;</inherit><typedef name="terminal_type"><type><classname>terminal</classname>&lt; T &gt;::type</type></typedef><typedef name="base_type"><type><classname>extends</classname>&lt; terminal_type, <classname>literal</classname>&lt; T, Domain &gt;, Domain &gt;</type></typedef><method-group name="public member functions"/><constructor><template>
+ </template><purpose>A simple wrapper for a terminal, provided for ease of use. </purpose><description><para>A simple wrapper for a terminal, provided for ease of use. In all cases, <computeroutput>literal&lt;X&gt; l(x);</computeroutput> is equivalent to <computeroutput>terminal&lt;X&gt;type l = {x};</computeroutput>.</para><para>The <computeroutput>Domain</computeroutput> template parameter defaults to <computeroutput>proto::default_domain</computeroutput>. </para></description><typedef name="value_type"><type><classname>proto::result_of::arg</classname>&lt; terminal_type &gt;::type</type></typedef><typedef name="reference"><type><classname>proto::result_of::arg</classname>&lt; terminal_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>proto::result_of::arg</classname>&lt; terminal_type &gt;::const_reference</type></typedef><method-group name="public member functions"><method name="get" cv=""><type>reference</type></method><method name="get" cv="const"><type>const_ref
erence</type></method></method-group><constructor><template>
           <template-type-parameter name="U"/>
         </template><parameter name="u"><paramtype>U &amp;</paramtype></parameter></constructor><constructor><template>
           <template-type-parameter name="U"/>
         </template><parameter name="u"><paramtype>U const &amp;</paramtype></parameter></constructor><constructor><template>
           <template-type-parameter name="U"/>
- </template><parameter name="u"><paramtype><classname>literal</classname>&lt; U, Domain &gt; const &amp;</paramtype></parameter></constructor></struct></namespace><overloaded-function name="lit"><signature><type><classname>literal</classname>&lt; T &amp; &gt;</type><template>
+ </template><parameter name="u"><paramtype><classname>literal</classname>&lt; U, Domain &gt; const &amp;</paramtype></parameter></constructor></struct></namespace><overloaded-function name="lit"><signature><type>literal&lt; T &amp; &gt;</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype>T &amp;</paramtype></parameter></signature><signature><type><classname>literal</classname>&lt; T const &amp; &gt;</type><template>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype><description><para>The object to wrap. </para></description></parameter></signature><signature><type>literal&lt; T const &amp; &gt;</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><description><para>lit </para></description></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/make_expr.hpp"><para>Given a Fusion sequence of arguments and the type of a proto Expression, unpacks the sequence into the Expression. </para><namespace name="boost"><namespace name="fusion"/><namespace name="proto"><namespace name="functional"><struct name="make_expr"><template>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><purpose>A helper function for creating a <computeroutput>literal&lt;&gt;</computeroutput> wrapper. </purpose><description><para>
+
+
+
+</para></description><returns><para>literal&lt;T &amp;&gt;(t) </para></returns><throws><simpara>Will not throw.</simpara></throws><notes><para>The returned value holds the argument by reference. </para></notes></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/make_expr.hpp"><para>Definition of the <computeroutput>make_expr()</computeroutput> and <computeroutput>unpack_expr()</computeroutput> utilities for building Proto expression nodes from children nodes or from a Fusion sequence of children nodes, respectively. </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="make_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Domain"/>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="A0"/>
- </template><specialization><template-arg>This(A0)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr&lt; Tag, Domain, remove_reference&lt; A0 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="result"><template>
+ </template><specialization><template-arg>This(A0)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
- </template><specialization><template-arg>This(A0</template-arg><template-arg>A1)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr&lt; Tag, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="result"><template>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
- </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr&lt; Tag, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="result"><template>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1, A2 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
- </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr&lt; Tag, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type, remove_reference&lt; A3 &gt;::type &gt;</inherit></struct-specialization><struct-specialization name="result"><template>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1, A2, A3 &gt;::type</type></typedef></struct-specialization><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="A4"/>
- </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr&lt; Tag, Domain, remove_reference&lt; A0 &gt;::type, remove_reference&lt; A1 &gt;::type, remove_reference&lt; A2 &gt;::type, remove_reference&lt; A3 &gt;::type, remove_reference&lt; A4 &gt;::type &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A &gt;::type const</type><template>
- <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0 &gt;::type const</type><template>
+ </template><specialization><template-arg>This(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><typedef name="type"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0, A1, A2, A3, A4 &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, A0 const &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1 &gt;::type const</type><template>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><description><para>Construct an expression node with tag type <computeroutput>Tag</computeroutput> and in the domain <computeroutput>Domain</computeroutput>. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2 &gt;::type const</type><template>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2, const A3 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
           <template-type-parameter name="A3"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2, const A3, const A4 &gt;::type const</type><template>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const A0, const A1, const A2, const A3, const A4 &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
           <template-type-parameter name="A3"/>
           <template-type-parameter name="A4"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter><parameter name="a4"><paramtype>const A4 &amp;</paramtype></parameter></method></method-group></struct><struct name="unpack_expr"><template>
+ </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><parameter name="a3"><paramtype>const A3 &amp;</paramtype></parameter><parameter name="a4"><paramtype>const A4 &amp;</paramtype></parameter><description><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></method></method-group></struct><struct name="unpack_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Domain"/>
     </template><struct name="result"><template>
@@ -918,55 +832,27 @@
     </template></struct><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Sequence"/>
- </template><specialization><template-arg>This(Sequence)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence &gt;::type</type><template>
+ </template><specialization><template-arg>This(Sequence)</template-arg></specialization><typedef name="type"><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, typename remove_reference&lt; Sequence &gt;::type &gt;::type</type></typedef></struct-specialization><typedef name="proto_is_callable_"><type>void</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence const &gt;::type const</type><template>
           <template-type-parameter name="Sequence"/>
- </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype></parameter></method></method-group></struct><struct name="unfused_expr_fun"><template>
+ </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="result_of"><struct name="unpack_expr"><template>
       <template-type-parameter name="Tag"/>
- <template-type-parameter name="Domain"/>
- </template><struct name="result"><template>
       <template-type-parameter name="Sequence"/>
- </template><inherit access="public">boost::proto::result_of::unpack_expr&lt; Tag, Domain, Sequence &gt;</inherit></struct><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>proto::result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence &gt;::type</type><template>
- <template-type-parameter name="Sequence"/>
- </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype></parameter></method></method-group></struct><struct name="unfused_expr"><template>
+ <template-type-parameter name="EnableIf1"/>
+ <template-type-parameter name="EnableIf2"/>
+ </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct><struct-specialization name="unpack_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Domain"/>
- </template></struct><struct-specialization name="make_expr"><template>
- <template-type-parameter name="Domain"/>
- </template><specialization><template-arg>tag::terminal</template-arg><template-arg>Domain</template-arg></specialization><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
- <template-type-parameter name="This"/>
- <template-type-parameter name="A"/>
- </template><specialization><template-arg>This(A)</template-arg></specialization><inherit access="public">boost::proto::result_of::make_expr&lt; tag::terminal, Domain, A &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; <classname>tag::terminal</classname>, Domain, A &gt;::type</type><template>
- <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::make_expr</classname>&lt; <classname>tag::terminal</classname>, Domain, A const &gt;::type</type><template>
- <template-type-parameter name="A"/>
- </template><parameter name="a"><paramtype>A const &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace><namespace name="result_of"><struct name="unpack_expr"><template>
- <template-type-parameter name="Tag"/>
       <template-type-parameter name="Sequence"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template></struct><struct name="make_expr"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>Sequence</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct name="make_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="A4"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template></struct><struct-specialization name="make_expr"><template>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="A0"/>
- <template-type-parameter name="A1"/>
- <template-type-parameter name="A2"/>
- <template-type-parameter name="A3"/>
- <template-type-parameter name="A4"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>deduce_domain</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization></struct-specialization><struct-specialization name="unpack_expr"><template>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="Domain"/>
- <template-type-parameter name="Sequence"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>Sequence</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization></struct-specialization><struct-specialization name="make_expr"><template>
+ <template-type-parameter name="EnableIf1"/>
+ <template-type-parameter name="EnableIf2"/>
+ </template><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct><struct-specialization name="make_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="Domain"/>
       <template-type-parameter name="A0"/>
@@ -974,28 +860,21 @@
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="A4"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization></struct-specialization></namespace><overloaded-function name="unpack_expr"><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; Sequence &gt;, <classname>result_of::unpack_expr</classname>&lt; Tag, Sequence &gt;&gt;::type const</type><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>Domain</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>typename Domain::proto_is_domain_</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization></namespace><overloaded-function name="unpack_expr"><signature><type>lazy_disable_if&lt; is_domain&lt; Sequence &gt;, <classname>result_of::unpack_expr</classname>&lt; Tag, Sequence const &gt;&gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="Sequence"/>
- </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype></parameter></signature><signature><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence2 &gt;::type const</type><template>
+ </template><parameter name="sequence"><paramtype>Sequence const &amp;</paramtype></parameter></signature><signature><type><classname>result_of::unpack_expr</classname>&lt; Tag, Domain, Sequence2 const &gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="Domain"/>
           <template-type-parameter name="Sequence2"/>
- </template><parameter name="sequence2"><paramtype>Sequence2 const &amp;</paramtype></parameter></signature><description><para>unpack_expr </para></description></overloaded-function><overloaded-function name="make_expr"><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, A0 &gt;&gt;::type const</type><template>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="A0"/>
- </template><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, B0 &gt;::type const</type><template>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="Domain"/>
- <template-type-parameter name="B0"/>
- </template><parameter name="b0"><paramtype>B0 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0 &gt;&gt;::type const</type><template>
+ </template><parameter name="sequence2"><paramtype>Sequence2 const &amp;</paramtype></parameter></signature><description><para>unpack_expr </para></description></overloaded-function><overloaded-function name="make_expr"><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, A0 const &gt;&gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="A0"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, const B0 &gt;::type const</type><template>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter></signature><signature><type><classname>result_of::make_expr</classname>&lt; Tag, Domain, B0 const &gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="Domain"/>
           <template-type-parameter name="B0"/>
- </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1 &gt;&gt;::type const</type><template>
+ </template><parameter name="b0"><paramtype>B0 const &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1 &gt;&gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
@@ -1004,7 +883,7 @@
           <template-type-parameter name="Domain"/>
           <template-type-parameter name="B0"/>
           <template-type-parameter name="B1"/>
- </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2 &gt;&gt;::type const</type><template>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2 &gt;&gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
@@ -1015,7 +894,7 @@
           <template-type-parameter name="B0"/>
           <template-type-parameter name="B1"/>
           <template-type-parameter name="B2"/>
- </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2, const A3 &gt;&gt;::type const</type><template>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2, const A3 &gt;&gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
@@ -1028,7 +907,7 @@
           <template-type-parameter name="B1"/>
           <template-type-parameter name="B2"/>
           <template-type-parameter name="B3"/>
- </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter><parameter name="b3"><paramtype>const B3 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; <classname>is_domain</classname>&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2, const A3, const A4 &gt;&gt;::type const</type><template>
+ </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter><parameter name="b3"><paramtype>const B3 &amp;</paramtype></parameter></signature><signature><type>lazy_disable_if&lt; is_domain&lt; A0 &gt;, <classname>result_of::make_expr</classname>&lt; Tag, const A0, const A1, const A2, const A3, const A4 &gt;&gt;::type const</type><template>
           <template-type-parameter name="Tag"/>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
@@ -1045,16 +924,54 @@
           <template-type-parameter name="B4"/>
         </template><parameter name="b0"><paramtype>const B0 &amp;</paramtype></parameter><parameter name="b1"><paramtype>const B1 &amp;</paramtype></parameter><parameter name="b2"><paramtype>const B2 &amp;</paramtype></parameter><parameter name="b3"><paramtype>const B3 &amp;</paramtype></parameter><parameter name="b4"><paramtype>const B4 &amp;</paramtype></parameter></signature><description><para>make_expr </para></description></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/matches.hpp"><para>Contains definition of matches&lt;&gt; metafunction for determining if a given expression matches a given pattern. </para><namespace name="boost"><namespace name="proto"><namespace name="control"><struct name="not_"><template>
       <template-type-parameter name="Grammar"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="proto_base_expr"><type><classname>not_</classname></type></typedef></struct><struct name="if_"><template>
- <template-type-parameter name="Condition"/>
+ </template><purpose>Inverts the set of expressions matched by a grammar. When used as a transform, <computeroutput>not_&lt;&gt;</computeroutput> returns the current expression unchanged. </purpose><description><para>If an expression type <computeroutput>E</computeroutput> does not match a grammar <computeroutput>G</computeroutput>, then <computeroutput>E</computeroutput> does match <computeroutput>not_&lt;G&gt;</computeroutput>. For example, <computeroutput>not_&lt;terminal&lt;_&gt; &gt;</computeroutput> will match any non-terminal. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>not_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,not_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>expr</computeroutput> </para></returns></method></method-group></struct><struct name="if_"><template>
+ <template-type-parameter name="If"/>
       <template-type-parameter name="Then"/>
       <template-type-parameter name="Else"/>
- </template><inherit access="public">boost::proto::control::or_&lt; and_&lt; if_&lt; Condition &gt;, Then &gt;, and_&lt; not_&lt; if_&lt; Condition &gt; &gt;, Else &gt; &gt;</inherit></struct><struct-specialization name="if_"><template>
- <template-type-parameter name="Condition"/>
- <template-type-parameter name="Then"/>
- </template><specialization><template-arg>Condition</template-arg><template-arg>Then</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::control::and_&lt; if_&lt; Condition &gt;, Then &gt;</inherit></struct-specialization><struct-specialization name="if_"><template>
- <template-type-parameter name="Condition"/>
- </template><specialization><template-arg>Condition</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="proto_base_expr"><type><classname>if_</classname></type></typedef></struct-specialization><struct name="or_"><template>
+ </template><purpose>Used to select one grammar or another based on the result of a compile-time Boolean. When used as a transform, <computeroutput>if_&lt;&gt;</computeroutput> selects between two transforms based on a compile-time Boolean. </purpose><description><para>When <computeroutput>if_&lt;If,Then,Else&gt;</computeroutput> is used as a grammar, <computeroutput>If</computeroutput> must be a Proto transform and <computeroutput>Then</computeroutput> and <computeroutput>Else</computeroutput> must be grammars. An expression type <computeroutput>E</computeroutput> matches <computeroutput>if_&lt;If,Then,Else&gt;</computeroutput> if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>U</computeroutput>; or, if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>false</computeroutput> and <computeroutpu
t>E</computeroutput> matches <computeroutput>V</computeroutput>.</para><para>The template parameter <computeroutput>Then</computeroutput> defaults to <computeroutput>_</computeroutput> and <computeroutput>Else</computeroutput> defaults to <computeroutput>not&lt;_&gt;</computeroutput>, so an expression type <computeroutput>E</computeroutput> will match <computeroutput>if_&lt;If&gt;</computeroutput> if and only if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput>.</para><para><programlisting> // A grammar that only matches integral terminals,
+ // using is_integral&lt;&gt; from Boost.Type_traits.
+ struct IsIntegral
+ : and_&lt;
+ terminal&lt;_&gt;
+ , if_&lt; is_integral&lt;_arg&gt;() &gt;
+ &gt;
+ {};
+</programlisting></para><para>When <computeroutput>if_&lt;If,Then,Else&gt;</computeroutput> is used as a transform, <computeroutput>If</computeroutput>, <computeroutput>Then</computeroutput> and <computeroutput>Else</computeroutput> must be Proto transforms. When applying the transform to an expression <computeroutput>E</computeroutput>, state <computeroutput>S</computeroutput> and visitor <computeroutput>V</computeroutput>, if <computeroutput>when&lt;_,If&gt;::result&lt;void(E,S,V)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput> then the <computeroutput>Then</computeroutput> transform is applied; otherwise the <computeroutput>Else</computeroutput> transform is applied.</para><para><programlisting> // Match a terminal. If the terminal is integral, return
+ // mpl::true_; otherwise, return mpl::false_.
+ struct IsIntegral2
+ : when&lt;
+ terminal&lt;_&gt;
+ , if_&lt;
+ is_integral&lt;_arg&gt;()
+ , mpl::true_()
+ , mpl::false_()
+ &gt;
+ &gt;
+ {};
+</programlisting> </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="condition"><type>when&lt; _, If &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef><typedef name="which"><type>mpl::if_&lt; condition, when&lt; _, Then &gt;, when&lt; _, Else &gt;&gt;::type</type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>if_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype><description><para>A visitor of arbitrary type </para></description></parameter><description><para>
+
+</para></description><returns><para><computeroutput>result&lt;void(Expr, State, Visitor)&gt;::which()(expr, state, visitor)</computeroutput> </para></returns></method></method-group></struct><struct name="or_"><template>
       <template-type-parameter name="G0"/>
       <template-type-parameter name="G1"/>
       <template-type-parameter name="G2"/>
@@ -1063,15 +980,19 @@
       <template-type-parameter name="G5"/>
       <template-type-parameter name="G6"/>
       <template-type-parameter name="G7"/>
- </template><struct name="apply"><template>
+ </template><purpose>For matching one of a set of alternate grammars. Alternates tried in order to avoid ambiguity. When used as a transform, <computeroutput>or_&lt;&gt;</computeroutput> applies the transform associated with the first grammar that matches the expression. </purpose><description><para>An expression type <computeroutput>E</computeroutput> matches <computeroutput>or_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches any <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>.</para><para>When applying <computeroutput>or_&lt;B0,B1,...Bn&gt;</computeroutput> as a transform with an expression <computeroutput>e</computeroutput> of type <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> and visitor <computeroutput>v</computeroutput>, it is equivalent to <computeroutput>Bx()(e, s, v)</computeroutput>, where <computeroutput>x</computeroutput> is the lowest number such that <compute
routput>matches&lt;E,Bx&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type></typedef></struct><typedef name="proto_base_expr"><type><classname>or_</classname></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>or_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="and_"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype><description><para>A visitor of arbitrary type </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,or_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Visitor)&gt;::which()(expr, state, visitor)</computeroutput> </para></returns></method></method-group></struct><struct name="and_"><template>
       <template-type-parameter name="G0"/>
       <template-type-parameter name="G1"/>
       <template-type-parameter name="G2"/>
@@ -1080,38 +1001,109 @@
       <template-type-parameter name="G5"/>
       <template-type-parameter name="G6"/>
       <template-type-parameter name="G7"/>
- </template><struct name="apply"><template>
+ </template><purpose>For matching all of a set of grammars. When used as a transform, <computeroutput>and_&lt;&gt;</computeroutput> applies the transform associated with the last grammar in the set. </purpose><description><para>An expression type <computeroutput>E</computeroutput> matches <computeroutput>and_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches all <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>.</para><para>When applying <computeroutput>and_&lt;B0,B1,...Bn&gt;</computeroutput> as a transform with an expression <computeroutput>e</computeroutput>, state <computeroutput>s</computeroutput> and visitor <computeroutput>v</computeroutput>, it is equivalent to <computeroutput>Bn()(e, s, v)</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type></typedef></struct><typedef name="proto_base_expr"><type><classname>and_</classname></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="which"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>and_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="switch_"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype><description><para>A visitor of arbitrary type </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,and_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Visitor)&gt;::which()(expr, state, visitor)</computeroutput> </para></returns></method></method-group></struct><struct name="switch_"><template>
       <template-type-parameter name="Cases"/>
- </template><struct name="apply"><template>
+ </template><purpose>For matching one of a set of alternate grammars, which are looked up based on an expression's tag type. When used as a transform, <computeroutput>switch_&lt;&gt;</computeroutput> applies the transform associated with the grammar that matches the expression. </purpose><description><para>
+An expression type <computeroutput>E</computeroutput> matches <computeroutput>switch_&lt;C&gt;</computeroutput> if <computeroutput>E</computeroutput> matches <computeroutput>C::case_&lt;E::proto_tag&gt;</computeroutput>.</para><para>When applying <computeroutput>switch_&lt;C&gt;</computeroutput> as a transform with an expression <computeroutput>e</computeroutput> of type <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> and visitor <computeroutput>v</computeroutput>, it is equivalent to <computeroutput>C::case_&lt;E::proto_tag&gt;()(e, s, v)</computeroutput>. </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><typedef name="proto_base_expr"><type><classname>switch_</classname></type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="which"><type>Cases::template case_&lt; typename Expr::proto_tag &gt;</type></typedef><typedef name="type"><type>which::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>switch_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="exact"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name="state"><paramtype>State const &amp;</paramtype><description><para>The current state </para></description></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype><description><para>A visitor of arbitrary type </para></description></parameter><description><para>
+
+
+</para></description><requires><para><computeroutput>matches&lt;Expr,switch_&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></requires><returns><para><computeroutput>result&lt;void(Expr, State, Visitor)&gt;::which()(expr, state, visitor)</computeroutput> </para></returns></method></method-group></struct><struct name="exact"><template>
       <template-type-parameter name="T"/>
- </template></struct><struct name="convertible_to"><template>
+ </template><purpose>For forcing exact matches of terminal types. </purpose><description><para>By default, matching terminals ignores references and cv-qualifiers. For instance, a terminal expression of type <computeroutput>terminal&lt;int const &amp;&gt;type</computeroutput> will match the grammar <computeroutput>terminal&lt;int&gt;</computeroutput>. If that is not desired, you can force an exact match with <computeroutput>terminal&lt;exact&lt;int&gt; &gt;</computeroutput>. This will only match integer terminals where the terminal is held by value. </para></description></struct><struct name="convertible_to"><template>
       <template-type-parameter name="T"/>
- </template></struct><struct name="vararg"><template>
+ </template><purpose>For matching terminals that are convertible to a type. </purpose><description><para>Use <computeroutput>convertible_to&lt;&gt;</computeroutput> to match a terminal that is convertible to some type. For example, the grammar <computeroutput>terminal&lt;convertible_to&lt;int&gt; &gt;</computeroutput> will match any terminal whose argument is convertible to an integer.</para><para>
+</para></description></struct><struct name="vararg"><template>
       <template-type-parameter name="Grammar"/>
- </template><typedef name="proto_is_vararg_"><type>void</type></typedef></struct></namespace><namespace name="result_of"><struct name="matches"><template>
+ </template><purpose>For matching a Grammar to a variable number of sub-expressions. </purpose><description><para>An expression type <computeroutput>expr&lt;AT, argsN&lt;A0,...An,U0,...Um&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT, argsM&lt;B0,...Bn,vararg&lt;V&gt; &gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>AT</computeroutput>, and if <computeroutput>Ax</computeroutput> matches <computeroutput>Bx</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput> and if <computeroutput>Ux</computeroutput> matches <computeroutput>V</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,m)</computeroutput>.</para><para>For example:</para><para><programlisting> // Match any function call expression, irregardless
+ // of the number of function arguments:
+ struct Function
+ : function&lt; vararg&lt;_&gt; &gt;
+ {};
+</programlisting></para><para>When used as a transform, <computeroutput>vararg&lt;G&gt;</computeroutput> applies <computeroutput>G</computeroutput>'s transform. </para></description><typedef name="proto_is_vararg_"><type>void</type></typedef></struct></namespace><namespace name="result_of"><struct name="matches"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="Grammar"/>
- </template></struct></namespace><namespace name="wildcardns_"><struct name="_"><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="proto_base_expr"><type><classname>_</classname></type></typedef><typedef name="proto_is_wildcard_"><type>void</type></typedef></struct><function name="is_wildcard_expression_fun"><type><emphasis>unspecified</emphasis></type><template>
- <template-type-parameter name="T"/>
- </template><parameter name=""><paramtype>T const *</paramtype></parameter></function></namespace></namespace></namespace></header><header name="boost/xpressive/proto/operators.hpp"><para>Contains all the overloaded operators that make it possible to build expression templates using proto components </para><namespace name="boost"><namespace name="proto"><struct name="is_extension"><template>
+ </template><purpose>A Boolean metafunction that evaluates whether a given expression type matches a grammar. </purpose><description><para><computeroutput>matches&lt;Expr,Grammar&gt;</computeroutput> inherits (indirectly) from <computeroutput>mpl::true_</computeroutput> if <computeroutput>Expr::proto_base_expr</computeroutput> matches <computeroutput>Grammar::proto_base_expr</computeroutput>, and from <computeroutput>mpl::false_</computeroutput> otherwise.</para><para>Non-terminal expressions are matched against a grammar according to the following rules:</para><para><itemizedlist>
+<listitem><para>The wildcard pattern, <computeroutput>_</computeroutput>, matches any expression. </para></listitem>
+<listitem><para>An expression <computeroutput>expr&lt;AT, argsN&lt;A0,A1,...An&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT, argsN&lt;B0,B1,...Bn&gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>AT</computeroutput>, and if <computeroutput>Ax</computeroutput> matches <computeroutput>Bx</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>expr&lt;AT, argsN&lt;A0,...An,U0,...Um&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT, argsM&lt;B0,...Bn,vararg&lt;V&gt; &gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>AT</computeroutput>, and if <computeroutput>Ax</computeroutput> matches <computeroutput>Bx</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput> and if <computeroutput>Ux</computeroutput> matches <computeroutput>V</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,m)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>or_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches some <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>and_&lt;B0,B1,...Bn&gt;</computeroutput> if <computeroutput>E</computeroutput> matches all <computeroutput>Bx</computeroutput> for <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>if_&lt;T,U,V&gt;</computeroutput> if <computeroutput>when&lt;_,T&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>true</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>U</computeroutput>; or, if <computeroutput>when&lt;_,T&gt;::result&lt;void(E,int,int)&gt;::type::value</computeroutput> is <computeroutput>false</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>V</computeroutput>. (Note: <computeroutput>U</computeroutput> defaults to <computeroutput>_</computeroutput> and <computeroutput>V</computeroutput> defaults to <computeroutput>not&lt;_&gt;</computeroutput>.) </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>not_&lt;T&gt;</computeroutput> if <computeroutput>E</computeroutput> does not match <computeroutput>T</computeroutput>. </para></listitem>
+<listitem><para>An expression <computeroutput>E</computeroutput> matches <computeroutput>switch_&lt;C&gt;</computeroutput> if <computeroutput>E</computeroutput> matches <computeroutput>C::case_&lt;E::proto_tag&gt;</computeroutput>.</para></listitem>
+</itemizedlist>
+A terminal expression <computeroutput>expr&lt;tag::terminal,args0&lt;A&gt; &gt;</computeroutput> matches a grammar <computeroutput>expr&lt;BT,args0&lt;B&gt; &gt;</computeroutput> if <computeroutput>BT</computeroutput> is <computeroutput>_</computeroutput> or <computeroutput>tag::terminal</computeroutput> and one of the following is true:</para><para><itemizedlist>
+<listitem><para><computeroutput>B</computeroutput> is the wildcard pattern, <computeroutput>_</computeroutput> </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>B</computeroutput> </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>B &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>B const &amp;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>exact&lt;A&gt;</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>convertible_to&lt;X&gt;</computeroutput> and <computeroutput>is_convertible&lt;A,X&gt;::value</computeroutput> is <computeroutput>true</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>X[M]</computeroutput> or <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is <computeroutput>X[proto::N]</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is <computeroutput>X(&amp;)[proto::N]</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>A</computeroutput> is <computeroutput>X[M]</computeroutput> or <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is <computeroutput>X*</computeroutput>. </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> lambda-matches <computeroutput>A</computeroutput> (see below).</para></listitem>
+</itemizedlist>
+A type <computeroutput>B</computeroutput> lambda-matches <computeroutput>A</computeroutput> if one of the following is true:</para><para><itemizedlist>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>A</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is the wildcard pattern, <computeroutput>_</computeroutput> </para></listitem>
+<listitem><para><computeroutput>B</computeroutput> is <computeroutput>T&lt;B0,B1,...Bn&gt;</computeroutput> and <computeroutput>A</computeroutput> is <computeroutput>T&lt;A0,A1,...An&gt;</computeroutput> and for each <computeroutput>x</computeroutput> in <computeroutput>[0,n)</computeroutput>, <computeroutput>Ax</computeroutput> and <computeroutput>Bx</computeroutput> are types such that <computeroutput>Ax</computeroutput> lambda-matches <computeroutput>Bx</computeroutput> </para></listitem>
+</itemizedlist>
+</para></description></struct></namespace><namespace name="wildcardns_"><struct name="_"><purpose>A wildcard grammar element that matches any expression, and a transform that returns the current expression unchanged. </purpose><description><para>The wildcard type, <computeroutput>_</computeroutput>, is a grammar element such that <computeroutput>matches&lt;E,_&gt;::value</computeroutput> is <computeroutput>true</computeroutput> for any expression type <computeroutput>E</computeroutput>.</para><para>The wildcard can also be used as a stand-in for a template argument when matching terminals. For instance, the following is a grammar that will match any <computeroutput>std::complex&lt;&gt;</computeroutput> terminal:</para><para><programlisting> BOOST_MPL_ASSERT((
+ matches&lt;
+ terminal&lt;std::complex&lt;double&gt; &gt;::type
+ , terminal&lt;std::complex&lt; _ &gt; &gt;
+ &gt;
+ ));
+</programlisting></para><para>When used as a transform, <computeroutput>_</computeroutput> returns the current expression unchanged. For instance, in the following, <computeroutput>_</computeroutput> is used with the <computeroutput>fold&lt;&gt;</computeroutput> transform to fold the children of a node:</para><para><programlisting> struct CountChildren
+ : or_&lt;
+ // Terminals have no children
+ when&lt;terminal&lt;_&gt;, mpl::int_&lt;0&gt;()&gt;
+ // Use fold&lt;&gt; to count the children of non-terminals
+ , otherwise&lt;
+ fold&lt;
+ _ // &lt;-- fold the current expression
+ , mpl::int_&lt;0&gt;()
+ , mpl::plus&lt;_state, mpl::int_&lt;1&gt; &gt;()
+ &gt;
+ &gt;
+ &gt;
+ {};
+</programlisting> </para></description><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><typedef name="proto_base_expr"><type><classname>_</classname></type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype><description><para>An expression </para></description></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter><description><para>
+
+</para></description><returns><para><computeroutput>expr</computeroutput> </para></returns></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/operators.hpp"><para>Contains all the overloaded operators that make it possible to build Proto expression trees. </para><namespace name="boost"><namespace name="proto"><struct name="is_extension"><template>
       <template-type-parameter name="T"/>
- </template></struct><namespace name="exprns_"><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
+ </template><inherit access="public">boost::mpl::false_</inherit></struct><namespace name="exprns_"><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
           <template-type-parameter name="Arg"/>
         </template><parameter name="arg"><paramtype>Arg &amp;</paramtype></parameter></function><function name="operator+"><type><emphasis>unspecified</emphasis></type><template>
           <template-type-parameter name="Arg"/>
@@ -1511,48 +1503,46 @@
         </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right &amp;</paramtype></parameter></function><function name="operator^="><type><emphasis>unspecified</emphasis></type><template>
           <template-type-parameter name="Left"/>
           <template-type-parameter name="Right"/>
- </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="if_else"><type><classname>boost::proto::result_of::make_expr</classname>&lt; <classname>tag::if_else_</classname>, <classname>deduce_domain</classname>, const A0, const A1, const A2 &gt;::type const</type><template>
+ </template><parameter name="left"><paramtype>Left const &amp;</paramtype></parameter><parameter name="right"><paramtype>Right const &amp;</paramtype></parameter></function><function name="if_else"><type><classname>boost::proto::result_of::make_expr</classname>&lt; <classname>tag::if_else_</classname>, deduce_domain, A0 const &amp;, A1 const &amp;, A2 const &amp; &gt;::type const</type><template>
           <template-type-parameter name="A0"/>
           <template-type-parameter name="A1"/>
           <template-type-parameter name="A2"/>
- </template><parameter name="a0"><paramtype>const A0 &amp;</paramtype></parameter><parameter name="a1"><paramtype>const A1 &amp;</paramtype></parameter><parameter name="a2"><paramtype>const A2 &amp;</paramtype></parameter><description><para>if_else </para></description></function></namespace></namespace></namespace></header><header name="boost/xpressive/proto/proto.hpp"><para>The proto expression template compiler and supporting utilities. </para></header><header name="boost/xpressive/proto/proto_fwd.hpp"><para>Forward declarations of all of proto's public types and functions. </para><namespace name="boost"><namespace name="proto"><namespace name="context"/><namespace name="control"><data-member name="N"><type>int const</type></data-member></namespace><namespace name="domainns_"/><namespace name="exops"/><namespace name="exprns_"/><namespace name="functional"/><namespace name="generatorns_"/><namespace name="has_transformns_"><struct name="has_identity_transform"><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="op"/><namespace name="refns_"/><namespace name="result_of"/><namespace name="tag"/><namespace name="transform"/><namespace name="utility"/><namespace name="wildcardns_"/></namespace></namespace></header><header name="boost/xpressive/proto/ref.hpp"><para>Utility for storing a sub-expr by reference </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="unref"><struct name="result"><template>
- <template-type-parameter name="T"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><parameter name="a0"><paramtype>A0 const &amp;</paramtype></parameter><parameter name="a1"><paramtype>A1 const &amp;</paramtype></parameter><parameter name="a2"><paramtype>A2 const &amp;</paramtype></parameter><description><para>if_else </para></description></function></namespace></namespace></namespace></header><header name="boost/xpressive/proto/proto.hpp"><para>The proto expression template compiler and supporting utilities. </para></header><header name="boost/xpressive/proto/proto_fwd.hpp"><para>Forward declarations of all of proto's public types and functions. </para><namespace name="boost"><namespace name="proto"><namespace name="context"/><namespace name="control"><data-member name="N"><type>int const</type></data-member></namespace><namespace name="domainns_"/><namespace name="exops"/><namespace name="exprns_"/><namespace name="functional"><typedef name="make_terminal"><type><classname>make_expr</classname>&lt; <classname>tag::terminal</classname> &gt;</type></typedef><typedef nam
e="make_posit"><type><classname>make_expr</classname>&lt; <classname>tag::posit</classname> &gt;</type></typedef><typedef name="make_negate"><type><classname>make_expr</classname>&lt; <classname>tag::negate</classname> &gt;</type></typedef><typedef name="make_dereference"><type><classname>make_expr</classname>&lt; <classname>tag::dereference</classname> &gt;</type></typedef><typedef name="make_complement"><type><classname>make_expr</classname>&lt; <classname>tag::complement</classname> &gt;</type></typedef><typedef name="make_address_of"><type><classname>make_expr</classname>&lt; <classname>tag::address_of</classname> &gt;</type></typedef><typedef name="make_logical_not"><type><classname>make_expr</classname>&lt; <classname>tag::logical_not</classname> &gt;</type></typedef><typedef name="make_pre_inc"><type><classname>make_expr</classname>&lt; <classname>tag::pre_inc</classname> &gt;</type></typedef><typedef name="make_pre_dec"><type><classname>make_expr</classname>&lt; <classname>tag::pre_dec</classname> &g
t;</type></typedef><typedef name="make_post_inc"><type><classname>make_expr</classname>&lt; <classname>tag::post_inc</classname> &gt;</type></typedef><typedef name="make_post_dec"><type><classname>make_expr</classname>&lt; <classname>tag::post_dec</classname> &gt;</type></typedef><typedef name="make_shift_left"><type><classname>make_expr</classname>&lt; <classname>tag::shift_left</classname> &gt;</type></typedef><typedef name="make_shift_right"><type><classname>make_expr</classname>&lt; <classname>tag::shift_right</classname> &gt;</type></typedef><typedef name="make_multiplies"><type><classname>make_expr</classname>&lt; <classname>tag::multiplies</classname> &gt;</type></typedef><typedef name="make_divides"><type><classname>make_expr</classname>&lt; <classname>tag::divides</classname> &gt;</type></typedef><typedef name="make_modulus"><type><classname>make_expr</classname>&lt; <classname>tag::modulus</classname> &gt;</type></typedef><typedef name="make_plus"><type><classname>make_expr</classname>&lt; <classna
me>tag::plus</classname> &gt;</type></typedef><typedef name="make_minus"><type><classname>make_expr</classname>&lt; <classname>tag::minus</classname> &gt;</type></typedef><typedef name="make_less"><type><classname>make_expr</classname>&lt; <classname>tag::less</classname> &gt;</type></typedef><typedef name="make_greater"><type><classname>make_expr</classname>&lt; <classname>tag::greater</classname> &gt;</type></typedef><typedef name="make_less_equal"><type><classname>make_expr</classname>&lt; <classname>tag::less_equal</classname> &gt;</type></typedef><typedef name="make_greater_equal"><type><classname>make_expr</classname>&lt; <classname>tag::greater_equal</classname> &gt;</type></typedef><typedef name="make_equal_to"><type><classname>make_expr</classname>&lt; <classname>tag::equal_to</classname> &gt;</type></typedef><typedef name="make_not_equal_to"><type><classname>make_expr</classname>&lt; <classname>tag::not_equal_to</classname> &gt;</type></typedef><typedef name="make_logical_or"><type><classname>make_
expr</classname>&lt; <classname>tag::logical_or</classname> &gt;</type></typedef><typedef name="make_logical_and"><type><classname>make_expr</classname>&lt; <classname>tag::logical_and</classname> &gt;</type></typedef><typedef name="make_bitwise_and"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_and</classname> &gt;</type></typedef><typedef name="make_bitwise_or"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_or</classname> &gt;</type></typedef><typedef name="make_bitwise_xor"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_xor</classname> &gt;</type></typedef><typedef name="make_comma"><type><classname>make_expr</classname>&lt; <classname>tag::comma</classname> &gt;</type></typedef><typedef name="make_mem_ptr"><type><classname>make_expr</classname>&lt; <classname>tag::mem_ptr</classname> &gt;</type></typedef><typedef name="make_assign"><type><classname>make_expr</classname>&lt; <classname>tag::assign</classname> &gt;</type></typedef><typedef name="
make_shift_left_assign"><type><classname>make_expr</classname>&lt; <classname>tag::shift_left_assign</classname> &gt;</type></typedef><typedef name="make_shift_right_assign"><type><classname>make_expr</classname>&lt; <classname>tag::shift_right_assign</classname> &gt;</type></typedef><typedef name="make_multiplies_assign"><type><classname>make_expr</classname>&lt; <classname>tag::multiplies_assign</classname> &gt;</type></typedef><typedef name="make_divides_assign"><type><classname>make_expr</classname>&lt; <classname>tag::divides_assign</classname> &gt;</type></typedef><typedef name="make_modulus_assign"><type><classname>make_expr</classname>&lt; <classname>tag::modulus_assign</classname> &gt;</type></typedef><typedef name="make_plus_assign"><type><classname>make_expr</classname>&lt; <classname>tag::plus_assign</classname> &gt;</type></typedef><typedef name="make_minus_assign"><type><classname>make_expr</classname>&lt; <classname>tag::minus_assign</classname> &gt;</type></typedef><typedef name="make_bitwise
_and_assign"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_and_assign</classname> &gt;</type></typedef><typedef name="make_bitwise_or_assign"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_or_assign</classname> &gt;</type></typedef><typedef name="make_bitwise_xor_assign"><type><classname>make_expr</classname>&lt; <classname>tag::bitwise_xor_assign</classname> &gt;</type></typedef><typedef name="make_subscript"><type><classname>make_expr</classname>&lt; <classname>tag::subscript</classname> &gt;</type></typedef><typedef name="make_if_else"><type><classname>make_expr</classname>&lt; <classname>tag::if_else_</classname> &gt;</type></typedef><typedef name="make_function"><type><classname>make_expr</classname>&lt; <classname>tag::function</classname> &gt;</type></typedef></namespace><namespace name="generatorns_"/><namespace name="op"/><namespace name="refns_"/><namespace name="result_of"/><namespace name="tag"/><namespace name="transform"><struct name="callable"><typedef
name="proto_is_callable_"><type>void</type></typedef></struct><typedef name="arg0"><type><classname>arg_c</classname>&lt; 0 &gt;</type></typedef><typedef name="arg1"><type><classname>arg_c</classname>&lt; 1 &gt;</type></typedef><typedef name="arg2"><type><classname>arg_c</classname>&lt; 2 &gt;</type></typedef><typedef name="arg3"><type><classname>arg_c</classname>&lt; 3 &gt;</type></typedef><typedef name="arg4"><type><classname>arg_c</classname>&lt; 4 &gt;</type></typedef><typedef name="arg5"><type><classname>arg_c</classname>&lt; 5 &gt;</type></typedef><typedef name="arg6"><type><classname>arg_c</classname>&lt; 6 &gt;</type></typedef><typedef name="arg7"><type><classname>arg_c</classname>&lt; 7 &gt;</type></typedef><typedef name="arg8"><type><classname>arg_c</classname>&lt; 8 &gt;</type></typedef><typedef name="arg9"><type><classname>arg_c</classname>&lt; 9 &gt;</type></typedef><typedef name="arg"><type><classname>arg0</classname></type></typedef><typedef name="left"><type><classname>arg0</classname></type>
</typedef><typedef name="right"><type><classname>arg1</classname></type></typedef></namespace><namespace name="utility"/><namespace name="wildcardns_"/><typedef name="_make_terminal"><type><classname>functional::make_terminal</classname></type></typedef><typedef name="_make_posit"><type><classname>functional::make_posit</classname></type></typedef><typedef name="_make_negate"><type><classname>functional::make_negate</classname></type></typedef><typedef name="_make_dereference"><type><classname>functional::make_dereference</classname></type></typedef><typedef name="_make_complement"><type><classname>functional::make_complement</classname></type></typedef><typedef name="_make_address_of"><type><classname>functional::make_address_of</classname></type></typedef><typedef name="_make_logical_not"><type><classname>functional::make_logical_not</classname></type></typedef><typedef name="_make_pre_inc"><type><classname>functional::make_pre_inc</classname></type></typedef><typedef name="_make_pre_dec"><type><classname>
functional::make_pre_dec</classname></type></typedef><typedef name="_make_post_inc"><type><classname>functional::make_post_inc</classname></type></typedef><typedef name="_make_post_dec"><type><classname>functional::make_post_dec</classname></type></typedef><typedef name="_make_shift_left"><type><classname>functional::make_shift_left</classname></type></typedef><typedef name="_make_shift_right"><type><classname>functional::make_shift_right</classname></type></typedef><typedef name="_make_multiplies"><type><classname>functional::make_multiplies</classname></type></typedef><typedef name="_make_divides"><type><classname>functional::make_divides</classname></type></typedef><typedef name="_make_modulus"><type><classname>functional::make_modulus</classname></type></typedef><typedef name="_make_plus"><type><classname>functional::make_plus</classname></type></typedef><typedef name="_make_minus"><type><classname>functional::make_minus</classname></type></typedef><typedef name="_make_less"><type><classname>functional::
make_less</classname></type></typedef><typedef name="_make_greater"><type><classname>functional::make_greater</classname></type></typedef><typedef name="_make_less_equal"><type><classname>functional::make_less_equal</classname></type></typedef><typedef name="_make_greater_equal"><type><classname>functional::make_greater_equal</classname></type></typedef><typedef name="_make_equal_to"><type><classname>functional::make_equal_to</classname></type></typedef><typedef name="_make_not_equal_to"><type><classname>functional::make_not_equal_to</classname></type></typedef><typedef name="_make_logical_or"><type><classname>functional::make_logical_or</classname></type></typedef><typedef name="_make_logical_and"><type><classname>functional::make_logical_and</classname></type></typedef><typedef name="_make_bitwise_and"><type><classname>functional::make_bitwise_and</classname></type></typedef><typedef name="_make_bitwise_or"><type><classname>functional::make_bitwise_or</classname></type></typedef><typedef name="_make_bitwis
e_xor"><type><classname>functional::make_bitwise_xor</classname></type></typedef><typedef name="_make_comma"><type><classname>functional::make_comma</classname></type></typedef><typedef name="_make_mem_ptr"><type><classname>functional::make_mem_ptr</classname></type></typedef><typedef name="_make_assign"><type><classname>functional::make_assign</classname></type></typedef><typedef name="_make_shift_left_assign"><type><classname>functional::make_shift_left_assign</classname></type></typedef><typedef name="_make_shift_right_assign"><type><classname>functional::make_shift_right_assign</classname></type></typedef><typedef name="_make_multiplies_assign"><type><classname>functional::make_multiplies_assign</classname></type></typedef><typedef name="_make_divides_assign"><type><classname>functional::make_divides_assign</classname></type></typedef><typedef name="_make_modulus_assign"><type><classname>functional::make_modulus_assign</classname></type></typedef><typedef name="_make_plus_assign"><type><classname>functio
nal::make_plus_assign</classname></type></typedef><typedef name="_make_minus_assign"><type><classname>functional::make_minus_assign</classname></type></typedef><typedef name="_make_bitwise_and_assign"><type><classname>functional::make_bitwise_and_assign</classname></type></typedef><typedef name="_make_bitwise_or_assign"><type><classname>functional::make_bitwise_or_assign</classname></type></typedef><typedef name="_make_bitwise_xor_assign"><type><classname>functional::make_bitwise_xor_assign</classname></type></typedef><typedef name="_make_subscript"><type><classname>functional::make_subscript</classname></type></typedef><typedef name="_make_if_else"><type><classname>functional::make_if_else</classname></type></typedef><typedef name="_make_function"><type><classname>functional::make_function</classname></type></typedef><typedef name="_flatten"><type><classname>functional::flatten</classname></type></typedef><typedef name="_pop_front"><type><classname>functional::pop_front</classname></type></typedef><typedef
name="_reverse"><type><classname>functional::reverse</classname></type></typedef><typedef name="_eval"><type><classname>functional::deep_copy</classname></type></typedef><typedef name="_deep_copy"><type><classname>functional::deep_copy</classname></type></typedef><typedef name="_expr"><type><classname>transform::expr</classname></type></typedef><typedef name="_state"><type><classname>transform::state</classname></type></typedef><typedef name="_visitor"><type><classname>transform::visitor</classname></type></typedef><typedef name="_arg0"><type><classname>transform::arg0</classname></type></typedef><typedef name="_arg1"><type><classname>transform::arg1</classname></type></typedef><typedef name="_arg2"><type><classname>transform::arg2</classname></type></typedef><typedef name="_arg3"><type><classname>transform::arg3</classname></type></typedef><typedef name="_arg4"><type><classname>transform::arg4</classname></type></typedef><typedef name="_arg5"><type><classname>transform::arg5</classname></type></typedef><typ
edef name="_arg6"><type><classname>transform::arg6</classname></type></typedef><typedef name="_arg7"><type><classname>transform::arg7</classname></type></typedef><typedef name="_arg8"><type><classname>transform::arg8</classname></type></typedef><typedef name="_arg9"><type><classname>transform::arg9</classname></type></typedef><typedef name="_arg"><type><classname>transform::arg</classname></type></typedef><typedef name="_left"><type><classname>transform::left</classname></type></typedef><typedef name="_right"><type><classname>transform::right</classname></type></typedef></namespace></namespace></header><header name="boost/xpressive/proto/ref.hpp"><para>Utility for storing a sub-expr by reference </para><namespace name="boost"><namespace name="proto"><namespace name="functional"><struct name="unref"><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="T"/>
- </template><specialization><template-arg>This(T)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>T &amp;</type><template>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; boost::remove_const&lt; boost::remove_reference&lt; T &gt;::type &gt;::type &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>T &amp;</type><template>
           <template-type-parameter name="T"/>
         </template><parameter name="t"><paramtype>T &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>T const &amp;</type><template>
           <template-type-parameter name="T"/>
         </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>T &amp;</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype><classname>ref_</classname>&lt; T &gt; &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>T &amp;</type><template>
+ </template><parameter name="t"><paramtype>ref_&lt; T &gt; &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>T &amp;</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype><classname>ref_</classname>&lt; T &gt; const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="refns_"><struct name="ref_"><template>
+ </template><parameter name="t"><paramtype>ref_&lt; T &gt; const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="refns_"><struct name="ref_"><template>
       <template-type-parameter name="Expr"/>
- </template><typedef name="proto_base_expr"><type>Expr::proto_base_expr</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_domain"><type>Expr::proto_domain</type></typedef><typedef name="fusion_tag"><type>tag::proto_ref</type></typedef><typedef name="proto_is_ref_"><type>void</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>Expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></typedef><method-group name="public member functions"><method name="proto_base" cv="const"><type>mpl:
:if_&lt; is_const &lt; Expr &gt;, proto_base_expr const &amp;, proto_base_expr &amp; &gt;::type</type></method></method-group><data-member name="expr"><type>Expr &amp;</type></data-member><method-group name="public static functions"><method name="make" cv=""><type>static <classname>ref_</classname>&lt; Expr &gt;</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="ref_"><template>
+ </template><typedef name="proto_base_expr"><type>Expr::proto_base_expr</type></typedef><typedef name="proto_tag"><type>Expr::proto_tag</type></typedef><typedef name="proto_args"><type>Expr::proto_args</type></typedef><typedef name="proto_arity"><type>Expr::proto_arity</type></typedef><typedef name="proto_domain"><type>Expr::proto_domain</type></typedef><typedef name="proto_is_ref_"><type>void</type></typedef><typedef name="proto_is_expr_"><type>void</type></typedef><typedef name="proto_derived_expr"><type>Expr</type></typedef><typedef name="proto_arg0"><type>Expr::proto_arg0</type></typedef><typedef name="proto_arg1"><type>Expr::proto_arg1</type></typedef><typedef name="proto_arg2"><type>Expr::proto_arg2</type></typedef><typedef name="proto_arg3"><type>Expr::proto_arg3</type></typedef><typedef name="proto_arg4"><type>Expr::proto_arg4</type></typedef><data-member name="expr"><type>Expr &amp;</type></data-member><method-group name="public member functions"><method name="proto_base" cv="const"><type>mpl::i
f_&lt; is_const&lt; Expr &gt;, proto_base_expr const &amp;, proto_base_expr &amp; &gt;::type</type></method></method-group><method-group name="public static functions"><method name="make" cv=""><type>static <classname>ref_</classname>&lt; Expr &gt;</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="ref_"><template>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>ref_&lt; Expr &gt;</template-arg></specialization></struct-specialization></namespace><namespace name="result_of"><struct name="unref"><template>
       <template-type-parameter name="T"/>
     </template><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T &amp;</type></typedef><typedef name="const_reference"><type>T const &amp;</type></typedef></struct><struct-specialization name="unref"><template>
       <template-type-parameter name="T"/>
- </template><specialization><template-arg>ref_&lt; T &gt;</template-arg></specialization><typedef name="type"><type>T::proto_derived_expr</type></typedef><typedef name="reference"><type>T &amp;</type></typedef><typedef name="const_reference"><type>T &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ </template><specialization><template-arg>ref_&lt; T &gt;</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T &amp;</type></typedef><typedef name="const_reference"><type>T &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>ref_&lt; T const &gt;</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T const &amp;</type></typedef><typedef name="const_reference"><type>T const &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
       <template-type-parameter name="T"/>
     </template><specialization><template-arg>T &amp;</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T &amp;</type></typedef><typedef name="const_reference"><type>T &amp;</type></typedef></struct-specialization><struct-specialization name="unref"><template>
       <template-type-parameter name="T"/>
- </template><specialization><template-arg>T const &amp;</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T const &amp;</type></typedef><typedef name="const_reference"><type>T const &amp;</type></typedef></struct-specialization></namespace><data-member name="unref"><type><classname>functional::unref</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/tags.hpp"><para>Contains the tags for all the overloadable operators in C++ </para><namespace name="boost"><namespace name="proto"><namespace name="tag"><struct name="terminal"><purpose>Tag type for terminals; aka, leaves in the expression tree. </purpose></struct><struct name="posit"><purpose>Tag type for the unary + operator. </purpose></struct><struct name="negate"><purpose>Tag type for the unary - operator. </purpose></struct><struct name="dereference"><purpose>Tag type for the unary * operator. </purpose></struct><struct name="complement"><pu
rpose>Tag type for the unary ~ operator. </purpose></struct><struct name="address_of"><purpose>Tag type for the unary &amp; operator. </purpose></struct><struct name="logical_not"><purpose>Tag type for the unary ! operator. </purpose></struct><struct name="pre_inc"><purpose>Tag type for the unary prefix ++ operator. </purpose></struct><struct name="pre_dec"><purpose>Tag type for the unary prefix -- operator. </purpose></struct><struct name="post_inc"><purpose>Tag type for the unary postfix ++ operator. </purpose></struct><struct name="post_dec"><purpose>Tag type for the unary postfix -- operator. </purpose></struct><struct name="shift_left"><purpose>Tag type for the binary &lt;&lt; operator. </purpose></struct><struct name="shift_right"><purpose>Tag type for the binary &gt;&gt; operator. </purpose></struct><struct name="multiplies"><purpose>Tag type for the binary * operator. </purpose></struct><struct name="divides"><purpose>Tag type for the binary / operator. </purpose></struct><struct name="modulus"><purp
ose>Tag type for the binary % operator. </purpose></struct><struct name="plus"><purpose>Tag type for the binary + operator. </purpose></struct><struct name="minus"><purpose>Tag type for the binary - operator. </purpose></struct><struct name="less"><purpose>Tag type for the binary &lt; operator. </purpose></struct><struct name="greater"><purpose>Tag type for the binary &gt; operator. </purpose></struct><struct name="less_equal"><purpose>Tag type for the binary &lt;= operator. </purpose></struct><struct name="greater_equal"><purpose>Tag type for the binary &gt;= operator. </purpose></struct><struct name="equal_to"><purpose>Tag type for the binary == operator. </purpose></struct><struct name="not_equal_to"><purpose>Tag type for the binary != operator. </purpose></struct><struct name="logical_or"><purpose>Tag type for the binary || operator. </purpose></struct><struct name="logical_and"><purpose>Tag type for the binary &amp;&amp; operator. </purpose></struct><struct name="bitwise_and"><purpose>Tag type for the b
inary &amp; operator. </purpose></struct><struct name="bitwise_or"><purpose>Tag type for the binary | operator. </purpose></struct><struct name="bitwise_xor"><purpose>Tag type for the binary ^ operator. </purpose></struct><struct name="comma"><purpose>Tag type for the binary , operator. </purpose></struct><struct name="mem_ptr"><purpose>Tag type for the binary -&gt;* operator. </purpose></struct><struct name="assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="shift_left_assign"><purpose>Tag type for the binary &lt;&lt;= operator. </purpose></struct><struct name="shift_right_assign"><purpose>Tag type for the binary &gt;&gt;= operator. </purpose></struct><struct name="multilpies_assign"><purpose>Tag type for the binary *= operator. </purpose></struct><struct name="divides_assign"><purpose>Tag type for the binary /= operator. </purpose></struct><struct name="modulus_assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="plus_assign"><purpose>Tag
type for the binary += operator. </purpose></struct><struct name="minus_assign"><purpose>Tag type for the binary -= operator. </purpose></struct><struct name="bitwise_and_assign"><purpose>Tag type for the binary &amp;= operator. </purpose></struct><struct name="bitwise_or_assign"><purpose>Tag type for the binary |= operator. </purpose></struct><struct name="bitwise_xor_assign"><purpose>Tag type for the binary ^= operator. </purpose></struct><struct name="subscript"><purpose>Tag type for the binary subscript operator. </purpose></struct><struct name="if_else_"><purpose>Tag type for the ternary ?: conditional operator. </purpose></struct><struct name="function"><purpose>Tag type for the nary function call operator. </purpose></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/traits.hpp"><para>Contains definitions for arg&lt;&gt;, arg_c&lt;&gt;, left&lt;&gt;, right&lt;&gt;, tag&lt;&gt;, and the helper functions arg(), arg_c(), left() and right(). </para><namespace name="bo
ost"><namespace name="proto"><namespace name="functional"><struct name="as_expr"><template>
+ </template><specialization><template-arg>T const &amp;</template-arg></specialization><typedef name="type"><type>T</type></typedef><typedef name="reference"><type>T const &amp;</type></typedef><typedef name="const_reference"><type>T const &amp;</type></typedef></struct-specialization></namespace><data-member name="unref"><type><classname>functional::unref</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/tags.hpp"><para>Contains the tags for all the overloadable operators in C++ </para><namespace name="boost"><namespace name="proto"><namespace name="tag"><struct name="terminal"><purpose>Tag type for terminals; aka, leaves in the expression tree. </purpose></struct><struct name="posit"><purpose>Tag type for the unary + operator. </purpose></struct><struct name="negate"><purpose>Tag type for the unary - operator. </purpose></struct><struct name="dereference"><purpose>Tag type for the unary * operator. </purpose></struct><struct name="complement"><pu
rpose>Tag type for the unary ~ operator. </purpose></struct><struct name="address_of"><purpose>Tag type for the unary &amp; operator. </purpose></struct><struct name="logical_not"><purpose>Tag type for the unary ! operator. </purpose></struct><struct name="pre_inc"><purpose>Tag type for the unary prefix ++ operator. </purpose></struct><struct name="pre_dec"><purpose>Tag type for the unary prefix -- operator. </purpose></struct><struct name="post_inc"><purpose>Tag type for the unary postfix ++ operator. </purpose></struct><struct name="post_dec"><purpose>Tag type for the unary postfix -- operator. </purpose></struct><struct name="shift_left"><purpose>Tag type for the binary &lt;&lt; operator. </purpose></struct><struct name="shift_right"><purpose>Tag type for the binary &gt;&gt; operator. </purpose></struct><struct name="multiplies"><purpose>Tag type for the binary * operator. </purpose></struct><struct name="divides"><purpose>Tag type for the binary / operator. </purpose></struct><struct name="modulus"><purp
ose>Tag type for the binary % operator. </purpose></struct><struct name="plus"><purpose>Tag type for the binary + operator. </purpose></struct><struct name="minus"><purpose>Tag type for the binary - operator. </purpose></struct><struct name="less"><purpose>Tag type for the binary &lt; operator. </purpose></struct><struct name="greater"><purpose>Tag type for the binary &gt; operator. </purpose></struct><struct name="less_equal"><purpose>Tag type for the binary &lt;= operator. </purpose></struct><struct name="greater_equal"><purpose>Tag type for the binary &gt;= operator. </purpose></struct><struct name="equal_to"><purpose>Tag type for the binary == operator. </purpose></struct><struct name="not_equal_to"><purpose>Tag type for the binary != operator. </purpose></struct><struct name="logical_or"><purpose>Tag type for the binary || operator. </purpose></struct><struct name="logical_and"><purpose>Tag type for the binary &amp;&amp; operator. </purpose></struct><struct name="bitwise_and"><purpose>Tag type for the b
inary &amp; operator. </purpose></struct><struct name="bitwise_or"><purpose>Tag type for the binary | operator. </purpose></struct><struct name="bitwise_xor"><purpose>Tag type for the binary ^ operator. </purpose></struct><struct name="comma"><purpose>Tag type for the binary , operator. </purpose></struct><struct name="mem_ptr"><purpose>Tag type for the binary -&gt;* operator. </purpose></struct><struct name="assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="shift_left_assign"><purpose>Tag type for the binary &lt;&lt;= operator. </purpose></struct><struct name="shift_right_assign"><purpose>Tag type for the binary &gt;&gt;= operator. </purpose></struct><struct name="multiplies_assign"><purpose>Tag type for the binary *= operator. </purpose></struct><struct name="divides_assign"><purpose>Tag type for the binary /= operator. </purpose></struct><struct name="modulus_assign"><purpose>Tag type for the binary = operator. </purpose></struct><struct name="plus_assign"><purpose>Tag
type for the binary += operator. </purpose></struct><struct name="minus_assign"><purpose>Tag type for the binary -= operator. </purpose></struct><struct name="bitwise_and_assign"><purpose>Tag type for the binary &amp;= operator. </purpose></struct><struct name="bitwise_or_assign"><purpose>Tag type for the binary |= operator. </purpose></struct><struct name="bitwise_xor_assign"><purpose>Tag type for the binary ^= operator. </purpose></struct><struct name="subscript"><purpose>Tag type for the binary subscript operator. </purpose></struct><struct name="if_else_"><purpose>Tag type for the ternary ?: conditional operator. </purpose></struct><struct name="function"><purpose>Tag type for the nary function call operator. </purpose></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/traits.hpp"><para>Contains definitions for arg&lt;&gt;, arg_c&lt;&gt;, left&lt;&gt;, right&lt;&gt;, tag&lt;&gt;, and the helper functions arg(), arg_c(), left() and right(). </para><namespace name="bo
ost"><namespace name="proto"><struct name="is_callable"><template>
+ <template-type-parameter name="T"/>
+ </template></struct><struct name="is_aggregate"><template>
+ <template-type-parameter name="T"/>
+ </template><description><para>is_aggregate </para></description></struct><struct-specialization name="is_aggregate"><template>
+ <template-type-parameter name="Tag"/>
+ <template-type-parameter name="Args"/>
+ <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
+ </template><specialization><template-arg>proto::expr&lt; Tag</template-arg><template-arg>Args</template-arg><template-arg>N &gt;</template-arg></specialization><inherit access="public">boost::mpl::true_</inherit></struct-specialization><namespace name="functional"><struct name="as_expr"><template>
       <template-type-parameter name="Domain"/>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="T"/>
     </template><specialization><template-arg>This(T)</template-arg></specialization><inherit access="public">boost::proto::result_of::as_expr&lt; remove_reference&lt; T &gt;::type, Domain &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::as_expr</classname>&lt; T, Domain &gt;::result_type</type><template>
@@ -1561,9 +1551,7 @@
           <template-type-parameter name="T"/>
         </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></method></method-group></struct><struct name="as_arg"><template>
       <template-type-parameter name="Domain"/>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="T"/>
     </template><specialization><template-arg>This(T)</template-arg></specialization><inherit access="public">boost::proto::result_of::as_arg&lt; remove_reference&lt; T &gt;::type, Domain &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::as_arg</classname>&lt; T, Domain &gt;::type</type><template>
@@ -1572,9 +1560,7 @@
           <template-type-parameter name="T"/>
         </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></method></method-group></struct><struct name="arg_c"><template>
       <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result_of::arg_c&lt; Expr, N &gt;::reference</type><template>
@@ -1583,230 +1569,245 @@
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="arg"><template>
       <template-type-parameter name="N"/>
- </template><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::arg</classname>&lt; Expr, N &gt;::reference</type><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><inherit access="public">boost::proto::result_of::arg&lt; boost::remove_const&lt; boost::remove_reference&lt; Expr &gt;::type &gt;::type, N &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::arg</classname>&lt; Expr, N &gt;::reference</type><template>
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::arg</classname>&lt; Expr, N &gt;::const_reference</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="left"><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="left"><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::left</classname>&lt; Expr &gt;::reference</type><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><inherit access="public">boost::proto::result_of::left&lt; boost::remove_const&lt; boost::remove_reference&lt; Expr &gt;::type &gt;::type &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::left</classname>&lt; Expr &gt;::reference</type><template>
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::left</classname>&lt; Expr &gt;::const_reference</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="right"><struct name="result"><template>
- <template-type-parameter name="Sig"/>
- </template></struct><struct-specialization name="result"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct><struct name="right"><struct-specialization name="result"><template>
       <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>This(Expr)</template-arg></specialization></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::right</classname>&lt; Expr &gt;::reference</type><template>
+ </template><specialization><template-arg>This(Expr)</template-arg></specialization><inherit access="public">boost::proto::result_of::right&lt; boost::remove_const&lt; boost::remove_reference&lt; Expr &gt;::type &gt;::type &gt;</inherit></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type><classname>result_of::right</classname>&lt; Expr &gt;::reference</type><template>
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type><classname>result_of::right</classname>&lt; Expr &gt;::const_reference</type><template>
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="op"><struct name="terminal"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_identity_transform</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::terminal</classname>, <classname>args0</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::terminal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="if_else_"><template>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::terminal</classname>, <classname>args0</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::terminal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="if_else_"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
       <template-type-parameter name="V"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::if_else_</classname>, <classname>args3</classname>&lt; T, U, V &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::if_else_</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><typedef name="proto_arg2"><type>V</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="unary_expr"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::if_else_</classname>, <classname>args3</classname>&lt; T, U, V &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::if_else_</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><typedef name="proto_arg2"><type>V</type></typedef></struct><struct name="unary_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="binary_expr"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="binary_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="posit"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="posit"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::posit</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::posit</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="negate"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::posit</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::posit</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="negate"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::negate</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::negate</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="dereference"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::negate</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::negate</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="dereference"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::dereference</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::dereference</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="complement"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::dereference</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::dereference</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="complement"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::complement</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::complement</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="address_of"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::complement</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::complement</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="address_of"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::address_of</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::address_of</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="logical_not"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::address_of</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::address_of</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="logical_not"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::logical_not</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_not</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="pre_inc"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::logical_not</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_not</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="pre_inc"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::pre_inc</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::pre_inc</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="pre_dec"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::pre_inc</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::pre_inc</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="pre_dec"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::pre_dec</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::pre_dec</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="post_inc"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::pre_dec</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::pre_dec</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="post_inc"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::post_inc</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::post_inc</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="post_dec"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::post_inc</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::post_inc</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="post_dec"><template>
       <template-type-parameter name="T"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::post_dec</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::post_dec</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_left"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::post_dec</classname>, <classname>args1</classname>&lt; T &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::post_dec</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef></struct><struct name="shift_left"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::shift_left</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_left</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_right"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_left</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_left</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="shift_right"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::shift_right</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_right</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="multiplies"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_right</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_right</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="multiplies"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::multiplies</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::multiplies</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="divides"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::multiplies</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::multiplies</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="divides"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::divides</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::divides</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="modulus"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::divides</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::divides</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="modulus"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::modulus</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::modulus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="plus"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::modulus</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::modulus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="plus"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::plus</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::plus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="minus"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::plus</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::plus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="minus"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::minus</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::minus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="less"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::minus</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::minus</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="less"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::less</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::less</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="greater"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::less</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::less</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="greater"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::greater</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::greater</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="less_equal"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::greater</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::greater</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="less_equal"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::less_equal</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::less_equal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="greater_equal"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::less_equal</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::less_equal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="greater_equal"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::greater_equal</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::greater_equal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="equal_to"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::greater_equal</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::greater_equal</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="equal_to"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::equal_to</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::equal_to</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="not_equal_to"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::equal_to</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::equal_to</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="not_equal_to"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::not_equal_to</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::not_equal_to</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="logical_or"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::not_equal_to</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::not_equal_to</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="logical_or"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::logical_or</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_or</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="logical_and"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::logical_or</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_or</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="logical_and"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::logical_and</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_and</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_and"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::logical_and</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::logical_and</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="bitwise_and"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::bitwise_and</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_and</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_or"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_and</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_and</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="bitwise_or"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::bitwise_or</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_or</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_xor"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_or</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_or</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="bitwise_xor"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::bitwise_xor</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_xor</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="comma"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_xor</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_xor</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="comma"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::comma</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::comma</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="mem_ptr"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::comma</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::comma</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="mem_ptr"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::mem_ptr</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::mem_ptr</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::mem_ptr</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::mem_ptr</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_left_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="shift_left_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::shift_left_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_left_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="shift_right_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_left_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_left_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="shift_right_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::shift_right_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_right_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="multilpies_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::shift_right_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::shift_right_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="multiplies_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::multilpies_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::multilpies_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="divides_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::multiplies_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::multiplies_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="divides_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::divides_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::divides_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="modulus_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::divides_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::divides_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="modulus_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::modulus_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::modulus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="plus_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::modulus_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::modulus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="plus_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::plus_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::plus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="minus_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::plus_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::plus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="minus_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::minus_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::minus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_and_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::minus_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::minus_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="bitwise_and_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::bitwise_and_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_and_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_or_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_and_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_and_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="bitwise_or_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::bitwise_or_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_or_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="bitwise_xor_assign"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_or_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_or_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="bitwise_xor_assign"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::bitwise_xor_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_xor_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct name="subscript"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::bitwise_xor_assign</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::bitwise_xor_assign</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct name="subscript"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="U"/>
- </template><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::subscript</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef><method-group name="public member functions"/><constructor/></struct><struct-specialization name="function"><template>
+ </template><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::subscript</classname>, <classname>args2</classname>&lt; T, U &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::subscript</classname></type></typedef><typedef name="proto_arg0"><type>T</type></typedef><typedef name="proto_arg1"><type>U</type></typedef></struct><struct-specialization name="function"><template>
       <template-type-parameter name="A0"/>
- </template><specialization><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; A0 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></ty
pedef></struct-specialization><struct-specialization name="nary_expr"><template>
+ </template><specialization><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args1</classname>&lt; A0 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-spec
ialization name="nary_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="A0"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args1</classname>&lt; A0 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specializa
tion name="function"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args1</classname>&lt; A0 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
- </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::function</classname>, <classname>args2</classname>&lt; A0, A1 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specializatio
n><struct-specialization name="nary_expr"><template>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args2</classname>&lt; A0, A1 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="nary_expr">
<template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args2</classname>&lt; A0, A1 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><templa
te>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args2</classname>&lt; A0, A1 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
- </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::function</classname>, <classname>args3</classname>&lt; A0, A1, A2 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization nam
e="nary_expr"><template>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args3</classname>&lt; A0, A1, A2 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args3</classname>&lt; A0, A1, A2 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>void</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args3</classname>&lt; A0, A1, A2 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
- </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::function</classname>, <classname>args4</classname>&lt; A0, A1, A2, A3 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args4</classname>&lt; A0, A1, A2, A3 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args4</classname>&lt; A0, A1, A2, A3 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>void</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args4</classname>&lt; A0, A1, A2, A3 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><struct-specialization name="function"><template>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="A4"/>
- </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; <classname>proto::tag::function</classname>, <classname>args5</classname>&lt; A0, A1, A2, A3, A4 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type>A4</type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
+ </template><specialization><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; <classname>proto::tag::function</classname>, <classname>args5</classname>&lt; A0, A1, A2, A3, A4 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type><classname>proto::tag::function</classname></type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type>A4</type></typedef></struct-specialization><struct-specialization name="nary_expr"><template>
       <template-type-parameter name="Tag"/>
       <template-type-parameter name="A0"/>
       <template-type-parameter name="A1"/>
       <template-type-parameter name="A2"/>
       <template-type-parameter name="A3"/>
       <template-type-parameter name="A4"/>
- </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><inherit access="public">boost::proto::has_transformns_::has_pass_through_transform&lt; Grammar &gt;</inherit><typedef name="type"><type>expr&lt; Tag, <classname>args5</classname>&lt; A0, A1, A2, A3, A4 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type>A4</type></typedef></struct-specialization></namespace><namespace name="result_of"><struct name="is_ref"><template>
+ </template><specialization><template-arg>Tag</template-arg><template-arg>A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4</template-arg><template-arg>void</template-arg></specialization><typedef name="proto_is_callable_"><type>int</type></typedef><typedef name="type"><type>proto::expr&lt; Tag, <classname>args5</classname>&lt; A0, A1, A2, A3, A4 &gt; &gt;</type></typedef><typedef name="proto_base_expr"><type>type</type></typedef><typedef name="proto_tag"><type>Tag</type></typedef><typedef name="proto_arg0"><type>A0</type></typedef><typedef name="proto_arg1"><type>A1</type></typedef><typedef name="proto_arg2"><type>A2</type></typedef><typedef name="proto_arg3"><type>A3</type></typedef><typedef name="proto_arg4"><type>A4</type></typedef></struct-specialization></namespace><namespace name="result_of"><struct name="is_ref"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="EnableIf"/>
- </template></struct><struct name="is_expr"><template>
+ </template><inherit access="public">boost::mpl::false_</inherit></struct><struct-specialization name="is_ref"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_ref_</template-arg></specialization><inherit access="public">boost::mpl::true_</inherit></struct-specialization><struct name="is_expr"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="EnableIf"/>
- </template></struct><struct name="tag_of"><template>
- <template-type-parameter name="Expr"/>
- </template><typedef name="type"><type>Expr::proto_tag</type></typedef></struct><struct name="id"><template>
+ </template><inherit access="public">boost::mpl::false_</inherit></struct><struct-specialization name="is_expr"><template>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><inherit access="public">boost::mpl::true_</inherit></struct-specialization><struct name="tag_of"><template>
       <template-type-parameter name="Expr"/>
- </template><inherit access="public">boost::proto::result_of::deep_copy&lt; Expr &gt;</inherit></struct><struct name="as_expr"><template>
+ </template><typedef name="type"><type>Expr::proto_tag</type></typedef></struct><struct name="as_expr"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="Domain"/>
       <template-type-parameter name="EnableIf"/>
- </template><typedef name="proto_arg0"><type>mpl::eval_if&lt; mpl::or_&lt; boost::is_array&lt; T &gt;, is_function&lt; T &gt; &gt;, add_reference&lt; T &gt;, remove_cv&lt; T &gt;&gt;::type</type></typedef><typedef name="expr_type"><type>expr&lt; <classname>proto::tag::terminal</classname>, <classname>args0</classname>&lt; proto_arg0 &gt; &gt;</type></typedef><typedef name="type"><type>Domain::template apply&lt; expr_type &gt;::type</type></typedef><typedef name="result_type"><type>type const</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static result_type</type><template>
+ </template><typedef name="proto_arg0"><type>mpl::eval_if&lt; mpl::or_&lt; boost::is_array&lt; T &gt;, is_function&lt; T &gt; &gt;, add_reference&lt; T &gt;, remove_cv&lt; T &gt;&gt;::type</type></typedef><typedef name="expr_type"><type>proto::expr&lt; <classname>proto::tag::terminal</classname>, <classname>args0</classname>&lt; proto_arg0 &gt; &gt;</type></typedef><typedef name="type"><type>Domain::template apply&lt; expr_type &gt;::type</type></typedef><typedef name="result_type"><type>type const</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static result_type</type><template>
           <template-type-parameter name="T2"/>
- </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct><struct name="as_arg"><template>
+ </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="as_expr"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>T::proto_derived_expr</type></typedef><typedef name="result_type"><type>T &amp;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static result_type</type><template>
+ <template-type-parameter name="T2"/>
+ </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct-specialization><struct name="as_arg"><template>
       <template-type-parameter name="T"/>
       <template-type-parameter name="Domain"/>
       <template-type-parameter name="EnableIf"/>
- </template><typedef name="expr_type"><type>expr&lt; <classname>proto::tag::terminal</classname>, <classname>args0</classname>&lt; T &amp; &gt; &gt;</type></typedef><typedef name="type"><type>Domain::template apply&lt; expr_type &gt;::type</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><template>
+ </template><typedef name="expr_type"><type>proto::expr&lt; <classname>proto::tag::terminal</classname>, <classname>args0</classname>&lt; T &amp; &gt; &gt;</type></typedef><typedef name="type"><type>Domain::template apply&lt; expr_type &gt;::type</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><template>
+ <template-type-parameter name="T2"/>
+ </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="as_arg"><template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Domain"/>
+ </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>ref_&lt; T &gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static type</type><template>
           <template-type-parameter name="T2"/>
- </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct><struct name="arg"><template>
+ </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct-specialization><struct name="arg"><template>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="N"/>
     </template></struct><struct name="left"><template>
@@ -1815,43 +1816,29 @@
       <template-type-parameter name="Expr"/>
     </template><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg1 &gt;</inherit></struct><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>0</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg0 &gt;</inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 0 &gt;::reference</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 0 &gt;::const_reference</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>0</template-arg></specialization><typedef name="wrapped_type"><type>Expr::proto_arg0</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>Expr const</template-arg><template-arg>0</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 0 &gt;</inherit></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>1</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg1 &gt;</inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 1 &gt;::reference</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 1 &gt;::const_reference</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>1</template-arg></specialization><typedef name="wrapped_type"><type>Expr::proto_arg1</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>Expr const</template-arg><template-arg>1</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 1 &gt;</inherit></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>2</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg2 &gt;</inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 2 &gt;::reference</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 2 &gt;::const_reference</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>2</template-arg></specialization><typedef name="wrapped_type"><type>Expr::proto_arg2</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>Expr const</template-arg><template-arg>2</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 2 &gt;</inherit></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>3</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg3 &gt;</inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 3 &gt;::reference</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 3 &gt;::const_reference</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>3</template-arg></specialization><typedef name="wrapped_type"><type>Expr::proto_arg3</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>Expr const</template-arg><template-arg>3</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 3 &gt;</inherit></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>4</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg4 &gt;</inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 4 &gt;::reference</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 4 &gt;::const_reference</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>4</template-arg></specialization><typedef name="wrapped_type"><type>Expr::proto_arg4</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
     </template><specialization><template-arg>Expr const</template-arg><template-arg>4</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 4 &gt;</inherit></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr</template-arg><template-arg>5</template-arg></specialization><inherit access="public">boost::proto::result_of::unref&lt; Expr::proto_arg5 &gt;</inherit><method-group name="public static functions"><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 5 &gt;::reference</type><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></method><method name="call" cv=""><type>static <classname>arg_c</classname>&lt; Expr, 5 &gt;::const_reference</type><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="arg_c"><template>
+ </template><specialization><template-arg>Expr</template-arg><template-arg>5</template-arg></specialization><typedef name="wrapped_type"><type>Expr::proto_arg5</type></typedef><typedef name="type"><type><classname>unref</classname>&lt; wrapped_type &gt;::type</type></typedef><typedef name="reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::reference</type></typedef><typedef name="const_reference"><type><classname>unref</classname>&lt; wrapped_type &gt;::const_reference</type></typedef><method-group name="public static functions"/></struct-specialization><struct-specialization name="arg_c"><template>
       <template-type-parameter name="Expr"/>
- </template><specialization><template-arg>Expr const</template-arg><template-arg>5</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 5 &gt;</inherit></struct-specialization><struct-specialization name="is_ref"><template>
- <template-type-parameter name="T"/>
- </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_ref_</template-arg></specialization></struct-specialization><struct-specialization name="is_expr"><template>
- <template-type-parameter name="T"/>
- </template><specialization><template-arg>T</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization></struct-specialization><struct-specialization name="as_expr"><template>
- <template-type-parameter name="T"/>
- <template-type-parameter name="Domain"/>
- </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type>T::proto_derived_expr</type></typedef><typedef name="result_type"><type>T &amp;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static result_type</type><template>
- <template-type-parameter name="T2"/>
- </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="as_arg"><template>
- <template-type-parameter name="T"/>
- <template-type-parameter name="Domain"/>
- </template><specialization><template-arg>T</template-arg><template-arg>Domain</template-arg><template-arg>typename T::proto_is_expr_</template-arg></specialization><typedef name="type"><type><classname>ref_</classname>&lt; T &gt;</type></typedef><method-group name="public static functions"><method name="call" cv=""><type>static <classname>type</classname></type><template>
- <template-type-parameter name="T2"/>
- </template><parameter name="t"><paramtype>T2 &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
+ </template><specialization><template-arg>Expr const</template-arg><template-arg>5</template-arg></specialization><inherit access="public">boost::proto::result_of::arg_c&lt; Expr, 5 &gt;</inherit></struct-specialization></namespace><data-member name="left"><type><classname>functional::left</classname> const</type></data-member><data-member name="right"><type><classname>functional::right</classname> const</type></data-member><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
           <template-type-parameter name="A0"/>
         </template><parameter name="a0"><paramtype>A0 &amp;</paramtype></parameter></function><function name="implicit_expr"><type><emphasis>unspecified</emphasis></type><template>
           <template-type-parameter name="A0"/>
@@ -1875,342 +1862,484 @@
           <template-type-parameter name="T"/>
         </template><parameter name="t"><paramtype>T &amp;</paramtype></parameter></signature><signature><type><classname>result_of::as_expr</classname>&lt; T const &gt;::result_type</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><description><para>as_expr </para></description></overloaded-function><overloaded-function name="as_arg"><signature><type><classname>result_of::as_arg</classname>&lt; T &gt;::type</type><template>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><description><para>as_expr</para><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></overloaded-function><overloaded-function name="as_arg"><signature><type><classname>result_of::as_arg</classname>&lt; T &gt;::type</type><template>
           <template-type-parameter name="T"/>
         </template><parameter name="t"><paramtype>T &amp;</paramtype></parameter></signature><signature><type><classname>result_of::as_arg</classname>&lt; T const &gt;::type</type><template>
           <template-type-parameter name="T"/>
- </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><description><para>as_arg </para></description></overloaded-function><overloaded-function name="arg"><signature><type><classname>result_of::unref</classname>&lt; typename Expr::proto_base_expr::proto_arg0 &gt;::reference</type><template>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></signature><description><para>as_arg</para><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></overloaded-function><overloaded-function name="arg"><signature><type><classname>result_of::unref</classname>&lt; typename Expr::proto_base_expr::proto_arg0 &gt;::reference</type><template>
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></signature><signature><type><classname>result_of::unref</classname>&lt; typename Expr::proto_base_expr::proto_arg0 &gt;::const_reference</type><template>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><description><para>arg </para></description></overloaded-function><overloaded-function name="arg_c"><signature><type>result_of::arg_c&lt; Expr, N &gt;::reference</type><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><description><para>arg</para><para>This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. </para></description></overloaded-function><overloaded-function name="arg_c"><signature><type>result_of::arg_c&lt; Expr, N &gt;::reference</type><template>
           <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
           <template-type-parameter name="Expr"/>
         </template><parameter name="expr"><paramtype>Expr &amp;</paramtype></parameter></signature><signature><type>result_of::arg_c&lt; Expr, N &gt;::const_reference</type><template>
           <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
           <template-type-parameter name="Expr"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><description><para>arg_c </para></description></overloaded-function><data-member name="left"><type><classname>functional::left</classname> const</type></data-member><data-member name="right"><type><classname>functional::right</classname> const</type></data-member></namespace></namespace></header><header name="boost/xpressive/proto/transform.hpp"><para>Includes all the transforms in the transform/ sub-directory. </para></header><header name="boost/xpressive/proto/transform/apply.hpp"><para>Proto transforms for applying MPL placeholder expressions. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="always"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Always"/>
- <template-type-parameter name="Factory"/>
- </template><struct name="apply"><template>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Always</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static Always</type><template>
- <template-type-parameter name="Expr"/>
- <template-type-parameter name="State"/>
- <template-type-parameter name="Visitor"/>
- </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="apply1"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Lambda"/>
- <template-type-parameter name="Factory"/>
- </template><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter></signature><description><para>arg_c </para></description></overloaded-function></namespace></namespace></header><header name="boost/xpressive/proto/transform.hpp"><para>Includes all the transforms in the transform/ sub-directory. </para></header><header name="boost/xpressive/proto/transform/arg.hpp"><para>Contains definition of the argN transforms. </para><namespace name="boost"><namespace name="proto"><struct name="_arg_c"><template>
+ <template-nontype-parameter name="I"><type>int</type></template-nontype-parameter>
+ </template><inherit access="public">boost::proto::transform::arg_c&lt; I &gt;</inherit></struct><namespace name="transform"><struct name="expr"><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>Expr</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Expr const &amp;</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="apply2"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Lambda"/>
- <template-type-parameter name="Factory"/>
- </template><struct name="apply"><template>
+ </template><parameter name="expr_"><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="state"><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>State</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>State const &amp;</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="apply3"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Lambda"/>
- <template-type-parameter name="Factory"/>
- </template><struct name="apply"><template>
+ </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state_"><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="visitor"><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>Visitor</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>Visitor &amp;</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/arg.hpp"><para>Proto transforms for extracting arguments from expressions. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="arg"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="N"/>
- </template><struct name="apply"><template>
+ </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor_"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="arg_c"><template>
+ <template-nontype-parameter name="I"><type>int</type></template-nontype-parameter>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><inherit access="public">boost::proto::result_of::arg&lt; Grammar::template apply&lt; Expr, State, Visitor &gt;::type, N &gt;</inherit></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>proto::result_of::arg_c&lt; Expr, I &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>proto::result_of::arg_c&lt; Expr, I &gt;::const_reference</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="arg_c"><template>
- <template-type-parameter name="Grammar"/>
- <template-nontype-parameter name="N"><type>long</type></template-nontype-parameter>
- </template><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="_ref"><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T &amp;)</template-arg></specialization><typedef name="type"><type>boost::reference_wrapper&lt; T &gt;</type></typedef></struct-specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="T"/>
+ </template><specialization><template-arg>This(T)</template-arg></specialization><typedef name="type"><type>boost::reference_wrapper&lt; T const &gt;</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>boost::reference_wrapper&lt; T &gt;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T &amp;</paramtype></parameter></method><method name="operator()" cv="const"><type>boost::reference_wrapper&lt; T const &gt;</type><template>
+ <template-type-parameter name="T"/>
+ </template><parameter name="t"><paramtype>T const &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/bind.hpp"><para>Contains definition of the bind&lt;&gt; transform. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="bind"><template>
+ <template-type-parameter name="Fun"/>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; <classname>Fun</classname> &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="left"><template>
- <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="bind"><template>
+ <template-type-parameter name="Return"/>
+ </template><specialization><template-arg>Return()</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><inherit access="public">boost::proto::result_of::left&lt; Grammar::template apply&lt; Expr, State, Visitor &gt;::type &gt;</inherit></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; Return &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type() &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="right"><template>
- <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="bind"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Return(A0)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><inherit access="public">boost::proto::result_of::right&lt; Grammar::template apply&lt; Expr, State, Visitor &gt;::type &gt;</inherit></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; Return &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type(A0) &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="identity"><template>
- <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>Expr_</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static Expr_ const &amp;</type><template>
- <template-type-parameter name="Expr_"/>
- <template-type-parameter name="State_"/>
- <template-type-parameter name="Visitor_"/>
- </template><parameter name="expr_"><paramtype>Expr_ const &amp;</paramtype></parameter><parameter name=""><paramtype>State_ const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor_ &amp;</paramtype></parameter></method></method-group></struct><struct name="state"><template>
- <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
- <template-type-parameter name=""/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="bind"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
- <template-type-parameter name=""/>
- </template><typedef name="type"><type>State</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static State const &amp;</type><template>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; Return &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type(A0, A1) &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state_"><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="visitor"><template>
- <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
- <template-type-parameter name=""/>
- <template-type-parameter name=""/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="bind"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><typedef name="type"><type>Visitor</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static Visitor &amp;</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; Return &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type(A0, A1, A2) &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor_"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/branch.hpp"><para>A special-purpose proto transform for transforming one branch of the expression tree separately from the rest. Given an expression and a new state, it transforms the expression using the new state. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="branch"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="BranchState"/>
- </template><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="bind"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; Return &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type(A0, A1, A2, A3) &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/compose.hpp"><para>A special-purpose proto transform for composing two transfomations. Given two Grammars, expressions that match the first grammar are transformed according to that grammar, and the result is forwarded to the second for further transformation. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="compose"><template>
- <template-type-parameter name="Grammar1"/>
- <template-type-parameter name="Grammar2"/>
- </template><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="bind"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><typedef name="type"><type>Grammar2::template <classname>apply</classname>&lt; typename Grammar1::template <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type, State, Visitor &gt;::type</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><classname>call</classname>&lt; typename <classname>make</classname>&lt; Return &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type(A0, A1, A2, A3, A4) &gt;</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/construct.hpp"><para>For constructing an arbitrary type from a bunch of transforms. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct-specialization name="construct"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Result"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>Result()</template-arg></specialization><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/call.hpp"><para>Contains definition of the call&lt;&gt; transform. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="call"><template>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">Fun</inherit><typedef name="proto_is_callable_"><type>void</type></typedef></struct><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ </template><specialization><template-arg>Fun()</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Result"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
       <template-type-parameter name="Arg0"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0)</template-arg></specialization><struct name="apply"><template>
+ </template><specialization><template-arg>Fun(Arg0)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Result"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
       <template-type-parameter name="Arg0"/>
       <template-type-parameter name="Arg1"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1)</template-arg></specialization><struct name="apply"><template>
+ </template><specialization><template-arg>Fun(Arg0</template-arg><template-arg>Arg1)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Result"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
       <template-type-parameter name="Arg0"/>
       <template-type-parameter name="Arg1"/>
       <template-type-parameter name="Arg2"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2)</template-arg></specialization><struct name="apply"><template>
+ </template><specialization><template-arg>Fun(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>boost::result_of&lt; <classname>Fun</classname>(typename <classname>when</classname>&lt; _, Arg0 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, Arg1 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, Arg2 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Result"/>
- <template-type-parameter name="Arg0"/>
- <template-type-parameter name="Arg1"/>
- <template-type-parameter name="Arg2"/>
- <template-type-parameter name="Arg3"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2</template-arg><template-arg>Arg3)</template-arg></specialization><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Fun(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>boost::result_of&lt; <classname>Fun</classname>(typename <classname>when</classname>&lt; _, A0 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A1 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A2 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A3 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization><struct-specialization name="construct"><template>
- <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Result"/>
- <template-type-parameter name="Arg0"/>
- <template-type-parameter name="Arg1"/>
- <template-type-parameter name="Arg2"/>
- <template-type-parameter name="Arg3"/>
- <template-type-parameter name="Arg4"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>Result(Arg0</template-arg><template-arg>Arg1</template-arg><template-arg>Arg2</template-arg><template-arg>Arg3</template-arg><template-arg>Arg4)</template-arg></specialization><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="call"><template>
+ <template-type-parameter name="Fun"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Fun(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type>boost::result_of&lt; <classname>Fun</classname>(typename <classname>when</classname>&lt; _, A0 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A1 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A2 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A3 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type, typename <classname>when</classname>&lt; _, A4 &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type)&gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group><method-group name="private static functions"/></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/fold.hpp"><para>A special-purpose proto transform for merging sequences of binary operations. It transforms the right operand and passes the result as state while transforming the left. Or, it might do the left first, if you choose. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct-specialization name="fold"><template>
- <template-type-parameter name="Grammar"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>void</template-arg></specialization><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/fold.hpp"><para>Contains definition of the fold&lt;&gt; and reverse_fold&lt;&gt; transforms.</para><para>Contains definition of the fold_tree&lt;&gt; and reverse_fold_tree&lt;&gt; transforms. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="fold"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"><method name="fold" cv=""><type/></method></method-group><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="sequence"><type><classname>when</classname>&lt; _, Sequence &gt;::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="reverse_fold"><template>
- <template-type-parameter name="Grammar"/>
- </template><specialization><template-arg>Grammar</template-arg><template-arg>void</template-arg></specialization><struct name="apply"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="reverse_fold"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::transform::fold&lt; Sequence, State0, Fun &gt;</inherit></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/fold_tree.hpp"><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="fold_tree"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"><method name="reverse_fold" cv=""><type/></method></method-group><method-group name="public static functions"><method name="call" cv=""><type>static apply&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/fold_tree.hpp"><para>A higher-level transform that uses the fold, and branch transforms to recursively fold a tree. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="fold_tree"><template>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="Grammar"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="reverse_fold_tree"><template>
+ <template-type-parameter name="Sequence"/>
+ <template-type-parameter name="State0"/>
+ <template-type-parameter name="Fun"/>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
- </template><description><para>fold_tree </para></description></struct><struct name="reverse_fold_tree"><template>
- <template-type-parameter name="Tag"/>
- <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type><emphasis>unspecified</emphasis></type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/make.hpp"><para>Contains definition of the make&lt;&gt; transform. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="make"><template>
+ <template-type-parameter name="Fun"/>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name=""><paramtype>Expr const &amp;</paramtype></parameter><parameter name=""><paramtype>State const &amp;</paramtype></parameter><parameter name=""><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct-specialization name="make"><template>
+ <template-type-parameter name="Return"/>
+ </template><specialization><template-arg>Return()</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Return(A0)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
- </template><description><para>reverse_fold_tree </para></description></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/function.hpp"><para>Proto transforms for applying a function object. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="function1"><template>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization><struct-specialization name="make"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
+ <template-type-parameter name="Expr"/>
+ <template-type-parameter name="State"/>
+ <template-type-parameter name="Visitor"/>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct-specialization></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/pass_through.hpp"><para>TODO </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="pass_through"><template>
       <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Function1"/>
- </template><struct name="apply"><template>
+ </template><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="type"><type><emphasis>unspecified</emphasis></type></typedef></struct-specialization><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="function2"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/when.hpp"><para>Definition of when transform. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">Fun</inherit><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef></struct><struct-specialization name="when"><template>
       <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Function2"/>
- </template><struct name="apply"><template>
+ <template-type-parameter name="Fun"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Fun *</template-arg></specialization><inherit access="public">boost::proto::transform::when&lt; Grammar, Fun &gt;</inherit></struct-specialization><struct name="otherwise"><template>
+ <template-type-parameter name="Fun"/>
+ </template><inherit access="public">boost::proto::transform::when&lt; _, Fun &gt;</inherit></struct><struct-specialization name="when"><template>
+ <template-type-parameter name="Grammar"/>
+ <template-type-parameter name="Return"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Return()</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type>mpl::if_&lt; <classname>is_callable</classname>&lt; Return &gt;, <classname>call</classname>&lt; Return() &gt;, <classname>make</classname>&lt; Return() &gt; &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="function3"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter><description><para>Function call operator </para></description></method></method-group></struct-specialization><struct-specialization name="when"><template>
       <template-type-parameter name="Grammar"/>
- <template-type-parameter name="Function3"/>
- </template><struct name="apply"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Return(A0)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type>mpl::if_&lt; <classname>is_callable</classname>&lt; Return &gt;, <classname>call</classname>&lt; Return(A0) &gt;, <classname>make</classname>&lt; Return(A0) &gt; &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/list.hpp"><para>A special-purpose proto transform for putting things into a fusion::cons&lt;&gt; list. </para><namespace name="boost"><namespace name="proto"><namespace name="transform"><struct name="list"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter><description><para>Function call operator </para></description></method></method-group></struct-specialization><struct-specialization name="when"><template>
       <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Return(A0</template-arg><template-arg>A1)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><typedef name="type"><type>fusion::cons&lt; typename Grammar::template <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type, State &gt;</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type>mpl::if_&lt; <classname>is_callable</classname>&lt; Return &gt;, <classname>call</classname>&lt; Return(A0, A1) &gt;, <classname>make</classname>&lt; Return(A0, A1) &gt; &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct><struct name="tail"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter><description><para>Function call operator </para></description></method></method-group></struct-specialization><struct-specialization name="when"><template>
       <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template><typedef name="type"><type>Grammar::template <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type::cdr_type</type></typedef></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type>mpl::if_&lt; <classname>is_callable</classname>&lt; Return &gt;, <classname>call</classname>&lt; Return(A0, A1, A2) &gt;, <classname>make</classname>&lt; Return(A0, A1, A2) &gt; &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header><header name="boost/xpressive/proto/transform/pass_through.hpp"><para>TODO </para><namespace name="boost"><namespace name="proto"><namespace name="has_transformns_"><struct name="has_pass_through_transform"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter><description><para>Function call operator </para></description></method></method-group></struct-specialization><struct-specialization name="when"><template>
       <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type>mpl::if_&lt; <classname>is_callable</classname>&lt; Return &gt;, <classname>call</classname>&lt; Return(A0, A1, A2, A3) &gt;, <classname>make</classname>&lt; Return(A0, A1, A2, A3) &gt; &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace><namespace name="transform"><struct name="pass_through"><template>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter><description><para>Function call operator </para></description></method></method-group></struct-specialization><struct-specialization name="when"><template>
       <template-type-parameter name="Grammar"/>
- </template><struct name="apply"><template>
+ <template-type-parameter name="Return"/>
+ <template-type-parameter name="A0"/>
+ <template-type-parameter name="A1"/>
+ <template-type-parameter name="A2"/>
+ <template-type-parameter name="A3"/>
+ <template-type-parameter name="A4"/>
+ </template><specialization><template-arg>Grammar</template-arg><template-arg>Return(A0</template-arg><template-arg>A1</template-arg><template-arg>A2</template-arg><template-arg>A3</template-arg><template-arg>A4)</template-arg></specialization><struct-specialization name="result"><template>
+ <template-type-parameter name="This"/>
       <template-type-parameter name="Expr"/>
       <template-type-parameter name="State"/>
       <template-type-parameter name="Visitor"/>
- </template></struct><method-group name="public member functions"/><constructor/><method-group name="public static functions"><method name="call" cv=""><type>static <classname>apply</classname>&lt; Expr, State, Visitor &gt;::type</type><template>
+ </template><specialization><template-arg>This(Expr</template-arg><template-arg>State</template-arg><template-arg>Visitor)</template-arg></specialization><typedef name="impl"><type>mpl::if_&lt; <classname>is_callable</classname>&lt; Return &gt;, <classname>call</classname>&lt; Return(A0, A1, A2, A3, A4) &gt;, <classname>make</classname>&lt; Return(A0, A1, A2, A3, A4) &gt; &gt;::type</type></typedef><typedef name="type"><type>impl::template result&lt; void(Expr, State, Visitor) &gt;::type</type></typedef></struct-specialization><typedef name="proto_base_expr"><type>Grammar::proto_base_expr</type></typedef><method-group name="public member functions"><method name="operator()" cv="const"><type>result&lt; void(Expr, State, Visitor) &gt;::type</type><template>
           <template-type-parameter name="Expr"/>
           <template-type-parameter name="State"/>
           <template-type-parameter name="Visitor"/>
- </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter></method></method-group></struct></namespace></namespace></namespace></header></library-reference>
+ </template><parameter name="expr"><paramtype>Expr const &amp;</paramtype></parameter><parameter name="state"><paramtype>State const &amp;</paramtype></parameter><parameter name="visitor"><paramtype>Visitor &amp;</paramtype></parameter><description><para>Function call operator </para></description></method></method-group></struct-specialization></namespace></namespace></namespace></header></library-reference>

Modified: branches/release/libs/xpressive/proto/doc/quick_start.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/quick_start.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/quick_start.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)

Modified: branches/release/libs/xpressive/proto/doc/rationale.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/rationale.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/rationale.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 [/
- / Copyright (c) 2006 Eric Niebler
+ / Copyright (c) 2008 Eric Niebler
  /
  / 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)
@@ -7,7 +7,9 @@
 
 [section:rationale Appendix B: Rationale]
 
+[/==================================================]
 [section:static_initialization Static Initialization]
+[/==================================================]
 
 Proto expression types are PODs (Plain Old Data), and do not have constructors.
 They are brace-initialized, as follows:
@@ -17,11 +19,81 @@
 The reason is so that expression objects like `_i` above can be ['statically
 initialized]. Why is static initialization important? The terminals of many
 domain-specific embedded languages are likely to be global const objects, like
-`_1` and `_2` from the Boost.Lambda library. Were these object to require
+`_1` and `_2` from the Boost Lambda Library. Were these object to require
 run-time initialization, it might be possible to use these objects before they
 are initialized. That would be bad. Statically initialized objects cannot be
 misused that way.
 
 [endsect]
 
+[/======================================================================]
+[section:result_of Proto Transforms and the Restricted ResultOf Protocol]
+[/======================================================================]
+
+All Proto primitive transforms make use of a variant of the TR1 ResultOf
+protocol for computing the type of the transform's return value. Such
+transforms must have a nested `result<>` template (not a nested `result_type`
+typedef) which takes exactly three parameter types. That is, it must be
+defined as:
+
+ template<typename Sig> struct result {};
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef ... type;
+ };
+
+In the above, `Expr`, `State`, and `Visitor` are assumed by Proto to be
+non-cv-qualified non-reference types. The implication is that for some
+Proto transform `Tr`, some `result_of<>` instantiations work while others
+don't. See below.
+
+ // ERROR, doesn't work:
+ boost::result_of<Tr(Expr const &, State const &, Visitor &)>::type
+
+ // OK, works:
+ boost::result_of<Tr(Expr, State, Visitor)>::type
+
+It is done this way largely for compile-time performance. Full
+compliance with the TR1 ResultOf protocol incurs a not insignificant penalty
+at compile time. Metaprogramming tricks are needed to first detect a nested
+`result_type` typedef if it exists. And each nested `result<>` template
+would need to be coded specially to handle references and cv-qualifiers, which
+incurs many instantiations of `remove_reference<>` and `remove_cv<>`. In
+private testing, this was found to have a measurable impact on compile-time
+performance in the order of 10-15%, which was deemed unacceptable.
+
+The restricted protocol improves compile times while remaining largely
+compatible with TR1's `result_of<>`. As a side benefit, it makes
+Proto's primitive transforms easier to implement, since the user need not
+worry about stripping references and cv-qualification in their nested
+`result<>` templates.
+
+[endsect]
+
+[/=========================================================]
+[section:preprocessor Why Not Reuse MPL, Fusion, et cetera?]
+[/=========================================================]
+
+Anyone who has peeked at Proto's source code has probably wondered,
+"Why all the dirty preprocessor gunk? Couldn't this have been all
+implemented cleanly on top of libraries like MPL and Fusion?" The
+answer is that Proto could have been implemented this way, and in fact
+was at one point. The problem is that template metaprogramming (TMP)
+makes for very long compile times. As a foundation upon which other
+TMP-heavy libraries will be built, Proto itself should be as lightweight
+as possible. That is achieved by prefering preprocessor metaprogramming
+to template metaprogramming. Expanding a macro is far more efficient
+than instantiating a template. In some cases, the "clean" version takes
+10x longer to compile than the "dirty" version.
+
+The "clean and slow" version of Proto can still be found at
+http://svn.boost.org/svn/boost/branches/proto/v3. Anyone who is interested
+can download it and verify that it is, in fact, unusably slow to compile.
+Note that this branch's development was abandoned, and it does not
+conform exactly with Proto's current interface.
+
+[endsect]
+
 [endsect]

Modified: branches/release/libs/xpressive/proto/doc/transforms.qbk
==============================================================================
--- branches/release/libs/xpressive/proto/doc/transforms.qbk (original)
+++ branches/release/libs/xpressive/proto/doc/transforms.qbk 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -28,30 +28,50 @@
 are to be transformed. Just as the grammar is defined recursively, so too
 is the tree transformation.
 
-A grammar decorated with transforms has a static member function named
-`call()` which takes three parameters:
-
-* `expr` -- the expression to transform
-* `state` -- the state of the transformation so far
-* `visitor` -- any optional auxiliary mutable state information
-
-It also has a nested `apply<>` template which is used to calculate the return
-type of the `call()` member function.
-
-Let's say we have a grammar called `Grammar`, an expression template
-object called `expr` that matches the grammar, and `state` and `visitor`
-objects of your choosing. What happens when you call
-`Grammar::call(expr, state, visitor)`? Well, if `Grammar` were defined as
-`shift_right< Rule1, Rule2 >`, for instance, it might transform the left
-child of `expr` according to `Rule1`'s transform, do the same thing to the
-right child using `Rule2`, and combine the results somehow. Of course, `Rule1`
-and `Rule2` might be defined in terms of other rules with other transforms, so
-the process executes recursively. Some transforms, the `fold<>` in particular,
-use the result of transforming one child as the `state` parameter when
-transforming the other child. In this way, the results of the recursive
-transformations can be accumulated bottom-up.
-
-That's it, in a nutshell. Now let's crack this nut and peek inside.
+You associate transforms with your grammar rules using _when_. For instance,
+you might want to promote all `int` terminals to `long`. You would say
+`when< terminal<int>, terminal<long>::type(_arg) >`. Here,
+`terminal<long>::type(_arg)` is an example of a Proto transform. It says to
+create an object of type `terminal<long>::type` and initialize it with the
+result of the `_arg` transform. `_arg` is a transform defined by Proto which
+essentially calls `proto::arg()` on the current expression.
+
+[note The transform above might look a little strange at first. It appears
+to be constructing a temporary object in place. In fact, it is a
+/function type/. Since `terminal<long>::type` and `_arg` are types,
+`terminal<long>::type(_arg)` is actually the type of a function that takes
+`_arg` as a parameter and returns `terminal<long>::type`. That is immaterial;
+there is no such function in reality. Rather, Proto interprets this function
+type as a transform, the effect of which is described above. The resemblance
+to an in-place construction of a temporary object is intentional. It is a
+concise and natural notation for specifying transforms. Proto transforms use
+function types extensively, as we'll see.]
+
+A grammar decorated with transforms is a function object that takes three
+parameters:
+
+* `expr` -- the Proto expression to transform
+* `state` -- the initial state of the transformation
+* `visitor` -- any optional mutable state information
+
+Grammars with transforms are proper function objects, so you can use
+`boost::result_of<>` to calculate their return types. So, applying a
+transform typically looks like this:
+
+ // Assuming we have an expression to transform,
+ // an initial state, and a visitor ...
+ Expr expr;
+ State state;
+ Visitor visitor;
+
+ // ... calculate the result type of applying
+ // Grammar's transform ...
+ typedef typename
+ boost::result_of<Grammar(Expr, State, Visitor)>::type
+ result_type;
+
+ // ... and apply Grammar's transform:
+ result_type result = Grammar()(expr, state, visitor);
 
 [/==========================================]
 [section Example: Calculator Arity Transform]
@@ -87,14 +107,14 @@
 
 We can immediately write the calculator grammar as follows:
 
-[CalculatorGrammar]
+[CalcGrammar]
 
 We can read this as follows: a calculator expression is either placeholder 1,
 placeholder 2, some other terminal, or some unary or binary operator whose
 operands are calculator expressions. Recall that `proto::_` is a wildcard which
 matches anything. So `terminal< _ >` will match any terminal, and
-`unary_expr< _, CalculatorGrammar >` will match any unary expression
-for which the operand matches CalculatorGrammar (the `_` matches any operator
+`unary_expr< _, CalcArity >` will match any unary expression
+for which the operand matches CalcArity (the `_` matches any operator
 tag).
 
 [/============================]
@@ -117,129 +137,151 @@
 The total arity of a calculator expression is found by recursively evaluating
 the arity of all of the sub-expressions and taking the maximum.
 
-Let's look at the sub-expression for placeholder 1. It is matched by this part
-of our grammar: `terminal< placeholder1 >`. We want to associate this
+Let's look at the sub-expression for the placeholder `_1`. It is matched by this
+part of our grammar: `terminal< placeholder1 >`. We want to associate this
 part of our grammar with an arity of `1`. We do that by attaching a transform.
 Since the arity of an expression can be evaluated at compile time, let's use
 `mpl::int_<1>` to represent the arity of the first placeholder. The following
 attaches a transform that always evaluates to `mpl::int_<1>`:
 
- transform::always< terminal< placeholder1 >, mpl::int_<1> >
+ when< terminal< placeholder1 >, mpl::int_<1>() >
 
 This grammar rule will match any `placeholder1` terminal, and will transform it
-to `mpl::int_<1>`. Likewise, we will use the `transform::always<>` transform to
-transform `placeholder2` terminals into `mpl::int_<2>`, and other terminals
-into `mpl::int_<0>`.
+to a (default-constructed) `mpl::int_<1>` object. As described previously,
+`mpl::int_<1>()` is a function type, but Proto interprets it as an object to
+construct. We will have a similar transform to convert `placeholder2` terminals
+into `mpl::int_<2>`, and other terminals into `mpl::int_<0>`.
 
 Next, let's write a transform for unary operators that returns the arity of the
 operand. It is simply:
 
- transform::arg< unary_expr< _, CalculatorGrammar > >
-
-As you might expect, the `transform::arg<>` transform returns the argument of the
-unary expression. This looks simple, but there is quite a lot going on here.
-
-First, you should know that transforms are written so that they can be chained.
-So `transform::arg<>` invokes the transform associated with
-`unary_expr< _, CalculatorGrammar >` before it does anything else.
-
-That begs the question, what does `unary_expr<>`'s transform do? Well,
-`unary_expr< _, CalculatorGrammar >` has a default transform
-associated with it. It is a /pass-through/ transform. When an expression
-of the form `expr< T, arg1< X > >` is passed to the transform, its `apply<>`
-member template will invoke the `CalculatorGrammar` transform (which we haven't
-completely defined yet -- patience) on `X` resulting in `Y`, and then
-reassemble the expression as `expr< T, arg1< Y > >`.
+ when< unary_expr< _, CalcArity >, CalcArity(_arg) >
 
-[note You may have noticed that Proto types like `unary_expr<>` serve several
-different but related roles. In particular, `unary_expr<>` is ...
+The transform `CalcArity(_arg)` recursively applies the `CalcArity`
+transform to the child node of the unary expression. As you might have noticed,
+`CalcArity(_arg)` is another function type, but Proto interprets this one
+differently. Rather than trying to construct a `CalcArity` object, Proto
+knows this is a function object and invokes it instead.
+
+[note When using function types as Proto transforms, they can either represent
+an object to construct or a function to call. It is similar to C++ where the
+syntax `foo(x)` can either be interpreted as an object to construct or a
+function to call, depending on whether `foo` is a type or a function. Proto
+can't know in general which is the case, so it uses a trait, `proto::is_callable<>`,
+to differentiate. `is_callable< mpl::int_<1> >::value` is false so `mpl::int_<1>()`
+is an object to construct, but `is_callable< CalcArity >::value` is true so
+`CalcArity(_arg)` is a function to call. (`is_callable< CalcArity >::value` is true
+because `CalcArity` inherits from `proto::or_<>`, which is callable.)]
+
+[/
+ That begs the question, what does `unary_expr<>`'s transform do? Well,
+ `unary_expr< _, CalcArity >` has a default transform
+ associated with it. It is a /pass-through/ transform. When an expression
+ of the form `expr< T, arg1< X > >` is passed to the transform, its `apply<>`
+ member template will invoke the `CalcArity` transform (which we haven't
+ completely defined yet -- patience) on `X` resulting in `Y`, and then
+ reassemble the expression as `expr< T, arg1< Y > >`.
+
+ [note You may have noticed that Proto types like `unary_expr<>` serve several
+ different but related roles. In particular, `unary_expr<>` is ...
+
+ ... [*a meta-function]: `unary_expr<T, X>::type` is a typedef for
+ `expr<T, args1<X> >`.
+
+ ... [*a grammar]: `unary_expr<U, Y>` is a simle grammar that matches
+ `expr<T, args1<X> >` if an only if `U` is `T` or `proto::_`, and `Y` is a
+ grammar that matches `X`.
+
+ ... [*a transform]: `unary_expr<U, Y>::apply<expr<T, args1<X> >, S, V>::type`
+ applies `unary_expr<>`'s pass-through transform to `expr<T, args1<X> >` with
+ state `S` and visitor `V`. The result is
+ `expr<T, args1< Y::apply<X, S, V>::type > >`.
+ ]
+
+ So, putting a few things together, consider the calculator expression `+_1`,
+ which would have the following type:
+
+ expr< tag::posit, arg1<
+ expr< tag::terminal, arg0< placeholder1 > >
+ > >
+
+ If we executed the `unary_expr< _, CalcArity >` transform on this
+ expression, we would expect to get:
+
+ expr< tag::posit, arg1<
+ mpl::int_<1>
+ > >
+
+ And if we added the `transform::arg<>` transform also, as in
+ `transform::arg< unary_expr< _, CalcArity > >`, we expect the result
+ to be:
 
-... [*a meta-function]: `unary_expr<T, X>::type` is a typedef for
-`expr<T, args1<X> >`.
-
-... [*a grammar]: `unary_expr<U, Y>` is a simle grammar that matches
-`expr<T, args1<X> >` if an only if `U` is `T` or `proto::_`, and `Y` is a
-grammar that matches `X`.
-
-... [*a transform]: `unary_expr<U, Y>::apply<expr<T, args1<X> >, S, V>::type`
-applies `unary_expr<>`'s pass-through transform to `expr<T, args1<X> >` with
-state `S` and visitor `V`. The result is
-`expr<T, args1< Y::apply<X, S, V>::type > >`.
-]
-
-So, putting a few things together, consider the calculator expression `+_1`,
-which would have the following type:
-
- expr< tag::posit, arg1<
- expr< tag::terminal, arg0< placeholder1 > >
- > >
+ mpl::int_<1>
 
-If we executed the `unary_expr< _, CalculatorGrammar >` transform on this
-expression, we would expect to get:
+ Which is exactly what we want.
 
- expr< tag::posit, arg1<
- mpl::int_<1>
- > >
+ [note *Default Transforms*
 
-And if we added the `transform::arg<>` transform also, as in
-`transform::arg< unary_expr< _, CalculatorGrammar > >`, we expect the result
-to be:
-
- mpl::int_<1>
-
-Which is exactly what we want.
-
-[note *Default Transforms*
-
-All the tools Proto provides for defining grammar rules have default transforms
-associated with them. Just as `unary_expr<>` has a pass-through transform,
-so too does `binary_expr<>`, `shift_right<>`, and all the others.
-`proto::or_<>` has a default transform which evaluates the transform of the
-branch that matched. `proto::and_<>`'s default transform evaluates the
-transform of the last branch. Even `proto::expr<>`, `proto::if_<>`,
-`proto::not_<>`, and `proto::_` have no-op default transforms that simply return
-unmodified the expressions passed to them.
+ All the tools Proto provides for defining grammar rules have default transforms
+ associated with them. Just as `unary_expr<>` has a pass-through transform,
+ so too does `binary_expr<>`, `shift_right<>`, and all the others.
+ `proto::or_<>` has a default transform which evaluates the transform of the
+ branch that matched. `proto::and_<>`'s default transform evaluates the
+ transform of the last branch. Even `proto::expr<>`, `proto::if_<>`,
+ `proto::not_<>`, and `proto::_` have no-op default transforms that simply return
+ unmodified the expressions passed to them.
+ ]
 ]
 
 The arity of a binary operator is the maximum of the arity of the left and
-right operands. Proto does not provide a transform that can help us directly,
-but we can easily write our own. This is what it looks like, and we'll describe
-it below:
-
-[binary_max]
-
-This transform will be used as follows:
-`binary_max< binary_expr< _, CalculatorGrammar, CalculatorGrammar > >`.
-First, note that the transform is a template that takes a Grammar as a template
-parameter. It inherits from the Grammar, as all transforms must. Next, we
-define a nested `apply<>` template which calculates the return type. The first
-thing it does is invoke `Grammar`'s transform. Recall that `binary_expr<>`
-has a pass-through transform. Given an expression like
-`expr< T, arg2< A, B > >`, it transforms it to `expr< T, arg2< X, Y > >`, where
-`X` and `Y` are the results of transforming `A` and `B` according to
-`CalculatorGrammar`.
-
-Next, we extract from this transformed binary expression the left and right
-argument types. As the arguments were transformed in the previous step, we
-expect them to already be of the form `mpl::int_<N>`. Then we use `mpl::max<>`
-to find the maximum, and we're done.
-
-The static `call()` member function is needed to complete the transform
-interface. It simply returns a default-constructed object, which will be an
-instantiation of `mpl::int_<>`.
+right operands. We can specify this with the help of `mpl::max<>`, which is a
+so-called meta-function that computes the maximum of two compile-time integers.
+The transform is described below:
+
+ when<
+ binary_expr< _, CalcArity, CalcArity >
+ , mpl::max< CalcArity(_left), CalcArity(_right) >()
+ >
 
-Piecing it all together, the complete `CalculatorGrammar` looks like this:
+The above says to match binary calculator expressions and compute their
+arity by first computing the arity of the left and right children and then
+taking their maximum.
+
+There's a lot going on in the above transform, so let's take it one piece
+at a time, starting with the parts we know. `CalcArity(_left)`
+will calculate the arity of the left child, returning a compile-time integer.
+Likewise for `CalcArity(_right)`. What is new is that these two
+transforms are nested within another: `mpl::max<...>()`. Proto notices that
+`mpl::max<...>` is not callable, so this transform is interpreted as an
+object to construct rather than a function to invoke. Using meta-programming
+tricks, Proto disassembles the `mpl::max<...>` template looking for nested
+Proto transforms to apply. It finds two and applies them, resulting in
+`mpl::max< mpl::int_<X>, mpl::int_<Y> >`.
+
+Having first applied any nested transforms, Proto then looks to see if
+`mpl::max<X, Y>` has a nested `::type` typedef. This is a common convention
+used by meta-functions. In this case, `mpl::max<>::type` is a typedef
+for `mpl::int_< Z >` where `Z` is the maximum of `X` and `Y`. The trailing
+`()` on the transform indicates that the result should be default-constructed,
+so this transform returns `mpl::int_<Z>()`. And we're done.
+
+[note Had `mpl::max<>` not had a nested `::type` typedef, the transform
+would have created and returned a default-constructed `mpl::max<>` object
+instead. That is, the result of substituting nested transforms need not
+of necessity have a nested `::type` typedef, but it is used if it is there.]
 
-[CalculatorArityGrammar]
+Piecing it all together, the complete `CalcArity` looks like this:
 
-We can use our CalculatorGrammar transform to calculate the arity of any
+[CalcArity]
+
+We can use our `CalcArity` transform to calculate the arity of any
 calculator expression:
 
     int i = 0; // not used, dummy state and visitor parameter
 
- std::cout << CalculatorGrammar::call( lit(100) * 200, i, i) << '\n';
- std::cout << CalculatorGrammar::call( (_1 - _1) / _1 * 100, i, i) << '\n';
- std::cout << CalculatorGrammar::call( (_2 - _1) / _2 * 100, i, i) << '\n';
+ std::cout << CalcArity()( lit(100) * 200, i, i) << '\n';
+ std::cout << CalcArity()( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalcArity()( (_2 - _1) / _2 * 100, i, i) << '\n';
 
 This displays the following:
 
@@ -257,67 +299,91 @@
 [section Canned Transforms]
 [/========================]
 
-Some transforms are generally useful, so Proto provides them. They are
-described below. Each is of the form:
-
- boost::proto::transform::``[~transform-name]``< Grammar ``[~\[, additional args ...\]]`` >
+So far, we've seen how to write custom transforms using function types.
+These were implemented in terms of more primitive transforms provided by
+Proto, such as `_arg`, `_left`, and `_right`. This section describes those
+transforms and others in detail.
 
-They each inherit from their `Grammar` parameter; therefore, they themselves
-match the same expressions as `Grammar` does. As transforms, they all have
-nested static `call()` member functions that accept `expr`, `state`, and
-`visitor` parameters, as well as `apply<>` member templates for calculating
-the return type of `call()`. The tables below show what `call()` and `apply<>`
-do for each of the transforms that Proto provides.
+All the transforms defined in this section are of the following form:
 
-[section:arg_c_and_friends [^arg<>], [^arc_c<>], [^left<>] and [^right<>]]
-
- namespace boost { namespace proto { namespace transform
+ struct some_transform : callable
     {
- template<typename Grammar, typename N = mpl::long_<0> >
- struct arg;
+ template<typename Sig>
+ struct result;
 
- template<typename Grammar, long N>
- struct arg_c;
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ {
+ typedef ... type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<void(Expr, State, Visitor)>::type
+ operator()(Expr const &expr, State const &state, Visitor &visitor) const
+ {
+ return ...;
+ }
+ };
+
+So defined, `some_transform` is a transform "in the raw". It can be used
+without needing to explicitly specify any arguments to the transform. These
+are the building blocks from which you can compose larger transforms using
+function types.
 
- template<typename Grammar>
- struct left;
+[section:arg_c_and_friends [^_arg], [^_left], and [^_right]]
 
- template<typename Grammar>
- struct right;
- }}}
+ namespace boost { namespace proto
+ {
+ namespace transform
+ {
+ template<long N>
+ struct arg_c;
+
+ typedef arg_c<0> arg0;
+ typedef arg_c<1> arg1;
+ ...
+ typedef arg_c<9> arg9;
+
+ typedef arg_c<0> arg;
+ typedef arg_c<0> left;
+ typedef arg_c<1> right;
+ }
+
+ typedef transform::arg0 _arg0;
+ typedef transform::arg1 _arg1;
+ ...
+ typedef transform::arg9 _arg9;
+
+ typedef transform::arg _arg;
+ typedef transform::left _left;
+ typedef transform::right _right;
+ }}
 
 These transforms are useful for extracting the ['[^N]]th argument from an
-expression. The `left<Grammar>` transform is equivalent to the
-`arg_c<Grammar, 0>` transform, and the `right<Grammar>` transform is equivalent
-to the `arg_c<Grammar, 1>` transform.
+expression. The `_left` transform is equivalent to the `arg_c<0>` transform,
+and the `_right` transform is equivalent to the `arg_c<1>` transform.
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::arg<Grammar, N>::apply<Expr, State, Visitor>::type`]
- [`proto::result_of::arg<typename Grammar::apply<Expr, State, Visitor>::type, N>::type`]
- ]
- [ [`transform::arg<Grammar, N>::call(expr, state, visitor)`]
- [`proto::arg<N>(Grammar::call(expr, state, visitor))`]
- ]
- [ [`transform::arg_c<Grammar, N>::apply<Expr, State, Visitor>::type`]
- [`proto::result_of::arg_c<typename Grammar::apply<Expr, State, Visitor>::type, N>::type`]
+ [ [`transform::arg_c<N>::result<void(Expr, State, Visitor)>::type`]
+ [`proto::result_of::arg_c<Expr, N>::type`]
     ]
- [ [`transform::arg_c<Grammar, N>::call(expr, state, visitor)`]
- [`proto::arg_c<N>(Grammar::call(expr, state, visitor))`]
+ [ [`transform::arg_c<N>()(expr, state, visitor)`]
+ [`proto::arg_c<N>(expr)`]
     ]
- [ [`transform::left<Grammar>::apply<Expr, State, Visitor>::type`]
- [`proto::result_of::left<typename Grammar::apply<Expr, State, Visitor>::type>::type`]
+ [ [`transform::left::result<void(Expr, State, Visitor)>::type`]
+ [`proto::result_of::left<Expr>::type`]
     ]
- [ [`transform::left<Grammar>::call(expr, state, visitor)`]
- [`proto::left(Grammar::call(expr, state, visitor))`]
+ [ [`transform::left()(expr, state, visitor)`]
+ [`proto::left(expr)`]
     ]
- [ [`transform::right<Grammar>::apply<Expr, State, Visitor>::type`]
- [`proto::result_of::right<typename Grammar::apply<Expr, State, Visitor>::type>::type`]
+ [ [`transform::right::result<void(Expr, State, Visitor)>::type`]
+ [`proto::result_of::right<Expr>::type`]
     ]
- [ [`transform::right<Grammar>::call(expr, state, visitor)`]
- [`proto::right(Grammar::call(expr, state, visitor))`]
+ [ [`transform::right()(expr, state, visitor)`]
+ [`proto::right(expr)`]
     ]
 ]
 
@@ -325,391 +391,649 @@
 
     // Matches an integer terminal and extracts the int.
     struct Int
- : transform::arg< terminal<int> >
+ : when< terminal<int>, _arg >
     {};
 
 [endsect]
 
-[section:identity_and_friends [^identity<>], [^state<>] and [^visitor<>]]
+[section:identity_and_friends [^_expr], [^_state] and [^_visitor]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar>
- struct identity;
-
- template<typename Grammar>
- struct state;
-
- template<typename Grammar>
- struct visitor;
- }}}
-
-The `identity<>`, `state<>` and `visitor<>` transforms merely return the
-`expr`, `state` and `visitor` arguments, respectively.
+ namespace transform
+ {
+ struct expr;
+ struct state;
+ struct visitor;
+ }
+
+ typedef transform::expr _expr;
+ typedef transform::state _state;
+ typedef transform::visitor _visitor;
+ }}
+
+The `expr`, `state` and `visitor` transforms merely return the
+`expr`, `state` and `visitor` arguments, respectively. Proto's
+wildcard pattern, `_`, behaves like `transform::expr` when used
+as a transform.
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::identity<Grammar>::apply<Expr, State, Visitor>::type`]
+ [ [`_::result<void(Expr, State, Visitor)>::type`]
         [`Expr`]
     ]
- [ [`transform::identity<Grammar>::call(expr, state, visitor)`]
- [`expr`]
+ [ [`_()(expr_, state, visitor)`]
+ [`expr_`]
     ]
- [ [`transform::state<Grammar>::apply<Expr, State, Visitor>::type`]
+ [ [`transform::expr::result<void(Expr, State, Visitor)>::type`]
+ [`Expr`]
+ ]
+ [ [`transform::expr()(expr_, state, visitor)`]
+ [`expr_`]
+ ]
+ [ [`transform::state::result<void(Expr, State, Visitor)>::type`]
         [`State`]
     ]
- [ [`transform::state<Grammar>::call(expr, state, visitor)`]
- [`state`]
+ [ [`transform::state()(expr, state_, visitor)`]
+ [`state_`]
     ]
- [ [`transform::visitor<Grammar>::apply<Expr, State, Visitor>::type`]
+ [ [`transform::visitor::result<void(Expr, State, Visitor)>::type`]
         [`Visitor`]
     ]
- [ [`transform::visitor<Grammar>::call(expr, state, visitor)`]
- [`visitor`]
+ [ [`transform::visitor()(expr, state, visitor_)`]
+ [`visitor_`]
     ]
 ]
 
 Example:
 
     // Matches a subscript expression where the left- and right-hand operands
- // match MyGrammar, returns the expression unmodified; that is, without
- // applying MyGrammar's transforms to the left and right operands, as would
- // happen by default.
+ // match MyGrammar, returns the expression unmodified
     struct Subscript
- : transform::identity< subscript<MyGrammar, MyGrammar> >
+ : when< subscript<MyGrammar, MyGrammar>, _expr >
     {};
 
 [endsect]
 
-[section:always [^always<>]]
+[section:if [^if_<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar, typename Always, typename Factory = ``[~default-factory]``>
- struct always;
- }}}
+ namespace control
+ {
+ template<
+ typename If
+ , typename Then = _
+ , typename Else = not_<_>
+ >
+ struct if_;
+ }
 
-The `always<>` transform always returns a certain type. By default, its
-`call()` member returns a default constructed object of that type, but you can
-configure this with the optional `Factory` parameter.
+ using control::if_;
+ }}
+
+We've already seen the _if_ template in the context of grammars, but
+_if_ can also be used as a transform. It can be used to conditionally
+apply one transform or another based on some condition. The three
+template parameters are Proto transforms. The result of applying the
+first transform should be a compile-time Boolean. If it is true, then
+the first transform is applied. The second is applied otherwise.
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::always<Grammar, Type, Factory>::apply<Expr, State, Visitor>::type`]
- [`Type`]
+ [ [``control::if_<If, Then, Else>
+ ::result<void(Expr, State, Visitor)>::type``]
+ [``typedef
+ mpl::if_<
+ when<_, If>::result<void(Expr, State, Visitor)>::type
+ , when<_, Then>
+ , when<_, Else>
+ >::type
+branch;
+
+typedef branch::result<void(Expr, State, Visitor)>::type type;``]
     ]
- [ [`transform::always<Grammar, Type, Factory>::call(expr, state, visitor)`]
- [`Factory()()`]
+ [ [`control::if_<If, Then, Else>()(expr, state, visitor)`]
+ [``typedef ... branch; // Same as above
+branch()(expr, state, visitor);``]
     ]
 ]
 
 Example:
 
- // Match a placeholder terminal and return the arity of the
- // placeholder.
- struct PlaceholderArity
- : transform::always< terminal<placeholder1>, mpl::int_<1> >
+ // Match a terminal. If size of the terminal
+ // argument is less than or equal to 4, make
+ // a new terminal that stores the argument by
+ // value. Otherwise, store the argument by
+ // reference.
+ struct ByValOrRef
+ : when<
+ terminal<_>
+ , if_<
+ mpl::less_equal<
+ mpl::sizeof_<_arg>
+ , mpl::size_t<4>
+ >()
+ , _make_terminal(_arg)
+ , _make_terminal(_ref(_arg))
+ >
+ >
     {};
 
 [endsect]
 
-[section:applyn [^apply1<>], [^apply2<>] and [^apply3<>]]
+[section:and_or_not [^and_<>], [^or_<>], and [^not_<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar, typename Lambda, typename Factory = ``[~default-factory]``>
- struct apply1;
-
- template<typename Grammar, typename Lambda, typename Factory = ``[~default-factory]``>
- struct apply2;
-
- template<typename Grammar, typename Lambda, typename Factory = ``[~default-factory]``>
- struct apply3;
- }}}
+ namespace control
+ {
+ template<typename... T>
+ struct and_;
+
+ template<typename... T>
+ struct or_;
+
+ template<typename T>
+ struct not_;
+ }
+
+ using control::and_;
+ using control::or_;
+ using control::not_;
+ }}
+
+As with _if_, the grammar elements _and_, _or_, and _not_ can
+also be used as transforms. At a high level, here is what the
+transforms do:
+
+[variablelist
+[ [`and_<T0,T1,...,Tn>`]
+ [Apply the transform `Tn`.] ]
+[ [`or_<T0,T1,...,Tn>`]
+ [Apply the transform `Tx` where `x` is the lowest number
+ such that `matches<Expr,Tx>::value` is `true`.] ]
+[ [`not_<T>`] [Return the current expression unchanged.] ]
+]
 
-The `apply1<>` transform invokes an MPL lambda expression with the Proto
-expression as the argument, `apply2<>` uses the expression and the state
-as arguments and `apply3<>` uses the expression, state and visitor.
+The following table specifies the behaviors described above more
+precisely.
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::apply1<Grammar, Lambda, Factory>::apply<Expr, State, Visitor>::type`]
- [`mpl::apply1<Lambda, typename Grammar::apply<Expr, State, Visitor>::type>::type`]
- ]
- [ [`transform::apply1<Grammar, Lambda, Factory>::call(expr, state, visitor)`]
- [`Factory()(Grammar::call(expr, state, visitor))`]
- ]
- [ [`transform::apply2<Grammar, Lambda, Factory>::apply<Expr, State, Visitor>::type`]
- [`mpl::apply2<Lambda, typename Grammar::apply<Expr, State, Visitor>::type, State>::type`]
+ [ [``control::and_<A,B,C>
+ ::result<void(Expr, State, Visitor)>::type``]
+ [`C::result<void(Expr, State, Visitor)>::type`]
+ ]
+ [ [`control::and_<A,B,C>()(expr, state, visitor)`]
+ [`C()(expr, state, visitor)`]
+ ]
+ [ [``control::or_<A,B,C>
+ ::result<void(Expr, State, Visitor)>::type``]
+ [``typedef mpl::if_<
+ matches<Expr, A>
+ , A
+ , mpl::if_<
+ matches<Expr, B>
+ , B
+ , C
+ >::type
+>::type which;
+
+typedef which::result<void(Expr, State, Visitor)>::type type;``]
     ]
- [ [`transform::apply2<Grammar, Lambda, Factory>::call(expr, state, visitor)`]
- [`Factory()(Grammar::call(expr, state, visitor), state)`]
+ [ [`control::or_<A,B,C>()(expr, state, visitor)`]
+ [``typedef ... which; // Same as above
+which()(expr, state, visitor);``]
     ]
- [ [`transform::apply3<Grammar, Lambda, Factory>::apply<Expr, State, Visitor>::type`]
- [`mpl::apply3<Lambda, typename Grammar::apply<Expr, State, Visitor>::type, State, Visitor>::type`]
+ [ [``control::not_<A>
+ ::result<void(Expr, State, Visitor)>::type``]
+ [`Expr`]
     ]
- [ [`transform::apply3<Grammar, Lambda, Factory>::call(expr, state, visitor)`]
- [`Factory()(Grammar::call(expr, state, visitor), state, visitor)`]
+ [ [`control::not_<A>()(expr, state, visitor)`]
+ [`expr`]
     ]
 ]
 
-The `call()` member functions of Proto's `applyN<>` transforms simply return a
-default constructed object of the appropriate type by default. If you want a
-different behavior, you can specify a `Factory` type as the third template
-parameter.
-
 Example:
 
- // Another way to implement a transform that calculates the arity of a
- // binary Calculator expression. This code is functionally equivalent to
- // the binary_max<> transform defined above. The mpl::max<...> type below
- // is an MPL Placeholder expression (note the use of mpl::_) that
- // mpl::apply1<> knows how to evaluate. The effect of the
- // BinaryCalculatorArity grammar is to match binary Calculator expressions,
- // evaluate the arity of the left and right sub-expressions and return the
- // maximum of the two.
- struct BinaryCalculatorArity
- : transform::apply1<
- binary_expr<_, CalculatorArity, CalculatorArity>
- , mpl::max<result_of::left<mpl::_>, result_of::right<mpl::_> >
+ // A transform that matches any expression and
+ // unwraps any reference_wrapped terminals it
+ // finds.
+ struct UnwrapReference
+ : or_<
+ // Pass through terminals that are not
+ // reference_wrappers unchanged:
+ and_<
+ terminal<_>
+ , not_<if_<is_reference_wrapper<_arg>()> >
+ >
+ // For other terminals (i.e., reference_wrapper
+ // terminals), unwrap the reference:
+ , when<
+ terminal<_>
+ , terminal<unwrap_reference<_arg> >(_arg)
+ >
+ // Otherwise, match non-terminals and
+ // recurse.
+ , when<
+ nary_expr<_, vararg<UnwrapReference> >
+ >
+ >
+ {};
+
+The above transform serves to illustrate the behaviors of the _and_,
+_or_, and _not_ transforms, but it is admittedly contrived. The
+transform is more easily written as follows:
+
+ // Functionally identical to the UnwrapReference
+ // transform above:
+ struct UnwrapReference
+ : or_<
+ when<
+ terminal<reference_wrapper<_> >
+ , terminal<unwrap_reference<_arg> >(_arg)
+ >
+ , terminal<_>
+ , nary_expr<_, vararg<UnwrapReference> >
>
     {};
 
 [endsect]
 
-[section:branch [^branch<>]]
+[section:call [^call<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar, typename BranchState>
- struct branch;
- }}}
+ namespace transform
+ {
+ template<typename Fun>
+ struct call;
+ }
+
+ using transform::call;
+ }}
+
+The `call<>` transform is used to invoke callable transforms and evaluate
+their arguments. When you use a callable transform as in
+`when< posit<_>, Callable(_arg) >`, the `call<>` transform is used behind
+the scenes to evaluate `Callable(_arg)`. In fact, for any callable
+transform, the following short- and long-forms are equivalent:
+
+[table
+ [ [Short From]
+ [Long Form] ]
+ [ [ `when< Grammar, Callable(Tran1, Tran2...) >` ]
+ [ `when< Grammar, call< Callable(Tran1, Tran2...) > >` ] ]
+]
+
+You might decide to use `call<>` explicitly in cases when Proto
+can't figure out that a given transform is callable. (See the discussion on
+the `is_callable<>` trait TODO LINK.) Rather than specialize
+`proto::is_callable<>` for your transform, you can simply wrap its use in
+`call<>`, instead.
+
+[tip For users of legacy compilers like MSVC 7.1, `call<>` is useful to work
+around compiler bugs. Doubly-nested transforms such as `Callable(_arg1(_arg2))`
+cause older compilers problems, but the equivalent `Callable(call<_arg1(_arg2)>)`
+solves the problem.]
 
-The `branch<>` transform applies `Grammar`'s transform with a new `state`
-parameter. This is useful when you want to compile a branch of the expression
-tree independently of the rest; for example, when you want to fold everything
-under a certain child node into a list.
+The semantics of `call<>` are described in the table below:
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::branch<Grammar, BranchState>::apply<Expr, State, Visitor>::type`]
- [`typename Grammar::template apply<Expr, BranchState, Visitor>::type`]
- ]
- [ [`transform::branch<Grammar, BranchState>::call(expr, state, visitor)`]
- [`Grammar::call(expr, BranchState(), visitor)`]
+ [ [`call<Fun(A0, A1, ... AN)>::result<void(Expr, State, Visitor)>::type`]
+ [``boost::result_of<Fun(
+ when<_, A0>::result<void(Expr, State, Visitor)>::type
+ , when<_, A1>::result<void(Expr, State, Visitor)>::type
+ ...
+ , when<_, AN>::result<void(Expr, State, Visitor)>::type
+)>::type``]
+ ]
+ [ [`call<Fun(A0, A1, ... AN)>()(expr, state, visitor)`]
+ [``Fun()(
+ when<_, A0>()(expr, state, visitor)
+ , when<_, A1>()(expr, state, visitor)
+ ...
+ , when<_, AN>()(expr, state, visitor)
+)``]
     ]
 ]
 
+The target of a callable transform can be any function object that implements
+the Boost.ResultOf protocol. Function objects that take up to
+`BOOST_PROTO_MAX_ARITY` are handled.
+
+For callable transforms that take 0, 1, or 2 arguments, special handling is done
+to see if the transform actually expects 3 arguments, as Proto's primitive
+transforms do. (This can be detected with meta-programming tricks.) So, even
+though a transform like `_arg1` requires three parameters: expression,
+state and visitor; it can be "called" with just one, like `_arg1(_arg2)`. Proto
+treats this as if were `call<_arg1(_arg2, _state, _visitor)>`.
+
+If no transform arguments are specified at all, as in `call<_arg1>`, this is
+the same as `_arg1`. For this reason, `call<_arg1>(_arg2)` is the same as
+`call<_arg1(_arg2)>`.
+
 Example:
 
-See the [link reverse_fold_example [^reverse_fold<>] example].
+[LazyMakePair2]
 
 [endsect]
 
-[section:compose [^compose<>]]
+[section:make [^make<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar1, typename Grammar2>
- struct compose;
- }}}
+ namespace transform
+ {
+ template<typename Fun>
+ struct make;
+ }
+
+ using transform::make;
+ }}
+
+The `make<>` transform is used to construct objects and evaluate
+their constructor arguments. When you use an object transform as in
+`when< posit<_>, Object(_arg) >`, the `make<>` transform is used behind
+the scenes to evaluate `Object(_arg)`. In fact, for any object
+transform, the following short- and long-forms are equivalent:
 
-The `compose<>` transform applies two transformations in succession. It
-inherits from `Grammar1`, so it matches whatever `Grammar1` matches. The
-result of applying `Grammar1`'s transform is passed to `Grammar2`'s transform,
-along with the `state` and `visitor` parameters. It is assumed that the
-result of applying `Grammar1`'s transform is an expression that matches
-the grammar specified by `Grammar2`.
+[table
+ [ [Short From]
+ [Long Form] ]
+ [ [ `when< Grammar, Object(Tran1, Tran2...) >` ]
+ [ `when< Grammar, make< Object(Tran1, Tran2...) > >` ] ]
+]
 
-The `compose<>` transform is useful in situations where you would like to
-preprocess a node in the expression tree before forwarding it on for further
-processing.
+You might decide to use `make<>` to explicitly differentiate object
+transforms from callable transforms. (See `call<>`.)
+
+[tip For users of legacy compilers like MSVC 7.1, `make<>` is useful to work
+around compiler bugs. Doubly-nested transforms such as `Object1(Object2(_arg))`
+cause older compilers problems, but the equivalent `Object1(make<Object2(_arg)>)`
+solves the problem.]
+
+The `make<>` transform checks to see if the resulting object type is a template.
+If it is, the template type is disassembled to find nested transforms. Proto
+considers the following types to represent transforms:
+
+[def __type__ [~type]]
+[def __X__ X\']
+[def __X0__ X0\']
+[def __X1__ X1\']
+
+* Function types
+* Function pointer types
+* Types for which `proto::is_callable<__type__>::value` is `true`
+
+When an object transform with a template type such as
+`Object<X0,X1,...>(Args...)` is evaluated with a given
+`Expr`, `State`, and `Visitor`, the result type is
+`make_<Object<X0,X1,...>, Expr, State, Visitor>::type` which is
+defined as follows. For each `X` in `X0,X1,...`, do:
+
+* If `X` is a template like `Object2<Y0,Y1,...>`, then let `__X__`
+ be `make_<Object2<Y0,Y1,...>, Expr, State, Visitor>::type`
+ (which evaluates this procedure recursively). Note whether any
+ substitutions took place during this operation.
+* Otherwise, if `X` is a transform, then let `__X__` be
+ `when<_, X>::result<void(Expr, State, Visitor)>::type`.
+ Note that a substitution took place.
+* Otherwise, let `__X__` be `X`, and note that no substitution
+ took place.
+* If any substitutions took place in any of the above steps and
+ `Object<__X0__,__X1__,...>` has a nested `::type` typedef, the
+ result type is `Object<__X0__,__X1__,...>::type`.
+* Otherwise, the result type is `Object<__X0__,__X1__,...>`.
+
+Note that `when<>` is implemented in terms of `call<>` and `make<>`,
+so the above procedure is evaluated recursively.
+
+Given the above description of the `make_<>` helper, the semantics
+of the `make<>` transform is described as follows:
+
+[def __AN__ A[~N]]
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::compose<Grammar1, Grammar2>::apply<Expr, State, Visitor>::type`]
- [``typename Grammar2::template apply<
- typename Grammar1::template apply<Expr, State, Visitor>::type
- , State
- , Visitor
->::type``]
+ [ [`make<Object(A0, A1, ... __AN__)>::result<void(Expr, State, Visitor)>::type`]
+ [`make_<Object, Expr, State, Visitor>::type`]
     ]
- [ [`transform::compose<Grammar1, Grammar2>::call(expr, state, visitor)`]
- [``Grammar2::call(
- Grammar1::call(expr, state, visitor), state, visitor)``]
+ [ [`make<Object(A0, A1, ... __AN__)>()(expr, state, visitor)`]
+ [``make_<Object, Expr, State, Visitor>::type(
+ when<_, A0>()(expr, state, visitor)
+ , when<_, A1>()(expr, state, visitor)
+ ...
+ , when<_, __AN__>()(expr, state, visitor)
+)``]
     ]
 ]
 
+Objects with constructors that take up to `BOOST_PROTO_MAX_ARITY` are handled.
+Some types are so-called /aggregates/ that do not have constructors; rather,
+they use /aggregate initialization/. For these types, you can specialize
+`proto::is_aggregate<>` and Proto will use a brace initializer list to
+initialize the object rather than a constructor. Proto knows that `proto::expr<>`
+is such an aggregate, so if you use object transforms to "construct" a
+new node in an expression tree, the right thing happens.
+
+If no transform arguments are specified at all, as in `make<Object>`, this is
+the same as `make<Object()>`.
+
 Example:
 
- // A fragment of a Calculator grammar which uses compose<> to process
- // a node in the expression tree after it has been preprocessed by
- // an arg<> transform.
- struct Calculator
- : or_<
- // ...
- transform::compose<
- // Match anything of the form +X, and
- // extract X, discarding the +.
- transform::arg<posit<_> >
- // Now invoke the Calculator transform on X
- , Calculator
- >
- >
- {};
+[LazyMakePair]
 
 [endsect]
 
-[section:list [^list<>]]
+[section:bind [^bind<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar>
- struct list;
- }}}
+ namespace transform
+ {
+ template<typename Fun>
+ struct bind;
+ }
+
+ using transform::bind;
+ }}
+
+Sometimes you would like a higher-order transform that returns another
+transform to be evaluated. This can happen when you have a transform
+whose behavior needs to be parameterized on the current state of the
+transformation. For these situations, you can use the `bind<>` transform,
+which is essentially an invocation of the `make<>` transform (to evaluate
+any nested transforms and create the higher-order transform) followed
+by an invocation of `call<>` (to actually execute the higher-order
+transform).
 
-`list<>` is a simple transform that builds a fusion cons list, using the
-transformed expression as the list's head, and the state as the list's tail.
+The behavior of `bind<>` is easily specified in terms of `make<>` and
+`call<>`.
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::list<Grammar>::apply<Expr, State, Visitor>::type`]
- [``fusion::cons<
- typename Grammar::template apply<Expr, State, Visitor>::type
- , State
->``]
- ]
- [ [`transform::list<Grammar>::call(expr, state, visitor)`]
- [``fusion::cons<
- typename Grammar::template apply<Expr, State, Visitor>::type
- , State
->(Grammar::call(expr, state, visitor), state)``]
+ [ [`bind<Object(A0, A1, ... __AN__)>::result<void(Expr, State, Visitor)>::type`]
+ [``call<
+ make<Object>::result<void(Expr, State, Visitor)>::type(A0, A1, ... __AN__)
+>::result<void(Expr, State, Visitor)>::type``]
+ ]
+ [ [`bind<Object(A0, A1, ... __AN__)>()(expr, state, visitor)`]
+ [``call<
+ make<Object>::result<void(Expr, State, Visitor)>::type(A0, A1, ... __AN__)
+>()(expr, state, visitor)``]
     ]
 ]
 
-Example:
+If no transform arguments are specified at all, as in `bind<Object>`, this is
+the same as `bind<Object(_expr, _state, _visitor)>`.
+
+[endsect]
 
-See the [link reverse_fold_example [^reverse_fold<>] example].
+[section:when [^when<>]]
+
+ namespace boost { namespace proto
+ {
+ namespace transform
+ {
+ template<typename Grammar, typename Transform = Grammar>
+ struct when;
+ }
+
+ using transform::when;
+ }}
+
+`when<>` associates a grammar rule with a transform. It can be used
+in a grammar in place of the rule; that is, it behaves as a grammar
+rule. Expression tree nodes that match the grammar rule are processed
+with the associated transform; that is, `when<>` also behaves like
+a transform.
+
+When no transform is specified, as with `when< posit<Calculator> >`,
+the grammar is treated as the transform. Every grammar element has
+a default transform. For most, such as `posit<>`, the default transform
+is `pass_through<>`.
+
+The `when<>` transform is easily specified in terms of `call<>`,
+`make<>`, and the `is_callable<>` trait.
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`when<Grammar, R(A0, A1, ... __AN__)>::result<void(Expr, State, Visitor)>::type`]
+ [``mpl::if_<
+ is_callable<R>
+ , call<R(A0, A1, ... __AN__)>
+ , make<R(A0, A1, ... __AN__)>
+>::type::result<void(Expr, State, Visitor)>::type``]
+ ]
+ [ [`when<Grammar, R(A0, A1, ... __AN__)>()(expr, state, visitor)`]
+ [``mpl::if_<
+ is_callable<R>
+ , call<R(A0, A1, ... __AN__)>
+ , make<R(A0, A1, ... __AN__)>
+>::type()(expr, state, visitor)``]
+ ]
+]
+
+If no transform arguments are specified, as in `when<Grammar, _arg>`, the
+transform is assumed to be callable; that is, it is equivalent to
+`when<Grammar, call<_arg> >`.
 
 [endsect]
 
 [section:fold [^fold<>] and [^reverse_fold<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar, typename State = void>
- struct fold;
-
- template<typename Grammar, typename State = void>
- struct reverse_fold;
- }}}
+ namespace transform
+ {
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold;
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold;
+ }
+
+ using transform::fold;
+ using transform::reverse_fold;
+ }}
 
 The transforms `fold<>` and `reverse_fold<>` are akin to the
-`std::accumulate()` algorithm in the STL. They iterate over some sequence and
-accumulate some state at each element. For Proto's `fold<>` and
-`reverse_fold<>`, the "elements" of the sequence are actually pairs consisting
-of the corresponding child grammars and expressions. The state is accumulated
-by applying the child grammar's transform to the corresponding child
-expression. The result of one transform is used as the state of the next
-transform, such that the transforms nest like Russian dolls. The `fold<>`
+`std::accumulate()` algorithm in the STL, or the `fold()` algorithm in
+Boost.Fusion. They iterate over some sequence and
+accumulate some state at each element. The `fold<>`
 transform iterates over the children in order, starting with the 0th child.
 The `reverse_fold<>` transform does it in reverse order, starting with the Nth
 child. (Note that for building things like cons lists, you'll often want to
 built it back-to-front with `reverse_fold<>`.)
 
-[def __arg_N__ proto_arg[~N]]
-[def __arg_N_sub_1__ proto_arg[~N-1]]
+Both `fold<>` and `reverse_fold<>` are implemented in terms of `fusion::fold<>`.
+The three template parameters must each be Proto transforms. The have the following
+meaning:
+
+* `Sequence`: A Proto transform that returns a Fusion sequence.
+* `State`: A Proto transform that returns the initial state of the fold.
+* `Fun`: A Proto transform representing the operation to perform at each
+ iteration of the fold algorithm.
+
+Often, the `Sequence` parameter is `proto::_`, which returns the current node
+in the Proto expression tree. Tree nodes are valid Fusion sequences, where
+the children are the elements of the sequence.
+
+The semantics of the `fold<>` and `reverse_fold<>` transforms can both be
+understood in terms of a helper struct, `as_callable<>`, which binds the
+visitor and the `Fun` transform into a binary function object for use by
+`fusion::fold()`. `as_callable<>` has the following behavior:
 
 [table
     [ [Expression]
         [Returns]
     ]
- [ [`transform::fold<Grammar>::apply<Expr, State, Visitor>::type`]
- [``typename Grammar::__arg_N__::apply<
- typename Expr::__arg_N__::proto_base_expr
- , typename Grammar::__arg_N_sub_1__::apply<
- typename Expr::__arg_N_sub_1__::proto_base_expr
- , // ...
- typename Grammar::proto_arg0::apply<
- typename Expr::proto_arg0::proto_base_expr, State, Visitor>::type
- // ...
- , Visitor
- >::type
- , Visitor
+ [ [`as_callable<Fun, Visitor>::result<void(Expr, State)>::type`]
+ [`when<_, Fun>::result<void(Expr, State, Visitor)>::type`]
+ ]
+ [ [`as_callable<Fun, Visitor>(visitor)(expr, state)`]
+ [`when<_, Fun>()(expr, state, visitor)`]
+ ]
+]
+
+With the above `as_callable<>` adaptor, `fold<>` and `reverse_fold<>`
+can be easily implemented in terms of `fusion::fold<>`:
+
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [`fold<Sequence, State0, Fun>::result<void(Expr, State, Visitor)>::type`]
+ [``fusion::result_of::fold<
+ when<_, Sequence>::result<void(Expr, State, Visitor)>::type
+ , when<_, State0>::result<void(Expr, State, Visitor)>::type
+ , as_callable<Fun, Visitor>
>::type``]
     ]
- [ [`transform::fold<Grammar>::call(expr, state, visitor)`]
- [``Grammar::__arg_N__::call(
- proto::arg_c<N>(expr)
- , Grammar::__arg_N_sub_1__::call(
- proto::arg_c<N-1>(expr)
- , // ...
- Grammar::proto_arg0::call(
- proto::arg_c<0>(expr), state, visitor)
- // ...
- , visitor
- )
- , visitor
+ [ [`fold<Sequence, State0, Fun>()(expr, state, visitor)`]
+ [``fusion::fold(
+ when<_, Sequence>()(expr, state, visitor)
+ , when<_, State0>()(expr, state, visitor)
+ , as_callable<Fun, Visitor>(visitor)
 )``]
     ]
- [ [`transform::reverse_fold<Grammar>::apply<Expr, State, Visitor>::type`]
- [``typename Grammar::proto_arg0::apply<
- typename Expr::proto_arg0::proto_base_expr
- , typename Grammar::proto_arg1::apply<
- typename Expr::proto_arg1::proto_base_expr
- , // ...
- typename Grammar::__arg_N__::apply<
- typename Expr::__arg_N__::proto_base_expr, State, Visitor>::type
- // ...
- , Visitor
+ [ [`reverse_fold<Sequence, State0, Fun>::result<void(Expr, State, Visitor)>::type`]
+ [``fusion::result_of::fold<
+ fusion::result_of::reverse<
+ when<_, Sequence>::result<void(Expr, State, Visitor)>::type
>::type
- , Visitor
+ , when<_, State0>::result<void(Expr, State, Visitor)>::type
+ , as_callable<Fun, Visitor>
>::type``]
     ]
- [ [`transform::reverse_fold<Grammar>::call(expr, state, visitor)`]
- [``Grammar::proto_arg0::call(
- proto::arg_c<0>(expr)
- , Grammar::proto_arg1::call(
- proto::arg_c<1>(expr)
- , // ...
- Grammar::__arg_N__::call(
- proto::arg_c<N>(expr), state, visitor)
- // ...
- , visitor
+ [ [`reverse_fold<Sequence, State0, Fun>()(expr, state, visitor)`]
+ [``fusion::fold(
+ fusion::reverse(
+ when<_, Sequence>()(expr, state, visitor)
     )
- , visitor
+ , when<_, State0>()(expr, state, visitor)
+ , as_callable<Fun, Visitor>(visitor)
 )``]
     ]
 ]
 
-Both the `fold<>` and `reverse_fold<>` transforms take an optional `State`
-template parameter. For non-`void` `State` parameters, the following
-equivalances hold:
-
-[table fold<> and reverse_fold<> Equivalencies
- [[Short-Cut Grammar] [Equivalent Grammar]]
- [[`transform::fold<Grammar, State>`] [``transform::branch<
- transform::fold<Grammar>
- , State
->``]]
- [[`transform::reverse_fold<Grammar, State>`][``transform::branch<
- transform::reverse_fold<Grammar>
- , State
->``]]
-]
-
 [#reverse_fold_example]Example:
 
 [AsArgList]
@@ -718,164 +1042,117 @@
 
 [section:fold_tree [^fold_tree<>] and [^reverse_fold_tree<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Tag, typename Grammar, typename State = void>
- struct fold_tree;
-
- template<typename Tag, typename Grammar, typename State = void>
- struct reverse_fold_tree;
- }}}
+ namespace transform
+ {
+ template<typename Sequence, typename State0, typename Fun>
+ struct fold_tree;
+
+ template<typename Sequence, typename State0, typename Fun>
+ struct reverse_fold_tree;
+ }
+
+ using transform::fold;
+ using transform::reverse_fold;
+ }}
 
 The `fold_tree<>` and `reverse_fold_tree<>` transforms recursively apply the
 `fold<>` and `reverse_fold<>` transforms to sub-trees that all share a common
-`Tag` type. This is useful for flattening trees into lists; for example, you
+tag type. This is useful for flattening trees into lists; for example, you
 might use `reverse_fold_tree<>` to flatten an expression tree like `a | b | c`
 into a Fusion list like `cons(a, cons(b, cons(c)))`.
 
 The `fold_tree<>` and `reverse_fold_tree<>` transforms are unlike the other
 transforms that Proto provides in that they operate on entire sub-trees rather
-than just single nodes within the tree. As a result, their interface is
-different. The `Tag` parameter is the type of the operator tag that behaves
-like a separator. The `Grammar` parameter represents that grammar that the
-separated sub-expressions must match, and the transform that will be applied
-to each. The optional `State` parameter is the initial state of the transform.
+than just single nodes within the tree.
 
 These are higher-level transforms, implemented in terms of the `fold<>`
-transform. They are probably best understood in terms of their definition,
-which is fairly small.
+and `reverse_fold<>` transforms and helper structs `fold_tree_<>` and
+`reverse_fold_tree_<>`, one of which is shown below:
 
- namespace detail
- {
- // fold_tree_ either recurses into the expression, if its Tag
- // matches, or else ends the recursion by matching Grammar and
- // applying its transform.
- template<typename Tag, typename Grammar>
- struct fold_tree_
- : or_<
- transform::fold<
- nary_expr<Tag, vararg<fold_tree_<Tag, Grammar> > >
- >
- , Grammar
- >
- {};
- }
-
- template<typename Tag, typename Grammar, typename State = void>
- struct fold_tree
- : transform::fold<
- nary_expr<Tag, vararg<detail::fold_tree_<Tag, Grammar> > >
- , State
+ // fold_tree_ either recurses into the expression, if its Grammar
+ // matches, or else ends the recursion by matching Grammar and
+ // applying its transform.
+ template<typename Grammar, typename Fun>
+ struct fold_tree_
+ : or_<
+ when<Grammar, fold<_, _state, fold_tree_<Grammar, Fun> > >
+ , when<_, Fun>
>
     {};
+
+The `reverse_fold_tree_<>` helper is specified similarly, only with
+`reverse_fold<>` instead of `fold<>`. With these two helpers, we can
+specify the behavior of `fold_tree<>` and `reverse_fold_tree<>` as
+follows:
 
-The `reverse_fold_tree<>` transform is specified similarly, only with
-`reverse_fold<>` instead of `fold<>`.
-
-Example:
-
-[FoldTreeToList]
-
-[endsect]
-
-[section:construct [^construct<>]]
-
- namespace boost { namespace proto { namespace transform
- {
- template<typename Grammar, typename Constructor>
- struct construct;
- }}}
-
-The `construct<>` transform is a flexible tool for transforming expressions
-into other types of objects. With it, you can specify both the type of the
-object to construct as well as what parameters to pass to its constructor. A
-typical usage of the `construct<>` transform is like this:
-
- transform::construct<
- terminal<float>
- , terminal<double>::type(transform::arg<_>)
+[table
+ [ [Expression]
+ [Returns]
+ ]
+ [ [``fold_tree<Sequence, State0, Fun>
+ ::result<void(Expr, State, Visitor)>::type``]
+ [``fold<
+ Sequence
+ , State0
+ , fold_tree_<
+ nary_expr<Expr::proto_tag, vararg<_> >
+ , Fun
>
-
-The first template parameter is the grammar to match; in this case, terminals
-of type `float`. The second template parameter might look a little strange. It
-is actually a function type, but here we're using it to describe what object to
-construct and how to initialize it. In this case, we will be constructing a
-`double` terminal, using the argument from the `float` terminal. This transform
-effectively promotes a `float` to a `double`.
-
-The `Constructor` template parameter is a function type of the following form:
-
- ResultType(Transform1, Transform2, ...)
-
-where `Transform1`, `Transform2`, etc, are Proto transforms. They specify what
-arguments should be used to construct the `ResultType` object. The way it works
-is as follows. Consider the transform `transform::construct<G, R(T)>`, and an
-expression object `e` of type `E` that matches `G`. Then the result will be an
-object of type `R` constructed like this:
-
- E2 e2 = G::call(e, s, v);
- R(T::call(e2, s, v));
-
-where `s` and `v` are some state and visitor parameters, and `E2` is the return
-type of `G::call(e,s,v)`. Note that `G`'s transform is applied first, followed
-by `T`'s transform.
-
-The result type itself may be specified in terms of Proto transforms. In that
-case, the return type is the result of applying the transforms and substituting
-the transforms with the results. Consider the following code that matches an
-invocation of a lazy `make_pair_` function, and actually returns a
-`std::pair<>` of the correct type.
-
-[LazyMakePair]
-
-Notice that the result type, `std::pair<...>`, is specified in terms of Proto
-transforms. Notice also that Proto transforms are used to specify how to
-construct the `std::pair<>` object. We can now use the `MakePair` transform to
-convert a lazy `make_pair_()` function invocation into an actual `std::pair<>`:
-
-[LazyMakePairTest]
-
-The above code would display the following:
-
-[pre
-1
-3.14
+>::result<void(Expr, State, Visitor)>::type``]
+ ]
+ [ [`fold_tree<Sequence, State0, Fun>()(expr, state, visitor)`]
+ [``fold<
+ Sequence
+ , State0
+ , fold_tree_<
+ nary_expr<Expr::proto_tag, vararg<_> >
+ , Fun
+ >
+>()(expr, state, visitor)``]
+ ]
+ [ [``reverse_fold_tree<Sequence, State0, Fun>
+ ::result<void(Expr, State, Visitor)>::type``]
+ [``reverse_fold<
+ Sequence
+ , State0
+ , reverse_fold_tree_<
+ nary_expr<Expr::proto_tag, vararg<_> >
+ , Fun
+ >
+>::result<void(Expr, State, Visitor)>::type``]
+ ]
+ [ [`reverse_fold_tree<Sequence, State0, Fun>()(expr, state, visitor)`]
+ [``reverse_fold<
+ Sequence
+ , State0
+ , reverse_fold_tree_<
+ nary_expr<Expr::proto_tag, vararg<_> >
+ , Fun
+ >
+>()(expr, state, visitor)``]
+ ]
 ]
 
-When building the result type, if the result of applying a Proto transform is a
-type that has a nested `::type` member typedef, then that type is used instead.
-For instance, here is a transform that matches an integer and negates it lazily
-by wrapping it in a `negate<>` node.
-
-[NegateInt]
-
-The return type is `negate<_>`, but what is actually constructed is
-`negate<terminal<int>::type>::type`. This behavior should seem familiar if you
-have ever used MPL Placeholder expressions.
-
-The `construct<>` transform gives you a simple and convenient syntax for
-creating temporary sub-objects. In the `Constructor` expression
-`ResultType(Transform1, Transform2)`, if the type of `Transform1` is a function
-type, then it is converted into the transform `construct<_, Transform1>`. The
-following example demonstrates how to match an integer, promote it to a long
-integer, and lazily square it.
-
-[SquareAndPromoteInt]
+Example:
 
-The "arguments" to the constructor are `terminal<long>::type(transform::arg<_>)`,
-which is short-cut syntax for a nested `construct<>` transform. [footnote The
-short-cut syntax for nested constructors does not work on MSVC due to compiler
-bugs.]
+[FoldTreeToList]
 
 [endsect]
 
 [section:pass_through [^pass_through<>]]
 
- namespace boost { namespace proto { namespace transform
+ namespace boost { namespace proto
     {
- template<typename Grammar>
- struct pass_through;
- }}}
+ namespace transform
+ {
+ template<typename Grammar>
+ struct pass_through;
+ }
+
+ using transform::pass_through;
+ }}
 
 The `pass_through<>` transform iterates over the pairs of
 children in the grammar and the expression, applying the child grammar's
@@ -895,22 +1172,30 @@
     [ [Expression]
         [Returns]
     ]
- [ [`transform::pass_through<Grammar>::apply<Expr, State, Visitor>::type`]
+ [ [``transform::pass_through<Grammar>
+ ::result<void(Expr, State, Visitor)>::type``]
         [``typename nary_expr<
- typename Expr::proto_tag
- , typename Grammar::proto_arg0::apply<typename Expr::proto_arg0::proto_base_expr, State, Visitor>::type
- , typename Grammar::proto_arg1::apply<typename Expr::proto_arg1::proto_base_expr, State, Visitor>::type
+ Expr::proto_tag
+ , result_of::arg_c<Grammar, 0>::type::result<
+ void(result_of::arg_c<Expr, 0>::type, State, Visitor)>::type
+ , result_of::arg_c<Grammar, 1>::type::result<
+ void(result_of::arg_c<Expr, 1>::type, State, Visitor)>::type
     // ...
- , typename Grammar::__arg_N__::apply<typename Expr::__arg_N__::proto_base_expr, State, Visitor>::type
+ , result_of::arg_c<Grammar, N>::type::result<
+ void(result_of::arg_c<Expr, N>::type, State, Visitor)>::type
>::type``]
     ]
- [ [`transform::pass_through<Grammar>::call(expr, state, visitor)`]
- [``transform::pass_through<Grammar>::apply<Expr, State, Visitor>::type::make(
- Grammar::proto_arg0::call(proto::arg_c<0>(expr), state, visitor)
- , Grammar::proto_arg1::call(proto::arg_c<1>(expr), state, visitor)
- // ...
- , Grammar::__arg_N__::call(proto::arg_c<N>(expr), state, visitor)
-)``]
+ [ [`transform::pass_through<Grammar>()(expr, state, visitor)`]
+ [``transform::pass_through<Grammar>
+ ::result<void(Expr, State, Visitor)>::type::make(
+ result_of::arg_c<Grammar, 0>::type()(
+ proto::arg_c<0>(expr), state, visitor)
+ , result_of::arg_c<Grammar, 1>::type()(
+ proto::arg_c<1>(expr), state, visitor)
+ // ...
+ , result_of::arg_c<Grammar, N>::type()(
+ proto::arg_c<N>(expr), state, visitor)
+ )``]
     ]
 ]
 
@@ -922,4 +1207,210 @@
 
 [endsect]
 
+[/======================================================]
+[section:user_defined_transforms User-Defined Transforms]
+[/======================================================]
+
+In previous sections, we've seen how to compose larger transforms
+out of smaller transforms using function types.
+We've also seen the primitive transforms that Proto provides.
+So-called primitive transforms can be used without specifying
+arguments, like `_arg0` which returns the first child of the
+current node. But primitive transforms are not special in any way.
+They are merely ternary function objects that take the current
+expression, state and visitor as arguments.
+
+You can define your own primitive transforms. You might want to
+do this if your transform is complicated and composing it out
+of primitives becomes unwieldy. You might also do this
+to work around compiler bugs on legacy compilers that makes
+composing transforms using function types problematic. Finally,
+you might also decide to define your own primitive transforms
+to improve compile times. Since Proto can simply invoke a
+primitive transform directly without having to process arguments
+or differentiate callable transforms from object transforms,
+primitive transforms are more efficient.
+
+To define your own primitive transform, merely define a ternary
+function object that accepts an expression, a state and a visitor.
+Here, for example, is how Proto defines the `arg_c<>` transform:
+
+ namespace boost { namespace proto { namespace transform
+ {
+ // A transform that returns the I-th child
+ template<int I>
+ struct arg_c : callable
+ {
+ // Nested "result" template, used by
+ // boost::result_of<> to compute the
+ // return type of the function.
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
+ : proto::result_of::arg_c<Expr, I>
+ {};
+
+ // Function call operator that actually
+ // executes the transform.
+ template<typename Expr, typename State, typename Visitor>
+ typename proto::result_of::arg_c<Expr, I>::const_reference
+ operator ()(Expr const &expr, State const &, Visitor &) const
+ {
+ return proto::arg_c<I>(expr);
+ }
+ };
+ }}}
+
+ namespace boost { namespace proto
+ {
+ // Note that arg_c<I> is callable, so that
+ // it can be used with arguments, as:
+ // arg_c<0>(arg_c<1>)
+ template<int I>
+ struct is_callable<transform::arg_c<I> >
+ : mpl::true_
+ {};
+ }}
+
+There is nothing particularly special about the definition of
+`arg_c<>`. It is just an ordinary polymorphic function object. The
+only interesting bit is the `is_callable<>` specialization, which
+will be described in the section called "Making Your Transform
+Callable".
+
+Once you have defined such a ternary function object, you can use
+it as a transform without any arguments and Proto will automatically
+pass it the current expression, state and visitor parameters.
+
+[endsect]
+
+[/=================================================]
+[section:is_callable Making Your Transform Callable]
+[/=================================================]
+
+Transforms are typically of the form `when< Something, R(A0,A1,...) >`. The
+question is whether `R` represents a function to call or an object to
+construct, and the answer determines how `when<>` evaluates the transform.
+`when<>` uses the `is_callable<>` trait to disambiguate between the two.
+Proto does its best to guess whether a transform is callable or not, but
+it doesn't always get it right. It's best to know the rules Proto uses,
+so that you know when you need to specialize `is_callable<>`.
+
+The first thing to know is that templates are not considered callable
+by default. This is true ['even if the template inherits from
+`proto::callable`]. Consider the following erroneous transform:
+
+ // Proto can't tell this defines a
+ // callable transform!
+ template<typename T>
+ struct times2 : callable
+ {
+ typedef T result_type;
+
+ T operator()(T i) const
+ {
+ return i * 2;
+ }
+ };
+
+ // ERROR! This is not going to
+ // multiply the int by 2.
+ struct IntTimes2
+ : when< terminal<int>, times2<int>(_arg) >
+ {};
+
+The problem is that Proto doesn't know that `times2<int>` is a callable
+transform. Instead, it assumes it's an object transform and will try to
+construct a `times2<int>` object and initialize it will an `int`. That
+will not compile.
+
+[note Why can't Proto tell that `times2<int>` is callable? After all,
+it inherits from `proto::callable`, and that is detectable, right?
+In fact, determining whether some type `X<Y>` inherits from
+`callable` will cause the template `X<Y>` to be instantiated. That's a
+problem for a type like `std::vector<_arg(_arg1)>()`, which is a valid
+transform that default-constructs a particular instantiation of
+`std::vector<>`. But `std::vector<>` will not suffer to be instantiated
+with `_arg(_arg1)` as a template parameter! As a result, Proto has
+to assume that a type `X<Y>` represents an object transform and not
+a callable transform.]
+
+There are a couple of solutions to the `times2<int>` problem. One
+solution is to wrap the transform in `call<>`. This forces Proto to
+treat `times2<int>` as callable:
+
+ // OK, calls times2<int>
+ struct IntTimes2
+ : when< terminal<int>, call<times2<int>(_arg)> >
+ {};
+
+This can be a bit of a pain, because we need to wrap every use of
+`times2<int>`, which can be tedious and error prone, and makes our
+grammar cluttered and harder to read.
+
+Another solution is to specialize `proto::is_callable<>` on our
+`times2<>` template:
+
+ namespace boost { namespace proto
+ {
+ template<typename T>
+ struct is_callable<times2<T> >
+ : mpl::true_
+ {};
+ }}
+
+ // OK, times2<> is callable
+ struct IntTimes2
+ : when< terminal<int>, times2<int>(_arg) >
+ {};
+
+This is better, but still a pain because of the need to open
+Proto's namespace.
+
+You could simply make sure that the transform is not
+a template. Consider the following:
+
+ // No longer a template!
+ struct times2int : times2<int> {};
+
+ // OK, times2int is callable
+ struct IntTimes2
+ : when< terminal<int>, times2int(_arg) >
+ {};
+
+This works because now Proto can tell that `times2int` inherits
+(indirectly) from `proto::callable`. Any non-template types can
+be safely checked for inheritance because, as they are not
+templates, there is no worry about instantiation errors.
+
+There is one last way to tell Proto that `times2<>` is callable.
+You could add an extra dummy template parameter that defaults
+to `proto::callable`:
+
+ // Proto will recognize this as callable
+ template<typename T, typename Dummy = callable>
+ struct times2 : callable
+ {
+ typedef T result_type;
+
+ T operator()(T i) const
+ {
+ return i * 2;
+ }
+ };
+
+ // OK, this works!
+ struct IntTimes2
+ : when< terminal<int>, times2<int>(_arg) >
+ {};
+
+Note that in addition to the extra template parameter, `times2<>`
+still inherits from `callable`. That's not necessary in this example
+but it's good style because any types derived from `times2<>` (as
+`times2int` defined above) will still be considered callable.
+
+[endsect]
+
 [endsect]

Modified: branches/release/libs/xpressive/proto/example/Jamfile.v2
==============================================================================
--- branches/release/libs/xpressive/proto/example/Jamfile.v2 (original)
+++ branches/release/libs/xpressive/proto/example/Jamfile.v2 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -53,3 +53,18 @@
         mixed.cpp
     ;
 
+exe futures
+ :
+ futures.cpp
+ ;
+
+exe map_assign
+ :
+ map_assign.cpp
+ ;
+
+exe lambda
+ :
+ lambda.cpp
+ ;
+

Modified: branches/release/libs/xpressive/proto/example/calc1.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/calc1.cpp (original)
+++ branches/release/libs/xpressive/proto/example/calc1.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,5 +1,5 @@
 //[ Calc1
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -12,11 +12,11 @@
 #include <boost/xpressive/proto/context.hpp>
 using namespace boost;
 
-template<typename I> struct arg {};
+template<int I> struct placeholder {};
 
 // Define some placeholders
-proto::terminal< arg< mpl::int_<1> > >::type const _1 = {{}};
-proto::terminal< arg< mpl::int_<2> > >::type const _2 = {{}};
+proto::terminal< placeholder< 1 > >::type const _1 = {{}};
+proto::terminal< placeholder< 2 > >::type const _2 = {{}};
 
 // Define a calculator context, for evaluating arithmetic expressions
 struct calculator_context
@@ -35,10 +35,10 @@
     }
 
     // Handle the evaluation of the placeholder terminals
- template<typename I>
- double operator()(proto::tag::terminal, arg<I>) const
+ template<int I>
+ double operator ()(proto::tag::terminal, placeholder<I>) const
     {
- return d[ I() - 1 ];
+ return d[ I - 1 ];
     }
 };
 
@@ -60,7 +60,7 @@
     // Displays "6"
     std::cout << evaluate( _1 * _2, 3.0, 2.0 ) << std::endl;
 
- // Displays "1.5"
+ // Displays "0.5"
     std::cout << evaluate( (_1 - _2) / _2, 3.0, 2.0 ) << std::endl;
 
     return 0;

Modified: branches/release/libs/xpressive/proto/example/calc2.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/calc2.cpp (original)
+++ branches/release/libs/xpressive/proto/example/calc2.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,11 +1,11 @@
 //[ Calc2
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
 // This example enhances the simple arithmetic expression evaluator
 // in calc1.cpp by using proto::extends to make arithemetic
-// expressions immediately evaluatable with operator(), a-la a
+// expressions immediately evaluatable with operator (), a-la a
 // function object
 
 #include <iostream>
@@ -15,9 +15,9 @@
 using namespace boost;
 
 // Will be used to define the placeholders _1 and _2
-template<typename I> struct arg {};
+template<int I> struct placeholder {};
 
-// For expressions in the calculator domain, operator()
+// For expressions in the calculator domain, operator ()
 // will be special; it will evaluate the expression.
 struct calculator_domain;
 
@@ -39,15 +39,15 @@
     }
 
     // Handle the evaluation of the placeholder terminals
- template<typename I>
- double operator()(proto::tag::terminal, arg<I>) const
+ template<int I>
+ double operator ()(proto::tag::terminal, placeholder<I>) const
     {
- return d[ I() - 1 ];
+ return d[ I - 1 ];
     }
 };
 
 // Wrap all calculator expressions in this type, which defines
-// operator() to evaluate the expression.
+// operator () to evaluate the expression.
 template<typename Expr>
 struct calculator_expression
   : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
@@ -55,27 +55,27 @@
     typedef
         proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
     base_type;
-
+
     explicit calculator_expression(Expr const &expr = Expr())
       : base_type(expr)
     {}
 
- using base_type::operator=;
+ using base_type::operator =;
 
- // Override operator() to evaluate the expression
- double operator()() const
+ // Override operator () to evaluate the expression
+ double operator ()() const
     {
         calculator_context const ctx;
         return proto::eval(*this, ctx);
     }
 
- double operator()(double d1) const
+ double operator ()(double d1) const
     {
         calculator_context const ctx(d1);
         return proto::eval(*this, ctx);
     }
 
- double operator()(double d1, double d2) const
+ double operator ()(double d1, double d2) const
     {
         calculator_context const ctx(d1, d2);
         return proto::eval(*this, ctx);
@@ -88,8 +88,8 @@
 {};
 
 // Define some placeholders (notice they're wrapped in calculator_expression<>)
-calculator_expression<proto::terminal< arg< mpl::int_<1> > >::type> const _1;
-calculator_expression<proto::terminal< arg< mpl::int_<2> > >::type> const _2;
+calculator_expression<proto::terminal< placeholder< 1 > >::type> const _1;
+calculator_expression<proto::terminal< placeholder< 2 > >::type> const _2;
 
 // Now, our arithmetic expressions are immediately executable function objects:
 int main()
@@ -100,7 +100,7 @@
     // Displays "6"
     std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
 
- // Displays "1.5"
+ // Displays "0.5"
     std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
 
     return 0;

Modified: branches/release/libs/xpressive/proto/example/calc3.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/calc3.cpp (original)
+++ branches/release/libs/xpressive/proto/example/calc3.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,11 +1,11 @@
 //[ Calc3
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
 // This example enhances the arithmetic expression evaluator
 // in calc2.cpp by using a proto transform to calculate the
-// number of arguments an expression requires and using a
+// number of arguments an expression requires and using a
 // compile-time assert to guarantee that the right number of
 // arguments are actually specified.
 
@@ -15,59 +15,11 @@
 #include <boost/mpl/min_max.hpp>
 #include <boost/xpressive/proto/proto.hpp>
 #include <boost/xpressive/proto/context.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
-#include <boost/xpressive/proto/transform/apply.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 using namespace boost;
 
 // Will be used to define the placeholders _1 and _2
-template<typename I> struct arg { typedef I arity; };
-
-// A meta-function for getting a placeholder terminal's arity.
-template<typename Arg>
-struct arg_arity
-{
- typedef typename Arg::arity type;
-};
-
-// A custom transform that fetches the arity of a placeholder terminal
-template<typename Grammar>
-struct placeholder_arity
- : Grammar
-{
- template<typename Expr, typename, typename>
- struct apply
- : arg_arity<typename proto::result_of::arg<Expr>::type>
- {};
-
- //// If this transform had a runtime counterpart, it would look like this:
- //template<typename Expr, typename State, typename Visitor>
- //static typename apply<Expr, State, Visitor>::type
- //call(Expr const &expr, State const &state, Visitor &visitor)
- //{
- // ... do stuff ...
- //}
-};
-
-// A custom transforms for calculating the max arity of a calculator expression
-template<typename Grammar>
-struct max_arity
- : Grammar
-{
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- // Calculate the arity of the current expression.
- typedef typename Grammar::template apply<Expr, State, Visitor>::type arity;
- // The old maximum is passed along in the State parameter by
- // proto::transform::fold<> (see below). The new maximum is the
- // larger of the old maximum and the arity we just calculated.
- typedef typename mpl::max<arity, State>::type type;
- };
-
- // As with placeholder_arity<> above, placeholder_arity<> has no need
- // for a call() member function.
-};
+template<typename I> struct placeholder : I {};
 
 using proto::_;
 
@@ -79,41 +31,18 @@
 // expression arity for each of the three cases.
 struct CalculatorGrammar
   : proto::or_<
- // placeholders have a non-zero arity ...
- placeholder_arity< proto::terminal< arg<_> > >
 
- //// This accomplishes the same thing without the need to
- //// define a separate placeholder_arity<> transform, but
- //// is a little more cryptic.
- //proto::transform::apply1<
- // proto::terminal< arg<_> >
- // , arg_arity< proto::result_of::arg<mpl::_> >
- //>
+ // placeholders have a non-zero arity ...
+ proto::when< proto::terminal< placeholder<_> >, proto::_arg >
 
         // Any other terminals have arity 0 ...
- , proto::transform::always< proto::terminal<_>, mpl::int_<0> >
+ , proto::when< proto::terminal<_>, mpl::int_<0>() >
+
         // For any non-terminals, find the arity of the children and
         // take the maximum. This is recursive.
- , proto::transform::fold<
- // This matches any non-terminal for which the children
- // are themselves calculator expressions.
- proto::nary_expr<_, proto::vararg< max_arity< CalculatorGrammar > > >
-
- //// This accomplishes the same thing without the need to
- //// define a separate max_arity<> transform, but is a little
- //// more cryptic.
- //proto::nary_expr<
- // _
- // , proto::vararg<
- // // Here, mpl::_1 will be replaced with the result of applying
- // // the CalculatorGrammar transform (i.e., the arity of the
- // // child node), and mpl::_2 will be replaced with the State of
- // // the transformation so far (i.e., the maximum arity found so
- // // far).
- // proto::transform::apply2<CalculatorGrammar, mpl::max<mpl::_1, mpl::_2> >
- // >
- //>
- >
+ , proto::when< proto::nary_expr<_, proto::vararg<_> >
+ , proto::fold<_, mpl::int_<0>(), mpl::max<CalculatorGrammar, proto::_state>() > >
+
>
 {};
 
@@ -122,10 +51,10 @@
 // is not used, is mpl::void_.
 template<typename Expr>
 struct calculator_arity
- : CalculatorGrammar::apply<Expr, mpl::int_<0>, mpl::void_>
+ : boost::result_of<CalculatorGrammar(Expr, mpl::int_<0>, mpl::void_)>
 {};
 
-// For expressions in the calculator domain, operator()
+// For expressions in the calculator domain, operator ()
 // will be special; it will evaluate the expression.
 struct calculator_domain;
 
@@ -148,14 +77,14 @@
 
     // Handle the evaluation of the placeholder terminals
     template<typename I>
- double operator()(proto::tag::terminal, arg<I>) const
+ double operator ()(proto::tag::terminal, placeholder<I>) const
     {
         return d[ I() - 1 ];
     }
 };
 
 // Wrap all calculator expressions in this type, which defines
-// operator() to evaluate the expression.
+// operator () to evaluate the expression.
 template<typename Expr>
 struct calculator_expression
   : proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
@@ -163,15 +92,15 @@
     typedef
         proto::extends<Expr, calculator_expression<Expr>, calculator_domain>
     base_type;
-
+
     explicit calculator_expression(Expr const &expr = Expr())
       : base_type(expr)
     {}
 
- using base_type::operator=;
+ using base_type::operator =;
 
- // Override operator() to evaluate the expression
- double operator()() const
+ // Override operator () to evaluate the expression
+ double operator ()() const
     {
         // Assert that the expression has arity 0
         BOOST_MPL_ASSERT_RELATION(0, ==, calculator_arity<Expr>::type::value);
@@ -179,7 +108,7 @@
         return proto::eval(*this, ctx);
     }
 
- double operator()(double d1) const
+ double operator ()(double d1) const
     {
         // Assert that the expression has arity 1
         BOOST_MPL_ASSERT_RELATION(1, ==, calculator_arity<Expr>::type::value);
@@ -187,7 +116,7 @@
         return proto::eval(*this, ctx);
     }
 
- double operator()(double d1, double d2) const
+ double operator ()(double d1, double d2) const
     {
         // Assert that the expression has arity 2
         BOOST_MPL_ASSERT_RELATION(2, ==, calculator_arity<Expr>::type::value);
@@ -202,8 +131,8 @@
 {};
 
 // Define some placeholders (notice they're wrapped in calculator_expression<>)
-calculator_expression<proto::terminal< arg< mpl::int_<1> > >::type> const _1;
-calculator_expression<proto::terminal< arg< mpl::int_<2> > >::type> const _2;
+calculator_expression<proto::terminal< placeholder< mpl::int_<1> > >::type> const _1;
+calculator_expression<proto::terminal< placeholder< mpl::int_<2> > >::type> const _2;
 
 // Now, our arithmetic expressions are immediately executable function objects:
 int main()
@@ -214,7 +143,7 @@
     // Displays "6"
     std::cout << ( _1 * _2 )( 3.0, 2.0 ) << std::endl;
 
- // Displays "1.5"
+ // Displays "0.5"
     std::cout << ( (_1 - _2) / _2 )( 3.0, 2.0 ) << std::endl;
 
     // This won't compile because the arity of the

Added: branches/release/libs/xpressive/proto/example/futures.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/example/futures.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,127 @@
+//[ FutureGroup
+// Copyright 2008 Eric Niebler. 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)
+//
+// This is an example of using Proto transforms to implement
+// Howard Hinnant's future group proposal.
+
+#include <boost/fusion/tuple.hpp>
+#include <boost/fusion/include/as_vector.hpp>
+#include <boost/fusion/include/joint_view.hpp>
+#include <boost/fusion/include/single_view.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+
+using namespace boost;
+using namespace proto;
+
+template<class L,class R>
+struct pick_left
+{
+ BOOST_MPL_ASSERT((is_same<L, R>));
+ typedef L type;
+};
+
+// Define the grammar of future group expression, as well as a
+// transform to turn them into a Fusion sequence of the correct
+// type.
+struct FutureGroup
+ : or_<
+ // terminals become a single-element Fusion sequence
+ when<
+ terminal<_>
+ , fusion::single_view<_arg>(_arg)
+ >
+ // (a && b) becomes a concatenation of the sequence
+ // from 'a' and the one from 'b':
+ , when<
+ logical_and<FutureGroup, FutureGroup>
+ , fusion::joint_view<
+ add_const<FutureGroup(_left)>,
+ add_const<FutureGroup(_right)>
+ >(FutureGroup(_left), FutureGroup(_right))
+ >
+ // (a || b) becomes the sequence for 'a', so long
+ // as it is the same as the sequence for 'b'.
+ , when<
+ logical_or<FutureGroup, FutureGroup>
+ , pick_left<
+ FutureGroup(_left)
+ , FutureGroup(_right)
+ >(FutureGroup(_left))
+ >
+ >
+{};
+
+template<class E>
+struct future_expr;
+
+struct future_dom
+ : domain<generator<future_expr>, FutureGroup>
+{};
+
+// Expressions in the future group domain have a .get()
+// member function that (ostensibly) blocks for the futures
+// to complete and returns the results in an appropriate
+// tuple.
+template<class E>
+struct future_expr
+ : extends<E, future_expr<E>, future_dom>
+{
+ explicit future_expr(E const &e)
+ : extends<E, future_expr<E>, future_dom>(e)
+ {}
+
+ typename fusion::result_of::as_vector<
+ typename boost::result_of<FutureGroup(E,int,int)>::type
+ >::type
+ get() const
+ {
+ int i = 0;
+ return fusion::as_vector(FutureGroup()(*this, i, i));
+ }
+};
+
+// The future<> type has an even simpler .get()
+// member function.
+template<class T>
+struct future
+ : future_expr<typename terminal<T>::type>
+{
+ future(T const &t = T())
+ : future_expr<typename terminal<T>::type>(
+ terminal<T>::type::make(t)
+ )
+ {}
+
+ T get() const
+ {
+ return proto::arg(*this);
+ }
+};
+
+// TEST CASES
+struct A {};
+struct B {};
+struct C {};
+
+int main()
+{
+ using fusion::tuple;
+ future<A> a;
+ future<B> b;
+ future<C> c;
+ future<tuple<A,B> > ab;
+
+ // Verify that various future groups have the
+ // correct return types.
+ A t0 = a.get();
+ tuple<A, B, C> t1 = (a && b && c).get();
+ tuple<A, C> t2 = ((a || a) && c).get();
+ tuple<A, B, C> t3 = ((a && b || a && b) && c).get();
+ tuple<tuple<A, B>, C> t4 = ((ab || ab) && c).get();
+
+ return 0;
+}
+//]

Modified: branches/release/libs/xpressive/proto/example/hello.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/hello.cpp (original)
+++ branches/release/libs/xpressive/proto/example/hello.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ HelloWorld
 ////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -10,7 +10,7 @@
 #include <boost/typeof/std/ostream.hpp>
 using namespace boost;
 
-proto::terminal< std::ostream & >::type cout_ = { std::cout };
+proto::terminal< std::ostream & >::type cout_ = {std::cout};
 
 template< typename Expr >
 void evaluate( Expr const & expr )

Added: branches/release/libs/xpressive/proto/example/lambda.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/example/lambda.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,228 @@
+//[ Lambda
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2008 Eric Niebler. 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)
+//
+// This example builds a simple but functional lambda library using Proto.
+
+#include <iostream>
+#include <algorithm>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/next_prior.hpp>
+#include <boost/fusion/tuple.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/typeof/std/ostream.hpp>
+#include <boost/typeof/std/iostream.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/context.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+
+using namespace boost;
+
+// Forward declaration of the lambda expression wrapper
+template<typename T>
+struct lambda;
+
+struct lambda_domain
+ : proto::domain<proto::pod_generator<lambda> >
+{};
+
+template<typename I>
+struct placeholder
+{
+ typedef I arity;
+};
+
+template<typename T>
+struct placeholder_arity
+{
+ typedef typename T::arity type;
+};
+
+namespace grammar
+{
+ using namespace proto;
+ using namespace transform;
+
+ // The lambda grammar, with the transforms for calculating the max arity
+ struct Lambda
+ : or_<
+ when< terminal< placeholder<_> >, mpl::next<placeholder_arity<_arg> >() >
+ , when< terminal<_>, mpl::int_<0>() >
+ , when< nary_expr<_, vararg<_> >, fold<_, mpl::int_<0>(), mpl::max<Lambda,_state>()> >
+ >
+ {};
+}
+
+// simple wrapper for calculating a lambda expression's arity.
+template<typename Expr>
+struct lambda_arity
+ : boost::result_of<grammar::Lambda(Expr, mpl::void_, mpl::void_)>
+{};
+
+// The lambda context is the same as the default context
+// with the addition of special handling for lambda placeholders
+template<typename Tuple>
+struct lambda_context
+ : proto::callable_context<lambda_context<Tuple> const>
+{
+ lambda_context(Tuple const &args)
+ : args_(args)
+ {}
+
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename I>
+ struct result<This(proto::tag::terminal, placeholder<I> const &)>
+ : fusion::result_of::at<Tuple, I>
+ {};
+
+ template<typename I>
+ typename fusion::result_of::at<Tuple, I>::type
+ operator ()(proto::tag::terminal, placeholder<I> const &) const
+ {
+ return fusion::at<I>(this->args_);
+ }
+
+ Tuple args_;
+};
+
+// The lambda<> expression wrapper makes expressions polymorphic
+// function objects
+template<typename T>
+struct lambda
+{
+ BOOST_PROTO_EXTENDS(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_ASSIGN(T, lambda<T>, lambda_domain)
+ BOOST_PROTO_EXTENDS_SUBSCRIPT(T, lambda<T>, lambda_domain)
+
+ // Careful not to evaluate the return type of the nullary function
+ // unless we have a nullary lambda!
+ typedef typename mpl::eval_if<
+ typename lambda_arity<T>::type
+ , mpl::identity<void>
+ , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
+ >::type nullary_type;
+
+ // Define our operator () that evaluates the lambda expression.
+ nullary_type operator ()() const
+ {
+ fusion::tuple<> args;
+ lambda_context<fusion::tuple<> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
+ operator ()(A0 const &a0) const
+ {
+ fusion::tuple<A0 const &> args(a0);
+ lambda_context<fusion::tuple<A0 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+
+ template<typename A0, typename A1>
+ typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
+ operator ()(A0 const &a0, A1 const &a1) const
+ {
+ fusion::tuple<A0 const &, A1 const &> args(a0, a1);
+ lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);
+ return proto::eval(*this, ctx);
+ }
+};
+
+// Define some lambda placeholders
+lambda<proto::terminal<placeholder<mpl::int_<0> > >::type> const _1 = {{}};
+lambda<proto::terminal<placeholder<mpl::int_<1> > >::type> const _2 = {{}};
+
+template<typename T>
+lambda<typename proto::terminal<T>::type> const val(T const &t)
+{
+ lambda<typename proto::terminal<T>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+lambda<typename proto::terminal<T &>::type> const var(T &t)
+{
+ lambda<typename proto::terminal<T &>::type> that = {{t}};
+ return that;
+}
+
+template<typename T>
+struct construct_helper
+{
+ typedef T result_type; // for TR1 result_of
+
+ T operator()() const
+ { return T(); }
+
+ template<typename A0>
+ T operator()(A0 const &a0) const
+ { return T(a0); }
+
+ template<typename A0, typename A1>
+ T operator()(A0 const &a0, A1 const &a1) const
+ { return T(a0, a1); }
+};
+
+// Generate BOOST_PROTO_MAX_ARITY-1 overloads of the
+// construct function template like the one defined above.
+BOOST_PROTO_DEFINE_VARARG_FUNCTION_TEMPLATE( \
+ construct \
+ , lambda_domain \
+ , (proto::tag::function) \
+ , ((construct_helper)(typename)) \
+)
+
+struct S
+{
+ S() {}
+ S(int i, char c)
+ {
+ std::cout << "S(" << i << "," << c << ")\n";
+ }
+};
+
+int main()
+{
+ // Create some lambda objects and immediately
+ // invoke them by applying their operator():
+ int i = ( (_1 + 2) / 4 )(42);
+ std::cout << i << std::endl; // prints 11
+
+ int j = ( (-(_1 + 2)) / 4 )(42);
+ std::cout << j << std::endl; // prints -11
+
+ double d = ( (4 - _2) * 3 )(42, 3.14);
+ std::cout << d << std::endl; // prints 2.58
+
+ // check non-const ref terminals
+ (std::cout << _1 << " -- " << _2)(42, "Life, the Universe and Everything!");
+ // prints "42 -- Life, the Universe and Everything!"
+
+ // "Nullary" lambdas work too
+ int k = (val(1) + val(2))();
+ std::cout << k << std::endl; // prints 3
+
+ // check array indexing for kicks
+ int integers[5] = {0};
+ (var(integers)[2] = 2)();
+ (var(integers)[_1] = _1)(3);
+ std::cout << integers[2] << std::endl; // prints 2
+ std::cout << integers[3] << std::endl; // prints 3
+
+ // Now use a lambda with an STL algorithm!
+ int rgi[4] = {1,2,3,4};
+ char rgc[4] = {'a','b','c','d'};
+ S rgs[4];
+
+ std::transform(rgi, rgi+4, rgc, rgs, construct<S>(_1, _2));
+ return 0;
+}
+//]

Modified: branches/release/libs/xpressive/proto/example/lazy_vector.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/lazy_vector.cpp (original)
+++ branches/release/libs/xpressive/proto/example/lazy_vector.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ LazyVector
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -22,13 +22,13 @@
 using proto::_;
 
 // This grammar describes which lazy vector expressions
-// are allowed; namely, vector terminals and addition
+// are allowed; namely, vector terminals and addition
 // and subtraction of lazy vector expressions.
 struct LazyVectorGrammar
   : proto::or_<
         proto::terminal< std::vector<_> >
- , proto::plus< LazyVectorGrammar, LazyVectorGrammar>
- , proto::minus< LazyVectorGrammar, LazyVectorGrammar>
+ , proto::plus< LazyVectorGrammar, LazyVectorGrammar >
+ , proto::minus< LazyVectorGrammar, LazyVectorGrammar >
>
 {};
 
@@ -57,7 +57,7 @@
     {
         typedef typename proto::result_of::arg<Expr>::type::value_type result_type;
 
- result_type operator()( Expr const & expr, lazy_subscript_context & ctx ) const
+ result_type operator ()( Expr const & expr, lazy_subscript_context & ctx ) const
         {
             return proto::arg( expr )[ ctx.subscript_ ];
         }
@@ -67,7 +67,7 @@
 };
 
 // Here is the domain-specific expression wrapper, which overrides
-// operator[] to evaluate the expression using the lazy_subscript_context.
+// operator [] to evaluate the expression using the lazy_subscript_context.
 template<typename Expr>
 struct lazy_vector_expr
   : proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain>

Added: branches/release/libs/xpressive/proto/example/map_assign.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/example/map_assign.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,105 @@
+//[ MapAssign
+// Copyright 2008 Eric Niebler. 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)
+//
+// This is a port of map_list_of() from the Boost.Assign library.
+// It has the advantage of being more efficient at runtime by not
+// building any temporary container that requires dynamic allocation.
+
+#include <map>
+#include <string>
+#include <iostream>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+
+using namespace boost;
+using namespace proto;
+
+struct map_list_of_tag
+{};
+
+// A simple callable function object that inserts a
+// (key,value) pair into a map.
+struct insert
+ : callable
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Map, typename Key, typename Value>
+ struct result<This(Map, Key, Value)>
+ : add_reference<Map>
+ {};
+
+ template<typename Map, typename Key, typename Value>
+ Map &operator()(Map &map, Key const &key, Value const &value) const
+ {
+ map.insert(typename Map::value_type(key, value));
+ return map;
+ }
+};
+
+// The grammmar for valid map-list expressions, and a
+// transform that populates the map.
+struct MapListOf
+ : or_<
+ when<
+ function<terminal<map_list_of_tag>, terminal<_>, terminal<_> >
+ , insert(_visitor, _arg(_arg1), _arg(_arg2))
+ >
+ , when<
+ function<MapListOf, terminal<_>, terminal<_> >
+ , insert(MapListOf(_arg0), _arg(_arg1), _arg(_arg2))
+ >
+ >
+{};
+
+template<typename Expr>
+struct map_list_of_expr;
+
+struct map_list_of_dom
+ : domain<pod_generator<map_list_of_expr>, MapListOf>
+{};
+
+// An expression wrapper that provides a conversion to a
+// map that uses the MapListOf
+template<typename Expr>
+struct map_list_of_expr
+{
+ BOOST_PROTO_EXTENDS(Expr, map_list_of_expr, map_list_of_dom)
+ BOOST_PROTO_EXTENDS_FUNCTION(Expr, map_list_of_expr, map_list_of_dom)
+
+ template<typename Map>
+ operator Map() const
+ {
+ Map map;
+ return MapListOf()(*this, 0, map);
+ }
+};
+
+map_list_of_expr<terminal<map_list_of_tag>::type> const map_list_of = {{{}}};
+
+int main()
+{
+ // Initialize a map:
+ std::map<std::string, int> op =
+ map_list_of
+ ("<",1)
+ ("<=",2)
+ (">",3)
+ (">=",4)
+ ("=",5)
+ ("<>",6)
+ ;
+
+ std::cout << "\"<\" --> " << op["<"] << std::endl;
+ std::cout << "\"<=\" --> " << op["<="] << std::endl;
+ std::cout << "\">\" --> " << op[">"] << std::endl;
+ std::cout << "\">=\" --> " << op[">="] << std::endl;
+ std::cout << "\"=\" --> " << op["="] << std::endl;
+ std::cout << "\"<>\" --> " << op["<>"] << std::endl;
+
+ return 0;
+}
+//]

Modified: branches/release/libs/xpressive/proto/example/mixed.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/mixed.cpp (original)
+++ branches/release/libs/xpressive/proto/example/mixed.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ Mixed
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -18,12 +18,14 @@
 #include <boost/xpressive/proto/proto.hpp>
 #include <boost/xpressive/proto/debug.hpp>
 #include <boost/xpressive/proto/context.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 #include <boost/typeof/std/list.hpp>
 #include <boost/typeof/std/vector.hpp>
 #include <boost/typeof/std/complex.hpp>
 
-using namespace boost;
-using proto::_;
+namespace proto = boost::proto;
+namespace mpl = boost::mpl;
+using namespace proto;
 
 template<typename Expr>
 struct MixedExpr;
@@ -38,30 +40,24 @@
     Iter it;
 };
 
-template<typename Cont>
-iterator_wrapper<typename Cont::const_iterator> cbegin(Cont const &cont)
+struct begin : proto::callable
 {
- return iterator_wrapper<typename Cont::const_iterator>(cont.begin());
-}
+ template<class Sig>
+ struct result;
 
-template<typename Grammar>
-struct begin
- : Grammar
-{
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : proto::terminal<
- iterator_wrapper<
- typename proto::result_of::arg<Expr>::type::const_iterator
- >
+ template<class This, class Cont>
+ struct result<This(Cont)>
+ : proto::result_of::as_expr<
+ iterator_wrapper<typename boost::remove_reference<Cont>::type::const_iterator>
>
     {};
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ template<typename Cont>
+ typename result<begin(Cont const &)>::type
+ operator ()(Cont const &cont) const
     {
- return proto::as_expr(cbegin(proto::arg(expr)));
+ iterator_wrapper<typename Cont::const_iterator> it(cont.begin());
+ return proto::as_expr(it);
     }
 };
 
@@ -69,10 +65,10 @@
 // begin iterators
 struct Begin
   : proto::or_<
- begin< proto::terminal< std::vector<_, _> > >
- , begin< proto::terminal< std::list<_, _> > >
- , proto::terminal<_>
- , proto::nary_expr<_, proto::vararg<Begin> >
+ when< proto::terminal< std::vector<_, _> >, begin(_arg) >
+ , when< proto::terminal< std::list<_, _> >, begin(_arg) >
+ , when< proto::terminal<_> >
+ , when< proto::nary_expr<_, proto::vararg<Begin> > >
>
 {};
 
@@ -80,20 +76,20 @@
 // terminals.
 struct DereferenceCtx
 {
- // Unless this is a vector terminal, use the
+ // Unless this is an iterator terminal, use the
     // default evaluation context
     template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>
     struct eval
       : proto::default_eval<Expr, DereferenceCtx const>
     {};
 
- // Index vector terminals with our subscript.
+ // Dereference iterator terminals.
     template<typename Expr, typename Iter>
     struct eval<Expr, iterator_wrapper<Iter> >
     {
         typedef typename std::iterator_traits<Iter>::reference result_type;
 
- result_type operator()(Expr &expr, DereferenceCtx const &) const
+ result_type operator ()(Expr &expr, DereferenceCtx const &) const
         {
             return *proto::arg(expr).it;
         }
@@ -104,20 +100,20 @@
 // terminals.
 struct IncrementCtx
 {
- // Unless this is a vector terminal, use the
+ // Unless this is an iterator terminal, use the
     // default evaluation context
     template<typename Expr, typename Arg = typename proto::result_of::arg<Expr>::type>
     struct eval
       : proto::null_eval<Expr, IncrementCtx const>
     {};
 
- // Index vector terminals with our subscript.
+ // advance iterator terminals.
     template<typename Expr, typename Iter>
     struct eval<Expr, iterator_wrapper<Iter> >
     {
         typedef void result_type;
 
- result_type operator()(Expr &expr, IncrementCtx const &) const
+ result_type operator ()(Expr &expr, IncrementCtx const &) const
         {
             ++proto::arg(expr).it;
         }
@@ -148,11 +144,14 @@
 };
 
 // A vector grammar is a terminal or some op that is not an
-// assignment op. (Assignment will be handles specially.)
+// assignment op. (Assignment will be handled specially.)
 struct MixedGrammar
   : proto::or_<
         proto::terminal<_>
- , proto::and_<proto::nary_expr<_, proto::vararg<MixedGrammar> >, proto::not_<AssignOps> >
+ , proto::and_<
+ proto::nary_expr<_, proto::vararg<MixedGrammar> >
+ , proto::not_<AssignOps>
+ >
>
 {};
 
@@ -172,7 +171,7 @@
     {}
 private:
     // hide this:
- using proto::extends<Expr, MixedExpr<Expr>, MixedDomain>::operator[];
+ using proto::extends<Expr, MixedExpr<Expr>, MixedDomain>::operator [];
 };
 
 // Define a trait type for detecting vector and list terminals, to
@@ -192,7 +191,7 @@
   : mpl::true_
 {};
 
-namespace VectorOps
+namespace MixedOps
 {
     // This defines all the overloads to make expressions involving
     // std::vector to build expression templates.
@@ -201,7 +200,7 @@
     struct assign_op
     {
         template<typename T, typename U>
- void operator()(T &t, U const &u) const
+ void operator ()(T &t, U const &u) const
         {
             t = u;
         }
@@ -210,7 +209,7 @@
     struct plus_assign_op
     {
         template<typename T, typename U>
- void operator()(T &t, U const &u) const
+ void operator ()(T &t, U const &u) const
         {
             t += u;
         }
@@ -219,7 +218,7 @@
     struct minus_assign_op
     {
         template<typename T, typename U>
- void operator()(T &t, U const &u) const
+ void operator ()(T &t, U const &u) const
         {
             t -= u;
         }
@@ -227,26 +226,31 @@
 
     struct sin_
     {
- template<typename Sig> struct result {};
+ template<typename Sig>
+ struct result;
+
         template<typename This, typename Arg>
         struct result<This(Arg)>
- : remove_const<typename remove_reference<Arg>::type>
+ : boost::remove_const<typename boost::remove_reference<Arg>::type>
         {};
 
         template<typename Arg>
- Arg operator()(Arg const &arg) const
+ Arg operator ()(Arg const &arg) const
         {
             return std::sin(arg);
         }
     };
 
- BOOST_PROTO_DEFINE_FUNCTION_TEMPLATE(
- 1
- , sin
+ template<typename A>
+ typename proto::result_of::make_expr<
+ proto::tag::function
       , MixedDomain
- , (boost::proto::tag::function)
- , ((sin_))
- )
+ , sin_ const
+ , A const &
+ >::type sin(A const &a)
+ {
+ return proto::make_expr<proto::tag::function, MixedDomain>(sin_(), boost::ref(a));
+ }
 
     template<typename FwdIter, typename Expr, typename Op>
     void evaluate(FwdIter begin, FwdIter end, Expr const &expr, Op op)
@@ -254,7 +258,7 @@
         int i = 0;
         IncrementCtx const inc = {};
         DereferenceCtx const deref = {};
- typename Begin::apply<Expr, int, int>::type expr2 = Begin::call(expr, i, i);
+ typename boost::result_of<Begin(Expr, int, int)>::type expr2 = Begin()(expr, i, i);
         for(; begin != end; ++begin)
         {
             op(*begin, proto::eval(expr2, deref));
@@ -313,7 +317,7 @@
 
 int main()
 {
- using namespace VectorOps;
+ using namespace MixedOps;
 
     int n = 10;
     std::vector<int> a,b,c,d;
@@ -331,11 +335,11 @@
         f.push_back(std::complex<double>(1.0, 1.0));
     }
 
- VectorOps::assign(b, 2);
- VectorOps::assign(d, a + b * c);
+ MixedOps::assign(b, 2);
+ MixedOps::assign(d, a + b * c);
     a += if_else(d < 30, b, c);
 
- VectorOps::assign(e, c);
+ MixedOps::assign(e, c);
     e += e - 4 / (c + 1);
 
     f -= sin(0.1 * e * std::complex<double>(0.2, 1.2));

Modified: branches/release/libs/xpressive/proto/example/rgb.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/rgb.cpp (original)
+++ branches/release/libs/xpressive/proto/example/rgb.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ RGB
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -11,9 +11,7 @@
 
 #include <iostream>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/apply.hpp>
-#include <boost/xpressive/proto/transform/compose.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 using namespace boost::proto;
 
 struct RedTag
@@ -40,35 +38,49 @@
     }
 };
 
-typedef terminal<RedTag>::type Red;
-typedef terminal<BlueTag>::type Blue;
-typedef terminal<GreenTag>::type Green;
+typedef terminal<RedTag>::type RedT;
+typedef terminal<BlueTag>::type BlueT;
+typedef terminal<GreenTag>::type GreenT;
+
+struct Red;
+struct Blue;
+struct Green;
 
 ///////////////////////////////////////////////////////////////////////////////
 // A transform that produces new colors according to some arbitrary rules:
 // red & green give blue, red & blue give green, blue and green give red.
+struct Red
+ : or_<
+ plus<Green, Blue>
+ , plus<Blue, Green>
+ , plus<Red, Red>
+ , terminal<RedTag>
+ >
+{};
+
+struct Green
+ : or_<
+ plus<Red, Blue>
+ , plus<Blue, Red>
+ , plus<Green, Green>
+ , terminal<GreenTag>
+ >
+{};
+
+struct Blue
+ : or_<
+ plus<Red, Green>
+ , plus<Green, Red>
+ , plus<Blue, Blue>
+ , terminal<BlueTag>
+ >
+{};
+
 struct RGB
   : or_<
- // leave terminals as they are
- terminal<_>
- , transform::compose<
- // Match binary nodes, convert left and right to terminals
- plus<RGB, RGB>
- // Forward resulting binary expression to the following transform
- , or_<
- // Green + Blue -> Red
- transform::always<plus<Green, Blue>, Red>
- , transform::always<plus<Blue, Green>, Red>
- // Red + Green -> Blue
- , transform::always<plus<Red, Green>, Blue>
- , transform::always<plus<Green, Red>, Blue>
- // Red + Blue -> Green
- , transform::always<plus<Red, Blue>, Green>
- , transform::always<plus<Blue, Red>, Green>
- // else (both same color), select the left operand
- , transform::left<_>
- >
- >
+ when< Red, RedTag() >
+ , when< Blue, BlueTag() >
+ , when< Green, GreenTag() >
>
 {};
 
@@ -76,14 +88,14 @@
 void printColor(Expr const & expr)
 {
     int i = 0; // dummy state and visitor parameter, not used
- std::cout << arg(RGB::call(expr, i, i)) << std::endl;
+ std::cout << RGB()(expr, i, i) << std::endl;
 }
 
 int main()
 {
- printColor(Red() + Green());
- printColor(Red() + Green() + Blue());
- printColor(Red() + (Green() + Blue()));
+ printColor(RedT() + GreenT());
+ printColor(RedT() + GreenT() + BlueT());
+ printColor(RedT() + (GreenT() + BlueT()));
 
     return 0;
 }

Modified: branches/release/libs/xpressive/proto/example/tarray.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/tarray.cpp (original)
+++ branches/release/libs/xpressive/proto/example/tarray.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ TArray
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -52,7 +52,7 @@
 
     // Index array terminals with our subscript. Everything
     // else will be handled by the default evaluation context.
- int operator()(proto::tag::terminal, int const (&data)[3]) const
+ int operator ()(proto::tag::terminal, int const (&data)[3]) const
     {
         return data[this->i_];
     }
@@ -68,43 +68,43 @@
 
     TArrayPrintCtx() {}
 
- std::ostream &operator()(proto::tag::terminal, int i) const
+ std::ostream &operator ()(proto::tag::terminal, int i) const
     {
         return std::cout << i;
     }
 
- std::ostream &operator()(proto::tag::terminal, int const (&arr)[3]) const
+ std::ostream &operator ()(proto::tag::terminal, int const (&arr)[3]) const
     {
         return std::cout << '{' << arr[0] << ", " << arr[1] << ", " << arr[2] << '}';
     }
 
     template<typename L, typename R>
- std::ostream &operator()(proto::tag::plus, L const &l, R const &r) const
+ std::ostream &operator ()(proto::tag::plus, L const &l, R const &r) const
     {
         return std::cout << '(' << l << " + " << r << ')';
     }
 
     template<typename L, typename R>
- std::ostream &operator()(proto::tag::minus, L const &l, R const &r) const
+ std::ostream &operator ()(proto::tag::minus, L const &l, R const &r) const
     {
         return std::cout << '(' << l << " - " << r << ')';
     }
 
     template<typename L, typename R>
- std::ostream &operator()(proto::tag::multiplies, L const &l, R const &r) const
+ std::ostream &operator ()(proto::tag::multiplies, L const &l, R const &r) const
     {
         return std::cout << l << " * " << r;
     }
 
     template<typename L, typename R>
- std::ostream &operator()(proto::tag::divides, L const &l, R const &r) const
+ std::ostream &operator ()(proto::tag::divides, L const &l, R const &r) const
     {
         return std::cout << l << " / " << r;
     }
 };
 
 // Here is the domain-specific expression wrapper, which overrides
-// operator[] to evaluate the expression using the TArraySubscriptCtx.
+// operator [] to evaluate the expression using the TArraySubscriptCtx.
 template<typename Expr>
 struct TArrayExpr
   : proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain>
@@ -143,9 +143,9 @@
         (*this)[2] = k;
     }
 
- // Here we override operator[] to give read/write access to
+ // Here we override operator [] to give read/write access to
     // the elements of the array. (We could use the TArrayExpr
- // operator[] if we made the subscript context smarter about
+ // operator [] if we made the subscript context smarter about
     // returning non-const reference when appropriate.)
     int &operator [](std::ptrdiff_t i)
     {
@@ -157,13 +157,13 @@
         return proto::arg(*this)[i];
     }
 
- // Here we define a operator= for TArray terminals that
+ // Here we define a operator = for TArray terminals that
     // takes a TArray expression.
     template< typename Expr >
     TArray &operator =(Expr const & expr)
     {
         // proto::as_expr<TArrayDomain>(expr) is the same as
- // expr unless expr is an integer, in which case it
+ // expr unless expr is an integer, in which case it
         // is made into a TArrayExpr terminal first.
         return this->assign(proto::as_expr<TArrayDomain>(expr));
     }

Modified: branches/release/libs/xpressive/proto/example/vec3.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/vec3.cpp (original)
+++ branches/release/libs/xpressive/proto/example/vec3.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ Vec3
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -16,12 +16,11 @@
 #include <boost/xpressive/proto/proto.hpp>
 #include <boost/xpressive/proto/context.hpp>
 #include <boost/xpressive/proto/proto_typeof.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
-#include <boost/xpressive/proto/transform/apply.hpp>
-#include <boost/xpressive/proto/transform/function.hpp>
-using namespace boost::proto;
+#include <boost/xpressive/proto/transform.hpp>
+
 namespace mpl = boost::mpl;
+namespace proto = boost::proto;
+using namespace proto;
 
 // Here is an evaluation context that indexes into a Vec3
 // expression, and combines the result.
@@ -36,7 +35,7 @@
 
     // Index array terminals with our subscript. Everything
     // else will be handled by the default evaluation context.
- int operator()(tag::terminal, int const (&arr)[3]) const
+ int operator ()(tag::terminal, int const (&arr)[3]) const
     {
         return arr[this->i_];
     }
@@ -45,41 +44,40 @@
 };
 
 // Here is an evaluation context that counts the number
-// of Vec3 terminals in an expression.
+// of Vec3 terminals in an expression.
 struct CountLeavesCtx
   : callable_context< CountLeavesCtx, null_context >
 {
     CountLeavesCtx()
       : count(0)
       {}
-
+
       typedef void result_type;
-
- void operator()(tag::terminal, int const(&)[3])
+
+ void operator ()(tag::terminal, int const(&)[3])
       {
           ++this->count;
       }
-
+
       int count;
 };
 
+struct iplus : std::plus<int>, callable {};
+
 // Here is a transform that does the same thing as the above context.
 // It demonstrates the use of the std::plus<> function object
-// with the function2 transform. With minor modifications, this
+// with the fold transform. With minor modifications, this
 // transform could be used to calculate the leaf count at compile
-// time, rather at runtime.
+// time, rather than at runtime.
 struct CountLeaves
   : or_<
         // match a Vec3 terminal, return 1
- transform::always<terminal<int[3]>, mpl::int_<1> >
+ when<terminal<int[3]>, mpl::int_<1>() >
         // match a terminal, return int() (which is 0)
- , transform::always<terminal<_>, int>
+ , when<terminal<_>, int() >
         // fold everything else, using std::plus<> to add
         // the leaf count of each child to the accumulated state.
- , transform::fold<
- nary_expr<_, vararg<transform::function2<CountLeaves, std::plus<int> > > >
- , int // initial state of the fold is int() (which is 0)
- >
+ , otherwise< fold<_, int(), iplus(CountLeaves, _state) > >
>
 {};
 
@@ -94,17 +92,17 @@
         (*this)[2] = k;
     }
 
- int &operator[](int i)
+ int &operator [](int i)
     {
- return arg(*this)[i];
+ return proto::arg(*this)[i];
     }
 
- int const &operator[](int i) const
+ int const &operator [](int i) const
     {
- return arg(*this)[i];
+ return proto::arg(*this)[i];
     }
 
- // Here we define a operator= for Vec3 terminals that
+ // Here we define a operator = for Vec3 terminals that
     // takes a Vec3 expression.
     template< typename Expr >
     Vec3 &operator =(Expr const & expr)
@@ -134,10 +132,10 @@
     // CountLeavesCtx evaluation context.
     CountLeavesCtx ctx;
     eval(expr, ctx);
-
+
     // This is another way to count the leaves using a transform.
     int i = 0;
- assert( CountLeaves::call(expr, i, i) == ctx.count );
+ assert( CountLeaves()(expr, i, i) == ctx.count );
 
     return ctx.count;
 }

Modified: branches/release/libs/xpressive/proto/example/vector.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/example/vector.cpp (original)
+++ branches/release/libs/xpressive/proto/example/vector.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,6 +1,6 @@
 //[ Vector
 ///////////////////////////////////////////////////////////////////////////////
-// Copyright 2007 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 //
@@ -42,7 +42,7 @@
     {
         typedef T result_type;
 
- T operator()(Expr &expr, VectorSubscriptCtx const &ctx) const
+ T operator ()(Expr &expr, VectorSubscriptCtx const &ctx) const
         {
             return proto::arg(expr)[ctx.i_];
         }
@@ -73,11 +73,11 @@
     {
         typedef void result_type;
 
- result_type operator()(Expr &expr, VectorSizeCtx const &ctx) const
+ result_type operator ()(Expr &expr, VectorSizeCtx const &ctx) const
         {
             if(ctx.size_ != proto::arg(expr).size())
             {
- throw std::invalid_argument("LHS and RHS are not compatible");
+ throw std::runtime_error("LHS and RHS are not compatible");
             }
         }
     };
@@ -109,7 +109,7 @@
 };
 
 // A vector grammar is a terminal or some op that is not an
-// assignment op. (Assignment will be handles specially.)
+// assignment op. (Assignment will be handled specially.)
 struct VectorGrammar
   : proto::or_<
         proto::terminal<_>
@@ -124,7 +124,7 @@
 {};
 
 // Here is VectorExpr, which extends a proto expr type by
-// giving it an operator[] which uses the VectorSubscriptCtx
+// giving it an operator [] which uses the VectorSubscriptCtx
 // to evaluate an expression with a given index.
 template<typename Expr>
 struct VectorExpr

Modified: branches/release/libs/xpressive/proto/test/Jamfile.v2
==============================================================================
--- branches/release/libs/xpressive/proto/test/Jamfile.v2 (original)
+++ branches/release/libs/xpressive/proto/test/Jamfile.v2 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -19,13 +19,15 @@
 
 test-suite "proto"
     :
+ [ run calculator.cpp ]
+ [ run deep_copy.cpp ]
+ [ run examples.cpp ]
+ [ run lambda.cpp ]
+ [ run make_expr.cpp ]
+ [ run matches.cpp ]
         [ run proto_fusion.cpp : : : <toolset>gcc:<cxxflags>-ftemplate-depth-1024 ]
         [ run proto_fusion_s.cpp ]
         [ run toy_spirit.cpp ]
         [ run toy_spirit2.cpp ]
- [ run calculator.cpp ]
- [ run lambda.cpp ]
- [ run matches.cpp ]
- [ run examples.cpp ]
     ;
 

Modified: branches/release/libs/xpressive/proto/test/calculator.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/calculator.cpp (original)
+++ branches/release/libs/xpressive/proto/test/calculator.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // calculator.hpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -22,36 +22,36 @@
       : i_(i)
     {}
 
- int operator()(proto::tag::terminal, placeholder) const
+ int operator ()(proto::tag::terminal, placeholder) const
     {
         return this->i_;
     }
 
- int operator()(proto::tag::terminal, int j) const
+ int operator ()(proto::tag::terminal, int j) const
     {
         return j;
     }
 
     template<typename Left, typename Right>
- int operator()(proto::tag::plus, Left const &left, Right const &right) const
+ int operator ()(proto::tag::plus, Left const &left, Right const &right) const
     {
         return proto::eval(left, *this) + proto::eval(right, *this);
     }
 
     template<typename Left, typename Right>
- int operator()(proto::tag::minus, Left const &left, Right const &right) const
+ int operator ()(proto::tag::minus, Left const &left, Right const &right) const
     {
         return proto::eval(left, *this) - proto::eval(right, *this);
     }
 
     template<typename Left, typename Right>
- int operator()(proto::tag::multiplies, Left const &left, Right const &right) const
+ int operator ()(proto::tag::multiplies, Left const &left, Right const &right) const
     {
         return proto::eval(left, *this) * proto::eval(right, *this);
     }
 
     template<typename Left, typename Right>
- int operator()(proto::tag::divides, Left const &left, Right const &right) const
+ int operator ()(proto::tag::divides, Left const &left, Right const &right) const
     {
         return proto::eval(left, *this) / proto::eval(right, *this);
     }
@@ -70,7 +70,7 @@
     {}
 
     template<typename T>
- result_type operator()(T const &t) const
+ result_type operator ()(T const &t) const
     {
         Fun fun(t);
         return proto::eval(this->expr_, fun);

Added: branches/release/libs/xpressive/proto/test/deep_copy.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/test/deep_copy.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////
+// deep_copy.hpp
+//
+// Copyright 2008 Eric Niebler. 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)
+
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+
+void foo() {}
+
+void test1()
+{
+ using namespace proto;
+
+ int i = 42;
+ terminal<int &>::type t1 = {i};
+ terminal<int>::type r1 = deep_copy(t1);
+ BOOST_CHECK_EQUAL(42, arg(r1));
+
+ plus<terminal<int>::type, terminal<int>::type>::type r2 = deep_copy(t1 + 24);
+ BOOST_CHECK_EQUAL(42, arg(left(r2)));
+ BOOST_CHECK_EQUAL(24, arg(right(r2)));
+
+ char buf[16] = {'\0'};
+ terminal<char (&)[16]>::type t3 = {buf};
+ terminal<char[16]>::type r3 = deep_copy(t3);
+
+ terminal<void(&)()>::type t4 = {foo};
+ plus<terminal<void(&)()>::type, terminal<int>::type>::type r4 = deep_copy(t4 + t1);
+ BOOST_CHECK_EQUAL(42, arg(right(r4)));
+ BOOST_CHECK_EQUAL(&foo, &arg(left(r4)));
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test deep_copy of proto parse trees");
+
+ test->add(BOOST_TEST_CASE(&test1));
+
+ return test;
+}

Modified: branches/release/libs/xpressive/proto/test/examples.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/examples.cpp (original)
+++ branches/release/libs/xpressive/proto/test/examples.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
-// matches.hpp
+// examples2.hpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -9,30 +9,36 @@
 #include <boost/config.hpp>
 #include <boost/mpl/min_max.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
-#include <boost/xpressive/proto/transform/branch.hpp>
-#include <boost/xpressive/proto/transform/list.hpp>
-#include <boost/xpressive/proto/transform/apply.hpp>
-#include <boost/xpressive/proto/transform/construct.hpp>
-#include <boost/xpressive/proto/transform/fold_tree.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 #include <boost/utility/result_of.hpp>
+#if BOOST_VERSION < 103500
+# include <boost/spirit/fusion/sequence/cons.hpp>
+#else
+# include <boost/fusion/include/cons.hpp>
+# include <boost/fusion/include/pop_front.hpp>
+#endif
 #include <boost/test/unit_test.hpp>
 
-using namespace boost::proto;
+namespace proto = boost::proto;
 namespace mpl = boost::mpl;
 namespace fusion = boost::fusion;
 
+using namespace proto;
+using namespace transform;
+
 struct placeholder1 {};
 struct placeholder2 {};
 
 namespace test1
 {
-//[ CalculatorGrammar
+//[ CalcGrammar
     using namespace boost::proto;
 
+ // This is the grammar for calculator expressions,
+ // to which we will attach transforms for computing
+ // the expressions' arity.
     /*<< A Calculator expression is ... >>*/
- struct CalculatorGrammar
+ struct CalcArity
       : or_<
             /*<< placeholder1, or ... >>*/
             terminal< placeholder1 >
@@ -41,48 +47,95 @@
           /*<< some other terminal, or ... >>*/
           , terminal< _ >
           /*<< a unary expression where the operand is a calculator expression, or ... >>*/
- , unary_expr< _, CalculatorGrammar >
- /*<< a binary expression where the operands are calculator expressions, or ... >>*/
- , binary_expr< _, CalculatorGrammar, CalculatorGrammar >
+ , unary_expr< _, CalcArity >
+ /*<< a binary expression where the operands are calculator expressions >>*/
+ , binary_expr< _, CalcArity, CalcArity >
>
     {};
 //]
 }
 
-//[ binary_max
+//[ binary_arity
+/*<< The `CalculatorArity` is a transform for calculating
+the arity of a calculator expression. It will be define in
+terms of `binary_arity`, which is defined in terms of
+`CalculatorArity`; hence, the definition is recursive.>>*/
+struct CalculatorArity;
+
+// A custom transform that returns the arity of a unary
+// calculator expression by finding the arity of the
+// child expression.
+struct unary_arity
+ /*<< Custom transforms should inherit from
+ callable. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_callable<> trait. >>*/
+ : callable
+{
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `result<>` for calculating their return type. >>*/
+ struct result<This(Expr, State, Visitor)>
+ {
+ /*<< Get the child. >>*/
+ typedef typename result_of::arg<Expr>::type child_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the child. >>*/
+ typedef typename boost::result_of<CalculatorArity(child_expr, State, Visitor)>::type type;
+ };
+
+ template<typename Expr, typename State, typename Visitor>
+ typename result<unary_arity(Expr, State, Visitor)>::type
+ /*<< Transforms have a nested `operator ()` member function. >>*/
+ operator ()(Expr const &, State const &, Visitor &) const
+ {
+ /*<< The `unary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ return typename result<unary_arity(Expr, State, Visitor)>::type();
+ }
+};
+
 // A custom transform that returns the arity of a binary
 // calculator expression by finding the maximum of the
-// arities of the two children expressions.
-/*<< All transforms take a Grammar as a template parameter. >>*/
-template<typename Grammar>
-struct binary_max
- /*<< All transforms must inherit from the `Grammar`, so that the transform
- IS-A `Grammar`, and matches the same expressions that `Grammar` does. >>*/
- : Grammar
+// arities of the mpl::int_<2> children expressions.
+struct binary_arity
+ /*<< All custom transforms should inherit from
+ callable. In some cases, (e.g., when the transform
+ is a template), it is also necessary to specialize
+ the proto::is_callable<> trait. >>*/
+ : callable
 {
- template<typename Expr, typename State, typename Visitor>
- /*<< Transforms have a nested `apply<>` for calculating their return type. >>*/
- struct apply
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename Expr, typename State, typename Visitor>
+ /*<< Transforms have a nested `result<>` for calculating their return type. >>*/
+ struct result<This(Expr, State, Visitor)>
     {
- /*<< Apply `Grammar`'s transform. This is what makes it possible to chain transforms. >>*/
- typedef typename mpl::apply_wrap3<Grammar, Expr, State, Visitor>::type expr_type;
- /*<< After applying `Grammar`'s transform, the children expressions have been
- replaced with their arities. >>*/
- typedef typename result_of::left<expr_type>::type left_arity;
- typedef typename result_of::right<expr_type>::type right_arity;
+ /*<< Get the left and right children. >>*/
+ typedef typename result_of::left<Expr>::type left_expr;
+ typedef typename result_of::right<Expr>::type right_expr;
+
+ /*<< Apply `CalculatorArity` to find the arity of the left and right children. >>*/
+ typedef typename boost::result_of<CalculatorArity(left_expr, State, Visitor)>::type left_arity;
+ typedef typename boost::result_of<CalculatorArity(right_expr, State, Visitor)>::type right_arity;
+
         /*<< The return type is the maximum of the children's arities. >>*/
         typedef typename mpl::max<left_arity, right_arity>::type type;
     };
 
     template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
+ typename result<binary_arity(Expr, State, Visitor)>::type
     /*<< Transforms have a nested `call()` member function. >>*/
- call(Expr const &, State const &, Visitor &)
+ operator ()(Expr const &, State const &, Visitor &) const
     {
- /*<< Usually, the `call()` member function invokes the `Grammar`'s `call()` function,
- as `Grammar::call(expr,state,visitor)`, but this transform doesn't have an interesting
- runtime counterpart, so just return a default-constructed object of the correct type. >>*/
- return typename apply<Expr, State, Visitor>::type();
+ /*<< The `binary_arity` transform doesn't have an interesting
+ runtime counterpart, so just return a default-constructed object
+ of the correct type. >>*/
+ return typename result<binary_arity(Expr, State, Visitor)>::type();
     }
 };
 //]
@@ -91,76 +144,98 @@
 terminal< placeholder2 >::type const _2 = {{}};
 
 //[ CalculatorArityGrammar
-struct CalculatorGrammar
+struct CalculatorArity
   : or_<
- transform::always< terminal< placeholder1 >, mpl::int_<1> >
- , transform::always< terminal< placeholder2 >, mpl::int_<2> >
- , transform::always< terminal< _ >, mpl::int_<0> >
- , transform::arg< unary_expr< _, CalculatorGrammar > >
- , binary_max< binary_expr< _, CalculatorGrammar, CalculatorGrammar > >
+ when< terminal< placeholder1 >, mpl::int_<1>() >
+ , when< terminal< placeholder2 >, mpl::int_<2>() >
+ , when< terminal<_>, mpl::int_<0>() >
+ , when< unary_expr<_, _>, unary_arity >
+ , when< binary_expr<_, _, _>, binary_arity >
>
 {};
 //]
 
+//[ CalcArity
+struct CalcArity
+ : or_<
+ when< terminal< placeholder1 >,
+ mpl::int_<1>()
+ >
+ , when< terminal< placeholder2 >,
+ mpl::int_<2>()
+ >
+ , when< terminal<_>,
+ mpl::int_<0>()
+ >
+ , when< unary_expr<_, CalcArity>,
+ CalcArity(_arg)
+ >
+ , when< binary_expr<_, CalcArity, CalcArity>,
+ mpl::max<CalcArity(_left),
+ CalcArity(_right)>()
+ >
+ >
+{};
+//]
+
+// BUGBUG find workaround for this
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#define _pop_front(x) call<_pop_front(x)>
+#define _arg(x) call<_arg(x)>
+#endif
+
 //[ AsArgList
 // This transform matches function invocations such as foo(1,'a',"b")
 // and transforms them into Fusion cons lists of their arguments. In this
 // case, the result would be cons(1, cons('a', cons("b", nil()))).
 struct ArgsAsList
- /*<< Use a `branch<>` transform to use `fusion::nil` as the initial
- state of this transformation. >>*/
- : transform::branch<
- /*<< Use a `reverse_fold<>` transform to iterate over the children
- of this node in reverse order, building a fusion list from back to
- front. >>*/
- transform::reverse_fold<
- /*<< The `Grammar` we're matching is a function invocation. >>*/
- function<
- /*<< The first child expression of a `function<>` node is the
- function being invoked. We don't want that in our list, so use
- the `state<>` transform to effectively skip it. (Recall that
- we're building a list in the state parameter, and that the
- `state<>` transform just returns the state unmodified. So this
- says to match a `terminal<>` but to not add it to the list.) >>*/
- transform::state<terminal<_> >
- /*<< We use `vararg<>` here because the function expression we're
- matching can have an arbitrary number of arguments. >>*/
- , vararg<
- /*<< The `list<>` transform puts the rest of the function
- arguments in a fusion cons list. >>*/
- transform::list<
- /*<< The arguments to the function are terminals.
- Extract the argument from each terminal before putting
- them into the list. >>*/
- transform::arg<terminal<_> >
- >
- >
- >
- >
- /*<< Here is the initial state used by this transform. >>*/
- , fusion::nil
- >
+ : when<
+ function<terminal<_>, vararg<terminal<_> > >
+ /*<< Use a `reverse_fold<>` transform to iterate over the children
+ of this node in reverse order, building a fusion list from back to
+ front. >>*/
+ , reverse_fold<
+ /*<< The first child expression of a `function<>` node is the
+ function being invoked. We don't want that in our list, so use
+ `pop_front()` to remove it. >>*/
+ _pop_front(_)
+ /*<< `nil` is the initial state used by the `reverse_fold<>`
+ transform. >>*/
+ , fusion::nil()
+ /*<< Put the rest of the function arguments in a fusion cons
+ list. >>*/
+ , fusion::cons<_arg, _state>(_arg, _state)
+ >
+ >
 {};
 //]
 
 //[ FoldTreeToList
-// This grammar describes what counts as the terminals in expressions
-// of the form (_1=1,'a',"b"), which will be flattened using
-// reverse_fold_tree<> below.
-struct Terminals
- : or_<
- transform::arg<transform::right<assign<_, terminal<_> > > >
- , transform::arg<terminal<_> >
- >
-{};
-
 // This transform matches expressions of the form (_1=1,'a',"b")
 // (note the use of the comma operator) and transforms it into a
 // Fusion cons list of their arguments. In this case, the result
 // would be cons(1, cons('a', cons("b", nil()))).
 struct FoldTreeToList
- /*<< Fold all terminals that are separated by commas into a Fusion cons list. >>*/
- : transform::reverse_fold_tree<tag::comma, transform::list<Terminals>, fusion::nil>
+ : or_<
+ // This grammar describes what counts as the terminals in expressions
+ // of the form (_1=1,'a',"b"), which will be flattened using
+ // reverse_fold_tree<> below.
+ when<assign<_, terminal<_> >
+ , _arg(_right)
+ >
+ , when<terminal<_>
+ , _arg
+ >
+ , when<
+ comma<FoldTreeToList, FoldTreeToList>
+ /*<< Fold all terminals that are separated by commas into a Fusion cons list. >>*/
+ , reverse_fold_tree<
+ _
+ , fusion::nil()
+ , fusion::cons<FoldTreeToList, _state>(FoldTreeToList, _state)
+ >
+ >
+ >
 {};
 //]
 
@@ -169,12 +244,14 @@
 // them to doubles.
 struct Promote
   : or_<
- /*<< Match a `terminal<float>`, then construct a `terminal<double>::type` with the `float`. >>*/
- transform::construct<terminal<float>, terminal<double>::type(transform::arg<_>) >
- , terminal<_>
- /*<< `nary_expr<>` has a pass-through transform which will transform each child
- sub-expression using the `Promote` transform. >>*/
- , nary_expr<_, vararg<Promote> >
+ /*<< Match a `terminal<float>`, then construct a
+ `terminal<double>::type` with the `float`. >>*/
+ when<terminal<float>, terminal<double>::type(_arg) >
+ , when<terminal<_> >
+ /*<< `nary_expr<>` has a pass-through transform which
+ will transform each child sub-expression using the
+ `Promote` transform. >>*/
+ , when<nary_expr<_, vararg<Promote> > >
>
 {};
 //]
@@ -187,40 +264,77 @@
 // `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
 // from the arguments.
 struct MakePair
- : transform::construct<
+ : when<
         /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
         function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
       /*<< Return `std::pair<F,S>(f,s)` where `f` and `s` are the
- first and second arguments to the lazy `make_pair_()` function >>*/
- , std::pair<
- transform::arg<transform::arg_c<_, 1> >
- , transform::arg<transform::arg_c<_, 2> >
- >(
- transform::arg<transform::arg_c<_, 1> >
- , transform::arg<transform::arg_c<_, 2> >
- )
+ first and second arguments to the lazy `make_pair_()` function.
+ (This uses `proto::make<>` under the covers to evaluate the
+ transform.)>>*/
+ , std::pair<_arg(_arg1), _arg(_arg2)>(_arg(_arg1), _arg(_arg2))
>
 {};
 //]
 
+namespace lazy_make_pair2
+{
+ //[ LazyMakePair2
+ struct make_pair_tag {};
+ terminal<make_pair_tag>::type const make_pair_ = {{}};
+
+ // Like std::make_pair(), only as a function object.
+ /*<<Inheriting from `proto::callable` lets Proto know
+ that this is a callable transform, so we can use it
+ without having to wrap it in `proto::call<>`.>>*/
+ struct make_pair : proto::callable
+ {
+ template<typename Sig> struct result;
+
+ template<typename This, typename First, typename Second>
+ struct result<This(First, Second)>
+ {
+ typedef std::pair<First, Second> type;
+ };
+
+ template<typename First, typename Second>
+ std::pair<First, Second>
+ operator()(First const &first, Second const &second) const
+ {
+ return std::make_pair(first, second);
+ }
+ };
+
+ // This transform matches lazy function invocations like
+ // `make_pair_(1, 3.14)` and actually builds a `std::pair<>`
+ // from the arguments.
+ struct MakePair
+ : when<
+ /*<< Match expressions like `make_pair_(1, 3.14)` >>*/
+ function<terminal<make_pair_tag>, terminal<_>, terminal<_> >
+ /*<< Return `make_pair()(f,s)` where `f` and `s` are the
+ first and second arguments to the lazy `make_pair_()` function.
+ (This uses `proto::call<>` under the covers to evaluate the
+ transform.)>>*/
+ , make_pair(_arg(_arg1), _arg(_arg2))
+ >
+ {};
+ //]
+}
+
+
 //[ NegateInt
 struct NegateInt
- : transform::construct<
- terminal<int>
- , negate<_>(_)
- >
+ : when<terminal<int>, negate<_>(_)>
 {};
 //]
 
 #ifndef BOOST_MSVC
 //[ SquareAndPromoteInt
 struct SquareAndPromoteInt
- : transform::construct<
+ : when<
         terminal<int>
- , multiplies<terminal<long>::type, terminal<long>::type>::type(
- terminal<long>::type(transform::arg<_>)
- , terminal<long>::type(transform::arg<_>)
- )
+ , multiplies<terminal<long>::type, terminal<long>::type>::type
+ (terminal<long>::type(_arg), terminal<long>::type(_arg))
>
 {};
 //]
@@ -231,23 +345,27 @@
     //[ CalculatorArityTest
     int i = 0; // not used, dummy state and visitor parameter
 
- std::cout << CalculatorGrammar::call( lit(100) * 200, i, i) << '\n';
- std::cout << CalculatorGrammar::call( (_1 - _1) / _1 * 100, i, i) << '\n';
- std::cout << CalculatorGrammar::call( (_2 - _1) / _2 * 100, i, i) << '\n';
+ std::cout << CalculatorArity()( lit(100) * 200, i, i) << '\n';
+ std::cout << CalculatorArity()( (_1 - _1) / _1 * 100, i, i) << '\n';
+ std::cout << CalculatorArity()( (_2 - _1) / _2 * 100, i, i) << '\n';
     //]
 
- BOOST_CHECK_EQUAL(0, CalculatorGrammar::call( lit(100) * 200, i, i));
- BOOST_CHECK_EQUAL(1, CalculatorGrammar::call( (_1 - _1) / _1 * 100, i, i));
- BOOST_CHECK_EQUAL(2, CalculatorGrammar::call( (_2 - _1) / _2 * 100, i, i));
+ BOOST_CHECK_EQUAL(0, CalculatorArity()( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalculatorArity()( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalculatorArity()( (_2 - _1) / _2 * 100, i, i));
+
+ BOOST_CHECK_EQUAL(0, CalcArity()( lit(100) * 200, i, i));
+ BOOST_CHECK_EQUAL(1, CalcArity()( (_1 - _1) / _1 * 100, i, i));
+ BOOST_CHECK_EQUAL(2, CalcArity()( (_2 - _1) / _2 * 100, i, i));
 
     using boost::fusion::cons;
     using boost::fusion::nil;
- cons<int, cons<char, cons<char const (&)[2]> > > args(ArgsAsList::call( _1(1, 'a', "b"), i, i ));
+ cons<int, cons<char, cons<std::string> > > args(ArgsAsList()( _1(1, 'a', std::string("b")), i, i ));
     BOOST_CHECK_EQUAL(args.car, 1);
     BOOST_CHECK_EQUAL(args.cdr.car, 'a');
     BOOST_CHECK_EQUAL(args.cdr.cdr.car, std::string("b"));
 
- cons<int, cons<char, cons<char const (&)[2]> > > lst(FoldTreeToList::call( (_1 = 1, 'a', "b"), i, i ));
+ cons<int, cons<char, cons<std::string> > > lst(FoldTreeToList()( (_1 = 1, 'a', std::string("b")), i, i ));
     BOOST_CHECK_EQUAL(lst.car, 1);
     BOOST_CHECK_EQUAL(lst.cdr.car, 'a');
     BOOST_CHECK_EQUAL(lst.cdr.cdr.car, std::string("b"));
@@ -255,13 +373,13 @@
     plus<
         terminal<double>::type
       , terminal<double>::type
- >::type p = Promote::call( lit(1.f) + 2.f, i, i );
+ >::type p = Promote()( lit(1.f) + 2.f, i, i );
 
     //[ LazyMakePairTest
     int j = 0; // not used, dummy state and visitor parameter
 
- std::pair<int, double> p2 = MakePair::call( make_pair_(1, 3.14), j, j );
-
+ std::pair<int, double> p2 = MakePair()( make_pair_(1, 3.14), j, j );
+
     std::cout << p2.first << std::endl;
     std::cout << p2.second << std::endl;
     //]
@@ -269,12 +387,19 @@
     BOOST_CHECK_EQUAL(p2.first, 1);
     BOOST_CHECK_EQUAL(p2.second, 3.14);
 
- NegateInt::call(lit(1), i, i);
-#ifndef BOOST_MSVC
- SquareAndPromoteInt::call(lit(1), i, i);
-#endif
-}
+ std::pair<int, double> p3 = lazy_make_pair2::MakePair()( lazy_make_pair2::make_pair_(1, 3.14), j, j );
 
+ std::cout << p3.first << std::endl;
+ std::cout << p3.second << std::endl;
+
+ BOOST_CHECK_EQUAL(p3.first, 1);
+ BOOST_CHECK_EQUAL(p3.second, 3.14);
+
+ NegateInt()(lit(1), i, i);
+ #ifndef BOOST_MSVC
+ SquareAndPromoteInt()(lit(1), i, i);
+ #endif
+}
 
 using namespace boost::unit_test;
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/release/libs/xpressive/proto/test/lambda.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/lambda.cpp (original)
+++ branches/release/libs/xpressive/proto/test/lambda.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // lambda.hpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -10,13 +10,14 @@
 #include <boost/mpl/int.hpp>
 #include <boost/mpl/min_max.hpp>
 #include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
 #include <boost/mpl/next_prior.hpp>
 #if BOOST_VERSION < 103500
 # include <boost/spirit/fusion/sequence/at.hpp>
 # include <boost/spirit/fusion/sequence/tuple.hpp>
 namespace boost { namespace fusion { namespace result_of { using namespace meta; }}}
 #else
-# include <boost/fusion/include/tuple.hpp>
+# include <boost/fusion/tuple.hpp>
 #endif
 #include <boost/typeof/typeof.hpp>
 #include <boost/typeof/std/sstream.hpp>
@@ -26,9 +27,7 @@
 #include <boost/type_traits/add_reference.hpp>
 #include <boost/xpressive/proto/proto.hpp>
 #include <boost/xpressive/proto/context.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/fold.hpp>
-#include <boost/xpressive/proto/transform/apply.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 #include <boost/test/unit_test.hpp>
 #include <boost/test/floating_point_comparison.hpp>
 
@@ -48,76 +47,61 @@
     typedef I arity;
 };
 
-// Some custom transforms for calculating the max arity of a lambda expression
-template<typename Grammar>
-struct max_arity
- : Grammar
-{
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef typename Grammar::template apply<Expr, State, Visitor>::type arity;
- typedef typename mpl::max<arity, State>::type type;
- };
-};
-
-template<typename Grammar>
+template<typename T>
 struct placeholder_arity
- : Grammar
 {
- template<typename Expr, typename, typename>
- struct apply
- : mpl::next<typename proto::result_of::arg<Expr>::type::arity>
- {};
+ typedef typename T::arity type;
 };
 
-using proto::_;
+namespace grammar
+{
+ using namespace proto;
+ using namespace transform;
 
-// The lambda grammar, with the transforms for calculating the max arity
-struct LambdaGrammar
- : proto::or_<
- placeholder_arity< proto::terminal< placeholder<_> > >
- , proto::transform::always< proto::terminal<_>, mpl::int_<0> >
- , proto::transform::fold<
- proto::nary_expr<_, proto::vararg< max_arity< LambdaGrammar > > >
+ // The lambda grammar, with the transforms for calculating the max arity
+ struct Lambda
+ : or_<
+ when< terminal< placeholder<_> >, mpl::next<placeholder_arity<_arg> >() >
+ , when< terminal<_>, mpl::int_<0>() >
+ , when< nary_expr<_, vararg<_> >, fold<_, mpl::int_<0>(), mpl::max<Lambda,_state>()> >
>
- >
-{};
+ {};
+}
 
 // simple wrapper for calculating a lambda expression's arity.
 template<typename Expr>
 struct lambda_arity
- : LambdaGrammar::apply<Expr, mpl::int_<0>, mpl::void_>
+ : boost::result_of<grammar::Lambda(Expr, mpl::void_, mpl::void_)>
 {};
 
 // The lambda context is the same as the default context
 // with the addition of special handling for lambda placeholders
 template<typename Tuple>
 struct lambda_context
+ : proto::callable_context<lambda_context<Tuple> const>
 {
     lambda_context(Tuple const &args)
       : args_(args)
     {}
 
- template<typename Expr, typename EnableIf = void>
- struct eval
- : proto::default_eval<Expr, lambda_context<Tuple> >
+ template<typename Sig>
+ struct result;
+
+ template<typename This, typename I>
+ struct result<This(proto::tag::terminal, placeholder<I> const &)>
+ : fusion::result_of::at<Tuple, I>
     {};
 
- template<typename Expr>
- struct eval<Expr, typename enable_if<proto::matches<Expr, proto::terminal<placeholder<_> > > >::type>
+ template<typename I>
+ typename fusion::result_of::at<Tuple, I>::type
+ operator ()(proto::tag::terminal, placeholder<I> const &) const
     {
- typedef typename proto::result_of::arg<Expr>::type::arity index;
- typedef typename fusion::result_of::at<Tuple, index>::type result_type;
- result_type operator()(Expr const &expr, lambda_context<Tuple> &ctx)
- {
-#if BOOST_VERSION < 103500
- return fusion::at<index::value>(ctx.args_);
-#else
- return fusion::at<index>(ctx.args_);
-#endif
- }
- };
+ #if BOOST_VERSION < 103500
+ return fusion::at<I::value>(this->args_);
+ #else
+ return fusion::at<I>(this->args_);
+ #endif
+ }
 
     Tuple args_;
 };
@@ -139,8 +123,8 @@
       , proto::result_of::eval<T const, lambda_context<fusion::tuple<> > >
>::type nullary_type;
 
- // Define our operator() that evaluates the lambda expression.
- nullary_type operator()() const
+ // Define our operator () that evaluates the lambda expression.
+ nullary_type operator ()() const
     {
         fusion::tuple<> args;
         lambda_context<fusion::tuple<> > ctx(args);
@@ -149,7 +133,7 @@
 
     template<typename A0>
     typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &> > >::type
- operator()(A0 const &a0) const
+ operator ()(A0 const &a0) const
     {
         fusion::tuple<A0 const &> args(a0);
         lambda_context<fusion::tuple<A0 const &> > ctx(args);
@@ -158,7 +142,7 @@
 
     template<typename A0, typename A1>
     typename proto::result_of::eval<T const, lambda_context<fusion::tuple<A0 const &, A1 const &> > >::type
- operator()(A0 const &a0, A1 const &a1) const
+ operator ()(A0 const &a0, A1 const &a1) const
     {
         fusion::tuple<A0 const &, A1 const &> args(a0, a1);
         lambda_context<fusion::tuple<A0 const &, A1 const &> > ctx(args);

Added: branches/release/libs/xpressive/proto/test/make_expr.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/proto/test/make_expr.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,236 @@
+///////////////////////////////////////////////////////////////////////////////
+// make_expr.hpp
+//
+// Copyright 2008 Eric Niebler. 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)
+
+#include <sstream>
+#include <boost/version.hpp>
+#include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform.hpp>
+#if BOOST_VERSION >= 103500
+#include <boost/fusion/tuple.hpp>
+#else
+#include <boost/spirit/fusion/sequence/make_tuple.hpp>
+#endif
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+using namespace proto;
+
+template<typename E> struct ewrap;
+
+struct mydomain
+ : domain<generator<ewrap> >
+{};
+
+template<typename E> struct ewrap
+ : extends<E, ewrap<E>, mydomain>
+{
+ explicit ewrap(E const &e = E())
+ : extends<E, ewrap<E>, mydomain>(e)
+ {}
+};
+
+void test_make_expr()
+{
+ int i = 42;
+ terminal<int>::type t1 = make_expr<tag::terminal>(1);
+ terminal<int>::type t2 = make_expr<tag::terminal>(i);
+ posit<terminal<int>::type>::type p1 = make_expr<tag::posit>(1);
+ posit<terminal<int>::type>::type p2 = make_expr<tag::posit>(i);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+ ewrap<posit<ewrap<terminal<int>::type> >::type> p3 = make_expr<tag::posit, mydomain>(i);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+ ewrap<plus<
+ ewrap<posit<ewrap<terminal<int>::type> >::type>
+ , ewrap<terminal<int>::type>
+ >::type> p4 = make_expr<tag::plus>(p3, 0);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_make_expr_ref()
+{
+ int i = 42;
+ terminal<int const &>::type t1 = make_expr<tag::terminal>(boost::cref(1)); // DANGEROUS
+ terminal<int &>::type t2 = make_expr<tag::terminal>(boost::ref(i));
+ BOOST_CHECK_EQUAL(&i, &proto::arg(t2));
+ posit<terminal<int const &>::type>::type p1 = make_expr<tag::posit>(boost::cref(1)); // DANGEROUS
+ posit<terminal<int &>::type>::type p2 = make_expr<tag::posit>(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+ ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = make_expr<tag::posit, mydomain>(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+ ewrap<plus<
+ proto::ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
+ , ewrap<terminal<int>::type>
+ >::type> p4 = make_expr<tag::plus>(boost::ref(p3), 0);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_make_expr_functional()
+{
+ int i = 42;
+ terminal<int>::type t1 = functional::make_expr<tag::terminal>()(1);
+ terminal<int>::type t2 = functional::make_expr<tag::terminal>()(i);
+ posit<terminal<int>::type>::type p1 = functional::make_expr<tag::posit>()(1);
+ posit<terminal<int>::type>::type p2 = functional::make_expr<tag::posit>()(i);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+ ewrap<posit<ewrap<terminal<int>::type> >::type> p3 = functional::make_expr<tag::posit, mydomain>()(i);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+ ewrap<plus<
+ ewrap<posit<ewrap<terminal<int>::type> >::type>
+ , ewrap<terminal<int>::type>
+ >::type> p4 = functional::make_expr<tag::plus, mydomain>()(p3, 0);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_make_expr_functional_ref()
+{
+ int i = 42;
+ terminal<int const &>::type t1 = functional::make_expr<tag::terminal>()(boost::cref(1)); // DANGEROUS
+ terminal<int &>::type t2 = functional::make_expr<tag::terminal>()(boost::ref(i));
+ BOOST_CHECK_EQUAL(&i, &proto::arg(t2));
+ posit<terminal<int const &>::type>::type p1 = functional::make_expr<tag::posit>()(boost::cref(1)); // DANGEROUS
+ posit<terminal<int &>::type>::type p2 = functional::make_expr<tag::posit>()(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+ ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = functional::make_expr<tag::posit, mydomain>()(boost::ref(i));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+ ewrap<plus<
+ proto::ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
+ , ewrap<terminal<int>::type>
+ >::type> p4 = functional::make_expr<tag::plus, mydomain>()(boost::ref(p3), 0);
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_unpack_expr()
+{
+ int i = 42;
+ terminal<int>::type t1 = unpack_expr<tag::terminal>(fusion::make_tuple(1));
+ terminal<int &>::type t2 = unpack_expr<tag::terminal>(fusion::make_tuple(boost::ref(i)));
+ posit<terminal<int>::type>::type p1 = unpack_expr<tag::posit>(fusion::make_tuple(1));
+ posit<terminal<int &>::type>::type p2 = unpack_expr<tag::posit>(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+ ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = unpack_expr<tag::posit, mydomain>(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+ ewrap<plus<
+ ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
+ , ewrap<terminal<int>::type>
+ >::type> p4 = unpack_expr<tag::plus>(fusion::make_tuple(boost::ref(p3), 0));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+void test_unpack_expr_functional()
+{
+ int i = 42;
+ terminal<int>::type t1 = functional::unpack_expr<tag::terminal>()(fusion::make_tuple(1));
+ terminal<int &>::type t2 = functional::unpack_expr<tag::terminal>()(fusion::make_tuple(boost::ref(i)));
+ posit<terminal<int>::type>::type p1 = functional::unpack_expr<tag::posit>()(fusion::make_tuple(1));
+ posit<terminal<int &>::type>::type p2 = functional::unpack_expr<tag::posit>()(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p2)), 42);
+
+ ewrap<posit<ewrap<terminal<int &>::type> >::type> p3 = functional::unpack_expr<tag::posit, mydomain>()(fusion::make_tuple(boost::ref(i)));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(p3)), 42);
+
+ ewrap<plus<
+ ref_<ewrap<posit<ewrap<terminal<int &>::type> >::type> >
+ , ewrap<terminal<int>::type>
+ >::type> p4 = functional::unpack_expr<tag::plus>()(fusion::make_tuple(boost::ref(p3), 0));
+ BOOST_CHECK_EQUAL(proto::arg(proto::arg(proto::left(p4))), 42);
+}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#define _ref(x) call<_ref(x)>
+#define Minus(x) call<Minus(x)>
+#endif
+
+// Turn all terminals held by reference into ones held by value
+struct ByVal
+ : or_<
+ when<terminal<_>, _make_terminal(_arg)>
+ , when<nary_expr<_, vararg<ByVal> > >
+ >
+{};
+
+// Turn all terminals held by value into ones held by reference (not safe in general)
+struct ByRef
+ : or_<
+ when<terminal<_>, _make_terminal(_ref(_arg))>
+ , when<nary_expr<_, vararg<ByRef> > >
+ >
+{};
+
+// turn all plus nodes to minus nodes:
+struct Minus
+ : or_<
+ when<terminal<_> >
+ , when<plus<Minus, Minus>, _make_minus(Minus(_left), Minus(_right)) >
+ >
+{};
+
+struct Square
+ : or_<
+ // Not creating new terminal nodes here,
+ // so hold the existing terminals by reference:
+ when<terminal<_>, _make_multiplies(_ref(_), _ref(_))>
+ , when<plus<Square, Square> >
+ >
+{};
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#undef _ref
+#undef Minus
+#endif
+
+void test_make_expr_transform()
+{
+ int x = 0;
+ plus<
+ terminal<int>::type
+ , terminal<int>::type
+ >::type t1 = ByVal()(as_expr(1) + 1, x, x);
+
+ plus<
+ terminal<int const &>::type
+ , terminal<int const &>::type
+ >::type t2 = ByRef()(as_expr(1) + 1, x, x);
+
+ minus<
+ terminal<int>::type
+ , terminal<int const &>::type
+ >::type t3 = Minus()(as_expr(1) + 1, x, x);
+
+ plus<
+ multiplies<ref_<terminal<int>::type const>, ref_<terminal<int>::type const> >::type
+ , multiplies<ref_<terminal<int const &>::type const>, ref_<terminal<int const &>::type const> >::type
+ >::type t4 = Square()(as_expr(1) + 1, x, x);
+}
+
+using namespace unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test make_expr, unpack_expr and friends");
+
+ test->add(BOOST_TEST_CASE(&test_make_expr));
+ test->add(BOOST_TEST_CASE(&test_make_expr_ref));
+ test->add(BOOST_TEST_CASE(&test_make_expr_functional));
+ test->add(BOOST_TEST_CASE(&test_make_expr_functional_ref));
+ test->add(BOOST_TEST_CASE(&test_unpack_expr));
+ test->add(BOOST_TEST_CASE(&test_unpack_expr_functional));
+ test->add(BOOST_TEST_CASE(&test_make_expr_transform));
+
+ return test;
+}

Modified: branches/release/libs/xpressive/proto/test/matches.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/matches.cpp (original)
+++ branches/release/libs/xpressive/proto/test/matches.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // matches.hpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -11,6 +11,7 @@
 #include <boost/mpl/placeholders.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/proto/proto.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 #include <boost/test/unit_test.hpp>
 
 using namespace boost;
@@ -48,8 +49,8 @@
>
 {};
 
-terminal< std::istream & >::type const cin_ = { std::cin };
-terminal< std::ostream & >::type const cout_ = { std::cout };
+terminal< std::istream & >::type const cin_ = {std::cin};
+terminal< std::ostream & >::type const cout_ = {std::cout};
 
 struct Anything
   : or_<
@@ -130,20 +131,20 @@
     assert_matches< terminal<convertible_to<int> > >( as_arg((int_convertible())) );
     assert_matches< terminal<convertible_to<int> > >( as_expr((int_convertible())) );
 
- assert_matches< if_<is_same<proto::result_of::arg<mpl::_>, int> > >( lit(1) );
- assert_not_matches< if_<is_same<proto::result_of::arg<mpl::_>, int> > >( lit('a') );
+ assert_matches< if_<is_same<_arg, int>() > >( lit(1) );
+ assert_not_matches< if_<is_same<_arg, int>() > >( lit('a') );
 
     assert_matches<
         and_<
             terminal<_>
- , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ , if_<is_same<_arg, int>() >
>
>( lit(1) );
 
     assert_not_matches<
         and_<
             terminal<_>
- , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ , if_<is_same<_arg, int>() >
>
>( lit('a') );
 
@@ -155,10 +156,18 @@
     assert_matches< terminal<char const (&)[6]> >( as_arg("hello") );
     assert_matches< terminal<char const (&)[6]> >( as_expr("hello") );
 
+ assert_matches< terminal<char [6]> >( lit("hello") );
+ assert_matches< terminal<char [6]> >( as_arg("hello") );
+ assert_matches< terminal<char [6]> >( as_expr("hello") );
+
     assert_matches< terminal<char const (&)[N]> >( lit("hello") );
     assert_matches< terminal<char const (&)[N]> >( as_arg("hello") );
     assert_matches< terminal<char const (&)[N]> >( as_expr("hello") );
 
+ assert_matches< terminal<char [N]> >( lit("hello") );
+ assert_matches< terminal<char [N]> >( as_arg("hello") );
+ assert_matches< terminal<char [N]> >( as_expr("hello") );
+
     assert_matches< terminal<std::string> >( lit(std::string("hello")) );
     assert_matches< terminal<std::string> >( as_arg(std::string("hello")) );
     assert_matches< terminal<std::string> >( as_expr(std::string("hello")) );
@@ -201,15 +210,15 @@
 
     assert_matches<
         or_<
- if_<is_same<proto::result_of::arg<mpl::_>, char> >
- , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ if_<is_same<_arg, char>() >
+ , if_<is_same<_arg, int>() >
>
>( lit(1) );
 
     assert_not_matches<
         or_<
- if_<is_same<proto::result_of::arg<mpl::_>, char> >
- , if_<is_same<proto::result_of::arg<mpl::_>, int> >
+ if_<is_same<_arg, char>() >
+ , if_<is_same<_arg, int>() >
>
>( lit(1u) );
 
@@ -244,3 +253,4 @@
 
     return test;
 }
+

Modified: branches/release/libs/xpressive/proto/test/proto_fusion.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/proto_fusion.cpp (original)
+++ branches/release/libs/xpressive/proto/test/proto_fusion.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // proto_fusion.cpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -65,7 +65,7 @@
     {}
 
     template<typename Op>
- void operator()(Op const &op) const
+ void operator ()(Op const &op) const
     {
         this->sout_ << '(' << boost::addressof(op) << ')';
     }
@@ -75,41 +75,43 @@
 
 void test1()
 {
+ using boost::proto::flatten;
+
     std::stringstream sout;
 
     // Test for 1-way branching "tree"
     sout.str("");
- boost::fusion::for_each(!!!!(a_ >> b_), to_string(sout));
+ boost::fusion::for_each(flatten(!!!!(a_ >> b_)), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)", sout.str());
 
     // Tests for 2-way branching trees
     sout.str("");
- boost::fusion::for_each(a_ >> b_ >> c_, to_string(sout));
+ boost::fusion::for_each(flatten(a_ >> b_ >> c_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
 
     sout.str("");
- boost::fusion::for_each(a_ | b_ | c_, to_string(sout));
+ boost::fusion::for_each(flatten(a_ | b_ | c_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
 
     sout.str("");
- boost::fusion::for_each(a_ >> b_ | c_ >> d_, to_string(sout));
+ boost::fusion::for_each(flatten(a_ >> b_ | c_ >> d_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
 
     sout.str("");
- boost::fusion::for_each(a_ | b_ >> c_ | d_, to_string(sout));
+ boost::fusion::for_each(flatten(a_ | b_ >> c_ | d_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
 
     sout.str("");
- boost::fusion::for_each(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_, to_string(sout));
+ boost::fusion::for_each(flatten(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
 
     sout.str("");
- boost::fusion::for_each(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_, to_string(sout));
+ boost::fusion::for_each(flatten(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
 
     // Test for n-way branching tree
     sout.str("");
- boost::fusion::for_each(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_), to_string(sout));
+ boost::fusion::for_each(flatten(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_)), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
 }
 

Modified: branches/release/libs/xpressive/proto/test/proto_fusion_s.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/proto_fusion_s.cpp (original)
+++ branches/release/libs/xpressive/proto/test/proto_fusion_s.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // proto_fusion_s.cpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -55,7 +55,7 @@
     {}
 
     template<typename Op>
- void operator()(Op const &op) const
+ void operator ()(Op const &op) const
     {
         this->sout_ << '(' << boost::addressof(op.proto_base()) << ')';
     }
@@ -65,6 +65,8 @@
 
 void test1()
 {
+ using boost::proto::flatten;
+
     boost::proto::terminal<char>::type a_ = {'a'};
     boost::proto::terminal<char>::type b_ = {'b'};
     boost::proto::terminal<char>::type c_ = {'c'};
@@ -79,37 +81,37 @@
 
     // Test for 1-way branching "tree"
     sout.str("");
- boost::fusion::for_each_s(!!!!(a_ >> b_), to_string(sout));
+ boost::fusion::for_each_s(flatten(!!!!(a_ >> b_)), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)", sout.str());
 
     // Tests for 2-way branching trees
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ >> c_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ >> c_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ | b_ | c_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ | b_ | c_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ | c_ >> d_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ | b_ >> c_ | d_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ | b_ >> c_ | d_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
 
     // Test for n-way branching tree
     sout.str("");
- boost::fusion::for_each_s(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_), to_string(sout));
+ boost::fusion::for_each_s(flatten(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_)), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
 }
 
@@ -134,6 +136,8 @@
 
 void test2()
 {
+ using boost::proto::flatten;
+
     My<boost::proto::terminal<char>::type> a_ = {{'a'}};
     My<boost::proto::terminal<char>::type> b_ = {{'b'}};
     My<boost::proto::terminal<char>::type> c_ = {{'c'}};
@@ -148,37 +152,37 @@
 
     // Test for 1-way branching "tree"
     sout.str("");
- boost::fusion::for_each_s(!!!!(a_ >> b_), to_string(sout));
+ boost::fusion::for_each_s(flatten(!!!!(a_ >> b_)), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)", sout.str());
 
     // Tests for 2-way branching trees
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ >> c_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ >> c_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ | b_ | c_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ | b_ | c_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ | c_ >> d_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ | b_ >> c_ | d_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ | b_ >> c_ | d_), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b>>c)(d)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> f_ >> g_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f>>g)", sout.str());
 
     sout.str("");
- boost::fusion::for_each_s(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_, to_string(sout));
+ boost::fusion::for_each_s(flatten(a_ >> b_ | c_ >> d_ | e_ >> (f_ | g_) >> h_), to_string(sout));
     BOOST_CHECK_EQUAL("(a>>b)(c>>d)(e>>f|g>>h)", sout.str());
 
     // Test for n-way branching tree
     sout.str("");
- boost::fusion::for_each_s(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_), to_string(sout));
+ boost::fusion::for_each_s(flatten(a_(b_(c_ >> d_, e_ | f_), g_ >> h_)(i_)), to_string(sout));
     BOOST_CHECK_EQUAL("(a)(b)(c>>d)(e|f)(g>>h)(i)", sout.str());
 }
 

Modified: branches/release/libs/xpressive/proto/test/toy_spirit.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/toy_spirit.cpp (original)
+++ branches/release/libs/xpressive/proto/test/toy_spirit.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,12 +1,13 @@
 ///////////////////////////////////////////////////////////////////////////////
 // toy_spirit.hpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
 #include <cctype>
 #include <string>
+#include <cstring>
 #include <iostream>
 #include <boost/assert.hpp>
 #include <boost/mpl/assert.hpp>
@@ -339,95 +340,86 @@
         bool in_skip_;
     };
 
- // remove_case
- template<typename Grammar>
- struct remove_case;
-
- template<>
- struct remove_case<CharParser>
+ struct as_ichar_parser : proto::callable
     {
         typedef proto::function<
             ianychar_p
           , proto::terminal<char>::type
           , proto::terminal<char>::type
- >::type type;
+ >::type result_type;
 
         template<typename Expr>
- static type call(Expr const &expr)
+ result_type operator()(Expr const &expr) const
         {
             char lo = std::tolower(proto::arg(proto::arg_c<1>(expr)));
             char hi = std::toupper(proto::arg(proto::arg_c<1>(expr)));
- type that = {ichar_, {lo}, {hi}};
+ result_type that = {ichar_, {lo}, {hi}};
             return that;
         }
     };
 
- template<>
- struct remove_case<CharRangeParser>
+ struct as_ichar_range_parser : proto::callable
     {
         typedef proto::function<
             ianychar_range_p
           , proto::terminal<char>::type
           , proto::terminal<char>::type
- >::type type;
+ >::type result_type;
 
         template<typename Expr>
- static type call(Expr const &expr)
+ result_type operator()(Expr const &expr) const
         {
             char lo = proto::arg(proto::arg_c<1>(expr));
             char hi = proto::arg(proto::arg_c<2>(expr));
- type that = {ichar_range_, {lo}, {hi}};
+ result_type that = {ichar_range_, {lo}, {hi}};
             return that;
         }
     };
 
- template<>
- struct remove_case<CharLiteral>
+ struct as_ichar_literal : proto::callable
     {
         typedef proto::function<
             ianychar_p
           , proto::terminal<char>::type
           , proto::terminal<char>::type
- >::type type;
+ >::type result_type;
 
         template<typename Expr>
- static type call(Expr const &expr)
+ result_type operator()(Expr const &expr) const
         {
             char lo = std::tolower(proto::arg(expr));
             char hi = std::toupper(proto::arg(expr));
- type that = {ichar_, {lo}, {hi}};
+ result_type that = {ichar_, {lo}, {hi}};
             return that;
         }
     };
 
- template<>
- struct remove_case<NTBSLiteral>
+ struct as_intbs_literal : proto::callable
     {
         typedef proto::function<
             ianystr_p
           , proto::terminal<std::string>::type
- >::type type;
+ >::type result_type;
 
         template<typename Expr>
- static type call(Expr const &expr)
+ result_type operator()(Expr const &expr) const
         {
- type that = {istr_, {utility::to_istr(proto::arg(expr))}};
+ result_type that = {istr_, {utility::to_istr(proto::arg(expr))}};
             return that;
         }
     };
 
- template<>
- struct remove_case<StdStringLiteral>
+ struct as_istdstring_literal : proto::callable
     {
         typedef proto::function<
             ianystr_p
           , proto::terminal<std::string>::type
- >::type type;
+ >::type result_type;
 
         template<typename Expr>
- static type call(Expr const &expr)
+ result_type operator()(Expr const &expr) const
         {
- type that = {istr_, {utility::to_istr(proto::arg(expr).c_str())}};
+ result_type that = {istr_, {utility::to_istr(proto::arg(expr).c_str())}};
             return that;
         }
     };
@@ -436,31 +428,13 @@
     // Transforms
     ///////////////////////////////////////////////////////////////////////////
 
- template<typename Grammar>
- struct case_sensitive
- : Grammar
+ struct skip_primitives : proto::callable
     {
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : remove_case<Grammar>
- {};
+ template<typename Sig>
+ struct result;
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &, Visitor &)
- {
- return apply<Expr, State, Visitor>::call(expr);
- }
- };
-
- template<typename Grammar>
- struct skip_primitives
- : Grammar
- {
- skip_primitives();
-
- template<typename Expr, typename State, typename Visitor>
- struct apply
+ template<typename This, typename Expr, typename State, typename Visitor>
+ struct result<This(Expr, State, Visitor)>
         {
             typedef typename proto::shift_right<
                 typename proto::dereference<State>::type
@@ -469,10 +443,10 @@
         };
 
         template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
+ typename result<void(Expr, State, Visitor)>::type
+ operator()(Expr const &expr, State const &state, Visitor &visitor) const
         {
- typedef typename apply<Expr, State, Visitor>::type type;
+ typedef typename result<void(Expr, State, Visitor)>::type type;
             type that = {{state}, expr};
             return that;
         }
@@ -481,16 +455,17 @@
     ///////////////////////////////////////////////////////////////////////////
     // Grammar
     ///////////////////////////////////////////////////////////////////////////
+ using proto::_;
 
     struct SpiritGrammar;
 
     struct SpiritCaseSensitivePrimitives
       : proto::or_<
- case_sensitive<CharParser>
- , case_sensitive<CharLiteral>
- , case_sensitive<NTBSLiteral>
- , case_sensitive<CharRangeParser>
- , case_sensitive<StdStringLiteral>
+ proto::when<CharParser, as_ichar_parser(_)>
+ , proto::when<CharLiteral, as_ichar_literal(_)>
+ , proto::when<NTBSLiteral, as_intbs_literal(_)>
+ , proto::when<CharRangeParser, as_ichar_range_parser(_)>
+ , proto::when<StdStringLiteral, as_istdstring_literal(_)>
>
     {};
 
@@ -535,7 +510,7 @@
     struct SkipperGrammar
       : proto::or_<
             SpiritComposites<SkipperGrammar>
- , skip_primitives<SpiritPrimitives>
+ , proto::when<SpiritPrimitives, skip_primitives>
>
     {};
 
@@ -546,11 +521,11 @@
     struct no_case_directive
     {
         template<typename Expr>
- typename SpiritGrammar::apply<Expr, mpl::void_, mpl::void_>::type const
+ typename SpiritGrammar::result<void(Expr, mpl::void_, mpl::void_)>::type const
         operator [](Expr const &expr) const
         {
             mpl::void_ null;
- return SpiritGrammar::call(expr, null, null);
+ return SpiritGrammar()(expr, null, null);
         }
     };
 
@@ -565,11 +540,11 @@
         {}
 
         template<typename Expr>
- typename SkipperGrammar::apply<Expr, Skipper, mpl::void_>::type const
+ typename SkipperGrammar::result<void(Expr, Skipper, mpl::void_)>::type const
         operator [](Expr const &expr) const
         {
             mpl::void_ null;
- return SkipperGrammar::call(expr, this->skip_, null);
+ return SkipperGrammar()(expr, this->skip_, null);
         }
     private:
         Skipper skip_;

Modified: branches/release/libs/xpressive/proto/test/toy_spirit2.cpp
==============================================================================
--- branches/release/libs/xpressive/proto/test/toy_spirit2.cpp (original)
+++ branches/release/libs/xpressive/proto/test/toy_spirit2.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,31 +1,32 @@
 ///////////////////////////////////////////////////////////////////////////////
-// toy_spirit2.cpp
+// toy_spirit3.cpp
 //
-// Copyright 2006 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
 #include <cctype>
 #include <string>
+#include <cstring>
 #include <iomanip>
 #include <iostream>
+#include <boost/version.hpp>
 #include <boost/assert.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/utility/result_of.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/xpressive/proto/proto.hpp>
-#include <boost/xpressive/proto/transform/arg.hpp>
-#include <boost/xpressive/proto/transform/construct.hpp>
-#include <boost/xpressive/proto/transform/fold_tree.hpp>
-#include <boost/xpressive/proto/transform/list.hpp>
+#include <boost/xpressive/proto/transform.hpp>
 #if BOOST_VERSION < 103500
 # include <boost/spirit/fusion/algorithm/for_each.hpp>
 # include <boost/spirit/fusion/algorithm/fold.hpp>
 # include <boost/spirit/fusion/algorithm/any.hpp>
+# include <boost/spirit/fusion/sequence/cons.hpp>
 #else
-#include <boost/fusion/include/for_each.hpp>
-#include <boost/fusion/include/fold.hpp>
-#include <boost/fusion/include/any.hpp>
+# include <boost/fusion/include/for_each.hpp>
+# include <boost/fusion/include/fold.hpp>
+# include <boost/fusion/include/cons.hpp>
+# include <boost/fusion/include/any.hpp>
 #endif
 #include <boost/test/unit_test.hpp>
 
@@ -70,7 +71,7 @@
             FwdIter tmp = begin;
             std::string::const_iterator istr = str.begin(), estr = str.end();
             for(; istr != estr; ++tmp, istr += 2)
- if(tmp == end || *tmp != *istr && *tmp != *(istr+1))
+ if(tmp == end || (*tmp != *istr && *tmp != *(istr+1)))
                     return false;
             begin = tmp;
             return true;
@@ -101,44 +102,22 @@
         }
     } // namespace utility
 
- // Composite parser that contains a Fusion cons-list of other parsers
- // OR
- // A compiler that compiles an expression and wraps the result in
- // a composite<> wrapper
- template<typename Tag, typename List>
- struct composite
+ template<typename List>
+ struct alternate
     {
- composite(List const &list)
+ explicit alternate(List const &list)
           : elems(list)
         {}
-
         List elems;
     };
 
- template<typename Tag, typename Grammar>
- struct as_composite
- : Grammar
- {
- as_composite();
-
- // The apply<> struct and the call() member are to satisfy the
- // proto compiler/transform protocol
- template<typename Expr, typename State, typename Visitor>
- struct apply
- {
- typedef composite<
- Tag
- , typename Grammar::template apply<Expr, State, Visitor>::type
- > type;
- };
-
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return typename apply<Expr, State, Visitor>::type
- (Grammar::call(expr, state, visitor));
- }
+ template<typename List>
+ struct sequence
+ {
+ explicit sequence(List const &list)
+ : elems(list)
+ {}
+ List elems;
     };
 
     struct char_range
@@ -171,276 +150,194 @@
     struct ichar_range
       : std::pair<char, char>
     {
- ichar_range(char_range const &rng)
- : std::pair<char, char>(rng)
+ ichar_range(char from, char to)
+ : std::pair<char, char>(from, to)
         {}
     };
 
     // The no-case directive
     struct no_case_tag {};
 
- // The no-case transform, applies the tree-transform with
- // mpl::true_ as the visitor.
- template<typename Grammar>
- struct no_case_transform
- : Grammar
+ struct True : mpl::true_ {};
+
+ ///////////////////////////////////////////////////////////////////////////////
+ /// Begin Spirit grammar here
+ ///////////////////////////////////////////////////////////////////////////////
+ namespace grammar
     {
- no_case_transform();
+ using namespace proto;
+ using namespace fusion;
+ using namespace transform;
 
- template<typename Expr, typename State, typename>
- struct apply
- : Grammar::template apply<Expr, State, mpl::true_>
- {};
+ struct SpiritExpr;
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &)
- {
- mpl::true_ case_sensitive;
- return Grammar::call(expr, state, case_sensitive);
- }
- };
+ struct AnyChar
+ : terminal<char_tag>
+ {};
 
- // remove_case specializations for stripping case-sensitivity from parsers
- template<typename T, bool CaseSensitive>
- struct remove_case
- {
- typedef T type;
- template<typename U> static U const &call(U const &t)
- {
- return t;
- }
- };
+ struct CharLiteral
+ : terminal<char>
+ {};
 
- template<>
- struct remove_case<char, true>
- {
- typedef ichar type;
- static ichar call(char ch)
- {
- return ichar(ch);
- }
- };
+ struct NTBSLiteral
+ : terminal<char const *>
+ {};
 
- template<>
- struct remove_case<char const *, true>
- {
- typedef istr type;
- static istr call(char const *sz)
- {
- return istr(sz);
- }
- };
+ struct CharParser
+ : proto::function<AnyChar, CharLiteral>
+ {};
 
- template<typename T, std::size_t N>
- struct remove_case<T(&)[N], true>
- : remove_case<char const *, true>
- {};
+ struct CharRangeParser
+ : proto::function<AnyChar, CharLiteral, CharLiteral>
+ {};
 
- template<>
- struct remove_case<char_range, true>
- {
- typedef ichar_range type;
- static ichar_range call(char_range const &rng)
- {
- return ichar_range(rng);
- }
- };
+ struct NoCase
+ : terminal<no_case_tag>
+ {};
 
- // A case-sensitive transform that removes case conditionally, depending on
- // a compile-time flag carried by the visitor.
- template<typename Grammar>
- struct case_sensitive
- : Grammar
- {
- case_sensitive();
+ // The visitor determines the case-sensitivity of the terminals
+ typedef _visitor _icase;
 
- template<typename Expr, typename State, typename Visitor>
- struct apply
- : remove_case<
- typename Grammar::template apply<Expr, State, Visitor>::type
- , Visitor::value
+ // Ugh, would be nice to find a work-around for this:
+ #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+ #define _arg(x) call<_arg(x)>
+ #define True() make<True()>
+ #endif
+
+ // Extract the arg from terminals
+ struct SpiritTerminal
+ : or_<
+ when< AnyChar, _arg >
+ , when< CharLiteral, if_<_icase, ichar(_arg), _arg> >
+ , when< CharParser, if_<_icase, ichar(_arg(_arg1)), _arg(_arg1)> > // char_('a')
+ , when< NTBSLiteral, if_<_icase, istr(_arg), char const*(_arg)> >
+ , when< CharRangeParser, if_<_icase
+ , ichar_range(_arg(_arg1), _arg(_arg2))
+ , char_range(_arg(_arg1), _arg(_arg2))> > // char_('a','z')
>
         {};
 
- template<typename Expr, typename State, typename Visitor>
- static typename apply<Expr, State, Visitor>::type
- call(Expr const &expr, State const &state, Visitor &visitor)
- {
- return apply<Expr, State, Visitor>::call(Grammar::call(expr, state, visitor));
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////////
- /// Begin ToySpiritGrammar here
- ///////////////////////////////////////////////////////////////////////////////
+ struct FoldToList
+ : reverse_fold_tree<_, nil(), cons<SpiritExpr, _state>(SpiritExpr, _state)>
+ {};
 
- struct ToySpiritGrammar;
+ // sequence rule folds all >>'s together into a list
+ // and wraps the result in a sequence<> wrapper
+ struct SpiritSequence
+ : when< shift_right<SpiritExpr, SpiritExpr>, sequence<FoldToList>(FoldToList) >
+ {};
 
- struct AnyChar
- : proto::terminal<char_tag>
- {};
-
- struct CharLiteral
- : proto::terminal<char>
- {};
-
- struct NTBSLiteral
- : proto::terminal<char const *>
- {};
-
- struct CharParser
- : proto::function<AnyChar, CharLiteral>
- {};
-
- struct CharRangeParser
- : proto::function<AnyChar, CharLiteral, CharLiteral>
- {};
-
- struct NoCase
- : proto::terminal<no_case_tag>
- {};
-
- // Extract the arg from terminals
- struct ToySpiritTerminal
- : proto::or_<
- proto::transform::arg< AnyChar >
- , case_sensitive< proto::transform::arg< CharLiteral > >
- , case_sensitive< proto::transform::arg< NTBSLiteral > >
- , case_sensitive<
- proto::transform::arg< proto::transform::arg_c< CharParser, 1 > > // char_('a')
- >
- , case_sensitive<
- proto::transform::construct< // char_('a','z')
- CharRangeParser
- , char_range(
- proto::transform::arg< proto::transform::arg_c< proto::_, 1 > >
- , proto::transform::arg< proto::transform::arg_c< proto::_, 2 > >
- )
- >
- >
- >
- {};
+ // alternate rule folds all |'s together into a list
+ // and wraps the result in a alternate<> wrapper
+ struct SpiritAlternate
+ : when< bitwise_or<SpiritExpr, SpiritExpr>, alternate<FoldToList>(FoldToList) >
+ {};
 
- // sequence rule folds all >>'s together into a list
- // and wraps the result in a composite<> wrapper
- struct ToySpiritSequence
- : as_composite<
- proto::tag::shift_right
- , proto::transform::reverse_fold_tree<
- proto::tag::shift_right
- , proto::transform::list<ToySpiritGrammar>
- , fusion::nil
- >
- >
- {};
+ // Directives such as no_case are handled here
+ struct SpiritDirective
+ : when< subscript<NoCase, SpiritExpr>, SpiritExpr(_right, _state, True()) >
+ {};
 
- // alternate rule folds all |'s together into a list
- // and wraps the result in a composite<> wrapper
- struct ToySpiritAlternate
- : as_composite<
- proto::tag::bitwise_or
- , proto::transform::reverse_fold_tree<
- proto::tag::bitwise_or
- , proto::transform::list<ToySpiritGrammar>
- , fusion::nil
+ // A SpiritExpr is an alternate, a sequence, a directive or a terminal
+ struct SpiritExpr
+ : or_<
+ SpiritSequence
+ , SpiritAlternate
+ , SpiritDirective
+ , SpiritTerminal
>
- >
- {};
+ {};
 
- // Directives such as no_case are handled here
- struct ToySpiritDirective
- : no_case_transform<
- proto::transform::arg_c<
- proto::subscript< NoCase, ToySpiritGrammar >
- , 1
- >
- >
- {};
+ } // namespace grammar
 
- // A ToySpiritGrammar is an alternate, a sequence, a directive or a terminal
- struct ToySpiritGrammar
- : proto::or_<
- ToySpiritSequence
- , ToySpiritAlternate
- , ToySpiritDirective
- , ToySpiritTerminal
- >
- {};
+ using grammar::SpiritExpr;
+ using grammar::NoCase;
 
     ///////////////////////////////////////////////////////////////////////////////
- /// End ToySpiritGrammar
+ /// End SpiritExpr
     ///////////////////////////////////////////////////////////////////////////////
 
     // Globals
     NoCase::type const no_case = {{}};
 
- // Parser
- template<typename Iterator, typename Derived>
- struct with_reset
+ template<typename Iterator>
+ struct parser;
+
+ template<typename Iterator>
+ struct fold_alternate
     {
- with_reset(Iterator begin, Iterator end)
- : first(begin), second(end)
+ parser<Iterator> const &parse;
+
+ explicit fold_alternate(parser<Iterator> const &p)
+ : parse(p)
         {}
 
         template<typename T>
- bool operator()(T const &t) const
+ bool operator ()(T const &t) const
         {
- Iterator tmp = this->first;
- if((*static_cast<Derived const *>(this))(t))
+ Iterator tmp = this->parse.first;
+ if(this->parse(t))
                 return true;
- this->first = tmp;
+ this->parse.first = tmp;
             return false;
         }
-
- bool done() const
- {
- return this->first == this->second;
- }
-
- mutable Iterator first;
- Iterator second;
     };
 
     template<typename Iterator>
- struct parser
- : with_reset<Iterator, parser<Iterator> >
+ struct fold_sequence
     {
- typedef with_reset<Iterator, parser<Iterator> > with_reset;
+ parser<Iterator> const &parse;
 
- parser(Iterator begin, Iterator end)
- : with_reset(begin, end)
+ explicit fold_sequence(parser<Iterator> const &p)
+ : parse(p)
         {}
 
-#if BOOST_VERSION < 103500
- template<typename, typename> // used by fusion::fold
+ #if BOOST_VERSION < 103500
+ template<typename, typename>
         struct apply
         {
             typedef bool type;
         };
-#else
- typedef bool result_type; // used by fusion::fold
-#endif
+ #else
+ typedef bool result_type;
+ #endif
 
         template<typename T>
- bool operator()(T const &t, bool success) const // used by fusion::fold
+ bool operator ()(T const &t, bool success) const
+ {
+ return success && this->parse(t);
+ }
+ };
+
+ template<typename Iterator>
+ struct parser
+ {
+ mutable Iterator first;
+ Iterator second;
+
+ parser(Iterator begin, Iterator end)
+ : first(begin)
+ , second(end)
+ {}
+
+ bool done() const
         {
- return success && (*this)(t);
+ return this->first == this->second;
         }
 
         template<typename List>
- bool operator()(composite<proto::tag::bitwise_or, List> const &alternates) const
+ bool operator ()(alternate<List> const &alternates) const
         {
- return fusion::any(alternates.elems, *static_cast<with_reset const *>(this));
+ return fusion::any(alternates.elems, fold_alternate<Iterator>(*this));
         }
 
         template<typename List>
- bool operator()(composite<proto::tag::shift_right, List> const &sequence) const
+ bool operator ()(sequence<List> const &sequence) const
         {
- return fusion::fold(sequence.elems, true, *this);
+ return fusion::fold(sequence.elems, true, fold_sequence<Iterator>(*this));
         }
 
- bool operator()(char_tag ch) const
+ bool operator ()(char_tag ch) const
         {
             if(this->done())
                 return false;
@@ -448,7 +345,7 @@
             return true;
         }
 
- bool operator()(char ch) const
+ bool operator ()(char ch) const
         {
             if(this->done() || ch != *this->first)
                 return false;
@@ -456,7 +353,7 @@
             return true;
         }
 
- bool operator()(ichar ich) const
+ bool operator ()(ichar ich) const
         {
             if(this->done() || !utility::char_icmp(*this->first, ich.lo_, ich.hi_))
                 return false;
@@ -464,17 +361,17 @@
             return true;
         }
 
- bool operator()(char const *sz) const
+ bool operator ()(char const *sz) const
         {
             return utility::string_cmp(sz, this->first, this->second);
         }
 
- bool operator()(istr const &s) const
+ bool operator ()(istr const &s) const
         {
             return utility::string_icmp(s.str_, this->first, this->second);
         }
 
- bool operator()(char_range rng) const
+ bool operator ()(char_range rng) const
         {
             if(this->done() || !utility::in_range(*this->first, rng.first, rng.second))
                 return false;
@@ -482,7 +379,7 @@
             return true;
         }
 
- bool operator()(ichar_range rng) const
+ bool operator ()(ichar_range rng) const
         {
             if(this->done() || !utility::in_irange(*this->first, rng.first, rng.second))
                 return false;
@@ -492,20 +389,20 @@
     };
 
     template<typename Rule, typename Iterator>
- typename enable_if<proto::matches< Rule, ToySpiritGrammar >, bool >::type
+ typename enable_if<proto::matches< Rule, SpiritExpr >, bool >::type
     parse_impl(Rule const &rule, Iterator begin, Iterator end)
     {
         mpl::false_ is_case_sensitive;
         parser<Iterator> parse_fun(begin, end);
- return parse_fun(ToySpiritGrammar::call(rule, 0, is_case_sensitive));
+ return parse_fun(SpiritExpr()(rule, 0, is_case_sensitive));
     }
 
     // 2nd overload provides a short error message for invalid rules
     template<typename Rule, typename Iterator>
- typename disable_if<proto::matches< Rule, ToySpiritGrammar >, bool >::type
+ typename disable_if<proto::matches< Rule, SpiritExpr >, bool >::type
     parse_impl(Rule const &rule, Iterator begin, Iterator end)
     {
- BOOST_MPL_ASSERT((proto::matches<Rule, ToySpiritGrammar>));
+ BOOST_MPL_ASSERT((proto::matches<Rule, SpiritExpr>));
         return false;
     }
 
@@ -519,15 +416,14 @@
 
 }}
 
-using namespace boost;
-
-void test_toy_spirit2()
+void test_toy_spirit3()
 {
- using spirit2::no_case;
+ using boost::spirit2::no_case;
+ using boost::char_;
     std::string hello("abcd");
 
     BOOST_CHECK(
- spirit2::parse(
+ boost::spirit2::parse(
             "abcd"
           , hello.begin()
           , hello.end()
@@ -535,7 +431,7 @@
     );
 
     BOOST_CHECK(
- spirit2::parse(
+ boost::spirit2::parse(
             char_ >> char_('b') >> 'c' >> char_
           , hello.begin()
           , hello.end()
@@ -543,7 +439,7 @@
     );
 
     BOOST_CHECK(
- !spirit2::parse(
+ !boost::spirit2::parse(
             char_ >> char_('b') >> 'c' >> 'D'
           , hello.begin()
           , hello.end()
@@ -551,13 +447,26 @@
     );
 
     BOOST_CHECK(
- spirit2::parse(
+ boost::spirit2::parse(
             char_ >> char_('b') >> 'c' >> 'e'
           | char_ >> no_case[char_('B') >> "C" >> char_('D','Z')]
           , hello.begin()
           , hello.end()
         )
     );
+
+ std::string nest_alt_input("abd");
+ BOOST_CHECK(
+ boost::spirit2::parse(
+ char_('a')
+ >> ( char_('b')
+ | char_('c')
+ )
+ >> char_('d')
+ , nest_alt_input.begin()
+ , nest_alt_input.end()
+ )
+ );
 }
 
 using namespace boost::unit_test;
@@ -568,7 +477,7 @@
 {
     test_suite *test = BOOST_TEST_SUITE("test proto, grammars and tree transforms");
 
- test->add(BOOST_TEST_CASE(&test_toy_spirit2));
+ test->add(BOOST_TEST_CASE(&test_toy_spirit3));
 
     return test;
 }

Modified: branches/release/libs/xpressive/test/Jamfile.v2
==============================================================================
--- branches/release/libs/xpressive/test/Jamfile.v2 (original)
+++ branches/release/libs/xpressive/test/Jamfile.v2 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -13,6 +13,7 @@
         <toolset>msvc-8.0:<define>_CRT_SECURE_NO_DEPRECATE
         <toolset>msvc-9.0:<define>_SCL_SECURE_NO_DEPRECATE
         <toolset>gcc:<cxxflags>-ftemplate-depth-1024
+ <toolset>darwin:<cxxflags>-ftemplate-depth-1024
 # <toolset>gcc:<cxxflags>-W
 # <toolset>gcc:<cxxflags>-Wall
 # <toolset>msvc:<cxxflags>-W4
@@ -48,6 +49,7 @@
          [ run test11u.cpp ]
          [ run misc1.cpp ]
          [ run misc2.cpp ]
+ [ run test_format.cpp ]
          [ run test_cycles.cpp ]
          [ run test_non_char.cpp ]
          [ run test_static.cpp ]
@@ -56,6 +58,7 @@
          [ run test_symbols.cpp ]
          [ run test_dynamic.cpp ]
          [ run test_dynamic_grammar.cpp ]
+ [ run test_skip.cpp ]
          [ link multiple_defs1.cpp multiple_defs2.cpp : : multiple_defs ]
          [ compile test_basic_regex.cpp ]
          [ compile test_match_results.cpp ]

Modified: branches/release/libs/xpressive/test/misc1.cpp
==============================================================================
--- branches/release/libs/xpressive/test/misc1.cpp (original)
+++ branches/release/libs/xpressive/test/misc1.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // misc1.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/misc2.cpp
==============================================================================
--- branches/release/libs/xpressive/test/misc2.cpp (original)
+++ branches/release/libs/xpressive/test/misc2.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,15 +1,16 @@
 ///////////////////////////////////////////////////////////////////////////////
 // misc2.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
-#include <iostream>
+#include <map>
+#include <string>
 #include <boost/xpressive/xpressive.hpp>
+#include <boost/xpressive/regex_actions.hpp>
 #include <boost/test/unit_test.hpp>
 
-using namespace boost::unit_test;
 using namespace boost::xpressive;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -26,6 +27,54 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+//
+void test_static_actions_in_dynamic_keep()
+{
+ std::string result;
+ std::string str("foo");
+
+ sregex_compiler compiler;
+ compiler["rx0"] = (s1="foo")[ ref(result) = s1 ];
+ sregex rx = compiler.compile("(?>(?$rx0))");
+
+ bool ok = regex_match(str, rx);
+ BOOST_CHECK(ok);
+ BOOST_CHECK_EQUAL(result, "foo");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+void test_static_actions_in_static_keep()
+{
+ std::string result;
+ std::string str("foo");
+
+ sregex rx0 = (s1="foo")[ ref(result) = s1 ];
+ sregex rx = keep(rx0);
+
+ bool ok = regex_match(str, rx);
+ BOOST_CHECK(ok);
+ BOOST_CHECK_EQUAL(result, "foo");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+void test_replace_with_lambda()
+{
+ std::map<std::string, std::string> replacements;
+ replacements["X"] = "this";
+ replacements["Y"] = "that";
+
+ std::string input("\"$(X)\" has the value \"$(Y)\""), output;
+ std::string expected("\"this\" has the value \"that\"");
+ sregex rx = "$(" >> (s1= +~as_xpr(')')) >> ')';
+
+ output = regex_replace(input, rx, ref(replacements)[s1]);
+ BOOST_CHECK_EQUAL(output, expected);
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
 // init_unit_test_suite
 //
 test_suite* init_unit_test_suite( int argc, char* argv[] )
@@ -33,6 +82,9 @@
     test_suite *test = BOOST_TEST_SUITE("miscelaneous tests");
 
     test->add(BOOST_TEST_CASE(&test_complement));
+ test->add(BOOST_TEST_CASE(&test_static_actions_in_dynamic_keep));
+ test->add(BOOST_TEST_CASE(&test_static_actions_in_static_keep));
+ test->add(BOOST_TEST_CASE(&test_replace_with_lambda));
 
     return test;
 }

Modified: branches/release/libs/xpressive/test/multiple_defs1.cpp
==============================================================================
--- branches/release/libs/xpressive/test/multiple_defs1.cpp (original)
+++ branches/release/libs/xpressive/test/multiple_defs1.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // multiple_defs1.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/multiple_defs2.cpp
==============================================================================
--- branches/release/libs/xpressive/test/multiple_defs2.cpp (original)
+++ branches/release/libs/xpressive/test/multiple_defs2.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // multiple_defs2.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/regress.ipp
==============================================================================
--- branches/release/libs/xpressive/test/regress.ipp (original)
+++ branches/release/libs/xpressive/test/regress.ipp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -272,11 +272,26 @@
         typedef typename std::basic_string<Char>::const_iterator iterator;
         basic_regex<iterator> rx = basic_regex<iterator>::compile(test.pat, test.syntax_flags);
 
+ // Build the same regex for use with C strings
+ basic_regex<Char const *> c_rx = basic_regex<Char const *>::compile(test.pat, test.syntax_flags);
+
         if(!test.res.empty())
         {
             // test regex_replace
             std::basic_string<Char> res = regex_replace(test.str, rx, test.sub, test.match_flags);
             BOOST_CHECK_MESSAGE(res == test.res, case_ << res << " != " << test.res );
+
+ // test regex_replace with NTBS format string
+ std::basic_string<Char> res2 = regex_replace(test.str, rx, test.sub.c_str(), test.match_flags);
+ BOOST_CHECK_MESSAGE(res2 == test.res, case_ << res2 << " != " << test.res );
+
+ // test regex_replace with NTBS input string
+ std::basic_string<Char> res3 = regex_replace(test.str.c_str(), c_rx, test.sub, test.match_flags);
+ BOOST_CHECK_MESSAGE(res3 == test.res, case_ << res3 << " != " << test.res );
+
+ // test regex_replace with NTBS input string and NTBS format string
+ std::basic_string<Char> res4 = regex_replace(test.str.c_str(), c_rx, test.sub.c_str(), test.match_flags);
+ BOOST_CHECK_MESSAGE(res4 == test.res, case_ << res4 << " != " << test.res );
         }
 
         if(0 == (test.match_flags & regex_constants::format_first_only))

Modified: branches/release/libs/xpressive/test/test.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test.hpp (original)
+++ branches/release/libs/xpressive/test/test.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test1.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test1.cpp (original)
+++ branches/release/libs/xpressive/test/test1.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test1.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test1.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test1.hpp (original)
+++ branches/release/libs/xpressive/test/test1.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test1.h
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test10.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test10.cpp (original)
+++ branches/release/libs/xpressive/test/test10.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test10.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test10.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test10.hpp (original)
+++ branches/release/libs/xpressive/test/test10.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test10.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test10u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test10u.cpp (original)
+++ branches/release/libs/xpressive/test/test10u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test10.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test11.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test11.cpp (original)
+++ branches/release/libs/xpressive/test/test11.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test11.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test11.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test11.hpp (original)
+++ branches/release/libs/xpressive/test/test11.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test11.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test11u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test11u.cpp (original)
+++ branches/release/libs/xpressive/test/test11u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test11u.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test1u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test1u.cpp (original)
+++ branches/release/libs/xpressive/test/test1u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test1.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test2.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test2.cpp (original)
+++ branches/release/libs/xpressive/test/test2.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test2.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test2.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test2.hpp (original)
+++ branches/release/libs/xpressive/test/test2.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test2.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test2u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test2u.cpp (original)
+++ branches/release/libs/xpressive/test/test2u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test2.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test3.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test3.cpp (original)
+++ branches/release/libs/xpressive/test/test3.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test3.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test3.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test3.hpp (original)
+++ branches/release/libs/xpressive/test/test3.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test3.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test3u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test3u.cpp (original)
+++ branches/release/libs/xpressive/test/test3u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test3.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test4.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test4.cpp (original)
+++ branches/release/libs/xpressive/test/test4.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test4.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test4.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test4.hpp (original)
+++ branches/release/libs/xpressive/test/test4.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test4.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test4u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test4u.cpp (original)
+++ branches/release/libs/xpressive/test/test4u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test4.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test5.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test5.cpp (original)
+++ branches/release/libs/xpressive/test/test5.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test5.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test5.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test5.hpp (original)
+++ branches/release/libs/xpressive/test/test5.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test5.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test5u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test5u.cpp (original)
+++ branches/release/libs/xpressive/test/test5u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test5.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test6.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test6.cpp (original)
+++ branches/release/libs/xpressive/test/test6.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test6.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test6.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test6.hpp (original)
+++ branches/release/libs/xpressive/test/test6.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test6.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test6u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test6u.cpp (original)
+++ branches/release/libs/xpressive/test/test6u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test6.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test7.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test7.cpp (original)
+++ branches/release/libs/xpressive/test/test7.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test7.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test7.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test7.hpp (original)
+++ branches/release/libs/xpressive/test/test7.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test7.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test7u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test7u.cpp (original)
+++ branches/release/libs/xpressive/test/test7u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test7.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test8.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test8.cpp (original)
+++ branches/release/libs/xpressive/test/test8.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test8.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test8.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test8.hpp (original)
+++ branches/release/libs/xpressive/test/test8.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test8.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test8u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test8u.cpp (original)
+++ branches/release/libs/xpressive/test/test8u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test8.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test9.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test9.cpp (original)
+++ branches/release/libs/xpressive/test/test9.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test9.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test9.hpp
==============================================================================
--- branches/release/libs/xpressive/test/test9.hpp (original)
+++ branches/release/libs/xpressive/test/test9.hpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test9.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test9u.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test9u.cpp (original)
+++ branches/release/libs/xpressive/test/test9u.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test9.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_actions.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_actions.cpp (original)
+++ branches/release/libs/xpressive/test/test_actions.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_actions.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -70,10 +70,10 @@
     std::list<int> result;
     std::string str("1 23 456 7890");
 #if BOOST_VERSION >= 103500
- sregex rx = (+_d)[ xp::ref(result)->*push_back( as<int>(_) ) ]
+ sregex rx = (+_d)[ xp::ref(result)->*push_back( as<int>(_) ) ]
>> *(' ' >> (+_d)[ xp::ref(result)->*push_back( as<int>(_) ) ]);
 #else
- sregex rx = (+_d)[ push_back(xp::ref(result), as<int>(_) ) ]
+ sregex rx = (+_d)[ push_back(xp::ref(result), as<int>(_) ) ]
>> *(' ' >> (+_d)[ push_back(xp::ref(result), as<int>(_) ) ]);
 #endif
 

Modified: branches/release/libs/xpressive/test/test_assert.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_assert.cpp (original)
+++ branches/release/libs/xpressive/test/test_assert.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_assert.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -53,7 +53,7 @@
 
     mark_tag month(1), day(2);
     // find a valid date of the form month/day/year.
- sregex date =
+ sregex date =
         (
             // Month must be between 1 and 12 inclusive
             (month= _d >> !_d) [ check(as<int>(_) >= 1

Modified: branches/release/libs/xpressive/test/test_basic_regex.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_basic_regex.cpp (original)
+++ branches/release/libs/xpressive/test/test_basic_regex.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_basic_regex.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_cycles.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_cycles.cpp (original)
+++ branches/release/libs/xpressive/test/test_cycles.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_cycles.hpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_dynamic.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_dynamic.cpp (original)
+++ branches/release/libs/xpressive/test/test_dynamic.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_dynamic.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_dynamic_grammar.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_dynamic_grammar.cpp (original)
+++ branches/release/libs/xpressive/test/test_dynamic_grammar.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -68,7 +68,7 @@
             compiler["factor"] = compiler.compile( "\\d+ | (? $group ) ", x);
             compiler["term"] = compiler.compile( "(? $factor ) (?: \\* (? $factor ) | / (? $factor ) )* ", x);
             compiler["expr"] = compiler.compile( "(? $term ) (?: \\+ (? $term ) | - (? $term ) )* ", x);
-
+
             expr = compiler["expr"];
         }
 

Added: branches/release/libs/xpressive/test/test_format.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/test/test_format.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,133 @@
+///////////////////////////////////////////////////////////////////////////////
+// test_format.hpp
+//
+// Copyright 2008 Eric Niebler. 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)
+//
+// Test all the different ways to call regex_replace with a formatter.
+
+#include <map>
+#include <string>
+#include <boost/test/unit_test.hpp>
+#include <boost/xpressive/xpressive.hpp>
+
+using namespace boost::xpressive;
+
+std::map<std::string, std::string> replacements;
+
+struct format1
+{
+ template<typename BidiIter>
+ std::string operator()(match_results<BidiIter> const &what) const
+ {
+ return replacements[what[1].str()];
+ }
+};
+
+struct format2
+{
+ template<typename BidiIter, typename OutIter>
+ OutIter operator()(match_results<BidiIter> const &what, OutIter out) const
+ {
+ std::map<std::string, std::string>::const_iterator where = replacements.find(what[1].str());
+ if(where != replacements.end())
+ out = std::copy((*where).second.begin(), (*where).second.end(), out);
+ return out;
+ }
+};
+
+struct format3
+{
+ template<typename BidiIter, typename OutIter>
+ OutIter operator()(match_results<BidiIter> const &what, OutIter out, regex_constants::match_flag_type) const
+ {
+ std::map<std::string, std::string>::const_iterator where = replacements.find(what[1].str());
+ if(where != replacements.end())
+ out = std::copy((*where).second.begin(), (*where).second.end(), out);
+ return out;
+ }
+};
+
+std::string format_fun(smatch const &what)
+{
+ return replacements[what[1].str()];
+}
+
+std::string c_format_fun(cmatch const &what)
+{
+ return replacements[what[1].str()];
+}
+
+void test_main()
+{
+ replacements["X"] = "this";
+ replacements["Y"] = "that";
+
+ std::string input("\"$(X)\" has the value \"$(Y)\""), output;
+ sregex rx = sregex::compile("\\$\\(([^\\)]+)\\)");
+ cregex crx = cregex::compile("\\$\\(([^\\)]+)\\)");
+
+ std::string result("\"this\" has the value \"that\"");
+
+ output = regex_replace(input, rx, format1());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input.c_str(), crx, format1());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input, rx, format2());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input.c_str(), crx, format2());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input, rx, format3());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input.c_str(), crx, format3());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input, rx, format_fun);
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input.c_str(), crx, c_format_fun);
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input, rx, &format_fun);
+ BOOST_CHECK_EQUAL(output, result);
+
+ output = regex_replace(input.c_str(), crx, &c_format_fun);
+ BOOST_CHECK_EQUAL(output, result);
+
+ output.clear();
+ regex_replace(std::back_inserter(output), input.begin(), input.end(), rx, format1());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output.clear();
+ regex_replace(std::back_inserter(output), input.begin(), input.end(), rx, format2());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output.clear();
+ regex_replace(std::back_inserter(output), input.begin(), input.end(), rx, format2());
+ BOOST_CHECK_EQUAL(output, result);
+
+ output.clear();
+ regex_replace(std::back_inserter(output), input.begin(), input.end(), rx, format_fun);
+ BOOST_CHECK_EQUAL(output, result);
+
+ output.clear();
+ regex_replace(std::back_inserter(output), input.begin(), input.end(), rx, &format_fun);
+ BOOST_CHECK_EQUAL(output, result);
+}
+
+using namespace boost::unit_test;
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test_format");
+ test->add(BOOST_TEST_CASE(&test_main));
+ return test;
+}

Modified: branches/release/libs/xpressive/test/test_match_results.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_match_results.cpp (original)
+++ branches/release/libs/xpressive/test/test_match_results.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_match_results.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_non_char.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_non_char.cpp (original)
+++ branches/release/libs/xpressive/test/test_non_char.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_non_char.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 
@@ -80,6 +80,12 @@
         BOOST_CHECK_EQUAL(3, what.position());
         BOOST_CHECK_EQUAL(3, what.length());
     }
+
+ // test for range-based regex_replace
+ std::vector<UChar> output = regex_replace(str, urx, pattern_);
+ std::string output_(output.begin(), output.end());
+ std::string expected("foob.*rboo");
+ BOOST_CHECK_EQUAL(output_, expected);
 }
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/release/libs/xpressive/test/test_partial_match.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_partial_match.cpp (original)
+++ branches/release/libs/xpressive/test/test_partial_match.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_partial_match.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_algorithms.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_algorithms.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_algorithms.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_algorithms.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_compiler.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_compiler.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_compiler.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_compiler.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_constants.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_constants.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_constants.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_constants.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_error.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_error.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_error.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_error.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_iterator.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_iterator.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_iterator.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_iterator.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_primitives.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_primitives.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_primitives.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_primitives.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_token_iterator.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_token_iterator.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_token_iterator.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_token_iterator.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_regex_traits.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_regex_traits.cpp (original)
+++ branches/release/libs/xpressive/test/test_regex_traits.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_regex_traits.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Added: branches/release/libs/xpressive/test/test_skip.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/xpressive/test/test_skip.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -0,0 +1,96 @@
+///////////////////////////////////////////////////////////////////////////////
+// test_skip.hpp
+//
+// Copyright 2008 Eric Niebler. 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)
+
+#include <map>
+#include <iostream>
+#include <boost/xpressive/xpressive.hpp>
+#include <boost/xpressive/regex_actions.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::unit_test;
+using namespace boost::xpressive;
+
+void test1()
+{
+ std::string s = "a a b b c c";
+
+ sregex rx =
+ "a a" >>
+ skip(_s)
+ (
+ (s1= as_xpr('b')) >>
+ as_xpr('b') >>
+ *as_xpr('c') // causes backtracking
+ ) >>
+ "c c";
+
+ smatch what;
+ BOOST_CHECK( regex_match(s, what, rx) );
+
+ s = "123,456,789";
+ sregex rx2 = skip(',')(+_d);
+ BOOST_CHECK( regex_match(s, what, rx2) );
+
+ s = "foo";
+ sregex rx3 = skip(_s)(after("fo") >> 'o');
+ BOOST_CHECK( regex_search(s, what, rx3) );
+}
+
+template<typename Expr>
+void test_skip_aux(Expr const &expr)
+{
+ sregex rx = skip(_s)(expr);
+}
+
+void test_skip()
+{
+ int i=0;
+ std::map<std::string, int> syms;
+ std::locale loc;
+
+ test_skip_aux( 'a' );
+ test_skip_aux( _ );
+ test_skip_aux( +_ );
+ test_skip_aux( -+_ );
+ test_skip_aux( !_ );
+ test_skip_aux( -!_ );
+ test_skip_aux( repeat<0,42>(_) );
+ test_skip_aux( -repeat<0,42>(_) );
+ test_skip_aux( _ >> 'a' );
+ test_skip_aux( _ >> 'a' | _ );
+ test_skip_aux( _ >> 'a' | _ >> 'b' );
+ test_skip_aux( s1= _ >> 'a' | _ >> 'b' );
+ test_skip_aux( icase(_ >> 'a' | _ >> 'b') );
+ test_skip_aux( imbue(loc)(_ >> 'a' | _ >> 'b') );
+ test_skip_aux( (set='a') );
+ test_skip_aux( (set='a','b') );
+ test_skip_aux( ~(set='a') );
+ test_skip_aux( ~(set='a','b') );
+ test_skip_aux( range('a','b') );
+ test_skip_aux( ~range('a','b') );
+ test_skip_aux( set['a' | alpha] );
+ test_skip_aux( ~set['a' | alpha] );
+ test_skip_aux( before(_) );
+ test_skip_aux( ~before(_) );
+ test_skip_aux( after(_) );
+ test_skip_aux( ~after(_) );
+ test_skip_aux( keep(*_) );
+ test_skip_aux( (*_)[ref(i) = as<int>(_) + 1] );
+ test_skip_aux( (a1= syms)[ref(i) = a1 + 1] );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// init_unit_test_suite
+//
+test_suite* init_unit_test_suite( int argc, char* argv[] )
+{
+ test_suite *test = BOOST_TEST_SUITE("test skip()");
+
+ test->add(BOOST_TEST_CASE(&test1));
+
+ return test;
+}

Modified: branches/release/libs/xpressive/test/test_static.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_static.cpp (original)
+++ branches/release/libs/xpressive/test/test_static.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_static.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_sub_match.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_sub_match.cpp (original)
+++ branches/release/libs/xpressive/test/test_sub_match.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_sub_match.cpp
 //
-// Copyright 2004 Eric Niebler. Distributed under the Boost
+// Copyright 2008 Eric Niebler. 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)
 

Modified: branches/release/libs/xpressive/test/test_symbols.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_symbols.cpp (original)
+++ branches/release/libs/xpressive/test/test_symbols.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,13 +1,14 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_symbols.cpp
 //
-// Copyright 2007 David Jenkins.
-// Copyright 2007 Eric Niebler.
+// Copyright 2008 David Jenkins.
+// Copyright 2008 Eric Niebler.
 //
 // 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)
 
+#include <string>
 #include <map>
 #include <boost/version.hpp>
 #include <boost/xpressive/xpressive_static.hpp>
@@ -25,14 +26,16 @@
 {
     using namespace boost::xpressive;
 
- std::string result;
+ local<std::string> result;
     std::string str("foo bar baz foo bar baz");
     std::map<std::string,std::string> map1;
     map1["foo"] = "1";
     map1["bar"] = "2";
     map1["baz"] = "3";
 
- sregex rx = (a1=map1)[ xp::ref(result) = a1 ] >> *(' ' >> (a1=map1)[ xp::ref(result) += ',' + a1 ]);
+ sregex rx = skip(_s) (+(a1=map1)
+ [ result += if_else(length(result) > 0, ",", "") + a1 ]
+ );
 
     if(!regex_match(str, rx))
     {
@@ -40,7 +43,7 @@
     }
     else
     {
- BOOST_CHECK_EQUAL(result, "1,2,3,1,2,3");
+ BOOST_CHECK_EQUAL(result.get(), "1,2,3,1,2,3");
     }
 }
 
@@ -51,7 +54,7 @@
 {
     using namespace boost::xpressive;
 
- std::string result;
+ local<std::string> result;
     std::string str("foobarbazfoobazbazfoobazbar");
     std::map<std::string,std::string> map1;
     map1["foo"] = "1";
@@ -60,8 +63,9 @@
     map1["foobaz"] = "4";
     map1["foobazbaz"] = "5";
 
- sregex rx = (a1=map1)[ xp::ref(result) = a1 ]
- >> *((a1=map1)[ xp::ref(result) += ',', xp::ref(result) += a1 ]);
+ sregex rx = skip(_s) (+(a1=map1)
+ [ result += if_else(length(result) > 0, ",", "") + a1 ]
+ );
 
     if(!regex_match(str, rx))
     {
@@ -69,7 +73,7 @@
     }
     else
     {
- BOOST_CHECK_EQUAL(result, "1,2,3,5,4,2");
+ BOOST_CHECK_EQUAL(result.get(), "1,2,3,5,4,2");
     }
 }
 
@@ -89,11 +93,13 @@
     map1["bop"] = 7890;
 
 #if BOOST_VERSION >= 103500
- sregex rx = (a1=map1)[ xp::ref(result)->*push_back( a1 ) ]
- >> *(' ' >> (a1=map1)[ xp::ref(result)->*push_back( a1 ) ]);
+ sregex rx = skip(_s) (+(a1=map1)
+ [ xp::ref(result)->*push_back( a1 ) ]
+ );
 #else
- sregex rx = (a1=map1)[ push_back(xp::ref(result), a1 ) ]
- >> *(' ' >> (a1=map1)[ push_back(xp::ref(result), a1 ) ]);
+ sregex rx = skip(_s) (+(a1=map1)
+ [ push_back(xp::ref(result), a1 ) ]
+ );
 #endif
 
     if(!regex_match(str, rx))
@@ -155,7 +161,7 @@
 {
     using namespace boost::xpressive;
 
- int result = 0;
+ local<int> result(0);
     std::string str("abcdefghi");
     std::map<std::string,int> map1;
     std::map<std::string,int> map2;
@@ -176,16 +182,16 @@
     map8["h"] = 8;
     map9["i"] = 9;
 
- sregex rx =
- (a1=map1)[ xp::ref(result) += a1 ]
- >> (a2=map2)[ xp::ref(result) += a2 ]
- >> (a3=map3)[ xp::ref(result) += a3 ]
- >> (a4=map4)[ xp::ref(result) += a4 ]
- >> (a5=map5)[ xp::ref(result) += a5 ]
- >> (a6=map6)[ xp::ref(result) += a6 ]
- >> (a7=map7)[ xp::ref(result) += a7 ]
- >> (a8=map8)[ xp::ref(result) += a8 ]
- >> (a9=map9)[ xp::ref(result) += a9 ];
+ sregex rx =
+ (a1=map1)[ result += a1 ]
+ >> (a2=map2)[ result += a2 ]
+ >> (a3=map3)[ result += a3 ]
+ >> (a4=map4)[ result += a4 ]
+ >> (a5=map5)[ result += a5 ]
+ >> (a6=map6)[ result += a6 ]
+ >> (a7=map7)[ result += a7 ]
+ >> (a8=map8)[ result += a8 ]
+ >> (a9=map9)[ result += a9 ];
 
     if(!regex_match(str, rx))
     {
@@ -193,7 +199,7 @@
     }
     else
     {
- BOOST_CHECK_EQUAL(result, 45);
+ BOOST_CHECK_EQUAL(result.get(), 45);
     }
 }
 
@@ -204,23 +210,25 @@
 {
     using namespace boost::xpressive;
 
- std::string result;
+ local<std::string> result;
     std::map<std::string,std::string> map1;
     map1["a"] = "1";
     map1["A"] = "2";
     map1["b"] = "3";
     map1["B"] = "4";
     std::string str("a A b B a A b B");
- sregex rx = icase(a1= map1) [ xp::ref(result) = a1 ]
- >> repeat<3>( (' ' >> icase(a1= map1) [ xp::ref(result) += ',', xp::ref(result) += a1 ]) )
- >> repeat<4>( (' ' >> (a1= map1) [ xp::ref(result) += ',', xp::ref(result) += a1 ]) );
+ sregex rx = skip(_s)(
+ icase(a1= map1) [ result = a1 ]
+ >> repeat<3>( (icase(a1= map1) [ result += ',' + a1 ]) )
+ >> repeat<4>( ((a1= map1) [ result += ',' + a1 ]) )
+ );
     if(!regex_match(str, rx))
     {
         BOOST_ERROR("oops");
     }
     else
     {
- BOOST_CHECK_EQUAL(result, "1,1,3,3,1,2,3,4");
+ BOOST_CHECK_EQUAL(result.get(), "1,1,3,3,1,2,3,4");
     }
 }
 
@@ -231,7 +239,7 @@
 {
     using namespace boost::xpressive;
 
- std::string result;
+ local<std::string> result;
     std::map<std::string,std::string> map1;
     map1["a"] = "1";
     map1["b"] = "2";
@@ -239,14 +247,14 @@
     map2["c"] = "3";
     map2["d"] = "4";
     std::string str("abcde");
- sregex rx = *((a1= map1) | (a1= map2) | 'e') [ xp::ref(result) += (a1 | "9") ];
+ sregex rx = *((a1= map1) | (a1= map2) | 'e') [ result += (a1 | "9") ];
     if(!regex_match(str, rx))
     {
         BOOST_ERROR("oops");
     }
     else
     {
- BOOST_CHECK_EQUAL(result, "12349");
+ BOOST_CHECK_EQUAL(result.get(), "12349");
     }
 }
 
@@ -281,17 +289,17 @@
     }
 
     std::wstring str(L"Chicago \u041c\u043E\u0441\u043A\u0432\u0430");
- City result1, result2;
- wsregex rx = (a1= map1)[ xp::ref(result1) = a1 ] >> +_s
- >> (a1= map1)[ xp::ref(result2) = a1 ];
+ local<City> result1, result2;
+ wsregex rx = (a1= map1)[ result1 = a1 ] >> +_s
+ >> (a1= map1)[ result2 = a1 ];
     if(!regex_match(str, rx))
     {
         BOOST_ERROR("oops");
     }
     else
     {
- BOOST_CHECK_EQUAL(result1.nickname, "The Windy City");
- BOOST_CHECK_EQUAL(result2.nickname, "Moscow");
+ BOOST_CHECK_EQUAL(result1.get().nickname, "The Windy City");
+ BOOST_CHECK_EQUAL(result2.get().nickname, "Moscow");
     }
 }
 #else
@@ -312,8 +320,8 @@
     std::string str("foobar");
     std::map<std::string,int> map1;
     map1["foo"] = 1;
- int xx = 0;
- sregex rx = ~before((a1=map1)[xp::ref(xx)=a1]) >> (s1=*_w)[ xp::ref(result) = s1 ];
+ sregex rx = ~before((a1=map1)[a1]) >>
+ (s1=*_w)[ xp::ref(result) = s1 ];
     if(!regex_match(str, rx))
     {
         BOOST_CHECK_EQUAL(result, "");

Modified: branches/release/libs/xpressive/test/test_typeof.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_typeof.cpp (original)
+++ branches/release/libs/xpressive/test/test_typeof.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_typeof.cpp
 //
-// Copyright 2007 David Jenkins. Distributed under the Boost
+// Copyright 2008 David Jenkins. 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)
 

Modified: branches/release/libs/xpressive/test/test_typeof2.cpp
==============================================================================
--- branches/release/libs/xpressive/test/test_typeof2.cpp (original)
+++ branches/release/libs/xpressive/test/test_typeof2.cpp 2008-06-19 22:29:59 EDT (Thu, 19 Jun 2008)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 // test_typeof2.cpp
 //
-// Copyright 2007 David Jenkins. Distributed under the Boost
+// Copyright 2008 David Jenkins. 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)
 
@@ -43,13 +43,13 @@
     TYPEOF_TEST((+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]));
     TYPEOF_TEST((+_w)[ xp::ref(result) += _ ] >> *(' ' >> (+_w)[ xp::ref(result) += ',' + _ ]) >> repeat<4>(_));
     std::list<int> result2;
- TYPEOF_TEST((+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ]
+ TYPEOF_TEST((+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ]
>> *(' ' >> (+_d)[ xp::ref(result2)->*push_back( as<int>(_) ) ]));
     std::map<std::string, int> result3;
     TYPEOF_TEST(( (s1= +_w) >> "=>" >> (s2= +_d) )[ xp::ref(result3)[s1] = as<int>(s2) ]);
     placeholder< std::map<std::string, int> > const _map5 = {{}};
     TYPEOF_TEST(( (s1= +_w) >> "=>" >> (s2= +_d) )[ _map5[s1] = as<int>(s2) ]);
-
+
     smatch what;
     placeholder< std::map<std::string, int> > const _map6 = {{}};
     std::map<std::string, int> result6;
@@ -101,11 +101,11 @@
     std::string result;
     std::map<std::string,std::string> map10;
     TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ] >> *(' ' >> (a1=map10)[ xp::ref(result) += ',' + a1 ]));
- TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ]
+ TYPEOF_TEST((a1=map10)[ xp::ref(result) = a1 ]
>> *((a1=map10)[ xp::ref(result) += ',', xp::ref(result) += a1 ]));
     std::list<int> result12;
     std::map<std::string,int> map12;
- TYPEOF_TEST((a1=map12)[ xp::ref(result12)->*push_back( a1 ) ]
+ TYPEOF_TEST((a1=map12)[ xp::ref(result12)->*push_back( a1 ) ]
>> *(' ' >> (a1=map12)[ xp::ref(result12)->*push_back( a1 ) ]));
 
     placeholder< std::map<std::string, int> > const _map13 = {};
@@ -121,10 +121,10 @@
     std::map<std::string,int> map3a;
     TYPEOF_TEST((a1=map1a)[ xp::ref(result14) += a1 ]
>> (a2=map2a)[ xp::ref(result) += a2 ]
- >> (a3=map3a)[ xp::ref(result) += a3 ]
+ >> (a3=map3a)[ xp::ref(result) += a3 ]
         );
         {
- TYPEOF_TEST(icase(a1= map10) [ xp::ref(result) = a1 ]
+ TYPEOF_TEST(icase(a1= map10) [ xp::ref(result) = a1 ]
>> repeat<3>( (' ' >> icase(a1= map10) [ xp::ref(result) += ',', xp::ref(result) += a1 ]) )
         );
     TYPEOF_TEST(*((a1= map1a) | (a1= map2a) | 'e') [ xp::ref(result) += (a1 | "9") ]);


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk