Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-08-14 19:42:04


Author: eric_niebler
Date: 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
New Revision: 48146
URL: http://svn.boost.org/trac/boost/changeset/48146

Log:
more doc work
Added:
   trunk/libs/proto/doc/conventions.qbk
      - copied, changed from r48118, /trunk/libs/proto/doc/quick_start.qbk
   trunk/libs/proto/doc/hello_world.qbk (contents, props changed)
   trunk/libs/proto/doc/resources.qbk
      - copied, changed from r48118, /trunk/libs/proto/doc/references.qbk
Removed:
   trunk/libs/proto/doc/quick_start.qbk
   trunk/libs/proto/doc/references.qbk
Text files modified:
   trunk/libs/proto/doc/conventions.qbk | 76 -----------------------
   trunk/libs/proto/doc/extensibility.qbk | 131 +++++++++++++++++++++++----------------
   trunk/libs/proto/doc/glossary.qbk | 18 ++++
   trunk/libs/proto/doc/grammars.qbk | 6 +
   trunk/libs/proto/doc/proto.qbk | 12 +-
   trunk/libs/proto/doc/resources.qbk | 6
   trunk/libs/proto/doc/transforms.qbk | 59 ++++++++++-------
   7 files changed, 141 insertions(+), 167 deletions(-)

Copied: trunk/libs/proto/doc/conventions.qbk (from r48118, /trunk/libs/proto/doc/quick_start.qbk)
==============================================================================
--- /trunk/libs/proto/doc/quick_start.qbk (original)
+++ trunk/libs/proto/doc/conventions.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -67,79 +67,3 @@
 
 [endsect]
 
