$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60750 - in trunk/libs/spirit/example/scheme: . detail
From: joel_at_[hidden]
Date: 2010-03-21 13:14:48
Author: djowel
Date: 2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
New Revision: 60750
URL: http://svn.boost.org/trac/boost/changeset/60750
Log:
more refactoring
Text files modified: 
   trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp |     8 +                                       
   trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp |   195 ++++++++++++++++++++++++++++++++------- 
   trunk/libs/spirit/example/scheme/sexpr.hpp                |    19 ---                                     
   trunk/libs/spirit/example/scheme/simple_print.hpp         |    89 ------------------                      
   trunk/libs/spirit/example/scheme/utree.hpp                |    47 ++++++---                               
   trunk/libs/spirit/example/scheme/utree_test.cpp           |     4                                         
   6 files changed, 202 insertions(+), 160 deletions(-)
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp	(original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp	2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -32,8 +32,8 @@
             bool_type,
             int_type,
             double_type,
-            small_string_type,
-            heap_string_type,
+            string_type,
+            binary_type,
             list_type,
             reference_type
         };
@@ -117,6 +117,7 @@
         void set_type(utree_type::info t);
         int get_subtype() const;
         void set_subtype(int t);
+        bool is_heap_allocated() const;
 
         std::size_t size() const;
         char const* str() const;
@@ -127,6 +128,9 @@
         void swap(fast_string& other);
         void free();
         void copy(fast_string const& other);
+
+        char& info();
+        char info() const;
     };
 }}
 
