Boost logo

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