Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r71292 - in trunk/boost/spirit/home/support/utree: . detail
From: blelbach_at_[hidden]
Date: 2011-04-15 12:27:43


Author: wash
Date: 2011-04-15 12:27:42 EDT (Fri, 15 Apr 2011)
New Revision: 71292
URL: http://svn.boost.org/trac/boost/changeset/71292

Log:
Implement more expressive utree diagnostics.

Text files modified:
   trunk/boost/spirit/home/support/utree/detail/utree_detail2.hpp | 114 ++++++++++++++++++++++--------
   trunk/boost/spirit/home/support/utree/operators.hpp | 146 +++++++++++++++++++++++++++++----------
   trunk/boost/spirit/home/support/utree/utree.hpp | 72 ++++++++++++++++--
   3 files changed, 253 insertions(+), 79 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 2011-04-15 12:27:42 EDT (Fri, 15 Apr 2011)
@@ -456,7 +456,8 @@
             switch (x.get_type())
             {
                 default:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception("corrupt utree type", x.get_type()));
                     break;
 
                 case type::invalid_type:
@@ -519,7 +520,8 @@
             switch (x.get_type())
             {
                 default:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception("corrupt utree type", x.get_type()));
                     break;
 
                 case type::invalid_type:
@@ -589,7 +591,10 @@
                 case utree_type::list_type:
                     return apply(ut.l.first, i);
                 default:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("index operation performed on non-list utree type",
+ ut.get_type()));
             }
         }
 
@@ -604,7 +609,10 @@
                 case utree_type::list_type:
                     return apply(ut.l.first, i);
                 default:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("index operation performed on non-list utree type",
+ ut.get_type()));
             }
         }
 
@@ -1006,7 +1014,7 @@
         if (get_type() == type::reference_type)
             return p->push_front(val);
 
- ensure_list_type();
+ ensure_list_type("push_front()");
         l.push_front(val);
     }
 
@@ -1016,7 +1024,7 @@
         if (get_type() == type::reference_type)
             return p->push_back(val);
 
- ensure_list_type();
+ ensure_list_type("push_back()");
         l.push_back(val);
     }
 
@@ -1026,7 +1034,7 @@
         if (get_type() == type::reference_type)
             return p->insert(pos, val);
 
- ensure_list_type();
+ ensure_list_type("insert()");
         if (!pos.node)
         {
             l.push_back(val);
@@ -1042,7 +1050,7 @@
         if (get_type() == type::reference_type)
             return p->insert(pos, n, val);
 
- ensure_list_type();
+ ensure_list_type("insert()");
         for (std::size_t i = 0; i != n; ++i)
             insert(pos, val);
     }
@@ -1053,7 +1061,7 @@
         if (get_type() == type::reference_type)
             return p->insert(pos, first, last);
 
- ensure_list_type();
+ ensure_list_type("insert()");
         while (first != last)
             insert(pos, *first++);
     }
@@ -1089,7 +1097,10 @@
         if (get_type() == type::reference_type)
             return p->pop_front();
         if (get_type() != type::list_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("pop_front() called on non-list utree type",
+ get_type()));
 
         l.pop_front();
     }
@@ -1099,7 +1110,10 @@
         if (get_type() == type::reference_type)
             return p->pop_back();
         if (get_type() != type::list_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("pop_back() called on non-list utree type",
+ get_type()));
 
         l.pop_back();
     }
@@ -1109,7 +1123,10 @@
         if (get_type() == type::reference_type)
             return p->erase(pos);
         if (get_type() != type::list_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("erase() called on non-list utree type",
+ get_type()));
 
         detail::list::node* np = l.erase(pos.node);
         return iterator(np, np?np->prev:l.last);
@@ -1121,7 +1138,10 @@
             return p->erase(first, last);
 
         if (get_type() != type::list_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("erase() called on non-list utree type",
+ get_type()));
         while (first != last)
             erase(first++);
         return last;
@@ -1135,7 +1155,7 @@
             return iterator(r.first, 0);
 
         // otherwise...
- ensure_list_type();
+ ensure_list_type("begin()");
         return iterator(l.first, 0);
     }
 
@@ -1147,7 +1167,7 @@
             return iterator(0, r.first);
 
         // otherwise...
- ensure_list_type();
+ ensure_list_type("end()");
         return iterator(0, l.last);
     }
 
@@ -1159,7 +1179,7 @@
             return ref_iterator(r.first, 0);
 
         // otherwise...
