$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;