/Src/Dependencies/Boost/boost/proto/debug.hpp

http://hadesmem.googlecode.com/ · C++ Header · 264 lines · 184 code · 29 blank · 51 comment · 0 complexity · 3804852dc3dfc64e46d9ef7623a05bc9 MD5 · raw file

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