|
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