Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67051 - in trunk/boost/spirit/home: karma/detail support/utree
From: hartmut.kaiser_at_[hidden]
Date: 2010-12-05 19:13:18


Author: hkaiser
Date: 2010-12-05 19:13:17 EST (Sun, 05 Dec 2010)
New Revision: 67051
URL: http://svn.boost.org/trac/boost/changeset/67051

Log:
Spirit: working on utree integration with Karma
Text files modified:
   trunk/boost/spirit/home/karma/detail/pass_container.hpp | 23 +++++-
   trunk/boost/spirit/home/support/utree/utree_traits.hpp | 138 +++++++++++++++++++++++++++++++++++++++
   2 files changed, 155 insertions(+), 6 deletions(-)

Modified: trunk/boost/spirit/home/karma/detail/pass_container.hpp
==============================================================================
--- trunk/boost/spirit/home/karma/detail/pass_container.hpp (original)
+++ trunk/boost/spirit/home/karma/detail/pass_container.hpp 2010-12-05 19:13:17 EST (Sun, 05 Dec 2010)
@@ -88,13 +88,20 @@
             return true;
         }
 
- // this is for the case when the current element expects an attribute
+ // This is for the case when the current element expects an attribute
         // which is a container itself, this element will get the rest of the
- // attribute container
+ // attribute container.
+ // For some attributes (like utree) we assume, that the generator ate
+ // at least one element of the sequence. This isn't pretty, but
+ // generators are either assumed to consume all remaining attributes or
+ // to consume exactly one.
         template <typename Component>
         bool dispatch_attribute_element(Component const& component, mpl::true_) const
         {
- return f(component, make_iterator_range(iter, end));
+ bool result = f(component, make_iterator_range(iter, end));
+ if (iter != end)
+ ++iter;
+ return result;
         }
 
         // This handles the distinction between elements in a sequence expecting
@@ -142,10 +149,18 @@
         // This handles the case where the attribute of the component is
         // an STL container *and* its value_type is convertible to the
         // target attribute's (Attr) value_type.
+ //
+ // For some attributes (like utree) we assume, that the generator ate
+ // at least one element of the sequence. This isn't pretty, but
+ // generators are either assumed to consume all remaining attributes or
+ // to consume exactly one.
         template <typename Component>
         bool dispatch_main(Component const& component, mpl::true_) const
         {
- return f(component, make_iterator_range(iter, end));
+ bool result = f(component, make_iterator_range(iter, end));
+ if (iter != end)
+ ++iter;
+ return result;
         }
 
         // Dispatches to dispatch_main depending on the attribute type

Modified: trunk/boost/spirit/home/support/utree/utree_traits.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree_traits.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree_traits.hpp 2010-12-05 19:13:17 EST (Sun, 05 Dec 2010)
@@ -219,7 +219,6 @@
     struct not_is_variant<utree, karma::domain>
       : mpl::false_ {};
 
- ///////////////////////////////////////////////////////////////////////////
     // this specialization tells Spirit how to extract the type of the value
     // stored in the given utree node
     template <>
@@ -228,7 +227,6 @@
         static int call(utree const& u) { return u.which(); }
     };
 
- ///////////////////////////////////////////////////////////////////////////
     // The specializations below tell Spirit to verify whether an attribute
     // type is compatible with a given variant type
     template <>
@@ -450,6 +448,68 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <>
+ struct extract_from_attribute<utree, char>
+ {
+ typedef char type;
+
+ template <typename Context>
+ static type call(utree const& t, Context&)
+ {
+ utf8_symbol_range r = boost::get<utf8_symbol_range>(t);
+ return r.front();
+ }
+ };
+
+ template <>
+ struct extract_from_attribute<utree, bool>
+ {
+ typedef bool type;
+
+ template <typename Context>
+ static type call(utree const& t, Context&)
+ {
+ return boost::get<bool>(t);
+ }
+ };
+
+ template <>
+ struct extract_from_attribute<utree, int>
+ {
+ typedef int type;
+
+ template <typename Context>
+ static type call(utree const& t, Context&)
+ {
+ return boost::get<int>(t);
+ }
+ };
+
+ template <>
+ struct extract_from_attribute<utree, double>
+ {
+ typedef double type;
+
+ template <typename Context>
+ static type call(utree const& t, Context&)
+ {
+ return boost::get<double>(t);
+ }
+ };
+
+ template <typename Traits, typename Alloc>
+ struct extract_from_attribute<utree, std::basic_string<char, Traits, Alloc> >
+ {
+ typedef std::basic_string<char, Traits, Alloc> type;
+
+ template <typename Context>
+ static type call(utree const& t, Context&)
+ {
+ utf8_symbol_range r = boost::get<utf8_string_range>(t);
+ return std::basic_string<char, Traits, Alloc>(r.begin(), r.end());
+ }
+ };
+
+ template <>
     struct extract_from_attribute<utree, utf8_symbol>
     {
         typedef std::string type;
@@ -477,6 +537,80 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <>
+ struct transform_attribute<utree const, char, karma::domain>
+ {
+ typedef char type;
+
+ static type pre(utree const& t)
+ {
+ utf8_string_range r = boost::get<utf8_string_range>(t);
+ return r.front();
+ }
+ };
+
+ template <>
+ struct transform_attribute<utree const, bool, karma::domain>
+ {
+ typedef bool type;
+
+ static type pre(utree const& t)
+ {
+ return boost::get<bool>(t);
+ }
+ };
+
+ template <>
+ struct transform_attribute<utree const, int, karma::domain>
+ {
+ typedef int type;
+
+ static type pre(utree const& t)
+ {
+ return boost::get<int>(t);
+ }
+ };
+
+ template <>
+ struct transform_attribute<utree const, double, karma::domain>
+ {
+ typedef double type;
+
+ static type pre(utree const& t)
+ {
+ return boost::get<double>(t);
+ }
+ };
+
+ template <typename Traits, typename Alloc>
+ struct transform_attribute<
+ utree const, std::basic_string<char, Traits, Alloc>, karma::domain>
+ {
+ typedef std::basic_string<char, Traits, Alloc> type;
+
+ static type pre(utree const& t)
+ {
+ utf8_symbol_range r = boost::get<utf8_string_range>(t);
+ return std::basic_string<char, Traits, Alloc>(r.begin(), r.end());
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // this specialization is used whenever a utree is passed to a rule as part
+ // of a sequence
+ template <typename Iterator>
+ struct transform_attribute<
+ iterator_range<Iterator> const, utree, karma::domain>
+ {
+ typedef utree type;
+
+ static type pre(iterator_range<Iterator> const& t)
+ {
+ return utree(boost::ref(t.front())); // return utree the begin iterator points to
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <>
     struct transform_attribute<utree const, utf8_string_type, karma::domain>
     {
         typedef std::string type;


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