inline utree operator<<(utree const& a, utree const& b) { 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 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) { 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; }
static utree const& apply(utree const& ut, std::size_t i) { switch (ut.get_type()) { case utree_type::reference_type: return apply(ut.deref(), i); case utree_type::range_type: return apply(ut.r.first, i); case utree_type::list_type: return apply(ut.l.first, i); default: BOOST_THROW_EXCEPTION( bad_type_exception ("index operation performed on non-list utree type", ut.get_type())); } }
typename F::result_type static apply(UTreeX& x, UTreeY& y, F f) // double dispatch { typedef typename boost::mpl::if_<boost::is_const<UTreeX>, typename UTreeX::const_iterator, typename UTreeX::iterator>::type iterator; typedef boost::iterator_range<iterator> list_range; typedef utree_type type; switch (x.get_type()) { default: boost::throw_exception(bad_type_exception()); break; case type::invalid_type: return visit_impl::apply(y, detail::bind(f, invalid)); case type::nil_type: return visit_impl::apply(y, detail::bind(f, nil)); case type::bool_type: return visit_impl::apply(y, detail::bind(f, x.b)); case type::int_type: return visit_impl::apply(y, detail::bind(f, x.i)); case type::double_type: return visit_impl::apply(y, detail::bind(f, x.d)); case type::list_type: return visit_impl::apply( y, detail::bind<F, list_range>(f, list_range(iterator(x.l.first, 0), 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, 0), iterator(0, x.r.last)))); case type::string_type: return visit_impl::apply(y, detail::bind( f, utf8_string_range_type(x.s.str(), x.s.size()))); case type::string_range_type: return visit_impl::apply(y, detail::bind( f, utf8_string_range_type(x.sr.first, x.sr.last))); case type::symbol_type: return visit_impl::apply(y, detail::bind( f, utf8_symbol_range_type(x.s.str(), x.s.size()))); case type::binary_type: return visit_impl::apply(y, detail::bind( f, binary_range_type(x.s.str(), x.s.size()))); case type::reference_type: return apply(*x.p, y, f); case type::any_type: return visit_impl::apply( y, detail::bind(f, any_ptr(x.v.p, x.v.i))); case type::function_type: return visit_impl::apply(y, detail::bind(f, *x.pf)); } }
typename F::result_type static apply(UTreeX& x, F f) // single dispatch { typedef typename boost::mpl::if_<boost::is_const<UTreeX>, typename UTreeX::const_iterator, typename UTreeX::iterator>::type iterator; typedef boost::iterator_range<iterator> list_range; typedef utree_type type; switch (x.get_type()) { default: BOOST_THROW_EXCEPTION( bad_type_exception("corrupt utree type", x.get_type())); break; case type::invalid_type: return f(invalid); case type::nil_type: return f(nil); case type::bool_type: return f(x.b); case type::int_type: return f(x.i); case type::double_type: return f(x.d); case type::list_type: return f(list_range(iterator(x.l.first, 0), iterator(0, x.l.last))); case type::range_type: return f(list_range(iterator(x.r.first, 0), iterator(0, x.r.last))); case type::string_type: return f(utf8_string_range_type(x.s.str(), x.s.size())); case type::string_range_type: return f(utf8_string_range_type(x.sr.first, x.sr.last)); case type::symbol_type: return f(utf8_symbol_range_type(x.s.str(), x.s.size())); case type::binary_type: return f(binary_range_type(x.s.str(), x.s.size())); case type::reference_type: return apply(*x.p, f); case type::any_type: return f(any_ptr(x.v.p, x.v.i)); case type::function_type: return f(*x.pf); } }