|
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