$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60470 - trunk/libs/spirit/example/scheme
From: joel_at_[hidden]
Date: 2010-03-11 02:20:11
Author: djowel
Date: 2010-03-11 02:20:10 EST (Thu, 11 Mar 2010)
New Revision: 60470
URL: http://svn.boost.org/trac/boost/changeset/60470
Log:
support for references
Text files modified: 
   trunk/libs/spirit/example/scheme/simple_print.hpp |     2                                         
   trunk/libs/spirit/example/scheme/utree.hpp        |    75 ++++++++++++++++++++++++++++++++++++++- 
   trunk/libs/spirit/example/scheme/utree_test.cpp   |    18 +++++++++                               
   3 files changed, 92 insertions(+), 3 deletions(-)
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-11 02:20:10 EST (Thu, 11 Mar 2010)
@@ -83,7 +83,7 @@
 
     inline std::ostream& println(std::ostream& out, scheme::utree const& val)
     {
-        out << detail::print(out, val) << std::endl;
+        detail::print(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-11 02:20:10 EST (Thu, 11 Mar 2010)
@@ -15,6 +15,7 @@
 #include <boost/iterator/iterator_facade.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <boost/type_traits/is_pointer.hpp>
+#include <boost/ref.hpp>
 
 #if defined(BOOST_MSVC)
 # pragma warning(push)
@@ -43,7 +44,8 @@
             double_type,
             small_string_type,
             heap_string_type,
-            list_type
+            list_type,
+            reference_type
         };
     };
 
@@ -172,9 +174,9 @@
         explicit utree(char const* str);
         explicit utree(char const* str, std::size_t len);
         explicit utree(std::string const& str);
+        explicit utree(boost::reference_wrapper<utree> ref);
 
         utree(utree const& other);
-        utree(utree const& other);
         ~utree();
 
         utree& operator=(utree const& other);
@@ -184,6 +186,7 @@
         utree& operator=(double d);
         utree& operator=(char const* s);
         utree& operator=(std::string const& s);
+        utree& operator=(boost::reference_wrapper<utree> ref);
 
         template <typename F>
         typename F::result_type
@@ -276,6 +279,7 @@
             bool b;
             int i;
             double d;
+            utree* p;
         };
     };
 
@@ -711,6 +715,8 @@
                 case type::heap_string_type:
                 case type::small_string_type:
                     return f(string_range(x.s.str(), x.s.str() + x.s.size()));
+                case type::reference_type:
+                    return apply(*x.p, f);
             }
         }
 
@@ -753,6 +759,8 @@
                 case type::small_string_type:
                     return visit_impl::apply(y, detail::bind(
                         f, string_range(x.s.str(), x.s.str() + x.s.size())));
+                case type::reference_type:
+                    return apply(*x.p, y, f);
             }
         }
     };
@@ -817,6 +825,12 @@
         s.construct(str.begin(), str.end());
     }
 
+    inline utree::utree(boost::reference_wrapper<utree> ref)
+      : p(ref.get_pointer())
+    {
+        set_type(type::reference_type);
+    }
+
     inline utree::utree(utree const& other)
     {
         copy(other);
@@ -883,6 +897,14 @@
         return *this;
     }
 
+    inline utree& utree::operator=(boost::reference_wrapper<utree> ref)
+    {
+        free();
+        p = ref.get_pointer();
+        set_type(type::reference_type);
+        return *this;
+    }
+
     template <typename F>
     typename F::result_type
     inline utree::visit(utree const& x, F f)
@@ -927,12 +949,16 @@
 
     inline utree& utree::operator[](std::size_t i)
     {
+        if (get_type() == type::reference_type)
+            return (*p)[i];
         BOOST_ASSERT(get_type() == type::list_type && size() > i);
         return detail::index_impl::apply(l.first, i);
     }
 
     inline utree const& utree::operator[](std::size_t i) const
     {
+        if (get_type() == type::reference_type)
+            return (*(utree const*)p)[i];
         BOOST_ASSERT(get_type() == type::list_type && size() > i);
         return detail::index_impl::apply(l.first, i);
     }
@@ -970,6 +996,8 @@
     template <typename T>
     inline void utree::push_front(T const& val)
     {
+        if (get_type() == type::reference_type)
+            return p->push_front(val);
         ensure_list_type();
         l.push_front(val);
     }
@@ -977,6 +1005,8 @@
     template <typename T>
     inline void utree::push_back(T const& val)
     {
+        if (get_type() == type::reference_type)
+            return p->push_back(val);
         ensure_list_type();
         l.push_back(val);
     }