-[section Hello World]
-
-Below is a very simple program that uses Proto to build an expression template
-and then execute it.
-
- #include <iostream>
- #include <boost/proto/proto.hpp>
- #include <boost/proto/context.hpp>
- #include <boost/typeof/std/ostream.hpp>
- using namespace boost;
-
- proto::terminal< std::ostream & >::type cout_ = { std::cout };
-
- template< typename Expr >
- void evaluate( Expr const & expr )
- {
- proto::default_context ctx;
- proto::eval(expr, ctx);
- }
-
- int main()
- {
- evaluate( cout_ << "hello" << ',' << " world" );
- return 0;
- }
-
-This program outputs the following:
-
-[pre
-hello, world
-]
-
-This program builds an object representing the output operation and passes
-it to an `evaluate()` function, which then executes it.
-
-The basic idea of expression templates is to overload all the operators so
-that, rather than evaluating the expression immediately, they build a tree-like
-representation of the expression so that it can be evaluated later. For each
-operator in an expression, at least one operand must be Protofied in order
-for Proto's operator overloads to be found. In the expression ...
-
- cout_ << "hello" << ',' << " world"
-
-... the Protofied sub-expression is `cout_`, which is the Proto-ification of
-`std::cout`. The presence of `cout_` "infects" the expression, and brings
-Proto's tree-building operator overloads into consideration. Any literals in
-the expression are then Protofied by wrapping them in a Proto terminal before
-they are combined into larger Proto expressions.
-
-Once Proto's operator overloads have built the expression tree, the expression
-can be lazily evaluated later by walking the tree. That is what `proto::eval()`
-does. It is a general tree-walking expression evaluator, whose behavior is
-customizable via a /context/ parameter. The use of _default_context_ assigns
-the standard meanings to the operators in the expression. (By using a different
-context, you could give the operators in your expressions different semantics.
-By default, Proto makes no assumptions about what operators actually /mean/.)
-
-[/==============================]
-[heading Proto Design Philosophy]
-[/==============================]
-
-Before we continue, let's use the above example to illustrate an important
-design principle of Proto's. The expression template created in the ['hello
-world] example is totally general and abstract. It is not tied in any way to
-any particular domain or application, nor does it have any particular meaning
-or behavior on its own, until it is evaluated in a /context/. Expression
-templates are really just heterogeneous trees, which might mean something in
-one domain, and something else entirely in a different one.
-
-As we'll see later, there is a way to create Proto expression trees that are
-['not] purely abstract, and that have meaning and behaviors independent of any
-context. There is also a way to control which operators are overloaded for your
-particular domain. But that is not the default behavior. We'll see later why
-the default is often a good thing.
-
-[endsect]

Modified: trunk/libs/proto/doc/extensibility.qbk
==============================================================================
--- trunk/libs/proto/doc/extensibility.qbk (original)
+++ trunk/libs/proto/doc/extensibility.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -15,23 +15,35 @@
 [section Domains]
 [/==============]
 
-In the examples we've seen so far, Proto has been used to construct an
-expression tree that either is evaluated with the help of a /context/ or else
-is transformed into some other object. What if you need something else? Take
-our old friend the calculator example. Perhaps we would like to build a
-calculator expression and immediately use it as a function object to a standard
-algorithm, like this:
+In most of the examples we've seen so far, Proto has been used to construct an
+expression tree that either is evaluated with the help of a /context/ or else is
+transformed into some other object. What if you need something else? Take our old
+friend the calculator example. Perhaps we would like to build a calculator
+expression and immediately use it as a function object to a standard algorithm,
+like this:
 
     double data[] = {1., 2., 3., 4.};
 
- // Use the calculator DSEL to square each element ... FAILS! :-(
+ // Use the calculator DSEL to square each element ... HOW?
     std::transform( data, data + 4, data, _1 * _1 );
 
-This will not compile. The problem is that the object created by the expression
-`_1 * _1` does not meet the `UnaryFunction` requirements of the
-`std::transform()` algorithm. In particular, it doesn't have an `operator()`
-member function that takes a `double` and returns a `double`, like
-`std::transform()` expects. What can we do?
+By default, Proto expressions don't have interesting behaviors of their own.
+They're just trees. In particular, the expression `_1 * _1` won't have an
+`operator()` that takes a double and returns a double, like `std::transform()`
+expects. In the [link boost_proto.users_guide.getting_started.hello_calculator
+Hello Calculator] section, we learned that to make this work, we need to define an
+expression wrapper type that defines the `operator()` member function, and we
+needed to associate the wrapper with the calculator /domain/.
+
+In Proto, the term /domain/ refers to a type that associates expressions in that
+domain to an expression /generator/. The generator is just a function object that
+accepts an expression and does something to it, like wrapping it in an expression
+wrapper.
+
+You can also use a domain to associate expressions with a a grammar. When you
+specify a domain's grammar, Proto ensures that all the expressions it generates in
+that domain conform to the domain's grammar. It does that by disabling any operator
+overloads that would create invalid expressions.
 
 [endsect]
 
@@ -39,12 +51,6 @@
 [section:extends The [^extends<>] Expression Wrapper]
 [/==================================================]
 
-The general idea is to add behaviors to the _expr_ type by wrapping it in a
-class template that you define. This wrapper is associated with a domain. Proto
-will build larger expressions out of your wrapper objects, and you will want
-those objects to also be wrapped. You do that by hooking Proto's expression
-generator for your domain.
-
 The first step to giving your calculator expressions extra behaviors is to
 define a calculator domain. All expressions within the calculator domain will
 be imbued with calculator-ness, as we'll see.
@@ -62,7 +68,9 @@
     struct calculator
       : proto::extends< Expr, calculator< Expr >, calculator_domain >
     {
- typedef proto::extends< Expr, calculator< Expr >, calculator_domain > base_type;
+ typedef
+ proto::extends< Expr, calculator< Expr >, calculator_domain >
+ base_type;
 
         calculator( Expr const &expr = Expr() )
           : base_type( expr )
@@ -77,13 +85,21 @@
         typedef double result_type;
         result_type operator()( double d1 = 0.0, double d2 = 0.0 ) const
         {
- calculator_context ctx( d1, d2 );
- return proto::eval(*this, ctx );
+ // As defined in the Hello Calculator section.
+ calculator_context ctx;
+
+ // ctx.args is a vector<double> that holds the values
+ // with which we replace the placeholders (e.g., _1 and _2)
+ // in the expression.
+ ctx.args.push_back( d1 ); // _1 gets the value of d1
+ ctx.args.push_back( d2 ); // _2 gets the value of d2
+
+ return proto::eval(*this, ctx ); // evaluate the expression
         }
     };
 
 We want calculator expressions to be function objects, so we have to define an
-`operator()` that takes and returns `double`s. The `calculator<>` wrapper above
+`operator()` that takes and returns doubles. The `calculator<>` wrapper above
 does that with the help of the _extends_ template. The first template to
 _extends_ parameter is the expression type we are extending. The second is the
 type of the wrapped expression. The third parameter is the domain that this
@@ -91,21 +107,20 @@
 from _extends_ behaves just like the expression type it has extended, with any
 additional behaviors you choose to give it.
 
-Although not strictly necessary in this case, we bring `extends<>::operator=`
-into scope with a `using` declaration. This is really only necessary if you
-want expressions like `_1 = 3` to create a lazily evaluated assignment.
-_extends_ defines the appropriate `operator=` for you, but the
-compiler-generated `calculator<>::operator=` will hide it unless you make it
-available with the `using` declaration.
-
-Note that in the implementation of `calculator<>::operator()`, we evaluate the
-expression with the `calculator_context` we defined earlier. As we saw before,
-the context is what gives the operators their meaning. In the case of the
-calculator, the context is also what defines the meaning of the placeholder
-terminals.
+Although not strictly necessary in this case, we bring `extends<>::operator=` into
+scope with a `using` declaration. This is really only necessary if you want
+expressions like `_1 = 3` to create a lazily evaluated assignment. _extends_
+defines the appropriate `operator=` for you, but the compiler-generated
+`calculator<>::operator=` will hide it unless you make it available with the
+`using` declaration.
+
+Note that in the implementation of `calculator<>::operator()`, we evaluate the
+expression with the `calculator_context` we defined earlier. As we saw before, the
+context is what gives the operators their meaning. In the case of the calculator,
+the context is also what defines the meaning of the placeholder terminals.
 
-Now that we have defined the `calculator<>` expression wrapper, we need to
-wrap the placeholders to imbue them with calculator-ness:
+Now that we have defined the `calculator<>` expression wrapper, we need to wrap the
+placeholders to imbue them with calculator-ness:
 
     calculator< proto::terminal< placeholder<0> >::type > const _1;
     calculator< proto::terminal< placeholder<1> >::type > const _2;
@@ -116,11 +131,11 @@
 [section Expression Generators]
 [/============================]
 
-The last thing that remains to be done is to tell Proto that it needs to wrap
-all of our calculator expressions in our `calculator<>` wrapper. We have
-already wrapped the placeholders, but we want /all/ expressions that involve
-the calculator placeholders to be calculators. We can do that by specifying an
-expression generator when we define our `calculator_domain`, as follows:
+The last thing that remains to be done is to tell Proto that it needs to wrap all
+of our calculator expressions in our `calculator<>` wrapper. We have already
+wrapped the placeholders, but we want /all/ expressions that involve the calculator
+placeholders to be calculators. We can do that by specifying an expression
+generator when we define our `calculator_domain`, as follows:
 
     // Define the calculator_domain we forward-declared above.
     // Specify that all expression in this domain should be wrapped
@@ -129,13 +144,16 @@
       : proto::domain< proto::generator< calculator > >
     {};
 
-Proto uses domains to generate expressions. After Proto has calculated a new
-expression type, it checks the domains of the child expressions. They must
-match. Assuming they do, Proto creates the new expression and passes it to
-`Domain::make()` for any additional processing. If we don't specify a
-generator, the new expression gets passed through unchanged. But since we've
-specified a generator above, `calculator_domain::make()` returns `calculator<>`
-objects.
+The first template parameter to `proto::domain<>` is the generator. "Generator" is just a fancy name for a function object that accepts an expression and does something to it. `proto::generator<>` is a very simple one --- it wraps an expression in the wrapper you specify. `proto::domain<>` inherits from its generator parameter, so all domains are themselves function objects.
+
+[def __domain__ [~Domain]]
+
+After Proto has calculated a new expression type, it checks the domains of the
+child expressions. They must match. Assuming they do, Proto creates the new
+expression and passes it to `__domain__::operator()` for any additional processing.
+If we don't specify a generator, the new expression gets passed through unchanged.
+But since we've specified a generator above, `calculator_domain::operator()`
+returns `calculator<>` objects.
 
 Now we can use calculator expressions as function objects to STL algorithms, as
 follows:
@@ -200,9 +218,12 @@
         template<typename Expr>
         struct eval<Expr, proto::tag::terminal>
         {
- typedef typename proto::result_of::child<Expr>::type::value_type result_type;
+ typedef
+ typename proto::result_of::child<Expr>::type::value_type
+ result_type;
 
- result_type operator()( Expr const & expr, lazy_subscript_context & ctx ) const
+ result_type
+ operator()( Expr const & expr, lazy_subscript_context & ctx ) const
             {
                 return proto::child( expr )[ ctx.subscript_ ];
             }
@@ -217,7 +238,9 @@
     struct lazy_vector_expr
       : proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain>
     {
- typedef proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain> base_type;
+ typedef
+ proto::extends<Expr, lazy_vector_expr<Expr>, lazy_vector_domain>
+ base_type;
 
         lazy_vector_expr( Expr const & expr = Expr() )
           : base_type( expr )
@@ -240,7 +263,9 @@
         typedef typename proto::terminal< std::vector<T> >::type expr_type;
 
         lazy_vector( std::size_t size = 0, T const & value = T() )
- : lazy_vector_expr<expr_type>( expr_type::make( std::vector<T>( size, value ) ) )
+ : lazy_vector_expr<expr_type>(
+ expr_type::make( std::vector<T>( size, value ) )
+ )
         {}
 
         template< typename Expr >
@@ -282,7 +307,7 @@
 
 The line `v1 += v2 - v3` is somewhat ambiguous. Clearly we want it to use the
 `lazy_vector<>::operator+=` we defined above, but it could also mean to
-construct an even larger expression template using proto's `operator+=`. At
+construct an even larger expression template using Proto's `operator+=`. At
 least one compiler actually believes the call to be ambiguous! We have to tell
 the compiler which.
 

Modified: trunk/libs/proto/doc/glossary.qbk
==============================================================================
--- trunk/libs/proto/doc/glossary.qbk (original)
+++ trunk/libs/proto/doc/glossary.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -19,6 +19,14 @@
        `proto::is_callable<R>::value` is `true`. `R` is treated as a polymorphic
        function object and the arguments are treated as transforms that yield the
        arguments to the function object.] ]
+ [ [ [anchor domain] domain]
+ [In Proto, the term /domain/ refers to a type that associates expressions
+ within that domain with a /generator/ for that domain and optionally a
+ /grammar/ for the domain. Domains are used primarily to imbue expressions
+ within that domain with additional members and to restrict Proto's operator
+ overloads such that expressions not conforming to the domain's grammar are
+ never created. Domains are empty structs that inherit from
+ `proto::domain<>`.]]
   [ [ [anchor dsel] domain-specific embedded language]
       [A domain-specific language implemented as a library. The langauge in which
        the library is written is called the "host" langauge, and the language
@@ -37,11 +45,17 @@
        expressions to build trees that represent the expression for lazy evaluation
        later, rather than evaluating the expression eagerly. Some C++ libraries use
        expression templates to build domain-specific embedded languages.]]
+ [ [ [anchor generator] generator]
+ [In Proto, a /generator/ is a unary polymorphic function object that you
+ specify when defining a /domain/. After constructing a new expression, Proto
+ passes the expression to your domain's generator for further processing.
+ Often, the generator wraps the expression in an extension wrapper that adds
+ additional members to it.]]
   [ [ [anchor grammar] grammar]
       [A grammar is a type that describes a subset of expression types. Expressions
        in a domain must conform to that domain's grammar. The `proto::matches<>`
- metafunction evaluates whether an expression type matchesa grammar. Grammars
- are either primitives such as `proto::_`, composites such as
+ metafunction evaluates whether an expression type matches a grammar.
+ Grammars are either primitives such as `proto::_`, composites such as
        `proto::plus<>`, control structures such as `proto::or_<>`, or some type
        derived from a grammar.]]
   [ [ [anchor object_transform] object transform]

Modified: trunk/libs/proto/doc/grammars.qbk
==============================================================================
--- trunk/libs/proto/doc/grammars.qbk (original)
+++ trunk/libs/proto/doc/grammars.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -12,7 +12,9 @@
 Expression trees can have a very rich and complicated structure. Often, you
 need to know some things about an expression's structure before you can process
 it. This section describes the tools Proto provides for peering inside an
-expression tree and discovering its structure.
+expression tree and discovering its structure. And as you'll see in later
+sections, all the really interesting things you can do with Proto begin right
+here.
 
 [/===============================================]
 [section:patterns Finding Patterns In Expressions]
@@ -286,7 +288,7 @@
 This says that a `CharString` must be a terminal, /and/ its value type must be
 the same as `char const *`. Notice the template argument of _if_:
 `boost::is_same< proto::_value, char const * >()`. This is Proto transform that
-compares the value of a terminal to `char const *`.
+compares the value type of a terminal to `char const *`.
 
 The _if_ template has a couple of variants. In additon to `if_<Condition>` you
 can also say `if_<Condition, ThenGrammar>` and

Added: trunk/libs/proto/doc/hello_world.qbk
==============================================================================
--- (empty file)
+++ trunk/libs/proto/doc/hello_world.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -0,0 +1,85 @@
+[/
+ / Copyright (c) 2008 Eric Niebler
+ /
+ / Distributed under the Boost Software License, Version 1.0. (See accompanying
+ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ /]
+
+[/==================]
+[section Hello World]
+[/==================]
+
+Below is a very simple program that uses Proto to build an expression template
+and then execute it.
+
+ #include <iostream>
+ #include <boost/proto/proto.hpp>
+ #include <boost/proto/context.hpp>
+ #include <boost/typeof/std/ostream.hpp>
+ using namespace boost;
+
+ proto::terminal< std::ostream & >::type cout_ = { std::cout };
+
+ template< typename Expr >
+ void evaluate( Expr const & expr )
+ {
+ proto::default_context ctx;
+ proto::eval(expr, ctx);
+ }
+
+ int main()
+ {
+ evaluate( cout_ << "hello" << ',' << " world" );
+ return 0;
+ }
+
+This program outputs the following:
+
+[pre
+hello, world
+]
+
+This program builds an object representing the output operation and passes
+it to an `evaluate()` function, which then executes it.
+
+The basic idea of expression templates is to overload all the operators so
+that, rather than evaluating the expression immediately, they build a tree-like
+representation of the expression so that it can be evaluated later. For each
+operator in an expression, at least one operand must be Protofied in order
+for Proto's operator overloads to be found. In the expression ...
+
+ cout_ << "hello" << ',' << " world"
+
+... the Protofied sub-expression is `cout_`, which is the Proto-ification of
+`std::cout`. The presence of `cout_` "infects" the expression, and brings
+Proto's tree-building operator overloads into consideration. Any literals in
+the expression are then Protofied by wrapping them in a Proto terminal before
+they are combined into larger Proto expressions.
+
+Once Proto's operator overloads have built the expression tree, the expression
+can be lazily evaluated later by walking the tree. That is what `proto::eval()`
+does. It is a general tree-walking expression evaluator, whose behavior is
+customizable via a /context/ parameter. The use of _default_context_ assigns
+the standard meanings to the operators in the expression. (By using a different
+context, you could give the operators in your expressions different semantics.
+By default, Proto makes no assumptions about what operators actually /mean/.)
+
+[/==============================]
+[heading Proto Design Philosophy]
+[/==============================]
+
+Before we continue, let's use the above example to illustrate an important
+design principle of Proto's. The expression template created in the ['hello
+world] example is totally general and abstract. It is not tied in any way to
+any particular domain or application, nor does it have any particular meaning
+or behavior on its own, until it is evaluated in a /context/. Expression
+templates are really just heterogeneous trees, which might mean something in
+one domain, and something else entirely in a different one.
+
+As we'll see later, there is a way to create Proto expression trees that are
+['not] purely abstract, and that have meaning and behaviors independent of any
+context. There is also a way to control which operators are overloaded for your
+particular domain. But that is not the default behavior. We'll see later why
+the default is often a good thing.
+
+[endsect]

Modified: trunk/libs/proto/doc/proto.qbk
==============================================================================
--- trunk/libs/proto/doc/proto.qbk (original)
+++ trunk/libs/proto/doc/proto.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -78,7 +78,9 @@
 
 [include preface.qbk]
 
+[/===============================]
 [section:users_guide Users' Guide]
+[/===============================]
 
 This Users' Guide describes how to use Proto to build expression-template
 based Domain-Specific Embedded Langauges. It is broken up in to 5 sections,
@@ -104,11 +106,7 @@
 But before we get started, let's have a look at some very simple Proto examples
 and say a few words about Proto's philosophy.
 
-[include installation.qbk]
-
-[include quick_start.qbk]
-
-[include calculator.qbk]
+[include getting_started.qbk]
 
 [include construction.qbk]
 
@@ -122,7 +120,7 @@
 
 [include examples.qbk]
 
-[include references.qbk]
+[include resources.qbk]
 
 [include glossary.qbk]
 
@@ -130,7 +128,9 @@
 
 [xinclude proto.xml]
 
+[/=================]
 [section Appendices]
+[/=================]
 
 [include history.qbk]
 

Deleted: trunk/libs/proto/doc/quick_start.qbk
==============================================================================
--- trunk/libs/proto/doc/quick_start.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
+++ (empty file)
@@ -1,145 +0,0 @@
-[/
- / Copyright (c) 2008 Eric Niebler
- /
- / Distributed under the Boost Software License, Version 1.0. (See accompanying
- / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- /]
-
-[/================================]
-[section:naming Naming Conventions]
-[/================================]
-
-Proto is a large library and probably quite unlike any library you've used
-before. Proto uses some consistent naming conventions to make it easier to
-navigate, and they're described below.
-
-[/================]
-[heading Functions]
-[/================]
-
-All of Proto's functions are defined in the `boost::proto` namespace. For
-example, there is a function called `value()` defined in `boost::proto` that
-accepts a terminal expression and returns the terminal's value.
-
-[/====================]
-[heading Metafunctions]
-[/====================]
-
-Proto defines /metafunctions/ that correspond to each of Proto's free functions.
-The metafunctions are used to compute the functions' return types. All of
-Proto's metafunctions live in the `boost::proto::result_of` namespace and
-have the same name as the functions to which they correspond. For instance,
-there is a class template `boost::proto::result_of::value<>` that you can
-use to compute the return type of the `boost::proto::value()` function.
-
-[/=======================]
-[heading Function Objects]
-[/=======================]
-
-Proto defines /function object/ equivalents of all of its free functions. (A
-function object is an instance of a class type that defines an `operator()`
-member function.) All of Proto's function object types are defined in the
-`boost::proto::functional` namespace and have the same name as their
-corresponding free functions. For example, `boost::proto::functional::value`
-is a class that defines a function object that does the same thing as the
-`boost::proto::value()` free function.
-
-[/===========================]
-[heading Primitive Transforms]
-[/===========================]
-
-Proto also defines /primitive transforms/ -- class types that can be used
-to compose larger transforms for manipulating expression trees. Many of
-Proto's free functions have corresponding primitive transforms. These live
-in the `boost::proto` namespace and their names have a leading underscore.
-For instance, the transform corresponding to the `value()` function is
-called `boost::proto::_value`.
-
-The following table summarizes the discussion above:
-
-[table Proto Naming Conventions
- [[Entity] [Example] ]
- [[Free Function] [`boost::proto::value()`] ]
- [[Metafunction] [`boost::proto::result_of::value<>`] ]
- [[Function Object] [`boost::proto::functional::value`] ]
- [[Transform] [`boost::proto::_value`] ]
-]
-
-[endsect]
-
-[section Hello World]
-
-Below is a very simple program that uses Proto to build an expression template
-and then execute it.
-
- #include <iostream>
- #include <boost/proto/proto.hpp>
- #include <boost/proto/context.hpp>
- #include <boost/typeof/std/ostream.hpp>
- using namespace boost;
-
- proto::terminal< std::ostream & >::type cout_ = { std::cout };
-
- template< typename Expr >
- void evaluate( Expr const & expr )
- {
- proto::default_context ctx;
- proto::eval(expr, ctx);
- }
-
- int main()
- {
- evaluate( cout_ << "hello" << ',' << " world" );
- return 0;
- }
-
-This program outputs the following:
-
-[pre
-hello, world
-]
-
-This program builds an object representing the output operation and passes
-it to an `evaluate()` function, which then executes it.
-
-The basic idea of expression templates is to overload all the operators so
-that, rather than evaluating the expression immediately, they build a tree-like
-representation of the expression so that it can be evaluated later. For each
-operator in an expression, at least one operand must be Protofied in order
-for Proto's operator overloads to be found. In the expression ...
-
- cout_ << "hello" << ',' << " world"
-
-... the Protofied sub-expression is `cout_`, which is the Proto-ification of
-`std::cout`. The presence of `cout_` "infects" the expression, and brings
-Proto's tree-building operator overloads into consideration. Any literals in
-the expression are then Protofied by wrapping them in a Proto terminal before
-they are combined into larger Proto expressions.
-
-Once Proto's operator overloads have built the expression tree, the expression
-can be lazily evaluated later by walking the tree. That is what `proto::eval()`
-does. It is a general tree-walking expression evaluator, whose behavior is
-customizable via a /context/ parameter. The use of _default_context_ assigns
-the standard meanings to the operators in the expression. (By using a different
-context, you could give the operators in your expressions different semantics.
-By default, Proto makes no assumptions about what operators actually /mean/.)
-
-[/==============================]
-[heading Proto Design Philosophy]
-[/==============================]
-
-Before we continue, let's use the above example to illustrate an important
-design principle of Proto's. The expression template created in the ['hello
-world] example is totally general and abstract. It is not tied in any way to
-any particular domain or application, nor does it have any particular meaning
-or behavior on its own, until it is evaluated in a /context/. Expression
-templates are really just heterogeneous trees, which might mean something in
-one domain, and something else entirely in a different one.
-
-As we'll see later, there is a way to create Proto expression trees that are
-['not] purely abstract, and that have meaning and behaviors independent of any
-context. There is also a way to control which operators are overloaded for your
-particular domain. But that is not the default behavior. We'll see later why
-the default is often a good thing.
-
-[endsect]

Deleted: trunk/libs/proto/doc/references.qbk
==============================================================================
--- trunk/libs/proto/doc/references.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
+++ (empty file)
@@ -1,37 +0,0 @@
-[/
- / Copyright (c) 2008 Eric Niebler
- /
- / Distributed under the Boost Software License, Version 1.0. (See accompanying
- / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- /]
-
-[/=============================================]
-[section:references References and Related Work]
-[/=============================================]
-
-Proto was initially developed as part of _xpressive_ to simplify the job of
-transforming an expression template into an executable finite state machine capable
-of matching a regular expression. Since then, Proto has found application in the
-redesigned and improved Spirit-2 and the related Karma library. As a result of
-these efforts, Proto evolved into a generic and abstract grammar and tree
-transformation framework applicable in a wide variety of DSEL scenarios.
-
-The grammar and tree transformation framework is modelled on Spirit's grammar and
-semantic action framework. The expression tree data structure is similar to Fusion
-data structures in many respects, and is interoperable with Fusion's iterators and
-algorithms.
-
-The syntax for the grammar-matching features of `proto::matches<>` is inspired by
-MPL's lambda expressions, and by Aleksey Gurtovoy's
-[@http://lists.boost.org/Archives/boost/2002/11/39718.php "round" lambda] notation.
-
-[/======================]
-[heading Further Reading]
-[/======================]
-
-A technical paper about an earlier version of Proto was accepted into the
-[@http://lcsd.cs.tamu.edu/2007/ ACM SIGPLAN Symposium on Library-Centric Software
-Design LCSD'07], and can be found at [@http://lcsd.cs.tamu.edu/2007/final/1/1_Paper.pdf].
-The tree transforms described in that paper differ from what exists today.
-
-[endsect]

Copied: trunk/libs/proto/doc/resources.qbk (from r48118, /trunk/libs/proto/doc/references.qbk)
==============================================================================
--- /trunk/libs/proto/doc/references.qbk (original)
+++ trunk/libs/proto/doc/resources.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -5,9 +5,9 @@
  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  /]
 
-[/=============================================]
-[section:references References and Related Work]
-[/=============================================]
+[/=========================================]
+[section:resources Background and Resources]
+[/=========================================]
 
 Proto was initially developed as part of _xpressive_ to simplify the job of
 transforming an expression template into an executable finite state machine capable

Modified: trunk/libs/proto/doc/transforms.qbk
==============================================================================
--- trunk/libs/proto/doc/transforms.qbk (original)
+++ trunk/libs/proto/doc/transforms.qbk 2008-08-14 19:42:03 EDT (Thu, 14 Aug 2008)
@@ -34,10 +34,10 @@
 
     proto::when< proto::terminal<int>, proto::terminal<long>::type(proto::_value) >
 
-`proto::terminal<long>::type(proto::_value)` is an example of a Proto transform. It says to
-create an object of type `proto::terminal<long>::type` and initialize it with the
-result of the `proto::_value` transform. `proto::_value` is a transform defined by Proto which
-extracts the value from a terminal expression.
+`proto::terminal<long>::type(proto::_value)` is an example of a Proto transform. It
+says to create an object of type `proto::terminal<long>::type` and initialize it
+with the result of the `proto::_value` transform. `proto::_value` is a transform
+defined by Proto which extracts the value from a terminal expression.
 
 [note The transform above might look a little strange at first. It appears
 to be constructing a temporary object in place. In fact, it is a
@@ -163,6 +163,12 @@
 will be to write a transform that calculates the arity of any calculator
 expression.
 
+[note *Why Bother Calculating Expression Arity?*
+
+This is more than just an intelectual exercise. Knowing the arity of a calculator
+expression is important if you want to give users a meaningful error message when
+they specify too few or too many arguments to an expression.]
+
 [/=========================]
 [heading Defining a Grammar]
 [/=========================]
@@ -180,13 +186,12 @@
 
 [CalcGrammar]
 
-We can read this as follows: a calculator expression is either placeholder 1,
-placeholder 2, some other terminal, or some unary or binary operator whose
-operands are calculator expressions. Recall that `proto::_` is a wildcard which
-matches anything. So `proto::terminal< _ >` will match any terminal, and
-`proto::unary_expr< _, CalcArity >` will match any unary expression
-for which the operand matches `CalcArity` (the `_` matches any operator
-tag).
+We can read this as follows: a calculator expression is either placeholder 1,
+placeholder 2, some other terminal, or some unary or binary operator whose operands
+are calculator expressions. Recall that `proto::_` is a wildcard that matches
+anything. So `proto::terminal< _ >` will match any terminal, and
+`proto::unary_expr< _, CalcArity >` will match any unary expression for which the
+operand matches `CalcArity` (the `_` matches any operator tag).
 
 [/============================]
 [heading Writing the Transform]
@@ -234,15 +239,20 @@
 differently. Rather than trying to construct a `CalcArity` object, Proto
 knows this is a function object and invokes it instead.
 
-[note When using function types as Proto transforms, they can either represent
-an object to construct or a function to call. It is similar to C++ where the
-syntax `foo(x)` can either be interpreted as an object to construct or a
-function to call, depending on whether `foo` is a type or a function. Proto
-can't know in general which is the case, so it uses a trait, `proto::is_callable<>`,
-to differentiate. `is_callable< mpl::int_<1> >::value` is false so `mpl::int_<1>()`
-is an object to construct, but `is_callable< CalcArity >::value` is true so
-`CalcArity(proto::_child)` is a function to call. (`is_callable< CalcArity >::value`
-is true because `CalcArity` inherits from `proto::or_<>`, which is callable.)]
+[/================================================]
+[note *Object Transforms vs. Callable Transforms*
+
+When using function types as Proto transforms, they can either represent an object
+to construct or a function to call. It is similar to C++ where the syntax `foo(x)`
+can either be interpreted as an object to construct or a function to call,
+depending on whether `foo` is a type or a function. Proto can't know in general
+which is the case, so it uses a trait, `proto::is_callable<>`, to differentiate.
+`is_callable< mpl::int_<1> >::value` is false so `mpl::int_<1>()` is an object to
+construct, but `is_callable< CalcArity >::value` is true so
+`CalcArity(proto::_child)` is a function to call.
+(`is_callable< CalcArity >::value` is true because `CalcArity` inherits from
+`proto::or_<>`, which is callable.)]
+[/================================================]
 
 [/
     That begs the question, what does `unary_expr<>`'s transform do? Well,
@@ -352,11 +362,10 @@
 We can use our `CalcArity` transform to calculate the arity of any
 calculator expression:
 
- int i = 0; // not used, dummy state and data parameter
-
- std::cout << CalcArity()( lit(100) * 200, i, i) << '\n';
- std::cout << CalcArity()( (_1 - _1) / _1 * 100, i, i) << '\n';
- std::cout << CalcArity()( (_2 - _1) / _2 * 100, i, i) << '\n';
+ CalcArity arity_of;
+ std::cout << arity_of( proto::lit(100) * 20 ) << '\n';
+ std::cout << arity_of( (_1 - _1) / _1 * 100 ) << '\n';
+ std::cout << arity_of( (_2 - _1) / _2 * 100 ) << '\n';
 
 This displays the following:
 


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