Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61012 - in trunk/libs/spirit/example/scheme: . detail test
From: joel_at_[hidden]
Date: 2010-04-03 03:57:37


Author: djowel
Date: 2010-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
New Revision: 61012
URL: http://svn.boost.org/trac/boost/changeset/61012

Log:
scheme operators
Added:
   trunk/libs/spirit/example/scheme/test/scheme.cpp (contents, props changed)
   trunk/libs/spirit/example/scheme/utree_operators.hpp (contents, props changed)
Text files modified:
   trunk/libs/spirit/example/scheme/detail/utree_detail1.hpp | 2
   trunk/libs/spirit/example/scheme/detail/utree_detail2.hpp | 217 +++------------------------------------
   trunk/libs/spirit/example/scheme/test/utree_test.cpp | 13 ++
   trunk/libs/spirit/example/scheme/utree.hpp | 27 ++--
   4 files changed, 51 insertions(+), 208 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-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
@@ -14,6 +14,8 @@
 # pragma warning(disable: 4244)
 #endif
 
+#include <boost/type_traits/alignment_of.hpp>
+
 namespace scheme { namespace detail
 {
     template <typename UTreeX, typename UTreeY>

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-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
@@ -315,167 +315,6 @@
         return bind_impl<F, X>(f, x);
     }
 
- struct utree_is_equal
- {
- typedef bool result_type;
-
- template <typename A, typename B>
- bool dispatch(const A&, const B&, boost::mpl::false_) const
- {
- return false; // cannot compare different types by default
- }
-
- template <typename A, typename B>
- bool dispatch(const A& a, const B& b, boost::mpl::true_) const
- {
- return a == b; // for arithmetic types
- }
-
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const
- {
- return dispatch(a, b,
- boost::mpl::and_<
- boost::is_arithmetic<A>,
- boost::is_arithmetic<B> >());
- }
-
- template <typename T>
- bool operator()(const T& a, const T& b) const
- {
- // This code works for lists
- return a == b;
- }
-
- template <typename Base, utree_type::info type_>
- bool operator()(
- basic_string<Base, type_> const& a,
- basic_string<Base, type_> const& b) const
- {
- return static_cast<Base const&>(a) == static_cast<Base const&>(b);
- }
-
- bool operator()(nil, nil) const
- {
- return true;
- }
- };
-
- struct utree_is_less_than
- {
- typedef bool result_type;
-
- template <typename A, typename B>
- bool dispatch(const A&, const B&, boost::mpl::false_) const
- {
- return false; // cannot compare different types by default
- }
-
- template <typename A, typename B>
- bool dispatch(const A& a, const B& b, boost::mpl::true_) const
- {
- return a < b; // for arithmetic types
- }
-
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const
- {
- return dispatch(a, b,
- boost::mpl::and_<
- boost::is_arithmetic<A>,
- boost::is_arithmetic<B> >());
- }
-
- template <typename T>
- bool operator()(const T& a, const T& b) const
- {
- // This code works for lists
- return a < b;
- }
-
- template <typename Base, utree_type::info type_>
- bool operator()(
- basic_string<Base, type_> const& a,
- basic_string<Base, type_> const& b) const
- {
- return static_cast<Base const&>(a) < static_cast<Base const&>(b);
- }
-
- 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");
- }
-
- void operator()(binary_range const& b) const
- {
- out << "b";
- out.width(2);
- out.fill('0');
-
- typedef binary_range::const_iterator iterator;
- for (iterator i = b.begin(); i != b.end(); ++i)
- out << std::hex << int((unsigned char)*i);
- out << std::dec;
- }
-
- void operator()(utf8_string_range const& str) const
- {
- typedef utf8_string_range::const_iterator iterator;
- iterator i = str.begin();
- out << '"';
- for (; i != str.end(); ++i)
- out << *i;
- out << '"';
- }
-
- void operator()(utf8_symbol_range const& str) const
- {
- typedef utf8_symbol_range::const_iterator iterator;
- iterator i = str.begin();
- for (; i != str.end(); ++i)
- out << *i;
- }
-
- template <typename Iterator>
- void operator()(boost::iterator_range<Iterator> const& range) const
- {
- typedef typename boost::iterator_range<Iterator>::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 UTreeX, typename UTreeY = UTreeX>
     struct visit_impl
     {
@@ -524,6 +363,9 @@
 
                 case type::reference_type:
                     return apply(*x.p, f);
+
+ case type::function_type:
+ return f(x.f);
             }
         }
 
@@ -577,6 +419,9 @@
 
                 case type::reference_type:
                     return apply(*x.p, y, f);
+
+ case type::function_type:
+ return visit_impl::apply(y, detail::bind(f, x.f));
             }
         }
     };
