$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r61328 - in trunk: boost/spirit/home/support libs/spirit/test libs/spirit/test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2010-04-16 18:47:14
Author: hkaiser
Date: 2010-04-16 18:47:13 EDT (Fri, 16 Apr 2010)
New Revision: 61328
URL: http://svn.boost.org/trac/boost/changeset/61328
Log:
Spirit: fixed attribute propagation of optionals in rules
Added:
   trunk/libs/spirit/test/karma/karma_optional_double.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/support/attributes.hpp     |    10 ++++++-                                 
   trunk/boost/spirit/home/support/attributes_fwd.hpp |    51 +++++++++++++++++++++------------------ 
   trunk/libs/spirit/test/Jamfile                     |     1                                         
   3 files changed, 37 insertions(+), 25 deletions(-)
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp	(original)
+++ trunk/boost/spirit/home/support/attributes.hpp	2010-04-16 18:47:13 EDT (Fri, 16 Apr 2010)
@@ -649,7 +649,10 @@
     struct transform_attribute<Exposed, Transformed, karma::domain>
     {
         typedef Transformed type;
-        static Transformed pre(Exposed& val) { return Transformed(val); }
+        static Transformed pre(Exposed& val) 
+        { 
+            return Transformed(extract_from<Exposed>(val, unused));
+        }
         // Karma only, no post() and no fail() required
     };
 
@@ -657,7 +660,10 @@
     struct transform_attribute<Exposed const, Transformed, karma::domain>
     {
         typedef Transformed type;
-        static Transformed pre(Exposed const& val) { return Transformed(val); }
+        static Transformed pre(Exposed const& val) 
+        { 
+            return Transformed(extract_from<Exposed>(val, unused));
+        }
         // Karma only, no post() and no fail() required
     };
 
Modified: trunk/boost/spirit/home/support/attributes_fwd.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes_fwd.hpp	(original)
+++ trunk/boost/spirit/home/support/attributes_fwd.hpp	2010-04-16 18:47:13 EDT (Fri, 16 Apr 2010)
@@ -12,6 +12,30 @@
 #pragma once
 #endif
 
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace result_of
+{
+    // forward declaration only
+    template <typename Exposed, typename Attribute>
+    struct extract_from;
+
+    template <typename Exposed, typename Transformed, typename Domain>
+    struct pre_transform;
+
+    template <typename T>
+    struct optional_value;
+
+    template <typename Container>
+    struct begin;
+
+    template <typename Container>
+    struct end;
+
+    template <typename Iterator>
+    struct deref;
+}}}
+
+///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit { namespace traits
 {
     ///////////////////////////////////////////////////////////////////////////
@@ -66,6 +90,10 @@
     template <typename Attribute, typename Exposed, typename Enable = void>
     struct extract_from_attribute;
 
+    template <typename Exposed, typename Attribute, typename Context>
+    typename spirit::result_of::extract_from<Exposed, Attribute>::type
+    extract_from(Attribute const& attr, Context& ctx);
+
     ///////////////////////////////////////////////////////////////////////////
     // Clear data efficiently
     ///////////////////////////////////////////////////////////////////////////
@@ -112,28 +140,5 @@
     struct compare_iterators;
 }}}
 
-///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace result_of
-{
-    // forward declaration only
-    template <typename Exposed, typename Attribute>
-    struct extract_from;
-
-    template <typename Exposed, typename Transformed, typename Domain>
-    struct pre_transform;
-
-    template <typename T>
-    struct optional_value;
-
-    template <typename Container>
-    struct begin;
-
-    template <typename Container>
-    struct end;
-
-    template <typename Iterator>
-    struct deref;
-}}}
-
 #endif
 
Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile	(original)
+++ trunk/libs/spirit/test/Jamfile	2010-04-16 18:47:13 EDT (Fri, 16 Apr 2010)
@@ -153,6 +153,7 @@
     # regression tests
     [ run qi/clear_test.cpp                 : : : : ]
     [ run qi/reorder_test.cpp               : : : : ]
+    [ run karma/karma_optional_double.cpp   : : : : ]
 
     ;
 
Added: trunk/libs/spirit/test/karma/karma_optional_double.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/karma/karma_optional_double.cpp	2010-04-16 18:47:13 EDT (Fri, 16 Apr 2010)
@@ -0,0 +1,52 @@
+//  Copyright (c) 2010 Olaf Peter
+//  Copyright (c) 2001-2010 Hartmut Kaiser
+// 
+//  Distributed under the Boost Software License, Version 1.0. (See accompanying 
+//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/config/warning_disable.hpp>
+#include <boost/spirit/include/karma.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+namespace client
+{
+    namespace karma = boost::spirit::karma;
+
+    template <typename OutputIterator>
+    struct grammar
+        : karma::grammar<OutputIterator, boost::optional<double>()>
+    {
+        grammar()
+          : grammar::base_type(start)
+        {
+            using karma::double_;
+
+            u = double_ << "U";
+            start = ( !double_ << "NA" ) | u;
+
+            start.name("start"); 
+            u.name("u");
+        }
+
+        karma::rule<OutputIterator, double()> u;
+        karma::rule<OutputIterator, boost::optional<double>()> start;
+    };
+}
+
+int main()
+{
+    namespace karma = boost::spirit::karma;
+
+    typedef std::back_insert_iterator<std::string> sink_type;
+
+    boost::optional<double> d1, d2;
+    d2 = 1.0;
+
+    std::string generated1, generated2;
+    client::grammar<sink_type> g;
+
+    BOOST_TEST(karma::generate(sink_type(generated1), g, d1) && generated1 == "NA");
+    BOOST_TEST(karma::generate(sink_type(generated2), g, d2) && generated2 == "1.0U");
+
+    return boost::report_errors();
+}