- ensure_list_type();
+ ensure_list_type("ref_begin()");
         return ref_iterator(l.first, 0);
     }
 
@@ -1171,7 +1191,7 @@
             return ref_iterator(0, r.first);
 
         // otherwise...
- ensure_list_type();
+ ensure_list_type("ref_end()");
         return ref_iterator(0, l.last);
     }
 
@@ -1184,7 +1204,10 @@
 
         // otherwise...
         if (get_type() != type::list_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("begin() called on non-list utree type",
+ get_type()));
 
         return const_iterator(l.first, 0);
     }
@@ -1198,7 +1221,10 @@
 
         // otherwise...
         if (get_type() != type::list_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("end() called on non-list utree type",
+ get_type()));
 
         return const_iterator(0, l.last);
     }
@@ -1240,7 +1266,10 @@
             return l.size;
 
         if (t != type::nil_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("size() called on non-list utree type",
+ get_type()));
 
         return 0;
     }
@@ -1262,7 +1291,10 @@
 
         // otherwise...
         if (get_type() != type::list_type || l.first == 0)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("front() called on non-list utree type",
+ get_type()));
 
         return l.first->val;
     }
@@ -1279,7 +1311,10 @@
 
         // otherwise...
         if (get_type() != type::list_type || l.last == 0)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("back() called on non-list utree type",
+ get_type()));
 
         return l.last->val;
     }
@@ -1296,7 +1331,10 @@
 
         // otherwise...
         if (get_type() != type::list_type || l.first == 0)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("front() called on non-list utree type",
+ get_type()));
 
         return l.first->val;
     }
@@ -1313,7 +1351,10 @@
 
         // otherwise...
         if (get_type() != type::list_type || l.last == 0)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception
+ ("back() called on non-list utree type",
+ get_type()));
 
         return l.last->val;
     }
@@ -1335,7 +1376,7 @@
         s.set_type(t);
     }
 
- inline void utree::ensure_list_type()
+ inline void utree::ensure_list_type(char const* failed_in)
     {
         type::info t = get_type();
         if (t == type::invalid_type)
@@ -1345,7 +1386,9 @@
         }
         else if (get_type() != type::list_type)
         {
- boost::throw_exception(bad_type_exception());
+ std::string msg = failed_in;
+ msg += "called on non-list and non-invalid utree type";
+ BOOST_THROW_EXCEPTION(bad_type_exception(msg.c_str(), get_type()));
         }
     }
 
@@ -1376,7 +1419,8 @@
         switch (other.get_type())
         {
             default:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception("corrupt utree type", other.get_type()));
                 break;
             case type::invalid_type:
             case type::nil_type:
@@ -1451,7 +1495,7 @@
         To dispatch(From const&, boost::mpl::false_) const
         {
             // From is NOT convertible to To !!!
- boost::throw_exception(std::bad_cast());
+ throw std::bad_cast();
             return To();
         }
 
@@ -1477,7 +1521,7 @@
         T* operator()(From const&) const
         {
             // From is NOT convertible to T !!!
- boost::throw_exception(std::bad_cast());
+ throw std::bad_cast();
             return 0;
         }
 
@@ -1511,7 +1555,9 @@
             case type::string_range_type:
             case type::binary_type:
             case type::symbol_type:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception(
+ "tag() called on string utree type", get_type()));
             default:
               break;
         }
@@ -1526,7 +1572,9 @@
             case type::string_range_type:
             case type::binary_type:
             case type::symbol_type:
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception(
+ "tag() called on string utree type", get_type()));
             default:
               break;
         }
@@ -1536,7 +1584,9 @@
     inline utree utree::eval(scope const& env) const
     {
         if (get_type() != type::function_type)
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(
+ bad_type_exception(
+ "eval() called on non-function utree type", get_type()));
         return (*pf)(env);
     }
 }}

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 2011-04-15 12:27:42 EDT (Fri, 15 Apr 2011)
@@ -24,22 +24,6 @@
 
 namespace boost { namespace spirit
 {
- struct illegal_arithmetic_operation : utree_exception
- {
- virtual const char* what() const throw()
- {
- return "utree: Illegal arithmetic operation.";
- }
- };
-
- struct illegal_integral_operation : utree_exception
- {
- virtual const char* what() const throw()
- {
- return "utree: Illegal integral operation.";
- }
- };
-
     // Relational operators
     bool operator==(utree const& a, utree const& b);
     bool operator<(utree const& a, utree const& b);
@@ -175,25 +159,33 @@
 
         bool operator()(utree::invalid_type, utree::invalid_type) const
         {
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("no less-than comparison for this utree type",
+ utree_type::invalid_type));
             return false; // no less than comparison for nil
         }
 
         bool operator()(utree::nil_type, utree::nil_type) const
         {
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("no less-than comparison for this utree type",
+ utree_type::nil_type));
             return false; // no less than comparison for nil
         }
 
         bool operator()(any_ptr const&, any_ptr const&) const
         {
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("no less-than comparison for this utree type",
+ utree_type::any_type));
             return false; // no less than comparison for any_ptr
         }
 
         bool operator()(function_base const&, function_base const&) const
         {
- boost::throw_exception(bad_type_exception());
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("no less-than comparison for this utree type",
+ utree_type::function_type));
             return false; // no less than comparison of functions
         }
     };