@@ -657,6 +502,12 @@
         set_type(type::reference_type);
     }
 
+ inline utree::utree(function_ptr fptr)
+ : f(fptr)
+ {
+ set_type(type::function_type);
+ }
+
     inline utree::utree(utree const& other)
     {
         copy(other);
@@ -742,6 +593,14 @@
         return *this;
     }
 
+ inline utree& utree::operator=(function_ptr fptr)
+ {
+ free();
+ f = fptr;
+ set_type(type::function_type);
+ return *this;
+ }
+
     template <typename F>
     typename F::result_type
     inline utree::visit(utree const& x, F f)
@@ -800,42 +659,6 @@
         return detail::index_impl::apply(l.first, i);
     }
 
- inline bool operator==(utree const& a, utree const& b)
- {
- return utree::visit(a, b, detail::utree_is_equal());
- }
-
- inline bool operator<(utree const& a, utree const& b)
- {
- return utree::visit(a, b, detail::utree_is_less_than());
- }
-
- inline bool operator!=(utree const& a, utree const& b)
- {
- return !(a == b);
- }
-
- inline bool operator>(utree const& a, utree const& b)
- {
- return b < a;
- }
-
- inline bool operator<=(utree const& a, utree const& b)
- {
- return !(b < a);
- }
-
- inline bool operator>=(utree const& a, utree const& b)
- {
- 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)
     {

Added: trunk/libs/spirit/example/scheme/test/scheme.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/test/scheme.cpp 2010-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
@@ -0,0 +1,148 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#include <boost/config/warning_disable.hpp>
+
+#include "../input/sexpr.hpp"
+#include "../input/parse_sexpr_impl.hpp"
+#include <iostream>
+#include <fstream>
+
+inline std::ostream& println(std::ostream& out, scheme::utree const& val)
+{
+ out << val << std::endl;
+ return out;
+}
+
+#include <boost/unordered_map.hpp>
+
+namespace scheme
+{
+ class environment
+ {
+ public:
+
+ environment(environment* parent = 0)
+ : bindings(), parent(parent) {}
+
+ void define(std::string const& name, utree const& def)
+ {
+ // check for duplicate names
+ BOOST_ASSERT(bindings.find(name) == bindings.end());
+ // $$$ TODO Use exceptions $$$
+ bindings[name] = def;
+ }
+
+ utree* find(std::string const& name)
+ {
+ map::iterator i = bindings.find(name);
+ if (i == bindings.end())
+ {
+ if (parent)
+ return parent->find(name);
+ return 0;
+ }
+ return &i->second;
+ }
+
+ private:
+
+ typedef boost::unordered_map<std::string, utree> map;
+ map bindings;
+ environment* parent;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Intrinsic functions
+ ///////////////////////////////////////////////////////////////////////////
+ struct arithmetic_function
+ {
+ typedef bool result_type;
+
+ template <typename A, typename B>
+ bool dispatch(const A&, const B&, boost::mpl::false_) const
+ {
+ return false; // cannot compare different types by default
+ }
+
+ template <typename A, typename B>
+ bool dispatch(const A& a, const B& b, boost::mpl::true_) const
+ {
+ return a == b; // for arithmetic types
+ }
+
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+ };
+
+ utree plus(environment*, utree& args)
+ {
+
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Main program
+///////////////////////////////////////////////////////////////////////////////
+int main(int argc, char **argv)
+{
+ char const* filename;
+ if (argc > 1)
+ {
+ filename = argv[1];
+ }
+ else
+ {
+ std::cerr << "Error: No input file provided." << std::endl;
+ return 1;
+ }
+
+ std::ifstream in(filename, std::ios_base::in);
+
+ if (!in)
+ {
+ std::cerr << "Error: Could not open input file: "
+ << filename << std::endl;
+ return 1;
+ }
+
+ // Ignore the BOM marking the beginning of a UTF-8 file in Windows
+ char c = in.peek();
+ if (c == '\xef')
+ {
+ char s[3];
+ in >> s[0] >> s[1] >> s[2];
+ s[3] = '\0';
+ if (s != std::string("\xef\xbb\xbf"))
+ {
+ std::cerr << "Error: Unexpected characters from input file: "
+ << filename << std::endl;
+ return 1;
+ }
+ }
+
+ scheme::utree result;
+ if (scheme::input::parse_sexpr(in, result))
+ {
+ std::cout << "success: ";
+ println(std::cout, result);
+ std::cout << std::endl;
+ }
+ else
+ {
+ std::cout << "parse error" << std::endl;
+ }
+
+ return 0;
+}
+
+

Modified: trunk/libs/spirit/example/scheme/test/utree_test.cpp
==============================================================================
--- trunk/libs/spirit/example/scheme/test/utree_test.cpp (original)
+++ trunk/libs/spirit/example/scheme/test/utree_test.cpp 2010-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
@@ -8,6 +8,7 @@
 #include <boost/config/warning_disable.hpp>
 
 #include "../utree.hpp"
+#include "../utree_operators.hpp"
 #include <iostream>
 
 inline std::ostream& println(std::ostream& out, scheme::utree const& val)
@@ -194,5 +195,17 @@
         println(std::cout, vals[2]);
     }
 
+ { // arithmetic
+ BOOST_ASSERT((utree(456) + utree(123)) == utree(456 + 123));
+ BOOST_ASSERT((utree(456) + utree(123.456)) == utree(456 + 123.456));
+ BOOST_ASSERT((utree(456) - utree(123)) == utree(456 - 123));
+ BOOST_ASSERT((utree(456) - utree(123.456)) == utree(456 - 123.456));
+ BOOST_ASSERT((utree(456) * utree(123)) == utree(456 * 123));
+ BOOST_ASSERT((utree(456) * utree(123.456)) == utree(456 * 123.456));
+ BOOST_ASSERT((utree(456) / utree(123)) == utree(456 / 123));
+ BOOST_ASSERT((utree(456) / utree(123.456)) == utree(456 / 123.456));
+ BOOST_ASSERT((utree(456) % utree(123)) == utree(456 % 123));
+ }
+
     return 0;
 }

Modified: trunk/libs/spirit/example/scheme/utree.hpp
==============================================================================
--- trunk/libs/spirit/example/scheme/utree.hpp (original)
+++ trunk/libs/spirit/example/scheme/utree.hpp 2010-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
@@ -16,8 +16,6 @@
 #include <boost/noncopyable.hpp>
 #include <boost/iterator/iterator_facade.hpp>
 #include <boost/range/iterator_range.hpp>
-#include <boost/type_traits/is_pointer.hpp>
-#include <boost/type_traits/alignment_of.hpp>
 #include <boost/ref.hpp>
 #include "detail/utree_detail1.hpp"
 
@@ -39,7 +37,8 @@
             symbol_type,
             binary_type,
             list_type,
- reference_type
+ reference_type,
+ function_type
         };
     };
 
