Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62839 - in branches/release: . boost boost/algorithm/string boost/archive boost/bimap boost/config boost/detail boost/filesystem boost/functional/hash boost/fusion boost/gil boost/graph boost/integer boost/interprocess boost/intrusive boost/iostreams boost/math boost/numeric/ublas boost/program_options boost/property_tree boost/proto boost/proto/detail boost/python boost/range boost/serialization boost/signals boost/signals2 boost/spirit boost/spirit/home boost/spirit/home/karma boost/spirit/home/support boost/statechart boost/system boost/thread boost/unordered boost/utility boost/uuid boost/variant boost/wave doc libs libs/array/doc libs/array/test libs/bimap libs/config libs/filesystem libs/functional/hash libs/fusion libs/graph_parallel libs/integer libs/interprocess libs/intrusive libs/iostreams libs/math libs/mpl/doc/refmanual libs/mpl/doc/src/refmanual libs/numeric/ublas libs/numeric/ublas/doc libs/program_options libs/property_tree libs/proto/doc libs/proto/doc/reference libs/proto/doc/reference/concepts libs/python libs/range libs/range/doc libs/serialization libs/signals libs/signals2 libs/spirit libs/spirit/classic/example libs/spirit/doc libs/spirit/example libs/spirit/phoenix libs/spirit/test libs/spirit/test/qi libs/statechart libs/static_assert libs/system libs/thread libs/timer libs/unordered libs/utility libs/utility/swap/test libs/uuid libs/wave more more/getting_started people status tools tools/bcp tools/boostbook tools/build/v2 tools/build/v2/tools tools/inspect tools/jam tools/quickbook tools/regression tools/release tools/wave wiki
From: eric_at_[hidden]
Date: 2010-06-12 08:38:51


Author: eric_niebler
Date: 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
New Revision: 62839
URL: http://svn.boost.org/trac/boost/changeset/62839

Log:
Merged revisions 62736,62781,62798,62829 via svnmerge from
https://svn.boost.org/svn/boost/trunk

........
  r62736 | eric_niebler | 2010-06-10 10:07:00 -0400 (Thu, 10 Jun 2010) | 1 line
  
  capture behavior can specified on a per-domain basis. Finally
........
  r62781 | eric_niebler | 2010-06-10 21:34:42 -0400 (Thu, 10 Jun 2010) | 1 line
  
  remove requirement that Generators have proto_base_generator typedef
........
  r62798 | eric_niebler | 2010-06-11 09:49:00 -0400 (Fri, 11 Jun 2010) | 1 line
  
  attempt to fix portability regression, eliminate unnecessary is_expr instantiations
........
  r62829 | eric_niebler | 2010-06-12 00:36:24 -0400 (Sat, 12 Jun 2010) | 1 line
  
  document new domain-specific as_expr and as_child customization points
........

Added:
   branches/release/boost/proto/detail/as_expr.hpp
      - copied, changed from r62736, /trunk/boost/proto/detail/as_expr.hpp
Properties modified:
   branches/release/ (props changed)
   branches/release/INSTALL (props changed)
   branches/release/Jamroot (props changed)
   branches/release/LICENSE_1_0.txt (props changed)
   branches/release/boost/ (props changed)
   branches/release/boost-build.jam (props changed)
   branches/release/boost.css (props changed)
   branches/release/boost.png (props changed)
   branches/release/boost/algorithm/string/ (props changed)
   branches/release/boost/archive/ (props changed)
   branches/release/boost/array.hpp (props changed)
   branches/release/boost/bimap/ (props changed)
   branches/release/boost/config/ (props changed)
   branches/release/boost/config.hpp (props changed)
   branches/release/boost/detail/ (props changed)
   branches/release/boost/detail/endian.hpp (props changed)
   branches/release/boost/filesystem/ (props changed)
   branches/release/boost/functional/hash/ (props changed)
   branches/release/boost/fusion/ (props changed)
   branches/release/boost/gil/ (props changed)
   branches/release/boost/graph/ (props changed)
   branches/release/boost/integer/ (props changed)
   branches/release/boost/interprocess/ (props changed)
   branches/release/boost/intrusive/ (props changed)
   branches/release/boost/iostreams/ (props changed)
   branches/release/boost/math/ (props changed)
   branches/release/boost/numeric/ublas/ (props changed)
   branches/release/boost/program_options/ (props changed)
   branches/release/boost/property_tree/ (props changed)
   branches/release/boost/python/ (props changed)
   branches/release/boost/range/ (props changed)
   branches/release/boost/serialization/ (props changed)
   branches/release/boost/serialization/factory.hpp (props changed)
   branches/release/boost/signals/ (props changed)
   branches/release/boost/signals2/ (props changed)
   branches/release/boost/spirit/ (props changed)
   branches/release/boost/spirit/home/ (props changed)
   branches/release/boost/spirit/home/karma/ (props changed)
   branches/release/boost/spirit/home/support/attributes.hpp (props changed)
   branches/release/boost/statechart/ (props changed)
   branches/release/boost/system/ (props changed)
   branches/release/boost/thread/ (props changed)
   branches/release/boost/thread.hpp (props changed)
   branches/release/boost/unordered/ (props changed)
   branches/release/boost/utility/ (props changed)
   branches/release/boost/utility/value_init.hpp (props changed)
   branches/release/boost/uuid/ (props changed)
   branches/release/boost/variant/ (props changed)
   branches/release/boost/version.hpp (props changed)
   branches/release/boost/wave/ (props changed)
   branches/release/bootstrap.bat (props changed)
   branches/release/bootstrap.sh (props changed)
   branches/release/doc/ (props changed)
   branches/release/index.htm (props changed)
   branches/release/index.html (props changed)
   branches/release/libs/ (props changed)
   branches/release/libs/array/doc/array.xml (props changed)
   branches/release/libs/array/test/array0.cpp (props changed)
   branches/release/libs/bimap/ (props changed)
   branches/release/libs/config/ (props changed)
   branches/release/libs/filesystem/ (props changed)
   branches/release/libs/functional/hash/ (props changed)
   branches/release/libs/fusion/ (props changed)
   branches/release/libs/graph_parallel/ (props changed)
   branches/release/libs/integer/ (props changed)
   branches/release/libs/interprocess/ (props changed)
   branches/release/libs/intrusive/ (props changed)
   branches/release/libs/iostreams/ (props changed)
   branches/release/libs/libraries.htm (props changed)
   branches/release/libs/maintainers.txt (props changed)
   branches/release/libs/math/ (props changed)
   branches/release/libs/mpl/doc/refmanual/broken-compiler-workarounds.html (props changed)
   branches/release/libs/mpl/doc/refmanual/categorized-index-concepts.html (props changed)
   branches/release/libs/mpl/doc/refmanual/cfg-no-preprocessed-headers.html (props changed)
   branches/release/libs/mpl/doc/refmanual/composition-and-argument-binding.html (props changed)
   branches/release/libs/mpl/doc/refmanual/data-types-concepts.html (props changed)
   branches/release/libs/mpl/doc/refmanual/data-types-miscellaneous.html (props changed)
   branches/release/libs/mpl/doc/refmanual/extensible-associative-sequence.html (props changed)
   branches/release/libs/mpl/doc/refmanual/inserter-class.html (props changed)
   branches/release/libs/mpl/doc/refmanual/tag-dispatched-metafunction.html (props changed)
   branches/release/libs/mpl/doc/refmanual/trivial-metafunctions-summary.html (props changed)
   branches/release/libs/mpl/doc/src/refmanual/Iterators-Iterator.rst (props changed)
   branches/release/libs/numeric/ublas/ (props changed)
   branches/release/libs/numeric/ublas/doc/ (props changed)
   branches/release/libs/program_options/ (props changed)
   branches/release/libs/property_tree/ (props changed)
   branches/release/libs/python/ (props changed)
   branches/release/libs/range/ (props changed)
   branches/release/libs/range/doc/ (props changed)
   branches/release/libs/serialization/ (props changed)
   branches/release/libs/signals/ (props changed)
   branches/release/libs/signals2/ (props changed)
   branches/release/libs/spirit/ (props changed)
   branches/release/libs/spirit/classic/example/ (props changed)
   branches/release/libs/spirit/doc/ (props changed)
   branches/release/libs/spirit/example/ (props changed)
   branches/release/libs/spirit/phoenix/ (props changed)
   branches/release/libs/spirit/test/ (props changed)
   branches/release/libs/spirit/test/qi/optional.cpp (props changed)
   branches/release/libs/statechart/ (props changed)
   branches/release/libs/static_assert/ (props changed)
   branches/release/libs/system/ (props changed)
   branches/release/libs/thread/ (props changed)
   branches/release/libs/timer/ (props changed)
   branches/release/libs/unordered/ (props changed)
   branches/release/libs/utility/ (props changed)
   branches/release/libs/utility/swap.html (props changed)
   branches/release/libs/utility/swap/test/std_bitset.cpp (props changed)
   branches/release/libs/utility/value_init.htm (props changed)
   branches/release/libs/utility/value_init_test.cpp (props changed)
   branches/release/libs/uuid/ (props changed)
   branches/release/libs/wave/ (props changed)
   branches/release/more/ (props changed)
   branches/release/more/getting_started/ (props changed)
   branches/release/people/ (props changed)
   branches/release/rst.css (props changed)
   branches/release/status/ (props changed)
   branches/release/status/Jamfile.v2 (props changed)
   branches/release/tools/ (props changed)
   branches/release/tools/bcp/ (props changed)
   branches/release/tools/boostbook/ (props changed)
   branches/release/tools/build/v2/ (props changed)
   branches/release/tools/build/v2/tools/ (props changed)
   branches/release/tools/inspect/ (props changed)
   branches/release/tools/jam/ (props changed)
   branches/release/tools/quickbook/ (props changed)
   branches/release/tools/regression/ (props changed)
   branches/release/tools/release/ (props changed)
   branches/release/tools/wave/ (props changed)
   branches/release/wiki/ (props changed)
