Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r74527 - in trunk: boost/proto boost/proto/detail libs/proto/doc/reference
From: eric_at_[hidden]
Date: 2011-09-22 18:09:51


Author: eric_niebler
Date: 2011-09-22 18:09:50 EDT (Thu, 22 Sep 2011)
New Revision: 74527
URL: http://svn.boost.org/trac/boost/changeset/74527

Log:
allow dependent domains to be specified with BOOST_PROTO_EXTENDS and BOOST_PROTO_BASIC_EXTENDS
Added:
   trunk/boost/proto/detail/remove_typename.hpp (contents, props changed)
Text files modified:
   trunk/boost/proto/extends.hpp | 13 ++++++-------
   trunk/libs/proto/doc/reference/extends.xml | 9 +++++++++
   2 files changed, 15 insertions(+), 7 deletions(-)

Added: trunk/boost/proto/detail/remove_typename.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/proto/detail/remove_typename.hpp 2011-09-22 18:09:50 EDT (Thu, 22 Sep 2011)
@@ -0,0 +1,82 @@
+//==============================================================================
+// Copyright 2003 - 2011 LASMEA UMR 6602 CNRS/Univ. Clermont II
+// Copyright 2009 - 2011 LRI UMR 8623 CNRS/Univ Paris Sud XI
+// Copyright 2011 Eric Niebler
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//==============================================================================
+#ifndef BOOST_PROTO_PREPROCESSOR_REMOVE_TYPENAME_HPP_INCLUDED
+#define BOOST_PROTO_PREPROCESSOR_REMOVE_TYPENAME_HPP_INCLUDED
+
+/*!
+ * \file
+ * \brief Defines the BOOST_PROTO_REMOVE_TYPENAME macro
+ */
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/expand.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/detail/is_unary.hpp>
+
+//==============================================================================
+// Boost.Preprocessor author P. Mensodines confirmed on an Boost email thread
+// (subject ``check if a token is a keyword (was "BOOST_PP_IS_UNARY()")'')
+// that it is OK to used `PP_IS_UNARY()` to check if tokens match predefined
+// "keyword" as it is done by the macros below (even if `PP_IS_UNARY()` is
+// technically only part of Boost.Preprocessor private API).
+//==============================================================================
+
+//==============================================================================
+// `checking_prefix ## tokens` expand to unary (e.g., `(1)`) iff `tokens` start
+// with keyword to check.
+//==============================================================================
+#define BOOST_PROTO_DETAILS_KEYWORD_FACILITY_IS_FRONT(T, CHECKING_PREFIX) \
+ BOOST_PP_IS_UNARY(BOOST_PP_CAT(CHECKING_PREFIX, T)) \
+ /**/
+
+//==============================================================================
+// `is_front_macro(tokens)` is 1 iff `tokens` start with keyword to remove.
+// `removing_prefix ## <keyword-to-remove>` must expand to nothing.
+//==============================================================================
+#define BOOST_PROTO_DETAILS_KEYWORD_FACILITY_REMOVE_FRONT(TOKENS, IS_FRONT_MACRO, REMOVING_PREFIX) \
+ BOOST_PP_EXPAND( /* without EXPAND doesn't expand on MSVC */ \
+ BOOST_PP_IIF( \
+ IS_FRONT_MACRO(TOKENS) \
+ , BOOST_PP_CAT \
+ , TOKENS BOOST_PP_TUPLE_EAT(2) \
+ )(REMOVING_PREFIX, TOKENS) \
+ ) \
+ /**/
+
+#define BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS_typename (1) /* unary */
+#define typename_BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS (1) /* unary */
+#define BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE_typename /* nothing */
+#define typename_BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE /* nothing */
+
+#define BOOST_PROTO_DETAILS_KEYWORD_IS_TYPENAME_FRONT(TOKENS) \
+ BOOST_PROTO_DETAILS_KEYWORD_FACILITY_IS_FRONT(TOKENS, BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_IS_) \
+ /**/
+
+//==============================================================================
+/*!
+ * \ingroup preprocessor
+ * For any symbol \c X, this macro returns the same symbol from which a potential
+ * leading \c typename keyword has been removed. If no typename keyword is present,
+ * this macros evaluates to \c X itself without error.
+ *
+ * The original implementation of this macro is from Lorenzo Caminiti.
+ *
+ * \param X Symbol to remove \c typename from
+ */
+//==============================================================================
+#define BOOST_PROTO_REMOVE_TYPENAME(X) \
+ BOOST_PROTO_DETAILS_KEYWORD_FACILITY_REMOVE_FRONT( \
+ X \
+ , BOOST_PROTO_DETAILS_KEYWORD_IS_TYPENAME_FRONT \
+ , BOOST_PROTO_DETAILS_KEYWORD_TYPENAME_REMOVE_ \
+ ) \
+ /**/
+
+#endif

