$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r67963 - in trunk: boost/spirit/home/qi/detail boost/spirit/home/support libs/spirit/test libs/spirit/test/qi
From: hartmut.kaiser_at_[hidden]
Date: 2011-01-11 11:18:21
Author: hkaiser
Date: 2011-01-11 11:18:19 EST (Tue, 11 Jan 2011)
New Revision: 67963
URL: http://svn.boost.org/trac/boost/changeset/67963
Log:
Spirit: fixing regression in netlib url parser
Added:
   trunk/libs/spirit/test/qi/regression_transform_assignment.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/qi/detail/assign_to.hpp    |    10 +++++++---                              
   trunk/boost/spirit/home/support/attributes.hpp     |     4 ++--                                    
   trunk/boost/spirit/home/support/attributes_fwd.hpp |     8 +++++++-                                
   trunk/libs/spirit/test/Jamfile                     |     1 +                                       
   4 files changed, 17 insertions(+), 6 deletions(-)
Modified: trunk/boost/spirit/home/qi/detail/assign_to.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/assign_to.hpp	(original)
+++ trunk/boost/spirit/home/qi/detail/assign_to.hpp	2011-01-11 11:18:19 EST (Tue, 11 Jan 2011)
@@ -234,7 +234,8 @@
             assign_to_attribute_from_value<Attribute, T>::call(val, attr);
         }
 
-        // overload for containers (but not for variants holding containers)
+        // overload for containers (but not for variants or optionals 
+        // holding containers)
         template <typename T, typename Attribute>
         inline void
         assign_to(T const& val, Attribute& attr, mpl::true_, mpl::true_)
@@ -248,9 +249,12 @@
     assign_to(T const& val, Attribute& attr)
     {
         typedef typename traits::is_container<Attribute>::type is_container;
-        typedef typename traits::not_is_variant<Attribute>::type not_is_variant;
+        typedef typename mpl::and_<
+            traits::not_is_variant<Attribute>
+          , traits::not_is_optional<Attribute> 
+        >::type is_not_wrapped_container;
 
-        detail::assign_to(val, attr, is_container(), not_is_variant());
+        detail::assign_to(val, attr, is_container(), is_not_wrapped_container());
     }
 
     template <typename T>
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp	(original)
+++ trunk/boost/spirit/home/support/attributes.hpp	2011-01-11 11:18:19 EST (Tue, 11 Jan 2011)
@@ -68,7 +68,7 @@
         >::type>
       : mpl::true_ {};
 
-    template <typename T, typename Domain>
+    template <typename T, typename Domain, typename Enable/* = void*/>
     struct not_is_variant
       : mpl::true_
     {};
@@ -203,7 +203,7 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
-    template <typename T, typename Domain>
+    template <typename T, typename Domain, typename Enable/* = void*/>
     struct not_is_optional
       : mpl::true_
     {};
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	2011-01-11 11:18:19 EST (Tue, 11 Jan 2011)
@@ -149,10 +149,16 @@
     ///////////////////////////////////////////////////////////////////////////
     // Determine, whether T is a variant like type
     ///////////////////////////////////////////////////////////////////////////
-    template <typename T, typename Domain = void>
+    template <typename T, typename Domain = unused_type, typename Enable = void>
     struct not_is_variant;
 
     ///////////////////////////////////////////////////////////////////////////
+    // Determine, whether T is a variant like type
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename T, typename Domain = unused_type, typename Enable = void>
+    struct not_is_optional;
+
+    ///////////////////////////////////////////////////////////////////////////
     // Clear data efficiently
     ///////////////////////////////////////////////////////////////////////////
     template <typename T, typename Enable = void>
Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile	(original)
+++ trunk/libs/spirit/test/Jamfile	2011-01-11 11:18:19 EST (Tue, 11 Jan 2011)
@@ -108,6 +108,7 @@
      [ run qi/regression_lazy_repeat.cpp                       : : : : qi_regression_lazy_repeat ]
      [ run qi/regression_reorder.cpp                           : : : : qi_regression_reorder ]
      [ run qi/regression_repeat.cpp                            : : : : qi_regression_repeat ]
+     [ run qi/regression_transform_assignment.cpp              : : : : qi_regression_transform_assignment ]
 
     ;
 
Added: trunk/libs/spirit/test/qi/regression_transform_assignment.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/qi/regression_transform_assignment.cpp	2011-01-11 11:18:19 EST (Tue, 11 Jan 2011)
@@ -0,0 +1,74 @@
+//  Copyright (c) 2001-2011 Hartmut Kaiser
+//  Copyright (c) 2011 Dean Michael Berries
+// 
+//  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/detail/lightweight_test.hpp>
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/fusion/tuple.hpp>
+#include <string>
+
+struct foo_parts 
+{
+    boost::optional<std::string> first;
+    std::string second;
+};
+
+namespace boost { namespace spirit { namespace traits 
+{
+    template <>
+    struct transform_attribute<foo_parts
+      , fusion::tuple<std::string &, optional<std::string> &>
+      , spirit::qi::domain>
+    {
+        typedef fusion::tuple<std::string&, optional<std::string>&> type;
+
+        static type pre(foo_parts & parts) 
+        {
+            return fusion::tie(parts.second, parts.first);
+        }
+
+        static void post(foo_parts &, type const &) {}
+        static void fail(foo_parts &) {}
+    };
+}}}    
+
+namespace qi = boost::spirit::qi;
+
+template <typename Iterator>
+struct foo_grammar : qi::grammar<Iterator, foo_parts()> 
+{
+    foo_grammar() : foo_grammar::base_type(start, "foo") 
+    {
+        foo_part = 
+               +qi::alpha >> -(+qi::digit)
+            |   qi::attr(std::string()) 
+                >> qi::attr(boost::optional<std::string>())
+            ;
+
+        start = foo_part.alias();
+    }
+
+    typedef boost::fusion::tuple<std::string&, boost::optional<std::string>&>
+        tuple_type;
+
+    qi::rule<Iterator, tuple_type()> foo_part;
+    qi::rule<Iterator, foo_parts()> start;
+};
+
+int main(int argc, char * argv[]) 
+{
+    foo_parts instance;
+    foo_grammar<std::string::iterator> grammar;
+    std::string input = "abc123";
+    
+    BOOST_TEST(qi::parse(input.begin(), input.end(), grammar, instance) &&
+        instance.first && instance.first.get() == "123" && 
+        instance.second == "abc");
+
+    return boost::report_errors();
+}
+