Text files modified:
   branches/release/boost/proto/args.hpp | 16 +
   branches/release/boost/proto/deep_copy.hpp | 27 +--
   branches/release/boost/proto/detail/as_expr.hpp | 242 +++++++++++++-----------------
   branches/release/boost/proto/domain.hpp | 132 +++++++++++++---
   branches/release/boost/proto/expr.hpp | 11 -
   branches/release/boost/proto/generate.hpp | 27 +++
   branches/release/boost/proto/literal.hpp | 4
   branches/release/boost/proto/make_expr.hpp | 42 ++--
   branches/release/boost/proto/proto_fwd.hpp | 34 +--
   branches/release/boost/proto/traits.hpp | 310 ++++++++--------------------------------
   branches/release/libs/proto/doc/reference.xml | 10 +
   branches/release/libs/proto/doc/reference/concepts/Domain.xml | 84 ++++++++++
   branches/release/libs/proto/doc/reference/domain.xml | 206 +++++++++++++++++++++-----
   branches/release/libs/proto/doc/reference/generate.xml | 48 +++++
   branches/release/libs/proto/doc/reference/literal.xml | 4
   branches/release/libs/proto/doc/reference/traits.xml | 131 ++++++++--------
   16 files changed, 727 insertions(+), 601 deletions(-)

Modified: branches/release/boost/proto/args.hpp
==============================================================================
--- branches/release/boost/proto/args.hpp (original)
+++ branches/release/boost/proto/args.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -11,6 +11,7 @@
     #ifndef BOOST_PROTO_ARGS_HPP_EAN_04_01_2005
     #define BOOST_PROTO_ARGS_HPP_EAN_04_01_2005
 
+ #include <iosfwd>
     #include <boost/config.hpp>
     #include <boost/detail/workaround.hpp>
     #include <boost/preprocessor/cat.hpp>
@@ -20,7 +21,10 @@
     #include <boost/preprocessor/repetition/repeat.hpp>
     #include <boost/preprocessor/repetition/repeat_from_to.hpp>
     #include <boost/type_traits/is_function.hpp>
+ #include <boost/type_traits/is_abstract.hpp>
+ #include <boost/type_traits/is_base_of.hpp>
     #include <boost/mpl/if.hpp>
+ #include <boost/mpl/or.hpp>
     #include <boost/mpl/void.hpp>
     #include <boost/proto/proto_fwd.hpp>
 