@@ -49,6 +48,17 @@
     struct nil {};
 
     ///////////////////////////////////////////////////////////////////////////
+ // The environment (this is forward declared)
+ ///////////////////////////////////////////////////////////////////////////
+ class environment;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Function pointer
+ ///////////////////////////////////////////////////////////////////////////
+ class utree; // forward
+ typedef utree (*function_ptr)(environment* env, utree& args);
+
+ ///////////////////////////////////////////////////////////////////////////
     // A typed string with parametric Base storage. The storage can be any
     // range or (stl container) of chars.
     ///////////////////////////////////////////////////////////////////////////
@@ -164,6 +174,7 @@
         explicit utree(char const* str, std::size_t len);
         explicit utree(std::string const& str);
         explicit utree(boost::reference_wrapper<utree> ref);
+ explicit utree(function_ptr fptr);
 
         template <typename Base, utree_type::info type_>
         explicit utree(basic_string<Base, type_> const& bin);
@@ -179,6 +190,7 @@
         utree& operator=(char const* s);
         utree& operator=(std::string const& s);
         utree& operator=(boost::reference_wrapper<utree> ref);
+ utree& operator=(function_ptr fptr);
 
         template <typename Base, utree_type::info type_>
         utree& operator=(basic_string<Base, type_> const& bin);