Modified: trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp	(original)
+++ trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp	2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -9,48 +9,55 @@
 
 namespace scheme { namespace detail
 {
+    inline char& fast_string::info()
+    {
+        return buff[small_string_size];
+    }
+
+    inline char fast_string::info() const
+    {
+        return buff[small_string_size];
+    }
+
     inline utree_type::info fast_string::get_type() const
     {
-        return static_cast<utree_type::info>(buff[small_string_size] & 0x7);
+        return static_cast<utree_type::info>((info() & 0x0F) >> 1);
     }
 
     inline void fast_string::set_type(utree_type::info t)
     {
-        buff[small_string_size] = static_cast<char>(t)
-                                | (buff[small_string_size] & 0xF8);
+        info() = (static_cast<char>(t) << 1) | (info() & 0xF1);
     }
 
     inline int fast_string::get_subtype() const
     {
-        return buff[small_string_size] >> 3;
+        return info() >> 4;
     }
 
     inline void fast_string::set_subtype(int t)
     {
-        buff[small_string_size] = (t << 3)
-                                | (buff[small_string_size] & 0x7);
+        info() = (t << 4) | (info() & 0x0F);
     }
 
-    inline std::size_t fast_string::size() const
+    inline bool fast_string::is_heap_allocated() const
     {
-        BOOST_ASSERT(get_type() == utree_type::small_string_type
-            || get_type() == utree_type::heap_string_type);
+        return info() & 0x01;
+    }
 
-        if (get_type() == utree_type::small_string_type)
-            return small_string_size - buff[small_string_size - 1];
-        else
+    inline std::size_t fast_string::size() const
+    {
+        if (is_heap_allocated())
             return heap.size;
+        else
+            return small_string_size - buff[small_string_size - 1];
     }
 
     inline char const* fast_string::str() const
     {
-        BOOST_ASSERT(get_type() == utree_type::small_string_type
-            || get_type() == utree_type::heap_string_type);
-
-        if (get_type() == utree_type::small_string_type)
-            return buff;
-        else
+        if (is_heap_allocated())
             return heap.str;
+        else
+            return buff;
     }
 
     template <typename Iterator>
@@ -64,15 +71,17 @@
             // of the string is placed in buff[small_string_size - 1]
             str = buff;
             buff[small_string_size - 1] = small_string_size - size;
-            set_type(utree_type::small_string_type);
+            info() &= ~0x1;
         }
         else
         {
+            BOOST_ASSERT(size < 200);
+
             // else, store it in the heap
             str = new char[size + 1]; // add one for the null char
             heap.str = str;
             heap.size = size;
-            set_type(utree_type::heap_string_type);
+            info() |= 0x1;
         }
         for (std::size_t i = 0; i != size; ++i)
         {
@@ -83,14 +92,12 @@
 
     inline void fast_string::swap(fast_string& other)
     {
-        fast_string temp = other;
-        other = *this;
-        *this = temp;
+        std::swap(*this, other);
     }
 
     inline void fast_string::free()
     {
-        if (get_type() == utree_type::heap_string_type)
+        if (is_heap_allocated())
         {
             delete [] heap.str;
             heap.str = 0;
@@ -352,7 +359,13 @@
             return a == b;
         }
 
-        bool operator()(utree::nil, utree::nil) const
+        template <typename Base>
+        bool operator()(binary<Base> const& a, binary<Base> const& b) const
+        {
+            return false;
+        }
+
+        bool operator()(nil, nil) const
         {
             return true;
         }
@@ -390,13 +403,94 @@
             return a < b;
         }
 
-        bool operator()(utree::nil, utree::nil) const
+        template <typename Base>
+        bool operator()(binary<Base> const& a, binary<Base> const& b) const
+        {
+            BOOST_ASSERT(false);
+            return false; // no less than comparison for binary
+        }
+
+        bool operator()(nil, nil) const
         {
             BOOST_ASSERT(false);
             return false; // no less than comparison for nil
         }
     };
 
+    struct utree_print
+    {
+        typedef void result_type;
+
+        std::ostream& out;
+        utree_print(std::ostream& out) : out(out) {}
+
+        void operator()(scheme::nil) const
+        {
+            out << "nil";
+        }
+
+        template <typename T>
+        void operator()(T val) const
+        {
+            out << val;
+        }
+
+        void operator()(bool b) const
+        {
+            out << (b ? "true" : "false");
+        }
+
+        template <typename Base>
+        void operator()(binary<Base> b) const
+        {
+            out << "b";
+            out.width(2);
+            out.fill('0');
+
+            typedef typename Base::const_iterator iterator;
+            for (iterator i = b.begin(); i != b.end(); ++i)
+                out << std::hex << int((unsigned char)*i);
+            out << std::dec;
+        }
+
+        template <typename Range> // for lists
+        void print_string_or_list(Range range, boost::mpl::false_) const
+        {
+            typedef typename Range::const_iterator iterator;
+            (*this)('(');
+            for (iterator i = range.begin(); i != range.end(); ++i)
+            {
+                if (i != range.begin())
+                    (*this)(' ');
+                scheme::utree::visit(*i, *this);
+            }
+            (*this)(')');
+        }
+
+        template <typename Range> // for strings
+        void print_string_or_list(Range range, boost::mpl::true_) const
+        {
+            typedef typename Range::const_iterator iterator;
+            iterator i = range.begin();
+            bool const is_symbol = *i == '\0';  // a 0 byte at the beginning signifies a symbol
+            if (!is_symbol)
+                out << '"';
+            else
+                ++i;
+            for (; i != range.end(); ++i)
+                out << *i;
+            if (!is_symbol)
+                out << '"';
+        }
+
+        template <typename Iterator>
+        void operator()(boost::iterator_range<Iterator> const& range) const
+        {
+            // This code works for both strings and lists
+            print_string_or_list(range, boost::is_pointer<Iterator>());
+        }
+    };
+
     template <typename UTreeX, typename UTreeY = UTreeX>
     struct visit_impl
     {
@@ -423,7 +517,7 @@
                 default:
                     BOOST_ASSERT(false); // can't happen
                 case type::nil_type:
-                    typename UTreeX::nil arg;
+                    nil arg;
                     return f(arg);
                 case type::bool_type:
                     return f(x.b);
@@ -433,9 +527,10 @@
                     return f(x.d);
                 case type::list_type:
                     return f(list_range(iterator(x.l.first), iterator(0)));
-                case type::heap_string_type:
-                case type::small_string_type:
+                case type::string_type:
                     return f(string_range(x.s.str(), x.s.str() + x.s.size()));
+                case type::binary_type:
+                    return f(binary_range(x.s.str(), x.s.size()));
                 case type::reference_type:
                     return apply(*x.p, f);
             }
@@ -464,7 +559,7 @@
                 default:
                     BOOST_ASSERT(false); // can't happen
                 case type::nil_type:
-                    typename UTreeX::nil x_;
+                    nil x_;
                     return visit_impl::apply(y, detail::bind(f, x_));
                 case type::bool_type:
                     return visit_impl::apply(y, detail::bind(f, x.b));
@@ -476,10 +571,12 @@
                     return visit_impl::apply(
                         y, detail::bind<F, list_range>(f,
                         list_range(iterator(x.l.first), iterator(0))));
-                case type::heap_string_type:
-                case type::small_string_type:
+                case type::string_type:
                     return visit_impl::apply(y, detail::bind(
                         f, string_range(x.s.str(), x.s.str() + x.s.size())));
+                case type::binary_type:
+                    return visit_impl::apply(y, detail::bind(
+                        f, binary_range(x.s.str(), x.s.size())));
                 case type::reference_type:
                     return apply(*x.p, y, f);
             }
