|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r67377 - in trunk/boost/spirit/home/support/utree: . detail
From: hartmut.kaiser_at_[hidden]
Date: 2010-12-20 21:37:36
Author: hkaiser
Date: 2010-12-20 21:37:28 EST (Mon, 20 Dec 2010)
New Revision: 67377
URL: http://svn.boost.org/trac/boost/changeset/67377
Log:
Spirit: adding uninitialized utree node type
Text files modified:
trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp | 134 +++++++++++++++++++++++++--------------
trunk/boost/spirit/home/support/utree/operators.hpp | 45 ++++++++++---
trunk/boost/spirit/home/support/utree/utree.hpp | 82 +++++++++++++++++-------
trunk/boost/spirit/home/support/utree/utree_traits.hpp | 23 +++++-
4 files changed, 195 insertions(+), 89 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-20 21:37:28 EST (Mon, 20 Dec 2010)
@@ -403,8 +403,10 @@
}
}
+ ///////////////////////////////////////////////////////////////////////////
+ // simple binder for binary visitation (we don't want to bring in the big guns)
template <typename F, typename X>
- struct bind_impl // simple binder for binary visitation (we don't want to bring in the big guns)
+ struct bind_impl
{
typedef typename F::result_type result_type;
X& x; // always by reference
@@ -455,11 +457,14 @@
switch (x.get_type())
{
default:
- BOOST_ASSERT(false); // can't happen
+ boost::throw_exception(bad_type_exception());
+ break;
+
+ case type::uninitialized_type:
+ return f(uninitialized);
case type::nil_type:
- nil arg;
- return f(arg);
+ return f(nil);
case type::bool_type:
return f(x.b);
@@ -515,11 +520,14 @@
switch (x.get_type())
{
default:
- BOOST_ASSERT(false); // can't happen
+ boost::throw_exception(bad_type_exception());
+ break;
+
+ case type::uninitialized_type:
+ return visit_impl::apply(y, detail::bind(f, uninitialized));
case type::nil_type:
- nil x_;
- return visit_impl::apply(y, detail::bind(f, x_));
+ return visit_impl::apply(y, detail::bind(f, nil));
case type::bool_type:
return visit_impl::apply(y, detail::bind(f, x.b));
@@ -565,7 +573,6 @@
case type::function_type:
return visit_impl::apply(y, detail::bind(f, *x.pf));
-
}
}
};
@@ -614,7 +621,13 @@
return new stored_function<F>(*this);
}
- inline utree::utree()
+ inline utree::utree(uninitialized_type)
+ {
+ s.initialize();
+ set_type(type::uninitialized_type);
+ }
+
+ inline utree::utree(nil_type)
{
s.initialize();
set_type(type::nil_type);
@@ -712,7 +725,7 @@
inline utree::utree(boost::iterator_range<Iter> r)
{
s.initialize();
- set_type(type::nil_type);
+ set_type(type::uninitialized_type);
assign(r.begin(), r.end());
}
@@ -761,6 +774,13 @@
return *this;
}
+ inline utree& utree::operator=(nil_type)
+ {
+ free();
+ set_type(type::nil_type);
+ return *this;
+ }
+
inline utree& utree::operator=(bool b_)
{
free();
@@ -936,6 +956,7 @@
{
if (get_type() == type::reference_type)
return p->push_front(val);
+
ensure_list_type();
l.push_front(val);
}
@@ -945,6 +966,7 @@
{
if (get_type() == type::reference_type)
return p->push_back(val);
+
ensure_list_type();
l.push_back(val);
}
@@ -954,6 +976,7 @@
{
if (get_type() == type::reference_type)
return p->insert(pos, val);
+
ensure_list_type();
if (!pos.node)
{
@@ -969,15 +992,18 @@
{
if (get_type() == type::reference_type)
return p->insert(pos, n, val);
+
+ ensure_list_type();
for (std::size_t i = 0; i != n; ++i)
insert(pos, val);
}
- template <typename Iter>
- inline void utree::insert(iterator pos, Iter first, Iter last)
+ template <typename Iterator>
+ inline void utree::insert(iterator pos, Iterator first, Iterator last)
{
if (get_type() == type::reference_type)
return p->insert(pos, first, last);
+
ensure_list_type();
while (first != last)
insert(pos, *first++);
@@ -987,8 +1013,8 @@
{
struct assign_impl
{
- template <typename Iter>
- static void dispatch(utree& ut, Iter first, Iter last)
+ template <typename Iterator>
+ static void dispatch(utree& ut, Iterator first, Iterator last)
{
ut.ensure_list_type();
ut.clear();
@@ -999,8 +1025,8 @@
}
}
- template <typename Iter>
- static void dispatch_string(utree& ut, Iter first, Iter last)
+ template <typename Iterator>
+ static void dispatch_string(utree& ut, Iterator first, Iterator last)
{
ut.free();
ut.s.construct(first, last);
@@ -1026,16 +1052,16 @@
dispatch_string(ut, first, last);
}
- template <typename Iter>
- static void call(utree& ut, Iter first, Iter last)
+ template <typename Iterator>
+ static void call(utree& ut, Iterator first, Iterator last)
{
dispatch(ut, first, last);
}
};
}
- template <typename Iter>
- inline void utree::assign(Iter first, Iter last)
+ template <typename Iterator>
+ inline void utree::assign(Iterator first, Iterator last)
{
if (get_type() == type::reference_type)
return p->assign(first, last);
@@ -1046,9 +1072,10 @@
{
if (get_type() == type::reference_type)
return p->clear();
- // clear will always make this a nil type
+
+ // clear will always make this an uninitialized type
free();
- set_type(type::nil_type);
+ set_type(type::uninitialized_type);
}
inline void utree::pop_front()
@@ -1057,6 +1084,7 @@
return p->pop_front();
if (get_type() != type::list_type)
boost::throw_exception(bad_type_exception());
+
l.pop_front();
}
@@ -1066,6 +1094,7 @@
return p->pop_back();
if (get_type() != type::list_type)
boost::throw_exception(bad_type_exception());
+
l.pop_back();
}
@@ -1075,6 +1104,7 @@
return p->erase(pos);
if (get_type() != type::list_type)
boost::throw_exception(bad_type_exception());
+
detail::list::node* np = l.erase(pos.node);
return iterator(np, np?np->prev:l.last);
}
@@ -1083,6 +1113,9 @@
{
if (get_type() == type::reference_type)
return p->erase(first, last);
+
+ if (get_type() != type::list_type)
+ boost::throw_exception(bad_type_exception());
while (first != last)
erase(first++);
return last;
@@ -1140,7 +1173,7 @@
{
if (get_type() == type::reference_type)
return ((utree const*)p)->begin();
- else if (get_type() == type::range_type)
+ if (get_type() == type::range_type)
return const_iterator(r.first, 0);
// otherwise...
@@ -1154,7 +1187,7 @@
{
if (get_type() == type::reference_type)
return ((utree const*)p)->end();
- else if (get_type() == type::range_type)
+ if (get_type() == type::range_type)
return const_iterator(0, r.first);
// otherwise...
@@ -1166,22 +1199,30 @@
inline bool utree::empty() const
{
- if (get_type() == type::reference_type)
+ type::info t = get_type();
+ if (t == type::uninitialized_type)
+ {
+ boost::throw_exception(bad_type_exception());
+ return false;
+ }
+ if (t == type::reference_type)
return ((utree const*)p)->empty();
- else if (get_type() == type::range_type)
+
+ if (t == type::range_type)
return r.first == 0;
- else if (get_type() == type::list_type)
+ if (t == type::list_type)
return l.size == 0;
- return get_type() == type::nil_type;
+
+ return t == type::nil_type;
}
inline std::size_t utree::size() const
{
- if (get_type() == type::reference_type)
- {
+ type::info t = get_type();
+ if (t == type::reference_type)
return ((utree const*)p)->size();
- }
- else if (get_type() == type::range_type)
+
+ if (t == type::range_type)
{
std::size_t size = 0;
detail::list::node* n = r.first;
@@ -1192,12 +1233,10 @@
}
return size;
}
- else if (get_type() == type::list_type)
- {
+ if (t == type::list_type)
return l.size;
- }
- if (get_type() != type::nil_type)
+ if (t != type::nil_type)
boost::throw_exception(bad_type_exception());
return 0;
@@ -1211,10 +1250,8 @@
inline utree& utree::front()
{
if (get_type() == type::reference_type)
- {
return p->front();
- }
- else if (get_type() == type::range_type)
+ if (get_type() == type::range_type)
{
BOOST_ASSERT(r.first != 0);
return r.first->val;
@@ -1230,10 +1267,8 @@
inline utree& utree::back()
{
if (get_type() == type::reference_type)
- {
return p->back();
- }
- else if (get_type() == type::range_type)
+ if (get_type() == type::range_type)
{
BOOST_ASSERT(r.last != 0);
return r.last->val;
@@ -1249,10 +1284,8 @@
inline utree const& utree::front() const
{
if (get_type() == type::reference_type)
- {
return ((utree const*)p)->front();
- }
- else if (get_type() == type::range_type)
+ if (get_type() == type::range_type)
{
BOOST_ASSERT(r.first != 0);
return r.first->val;
@@ -1268,10 +1301,8 @@
inline utree const& utree::back() const
{
if (get_type() == type::reference_type)
- {
return ((utree const*)p)->back();
- }
- else if (get_type() == type::range_type)
+ if (get_type() == type::range_type)
{
BOOST_ASSERT(r.last != 0);
return r.last->val;
@@ -1303,7 +1334,8 @@
inline void utree::ensure_list_type()
{
- if (get_type() == type::nil_type)
+ type::info t = get_type();
+ if (t == type::uninitialized_type || t == type::nil_type)
{
set_type(type::list_type);
l.default_construct();
@@ -1340,6 +1372,10 @@
set_type(other.get_type());
switch (other.get_type())
{
+ default:
+ boost::throw_exception(bad_type_exception());
+ break;
+ case type::uninitialized_type:
case type::nil_type:
break;
case type::bool_type:
Modified: trunk/boost/spirit/home/support/utree/operators.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/operators.hpp (original)
+++ trunk/boost/spirit/home/support/utree/operators.hpp 2010-12-20 21:37:28 EST (Mon, 20 Dec 2010)
@@ -51,7 +51,8 @@
std::ostream& operator<<(std::ostream& out, utree const& x);
std::istream& operator>>(std::istream& in, utree& x);
- std::ostream& operator<<(std::ostream& out, nil const& x);
+ std::ostream& operator<<(std::ostream& out, uninitialized_type const& x);
+ std::ostream& operator<<(std::ostream& out, nil_type const& x);
// Logical operators
utree operator&&(utree const& a, utree const& b);
@@ -115,7 +116,12 @@
return static_cast<Base const&>(a) == static_cast<Base const&>(b);
}
- bool operator()(nil, nil) const
+ bool operator()(uninitialized_type, uninitialized_type) const
+ {
+ return true;
+ }
+
+ bool operator()(nil_type, nil_type) const
{
return true;
}
@@ -166,21 +172,27 @@
return static_cast<Base const&>(a) < static_cast<Base const&>(b);
}
- bool operator()(nil, nil) const
+ bool operator()(uninitialized_type, uninitialized_type) const
+ {
+ boost::throw_exception(bad_type_exception());
+ return false; // no less than comparison for nil
+ }
+
+ bool operator()(nil_type, nil_type) const
{
- BOOST_ASSERT(false);
+ boost::throw_exception(bad_type_exception());
return false; // no less than comparison for nil
}
bool operator()(any_ptr const& a, any_ptr const& b) const
{
- BOOST_ASSERT(false);
+ boost::throw_exception(bad_type_exception());
return false; // no less than comparison for any_ptr
}
bool operator()(function_base const& a, function_base const& b) const
{
- BOOST_ASSERT(false);
+ boost::throw_exception(bad_type_exception());
return false; // no less than comparison of functions
}
};
@@ -192,7 +204,12 @@
std::ostream& out;
utree_print(std::ostream& out) : out(out) {}
- void operator()(boost::spirit::nil) const
+ void operator()(boost::spirit::uninitialized_type) const
+ {
+ out << "uninitialized ";
+ }
+
+ void operator()(boost::spirit::nil_type) const
{
out << "<nil> ";
}
@@ -236,6 +253,7 @@
iterator i = str.begin();
for (; i != str.end(); ++i)
out << *i;
+ out << ' ';
}
template <typename Iterator>
@@ -317,7 +335,7 @@
template <typename A, typename B>
utree dispatch(A const&, B const&, boost::mpl::false_) const
{
- throw illegal_arithmetic_operation();
+ boost::throw_exception(illegal_arithmetic_operation());
return utree(); // cannot apply to non-arithmetic types
}
@@ -340,7 +358,7 @@
template <typename A>
utree dispatch(A const&, boost::mpl::false_) const
{
- throw illegal_arithmetic_operation();
+ boost::throw_exception(illegal_arithmetic_operation());
return utree(); // cannot apply to non-arithmetic types
}
@@ -389,7 +407,7 @@
template <typename A>
utree dispatch(A const&, boost::mpl::false_) const
{
- throw illegal_integral_operation();
+ boost::throw_exception(illegal_integral_operation());
return utree(); // cannot apply to non-integral types
}
@@ -475,7 +493,12 @@
return out;
}
- inline std::ostream& operator<<(std::ostream& out, nil const& x)
+ inline std::ostream& operator<<(std::ostream& out, uninitialized_type const& x)
+ {
+ return out;
+ }
+
+ inline std::ostream& operator<<(std::ostream& out, nil_type const& x)
{
return out;
}
Modified: trunk/boost/spirit/home/support/utree/utree.hpp
==============================================================================
--- trunk/boost/spirit/home/support/utree/utree.hpp (original)
+++ trunk/boost/spirit/home/support/utree/utree.hpp 2010-12-20 21:37:28 EST (Mon, 20 Dec 2010)
@@ -61,6 +61,8 @@
{
enum info
{
+ uninitialized_type, // the utree has not been initialized (it's
+ // default constructed)
nil_type, // nil is the sentinel (empty) utree type.
list_type, // A doubly linked list of utrees.
range_type, // A range of list::iterators.
@@ -87,9 +89,16 @@
//]
///////////////////////////////////////////////////////////////////////////
+ // The uninitialized type
+ ///////////////////////////////////////////////////////////////////////////
+ struct uninitialized_type {};
+ uninitialized_type const uninitialized = uninitialized_type();
+
+ ///////////////////////////////////////////////////////////////////////////
// The nil type
///////////////////////////////////////////////////////////////////////////
- struct nil {};
+ struct nil_type {};
+ nil_type const nil = nil_type();
///////////////////////////////////////////////////////////////////////////
// A typed string with parametric Base storage. The storage can be any
@@ -179,10 +188,10 @@
{
virtual ~function_base() {};
virtual utree operator()(scope const& env) const = 0;
- virtual function_base* clone() const = 0; // Calling f.clone() must
- // return a newly allocated
- // function_base instance
- // that is equal to f.
+
+ // Calling f.clone() must return a newly allocated function_base
+ // instance that is equal to f.
+ virtual function_base* clone() const = 0;
};
template <typename F>
@@ -220,7 +229,7 @@
{
return static_cast<Ptr>(p);
}
- throw std::bad_cast();
+ boost::throw_exception(std::bad_cast());
}
template <typename T>
@@ -275,27 +284,41 @@
/*`A `utree` can be constructed or initialized from a wide range of
data types, allowing to create `utree` instances for every
possible node type (see the description of `utree_type::info` above).
- For this reason it exposes a constructor and a assignment operator
- for each of the allowed node types as shown below:
+ For this reason it exposes a constructor and an assignment operator
+ for each of the allowed node types as shown below. All constructors
+ are non-explicit on purpose, allowing to use an utree instance as
+ the attribute to almost any Qi parser.
*/
- // constructs `nil_type` node
- utree();
+ // This constructs an `uninitialized_type` node. When used in places
+ // where a boost::optional is expected (i.e. as an attribute for the
+ // optional component), this represents the 'empty' state.
+ utree(uninitialized_type = uninitialized);
+
+ // This initializes a `nil_type` node, which represents a valid,
+ // 'initialized empty' utree (different from uninitialized_type!).
+ utree(nil_type);
+ reference operator=(nil_type);
- // initializes a `boolean_type` node
+ // This initializes a `boolean_type` node, which can hold 'true' or
+ // 'false' only.
utree(bool);
reference operator=(bool);
- // initializes a `integer_type` node
+ // This initializes an `integer_type` node, which can hold arbitrary
+ // integers. For convenience these functions are overloaded for signed
+ // and unsigned integer types.
utree(unsigned int);
utree(int);
reference operator=(unsigned int);
reference operator=(int);
- // initializes a `double_type` node
+ // This initializes a `double_type` node, which can hold arbitrary
+ // floating point (double) values.
utree(double);
reference operator=(double);
- // initializes a `string_type` node
+ // This initializes a `string_type` node, which can hold a narrow
+ // character sequence (usually an UTF-8 string).
utree(char);
utree(char const*);
utree(char const*, std::size_t);
@@ -304,32 +327,43 @@
reference operator=(char const*);
reference operator=(std::string const&);
- // constructs a `string_range_type` node, does not copy the data
- // but stores the iterator range
+ // This constructs a `string_range_type` node, which does not copy the
+ // data but stores the iterator range to the character sequence the
+ // range has been initialized from.
utree(utf8_string_range_type const&, shallow_tag);
- // initializes a `reference_type` node
+ // This initializes a `reference_type` node, which holds a reference to
+ // another utree node. All operations on such a node are automatically
+ // forwarded to the referenced utree instance.
utree(boost::reference_wrapper<utree>);
reference operator=(boost::reference_wrapper<utree>);
- // initializes an `any_type` node
+ // This initializes an `any_type` node, which can hold a pointer to an
+ // instance of any type together with the typeid of that type. When
+ // accessing that pointer the typeid will be checked, causing a
+ // std::bad_cast to be thrown if the typeids do not match.
utree(any_ptr const&);
reference operator=(any_ptr const&);
- // initialize a `range_type` node
+ // This initializes a `range_type` node, which holds an utree list node
+ // the elements of which are copy constructed (assigned) from the
+ // elements referenced by the given range of iterators.
template <class Iterator>
utree(boost::iterator_range<Iterator>);
template <class Iterator>
reference operator=(boost::iterator_range<Iterator>);
- // initialize a `function_type` node
+ // This initializes a `function_type` node, which can store an
+ // arbitrary function or function object.
template <class F>
utree(stored_function<F> const&);
template <class F>
reference operator=(stored_function<F> const&);
- // initialize either a `string_type`, a `symbol_type`, or a `binary_type`
- // node (depending on the template parameter `type_`)
+ // This initializes either a `string_type`, a `symbol_type`, or a
+ // `binary_type` node (depending on the template parameter `type_`),
+ // which will hold the corresponding narrow character sequence (usually
+ // an UTF-8 string).
template <class Base, utree_type::info type_>
utree(basic_string<Base, type_> const&);
template <class Base, utree_type::info type_>
@@ -345,8 +379,8 @@
utree(const_range, shallow_tag);
// assign dispatch
- template <class Iter>
- void assign(Iter, Iter);
+ template <class Iterator>
+ void assign(Iterator, Iterator);
////////////////////////////////////////////////////////////////////////
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-20 21:37:28 EST (Mon, 20 Dec 2010)
@@ -159,6 +159,7 @@
{
switch (c.which())
{
+ case utree_type::uninitialized_type:
case utree_type::nil_type:
case utree_type::list_type:
{
@@ -222,7 +223,7 @@
static bool is_valid(utree const& val)
{
- return val.which() != utree_type::nil_type;
+ return val.which() != utree_type::uninitialized_type;
}
};
@@ -270,10 +271,22 @@
};
template <>
- struct compute_compatible_component_variant<utree, nil>
+ struct compute_compatible_component_variant<utree, uninitialized_type>
: mpl::true_
{
- typedef nil compatible_type;
+ typedef uninitialized_type compatible_type;
+
+ static bool is_compatible(int d)
+ {
+ return d == utree_type::uninitialized_type;
+ }
+ };
+
+ template <>
+ struct compute_compatible_component_variant<utree, nil_type>
+ : mpl::true_
+ {
+ typedef nil_type compatible_type;
static bool is_compatible(int d)
{
@@ -403,7 +416,7 @@
static bool is_compatible(int d)
{
- return d >= utree_type::nil_type &&
+ return d >= utree_type::uninitialized_type &&
d <= utree_type::reference_type;
}
};
@@ -417,7 +430,7 @@
static bool is_compatible(int d)
{
- return d >= utree_type::nil_type &&
+ return d >= utree_type::uninitialized_type &&
d <= utree_type::reference_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