@@ -984,6 +1014,8 @@
     template <typename T>
     inline utree::iterator utree::insert(iterator pos, T const& val)
     {
+        if (get_type() == type::reference_type)
+            return p->insert(pos, val);
         ensure_list_type();
         if (pos.node == l.last)
         {
@@ -1001,6 +1033,8 @@
     template <typename T>
     inline void utree::insert(iterator pos, std::size_t n, T const& val)
     {
+        if (get_type() == type::reference_type)
+            return p->insert(pos, n, val);
         for (std::size_t i = 0; i != n; ++i)
             insert(pos, val);
     }
@@ -1008,6 +1042,8 @@
     template <typename Iter>
     inline void utree::insert(iterator pos, Iter first, Iter last)
     {
+        if (get_type() == type::reference_type)
+            return p->insert(pos, first, last);
         ensure_list_type();
         while (first != last)
             insert(pos, *first++);
@@ -1016,6 +1052,8 @@
     template <typename Iter>
     inline void utree::assign(Iter first, Iter last)
     {
+        if (get_type() == type::reference_type)
+            return p->assign(first, last);
         ensure_list_type();
         clear();
         while (first != last)
@@ -1024,6 +1062,8 @@
 
     inline void utree::clear()
     {
+        if (get_type() == type::reference_type)
+            return p->clear();
         // clear will always make this a nil type
         free();
         set_type(type::nil_type);
@@ -1031,24 +1071,32 @@
 
     inline void utree::pop_front()
     {
+        if (get_type() == type::reference_type)
+            return p->pop_front();
         BOOST_ASSERT(get_type() == type::list_type);
         l.pop_front();
     }
 
     inline void utree::pop_back()
     {
+        if (get_type() == type::reference_type)
+            return p->pop_back();
         BOOST_ASSERT(get_type() == type::list_type);
         l.pop_back();
     }
 
     inline utree::iterator utree::erase(iterator pos)
     {
+        if (get_type() == type::reference_type)
+            return p->erase(pos);
         BOOST_ASSERT(get_type() == type::list_type);
         return iterator(l.erase(pos.node));
     }
 
     inline utree::iterator utree::erase(iterator first, iterator last)
     {
+        if (get_type() == type::reference_type)
+            return p->erase(first, last);
         while (first != last)
             erase(first++);
         return last;
@@ -1056,30 +1104,40 @@
 
     inline utree::iterator utree::begin()
     {
+        if (get_type() == type::reference_type)
+            return p->begin();
         ensure_list_type();
         return iterator(l.first);
     }
 
     inline utree::iterator utree::end()
     {
+        if (get_type() == type::reference_type)
+            return p->end();
         ensure_list_type();
         return iterator(l.last);
     }
 
     inline utree::const_iterator utree::begin() const
     {
+        if (get_type() == type::reference_type)
+            return ((utree const*)p)->begin();
         BOOST_ASSERT(get_type() == type::list_type);
         return const_iterator(l.first);
     }
 
     inline utree::const_iterator utree::end() const
     {
+        if (get_type() == type::reference_type)
+            return ((utree const*)p)->end();
         BOOST_ASSERT(get_type() == type::list_type);
         return const_iterator(l.last);
     }
 
     inline bool utree::empty() const
     {
+        if (get_type() == type::reference_type)
+            return ((utree const*)p)->empty();
         if (get_type() == type::list_type)
             return l.size == 0;
         BOOST_ASSERT(get_type() == type::nil_type);
@@ -1088,6 +1146,8 @@
 
     inline std::size_t utree::size() const
     {
+        if (get_type() == type::reference_type)
+            return ((utree const*)p)->size();
         if (get_type() == type::list_type)
             return l.size;
         BOOST_ASSERT(get_type() == type::nil_type);
@@ -1096,24 +1156,32 @@
 
     inline utree& utree::front()
     {
+        if (get_type() == type::reference_type)
+            return p->front();
         BOOST_ASSERT(get_type() == type::list_type && l.first != 0);
         return l.first->val;
     }
 
     inline utree& utree::back()
     {
+        if (get_type() == type::reference_type)
+            return p->back();
         BOOST_ASSERT(get_type() == type::list_type && l.last != 0);
         return l.last->val;
     }
 
     inline utree const& utree::front() const
     {
+        if (get_type() == type::reference_type)
+            return ((utree const*)p)->front();
         BOOST_ASSERT(get_type() == type::list_type && l.first != 0);
         return l.first->val;
     }
 
     inline utree const& utree::back() const
     {
+        if (get_type() == type::reference_type)
+            return ((utree const*)p)->back();
         BOOST_ASSERT(get_type() == type::list_type && l.last != 0);
         return l.last->val;
     }
@@ -1179,6 +1247,9 @@
             case type::double_type:
                 d = other.d;
                 break;
+            case type::reference_type:
+                p = other.p;
+                break;
             case type::small_string_type:
             case type::heap_string_type:
                 s.copy(other.s);
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-11 02:20:10 EST (Thu, 11 Mar 2010)
@@ -151,5 +151,23 @@
         BOOST_ASSERT(a[11] == utree(12));
     }
 
+    { // test references
+        utree val(123);
+        utree ref(boost::ref(val));
+        println(std::cout, ref);
+        BOOST_ASSERT(ref == utree(123));
+
+        val.clear();
+        val.push_back(1);
+        val.push_back(2);
+        val.push_back(3);
+        val.push_back(4);
+        println(std::cout, ref);
+        BOOST_ASSERT(ref[0] == utree(1));
+        BOOST_ASSERT(ref[1] == utree(2));
+        BOOST_ASSERT(ref[2] == utree(3));
+        BOOST_ASSERT(ref[3] == utree(4));
+    }
+
     return 0;
 }