@@ -534,16 +631,26 @@
     inline utree::utree(char const* str)
     {
         s.construct(str, str + strlen(str));
+        set_type(type::string_type);
     }
 
     inline utree::utree(char const* str, std::size_t len)
     {
         s.construct(str, str + len);
+        set_type(type::string_type);
     }
 
     inline utree::utree(std::string const& str)
     {
         s.construct(str.begin(), str.end());
+        set_type(type::string_type);
+    }
+
+    template <typename Base>
+    inline utree::utree(binary<Base> const& bin)
+    {
+        s.construct(bin.begin(), bin.end());
+        set_type(type::binary_type);
     }
 
     inline utree::utree(boost::reference_wrapper<utree> ref)
@@ -608,6 +715,7 @@
     {
         free();
         s.construct(s_, s_ + strlen(s_));
+        set_type(type::string_type);
         return *this;
     }
 
@@ -615,6 +723,16 @@
     {
         free();
         s.construct(s_.begin(), s_.end());
+        set_type(type::string_type);
+        return *this;
+    }
+
+    template <typename Base>
+    inline utree& utree::operator=(binary<Base> const& bin)
+    {
+        free();
+        s.construct(bin.begin(), bin.end());
+        set_type(type::binary_type);
         return *this;
     }
 
@@ -714,6 +832,12 @@
         return !(a < b);
     }
 
