PageRenderTime 55ms CodeModel.GetById 21ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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 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
 96        struct named_any
 97        {
 98            template<typename T>
 99            named_any(T const &)
100              : name_(BOOST_SP_TYPEID(T).name())
101            {}
102
103            char const *name_;
104        };
105
106        inline std::ostream &operator <<(ostream_wrapper sout_wrap, named_any t)
107        {
108            return sout_wrap.sout_ << t.name_;
109        }
110    }
111
112    namespace detail
113    {
114        struct display_expr_impl
115        {
116            explicit display_expr_impl(std::ostream &sout, int depth = 0)
117              : depth_(depth)
118              , first_(true)
119              , sout_(sout)
120            {}
121
122            template<typename Expr>
123            void operator()(Expr const &expr) const
124            {
125                this->impl(expr, mpl::long_<arity_of<Expr>::value>());
126            }
127
128        private:
129            display_expr_impl(display_expr_impl const &);
130            display_expr_impl &operator =(display_expr_impl const &);
131
132            template<typename Expr>
133            void impl(Expr const &expr, mpl::long_<0>) const
134            {
135                using namespace hidden_detail_;
136                typedef typename tag_of<Expr>::type tag;
137                this->sout_.width(this->depth_);
138                this->sout_ << (this->first_? "" : ", ");
139                this->sout_ << tag() << "(" << proto::value(expr) << ")\n";
140                this->first_ = false;
141            }
142
143            template<typename Expr, typename Arity>
144            void impl(Expr const &expr, Arity) const
145            {
146                using namespace hidden_detail_;
147                typedef typename tag_of<Expr>::type tag;
148                this->sout_.width(this->depth_);
149                this->sout_ << (this->first_? "" : ", ");
150                this->sout_ << tag() << "(\n";
151                display_expr_impl display(this->sout_, this->depth_ + 4);
152                fusion::for_each(expr, display);
153                this->sout_.width(this->depth_);
154                this->sout_ << "" << ")\n";
155                this->first_ = false;
156            }
157
158            int depth_;
159            mutable bool first_;
160            std::ostream &sout_;
161        };
162    }
163
164    namespace functional
165    {
166        /// \brief Pretty-print a Proto expression tree.
167        ///
168        /// A PolymorphicFunctionObject which accepts a Proto expression
169        /// tree and pretty-prints it to an \c ostream for debugging
170        /// purposes.
171        struct display_expr
172        {
173            BOOST_PROTO_CALLABLE()
174
175            typedef void result_type;
176
177            /// \param sout  The \c ostream to which the expression tree
178            ///              will be written.
179            /// \param depth The starting indentation depth for this node.
180            ///              Children nodes will be displayed at a starting
181            ///              depth of <tt>depth+4</tt>.
182            explicit display_expr(std::ostream &sout = std::cout, int depth = 0)
183              : depth_(depth)
184              , sout_(sout)
185            {}
186
187            /// \brief Pretty-print the current node in a Proto expression
188            /// tree.
189            template<typename Expr>
190            void operator()(Expr const &expr) const
191            {
192                detail::display_expr_impl(this->sout_, this->depth_)(expr);
193            }
194
195        private:
196            int depth_;
197            reference_wrapper<std::ostream> sout_;
198        };
199    }
200
201    /// \brief Pretty-print a Proto expression tree.
202    ///
203    /// \note Equivalent to <tt>functional::display_expr(0, sout)(expr)</tt>
204    /// \param expr The Proto expression tree to pretty-print
205    /// \param sout The \c ostream to which the output should be
206    ///             written. If not specified, defaults to
207    ///             <tt>std::cout</tt>.
208    template<typename Expr>
209    void display_expr(Expr const &expr, std::ostream &sout)
210    {
211        functional::display_expr(sout, 0)(expr);
212    }
213
214    /// \overload
215    ///
216    template<typename Expr>
217    void display_expr(Expr const &expr)
218    {
219        functional::display_expr()(expr);
220    }
221
222    /// \brief Assert at compile time that a particular expression
223    ///        matches the specified grammar.
224    ///
225    /// \note Equivalent to <tt>BOOST_MPL_ASSERT((proto::matches\<Expr, Grammar\>))</tt>
226    /// \param expr The Proto expression to check againts <tt>Grammar</tt>
227    template<typename Grammar, typename Expr>
228    void assert_matches(Expr const & /*expr*/)
229    {
230        BOOST_MPL_ASSERT((proto::matches<Expr, Grammar>));
231    }
232
233    /// \brief Assert at compile time that a particular expression
234    ///        does not match the specified grammar.
235    ///
236    /// \note Equivalent to <tt>BOOST_MPL_ASSERT_NOT((proto::matches\<Expr, Grammar\>))</tt>
237    /// \param expr The Proto expression to check againts <tt>Grammar</tt>
238    template<typename Grammar, typename Expr>
239    void assert_matches_not(Expr const & /*expr*/)
240    {
241        BOOST_MPL_ASSERT_NOT((proto::matches<Expr, Grammar>));
242    }
243
244    /// \brief Assert at compile time that a particular expression
245    ///        matches the specified grammar.
246    ///
247    /// \note Equivalent to <tt>proto::assert_matches\<Grammar\>(Expr)</tt>
248    /// \param Expr The Proto expression to check againts <tt>Grammar</tt>
249    /// \param Grammar The grammar used to validate Expr.
250    #define BOOST_PROTO_ASSERT_MATCHES(Expr, Grammar)                                               \
251        (true ? (void)0 : boost::proto::assert_matches<Grammar>(Expr))
252
253    /// \brief Assert at compile time that a particular expression
254    ///        does not match the specified grammar.
255    ///
256    /// \note Equivalent to <tt>proto::assert_matches_not\<Grammar\>(Expr)</tt>
257    /// \param Expr The Proto expression to check againts <tt>Grammar</tt>
258    /// \param Grammar The grammar used to validate Expr.
259    #define BOOST_PROTO_ASSERT_MATCHES_NOT(Expr, Grammar)                                           \
260        (true ? (void)0 : boost::proto::assert_matches_not<Grammar>(Expr))
261
262}}
263
264#endif