|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61479 - in trunk/libs/spirit/example/scheme: scheme test/utree utree utree/detail
From: joel_at_[hidden]
Date: 2010-04-21 22:39:04
Author: djowel
Date: 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
New Revision: 61479
URL: http://svn.boost.org/trac/boost/changeset/61479
Log:
added utree shallow ranges
Text files modified:
trunk/libs/spirit/example/scheme/scheme/compiler.hpp | 2
trunk/libs/spirit/example/scheme/scheme/interpreter.hpp | 2
trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp | 21 +++++
trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp | 9 ++
trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp | 139 +++++++++++++++++++++++++++++++++++----
trunk/libs/spirit/example/scheme/utree/operators.hpp | 33 +++++++--
trunk/libs/spirit/example/scheme/utree/utree.hpp | 31 ++++++--
7 files changed, 203 insertions(+), 34 deletions(-)
Modified: trunk/libs/spirit/example/scheme/scheme/compiler.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/compiler.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/compiler.hpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -352,7 +352,7 @@
return function();
}
- function operator()(polymorphic_function_base const& pf) const
+ function operator()(function_base const& pf) const
{
// Can't reach here. Surely, at this point, we don't have
// utree functions yet. The utree AST should be pure data.
Modified: trunk/libs/spirit/example/scheme/scheme/interpreter.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/scheme/interpreter.hpp (original)
+++ trunk/libs/spirit/example/scheme/scheme/interpreter.hpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -98,7 +98,7 @@
template <typename F>
function(F const& f)
- : f(polymorphic_function<F>(f))
+ : f(stored_function<F>(f))
{
}
Modified: trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/utree/utree_test.cpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -265,9 +265,28 @@
{
// test functions
- utree f = scheme::polymorphic_function<one_two_three>();
+ utree f = scheme::stored_function<one_two_three>();
f.eval(scheme::args_type());
}
+ {
+ // shallow ranges
+ utree val;
+ val.push_back(1);
+ val.push_back(2);
+ val.push_back(3);
+ val.push_back(4);
+
+ utree::iterator i = val.begin(); ++i;
+ utree alias(utree::range(i, val.end()), scheme::shallow);
+
+ check(alias, "( 2 3 4 )");
+ BOOST_TEST(alias.size() == 3);
+ BOOST_TEST(alias.front() == 2);
+ BOOST_TEST(alias.back() == 4);
+ BOOST_TEST(!alias.empty());
+ BOOST_TEST(alias[1] == 3);
+ }
+
return boost::report_errors();
}
Modified: trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail1.hpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -56,6 +56,15 @@
};
///////////////////////////////////////////////////////////////////////////
+ // A range of utree(s) using an iterator range (begin/end) of node(s)
+ ///////////////////////////////////////////////////////////////////////////
+ struct range
+ {
+ list::node* first;
+ list::node* last;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
// Our POD fast string. This implementation is very primitive and is not
// meant to be used stand-alone. This is the internal data representation
// of strings in our utree. This is deliberately a POD to allow it to be
Modified: trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/detail/utree_detail2.hpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -182,7 +182,7 @@
return node == other.node;
}
- reference dereference() const
+ typename node_iterator::reference dereference() const
{
return node->val;
}
@@ -240,7 +240,7 @@
return node == other.node;
}
- reference dereference() const
+ typename node_iterator::reference dereference() const
{
return curr;
}
@@ -450,6 +450,9 @@
case type::list_type:
return f(list_range(iterator(x.l.first), iterator(0, x.l.last)));
+ case type::range_type:
+ return f(list_range(iterator(x.r.first), iterator(0, x.r.last)));
+
case type::string_type:
return f(utf8_string_range(x.s.str(), x.s.size()));
@@ -503,6 +506,11 @@
y, detail::bind<F, list_range>(f,
list_range(iterator(x.l.first), iterator(0, x.l.last))));
+ case type::range_type:
+ return visit_impl::apply(
+ y, detail::bind<F, list_range>(f,
+ list_range(iterator(x.r.first), iterator(0, x.r.last))));
+
case type::string_type:
return visit_impl::apply(y, detail::bind(
f, utf8_string_range(x.s.str(), x.s.size())));
@@ -546,27 +554,27 @@
namespace scheme
{
template <typename F>
- polymorphic_function<F>::polymorphic_function(F f)
+ stored_function<F>::stored_function(F f)
: f(f)
{
}
template <typename F>
- polymorphic_function<F>::~polymorphic_function()
+ stored_function<F>::~stored_function()
{
};
template <typename F>
- utree polymorphic_function<F>::operator()(args_type args) const
+ utree stored_function<F>::operator()(args_type args) const
{
return f(args);
}
template <typename F>
- polymorphic_function_base*
- polymorphic_function<F>::clone() const
+ function_base*
+ stored_function<F>::clone() const
{
- return new polymorphic_function<F>(*this);
+ return new stored_function<F>(*this);
}
inline utree::utree()
@@ -626,8 +634,8 @@
}
template <typename F>
- inline utree::utree(polymorphic_function<F> const& pf)
- : pf(new polymorphic_function<F>(pf))
+ inline utree::utree(stored_function<F> const& pf)
+ : pf(new stored_function<F>(pf))
{
set_type(type::function_type);
}
@@ -639,6 +647,20 @@
assign(r.begin(), r.end());
}
+ inline utree::utree(range r, shallow_tag)
+ {
+ this->r.first = r.begin().node;
+ this->r.last = r.end().prev;
+ set_type(type::range_type);
+ }
+
+ inline utree::utree(const_range r, shallow_tag)
+ {
+ this->r.first = r.begin().node;
+ this->r.last = r.end().prev;
+ set_type(type::range_type);
+ }
+
inline utree::utree(utree const& other)
{
copy(other);
@@ -725,10 +747,10 @@
}
template <typename F>
- utree& utree::operator=(polymorphic_function<F> const& pf)
+ utree& utree::operator=(stored_function<F> const& pf)
{
free();
- pf = new polymorphic_function<F>(pf);
+ pf = new stored_function<F>(pf);
set_type(type::function_type);
return *this;
}
@@ -738,6 +760,7 @@
{
free();
assign(r.begin(), r.end());
+ return *this;
}
template <typename F>
@@ -786,6 +809,10 @@
{
if (get_type() == type::reference_type)
return (*p)[i];
+ else if (get_type() == type::range_type)
+ return detail::index_impl::apply(r.first, i);
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type && size() > i);
return detail::index_impl::apply(l.first, i);
}
@@ -794,6 +821,10 @@
{
if (get_type() == type::reference_type)
return (*(utree const*)p)[i];
+ else if (get_type() == type::range_type)
+ return detail::index_impl::apply(r.first, i);
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type && size() > i);
return detail::index_impl::apply(l.first, i);
}
@@ -911,6 +942,10 @@
{
if (get_type() == type::reference_type)
return p->begin();
+ else if (get_type() == type::range_type)
+ return iterator(r.first);
+
+ // otherwise...
ensure_list_type();
return iterator(l.first);
}
@@ -919,6 +954,10 @@
{
if (get_type() == type::reference_type)
return p->end();
+ else if (get_type() == type::range_type)
+ return iterator(0, r.first);
+
+ // otherwise...
ensure_list_type();
return iterator(0, l.last);
}
@@ -927,6 +966,10 @@
{
if (get_type() == type::reference_type)
return p->ref_begin();
+ else if (get_type() == type::range_type)
+ return ref_iterator(r.first);
+
+ // otherwise...
ensure_list_type();
return ref_iterator(l.first);
}
@@ -935,6 +978,10 @@
{
if (get_type() == type::reference_type)
return p->ref_end();
+ else if (get_type() == type::range_type)
+ return ref_iterator(0, r.first);
+
+ // otherwise...
ensure_list_type();
return ref_iterator(0, l.last);
}
@@ -943,6 +990,10 @@
{
if (get_type() == type::reference_type)
return ((utree const*)p)->begin();
+ else if (get_type() == type::range_type)
+ return const_iterator(r.first);
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type);
return const_iterator(l.first);
}
@@ -951,6 +1002,10 @@
{
if (get_type() == type::reference_type)
return ((utree const*)p)->end();
+ else if (get_type() == type::range_type)
+ return const_iterator(0, r.first);
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type);
return const_iterator(0, l.last);
}
@@ -959,7 +1014,9 @@
{
if (get_type() == type::reference_type)
return ((utree const*)p)->empty();
- if (get_type() == type::list_type)
+ else if (get_type() == type::range_type)
+ return r.first == 0;
+ else if (get_type() == type::list_type)
return l.size == 0;
BOOST_ASSERT(get_type() == type::nil_type);
return true;
@@ -968,9 +1025,24 @@
inline std::size_t utree::size() const
{
if (get_type() == type::reference_type)
+ {
return ((utree const*)p)->size();
- if (get_type() == type::list_type)
+ }
+ else if (get_type() == type::range_type)
+ {
+ std::size_t size = 0;
+ detail::list::node* n = r.first;
+ while (n)
+ {
+ n = n->next;
+ ++size;
+ }
+ return size;
+ }
+ else if (get_type() == type::list_type)
+ {
return l.size;
+ }
BOOST_ASSERT(get_type() == type::nil_type);
return 0;
}
@@ -983,7 +1055,16 @@
inline utree& utree::front()
{
if (get_type() == type::reference_type)
+ {
return p->front();
+ }
+ else if (get_type() == type::range_type)
+ {
+ BOOST_ASSERT(r.first != 0);
+ return r.first->val;
+ }
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type && l.first != 0);
return l.first->val;
}
@@ -991,7 +1072,16 @@
inline utree& utree::back()
{
if (get_type() == type::reference_type)
+ {
return p->back();
+ }
+ else if (get_type() == type::range_type)
+ {
+ BOOST_ASSERT(r.last != 0);
+ return r.last->val;
+ }
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type && l.last != 0);
return l.last->val;
}
@@ -999,7 +1089,16 @@
inline utree const& utree::front() const
{
if (get_type() == type::reference_type)
+ {
return ((utree const*)p)->front();
+ }
+ else if (get_type() == type::range_type)
+ {
+ BOOST_ASSERT(r.first != 0);
+ return r.first->val;
+ }
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type && l.first != 0);
return l.first->val;
}
@@ -1007,7 +1106,16 @@
inline utree const& utree::back() const
{
if (get_type() == type::reference_type)
+ {
return ((utree const*)p)->back();
+ }
+ else if (get_type() == type::range_type)
+ {
+ BOOST_ASSERT(r.last != 0);
+ return r.last->val;
+ }
+
+ // otherwise...
BOOST_ASSERT(get_type() == type::list_type && l.last != 0);
return l.last->val;
}
@@ -1081,6 +1189,9 @@
case type::reference_type:
p = other.p;
break;
+ case type::range_type:
+ r = other.r;
+ break;
case type::function_type:
pf = other.pf->clone();
break;
Modified: trunk/libs/spirit/example/scheme/utree/operators.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/operators.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/operators.hpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -13,6 +13,7 @@
# pragma warning(disable: 4805)
#endif
+#include <exception>
#include <utree/utree.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
@@ -20,6 +21,24 @@
namespace scheme
{
+ struct utree_exception : std::exception {};
+
+ 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);
@@ -99,7 +118,7 @@
return true;
}
- bool operator()(polymorphic_function_base const& a, polymorphic_function_base const& b) const
+ bool operator()(function_base const& a, function_base const& b) const
{
return false; // just don't allow comparison of functions
}
@@ -151,7 +170,7 @@
return false; // no less than comparison for nil
}
- bool operator()(polymorphic_function_base const& a, polymorphic_function_base const& b) const
+ bool operator()(function_base const& a, function_base const& b) const
{
BOOST_ASSERT(false);
return false; // no less than comparison of functions
@@ -225,7 +244,7 @@
(*this)(')');
}
- void operator()(polymorphic_function_base const& pf) const
+ void operator()(function_base const& pf) const
{
return (*this)("<function>");
}
@@ -288,7 +307,7 @@
template <typename A, typename B>
utree dispatch(A const&, B const&, boost::mpl::false_) const
{
- // $$$ Throw exception here? $$$
+ throw illegal_arithmetic_operation();
return utree(); // cannot apply to non-arithmetic types
}
@@ -311,7 +330,7 @@
template <typename A>
utree dispatch(A const&, boost::mpl::false_) const
{
- // $$$ Throw exception here? $$$
+ throw illegal_arithmetic_operation();
return utree(); // cannot apply to non-arithmetic types
}
@@ -337,7 +356,7 @@
template <typename A, typename B>
utree dispatch(A const&, B const&, boost::mpl::false_) const
{
- // $$$ Throw exception here? $$$
+ throw illegal_integral_operation();
return utree(); // cannot apply to non-integral types
}
@@ -360,7 +379,7 @@
template <typename A>
utree dispatch(A const&, boost::mpl::false_) const
{
- // $$$ Throw exception here? $$$
+ throw illegal_integral_operation();
return utree(); // cannot apply to non-integral types
}
Modified: trunk/libs/spirit/example/scheme/utree/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree/utree.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree/utree.hpp 2010-04-21 22:39:03 EDT (Wed, 21 Apr 2010)
@@ -45,6 +45,7 @@
symbol_type,
binary_type,
list_type,
+ range_type,
reference_type,
function_type
};
@@ -136,24 +137,31 @@
class utree;
typedef boost::iterator_range<utree const*> args_type;
- struct polymorphic_function_base
+ struct function_base
{
- virtual ~polymorphic_function_base() {};
+ virtual ~function_base() {};
virtual utree operator()(args_type args) const = 0;
- virtual polymorphic_function_base* clone() const = 0;
+ virtual function_base* clone() const = 0;
};
template <typename F>
- struct polymorphic_function : polymorphic_function_base
+ struct stored_function : function_base
{
F f;
- polymorphic_function(F f = F());
- virtual ~polymorphic_function();
+ stored_function(F f = F());
+ virtual ~stored_function();
virtual utree operator()(args_type args) const;
- virtual polymorphic_function_base* clone() const;
+ virtual function_base* clone() const;
};
///////////////////////////////////////////////////////////////////////////
+ // Shallow tag. Instructs utree to hold an iterator_range
+ // as-is without deep copying the range.
+ ///////////////////////////////////////////////////////////////////////////
+ struct shallow_tag {};
+ shallow_tag const shallow = {};
+
+ ///////////////////////////////////////////////////////////////////////////
// The main utree (Universal Tree) class
// The utree is a hierarchical, dynamic type that can store:
// - a nil
@@ -199,9 +207,11 @@
template <typename Iter>
utree(boost::iterator_range<Iter> r);
+ utree(range r, shallow_tag);
+ utree(const_range r, shallow_tag);
template <typename F>
- utree(polymorphic_function<F> const& pf);
+ utree(stored_function<F> const& pf);
template <typename Base, utree_type::info type_>
utree(basic_string<Base, type_> const& bin);
@@ -219,7 +229,7 @@
utree& operator=(boost::reference_wrapper<utree> ref);
template <typename F>
- utree& operator=(polymorphic_function<F> const& pf);
+ utree& operator=(stored_function<F> const& pf);
template <typename Iter>
utree& operator=(boost::iterator_range<Iter> r);
@@ -330,11 +340,12 @@
{
detail::fast_string s;
detail::list l;
+ detail::range r;
bool b;
int i;
double d;
utree* p;
- polymorphic_function_base* pf;
+ function_base* pf;
};
};
}
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