@@ -354,7 +346,6 @@
         template <typename A, typename B>
         utree dispatch(A const&, B const&, boost::mpl::false_) const
         {
- boost::throw_exception(illegal_arithmetic_operation());
             return utree(); // cannot apply to non-arithmetic types
         }
 
@@ -377,7 +368,6 @@
         template <typename A>
         utree dispatch(A const&, boost::mpl::false_) const
         {
- boost::throw_exception(illegal_arithmetic_operation());
             return utree(); // cannot apply to non-arithmetic types
         }
 
@@ -403,7 +393,6 @@
         template <typename A, typename B>
         utree dispatch(A const&, B const&, boost::mpl::false_) const
         {
- boost::throw_exception(illegal_integral_operation());
             return utree(); // cannot apply to non-integral types
         }
 
@@ -426,7 +415,6 @@
         template <typename A>
         utree dispatch(A const&, boost::mpl::false_) const
         {
- boost::throw_exception(illegal_integral_operation());
             return utree(); // cannot apply to non-integral types
         }
 
@@ -542,7 +530,7 @@
 
     inline utree operator&&(utree const& a, utree const& b)
     {
- return utree::visit(a, b, logical_function_and_);
+ return utree::visit(a, b, logical_function_and_);
     }
 
     inline utree operator||(utree const& a, utree const& b)
