Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r53585 - in trunk: boost/spirit/home/karma/detail boost/spirit/home/karma/operator boost/spirit/home/qi/detail boost/spirit/home/support libs/spirit/test/karma
From: hartmut.kaiser_at_[hidden]
Date: 2009-06-02 20:06:00


Author: hkaiser
Date: 2009-06-02 20:05:58 EDT (Tue, 02 Jun 2009)
New Revision: 53585
URL: http://svn.boost.org/trac/boost/changeset/53585

Log:
Spirit: fixed a problem with Karma alternatives
Text files modified:
   trunk/boost/spirit/home/karma/detail/alternative_function.hpp | 42 +++++++++++++++++++++++++++++++++++----
   trunk/boost/spirit/home/karma/operator/sequence.hpp | 15 ++++++++++++-
   trunk/boost/spirit/home/qi/detail/alternative_function.hpp | 10 --------
   trunk/boost/spirit/home/support/attributes.hpp | 8 +++++++
   trunk/libs/spirit/test/karma/alternative.cpp | 10 +++++++++
   5 files changed, 69 insertions(+), 16 deletions(-)

Modified: trunk/boost/spirit/home/karma/detail/alternative_function.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/alternative_function.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/alternative_function.hpp 2009-06-02 20:05:58 EDT (Tue, 02 Jun 2009)
@@ -28,21 +28,38 @@
     // A component is compatible to a given Attribute type if the Attribute
     // is the same as the expected type of the component
     ///////////////////////////////////////////////////////////////////////////
+ template <typename Expected, typename Attribute, typename IsNotVariant>
+ struct compute_compatible_component_variant
+ {
+ typedef mpl::int_<-1> distance;
+ typedef typename is_same<Expected, Attribute>::type type;
+ enum { value = type::value };
+ };
+
     template <typename Expected, typename Attribute>
- struct compute_compatible_component
+ struct compute_compatible_component_variant<Expected, Attribute, mpl::false_>
     {
         typedef typename Attribute::types types;
         typedef typename mpl::end<types>::type end;
- typedef typename mpl::begin<types>::type begin;
 
         typedef typename
             mpl::find_if<types, is_same<Expected, mpl::_1> >::type
         iter;
 
+ typedef typename mpl::distance<
+ typename mpl::begin<types>::type, iter
+ >::type distance;
+
         typedef typename mpl::not_<is_same<iter, end> >::type type;
         enum { value = type::value };
     };
 
+ template <typename Expected, typename Attribute>
+ struct compute_compatible_component
+ : compute_compatible_component_variant<Expected, Attribute
+ , typename spirit::traits::not_is_variant<Attribute>::type>
+ {};
+
     template <typename Expected>
     struct compute_compatible_component<Expected, unused_type>
       : mpl::false_ {};
@@ -111,13 +128,28 @@
         call(Component const& component, OutputIterator& sink,
             Context& ctx, Delimiter const& d, Attribute const& attr)
         {
+ return call(component, sink, ctx, d, attr
+ , spirit::traits::not_is_variant<Attribute>());
+ }
+
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& d, Attribute const& attr, mpl::true_)
+ {
+ return component.generate(sink, ctx, d, attr);
+ }
+
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& d, Attribute const& attr, mpl::false_)
+ {
             typedef
                 compute_compatible_component<Expected, Attribute>
             component_type;
 
- typedef typename mpl::distance<
- typename component_type::begin, typename component_type::iter
- >::type distance_type;
+ typedef typename component_type::distance distance_type;
 
             // make sure, the content of the passed variant matches our
             // expectations

Modified: trunk/boost/spirit/home/karma/operator/sequence.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/operator/sequence.hpp (original)
+++ trunk/boost/spirit/home/karma/operator/sequence.hpp 2009-06-02 20:05:58 EDT (Tue, 02 Jun 2009)
@@ -16,6 +16,7 @@
 #include <boost/spirit/home/karma/meta_compiler.hpp>
 #include <boost/spirit/home/karma/detail/fail_function.hpp>
 #include <boost/spirit/home/karma/detail/pass_container.hpp>
+#include <boost/spirit/home/karma/detail/output_iterator.hpp>
 #include <boost/spirit/home/support/info.hpp>
 #include <boost/spirit/home/support/detail/what_function.hpp>
 #include <boost/spirit/home/support/attributes.hpp>
@@ -120,8 +121,18 @@
         bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
           , Attribute const& attr) const
         {
- return generate_impl(sink, ctx, d, attr
- , traits::is_container<Attribute>());
+ // wrap the given output iterator avoid output as long as one
+ // component of the sequence fails
+ detail::enable_buffering<OutputIterator> buffering(sink);
+ bool r = false;
+ {
+ detail::disable_counting<OutputIterator> nocounting(sink);
+ r = generate_impl(sink, ctx, d, attr
+ , traits::is_container<Attribute>());
+ }
+ if (r)
+ buffering.buffer_copy();
+ return r;
         }
 
         template <typename Context>

Modified: trunk/boost/spirit/home/qi/detail/alternative_function.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/detail/alternative_function.hpp (original)
+++ trunk/boost/spirit/home/qi/detail/alternative_function.hpp 2009-06-02 20:05:58 EDT (Tue, 02 Jun 2009)
@@ -19,14 +19,6 @@
 
 namespace boost { namespace spirit { namespace qi { namespace detail
 {
- template <typename T>
- struct not_is_variant
- : mpl::true_ {};
-
- template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
- struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- : mpl::false_ {};
-
     template <typename Iterator, typename Context, typename Skipper,
         typename Attribute>
     struct alternative_function
@@ -64,7 +56,7 @@
         bool operator()(Component const& component) const
         {
             // return true if the parser succeeds
- return call(component, not_is_variant<Attribute>());
+ return call(component, spirit::traits::not_is_variant<Attribute>());
         }
 
         Iterator& first;

Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2009-06-02 20:05:58 EDT (Tue, 02 Jun 2009)
@@ -37,6 +37,14 @@
     // components.
     ///////////////////////////////////////////////////////////////////////////
 
+ template <typename T>
+ struct not_is_variant
+ : mpl::true_ {};
+
+ template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
+ struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
+ : mpl::false_ {};
+
     ///////////////////////////////////////////////////////////////////////////
     // attribute_of
     //

Modified: trunk/libs/spirit/test/karma/alternative.cpp
==============================================================================
--- trunk/libs/spirit/test/karma/alternative.cpp (original)
+++ trunk/libs/spirit/test/karma/alternative.cpp 2009-06-02 20:05:58 EDT (Tue, 02 Jun 2009)
@@ -108,6 +108,16 @@
         BOOST_TEST(!test_delimited("", char_ | int_, v, char_(' ')));
     }
 
+ {
+ std::vector<int> v;
+ BOOST_TEST(test("[]", '[' << (int_ % ", ") << ']' | "[]", v));
+
+ v.push_back(5);
+ v.push_back(5);
+ v.push_back(5);
+ BOOST_TEST(test("[5, 5, 5]", '[' << (int_ % ", ") << ']' | "[]", v));
+ }
+
     return boost::report_errors();
 }
 


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