diff options
Diffstat (limited to '3rdParty/Boost/src/boost/proto/debug.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/proto/debug.hpp | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/proto/debug.hpp b/3rdParty/Boost/src/boost/proto/debug.hpp new file mode 100644 index 0000000..f732bc2 --- /dev/null +++ b/3rdParty/Boost/src/boost/proto/debug.hpp @@ -0,0 +1,267 @@ +/////////////////////////////////////////////////////////////////////////////// +/// \file debug.hpp +/// Utilities for debugging Proto expression trees +// +// Copyright 2008 Eric Niebler. 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) + +#ifndef BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006 +#define BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006 + +#include <iostream> +#include <boost/preprocessor/stringize.hpp> +#include <boost/ref.hpp> +#include <boost/mpl/assert.hpp> +#include <boost/proto/proto_fwd.hpp> +#include <boost/proto/traits.hpp> +#include <boost/proto/matches.hpp> +#include <boost/proto/fusion.hpp> +#include <boost/fusion/algorithm/iteration/for_each.hpp> +#include <boost/detail/sp_typeinfo.hpp> + +namespace boost { namespace proto +{ + namespace tagns_ { namespace tag + { + #define BOOST_PROTO_DEFINE_TAG_INSERTION(Tag) \ + /** \brief INTERNAL ONLY */ \ + inline std::ostream &operator <<(std::ostream &sout, Tag const &) \ + { \ + return sout << BOOST_PP_STRINGIZE(Tag); \ + } \ + /**/ + + BOOST_PROTO_DEFINE_TAG_INSERTION(terminal) + BOOST_PROTO_DEFINE_TAG_INSERTION(unary_plus) + BOOST_PROTO_DEFINE_TAG_INSERTION(negate) + BOOST_PROTO_DEFINE_TAG_INSERTION(dereference) + BOOST_PROTO_DEFINE_TAG_INSERTION(complement) + BOOST_PROTO_DEFINE_TAG_INSERTION(address_of) + BOOST_PROTO_DEFINE_TAG_INSERTION(logical_not) + BOOST_PROTO_DEFINE_TAG_INSERTION(pre_inc) + BOOST_PROTO_DEFINE_TAG_INSERTION(pre_dec) + BOOST_PROTO_DEFINE_TAG_INSERTION(post_inc) + BOOST_PROTO_DEFINE_TAG_INSERTION(post_dec) + BOOST_PROTO_DEFINE_TAG_INSERTION(shift_left) + BOOST_PROTO_DEFINE_TAG_INSERTION(shift_right) + BOOST_PROTO_DEFINE_TAG_INSERTION(multiplies) + BOOST_PROTO_DEFINE_TAG_INSERTION(divides) + BOOST_PROTO_DEFINE_TAG_INSERTION(modulus) + BOOST_PROTO_DEFINE_TAG_INSERTION(plus) + BOOST_PROTO_DEFINE_TAG_INSERTION(minus) + BOOST_PROTO_DEFINE_TAG_INSERTION(less) + BOOST_PROTO_DEFINE_TAG_INSERTION(greater) + BOOST_PROTO_DEFINE_TAG_INSERTION(less_equal) + BOOST_PROTO_DEFINE_TAG_INSERTION(greater_equal) + BOOST_PROTO_DEFINE_TAG_INSERTION(equal_to) + BOOST_PROTO_DEFINE_TAG_INSERTION(not_equal_to) + BOOST_PROTO_DEFINE_TAG_INSERTION(logical_or) + BOOST_PROTO_DEFINE_TAG_INSERTION(logical_and) + BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_and) + BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_or) + BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_xor) + BOOST_PROTO_DEFINE_TAG_INSERTION(comma) + BOOST_PROTO_DEFINE_TAG_INSERTION(mem_ptr) + BOOST_PROTO_DEFINE_TAG_INSERTION(assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(shift_left_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(shift_right_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(multiplies_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(divides_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(modulus_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(plus_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(minus_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_and_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_or_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_xor_assign) + BOOST_PROTO_DEFINE_TAG_INSERTION(subscript) + BOOST_PROTO_DEFINE_TAG_INSERTION(member) + BOOST_PROTO_DEFINE_TAG_INSERTION(if_else_) + BOOST_PROTO_DEFINE_TAG_INSERTION(function) + + #undef BOOST_PROTO_DEFINE_TAG_INSERTION + }} + + namespace hidden_detail_ + { + struct ostream_wrapper + { + ostream_wrapper(std::ostream &sout) + : sout_(sout) + {} + + std::ostream &sout_; + + private: + ostream_wrapper &operator =(ostream_wrapper const &); + }; + + struct named_any + { + template<typename T> + named_any(T const &) + : name_(BOOST_SP_TYPEID(T).name()) + {} + + char const *name_; + }; + + inline std::ostream &operator <<(ostream_wrapper sout_wrap, named_any t) + { + return sout_wrap.sout_ << t.name_; + } + } + + namespace detail + { + struct display_expr_impl + { + explicit display_expr_impl(std::ostream &sout, int depth = 0) + : depth_(depth) + , first_(true) + , sout_(sout) + {} + + template<typename Expr> + void operator()(Expr const &expr) const + { + this->impl(expr, mpl::long_<arity_of<Expr>::value>()); + } + + private: + display_expr_impl(display_expr_impl const &); + display_expr_impl &operator =(display_expr_impl const &); + + template<typename Expr> + void impl(Expr const &expr, mpl::long_<0>) const + { + using namespace hidden_detail_; + typedef typename tag_of<Expr>::type tag; + this->sout_.width(this->depth_); + this->sout_ << (this->first_? "" : ", "); + this->sout_ << tag() << "(" << proto::value(expr) << ")\n"; + this->first_ = false; + } + + template<typename Expr, typename Arity> + void impl(Expr const &expr, Arity) const + { + using namespace hidden_detail_; + typedef typename tag_of<Expr>::type tag; + this->sout_.width(this->depth_); + this->sout_ << (this->first_? "" : ", "); + this->sout_ << tag() << "(\n"; + display_expr_impl display(this->sout_, this->depth_ + 4); + fusion::for_each(expr, display); + this->sout_.width(this->depth_); + this->sout_ << "" << ")\n"; + this->first_ = false; + } + + int depth_; + mutable bool first_; + std::ostream &sout_; + }; + } + + namespace functional + { + /// \brief Pretty-print a Proto expression tree. + /// + /// A PolymorphicFunctionObject which accepts a Proto expression + /// tree and pretty-prints it to an \c ostream for debugging + /// purposes. + struct display_expr + { + BOOST_PROTO_CALLABLE() + + typedef void result_type; + + /// \param sout The \c ostream to which the expression tree + /// will be written. + /// \param depth The starting indentation depth for this node. + /// Children nodes will be displayed at a starting + /// depth of <tt>depth+4</tt>. + explicit display_expr(std::ostream &sout = std::cout, int depth = 0) + : depth_(depth) + , sout_(sout) + {} + + /// \brief Pretty-print the current node in a Proto expression + /// tree. + template<typename Expr> + void operator()(Expr const &expr) const + { + detail::display_expr_impl(this->sout_, this->depth_)(expr); + } + + private: + int depth_; + reference_wrapper<std::ostream> sout_; + }; + } + + /// \brief Pretty-print a Proto expression tree. + /// + /// \note Equivalent to <tt>functional::display_expr(0, sout)(expr)</tt> + /// \param expr The Proto expression tree to pretty-print + /// \param sout The \c ostream to which the output should be + /// written. If not specified, defaults to + /// <tt>std::cout</tt>. + template<typename Expr> + void display_expr(Expr const &expr, std::ostream &sout) + { + functional::display_expr(sout, 0)(expr); + } + + /// \overload + /// + template<typename Expr> + void display_expr(Expr const &expr) + { + functional::display_expr()(expr); + } + + /// \brief Assert at compile time that a particular expression + /// matches the specified grammar. + /// + /// \note Equivalent to <tt>BOOST_MPL_ASSERT((proto::matches\<Expr, Grammar\>))</tt> + /// \param expr The Proto expression to check againts <tt>Grammar</tt> + template<typename Grammar, typename Expr> + void assert_matches(Expr const & /*expr*/) + { + BOOST_MPL_ASSERT((proto::matches<Expr, Grammar>)); + } + + /// \brief Assert at compile time that a particular expression + /// does not match the specified grammar. + /// + /// \note Equivalent to <tt>BOOST_MPL_ASSERT_NOT((proto::matches\<Expr, Grammar\>))</tt> + /// \param expr The Proto expression to check againts <tt>Grammar</tt> + template<typename Grammar, typename Expr> + void assert_matches_not(Expr const & /*expr*/) + { + BOOST_MPL_ASSERT_NOT((proto::matches<Expr, Grammar>)); + } + + /// \brief Assert at compile time that a particular expression + /// matches the specified grammar. + /// + /// \note Equivalent to <tt>proto::assert_matches\<Grammar\>(Expr)</tt> + /// \param Expr The Proto expression to check againts <tt>Grammar</tt> + /// \param Grammar The grammar used to validate Expr. + #define BOOST_PROTO_ASSERT_MATCHES(Expr, Grammar) \ + (true ? (void)0 : boost::proto::assert_matches<Grammar>(Expr)) + + /// \brief Assert at compile time that a particular expression + /// does not match the specified grammar. + /// + /// \note Equivalent to <tt>proto::assert_matches_not\<Grammar\>(Expr)</tt> + /// \param Expr The Proto expression to check againts <tt>Grammar</tt> + /// \param Grammar The grammar used to validate Expr. + #define BOOST_PROTO_ASSERT_MATCHES_NOT(Expr, Grammar) \ + (true ? (void)0 : boost::proto::assert_matches_not<Grammar>(Expr)) + +}} + +#endif |