+    inline std::ostream& operator<<(std::ostream& out, utree const& x)
+    {
+        utree::visit(x, detail::utree_print(out));
+        return out;
+    }
+
     template <typename T>
     inline void utree::push_front(T const& val)
     {
@@ -941,7 +1065,8 @@
     {
         switch (get_type())
         {
-            case type::heap_string_type:
+            case type::binary_type:
+            case type::string_type:
                 s.free();
                 break;
             case type::list_type:
@@ -971,8 +1096,8 @@
             case type::reference_type:
                 p = other.p;
                 break;
-            case type::small_string_type:
-            case type::heap_string_type:
+            case type::string_type:
+            case type::binary_type:
                 s.copy(other.s);
                 break;
             case type::list_type:
Modified: trunk/libs/spirit/example/scheme/sexpr.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/sexpr.hpp	(original)
+++ trunk/libs/spirit/example/scheme/sexpr.hpp	2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -89,20 +89,6 @@
             }
         };
 
-        struct push_binary
-        {
-            template <typename S, typename C>
-            struct result { typedef void type; };
-
-            void operator()(std::string& utf8, char byte) const
-            {
-                if (utf8.size() == 0)
-                    utf8 += '\1';   //  mark a byte string with prefix 1
-                                    //  (a 1 byte at the beginning signifies a byte string)
-                utf8 += byte;
-            }
-        };
-
         struct push_esc
         {
             template <typename S, typename C>
@@ -161,7 +147,6 @@
             real_parser<double, strict_real_policies<double> > strict_double;
             uint_parser<unsigned char, 16, 2, 2> hex2;
             function<detail::push_symbol> push_symbol;
-            function<detail::push_binary> push_binary;
 
             start   = atom | list;
 
@@ -183,13 +168,13 @@
                     | int_                              [_val = _1]
                     ;
 
-            byte_str = lexeme[no_case['b'] >> +(hex2    [push_binary(_val, _1)])];
+            byte_str = lexeme[no_case['b'] >> +hex2];
         }
 
         rule<Iterator, white_space<Iterator>, utree()> start, list;
         rule<Iterator, utree()> atom, number;
         rule<Iterator, std::string()> symbol;
-        rule<Iterator, std::string()> byte_str;
+        rule<Iterator, binary_string()> byte_str;
         scheme::string<Iterator> string;
     };
 }
Modified: trunk/libs/spirit/example/scheme/simple_print.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/simple_print.hpp	(original)
+++ trunk/libs/spirit/example/scheme/simple_print.hpp	2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -6,96 +6,9 @@
 
 namespace detail
 {
-    ///////////////////////////////////////////////////////////////////////////
-    // simple utree printing facility prints the utree in a single line
-    ///////////////////////////////////////////////////////////////////////////
-
-    std::ostream& print(std::ostream& out, scheme::utree const& val);
-    std::ostream& println(std::ostream& out, scheme::utree const& val);
-
-    // simple_print visitor
-    struct simple_print
-    {
-        typedef void result_type;
-
-        std::ostream& out;
-        simple_print(std::ostream& out) : out(out) {}
-
-        void operator()(scheme::utree::nil) const
-        {
-            out << "nil";
-        }
-
-        template <typename T>
-        void operator()(T val) const
-        {
-            out << val;
-        }
-
-        void operator()(bool b) const
-        {
-            out << (b ? "true" : "false");
-        }
-
-        template <typename Range> // for lists
-        void print_string_or_list(Range range, boost::mpl::false_) const
-        {
-            typedef typename Range::const_iterator iterator;
-            (*this)('(');
-            for (iterator i = range.begin(); i != range.end(); ++i)
-            {
-                if (i != range.begin())
-                    (*this)(' ');
-                scheme::utree::visit(*i, *this);
-            }
-            (*this)(')');
-        }
-
-        template <typename Range> // for strings
-        void print_string_or_list(Range range, boost::mpl::true_) const
-        {
-            typedef typename Range::const_iterator iterator;
-            iterator i = range.begin();
-            if (*i == '\1') // a 1 byte at the beginning signifies a byte string
-            {
-                out << "b"; ++i;
-                out.width(2);
-                out.fill('0');
-                for (; i != range.end(); ++i)
-                    out << std::hex << int((unsigned char)*i);
-                out << std::dec;
-            }
-            else
-            {
-                bool const is_symbol = *i == '\0';  // a 0 byte at the beginning signifies a symbol
-                if (!is_symbol)
-                    out << '"';
-                else
-                    ++i;
-                for (; i != range.end(); ++i)
-                    out << *i;
-                if (!is_symbol)
-                    out << '"';
-            }
-        }
-
-        template <typename Iterator>
-        void operator()(boost::iterator_range<Iterator> const& range) const
-        {
-            // This code works for both strings and lists
-            print_string_or_list(range, boost::is_pointer<Iterator>());
-        }
-    };
-
-    inline std::ostream& print(std::ostream& out, scheme::utree const& val)
-    {
-        scheme::utree::visit(val, simple_print(out));
-        return out;
-    }
-
     inline std::ostream& println(std::ostream& out, scheme::utree const& val)
     {
-        detail::print(out, val) << std::endl;
+        out << val << std::endl;
         return out;
     }
 }