@@ -278,16 +290,9 @@
             int i;
             double d;
             utree* p;
+ function_ptr f;
         };
     };
-
- bool operator==(utree const& a, utree const& b);
- bool operator<(utree const& a, utree const& b);
- bool operator!=(utree const& a, utree const& b);
- 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);
 }
 
 #include "detail/utree_detail2.hpp"

Added: trunk/libs/spirit/example/scheme/utree_operators.hpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/example/scheme/utree_operators.hpp 2010-04-03 03:57:36 EDT (Sat, 03 Apr 2010)
@@ -0,0 +1,355 @@
+/*=============================================================================
+ Copyright (c) 2001-2010 Joel de Guzman
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_UTREE_OPERATORS)
+#define BOOST_SPIRIT_UTREE_OPERATORS
+
+#include "utree.hpp"
+#include <boost/preprocessor/cat.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_integral.hpp>
+
+namespace scheme
+{
+ // Available operators
+ bool operator==(utree const& a, utree const& b);
+ bool operator<(utree const& a, utree const& b);
+ bool operator!=(utree const& a, utree const& b);
+ 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);
+
+ utree operator+(utree const& a, utree const& b);
+ utree operator-(utree const& a, utree const& b);
+ utree operator*(utree const& a, utree const& b);
+ utree operator/(utree const& a, utree const& b);
+ utree operator%(utree const& a, utree const& b);
+
+ // Implementation
+ struct utree_is_equal
+ {
+ typedef bool result_type;
+
+ template <typename A, typename B>
+ bool dispatch(const A&, const B&, boost::mpl::false_) const
+ {
+ return false; // cannot compare different types by default
+ }
+
+ template <typename A, typename B>
+ bool dispatch(const A& a, const B& b, boost::mpl::true_) const
+ {
+ return a == b; // for arithmetic types
+ }
+
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+
+ template <typename T>
+ bool operator()(const T& a, const T& b) const
+ {
+ // This code works for lists
+ return a == b;
+ }
+
+ template <typename Base, utree_type::info type_>
+ bool operator()(
+ basic_string<Base, type_> const& a,
+ basic_string<Base, type_> const& b) const
+ {
+ return static_cast<Base const&>(a) == static_cast<Base const&>(b);
+ }
+
+ bool operator()(nil, nil) const
+ {
+ return true;
+ }
+ };
+
+ struct utree_is_less_than
+ {
+ typedef bool result_type;
+
+ template <typename A, typename B>
+ bool dispatch(const A&, const B&, boost::mpl::false_) const
+ {
+ return false; // cannot compare different types by default
+ }
+
+ template <typename A, typename B>
+ bool dispatch(const A& a, const B& b, boost::mpl::true_) const
+ {
+ return a < b; // for arithmetic types
+ }
+
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+
+ template <typename T>
+ bool operator()(const T& a, const T& b) const
+ {
+ // This code works for lists
+ return a < b;
+ }
+
+ template <typename Base, utree_type::info type_>
+ bool operator()(
+ basic_string<Base, type_> const& a,
+ basic_string<Base, type_> const& b) const
+ {
+ return static_cast<Base const&>(a) < static_cast<Base const&>(b);
+ }
+
+ 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");
+ }
+
+ void operator()(binary_range const& b) const
+ {
+ out << "b";
+ out.width(2);
+ out.fill('0');
+
+ typedef binary_range::const_iterator iterator;
+ for (iterator i = b.begin(); i != b.end(); ++i)
+ out << std::hex << int((unsigned char)*i);
+ out << std::dec;
+ }
+
+ void operator()(utf8_string_range const& str) const
+ {
+ typedef utf8_string_range::const_iterator iterator;
+ iterator i = str.begin();
+ out << '"';
+ for (; i != str.end(); ++i)
+ out << *i;
+ out << '"';
+ }
+
+ void operator()(utf8_symbol_range const& str) const
+ {
+ typedef utf8_symbol_range::const_iterator iterator;
+ iterator i = str.begin();
+ for (; i != str.end(); ++i)
+ out << *i;
+ }
+
+ template <typename Iterator>
+ void operator()(boost::iterator_range<Iterator> const& range) const
+ {
+ typedef typename boost::iterator_range<Iterator>::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 Base>
+ struct arithmetic_function
+ {
+ typedef utree result_type;
+
+ template <typename A, typename B>
+ utree dispatch(A&, B&, boost::mpl::false_) const
+ {
+ // $$$ Throw exception here? $$$
+ return utree(); // cannot apply to different types
+ }
+
+ template <typename A, typename B>
+ utree dispatch(A& a, B& b, boost::mpl::true_) const
+ {
+ return Base::eval(a, b); // for arithmetic types
+ }
+
+ template <typename A, typename B>
+ utree operator()(A& a, B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_arithmetic<A>,
+ boost::is_arithmetic<B> >());
+ }
+ };
+
+ template <typename Base>
+ struct integral_function
+ {
+ typedef utree result_type;
+
+ template <typename A, typename B>
+ utree dispatch(A&, B&, boost::mpl::false_) const
+ {
+ // $$$ Throw exception here? $$$
+ return utree(); // cannot apply to different types
+ }
+
+ template <typename A, typename B>
+ utree dispatch(A& a, B& b, boost::mpl::true_) const
+ {
+ return Base::eval(a, b); // for integral types
+ }
+
+ template <typename A, typename B>
+ utree operator()(A& a, B& b) const
+ {
+ return dispatch(a, b,
+ boost::mpl::and_<
+ boost::is_integral<A>,
+ boost::is_integral<B> >());
+ }
+ };
+
+#define SCHEME_CREATE_FUNCTION(name, expr, base) \
+ struct BOOST_PP_CAT(function_impl_, name) \
+ { \
+ template <typename A, typename B> \
+ static utree eval(A& a, B& b) \
+ { \
+ return utree(expr); \
+ } \
+ }; \
+ base<BOOST_PP_CAT(function_impl_, name)> const \
+ BOOST_PP_CAT(base, BOOST_PP_CAT(_, name)) = {}; \
+ /***/
+
+#define SCHEME_CREATE_ARITHMETIC_FUNCTION(name, expr) \
+ SCHEME_CREATE_FUNCTION(name, expr, arithmetic_function) \
+ /***/
+
+#define SCHEME_CREATE_INTEGRAL_FUNCTION(name, expr) \
+ SCHEME_CREATE_FUNCTION(name, expr, integral_function) \
+ /***/
+
+#define SCHEME_CREATE_ARITHMETIC_OPERATOR(name, op) \
+ SCHEME_CREATE_FUNCTION(name, a op b, arithmetic_function) \
+ inline utree operator op (utree const& a, utree const& b) \
+ { \
+ return utree::visit(a, b, BOOST_PP_CAT(arithmetic_function, name)); \
+ } \
+ /***/
+
+#define SCHEME_CREATE_INTEGRAL_OPERATOR(name, op) \
+ SCHEME_CREATE_FUNCTION(name, a op b, integral_function) \
+ inline utree operator op (utree const& a, utree const& b) \
+ { \
+ return utree::visit(a, b, BOOST_PP_CAT(integral_function, name)); \
+ } \
+ /***/
+
+ inline bool operator==(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, utree_is_equal());
+ }
+
+ inline bool operator<(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, utree_is_less_than());
+ }
+
+ inline bool operator!=(utree const& a, utree const& b)
+ {
+ return !(a == b);
+ }
+
+ inline bool operator>(utree const& a, utree const& b)
+ {
+ return b < a;
+ }
+
+ inline bool operator<=(utree const& a, utree const& b)
+ {
+ return !(b < a);
+ }
+
+ inline bool operator>=(utree const& a, utree const& b)
+ {
+ return !(a < b);
+ }
+
+ inline std::ostream& operator<<(std::ostream& out, utree const& x)
+ {
+ utree::visit(x, utree_print(out));
+ return out;
+ }
+
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(plus, a+b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(minus, a-b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(times, a*b);
+ SCHEME_CREATE_ARITHMETIC_FUNCTION(divides, a/b);
+ SCHEME_CREATE_INTEGRAL_FUNCTION(modulus, a%b);
+
+ inline utree operator+(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_plus);
+ }
+
+ inline utree operator-(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_minus);
+ }
+
+ inline utree operator*(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_times);
+ }
+
+ inline utree operator/(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, arithmetic_function_divides);
+ }
+
+ inline utree operator%(utree const& a, utree const& b)
+ {
+ return utree::visit(a, b, integral_function_modulus);
+ }
+}
+
+#endif


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