@@ -29,6 +33,16 @@
         namespace detail
         {
             /// INTERNAL ONLY
+ template<typename T>
+ struct ref_only
+ : mpl::or_<
+ is_function<T>
+ , is_abstract<T>
+ , is_base_of<std::ios_base, T>
+ >
+ {};
+
+ /// INTERNAL ONLY
             template<typename Expr>
             struct expr_traits
             {
@@ -68,7 +82,7 @@
             template<typename T>
             struct term_traits<T &>
             {
- typedef typename mpl::if_c<is_function<T>::value, T &, T>::type value_type;
+ typedef typename mpl::if_c<ref_only<T>::value, T &, T>::type value_type;
                 typedef T &reference;
                 typedef T &const_reference;
             };

Modified: branches/release/boost/proto/deep_copy.hpp
==============================================================================
--- branches/release/boost/proto/deep_copy.hpp (original)
+++ branches/release/boost/proto/deep_copy.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -14,9 +14,9 @@
     #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/type_traits/remove_reference.hpp>
     #include <boost/proto/proto_fwd.hpp>
+ #include <boost/proto/args.hpp>
     #include <boost/proto/expr.hpp>
 
     namespace boost { namespace proto
@@ -29,32 +29,21 @@
             template<typename Expr>
             struct deep_copy_impl<Expr, 0>
             {
- typedef BOOST_PROTO_UNCVREF(typename Expr::proto_child0) raw_terminal_type;
-
- // can't store a function type in a terminal.
- typedef
- typename mpl::if_c<
- is_function<raw_terminal_type>::value
- , typename Expr::proto_child0
- , raw_terminal_type
- >::type
- actual_terminal_type;
-
                 typedef
                     typename base_expr<
                         typename Expr::proto_domain
                       , tag::terminal
- , term<actual_terminal_type>
+ , term<typename term_traits<typename Expr::proto_child0>::value_type>
>::type
- expr_;
+ expr_type;
 
                 typedef typename Expr::proto_generator proto_generator;
- typedef typename proto_generator::template result<proto_generator(expr_)>::type result_type;
+ typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type;
 
                 template<typename Expr2, typename S, typename D>
                 result_type operator()(Expr2 const &e, S const &, D const &) const
                 {
- return proto_generator()(expr_::make(e.proto_base().child0));
+ return proto_generator()(expr_type::make(e.proto_base().child0));
                 }
             };
         }
@@ -203,15 +192,15 @@
                             BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_TYPE, ~)
>
>::type
- expr_;
+ expr_type;
 
                 typedef typename Expr::proto_generator proto_generator;
- typedef typename proto_generator::template result<proto_generator(expr_)>::type result_type;
+ typedef typename proto_generator::template result<proto_generator(expr_type)>::type result_type;
 
                 template<typename Expr2, typename S, typename D>
                 result_type operator()(Expr2 const &e, S const &, D const &) const
                 {
- expr_ const that = {
+ expr_type const that = {
                         BOOST_PP_ENUM(N, BOOST_PROTO_DEFINE_DEEP_COPY_FUN, ~)
                     };
 

Copied: branches/release/boost/proto/detail/as_expr.hpp (from r62736, /trunk/boost/proto/detail/as_expr.hpp)
==============================================================================
--- /trunk/boost/proto/detail/as_expr.hpp (original)
+++ branches/release/boost/proto/detail/as_expr.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -11,29 +11,82 @@
 #ifndef BOOST_PROTO_DETAIL_AS_EXPR_HPP_EAN_06_09_2010
 #define BOOST_PROTO_DETAIL_AS_EXPR_HPP_EAN_06_09_2010
 
-#include <boost/type_traits/is_same.hpp>
 #include <boost/proto/proto_fwd.hpp>
 #include <boost/proto/args.hpp>
 
 namespace boost { namespace proto { namespace detail
 {
+
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<
- typename T
- , typename Generator
- , bool IsExpr = is_expr<T>::value
- , bool WantsBasicExpr = wants_basic_expr<Generator>::value
- >
+ template<typename Generator>
+ struct base_generator
+ {
+ typedef Generator type;
+ };
+
+ template<typename Generator>
+ struct base_generator<use_basic_expr<Generator> >
+ {
+ typedef Generator type;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename T, typename Generator, bool WantsBasicExpr>
     struct as_expr;
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<
- typename T
- , typename Generator
- , bool IsExpr = is_expr<T>::value
- , bool WantsBasicExpr = wants_basic_expr<Generator>::value
- >
- struct as_child;
+ template<typename T, typename Generator>
+ struct as_expr<T, Generator, false>
+ {
+ typedef typename term_traits<T &>::value_type value_type;
+ typedef proto::expr<proto::tag::terminal, term<value_type>, 0> expr_type;
+ typedef typename Generator::template result<Generator(expr_type)>::type result_type;
+
+ result_type operator()(T &t) const
+ {
+ return Generator()(expr_type::make(t));
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename T, typename Generator>
+ struct as_expr<T, Generator, true>
+ {
+ typedef typename term_traits<T &>::value_type value_type;
+ typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> expr_type;
+ typedef typename Generator::template result<Generator(expr_type)>::type result_type;
+
+ result_type operator()(T &t) const
+ {
+ return Generator()(expr_type::make(t));
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename T>
+ struct as_expr<T, proto::default_generator, false>
+ {
+ typedef typename term_traits<T &>::value_type value_type;
+ typedef proto::expr<proto::tag::terminal, term<value_type>, 0> result_type;
+
+ result_type operator()(T &t) const
+ {
+ return result_type::make(t);
+ }
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename T>
+ struct as_expr<T, proto::default_generator, true>
+ {
+ typedef typename term_traits<T &>::value_type value_type;
+ typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> result_type;
+
+ result_type operator()(T &t) const
+ {
+ return result_type::make(t);
+ }
+ };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     template<typename Expr, typename Generator, bool SameGenerator>
@@ -52,7 +105,7 @@
     template<typename Expr, typename Generator>
     struct already_expr<Expr, Generator, true>
     {
- typedef typename Expr::proto_derived_expr result_type;
+ typedef typename Expr::proto_derived_expr result_type; // remove cv
 
         result_type operator()(Expr &e) const
         {
@@ -61,23 +114,22 @@
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename Expr, typename Generator, bool SameGenerator>
- struct already_child
+ template<typename Expr>
+ struct already_expr<Expr, default_generator, false>
     {
- typedef typename Expr::proto_derived_expr uncv_expr_type;
- typedef typename Generator::template result<Generator(uncv_expr_type)>::type result_type;
+ typedef typename Expr::proto_derived_expr result_type; // remove cv
 
         result_type operator()(Expr &e) const
         {
- return Generator()(e);
+ return e;
         }
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename Expr, typename Generator>
- struct already_child<Expr, Generator, true>
+ template<typename Expr>
+ struct already_expr<Expr, default_generator, true>
     {
- typedef Expr &result_type;
+ typedef typename Expr::proto_derived_expr result_type; // remove cv
 
         result_type operator()(Expr &e) const
         {
@@ -86,11 +138,14 @@
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
+ template<typename T, typename Generator, bool WantsBasicExpr>
+ struct as_child;
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////
     template<typename T, typename Generator>
- struct as_expr<T, Generator, false, false>
+ struct as_child<T, Generator, false>
     {
- typedef typename term_traits<T &>::value_type value_type;
- typedef proto::expr<proto::tag::terminal, term<value_type>, 0> expr_type;
+ typedef proto::expr<proto::tag::terminal, term<T &>, 0> expr_type;
         typedef typename Generator::template result<Generator(expr_type)>::type result_type;
 
         result_type operator()(T &t) const
@@ -101,10 +156,9 @@
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     template<typename T, typename Generator>
- struct as_expr<T, Generator, false, true>
+ struct as_child<T, Generator, true>
     {
- typedef typename term_traits<T &>::value_type value_type;
- typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> expr_type;
+ typedef proto::basic_expr<proto::tag::terminal, term<T &>, 0> expr_type;
         typedef typename Generator::template result<Generator(expr_type)>::type result_type;
 
         result_type operator()(T &t) const
@@ -114,37 +168,10 @@
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T, typename Generator>
- struct as_expr<T, Generator, true, false>
- : already_expr<
- T
- , Generator
- , is_same<
- typename Generator::proto_base_generator
- , typename T::proto_generator::proto_base_generator
- >::value
- >
- {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T, typename Generator>
- struct as_expr<T, Generator, true, true>
- : already_expr<
- T
- , Generator
- , is_same<
- typename Generator::proto_base_generator
- , typename T::proto_generator::proto_base_generator
- >::value
- >
- {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
     template<typename T>
- struct as_expr<T, proto::_, false, false>
+ struct as_child<T, proto::default_generator, false>
     {
- typedef typename term_traits<T &>::value_type value_type;
- typedef proto::expr<proto::tag::terminal, term<value_type>, 0> result_type;
+ typedef proto::expr<proto::tag::terminal, term<T &>, 0> result_type;
 
         result_type operator()(T &t) const
         {
@@ -154,10 +181,9 @@
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     template<typename T>
- struct as_expr<T, proto::_, false, true>
+ struct as_child<T, proto::default_generator, true>
     {
- typedef typename term_traits<T &>::value_type value_type;
- typedef proto::basic_expr<proto::tag::terminal, term<value_type>, 0> result_type;
+ typedef proto::basic_expr<proto::tag::terminal, term<T &>, 0> result_type;
 
         result_type operator()(T &t) const
         {
@@ -166,106 +192,54 @@
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T>
- struct as_expr<T, proto::_, true, false>
- : already_expr<T, proto::_, true>
- {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T>
- struct as_expr<T, proto::_, true, true>
- : already_expr<T, proto::_, true>
- {};
-
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T, typename Generator>
- struct as_child<T, Generator, false, false>
+ template<typename Expr, typename Generator, bool SameGenerator>
+ struct already_child
     {
- typedef proto::expr<proto::tag::terminal, term<T &>, 0> expr_type;
- typedef typename Generator::template result<Generator(expr_type)>::type result_type;
+ typedef typename Expr::proto_derived_expr uncv_expr_type;
+ typedef typename Generator::template result<Generator(uncv_expr_type)>::type result_type;
 
- result_type operator()(T &t) const
+ result_type operator()(Expr &e) const
         {
- return Generator()(expr_type::make(t));
+ return Generator()(e);
         }
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T, typename Generator>
- struct as_child<T, Generator, false, true>
+ template<typename Expr, typename Generator>
+ struct already_child<Expr, Generator, true>
     {
- typedef proto::basic_expr<proto::tag::terminal, term<T &>, 0> expr_type;
- typedef typename Generator::template result<Generator(expr_type)>::type result_type;
+ typedef Expr &result_type;
 
- result_type operator()(T &t) const
+ result_type operator()(Expr &e) const
         {
- return Generator()(expr_type::make(t));
+ return e;
         }
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T, typename Generator>
- struct as_child<T, Generator, true, false>
- : already_child<
- T
- , Generator
- , is_same<
- typename Generator::proto_base_generator
- , typename T::proto_generator::proto_base_generator
- >::value
- >
- {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T, typename Generator>
- struct as_child<T, Generator, true, true>
- : already_child<
- T
- , Generator
- , is_same<
- typename Generator::proto_base_generator
- , typename T::proto_generator::proto_base_generator
- >::value
- >
- {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T>
- struct as_child<T, proto::_, false, false>
+ template<typename Expr>
+ struct already_child<Expr, default_generator, false>
     {
- typedef proto::expr<proto::tag::terminal, term<T &>, 0> result_type;
+ typedef Expr &result_type;
 
- result_type operator()(T &t) const
+ result_type operator()(Expr &e) const
         {
- return result_type::make(t);
+ return e;
         }
     };
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T>
- struct as_child<T, proto::_, false, true>
+ template<typename Expr>
+ struct already_child<Expr, default_generator, true>
     {
- typedef proto::basic_expr<proto::tag::terminal, term<T &>, 0> result_type;
+ typedef Expr &result_type;
 
- result_type operator()(T &t) const
+ result_type operator()(Expr &e) const
         {
- return result_type::make(t);
+ return e;
         }
     };
 
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T>
- struct as_child<T, proto::_, true, false>
- : already_child<T, proto::_, true>
- {};
-
- ////////////////////////////////////////////////////////////////////////////////////////////////
- template<typename T>
- struct as_child<T, proto::_, true, true>
- : already_child<T, proto::_, true>
- {};
-
 }}}
 
 #endif

Modified: branches/release/boost/proto/domain.hpp
==============================================================================
--- branches/release/boost/proto/domain.hpp (original)
+++ branches/release/boost/proto/domain.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -12,7 +12,10 @@
 #define BOOST_PROTO_DOMAIN_HPP_EAN_02_13_2007
 
 #include <boost/ref.hpp>
+#include <boost/type_traits/is_same.hpp>
 #include <boost/proto/proto_fwd.hpp>
+#include <boost/proto/generate.hpp>
+#include <boost/proto/detail/as_expr.hpp>
 #include <boost/proto/detail/deduce_domain.hpp>
 
 namespace boost { namespace proto
@@ -81,7 +84,7 @@
     template<
         typename Generator // = default_generator
       , typename Grammar // = proto::_
- , typename Super // = detail::not_a_domain
+ , typename Super // = no_super_domain
>
     struct domain
       : Generator
@@ -89,9 +92,106 @@
         typedef Generator proto_generator;
         typedef Grammar proto_grammar;
         typedef Super proto_super_domain;
+ typedef domain proto_base_domain;
 
         /// INTERNAL ONLY
         typedef void proto_is_domain_;
+
+ /// \brief A unary MonomorphicFunctionObject that turns objects into Proto
+ /// expression objects in this domain.
+ ///
+ /// The <tt>as_expr\<\></tt> function object turns objects into Proto expressions, if
+ /// they are not already, by making them Proto terminals held by value if
+ /// possible. Objects that are already Proto expressions are left alone.
+ ///
+ /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr;
+ /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T:
+ ///
+ /// If \c T is not a Proto expression type the resulting terminal is
+ /// calculated as follows:
+ ///
+ /// If \c T is a function type, an abstract type, or a type derived from
+ /// \c std::ios_base, let \c A be <tt>T &</tt>.
+ /// Otherwise, let \c A be the type \c T stripped of cv-qualifiers.
+ /// Then, the result of applying <tt>as_expr\<T\>()(t)</tt> is
+ /// <tt>Generator()(E\<tag::terminal, term\<A\> \>::make(t))</tt>.
+ ///
+ /// If \c T is a Proto expression type and its generator type is different from
+ /// \c Generator, the result is <tt>Generator()(t)</tt>.
+ ///
+ /// Otherwise, the result is \c t converted to an (un-const) rvalue.
+ ///
+ template<typename T, typename IsExpr = void, typename Callable = proto::callable>
+ struct as_expr
+ : detail::as_expr<
+ T
+ , typename detail::base_generator<Generator>::type
+ , wants_basic_expr<Generator>::value
+ >
+ {
+ BOOST_PROTO_CALLABLE()
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct as_expr<T, typename T::proto_is_expr_, proto::callable>
+ : detail::already_expr<
+ T
+ , typename detail::base_generator<Generator>::type
+ , is_same<
+ typename detail::base_generator<Generator>::type
+ , typename detail::base_generator<typename T::proto_generator>::type
+ >::value
+ >
+ {
+ BOOST_PROTO_CALLABLE()
+ };
+
+ /// \brief A unary MonomorphicFunctionObject that turns objects into Proto
+ /// expression objects in this domain.
+ ///
+ /// The <tt>as_child\<\></tt> function object turns objects into Proto expressions, if
+ /// they are not already, by making them Proto terminals held by reference.
+ /// Objects that are already Proto expressions are simply returned by reference.
+ ///
+ /// If <tt>wants_basic_expr\<Generator\>::value</tt> is true, then let \c E be \c basic_expr;
+ /// otherwise, let \t E be \c expr. Given an lvalue \c t of type \c T:
+ ///
+ /// If \c T is not a Proto expression type the resulting terminal is
+ /// <tt>Generator()(E\<tag::terminal, term\<T &\> \>::make(t))</tt>.
+ ///
+ /// If \c T is a Proto expression type and its generator type is different from
+ /// \c Generator, the result is <tt>Generator()(t)</tt>.
+ ///
+ /// Otherwise, the result is the lvalue \c t.
+ ///
+ template<typename T, typename IsExpr = void, typename Callable = proto::callable>
+ struct as_child
+ : detail::as_child<
+ T
+ , typename detail::base_generator<Generator>::type
+ , wants_basic_expr<Generator>::value
+ >
+ {
+ BOOST_PROTO_CALLABLE()
+ };
+
+ /// INTERNAL ONLY
+ ///
+ template<typename T>
+ struct as_child<T, typename T::proto_is_expr_, proto::callable>
+ : detail::already_child<
+ T
+ , typename detail::base_generator<Generator>::type
+ , is_same<
+ typename detail::base_generator<Generator>::type
+ , typename detail::base_generator<typename T::proto_generator>::type
+ >::value
+ >
+ {
+ BOOST_PROTO_CALLABLE()
+ };
     };
 
     /// \brief The domain expressions have by default, if
@@ -173,26 +273,12 @@
         typedef typename domain_of<T>::type type;
     };
 
- /// \brief Tests a domain to see whether its generator would prefer
- /// to be passed instances of \c proto::basic_expr\<\> rather than
- /// \c proto::expr\<\>.
- ///
- template<typename Domain, typename Void>
- struct wants_basic_expr
- : mpl::false_
- {};
-
- template<typename Domain>
- struct wants_basic_expr<Domain, typename Domain::proto_use_basic_expr_>
- : mpl::true_
- {};
-
     /// \brief Given a domain, a tag type and an argument list,
     /// compute the type of the expression to generate. This is
     /// either an instance of \c proto::expr\<\> or
     /// \c proto::basic_expr\<\>.
     ///
- template<typename Domain, typename Tag, typename Args, typename Void>
+ template<typename Domain, typename Tag, typename Args, typename Void /*= void*/>
     struct base_expr
     {
         typedef proto::expr<Tag, Args, Args::arity> type;
@@ -201,23 +287,11 @@
     /// INTERNAL ONLY
     ///
     template<typename Domain, typename Tag, typename Args>
- struct base_expr<Domain, Tag, Args, typename Domain::proto_use_basic_expr_>
+ struct base_expr<Domain, Tag, Args, typename Domain::proto_generator::proto_use_basic_expr_>
     {
         typedef proto::basic_expr<Tag, Args, Args::arity> type;
     };
 
- /// \brief Annotate a domain to indicate that its generator would
- /// prefer to be passed instances of \c proto::basic_expr\<\> rather
- /// than \c proto::expr\<\>. <tt>use_basic_expr\<Domain\></tt> is
- /// itself a domain.
- ///
- template<typename Domain>
- struct use_basic_expr
- : Domain
- {
- BOOST_PROTO_USE_BASIC_EXPR()
- };
-
 }}
 
 #endif

Modified: branches/release/boost/proto/expr.hpp
==============================================================================
--- branches/release/boost/proto/expr.hpp (original)
+++ branches/release/boost/proto/expr.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -122,17 +122,6 @@
         #include BOOST_PP_ITERATE()
     }
 
- // TODO consider adding a basic_expr<> that doesn't have operator=,
- // operator[] or operator() for use by BOOST_PROTO_BASIC_EXTENDS().
- // Those member functions are unused in that case, and only slow
- // down instantiations. basic_expr::proto_base_expr can still be
- // expr<> because uses of proto_base_expr in proto::matches<> shouldn't
- // cause the expr<> type to be instantiated. (<-- Check that assumtion!)
- // OR, should expr<>::proto_base_expr be a typedef for basic_expr<>?
- // It should, and proto_base() can return *this reinterpret_cast to
- // a basic_expr because they should be layout compatible. Or not, because
- // that would incur an extra template instantiation. :-(
-
     namespace exprns_
     {
         // The expr<> specializations are actually defined here.

Modified: branches/release/boost/proto/generate.hpp
==============================================================================
--- branches/release/boost/proto/generate.hpp (original)
+++ branches/release/boost/proto/generate.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -18,6 +18,7 @@
     #include <boost/preprocessor/repetition/enum_params.hpp>
     #include <boost/preprocessor/repetition/enum_binary_params.hpp>
     #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+ #include <boost/mpl/bool.hpp>
     #include <boost/utility/enable_if.hpp>
     #include <boost/utility/result_of.hpp>
     #include <boost/proto/proto_fwd.hpp>
@@ -310,6 +311,32 @@
             }
         };
 
+ /// \brief Annotate a generator to indicate that it would
+ /// prefer to be passed instances of \c proto::basic_expr\<\> rather
+ /// than \c proto::expr\<\>. <tt>use_basic_expr\<Generator\></tt> is
+ /// itself a generator.
+ ///
+ template<typename Generator>
+ struct use_basic_expr
+ : Generator
+ {
+ BOOST_PROTO_USE_BASIC_EXPR()
+ };
+
+ /// \brief Tests a generator to see whether it would prefer
+ /// to be passed instances of \c proto::basic_expr\<\> rather than
+ /// \c proto::expr\<\>.
+ ///
+ template<typename Generator, typename Void>
+ struct wants_basic_expr
+ : mpl::false_
+ {};
+
+ template<typename Generator>
+ struct wants_basic_expr<Generator, typename Generator::proto_use_basic_expr_>
+ : mpl::true_
+ {};
+
         /// INTERNAL ONLY
         template<>
         struct is_callable<default_generator>

Modified: branches/release/boost/proto/literal.hpp
==============================================================================
--- branches/release/boost/proto/literal.hpp (original)
+++ branches/release/boost/proto/literal.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -34,10 +34,10 @@
           , typename Domain // = default_domain
>
         struct literal
- : extends<expr<tag::terminal, term<T>, 0>, literal<T, Domain>, Domain>
+ : extends<basic_expr<tag::terminal, term<T>, 0>, literal<T, Domain>, Domain>
         {
         private:
- typedef expr<tag::terminal, term<T>, 0> terminal_type;
+ typedef basic_expr<tag::terminal, term<T>, 0> terminal_type;
             typedef extends<terminal_type, literal<T, Domain>, Domain> base_type;
 
         public:

Modified: branches/release/boost/proto/make_expr.hpp
==============================================================================
--- branches/release/boost/proto/make_expr.hpp (original)
+++ branches/release/boost/proto/make_expr.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -71,19 +71,19 @@
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_CHILD_TYPE(Z, N, DATA) \
- typename boost::proto::detail::protoify_< \
+ typename boost::proto::detail::protoify< \
             BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 0, DATA), N) \
           , BOOST_PP_TUPLE_ELEM(3, 2, DATA) \
- >::type \
+ >::result_type \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_AS_CHILD(Z, N, DATA) \
- boost::proto::detail::protoify_< \
+ 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)) \
+ >()(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, DATA), N)) \
         /**/
 
     /// INTERNAL ONLY
@@ -136,41 +136,41 @@
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_FUSION_AS_CHILD_AT_TYPE(Z, N, DATA) \
- typename detail::protoify_< \
+ typename detail::protoify< \
             BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA) \
           , Domain \
- >::type \
+ >::result_type \
         /**/
 
     /// INTERNAL ONLY
     ///
     #define BOOST_PROTO_FUSION_AS_CHILD_AT(Z, N, DATA) \
- detail::protoify_< \
+ detail::protoify< \
             BOOST_PROTO_FUSION_AT_TYPE(Z, N, DATA) \
           , Domain \
- >::call(BOOST_PROTO_FUSION_AT(Z, N, DATA)) \
+ >()(BOOST_PROTO_FUSION_AT(Z, N, DATA)) \
         /**/
 
         namespace detail
         {
             template<typename T, typename Domain>
- struct protoify_
- : result_of::as_expr<T, Domain>
+ struct protoify
+ : Domain::template as_expr<T>
             {};
 
             template<typename T, typename Domain>
- struct protoify_<T &, Domain>
- : result_of::as_child<T, Domain>
+ struct protoify<T &, Domain>
+ : Domain::template as_child<T>
             {};
 
             template<typename T, typename Domain>
- struct protoify_<boost::reference_wrapper<T>, Domain>
- : result_of::as_child<T, Domain>
+ struct protoify<boost::reference_wrapper<T>, Domain>
+ : Domain::template as_child<T>
             {};
 
             template<typename T, typename Domain>
- struct protoify_<boost::reference_wrapper<T> const, Domain>
- : result_of::as_child<T, Domain>
+ struct protoify<boost::reference_wrapper<T> const, Domain>
+ : Domain::template as_child<T>
             {};
 
             template<typename Tag, typename Domain, typename Sequence, std::size_t Size>
@@ -189,15 +189,15 @@
                 terminal_type;
 
                 typedef
- typename proto::detail::protoify_<
+ typename proto::detail::protoify<
                         terminal_type
                       , Domain
- >::type
+ >::result_type
                 type;
 
                 static type const call(Sequence const &sequence)
                 {
- return proto::detail::protoify_<terminal_type, Domain>::call(fusion::at_c<0>(sequence));
+ return proto::detail::protoify<terminal_type, Domain>()(fusion::at_c<0>(sequence));
                 }
             };
 
@@ -223,11 +223,11 @@
             struct make_expr_<tag::terminal, Domain, A
                 BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PROTO_MAX_ARITY, void BOOST_PP_INTERCEPT)>
             {
- typedef typename proto::detail::protoify_<A, Domain>::type result_type;
+ typedef typename proto::detail::protoify<A, Domain>::result_type result_type;
 
                 result_type operator()(typename add_reference<A>::type a) const
                 {
- return proto::detail::protoify_<A, Domain>::call(a);
+ return proto::detail::protoify<A, Domain>()(a);
                 }
             };
 

Modified: branches/release/boost/proto/proto_fwd.hpp
==============================================================================
--- branches/release/boost/proto/proto_fwd.hpp (original)
+++ branches/release/boost/proto/proto_fwd.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -251,11 +251,19 @@
     template<typename First, typename Second>
     struct compose_generators;
 
+ template<typename Generator, typename Void = void>
+ struct wants_basic_expr;
+
+ template<typename Generator>
+ struct use_basic_expr;
+
     ////////////////////////////////////////////////////////////////////////////////////////////////
+ typedef detail::not_a_domain no_super_domain;
+
     template<
         typename Generator = default_generator
       , typename Grammar = proto::_
- , typename Super = detail::not_a_domain
+ , typename Super = no_super_domain
>
     struct domain;
 
@@ -263,15 +271,9 @@
 
     struct deduce_domain;
 
- template<typename Domain, typename Void = void>
- struct wants_basic_expr;
-
     template<typename Domain, typename Tag, typename Args, typename Void = void>
     struct base_expr;
 
- template<typename Domain>
- struct use_basic_expr;
-
     ////////////////////////////////////////////////////////////////////////////////////////////////
     namespace exprns_
     {
@@ -363,24 +365,10 @@
 
     namespace result_of
     {
- template<
- typename T
- , typename Domain = default_domain
- , typename Void = void
- #ifdef BOOST_PROTO_BROKEN_PTS
- , typename Void2 = void
- #endif
- >
+ template<typename T, typename Domain = default_domain>
         struct as_expr;
 
- template<
- typename T
- , typename Domain = default_domain
- , typename Void = void
- #ifdef BOOST_PROTO_BROKEN_PTS
- , typename Void2 = void
- #endif
- >
+ template<typename T, typename Domain = default_domain>
         struct as_child;
 
         template<typename Expr, typename N = mpl::long_<0> >

Modified: branches/release/boost/proto/traits.hpp
==============================================================================
--- branches/release/boost/proto/traits.hpp (original)
+++ branches/release/boost/proto/traits.hpp 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -17,31 +17,20 @@
     #include <boost/preprocessor/iteration/iterate.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_trailing_params.hpp>
     #include <boost/preprocessor/repetition/repeat.hpp>
     #include <boost/preprocessor/repetition/repeat_from_to.hpp>
     #include <boost/preprocessor/facilities/intercept.hpp>
     #include <boost/preprocessor/arithmetic/sub.hpp>
- #include <boost/ref.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/mpl/or.hpp>
+ #include <boost/static_assert.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/utility/enable_if.hpp>
     #include <boost/type_traits/is_pod.hpp>
     #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/is_function.hpp>
- #include <boost/type_traits/remove_cv.hpp>
- #include <boost/type_traits/add_reference.hpp>
     #include <boost/proto/proto_fwd.hpp>
     #include <boost/proto/args.hpp>
- #include <boost/proto/tags.hpp>
- #include <boost/proto/generate.hpp>
+ #include <boost/proto/domain.hpp>
     #include <boost/proto/transform/pass_through.hpp>
 
     #if BOOST_WORKAROUND( BOOST_MSVC, >= 1400 )
@@ -237,211 +226,18 @@
         {
             /// \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 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>boost::result_of\<Domain(expr\< tag::terminal, term\<A\> \>)\>::type</tt>.
- template<
- typename T
- , typename Domain // = default_domain
- , typename Void // = void
- #ifdef BOOST_PROTO_BROKEN_PTS
- , typename Void2 // = void
- #endif
- >
+ template<typename T, typename Domain /*= default_domain*/>
             struct as_expr
             {
- typedef
- typename mpl::eval_if_c<
- is_function<T>::value
- , add_reference<T>
- , remove_cv<T>
- >::type
- arg0_;
- typedef typename base_expr<Domain, proto::tag::terminal, term<arg0_> >::type expr_;
- typedef typename Domain::proto_generator proto_generator;
- typedef typename proto_generator::template result<Domain(expr_)>::type type;
- typedef type const reference;
-
- /// INTERNAL ONLY
- ///
- template<typename T2>
- static reference call(T2 &t)
- {
- return proto_generator()(expr_::make(static_cast<T &>(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_
- #ifdef BOOST_PROTO_BROKEN_PTS
- , typename disable_if<is_same<Domain, typename T::proto_domain> >::type
- #endif
- >
- {
- typedef typename T::proto_derived_expr expr_; // removes the const
- typedef typename Domain::proto_generator proto_generator;
- typedef typename proto_generator::template result<proto_generator(expr_)>::type type;
- typedef type const reference;
-
- /// INTERNAL ONLY
- ///
- template<typename T2>
- static reference call(T2 &t)
- {
- return proto_generator()(static_cast<T &>(t));
- }
- };
-
- template<typename T>
- struct as_expr<
- T
- , typename T::proto_domain
- , typename T::proto_is_expr_
- #ifdef BOOST_PROTO_BROKEN_PTS
- , void
- #endif
- >
- {
- typedef typename T::proto_derived_expr type; // removes the const
- typedef T &reference;
-
- /// INTERNAL ONLY
- ///
- template<typename T2>
- static reference call(T2 &t)
- {
- return t;
- }
+ typedef typename Domain::template as_expr<T>::result_type type;
             };
 
             /// \brief A metafunction that computes the return type of the \c as_child()
             /// function.
- ///
- /// The <tt>as_child\<\></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 returned by reference.
- ///
- /// This specialization is selected when the type is not yet a Proto type.
- /// The result type <tt>as_child\<T, Domain\>::type</tt> is
- /// <tt>boost::result_of\<Domain(expr\< tag::terminal, term\<T &\> \>)\>::type</tt>.
- template<
- typename T
- , typename Domain // = default_domain
- , typename Void // = void
- #ifdef BOOST_PROTO_BROKEN_PTS
- , typename Void2 // = void
- #endif
- >
+ template<typename T, typename Domain /*= default_domain*/>
             struct as_child
             {
- typedef typename base_expr<Domain, proto::tag::terminal, term<T &> >::type expr_;
- typedef typename Domain::proto_generator proto_generator;
- typedef typename proto_generator::template result<proto_generator(expr_)>::type type;
-
- /// INTERNAL ONLY
- ///
- template<typename T2>
- static type call(T2 &t)
- {
- return proto_generator()(expr_::make(static_cast<T &>(t)));
- }
- };
-
- /// \brief A metafunction that computes the return type of the \c as_child()
- /// function.
- ///
- /// The <tt>as_child\<\></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 returned by reference.
- ///
- /// This specialization is selected when the type is already a Proto type.
- /// The result type <tt>as_child\<T, Domain\>::type</tt> is
- /// <tt>T &</tt>.
- template<typename T, typename Domain>
- struct as_child<
- T
- , Domain
- , typename T::proto_is_expr_
- #ifdef BOOST_PROTO_BROKEN_PTS
- , typename disable_if<is_same<Domain, typename T::proto_domain> >::type
- #endif
- >
- {
- typedef typename Domain::proto_generator proto_generator;
- // BUGBUG should be able to hold this guy by reference, no?
- #if BOOST_WORKAROUND(BOOST_MSVC, == 1310) || \
- BOOST_WORKAROUND(BOOST_INTEL, BOOST_TESTED_AT(1010))
- // These compilers don't strip top-level cv qualifiers
- // on arguments in function types
- typedef
- typename proto_generator::template result<
- proto_generator(typename T::proto_derived_expr)
- >::type
- type;
- #else
- typedef typename proto_generator::template result<proto_generator(T)>::type type;
- #endif
-
- /// INTERNAL ONLY
- ///
- template<typename T2>
- static type call(T2 &t)
- {
- return proto_generator()(static_cast<T &>(t));
- }
- };
-
- /// \brief A metafunction that computes the return type of the \c as_child()
- /// function.
- ///
- /// The <tt>as_child\<\></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 returned by reference.
- ///
- /// This specialization is selected when the type is already a Proto type.
- /// The result type <tt>as_child\<T, Domain\>::type</tt> is
- /// <tt>T &</tt>.
- template<typename T>
- struct as_child<
- T
- , typename T::proto_domain
- , typename T::proto_is_expr_
- #ifdef BOOST_PROTO_BROKEN_PTS
- , void
- #endif
- >
- {
- typedef T &type;
-
- /// INTERNAL ONLY
- ///
- template<typename T2>
- static type call(T2 &t)
- {
- return static_cast<T &>(t);
- }
+ typedef typename Domain::template as_child<T>::result_type type;
             };
 
             /// \brief A metafunction that returns the type of the Nth child
@@ -460,6 +256,9 @@
             template<typename Expr>
             struct value
             {
+ /// Verify that we are actually operating on a terminal
+ BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+
                 /// The raw type of the Nth child as it is stored within
                 /// \c Expr. This may be a value or a reference
                 typedef typename Expr::proto_child0 value_type;
@@ -479,6 +278,9 @@
             template<typename Expr>
             struct value<Expr &>
             {
+ /// Verify that we are actually operating on a terminal
+ BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+
                 /// The raw type of the Nth child as it is stored within
                 /// \c Expr. This may be a value or a reference
                 typedef typename Expr::proto_child0 value_type;
@@ -498,6 +300,9 @@
             template<typename Expr>
             struct value<Expr const &>
             {
+ /// Verify that we are actually operating on a terminal
+ BOOST_STATIC_ASSERT(0 == Expr::proto_arity_c);
+
                 /// The raw type of the Nth child as it is stored within
                 /// \c Expr. This may be a value or a reference
                 typedef typename Expr::proto_child0 value_type;
@@ -514,10 +319,6 @@
                 typedef typename detail::term_traits<typename Expr::proto_child0>::const_reference type;
             };
 
- // TODO left<> and right<> force the instantiation of Expr.
- // Couldn't we partially specialize them on proto::expr< T, A >
- // and return A::child0 / A::child1?
-
             /// \brief A metafunction that returns the type of the left child
             /// of a binary Proto expression.
             ///
@@ -814,47 +615,49 @@
 
                 template<typename This, typename T>
                 struct result<This(T)>
- : result_of::as_expr<T, Domain>
- {};
+ {
+ typedef typename Domain::template as_expr<T>::result_type type;
+ };
 
                 template<typename This, typename T>
                 struct result<This(T &)>
- : result_of::as_expr<T, Domain>
- {};
+ {
+ typedef typename Domain::template as_expr<T>::result_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>::reference
+ typename result<as_expr(T &)>::type
                 operator ()(T &t) const
                 {
- return result_of::as_expr<T, Domain>::call(t);
+ return typename Domain::template as_expr<T>()(t);
                 }
 
                 /// \overload
                 ///
                 template<typename T>
- typename result_of::as_expr<T const, Domain>::reference
+ typename result<as_expr(T const &)>::type
                 operator ()(T const &t) const
                 {
- return result_of::as_expr<T const, Domain>::call(t);
+ return typename Domain::template as_expr<T const>()(t);
                 }
 
                 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
                 template<typename T, std::size_t N_>
- typename result_of::as_expr<T[N_], Domain>::reference
+ typename result<as_expr(T (&)[N_])>::type
                 operator ()(T (&t)[N_]) const
                 {
- return result_of::as_expr<T[N_], Domain>::call(t);
+ return typename Domain::template as_expr<T[N_]>()(t);
                 }
 
                 template<typename T, std::size_t N_>
- typename result_of::as_expr<T const[N_], Domain>::reference
+ typename result<as_expr(T const (&)[N_])>::type
                 operator ()(T const (&t)[N_]) const
                 {
- return result_of::as_expr<T const[N_], Domain>::call(t);
+ return typename Domain::template as_expr<T const[N_]>()(t);
                 }
                 #endif
             };
@@ -871,32 +674,34 @@
 
                 template<typename This, typename T>
                 struct result<This(T)>
- : result_of::as_child<T, Domain>
- {};
+ {
+ typedef typename Domain::template as_child<T>::result_type type;
+ };
 
                 template<typename This, typename T>
                 struct result<This(T &)>
- : result_of::as_child<T, Domain>
- {};
+ {
+ typedef typename Domain::template as_child<T>::result_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_child\<Domain\>(t)</tt>
                 template<typename T>
- typename result_of::as_child<T, Domain>::type
+ typename result<as_child(T &)>::type
                 operator ()(T &t) const
                 {
- return result_of::as_child<T, Domain>::call(t);
+ return typename Domain::template as_child<T>()(t);
                 }
 
                 /// \overload
                 ///
                 template<typename T>
- typename result_of::as_child<T const, Domain>::type
+ typename result<as_child(T const &)>::type
                 operator ()(T const &t) const
                 {
- return result_of::as_child<T const, Domain>::call(t);
+ return typename Domain::template as_child<T const>()(t);
                 }
             };
 
@@ -1118,37 +923,37 @@
         ///
         /// \param t The object to wrap.
         template<typename T>
- typename result_of::as_expr<T>::reference
+ typename result_of::as_expr<T, default_domain>::type
         as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
         {
- return result_of::as_expr<T>::call(t);
+ return default_domain::as_expr<T>()(t);
         }
 
         /// \overload
         ///
         template<typename T>
- typename result_of::as_expr<T const>::reference
+ typename result_of::as_expr<T const, default_domain>::type
         as_expr(T const &t)
         {
- return result_of::as_expr<T const>::call(t);
+ return default_domain::as_expr<T const>()(t);
         }
 
         /// \overload
         ///
         template<typename Domain, typename T>
- typename result_of::as_expr<T, Domain>::reference
+ typename result_of::as_expr<T, Domain>::type
         as_expr(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
         {
- return result_of::as_expr<T, Domain>::call(t);
+ return typename Domain::template as_expr<T>()(t);
         }
 
         /// \overload
         ///
         template<typename Domain, typename T>
- typename result_of::as_expr<T const, Domain>::reference
+ typename result_of::as_expr<T const, Domain>::type
         as_expr(T const &t)
         {
- return result_of::as_expr<T const, Domain>::call(t);
+ return typename Domain::template as_expr<T const>()(t);
         }
 
         /// \brief A function that wraps non-Proto expression types in Proto
@@ -1171,19 +976,19 @@
         ///
         /// \param t The object to wrap.
         template<typename T>
- typename result_of::as_child<T>::type
+ typename result_of::as_child<T, default_domain>::type
         as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
         {
- return result_of::as_child<T>::call(t);
+ return default_domain::as_child<T>()(t);
         }
 
         /// \overload
         ///
         template<typename T>
- typename result_of::as_child<T const>::type
+ typename result_of::as_child<T const, default_domain>::type
         as_child(T const &t)
         {
- return result_of::as_child<T const>::call(t);
+ return default_domain::as_child<T const>()(t);
         }
 
         /// \overload
@@ -1192,7 +997,7 @@
         typename result_of::as_child<T, Domain>::type
         as_child(T &t BOOST_PROTO_DISABLE_IF_IS_CONST(T) BOOST_PROTO_DISABLE_IF_IS_FUNCTION(T))
         {
- return result_of::as_child<T, Domain>::call(t);
+ return typename Domain::template as_child<T>()(t);
         }
 
         /// \overload
@@ -1201,7 +1006,7 @@
         typename result_of::as_child<T const, Domain>::type
         as_child(T const &t)
         {
- return result_of::as_child<T const, Domain>::call(t);
+ return typename Domain::template as_child<T const>()(t);
         }
 
         /// \brief Return the Nth child of the specified Proto expression.
@@ -1506,6 +1311,9 @@
             template<typename Expr>
             struct child_c<Expr, N>
             {
+ /// Verify that we are not operating on a terminal
+ BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
                 /// The raw type of the Nth child as it is stored within
                 /// \c Expr. This may be a value or a reference
                 typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
@@ -1521,6 +1329,9 @@
             template<typename Expr>
             struct child_c<Expr &, N>
             {
+ /// Verify that we are not operating on a terminal
+ BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
                 /// The raw type of the Nth child as it is stored within
                 /// \c Expr. This may be a value or a reference
                 typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;
@@ -1543,6 +1354,9 @@
             template<typename Expr>
             struct child_c<Expr const &, N>
             {
+ /// Verify that we are not operating on a terminal
+ BOOST_STATIC_ASSERT(0 != Expr::proto_arity_c);
+
                 /// The raw type of the Nth child as it is stored within
                 /// \c Expr. This may be a value or a reference
                 typedef typename Expr::BOOST_PP_CAT(proto_child, N) value_type;

Modified: branches/release/libs/proto/doc/reference.xml
==============================================================================
--- branches/release/libs/proto/doc/reference.xml (original)
+++ branches/release/libs/proto/doc/reference.xml 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -222,6 +222,16 @@
       </listitem>
       <listitem>
         <computeroutput>
+ <classname alt="boost::proto::domain::as_child">proto::domain::as_child</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
+ <classname alt="boost::proto::domain::as_expr">proto::domain::as_expr</classname>
+ </computeroutput>
+ </listitem>
+ <listitem>
+ <computeroutput>
           <classname alt="boost::proto::domain_of">proto::domain_of</classname>
         </computeroutput>
       </listitem>

Modified: branches/release/libs/proto/doc/reference/concepts/Domain.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/concepts/Domain.xml (original)
+++ branches/release/libs/proto/doc/reference/concepts/Domain.xml 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -9,6 +9,7 @@
   -->
   <param name="Domain" role="domain-type" />
   <param name="Expr" role="expression-type" />
+ <param name="Object" role="object-type" />
 
   <models-sentence>
     The type <arg num="1" /> must be a model of <self/>. It also
@@ -41,6 +42,12 @@
     </sample-value>
   </notation>
 
+ <notation variables="o">
+ <sample-value>
+ <type name="Object" />
+ </sample-value>
+ </notation>
+
   <associated-type name="proto_grammar">
     <get-member-type name="proto_grammar">
       <type name="Domain"/>
@@ -89,11 +96,50 @@
         the specified expression type. The result is required to
         model <conceptname>Expr</conceptname>. The domain type
         associated with <computeroutput>result_type</computeroutput>
+ (<computeroutput>result_type::proto_domain</computeroutput>)
         is required to be the same type as this Domain.
       </simpara>
     </description>
   </associated-type>
 
+ <associated-type name="as_expr_result_type">
+ <get-member-type name="result_type">
+ <apply-template name="Domain::as_expr">
+ <type name="Object"/>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>
+ The result of converting some type to a Proto expression
+ type in this domain. This is used, for instance, when
+ calculating the type of a variable to hold a Proto
+ expression.
+ <computeroutput>as_expr_result_type</computeroutput>
+ models
+ <computeroutput><conceptname>Expr</conceptname></computeroutput>.
+ </simpara>
+ </description>
+ </associated-type>
+
+ <associated-type name="as_child_result_type">
+ <get-member-type name="result_type">
+ <apply-template name="Domain::as_child">
+ <type name="Object"/>
+ </apply-template>
+ </get-member-type>
+ <description>
+ <simpara>
+ The result of converting some type to a Proto expression
+ type in this domain. This is used, for instance, to
+ compute the type of an object suitable for storage
+ as a child in an expression tree.
+ <computeroutput>as_child_result_type</computeroutput>
+ models
+ <computeroutput><conceptname>Expr</conceptname></computeroutput>.
+ </simpara>
+ </description>
+ </associated-type>
+
   <valid-expression name="Apply Generator">
     <apply-function name="d">
       <sample-value>
@@ -111,6 +157,44 @@
     </semantics>
   </valid-expression>
 
+ <valid-expression name="As Expression">
+ <apply-function name="Domain::as_expr&lt; Object &gt;()">
+ <sample-value>
+ <type name="Object"/>
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="as_expr_result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>
+ The result of converting some object to a Proto expression
+ in this domain. It returns a Proto expression object that
+ is suitable for storage in a variable. It should return a
+ new object, which may be a copy of the object passed in.
+ </semantics>
+ </valid-expression>
+
+ <valid-expression name="As Child">
+ <apply-function name="Domain::as_child&lt; Object &gt;()">
+ <sample-value>
+ <type name="Object"/>
+ </sample-value>
+ </apply-function>
+ <return-type>
+ <require-same-type testable="yes">
+ <type name="as_child_result_type"/>
+ </require-same-type>
+ </return-type>
+ <semantics>
+ The result of converting some object to a Proto expression
+ in this domain. It returns an object suitable for storage
+ as a child in an expression tree, which may simply be a
+ reference to the object passed in.
+ </semantics>
+ </valid-expression>
+
   <example-model>
     <type name="boost::proto::default_domain" />
   </example-model>

Modified: branches/release/libs/proto/doc/reference/domain.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/domain.xml (original)
+++ branches/release/libs/proto/doc/reference/domain.xml 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -1,9 +1,9 @@
 ï»¿<?xml version="1.0" encoding="utf-8"?>
 <header name="boost/proto/domain.hpp">
   <para>
- Contains definition of <computeroutput><classname alt="boost::proto::domain">proto::domain&lt;&gt;</classname>
- </computeroutput> class template and helpers for defining domains with a generator and a grammar for controlling
- operator overloading.
+ Contains definition of the <computeroutput><classname alt="boost::proto::domain">proto::domain&lt;&gt;</classname>
+ </computeroutput> class template and helpers for defining domains with a generator for customizing expression
+ construction and a grammar for controlling operator overloading.
   </para>
   <namespace name="boost">
     <namespace name="proto">
@@ -27,22 +27,25 @@
           <computeroutput><macroname>BOOST_PROTO_EXTENDS</macroname>()</computeroutput> and
           <computeroutput><macroname>BOOST_PROTO_DEFINE_OPERATORS</macroname>()</computeroutput>.
           A <emphasis>domain</emphasis> associates an expression type with a <emphasis>generator</emphasis>,
- and optionally a <emphasis>grammar</emphasis>.
+ and optionally a <emphasis>grammar</emphasis>. It may also have a super-domain. Expressions
+ in a sub-domain are interoperable (i.e. can be combined freely with) expressions in a
+ super-domain. Finally, domains control how non-Proto objects are turned into Proto
+ expressions and how they are combined to form larger Proto expressions.
         </purpose>
         <description>
           <para>
- The Generator determines how new expressions in the domain are constructed. Typically, a generator
+ The Generator parameter determines how new expressions in the domain are post-processed. Typically, a generator
             wraps all new expressions in a wrapper that imparts domain-specific behaviors to expressions within
             its domain. (See <computeroutput><classname alt="proto::extends">proto::extends&lt;&gt;</classname></computeroutput>.)
           </para>
           <para>
- The Grammar determines whether a given expression is valid within the domain, and automatically
+ The Grammar parameter 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><classname>proto::_</classname>
             </computeroutput>, which makes all expressions valid within the domain.
           </para>
           <para>
- The Super declares the domain currently being defined to be a sub-domain of Super. An expression in
+ The Super parameter declares the domain currently being defined to be a sub-domain of Super. An expression in
             a sub-domain can be freely combined with expressions in its super-domain (and <emphasis>its</emphasis>
             super-domain, etc.).
           </para>
@@ -70,6 +73,14 @@
  };
             </programlisting>
           </para>
+ <para>
+ The <computeroutput><classname>domain::as_expr</classname>&lt;&gt;</computeroutput> and
+ <computeroutput><classname>domain::as_child</classname>&lt;&gt;</computeroutput> member
+ templates define how non-Proto objects are turned into Proto terminals and how Proto
+ expressions should be processed before they are combined to form larger expressions.
+ They can be overridden in a derived domain for customization. See their descriptions to
+ understand how Proto uses these two templates and what their default behavior is.
+ </para>
         </description>
         <typedef name="proto_grammar">
           <type>Grammar</type>
@@ -80,6 +91,151 @@
         <typedef name="proto_super_domain">
           <type>Super</type>
         </typedef>
+
+ <struct name="as_expr">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <inherit><type><classname>proto::callable</classname></type></inherit>
+ <purpose>
+ A callable unary MonomorphicFunctionObject that specifies how objects are turned into
+ Proto expressions in this domain. The resulting expression object is suitable for storage
+ in a local variable.
+ </purpose>
+ <description>
+ <para>
+ A unary MonomorphicFunctionObject that specifies how objects are turned into Proto
+ expressions in this domain. The resulting expression object is suitable for storage
+ in a local variable. In that scenario, it is usually preferable to return
+ expressions by value; and, in the case of objects that are not yet Proto expressions,
+ to wrap they by value (if possible) in a new Proto terminal expression. (Contrast
+ this description with the description for
+ <computeroutput><classname>proto::domain::as_child</classname></computeroutput>.)
+ </para>
+ <para>
+ The <computeroutput>as_expr</computeroutput> function object turns objects into
+ Proto expressions, if they are not already, by making them Proto terminals held by
+ value if possible. Objects that are already Proto expressions are simply returned
+ by value. If
+ <computeroutput>wants_basic_expr&lt;Generator&gt;::value</computeroutput> is true,
+ then let <emphasis>E</emphasis> be
+ <computeroutput><classname>proto::basic_expr</classname></computeroutput>;
+ otherwise, let <emphasis>E</emphasis> be
+ <computeroutput><classname>proto::expr</classname></computeroutput>.
+ Given an lvalue <computeroutput>t</computeroutput> of type
+ <computeroutput>T</computeroutput>:
+ <itemizedlist>
+ <listitem>
+ If <computeroutput>T</computeroutput> is not a Proto expression type the resulting
+ terminal is calculated as follows:
+ <itemizedlist>
+ <listitem>
+ If <computeroutput>T</computeroutput> is a function type, an abstract type, or
+ a type derived from <computeroutput>std::ios_base</computeroutput>, let
+ <replaceable>A</replaceable> be <computeroutput>T &amp;</computeroutput>.
+ </listitem>
+ <listitem>
+ Otherwise, let <replaceable>A</replaceable> be the type
+ <computeroutput>T</computeroutput> stripped of cv-qualifiers.
+ </listitem>
+ </itemizedlist>
+ Then, the result of <computeroutput>as_expr&lt;T&gt;()(t)</computeroutput> is
+ <computeroutput>Generator()(<replaceable>E</replaceable>&lt;tag::terminal,
+ term&lt; <replaceable>A</replaceable> &gt; &gt;::make(t))</computeroutput>.
+ </listitem>
+ <listitem>
+ If <computeroutput>T</computeroutput> is a Proto expression type and its generator
+ type is different from <computeroutput>Generator</computeroutput>, the result is
+ <computeroutput>Generator()(t)</computeroutput>.
+ </listitem>
+ <listitem>
+ Otherwise, the result is <computeroutput>t</computeroutput> converted to an
+ (un-const) rvalue.
+ </listitem>
+ </itemizedlist>
+ </para>
+ </description>
+ <typedef name="result_type">
+ <type><replaceable>see-below</replaceable></type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="operator()" cv="const">
+ <type>result_type</type>
+ <parameter name="t">
+ <paramtype>T &amp;</paramtype>
+ <description>
+ <para>The object to wrap.</para>
+ </description>
+ </parameter>
+ </method>
+ </method-group>
+ </struct>
+
+ <struct name="as_child">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <inherit><type><classname>proto::callable</classname></type></inherit>
+ <purpose>
+ A callable unary MonomorphicFunctionObject that specifies how objects are turned into
+ Proto expressions in this domain, for use in scenarios where the resulting expression is
+ intended to be made a child of another expression.
+ </purpose>
+ <description>
+ <para>
+ A unary MonomorphicFunctionObject that specifies how objects are turned into Proto
+ expressions in this domain. The resulting expression object is suitable for storage
+ as a child of another expression. In that scenario, it is usually
+ preferable to store child expressions by reference; or, in the case of objects that
+ are not yet Proto expressions, to wrap them by reference in a new Proto terminal
+ expression. (Contrast this description with the description for
+ <computeroutput><classname>proto::domain::as_expr</classname></computeroutput>.)
+ </para>
+ <para>
+ The <computeroutput>as_child</computeroutput> function object turns objects into
+ Proto expressions, if they are not already, by making them Proto terminals held by
+ reference. Objects that are already Proto expressions are simply returned by
+ reference. If
+ <computeroutput>wants_basic_expr&lt;Generator&gt;::value</computeroutput> is true,
+ then let <emphasis>E</emphasis> be
+ <computeroutput><classname>proto::basic_expr</classname></computeroutput>;
+ otherwise, let <emphasis>E</emphasis> be
+ <computeroutput><classname>proto::expr</classname></computeroutput>.
+ Given an lvalue <computeroutput>t</computeroutput> of type
+ <computeroutput>T</computeroutput>:
+ <itemizedlist>
+ <listitem>
+ If <computeroutput>T</computeroutput> is not a Proto expression type the resulting
+ terminal is
+ <computeroutput>Generator()(<replaceable>E</replaceable>&lt;tag::terminal,
+ term&lt; <computeroutput>T &amp;</computeroutput> &gt; &gt;::make(t))</computeroutput>.
+ </listitem>
+ <listitem>
+ If <computeroutput>T</computeroutput> is a Proto expression type and its generator
+ type is different from <computeroutput>Generator</computeroutput>, the result is
+ <computeroutput>Generator()(t)</computeroutput>.
+ </listitem>
+ <listitem>
+ Otherwise, the result is the lvalue <computeroutput>t</computeroutput>.
+ </listitem>
+ </itemizedlist>
+ </para>
+ </description>
+ <typedef name="result_type">
+ <type><replaceable>see-below</replaceable></type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="operator()" cv="const">
+ <type>result_type</type>
+ <parameter name="t">
+ <paramtype>T &amp;</paramtype>
+ <description>
+ <para>The object to wrap.</para>
+ </description>
+ </parameter>
+ </method>
+ </method-group>
+ </struct>
       </struct>
 
       <!-- proto::default_domain -->
@@ -132,41 +288,7 @@
         </typedef>
       </struct>
 
- <!-- proto::use_basic_expr -->
- <struct name="use_basic_expr">
- <template>
- <template-type-parameter name="Domain"/>
- </template>
- <description>
- <para>
- Annotate a domain to indicate that its generator would
- prefer to be passed instances of
- <computeroutput><classname>proto::basic_expr</classname>&lt;&gt;</computeroutput> rather than
- <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
- <computeroutput>use_basic_expr&lt; Domain &gt;</computeroutput> is itself a domain.
- </para>
- </description>
- </struct>
-
- <!-- proto::wants_basic_expr -->
- <struct name="wants_basic_expr">
- <template>
- <template-type-parameter name="Domain"/>
- </template>
- <description>
- <para>
- A Boolean metafunction that tests a domain to see whether
- its generator would prefer to be passed instances of
- <computeroutput><classname>proto::basic_expr</classname>&lt;&gt;</computeroutput> rather than
- <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
- </para>
- </description>
- <inherit>
- <type>mpl::bool_&lt; <replaceable>true-or-false</replaceable> &gt;</type>
- </inherit>
- </struct>
-
- <!-- proto::wants_basic_expr -->
+ <!-- proto::base_expr -->
       <struct name="base_expr">
         <template>
           <template-type-parameter name="Domain"/>

Modified: branches/release/libs/proto/doc/reference/generate.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/generate.xml (original)
+++ branches/release/libs/proto/doc/reference/generate.xml 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -1,7 +1,11 @@
 ï»¿<?xml version="1.0" encoding="utf-8"?>
 <header name="boost/proto/generate.hpp">
- <para>Contains definition of <computeroutput><classname alt="boost::proto::generator">proto::generator&lt;&gt;</classname></computeroutput>
- class template and friends that end users can use to generate domain-specific expression wrappers.</para>
+ <para>Contains definition of
+ <computeroutput><classname alt="boost::proto::default_generator">proto::default_generator</classname></computeroutput>,
+ <computeroutput><classname alt="boost::proto::generator">proto::generator</classname>&lt;&gt;</computeroutput>,
+ <computeroutput><classname alt="boost::proto::pod_generator">proto::pod_generator</classname>&lt;&gt;</computeroutput>
+ and other utilities that users can use to post-process new expression objects that
+ Proto creates.</para>
   <namespace name="boost">
     <namespace name="proto">
       <!-- proto::default_generator -->
@@ -259,6 +263,46 @@
           </method>
         </method-group>
       </struct>
+
+ <!-- proto::use_basic_expr -->
+ <struct name="use_basic_expr">
+ <template>
+ <template-type-parameter name="Generator"/>
+ </template>
+ <inherit>
+ <type>Generator</type>
+ </inherit>
+ <description>
+ <para>
+ Annotate a generator to indicate that it would
+ prefer to be passed instances of
+ <computeroutput><classname>proto::basic_expr</classname>&lt;&gt;</computeroutput> rather than
+ <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
+ </para>
+ <para>
+ <computeroutput>use_basic_expr&lt; Generator &gt;</computeroutput> is itself a generator.
+ </para>
+ </description>
+ </struct>
+
+ <!-- proto::wants_basic_expr -->
+ <struct name="wants_basic_expr">
+ <template>
+ <template-type-parameter name="Generator"/>
+ </template>
+ <inherit>
+ <type>mpl::bool_&lt; <replaceable>true-or-false</replaceable> &gt;</type>
+ </inherit>
+ <description>
+ <para>
+ A Boolean metafunction that tests a generator to see whether
+ it would prefer to be passed instances of
+ <computeroutput><classname>proto::basic_expr</classname>&lt;&gt;</computeroutput> rather than
+ <computeroutput><classname>proto::expr</classname>&lt;&gt;</computeroutput>.
+ </para>
+ </description>
+ </struct>
+
     </namespace>
   </namespace>
 </header>

Modified: branches/release/libs/proto/doc/reference/literal.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/literal.xml (original)
+++ branches/release/libs/proto/doc/reference/literal.xml 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -20,7 +20,7 @@
         </template>
         <inherit>
           <type>
- <classname>proto::extends</classname>&lt;typename <classname>proto::terminal</classname>&lt;T&gt;::type, proto::literal&lt;T, Domain&gt;, Domain&gt;</type>
+ <classname>proto::extends</classname>&lt;<classname>proto::basic_expr</classname>&lt;<classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt; T &gt; &gt;, proto::literal&lt;T, Domain&gt;, Domain&gt;</type>
         </inherit>
         <purpose>A simple wrapper for a terminal, provided for ease of use.</purpose>
         <description>
@@ -36,7 +36,7 @@
         </description>
         <typedef name="X">
           <purpose>For exposition only</purpose>
- <type>typename <classname>proto::terminal</classname>&lt;T&gt;::type</type>
+ <type><classname>proto::basic_expr</classname>&lt;<classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt; T &gt; &gt;</type>
         </typedef>
         <typedef name="value_type">
           <type>typename <classname>proto::result_of::value</classname>&lt;X&gt;::type</type>

Modified: branches/release/libs/proto/doc/reference/traits.xml
==============================================================================
--- branches/release/libs/proto/doc/reference/traits.xml (original)
+++ branches/release/libs/proto/doc/reference/traits.xml 2010-06-12 08:38:48 EDT (Sat, 12 Jun 2010)
@@ -1,6 +1,19 @@
 ï»¿<?xml version="1.0" encoding="utf-8"?>
 <header name="boost/proto/traits.hpp">
- <para>Contains definitions for child&lt;&gt;, child_c&lt;&gt;, left&lt;&gt;, right&lt;&gt;, tag_of&lt;&gt;, and the helper functions child(), child_c(), value(), left() and right(). </para>
+ <para>
+ Contains definitions for various expression traits and utilities like
+ <computeroutput><classname alt="boost::proto::tag_of">proto::tag_of</classname>&lt;&gt;</computeroutput> and
+ <computeroutput><classname alt="boost::proto::arity_of">proto::arity_of</classname>&lt;&gt;</computeroutput>;
+ the functions
+ <computeroutput><functionname alt="boost::proto::value">proto::value</functionname>()</computeroutput>,
+ <computeroutput><functionname alt="boost::proto::left">proto::left</functionname>()</computeroutput> and
+ <computeroutput><functionname alt="boost::proto::right">proto::right</functionname>()</computeroutput>;
+ <computeroutput><functionname alt="boost::proto::child">proto::child</functionname>()</computeroutput>,
+ <computeroutput><functionname alt="boost::proto::child_c">proto::child_c</functionname>()</computeroutput>,
+ <computeroutput><functionname alt="boost::proto::as_expr">proto::as_expr</functionname>()</computeroutput>,
+ <computeroutput><functionname alt="boost::proto::as_child">proto::as_child</functionname>()</computeroutput>,
+ and assorted helpers.
+ </para>
   <namespace name="boost">
     <namespace name="proto">
       <struct name="is_callable">
@@ -97,7 +110,7 @@
             <specialization>
               <template-arg>This(T)</template-arg>
             </specialization>
- <inherit><type><classname>proto::result_of::as_expr</classname>&lt; T, Domain &gt;</type></inherit>
+ <inherit><type><classname>proto::result_of::as_expr</classname>&lt; typename remove_reference&lt; T &gt;::type, Domain &gt;</type></inherit>
           </struct-specialization>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
@@ -156,7 +169,7 @@
             <specialization>
               <template-arg>This(T)</template-arg>
             </specialization>
- <inherit><type><classname>proto::result_of::as_child</classname>&lt; T, Domain &gt;</type></inherit>
+ <inherit><type><classname>proto::result_of::as_child</classname>&lt; typename remove_reference&lt; T &gt;::type, Domain &gt;</type></inherit>
           </struct-specialization>
           <method-group name="public member functions">
             <method name="operator()" cv="const">
@@ -2087,27 +2100,21 @@
             </template-type-parameter>
           </template>
           <purpose>A metafunction that computes the return type of the
- <computeroutput><functionname alt="proto::as_expr">proto::as_expr()</functionname></computeroutput> function.</purpose>
+ <computeroutput><functionname>proto::as_expr</functionname>()</computeroutput> function.</purpose>
           <description>
             <para>
- The <computeroutput>proto::result_of::as_expr&lt;&gt;</computeroutput> 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.
+ The <computeroutput>proto::result_of::as_expr&lt;&gt;</computeroutput> metafunction turns types
+ into Proto expression types, if they are not already, in a domain-specific way. It is intended
+ for use to compute the type of a local variable that can hold the result of the
+ <computeroutput><functionname>proto::as_expr</functionname>()</computeroutput> function.
             </para>
             <para>
- If <computeroutput>T</computeroutput> is not yet a Proto type, the resulting terminal type is calculated
- as follows:
- </para>
- <para>
- If <computeroutput>T</computeroutput> is a function type, let
- <computeroutput>A</computeroutput> be <computeroutput>T &amp;</computeroutput>. Otherwise, let
- <computeroutput>A</computeroutput> be the type <computeroutput>T</computeroutput> stripped of
- cv-qualifiers. Then, the result type <computeroutput>proto::result_of::as_expr&lt;T, Domain&gt;::type</computeroutput>
- is <computeroutput>boost::result_of&lt;Domain(typename <classname>proto::base_expr</classname>&lt;Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;A&gt; &gt;::type)&gt;::type</computeroutput>.
+ See <computeroutput><classname>proto::domain::as_expr</classname>&lt;&gt;</computeroutput>
+ for a complete description of the default behavior.
             </para>
           </description>
           <typedef name="type">
- <type><replaceable>see-below</replaceable></type>
+ <type>typename Domain::template as_expr&lt; T &gt;::result_type</type>
           </typedef>
         </struct>
 
@@ -2119,26 +2126,20 @@
             </template-type-parameter>
           </template>
           <purpose>A metafunction that computes the return type of the
- <computeroutput><functionname alt="proto::as_child">proto::as_child()</functionname></computeroutput> function.</purpose>
+ <computeroutput><functionname>proto::as_child</functionname>()</computeroutput> function.</purpose>
           <description>
             <para>
- The <computeroutput>proto::result_of::as_child&lt;&gt;</computeroutput> 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 left alone.
- </para>
- <para>
- When <computeroutput>T</computeroutput> is not yet a Proto type,
- the result type <computeroutput>proto::result_of::as_child&lt;T, Domain&gt;::type</computeroutput> is
- <computeroutput>boost::result_of&lt;Domain(typename <classname>proto::base_expr</classname>&lt;Domain, <classname>proto::tag::terminal</classname>, <classname>proto::term</classname>&lt;T &amp;&gt; &gt;::type)&gt;::type</computeroutput>.
+ The <computeroutput>proto::result_of::as_child&lt;&gt;</computeroutput> metafunction turns types
+ into Proto expression types, if they are not already, in a domain-specific way. It is used by Proto
+ to compute the type of an object to store as a child in another expression node.
             </para>
             <para>
- When <computeroutput>T</computeroutput> is already a Proto type
- The result type <computeroutput>proto::result_of::as_child&lt;T, Domain&gt;::type</computeroutput> is
- <computeroutput>T &amp;</computeroutput>.
+ See <computeroutput><classname>proto::domain::as_child</classname>&lt;&gt;</computeroutput>
+ for a complete description of the default behavior.
             </para>
           </description>
           <typedef name="type">
- <type><replaceable>see-below</replaceable></type>
+ <type>typename Domain::template as_child&lt; T &gt;::result_type</type>
           </typedef>
         </struct>
 
@@ -2472,28 +2473,24 @@
           expression types alone.</purpose>
         <description>
           <para>
- The <computeroutput>proto::as_expr()</computeroutput> 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.
- </para>
- <para>
- This function can be called either with an explicitly specified
- <computeroutput>Domain</computeroutput> parameter
- (i.e., <computeroutput>proto::as_expr&lt;Domain&gt;(t)</computeroutput>), or without
- (i.e., <computeroutput>proto::as_expr(t)</computeroutput>). If no domain is specified,
- <computeroutput><classname>proto::default_domain</classname></computeroutput> is assumed.
- </para>
- <para>
- If <computeroutput><classname>proto::is_expr</classname>&lt;T&gt;::value</computeroutput> is
- <computeroutput>true</computeroutput>, then the argument is returned unmodified. Otherwise,
- the argument is wrapped in a Proto terminal expression node according to the following rules.
- If <computeroutput>T</computeroutput> is a function type, let
- <computeroutput>A</computeroutput> be <computeroutput>T &amp;</computeroutput>. Otherwise, let
- <computeroutput>A</computeroutput> be the type <computeroutput>T</computeroutput> stripped of
- cv-qualifiers. Then, <computeroutput>proto::as_expr()</computeroutput> returns
- <computeroutput>Domain()(<classname>proto::terminal</classname>&lt;A&gt;::type::make(t))</computeroutput>.
+ The <computeroutput>proto::as_expr()</computeroutput> function returns Proto expression
+ objects that are suitable for storage in a local variable. It turns non-Proto objects
+ into Proto terminals. Its behavior is domain-specific. By default,
+ non-Proto types are wrapped by value (if possible) in a new Proto terminal expression,
+ and objects that are already Proto expressions are returned by value.
+ </para>
+ <para>
+ If <computeroutput>Domain</computeroutput> is not explicitly specified, it is assumed to
+ be <computeroutput><classname>proto::default_domain</classname></computeroutput>.
+ </para>
+ <para>
+ See <computeroutput><classname>proto::domain::as_expr</classname>&lt;&gt;</computeroutput>
+ for a complete description of this function's default behavior.
           </para>
         </description>
+ <returns>
+ <computeroutput>typename Domain::template as_expr&lt; T &gt;()(t)</computeroutput>
+ </returns>
       </overloaded-function>
       
       <overloaded-function name="as_child">
@@ -2535,28 +2532,28 @@
             <paramtype>T const &amp;</paramtype>
           </parameter>
         </signature>
- <purpose>A function that wraps non-Proto expression types in Proto terminals (by reference) and leaves
+ <purpose>A function that wraps non-Proto objects in Proto terminals (by reference) and leaves
           Proto expression types alone.</purpose>
         <description>
           <para>
- The <computeroutput>proto::as_child()</computeroutput> 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 simply returned as-is.
- </para>
- <para>
- This function can be called either with an explicitly specified
- <computeroutput>Domain</computeroutput> parameter
- (i.e., <computeroutput>proto::as_child&lt;Domain&gt;(t)</computeroutput>), or without
- (i.e., <computeroutput>proto::as_child(t)</computeroutput>). If no domain is specified,
- <computeroutput><classname>proto::default_domain</classname></computeroutput> is assumed.
- </para>
- <para>
- If <computeroutput><classname>proto::is_expr</classname>&lt;T&gt;::value</computeroutput> is
- <computeroutput>true</computeroutput>, then the argument is returned as-is. Otherwise,
- <computeroutput>proto::as_child()</computeroutput> returns
- <computeroutput>Domain()(<classname>proto::terminal</classname>&lt;T &amp;&gt;::type::make(t))</computeroutput>.
+ The <computeroutput>proto::as_child()</computeroutput> function returns Proto expression
+ objects that are suitable for storage as child nodes in an expression tree. It turns
+ non-Proto objects into Proto terminals. Its behavior is domain-specific. By default,
+ non-Proto types are held wrapped by reference in a new Proto terminal expression, and
+ objects that are already Proto expressions are simply returned by reference.
+ </para>
+ <para>
+ If <computeroutput>Domain</computeroutput> is not explicitly specified, it is assumed to
+ be <computeroutput><classname>proto::default_domain</classname></computeroutput>.
+ </para>
+ <para>
+ See <computeroutput><classname>proto::domain::as_child</classname>&lt;&gt;</computeroutput>
+ for a complete description of this function's default behavior.
           </para>
         </description>
+ <returns>
+ <computeroutput>typename Domain::template as_child&lt; T &gt;()(t)</computeroutput>
+ </returns>
       </overloaded-function>
 
       <overloaded-function name="child">


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