the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at master 267 lines 10 kB view raw
1/////////////////////////////////////////////////////////////////////////////// 2/// \file debug.hpp 3/// Utilities for debugging Proto expression trees 4// 5// Copyright 2008 Eric Niebler. Distributed under the Boost 6// Software License, Version 1.0. (See accompanying file 7// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 8 9#ifndef BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006 10#define BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006 11 12#include <iostream> 13#include <boost/preprocessor/stringize.hpp> 14#include <boost/ref.hpp> 15#include <boost/mpl/assert.hpp> 16#include <boost/proto/proto_fwd.hpp> 17#include <boost/proto/traits.hpp> 18#include <boost/proto/matches.hpp> 19#include <boost/proto/fusion.hpp> 20#include <boost/fusion/algorithm/iteration/for_each.hpp> 21#include <boost/detail/sp_typeinfo.hpp> 22 23namespace boost { namespace proto 24{ 25 namespace tagns_ { namespace tag 26 { 27 #define BOOST_PROTO_DEFINE_TAG_INSERTION(Tag) \ 28 /** \brief INTERNAL ONLY */ \ 29 inline std::ostream &operator <<(std::ostream &sout, Tag const &) \ 30 { \ 31 return sout << BOOST_PP_STRINGIZE(Tag); \ 32 } \ 33 /**/ 34 35 BOOST_PROTO_DEFINE_TAG_INSERTION(terminal) 36 BOOST_PROTO_DEFINE_TAG_INSERTION(unary_plus) 37 BOOST_PROTO_DEFINE_TAG_INSERTION(negate) 38 BOOST_PROTO_DEFINE_TAG_INSERTION(dereference) 39 BOOST_PROTO_DEFINE_TAG_INSERTION(complement) 40 BOOST_PROTO_DEFINE_TAG_INSERTION(address_of) 41 BOOST_PROTO_DEFINE_TAG_INSERTION(logical_not) 42 BOOST_PROTO_DEFINE_TAG_INSERTION(pre_inc) 43 BOOST_PROTO_DEFINE_TAG_INSERTION(pre_dec) 44 BOOST_PROTO_DEFINE_TAG_INSERTION(post_inc) 45 BOOST_PROTO_DEFINE_TAG_INSERTION(post_dec) 46 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_left) 47 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_right) 48 BOOST_PROTO_DEFINE_TAG_INSERTION(multiplies) 49 BOOST_PROTO_DEFINE_TAG_INSERTION(divides) 50 BOOST_PROTO_DEFINE_TAG_INSERTION(modulus) 51 BOOST_PROTO_DEFINE_TAG_INSERTION(plus) 52 BOOST_PROTO_DEFINE_TAG_INSERTION(minus) 53 BOOST_PROTO_DEFINE_TAG_INSERTION(less) 54 BOOST_PROTO_DEFINE_TAG_INSERTION(greater) 55 BOOST_PROTO_DEFINE_TAG_INSERTION(less_equal) 56 BOOST_PROTO_DEFINE_TAG_INSERTION(greater_equal) 57 BOOST_PROTO_DEFINE_TAG_INSERTION(equal_to) 58 BOOST_PROTO_DEFINE_TAG_INSERTION(not_equal_to) 59 BOOST_PROTO_DEFINE_TAG_INSERTION(logical_or) 60 BOOST_PROTO_DEFINE_TAG_INSERTION(logical_and) 61 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_and) 62 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_or) 63 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_xor) 64 BOOST_PROTO_DEFINE_TAG_INSERTION(comma) 65 BOOST_PROTO_DEFINE_TAG_INSERTION(mem_ptr) 66 BOOST_PROTO_DEFINE_TAG_INSERTION(assign) 67 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_left_assign) 68 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_right_assign) 69 BOOST_PROTO_DEFINE_TAG_INSERTION(multiplies_assign) 70 BOOST_PROTO_DEFINE_TAG_INSERTION(divides_assign) 71 BOOST_PROTO_DEFINE_TAG_INSERTION(modulus_assign) 72 BOOST_PROTO_DEFINE_TAG_INSERTION(plus_assign) 73 BOOST_PROTO_DEFINE_TAG_INSERTION(minus_assign) 74 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_and_assign) 75 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_or_assign) 76 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_xor_assign) 77 BOOST_PROTO_DEFINE_TAG_INSERTION(subscript) 78 BOOST_PROTO_DEFINE_TAG_INSERTION(member) 79 BOOST_PROTO_DEFINE_TAG_INSERTION(if_else_) 80 BOOST_PROTO_DEFINE_TAG_INSERTION(function) 81 82 #undef BOOST_PROTO_DEFINE_TAG_INSERTION 83 }} 84 85 namespace hidden_detail_ 86 { 87 struct ostream_wrapper 88 { 89 ostream_wrapper(std::ostream &sout) 90 : sout_(sout) 91 {} 92 93 std::ostream &sout_; 94 95 private: 96 ostream_wrapper &operator =(ostream_wrapper const &); 97 }; 98 99 struct named_any 100 { 101 template<typename T> 102 named_any(T const &) 103 : name_(BOOST_SP_TYPEID(T).name()) 104 {} 105 106 char const *name_; 107 }; 108 109 inline std::ostream &operator <<(ostream_wrapper sout_wrap, named_any t) 110 { 111 return sout_wrap.sout_ << t.name_; 112 } 113 } 114 115 namespace detail 116 { 117 struct display_expr_impl 118 { 119 explicit display_expr_impl(std::ostream &sout, int depth = 0) 120 : depth_(depth) 121 , first_(true) 122 , sout_(sout) 123 {} 124 125 template<typename Expr> 126 void operator()(Expr const &expr) const 127 { 128 this->impl(expr, mpl::long_<arity_of<Expr>::value>()); 129 } 130 131 private: 132 display_expr_impl(display_expr_impl const &); 133 display_expr_impl &operator =(display_expr_impl const &); 134 135 template<typename Expr> 136 void impl(Expr const &expr, mpl::long_<0>) const 137 { 138 using namespace hidden_detail_; 139 typedef typename tag_of<Expr>::type tag; 140 this->sout_.width(this->depth_); 141 this->sout_ << (this->first_? "" : ", "); 142 this->sout_ << tag() << "(" << proto::value(expr) << ")\n"; 143 this->first_ = false; 144 } 145 146 template<typename Expr, typename Arity> 147 void impl(Expr const &expr, Arity) const 148 { 149 using namespace hidden_detail_; 150 typedef typename tag_of<Expr>::type tag; 151 this->sout_.width(this->depth_); 152 this->sout_ << (this->first_? "" : ", "); 153 this->sout_ << tag() << "(\n"; 154 display_expr_impl display(this->sout_, this->depth_ + 4); 155 fusion::for_each(expr, display); 156 this->sout_.width(this->depth_); 157 this->sout_ << "" << ")\n"; 158 this->first_ = false; 159 } 160 161 int depth_; 162 mutable bool first_; 163 std::ostream &sout_; 164 }; 165 } 166 167 namespace functional 168 { 169 /// \brief Pretty-print a Proto expression tree. 170 /// 171 /// A PolymorphicFunctionObject which accepts a Proto expression 172 /// tree and pretty-prints it to an \c ostream for debugging 173 /// purposes. 174 struct display_expr 175 { 176 BOOST_PROTO_CALLABLE() 177 178 typedef void result_type; 179 180 /// \param sout The \c ostream to which the expression tree 181 /// will be written. 182 /// \param depth The starting indentation depth for this node. 183 /// Children nodes will be displayed at a starting 184 /// depth of <tt>depth+4</tt>. 185 explicit display_expr(std::ostream &sout = std::cout, int depth = 0) 186 : depth_(depth) 187 , sout_(sout) 188 {} 189 190 /// \brief Pretty-print the current node in a Proto expression 191 /// tree. 192 template<typename Expr> 193 void operator()(Expr const &expr) const 194 { 195 detail::display_expr_impl(this->sout_, this->depth_)(expr); 196 } 197 198 private: 199 int depth_; 200 reference_wrapper<std::ostream> sout_; 201 }; 202 } 203 204 /// \brief Pretty-print a Proto expression tree. 205 /// 206 /// \note Equivalent to <tt>functional::display_expr(0, sout)(expr)</tt> 207 /// \param expr The Proto expression tree to pretty-print 208 /// \param sout The \c ostream to which the output should be 209 /// written. If not specified, defaults to 210 /// <tt>std::cout</tt>. 211 template<typename Expr> 212 void display_expr(Expr const &expr, std::ostream &sout) 213 { 214 functional::display_expr(sout, 0)(expr); 215 } 216 217 /// \overload 218 /// 219 template<typename Expr> 220 void display_expr(Expr const &expr) 221 { 222 functional::display_expr()(expr); 223 } 224 225 /// \brief Assert at compile time that a particular expression 226 /// matches the specified grammar. 227 /// 228 /// \note Equivalent to <tt>BOOST_MPL_ASSERT((proto::matches\<Expr, Grammar\>))</tt> 229 /// \param expr The Proto expression to check againts <tt>Grammar</tt> 230 template<typename Grammar, typename Expr> 231 void assert_matches(Expr const & /*expr*/) 232 { 233 BOOST_MPL_ASSERT((proto::matches<Expr, Grammar>)); 234 } 235 236 /// \brief Assert at compile time that a particular expression 237 /// does not match the specified grammar. 238 /// 239 /// \note Equivalent to <tt>BOOST_MPL_ASSERT_NOT((proto::matches\<Expr, Grammar\>))</tt> 240 /// \param expr The Proto expression to check againts <tt>Grammar</tt> 241 template<typename Grammar, typename Expr> 242 void assert_matches_not(Expr const & /*expr*/) 243 { 244 BOOST_MPL_ASSERT_NOT((proto::matches<Expr, Grammar>)); 245 } 246 247 /// \brief Assert at compile time that a particular expression 248 /// matches the specified grammar. 249 /// 250 /// \note Equivalent to <tt>proto::assert_matches\<Grammar\>(Expr)</tt> 251 /// \param Expr The Proto expression to check againts <tt>Grammar</tt> 252 /// \param Grammar The grammar used to validate Expr. 253 #define BOOST_PROTO_ASSERT_MATCHES(Expr, Grammar) \ 254 (true ? (void)0 : boost::proto::assert_matches<Grammar>(Expr)) 255 256 /// \brief Assert at compile time that a particular expression 257 /// does not match the specified grammar. 258 /// 259 /// \note Equivalent to <tt>proto::assert_matches_not\<Grammar\>(Expr)</tt> 260 /// \param Expr The Proto expression to check againts <tt>Grammar</tt> 261 /// \param Grammar The grammar used to validate Expr. 262 #define BOOST_PROTO_ASSERT_MATCHES_NOT(Expr, Grammar) \ 263 (true ? (void)0 : boost::proto::assert_matches_not<Grammar>(Expr)) 264 265}} 266 267#endif