Modified: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp	(original)
+++ trunk/libs/spirit/example/scheme/utree.hpp	2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -10,6 +10,8 @@
 #include <cstddef>
 #include <algorithm>
 #include <string>
+#include <ostream>
+
 #include <boost/assert.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/iterator/iterator_facade.hpp>
@@ -21,6 +23,11 @@
 
 namespace scheme
 {
+    struct nil {};
+
+    template <typename Base>
+    struct binary;
+
     ///////////////////////////////////////////////////////////////////////////
     // The main utree (Universal Tree) class
     // The utree is a hierarchical, dynamic type that can store:
@@ -28,7 +35,8 @@
     //  - a bool
     //  - an integer
     //  - a double
-    //  - a string (textual or binary)
+    //  - a string
+    //  - binary data
     //  - a (doubly linked) list of utree
     //  - a reference to a utree
     //
@@ -48,16 +56,6 @@
         typedef std::ptrdiff_t difference_type;
         typedef std::size_t size_type;
 
-        struct nil {};
-
-        struct binary
-        {
-            binary(unsigned char bits[], std::size_t len)
-              : bits(bits), len(len) {}
-            unsigned char* bits;
-            std::size_t len;
-        };
-
         utree();
         explicit utree(bool b);
         explicit utree(unsigned int i);
@@ -66,6 +64,9 @@
         explicit utree(char const* str);
         explicit utree(char const* str, std::size_t len);
         explicit utree(std::string const& str);
+
+        template <typename Base>
+        explicit utree(binary<Base> const& bin);
         explicit utree(boost::reference_wrapper<utree> ref);
 
         utree(utree const& other);
@@ -78,6 +79,9 @@
         utree& operator=(double d);
         utree& operator=(char const* s);
         utree& operator=(std::string const& s);
+
+        template <typename Base>
+        utree& operator=(binary<Base> const& bin);
         utree& operator=(boost::reference_wrapper<utree> ref);
 
         template <typename F>
@@ -181,14 +185,25 @@
     bool operator>(utree const& a, utree const& b);
     bool operator<=(utree const& a, utree const& b);
     bool operator>=(utree const& a, utree const& b);
+    std::ostream& operator<<(std::ostream& out, utree const& x);
 
-    ///////////////////////////////////////////////////////////////////////////
-    // The ulist is a utility class for easy construction of utree lists
-    ///////////////////////////////////////////////////////////////////////////
-    struct ulist : utree
+    template <typename Base>
+    struct binary : Base
     {
-        ulist() : utree(construct_list()) {}
+        binary()
+          : Base() {}
+
+        template <typename Iterator>
+        binary(Iterator bits, std::size_t len)
+          : Base(bits, bits + len) {}
+
+        template <typename Iterator>
+        binary(Iterator first, Iterator last)
+          : Base(first, last) {}
     };
+
+    typedef binary<boost::iterator_range<char const*> > binary_range;
+    typedef binary<std::string> binary_string;
 }
 
 #include "detail/utree_detail2.hpp"
Modified: trunk/libs/spirit/example/scheme/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree_test.cpp	(original)
+++ trunk/libs/spirit/example/scheme/utree_test.cpp	2010-03-21 13:14:47 EDT (Sun, 21 Mar 2010)
@@ -108,7 +108,7 @@
         a = 100.00;
         BOOST_ASSERT(a < b);
 
-        b = a = ulist();
+        b = a = utree();
         BOOST_ASSERT(a == b);
         a.push_back(1);
         a.push_back("two");
@@ -123,7 +123,7 @@
     }
 
     {
-        ulist a;
+        utree a;
         a.push_back(1);
         a.push_back(2);
         a.push_back(3);