File indexing completed on 2025-01-18 09:50:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006
0010 #define BOOST_PROTO_DEBUG_HPP_EAN_12_31_2006
0011
0012 #include <iostream>
0013 #include <boost/preprocessor/stringize.hpp>
0014 #include <boost/core/ref.hpp>
0015 #include <boost/core/typeinfo.hpp>
0016 #include <boost/mpl/assert.hpp>
0017 #include <boost/proto/proto_fwd.hpp>
0018 #include <boost/proto/traits.hpp>
0019 #include <boost/proto/matches.hpp>
0020 #include <boost/proto/fusion.hpp>
0021 #include <boost/fusion/algorithm/iteration/for_each.hpp>
0022
0023 namespace boost { namespace proto
0024 {
0025 namespace tagns_ { namespace tag
0026 {
0027 #define BOOST_PROTO_DEFINE_TAG_INSERTION(Tag) \
0028 \
0029 inline std::ostream &operator <<(std::ostream &sout, Tag const &) \
0030 { \
0031 return sout << BOOST_PP_STRINGIZE(Tag); \
0032 } \
0033
0034
0035 BOOST_PROTO_DEFINE_TAG_INSERTION(terminal)
0036 BOOST_PROTO_DEFINE_TAG_INSERTION(unary_plus)
0037 BOOST_PROTO_DEFINE_TAG_INSERTION(negate)
0038 BOOST_PROTO_DEFINE_TAG_INSERTION(dereference)
0039 BOOST_PROTO_DEFINE_TAG_INSERTION(complement)
0040 BOOST_PROTO_DEFINE_TAG_INSERTION(address_of)
0041 BOOST_PROTO_DEFINE_TAG_INSERTION(logical_not)
0042 BOOST_PROTO_DEFINE_TAG_INSERTION(pre_inc)
0043 BOOST_PROTO_DEFINE_TAG_INSERTION(pre_dec)
0044 BOOST_PROTO_DEFINE_TAG_INSERTION(post_inc)
0045 BOOST_PROTO_DEFINE_TAG_INSERTION(post_dec)
0046 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_left)
0047 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_right)
0048 BOOST_PROTO_DEFINE_TAG_INSERTION(multiplies)
0049 BOOST_PROTO_DEFINE_TAG_INSERTION(divides)
0050 BOOST_PROTO_DEFINE_TAG_INSERTION(modulus)
0051 BOOST_PROTO_DEFINE_TAG_INSERTION(plus)
0052 BOOST_PROTO_DEFINE_TAG_INSERTION(minus)
0053 BOOST_PROTO_DEFINE_TAG_INSERTION(less)
0054 BOOST_PROTO_DEFINE_TAG_INSERTION(greater)
0055 BOOST_PROTO_DEFINE_TAG_INSERTION(less_equal)
0056 BOOST_PROTO_DEFINE_TAG_INSERTION(greater_equal)
0057 BOOST_PROTO_DEFINE_TAG_INSERTION(equal_to)
0058 BOOST_PROTO_DEFINE_TAG_INSERTION(not_equal_to)
0059 BOOST_PROTO_DEFINE_TAG_INSERTION(logical_or)
0060 BOOST_PROTO_DEFINE_TAG_INSERTION(logical_and)
0061 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_and)
0062 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_or)
0063 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_xor)
0064 BOOST_PROTO_DEFINE_TAG_INSERTION(comma)
0065 BOOST_PROTO_DEFINE_TAG_INSERTION(mem_ptr)
0066 BOOST_PROTO_DEFINE_TAG_INSERTION(assign)
0067 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_left_assign)
0068 BOOST_PROTO_DEFINE_TAG_INSERTION(shift_right_assign)
0069 BOOST_PROTO_DEFINE_TAG_INSERTION(multiplies_assign)
0070 BOOST_PROTO_DEFINE_TAG_INSERTION(divides_assign)
0071 BOOST_PROTO_DEFINE_TAG_INSERTION(modulus_assign)
0072 BOOST_PROTO_DEFINE_TAG_INSERTION(plus_assign)
0073 BOOST_PROTO_DEFINE_TAG_INSERTION(minus_assign)
0074 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_and_assign)
0075 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_or_assign)
0076 BOOST_PROTO_DEFINE_TAG_INSERTION(bitwise_xor_assign)
0077 BOOST_PROTO_DEFINE_TAG_INSERTION(subscript)
0078 BOOST_PROTO_DEFINE_TAG_INSERTION(member)
0079 BOOST_PROTO_DEFINE_TAG_INSERTION(if_else_)
0080 BOOST_PROTO_DEFINE_TAG_INSERTION(function)
0081
0082 #undef BOOST_PROTO_DEFINE_TAG_INSERTION
0083 }}
0084
0085 namespace hidden_detail_
0086 {
0087 struct ostream_wrapper
0088 {
0089 ostream_wrapper(std::ostream &sout)
0090 : sout_(sout)
0091 {}
0092
0093 std::ostream &sout_;
0094
0095 BOOST_DELETED_FUNCTION(ostream_wrapper &operator =(ostream_wrapper const &))
0096 };
0097
0098 struct named_any
0099 {
0100 template<typename T>
0101 named_any(T const &)
0102 : name_(BOOST_CORE_TYPEID(T).name())
0103 {}
0104
0105 char const *name_;
0106 };
0107
0108 inline std::ostream &operator <<(ostream_wrapper sout_wrap, named_any t)
0109 {
0110 return sout_wrap.sout_ << t.name_;
0111 }
0112 }
0113
0114 namespace detail
0115 {
0116
0117 struct display_expr_impl;
0118 struct display_expr_impl_functor
0119 {
0120 display_expr_impl_functor(display_expr_impl const& impl): impl_(impl)
0121 {}
0122
0123 template<typename Expr>
0124 void operator()(Expr const &expr) const
0125 {
0126 this->impl_(expr);
0127 }
0128
0129 private:
0130 display_expr_impl const& impl_;
0131 };
0132
0133 struct display_expr_impl
0134 {
0135 explicit display_expr_impl(std::ostream &sout, int depth = 0)
0136 : depth_(depth)
0137 , first_(true)
0138 , sout_(sout)
0139 {}
0140
0141 template<typename Expr>
0142 void operator()(Expr const &expr) const
0143 {
0144 this->impl(expr, mpl::long_<arity_of<Expr>::value>());
0145 }
0146
0147 BOOST_DELETED_FUNCTION(display_expr_impl(display_expr_impl const &))
0148 BOOST_DELETED_FUNCTION(display_expr_impl &operator =(display_expr_impl const &))
0149 private:
0150
0151 template<typename Expr>
0152 void impl(Expr const &expr, mpl::long_<0>) const
0153 {
0154 using namespace hidden_detail_;
0155 typedef typename tag_of<Expr>::type tag;
0156 this->sout_.width(this->depth_);
0157 this->sout_ << (this->first_? "" : ", ");
0158 this->sout_ << tag() << "(" << proto::value(expr) << ")\n";
0159 this->first_ = false;
0160 }
0161
0162 template<typename Expr, typename Arity>
0163 void impl(Expr const &expr, Arity) const
0164 {
0165 using namespace hidden_detail_;
0166 typedef typename tag_of<Expr>::type tag;
0167 this->sout_.width(this->depth_);
0168 this->sout_ << (this->first_? "" : ", ");
0169 this->sout_ << tag() << "(\n";
0170 display_expr_impl display(this->sout_, this->depth_ + 4);
0171 fusion::for_each(expr, display_expr_impl_functor(display));
0172 this->sout_.width(this->depth_);
0173 this->sout_ << "" << ")\n";
0174 this->first_ = false;
0175 }
0176
0177 int depth_;
0178 mutable bool first_;
0179 std::ostream &sout_;
0180 };
0181 }
0182
0183 namespace functional
0184 {
0185
0186
0187
0188
0189
0190 struct display_expr
0191 {
0192 BOOST_PROTO_CALLABLE()
0193
0194 typedef void result_type;
0195
0196
0197
0198
0199
0200
0201 explicit display_expr(std::ostream &sout = std::cout, int depth = 0)
0202 : depth_(depth)
0203 , sout_(sout)
0204 {}
0205
0206
0207
0208 template<typename Expr>
0209 void operator()(Expr const &expr) const
0210 {
0211 detail::display_expr_impl(this->sout_, this->depth_)(expr);
0212 }
0213
0214 private:
0215 int depth_;
0216 reference_wrapper<std::ostream> sout_;
0217 };
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
0227 template<typename Expr>
0228 void display_expr(Expr const &expr, std::ostream &sout)
0229 {
0230 functional::display_expr(sout, 0)(expr);
0231 }
0232
0233
0234
0235 template<typename Expr>
0236 void display_expr(Expr const &expr)
0237 {
0238 functional::display_expr()(expr);
0239 }
0240
0241
0242
0243
0244
0245
0246 template<typename Grammar, typename Expr>
0247 void assert_matches(Expr const & )
0248 {
0249 BOOST_MPL_ASSERT((proto::matches<Expr, Grammar>));
0250 }
0251
0252
0253
0254
0255
0256
0257 template<typename Grammar, typename Expr>
0258 void assert_matches_not(Expr const & )
0259 {
0260 BOOST_MPL_ASSERT_NOT((proto::matches<Expr, Grammar>));
0261 }
0262
0263
0264
0265
0266
0267
0268
0269 #define BOOST_PROTO_ASSERT_MATCHES(Expr, Grammar) \
0270 (true ? (void)0 : boost::proto::assert_matches<Grammar>(Expr))
0271
0272
0273
0274
0275
0276
0277
0278 #define BOOST_PROTO_ASSERT_MATCHES_NOT(Expr, Grammar) \
0279 (true ? (void)0 : boost::proto::assert_matches_not<Grammar>(Expr))
0280
0281 }}
0282
0283 #endif