$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r76462 - in trunk: boost/spirit/home/support libs/spirit/doc libs/spirit/test libs/spirit/test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2012-01-13 13:46:13
Author: hkaiser
Date: 2012-01-13 13:46:11 EST (Fri, 13 Jan 2012)
New Revision: 76462
URL: http://svn.boost.org/trac/boost/changeset/76462
Log:
Spirit: Fixed a problem in Karma when a variant holding a container was used as a generator inside a sequence.
Added:
   trunk/libs/spirit/test/karma/regression_container_variant_sequence.cpp   (contents, props changed)
Text files modified: 
   trunk/boost/spirit/home/support/attributes.hpp |    25 ++++++++++++++++++++++++-               
   trunk/libs/spirit/doc/what_s_new.qbk           |     4 +++-                                    
   trunk/libs/spirit/test/Jamfile                 |     1 +                                       
   3 files changed, 28 insertions(+), 2 deletions(-)
Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp	(original)
+++ trunk/boost/spirit/home/support/attributes.hpp	2012-01-13 13:46:11 EST (Fri, 13 Jan 2012)
@@ -1,6 +1,6 @@
 /*=============================================================================
     Copyright (c) 2001-2011 Joel de Guzman
-    Copyright (c) 2001-2011 Hartmut Kaiser
+    Copyright (c) 2001-2012 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)
@@ -520,6 +520,29 @@
         }
     };
 
+    namespace detail
+    {
+        struct attribute_size_visitor : static_visitor<>
+        {
+            template <typename T>
+            typename attribute_size<T>::type operator()(T const& val) const
+            {
+                return spirit::traits::size(val);
+            }
+        };
+    }
+
+    template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+    struct attribute_size<variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+    {
+        typedef std::size_t type;
+
+        static void call(variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& val)
+        {
+            apply_visitor(detail::attribute_size_visitor(), val);
+        }
+    };
+
     template <typename Iterator>
     struct attribute_size<iterator_range<Iterator> >
     {
Modified: trunk/libs/spirit/doc/what_s_new.qbk
==============================================================================
--- trunk/libs/spirit/doc/what_s_new.qbk	(original)
+++ trunk/libs/spirit/doc/what_s_new.qbk	2012-01-13 13:46:11 EST (Fri, 13 Jan 2012)
@@ -1,6 +1,6 @@
 [/==============================================================================
     Copyright (C) 2001-2011 Joel de Guzman
-    Copyright (C) 2001-2011 Hartmut Kaiser
+    Copyright (C) 2001-2012 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)
@@ -27,6 +27,8 @@
   (thanks to Lee Clagett for submitting a patch).
 * Fixed __karma__ examples (thanks to Lee Clagett for submitting a patch).
 * Fixed #6368: [multi_pass] clear_queue isn't forwarded to the storage policy.
+* Fixed a problem in __karma__ when a variant holding a container was used as
+  a generator inside a sequence.
 
 [endsect]
 
Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile	(original)
+++ trunk/libs/spirit/test/Jamfile	2012-01-13 13:46:11 EST (Fri, 13 Jan 2012)
@@ -249,6 +249,7 @@
      [ run karma/regression_semantic_action_attribute.cpp  : : : :  karma_regression_semantic_action_attribute ]
      [ run karma/regression_real_scientific.cpp            : : : :  karma_regression_real_scientific ]
      [ run karma/regression_center_alignment.cpp           : : : :  karma_regression_center_alignment ]
+     [ run karma/regression_container_variant_sequence.cpp : : : :  regression_container_variant_sequence ]
 
     ;
 
Added: trunk/libs/spirit/test/karma/regression_container_variant_sequence.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/karma/regression_container_variant_sequence.cpp	2012-01-13 13:46:11 EST (Fri, 13 Jan 2012)
@@ -0,0 +1,79 @@
+//  Copyright (c) 2001-2012 Hartmut Kaiser
+//  Copyright (c) 2012 bschindler
+//
+//  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/detail/lightweight_test.hpp>
+
+#include <boost/spirit/include/karma.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/fusion/include/adapt_struct.hpp>
+#include <set>
+
+namespace generator
+{
+    struct Enum
+    {
+        std::string enumName;
+        std::vector<std::string> enumEntries;
+    };
+    typedef boost::variant<std::string, Enum> VariantType;
+
+    namespace spirit = boost::spirit;
+    namespace karma = spirit::karma;
+    namespace phoenix = boost::phoenix;
+
+    // Our grammar definition
+    template<typename Iterator>
+    struct SettingsHeaderGenerator: karma::grammar<Iterator, VariantType()>
+    {
+        SettingsHeaderGenerator() : SettingsHeaderGenerator::base_type(baseRule)
+        {
+            using phoenix::insert;
+            using phoenix::at_c;
+            using phoenix::push_back;
+            using phoenix::ref;
+            using karma::lit;
+            using karma::string;
+            using namespace karma::labels;
+
+            enumRule = lit("enum ") << string << lit("\n{\n") << string % ",\n" << "}";
+            declarationRule = lit("class ") << string << ';';
+            baseRule = (declarationRule | enumRule) << lit("\n");
+
+            baseRule.name("base");
+            enumRule.name("enum");
+            declarationRule.name("declaration");
+        }
+
+        karma::rule<Iterator, std::string()> declarationRule;
+        karma::rule<Iterator, Enum()> enumRule;
+        karma::rule<Iterator, VariantType()> baseRule;
+    };
+
+    template <typename OutputIterator>
+    bool generate_header(OutputIterator& sink, VariantType& data)
+    {
+        SettingsHeaderGenerator<OutputIterator> generator;
+        return karma::generate(sink, generator, data);
+    }
+}
+
+BOOST_FUSION_ADAPT_STRUCT(generator::Enum,
+    (std::string, enumName)
+    (std::vector<std::string>, enumEntries)
+);
+
+int main()
+{
+    generator::VariantType variant = "bla";
+    std::string generated;
+    std::back_insert_iterator<std::string> sink(generated);
+    BOOST_TEST(generator::generate_header(sink, variant));
+    BOOST_TEST(generated == "class bla;\n");
+
+    return boost::report_errors();
+}
+