annotate DEPENDENCIES/generic/include/boost/proto/debug.hpp @ 133:4acb5d8d80b6 tip

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