Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67407 - in trunk/boost/spirit/home/support/utree: . detail
From: hartmut.kaiser_at_[hidden]
Date: 2010-12-21 20:26:19


Author: hkaiser
Date: 2010-12-21 20:26:17 EST (Tue, 21 Dec 2010)
New Revision: 67407
URL: http://svn.boost.org/trac/boost/changeset/67407

Log:
Spirit: fixing iterator issue with utree
Text files modified:
   trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp | 59 +--------------
   trunk/boost/spirit/home/support/utree/utree_traits.hpp | 141 ++++++++++++++++++++++++++-------------
   2 files changed, 102 insertions(+), 98 deletions(-)

Modified: trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp (original)
+++ trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp 2010-12-21 20:26:17 EST (Tue, 21 Dec 2010)
@@ -1009,63 +1009,18 @@
             insert(pos, *first++);
     }
 
- namespace detail
- {
- struct assign_impl
- {
- template <typename Iterator>
- static void dispatch(utree& ut, Iterator first, Iterator last)
- {
- ut.ensure_list_type();
- ut.clear();
- while (first != last)
- {
- ut.push_back(*first);
- ++first;
- }
- }
-
- template <typename Iterator>
- static void dispatch_string(utree& ut, Iterator first, Iterator last)
- {
- ut.free();
- ut.s.construct(first, last);
- ut.set_type(utree_type::string_type);
- }
-
- static void dispatch(utree& ut,
- std::basic_string<char>::iterator first,
- std::basic_string<char>::iterator last)
- {
- dispatch_string(ut, first, last);
- }
-
- static void dispatch(utree& ut,
- std::basic_string<char>::const_iterator first,
- std::basic_string<char>::const_iterator last)
- {
- dispatch_string(ut, first, last);
- }
-
- static void dispatch(utree& ut, char const* first, char const* last)
- {
- dispatch_string(ut, first, last);
- }
-
- template <typename Iterator>
- static void call(utree& ut, Iterator first, Iterator last)
- {
- dispatch(ut, first, last);
- }
- };
- }
-
     template <typename Iterator>
     inline void utree::assign(Iterator first, Iterator last)
     {
         if (get_type() == type::reference_type)
             return p->assign(first, last);
- detail::assign_impl::call(*this, first, last);
+
+ clear();
+ while (first != last)
+ {
+ push_back(*first);
+ ++first;
+ }
     }
 
     inline void utree::clear()

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-21 20:26:17 EST (Tue, 21 Dec 2010)
@@ -38,22 +38,24 @@
 namespace boost { namespace spirit { namespace traits
 {
     ///////////////////////////////////////////////////////////////////////////
- // this specialization lets Spirit.Karma know that typed basic_strings
+ // this specialization lets Spirit know that typed basic_strings
     // are strings
     template <typename Base, utree_type::info I>
- struct is_string<spirit::basic_string<Base, I> > : mpl::true_ { };
+ struct is_string<spirit::basic_string<Base, I> >
+ : mpl::true_
+ {};
 
     ///////////////////////////////////////////////////////////////////////////
     // these specializations extract the character type of a utree typed string
     template <typename T, utree_type::info I>
     struct char_type_of<spirit::basic_string<iterator_range<T>, I> >
- : char_type_of<T> {};
+ : char_type_of<T>
+ {};
 
- template <typename T, typename Traits, typename Allocator,
- utree_type::info I>
- struct char_type_of<
- spirit::basic_string<std::basic_string<T, Traits, Allocator>, I>
- > : mpl::identity<T> {};
+ template <utree_type::info I>
+ struct char_type_of<spirit::basic_string<std::string, I> >
+ : mpl::identity<char>
+ {};
 
     ///////////////////////////////////////////////////////////////////////////
     // these specializations extract a c string from a utree typed string
@@ -78,19 +80,19 @@
         }
     };
     
- template <typename T, typename Traits, typename Allocator, utree_type::info I>
- struct get_c_string<spirit::basic_string<std::basic_string<T, Traits, Allocator>, I> >
+ template <utree_type::info I>
+ struct get_c_string<spirit::basic_string<std::string, I> >
     {
- typedef T char_type;
+ typedef char char_type;
 
- typedef spirit::basic_string<std::basic_string<T, Traits, Allocator>, I> string;
+ typedef spirit::basic_string<std::string, I> string;
 
- static T const* call (string& s)
+ static char const* call (string& s)
         {
             return s.c_str();
         }
 
- static T const* call (string const& s)
+ static char const* call (string const& s)
         {
             return s.c_str();
         }
@@ -132,6 +134,7 @@
     template <typename Attribute>
     struct assign_to_attribute_from_value<utree, Attribute>
     {
+ // any non-container type will be either directly assigned or appended
         static void call(Attribute const& val, utree& attr, mpl::false_)
         {
             if (attr.empty())
@@ -140,6 +143,7 @@
                 push_back(attr, val);
         }
 
+ // any container type will be converted into a list_type utree
         static void call(Attribute const& val, utree& attr, mpl::true_)
         {
             attr = make_iterator_range(traits::begin(val), traits::end(val));
@@ -164,26 +168,30 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
- // this specialization tells Spirit.Qi to allow assignment to an utree from
- // generic iterators
- template <typename Iterator>
- struct assign_to_attribute_from_iterators<utree, Iterator>
+ // this specialization makes sure strings get assigned as a whole and are
+ // not converted into a utree list
+ template <>
+ struct assign_to_attribute_from_value<utree, utf8_string_type>
     {
- static void
- call(Iterator const& first, Iterator const& last, utree& attr)
+ static void call(utf8_string_type const& val, utree& attr)
         {
- attr.assign(first, last);
+ if (attr.empty())
+ attr = val;
+ else
+ push_back(attr, val);
         }
     };
 
- ///////////////////////////////////////////////////////////////////////////
     // this specialization keeps symbols from being transformed into strings
     template<>
     struct assign_to_attribute_from_value<utree, utf8_symbol_type>
     {
         static void call (utf8_symbol_type const& val, utree& attr)
         {
- attr = val;
+ if (attr.empty())
+ attr = val;
+ else
+ push_back(attr, val);
         }
     };
 
@@ -192,24 +200,55 @@
     {
         static void call (utf8_symbol_range_type const& val, utree& attr)
         {
- attr = val;
+ if (attr.empty())
+ attr = val;
+ else
+ push_back(attr, val);
+ }
+ };
+
+ template <>
+ struct assign_to_attribute_from_value<utree, std::string>
+ {
+ static void call(std::string const& val, utree& attr)
+ {
+ if (attr.empty())
+ attr = val;
+ else
+ push_back(attr, val);
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////
- // this specialization allows the use of char("+-/*")
- template<typename T, typename Traits, typename Allocator, utree_type::info I>
- struct assign_to_attribute_from_value<spirit::basic_string<std::basic_string<T, Traits, Allocator>, I>, char>
+ // this specialization allows the use of utree as the attribute for single
+ // character parsers
+ // FIXME: should we leave that in?
+ template<utree_type::info I>
+ struct assign_to_attribute_from_value<
+ spirit::basic_string<std::string, I>, char>
     {
- typedef spirit::basic_string<std::basic_string<T, Traits, Allocator>, I> attribute;
+ typedef spirit::basic_string<std::string, I> attribute_type;
 
- static void call (char val, attribute& attr)
+ static void call (char val, attribute_type& attr)
         {
             attr.assign(1, val);
         }
     };
 
     ///////////////////////////////////////////////////////////////////////////
+ // this specialization tells Spirit.Qi to allow assignment to an utree from
+ // generic iterators
+ template <typename Iterator>
+ struct assign_to_attribute_from_iterators<utree, Iterator>
+ {
+ static void
+ call(Iterator const& first, Iterator const& last, utree& attr)
+ {
+ attr.assign(first, last);
+ }
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
     // Karma only: convert utree node to string
     template <>
     struct attribute_as_string<utree>
@@ -223,8 +262,7 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
- // push_back support for utree allows concatenation of strings
- // (utree strings are immutable)
+ // push_back support for utree
     template <typename T>
     struct push_back_container<utree, T>
     {
@@ -294,6 +332,7 @@
             return val;
         }
 
+ // only 'uninitialized_type' utree nodes are not valid
         static bool is_valid(utree const& val)
         {
             return val.which() != utree_type::uninitialized_type;
@@ -305,7 +344,8 @@
     // where a 'real' variant (in the context of karma)
     template <>
     struct not_is_variant<utree, karma::domain>
- : mpl::false_ {};
+ : mpl::false_
+ {};
 
     // this specialization tells Spirit how to extract the type of the value
     // stored in the given utree node
@@ -548,6 +588,18 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <>
+ struct extract_from_attribute<utree, spirit::nil_type>
+ {
+ typedef spirit::nil_type type;
+
+ template <typename Context>
+ static type call(utree const&, Context&)
+ {
+ return spirit::nil;
+ }
+ };
+
+ template <>
     struct extract_from_attribute<utree, char>
     {
         typedef char type;
@@ -609,7 +661,6 @@
         }
     };
 
- ///////////////////////////////////////////////////////////////////////////
     template <>
     struct extract_from_attribute<utree, utf8_symbol_type>
     {
@@ -636,21 +687,19 @@
         }
     };
 
-// template <typename Iterator>
-// struct extract_from_attribute<utree, iterator_range<Iterator> >
-// {
-// typedef utree type;
-//
-// template <typename Context>
-// static type call(utree const& t, Context&)
-// {
-// // return utree the begin iterator points to
-// return utree(boost::ref(t.front()));
-// }
-// };
-
     ///////////////////////////////////////////////////////////////////////////
     template <>
+ struct transform_attribute<utree const, spirit::nil_type, karma::domain>
+ {
+ typedef spirit::nil_type type;
+
+ static type pre(utree const& t)
+ {
+ return spirit::nil;
+ }
+ };
+
+ template <>
     struct transform_attribute<utree const, char, karma::domain>
     {
         typedef char 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