@@ -557,62 +545,146 @@
 
     inline utree operator+(utree const& a, utree const& b)
     {
- return utree::visit(a, b, arithmetic_function_plus);
+ utree r = utree::visit(a, b, arithmetic_function_plus);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("addition performed on non-arithmetic utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator-(utree const& a, utree const& b)
     {
- return utree::visit(a, b, arithmetic_function_minus);
+ utree r = utree::visit(a, b, arithmetic_function_minus);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("subtraction performed on non-arithmetic utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator*(utree const& a, utree const& b)
     {
- return utree::visit(a, b, arithmetic_function_times);
+ utree r = utree::visit(a, b, arithmetic_function_times);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("multiplication performed on non-arithmetic utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator/(utree const& a, utree const& b)
     {
- return utree::visit(a, b, arithmetic_function_divides);
+ utree r = utree::visit(a, b, arithmetic_function_divides);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("division performed on non-arithmetic utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator%(utree const& a, utree const& b)
     {
- return utree::visit(a, b, integral_function_modulus);
+ utree r = utree::visit(a, b, integral_function_modulus);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("modulos performed on non-integral utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator-(utree const& a)
     {
- return utree::visit(a, arithmetic_function_negate);
+ utree r = utree::visit(a, arithmetic_function_negate);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("negation performed on non-arithmetic utree type",
+ a.which()));
+ }
+ return r;
     }
 
     inline utree operator&(utree const& a, utree const& b)
     {
- return utree::visit(a, b, integral_function_bitand_);
+ utree r = utree::visit(a, b, integral_function_bitand_);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("bitwise and performed on non-integral utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator|(utree const& a, utree const& b)
     {
- return utree::visit(a, b, integral_function_bitor_);
+ utree r = utree::visit(a, b, integral_function_bitor_);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("bitwise or performed on non-integral utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator^(utree const& a, utree const& b)
     {
- return utree::visit(a, b, integral_function_bitxor_);
+ utree r = utree::visit(a, b, integral_function_bitxor_);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("bitwise xor performed on non-integral utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator<<(utree const& a, utree const& b)
     {
- return utree::visit(a, b, integral_function_shift_left);
+ utree r = utree::visit(a, b, integral_function_shift_left);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("left shift performed on non-integral utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator>>(utree const& a, utree const& b)
     {
- return utree::visit(a, b, integral_function_shift_right);
+ utree r = utree::visit(a, b, integral_function_shift_right);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("right shift performed on non-integral utree types",
+ a.which(), b.which()));
+ }
+ return r;
     }
 
     inline utree operator~(utree const& a)
     {
- return utree::visit(a, integral_function_invert);
+ utree r = utree::visit(a, integral_function_invert);
+ if (r.which() == utree_type::invalid_type)
+ {
+ BOOST_THROW_EXCEPTION(bad_type_exception
+ ("inversion performed on non-integral utree type",
+ a.which()));
+ }
+ return r;
     }
 }}
 

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 2011-04-15 12:27:42 EDT (Fri, 15 Apr 2011)
@@ -12,9 +12,11 @@
 #include <cstddef>
 #include <algorithm>
 #include <string>
-#include <ostream>
+#include <iostream>
+#include <sstream>
 #include <typeinfo>
 
+#include <boost/integer.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/assert.hpp>
 #include <boost/noncopyable.hpp>
@@ -45,13 +47,7 @@
        function, which applies to certain stored utree_type's only, but this
        precondition is violated as the `utree` instance holds some other type.
     */
- struct bad_type_exception : utree_exception
- {
- virtual const char* what() const throw()
- {
- return "utree: Illegal operation for currently stored data.";
- }
- };
+ struct bad_type_exception /*: utree_exception*/;
     //]
 
     //[utree_types
@@ -86,9 +82,65 @@
 
             binary_type // Arbitrary binary data
         };
+ typedef boost::uint_t<sizeof(info)*8>::exact exact_integral_type;
+ typedef boost::uint_t<sizeof(info)*8>::fast fast_integral_type;
     };
     //]
 
+ // streaming operator for utree types - essential for diagnostics
+ inline std::ostream& operator<<(std::ostream& out, utree_type::info t)
+ {
+ switch (t) {
+ case utree_type::invalid_type: { out << "invalid"; break; }
+ case utree_type::nil_type: { out << "nil"; break; }
+ case utree_type::list_type: { out << "list"; break; }
+ case utree_type::range_type: { out << "range"; break; }
+ case utree_type::reference_type: { out << "reference"; break; }
+ case utree_type::any_type: { out << "any"; break; }
+ case utree_type::function_type: { out << "function"; break; }
+ case utree_type::bool_type: { out << "bool"; break; }
+ case utree_type::int_type: { out << "int"; break; }
+ case utree_type::double_type: { out << "double"; break; }
+ case utree_type::string_type: { out << "string"; break; }
+ case utree_type::string_range_type: { out << "string_range"; break; }
+ case utree_type::symbol_type: { out << "symbol"; break; }
+ case utree_type::binary_type: { out << "binary"; break; }
+ default: { out << "unknown"; break; }
+ }
+ out << std::hex << "[0x"
+ << static_cast<utree_type::fast_integral_type>(t) << "]";
+ return out;
+ }
+
+ struct bad_type_exception : utree_exception
+ {
+ std::string msg;
+
+ bad_type_exception(char const* error, utree_type::info got)
+ : msg()
+ {
+ std::ostringstream oss;
+ oss << "utree: " << error
+ << " (got utree type '" << got << "')";
+ msg = oss.str();
+ }
+
+ bad_type_exception(char const* error, utree_type::info got1,
+ utree_type::info got2)
+ : msg()
+ {
+ std::ostringstream oss;
+ oss << "utree: " << error
+ << " (got utree types '" << got1 << "' and '" << got2 << "')";
+ msg = oss.str();
+ }
+
+ virtual ~bad_type_exception() throw() {}
+
+ virtual const char* what() const throw()
+ { return msg.c_str(); }
+ };
+
     ///////////////////////////////////////////////////////////////////////////
     // A typed string with parametric Base storage. The storage can be any
     // range or (stl container) of chars.
@@ -506,7 +558,7 @@
 
     //<-
     protected:
- void ensure_list_type();
+ void ensure_list_type(char const* failed_in = "ensure_list_type()");
 
     private:
         typedef utree_type type;
@@ -549,7 +601,7 @@
     {
         using utree::operator=;
 
- list_type() : utree() { ensure_list_type(); }
+ list_type() : utree() { ensure_list_type("list_type()"); }
 
         template <typename T0>
         list_type(T0 t0) : utree(t0) {}


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