$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r66200 - in trunk: boost/proto/transform libs/proto/doc libs/proto/doc/reference/transform
From: eric_at_[hidden]
Date: 2010-10-26 01:42:16
Author: eric_niebler
Date: 2010-10-26 01:42:13 EDT (Tue, 26 Oct 2010)
New Revision: 66200
URL: http://svn.boost.org/trac/boost/changeset/66200
Log:
small tweak, add docs for external transforms
Text files modified: 
   trunk/boost/proto/transform/when.hpp              |     1                                         
   trunk/libs/proto/doc/reference.xml                |    10 ++                                      
   trunk/libs/proto/doc/reference/transform/when.xml |   137 ++++++++++++++++++++++++++++++++++++++- 
   3 files changed, 143 insertions(+), 5 deletions(-)
Modified: trunk/boost/proto/transform/when.hpp
==============================================================================
--- trunk/boost/proto/transform/when.hpp	(original)
+++ trunk/boost/proto/transform/when.hpp	2010-10-26 01:42:13 EDT (Tue, 26 Oct 2010)
@@ -112,6 +112,7 @@
         /// See \c action_map for an example.
         template<typename Grammar>
         struct when<Grammar, external_transform>
+          : proto::transform<when<Grammar, external_transform> >
         {
             typedef Grammar first;
             typedef external_transform second;
Modified: trunk/libs/proto/doc/reference.xml
==============================================================================
--- trunk/libs/proto/doc/reference.xml	(original)
+++ trunk/libs/proto/doc/reference.xml	2010-10-26 01:42:13 EDT (Tue, 26 Oct 2010)
@@ -257,6 +257,16 @@
       </listitem>
       <listitem>
         <computeroutput>
+          <classname alt="boost::proto::external_transform">proto::external_transform</classname>
+        </computeroutput>
+      </listitem>
+      <listitem>
+        <computeroutput>
+          <classname alt="boost::proto::external_transforms">proto::external_transforms</classname>
+        </computeroutput>
+      </listitem>
+      <listitem>
+        <computeroutput>
           <classname alt="boost::proto::fold">proto::fold</classname>
         </computeroutput>
       </listitem>
Modified: trunk/libs/proto/doc/reference/transform/when.xml
==============================================================================
--- trunk/libs/proto/doc/reference/transform/when.xml	(original)
+++ trunk/libs/proto/doc/reference/transform/when.xml	2010-10-26 01:42:13 EDT (Tue, 26 Oct 2010)
@@ -69,7 +69,7 @@
           <template-arg>Grammar</template-arg>
           <template-arg>Fun *</template-arg>
         </specialization>
-        <inherit><classname>proto::when</classname>< Grammar, Fun ></inherit>
+        <inherit><type><classname>proto::when</classname>< Grammar, Fun ></type></inherit>
         <purpose>A specialization that treats function pointer <conceptname>Transform</conceptname>s as if they
           were function type <conceptname>Transform</conceptname>s.</purpose>
         <description>
@@ -97,8 +97,8 @@
           <template-arg>Grammar</template-arg>
           <template-arg>R(A...)</template-arg>
         </specialization>
-        <inherit><classname>proto::transform</classname>< when<Grammar, R(A...)> ></inherit>
-        <purpose>A grammar element and a <conceptname>PrimitiveTransform</conceptname> that associates a
+        <inherit><type><classname>proto::transform</classname>< when<Grammar, R(A...)> ></type></inherit>
+        <purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a
           transform with the grammar. </purpose>
         <description>
           <para>
@@ -124,7 +124,7 @@
             <template-type-parameter name="State"/>
             <template-type-parameter name="Data"/>
           </template>
-          <inherit><classname>proto::transform_impl</classname>< Expr, State, Data ></inherit>
+          <inherit><type><classname>proto::transform_impl</classname>< Expr, State, Data ></type></inherit>
           <typedef name="call_">
             <purpose>For exposition only</purpose>
             <type><classname>proto::call</classname><R(A...)></type>
@@ -188,12 +188,59 @@
           <type>typename Grammar::proto_grammar</type>
         </typedef>
       </struct-specialization>
+
+      <struct-specialization name="when">
+        <template>
+          <template-type-parameter name="Grammar"/>
+        </template>
+        <specialization>
+          <template-arg>Grammar</template-arg>
+          <template-arg><classname>proto::external_transform</classname></template-arg>
+        </specialization>
+        <inherit><type>
+  <classname>proto::transform</classname>< when<Grammar, <classname>proto::external_transform</classname>> ></type></inherit>
+        <purpose>A grammar element that associates an externally-specified transform with the grammar.
+          The transform is looked up in the Data parameter using the Grammar as a key.</purpose>
+        <description>
+          <para>
+            Use <computeroutput>proto::when<></computeroutput> to override a grammar's default
+            transform with a custom transform. It is for use when composing larger transforms by associating
+            smaller transforms with individual rules in your grammar.
+          </para>
+          <para>
+            The <computeroutput>when<G, <classname>proto::external_transform</classname>></computeroutput>
+            indicates that the associated transform is not yet known. It should be looked up when the transform
+            is about to be applied. It is found by looking it up in the passed-in Data parameter, which
+            behaves like a compile-time map from grammar types to transform types. The map is indexed using
+            <computeroutput>Grammar</computeroutput> as a key. The associated value type is used as the transform
+            to apply. In this way, the same grammar can be used to define multiple evaluating strategies that
+            can be added post-hoc.
+          </para>
+          <para>
+            See <computeroutput><classname>proto::external_transforms</classname></computeroutput> for an example.
+          </para>
+        </description>
+        <struct name="impl">
+          <template>
+            <template-type-parameter name="Expr"/>
+            <template-type-parameter name="State"/>
+            <template-type-parameter name="Data"/>
+          </template>
+          <inherit><type>
+    boost::remove_reference< Data >::type
+      ::template when< Grammar >
+        ::template impl< Expr, State, Data ></type></inherit>
+        </struct>
+        <typedef name="proto_grammar">
+          <type>typename Grammar::proto_grammar</type>
+        </typedef>
+      </struct-specialization>
       
       <struct name="otherwise">
         <template>
           <template-type-parameter name="Fun"/>
         </template>
-        <inherit><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></inherit>
+        <inherit><type><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></type></inherit>
         <purpose>
           Syntactic sugar for <computeroutput><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></computeroutput>,
           for use in grammars to handle all the cases not yet handled.
@@ -216,6 +263,86 @@
           </para>
         </description>
       </struct>
+
+      <struct name="external_transform">
+        <purpose>A placeholder for use as the second parameter for <computeroutput><classname>proto::when</classname></computeroutput>
+          to indicate that the rule's transform is specified externally.</purpose>
+        <description>
+          <para>
+            See <computeroutput><classname>proto::external_transforms</classname></computeroutput> for an example.
+          </para>
+        </description>
+      </struct>
+      
+      <struct name="external_transforms">
+        <template>
+          <template-type-parameter name="When" pack="1"/>
+        </template>
+        <purpose>A map from grammars to transforms, used as a way to externally associate transforms.</purpose>
+        <typedef name="map_type">
+          <purpose>For exposition only.</purpose>
+          <type>mpl::map< typename to_mpl_pair< When >::type... ></type>
+        </typedef>
+        <struct name="when">
+          <template>
+            <template-type-parameter name="Grammar"/>
+          </template>
+          <inherit><type><classname>proto::otherwise</classname>< typename mpl::at< map_type, Grammar >::type ></type></inherit>
+        </struct>
+        <description>
+          <para>
+            It is sometimes desirable to define a grammar that can be customized with different sets of transforms.
+            To do that, where you would normally specify a transform within a grammar, you can instead put
+            <computeroutput><classname>proto::external_transform</classname></computeroutput>; for example:
+            <computeroutput>proto::when< some_grammar, proto::external_transform ></computeroutput>. Then, when
+            invoking the grammar, you can pass an approriately-defined instance of <computeroutput>proto::external_transforms</computeroutput>
+            as the Data parameter. When an expression matches <computeroutput>some_grammar</computeroutput>, Proto
+            will look up the approprite transform in the Data parameter using <computeroutput>some_grammar</computeroutput>
+            as a key.
+          </para>
+          <para>
+            <programlisting>struct int_terminal
+  : <classname>proto::terminal</classname><int>
+{};
+
+struct char_terminal
+  : <classname>proto::terminal</classname><char>
+{};
+
+struct my_grammar
+  : <classname>proto::or_</classname><
+        // The next two grammar rules are customization points.
+        // The associated transforms are specified externally
+        // using external_transforms below.
+        <classname>proto::when</classname>< int_terminal, <classname>proto::external_transform</classname> >
+      , <classname>proto::when</classname>< char_terminal, <classname>proto::external_transform</classname> >
+      , <classname>proto::when</classname><
+            <classname>proto::plus</classname>< my_grammar, my_grammar >
+          , <classname>proto::fold</classname>< <classname>proto::_</classname>, int(), my_grammar >
+        >
+    >
+{};
+
+// Here is where the transforms are associated with the
+// grammar rules above.
+struct my_transforms
+  : proto::external_transforms<
+        <classname>proto::when</classname><int_terminal, print(<classname>proto::_value</classname>)>
+      , <classname>proto::when</classname><char_terminal, print(<classname>proto::_value</classname>)>
+    >
+{};
+
+// ...
+
+<classname>proto::literal</classname><int> i(1);
+<classname>proto::literal</classname><char> c('a');
+my_transforms trx;
+
+// Evaluate "i+c" using my_grammar with the specified transforms:
+my_grammar()(i + c, 0, trx);</programlisting>
+          </para>
+        </description>
+      </struct>    
     </namespace>
   </namespace>
 </header>