Modified: trunk/boost/proto/extends.hpp
==============================================================================
--- trunk/boost/proto/extends.hpp (original)
+++ trunk/boost/proto/extends.hpp 2011-09-22 18:09:50 EDT (Thu, 22 Sep 2011)
@@ -32,6 +32,7 @@
 #include <boost/proto/args.hpp>
 #include <boost/proto/traits.hpp>
 #include <boost/proto/generate.hpp>
+#include <boost/proto/detail/remove_typename.hpp>
 
 #ifdef _MSC_VER
 #define BOOST_PROTO_DISABLE_MSVC_C4522 __pragma(warning(disable: 4522))
@@ -160,15 +161,16 @@
                                                                                                     \
         typedef Expr proto_base_expr_; /**< INTERNAL ONLY */ \
         typedef typename proto_base_expr_::proto_base_expr proto_base_expr; \
- typedef Domain proto_domain; \
+ typedef BOOST_PROTO_REMOVE_TYPENAME(Domain) proto_domain; \
         typedef Derived proto_derived_expr; \
+ typedef Domain::proto_generator proto_generator; \
         typedef typename proto_base_expr::proto_tag proto_tag; \
         typedef typename proto_base_expr::proto_args proto_args; \
         typedef typename proto_base_expr::proto_arity proto_arity; \
         typedef typename proto_base_expr::proto_grammar proto_grammar; \
         typedef typename proto_base_expr::address_of_hack_type_ proto_address_of_hack_type_; \
         typedef void proto_is_expr_; /**< INTERNAL ONLY */ \
- static const long proto_arity_c = proto_base_expr::proto_arity_c; \
+ static const long proto_arity_c = proto_base_expr::proto_arity_c; \
         typedef boost::proto::tag::proto_expr fusion_tag; \
         BOOST_PP_REPEAT(BOOST_PROTO_MAX_ARITY, BOOST_PROTO_EXTENDS_CHILD, ~) \
                                                                                                     \
@@ -197,7 +199,6 @@
     #define BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, Domain) \
         BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain) \
         typedef void proto_is_aggregate_; \
- typedef Domain::proto_generator proto_generator; \
         /**< INTERNAL ONLY */
 
     #define BOOST_PROTO_EXTENDS_COPY_ASSIGN_IMPL_(This, Const, Typename) \
@@ -504,8 +505,7 @@
             {}
 
             typedef extends proto_extends;
- BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain)
- typedef typename Domain::proto_generator proto_generator;
+ BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, typename Domain)
             BOOST_PROTO_EXTENDS_ASSIGN_CONST_()
             BOOST_PROTO_EXTENDS_SUBSCRIPT_CONST()
 
@@ -533,8 +533,7 @@
             {}
 
             typedef extends proto_extends;
- BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, Domain)
- typedef typename Domain::proto_generator proto_generator;
+ BOOST_PROTO_BASIC_EXTENDS_(Expr, Derived, typename Domain)
             BOOST_PROTO_EXTENDS_ASSIGN_()
             BOOST_PROTO_EXTENDS_SUBSCRIPT()
 

Modified: trunk/libs/proto/doc/reference/extends.xml
==============================================================================
--- trunk/libs/proto/doc/reference/extends.xml (original)
+++ trunk/libs/proto/doc/reference/extends.xml 2011-09-22 18:09:50 EDT (Thu, 22 Sep 2011)
@@ -378,6 +378,10 @@
 <macroname>BOOST_PROTO_EXTENDS_SUBSCRIPT</macroname>()
 <macroname>BOOST_PROTO_EXTENDS_FUNCTION</macroname>()</programlisting>
       </para>
+ <para>If the <computeroutput>Domain</computeroutput> parameter is dependent, you can specify it as
+ <computeroutput>typename Domain</computeroutput>, as in
+ <computeroutput>BOOST_PROTO_EXTENDS(Expr, Derived, typename Domain)</computeroutput>
+ </para>
       <para>
         <emphasis role="bold">Example:</emphasis><programlisting>template&lt; class Expr &gt;
 struct my_expr;
@@ -420,10 +424,15 @@
         <computeroutput>Derived</computeroutput> is the type of the enclosing struct.
         <computeroutput>Domain</computeroutput> is the Proto domain to which this expression extension belongs.
         (See <computeroutput><classname alt="boost::proto::domain">proto::domain&lt;&gt;</classname></computeroutput>.)
+ Can be preceeded with "<computeroutput>typename</computeroutput>" if the specified domain is a dependent type.
       </para>
       <para><computeroutput>BOOST_PROTO_BASIC_EXTENDS()</computeroutput> adds to its enclosing struct
         exactly one data member of type <computeroutput>Expr</computeroutput>.
       </para>
+ <para>If the <computeroutput>Domain</computeroutput> parameter is dependent, you can specify it as
+ <computeroutput>typename Domain</computeroutput>, as in
+ <computeroutput>BOOST_PROTO_BASIC_EXTENDS(Expr, Derived, typename Domain)</computeroutput>
+ </para>
       <para>
         <emphasis role="bold">Example:</emphasis><programlisting>template&lt; class Expr &gt;
 struct my_expr;


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