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