Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r60495 - in trunk/boost/spirit/home: qi/nonterminal support
From: joel_at_[hidden]
Date: 2010-03-11 19:20:35


Author: djowel
Date: 2010-03-11 19:20:34 EST (Thu, 11 Mar 2010)
New Revision: 60495
URL: http://svn.boost.org/trac/boost/changeset/60495

Log:
added support for debug printing stl containers
Text files modified:
   trunk/boost/spirit/home/qi/nonterminal/simple_trace.hpp | 14 ++-
   trunk/boost/spirit/home/support/attributes.hpp | 142 ++++++++++++++++++++++++++++++---------
   2 files changed, 118 insertions(+), 38 deletions(-)

Modified: trunk/boost/spirit/home/qi/nonterminal/simple_trace.hpp
==============================================================================
--- trunk/boost/spirit/home/qi/nonterminal/simple_trace.hpp (original)
+++ trunk/boost/spirit/home/qi/nonterminal/simple_trace.hpp 2010-03-11 19:20:34 EST (Thu, 11 Mar 2010)
@@ -55,7 +55,7 @@
                     o << "\\t";
                 else if (c == static_cast<Char>('\v'))
                     o << "\\v";
- else if (iscntrl(c))
+ else if (c < 127 && iscntrl(c))
                     o << "\\" << std::oct << static_cast<int>(c);
                 else
                     o << static_cast<char>(c);
@@ -114,8 +114,8 @@
             for (int i = 0; first != last && i != n && *first; ++i, ++first)
                 detail::token_printer(BOOST_SPIRIT_DEBUG_OUT, *first);
             BOOST_SPIRIT_DEBUG_OUT << "</" << tag << '>' << std::endl;
-
- // $$$ FIXME convert invalid xml characters (e.g. '<') to valid
+
+ // $$$ FIXME convert invalid xml characters (e.g. '<') to valid
             // character entities. $$$
         }
 
@@ -142,8 +142,12 @@
                     print_some("success", indent, first, last);
                     print_indent(indent);
                     BOOST_SPIRIT_DEBUG_OUT
- << "<attributes>"
- << context.attributes
+ << "<attributes>";
+ traits::print_attribute(
+ BOOST_SPIRIT_DEBUG_OUT,
+ context.attributes
+ );
+ BOOST_SPIRIT_DEBUG_OUT
                         << "</attributes>";
                     if (!fusion::empty(context.locals))
                         BOOST_SPIRIT_DEBUG_OUT

Modified: trunk/boost/spirit/home/support/attributes.hpp
==============================================================================
--- trunk/boost/spirit/home/support/attributes.hpp (original)
+++ trunk/boost/spirit/home/support/attributes.hpp 2010-03-11 19:20:34 EST (Thu, 11 Mar 2010)
@@ -24,6 +24,7 @@
 #include <boost/fusion/include/pop_front.hpp>
 #include <boost/fusion/include/is_sequence.hpp>
 #include <boost/fusion/include/for_each.hpp>
+#include <boost/foreach.hpp>
 #include <boost/utility/value_init.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/type_traits/is_convertible.hpp>
@@ -49,12 +50,12 @@
 
     template <typename T>
     struct not_is_variant
- : mpl::true_
+ : mpl::true_
     {};
 
     template <BOOST_VARIANT_ENUM_PARAMS(typename T)>
     struct not_is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> >
- : mpl::false_
+ : mpl::false_
     {};
 
     template <typename T>
@@ -66,7 +67,7 @@
     // invoked for variant types only)
     template <typename T>
     struct variant_type
- : mpl::identity<T>
+ : mpl::identity<T>
     {};
 
     template <typename T>
@@ -77,12 +78,12 @@
     ///////////////////////////////////////////////////////////////////////////
     template <typename T>
     struct not_is_optional
- : mpl::true_
+ : mpl::true_
     {};
 
     template <typename T>
     struct not_is_optional<boost::optional<T> >
- : mpl::false_
+ : mpl::false_
     {};
 
     ///////////////////////////////////////////////////////////////////////////
@@ -143,7 +144,7 @@
     // the attribute in a tuple only IFF it is not already a fusion tuple.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Attribute, typename Force = mpl::false_>
- struct wrap_if_not_tuple
+ struct wrap_if_not_tuple
       : mpl::if_<
             fusion::traits::is_sequence<Attribute>
           , Attribute&, fusion::vector1<Attribute&> >
@@ -297,7 +298,7 @@
             typename mpl::find_if<Sequence, is_same<mpl::_, unused_type> >::type
           , typename mpl::end<Sequence>::type>
     {};
-
+
     namespace detail
     {
         template <typename Sequence, bool no_unused
@@ -357,7 +358,7 @@
     // that 1) all attributes in the variant are unique 2) puts the unused
     // attribute, if there is any, to the front and 3) collapses single element
     // variants, variant<T> to T.
- ///////////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////////
     template <typename Sequence>
     struct build_variant
     {
@@ -404,13 +405,13 @@
     // transform_attribute
     //
     // Sometimes the user needs to transform the attribute types for certain
- // attributes. This template can be used as a customization point, where
+ // attributes. This template can be used as a customization point, where
     // the user is able specify specific transformation rules for any attribute
     // type.
     //
     // The default attribute transformation (where the exposed attribute type is
     // different from the required transformed attribute type) relies on the
- // convertibility 'exposed type' --> 'transformed type', which has to exist
+ // convertibility 'exposed type' --> 'transformed type', which has to exist
     // in order to successfully execute the pre transform step.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Exposed, typename Transformed, typename Enable/* = void*/>
@@ -420,19 +421,19 @@
 
         static Transformed pre(Exposed& val) { return Transformed(val); }
 
- // By default do post transformation only if types are convertible,
- // otherwise we assume no post transform is required (i.e. the user
- // utilizes nview et.al.).
- static void post(Exposed&, Transformed const&, mpl::false_)
+ // By default do post transformation only if types are convertible,
+ // otherwise we assume no post transform is required (i.e. the user
+ // utilizes nview et.al.).
+ static void post(Exposed&, Transformed const&, mpl::false_)
         {
         }
- static void post(Exposed& val, Transformed const& attr, mpl::true_)
+ static void post(Exposed& val, Transformed const& attr, mpl::true_)
         {
- assign_to(attr, val);
+ assign_to(attr, val);
         }
 
- static void post(Exposed& val, Transformed const& attr)
- {
+ static void post(Exposed& val, Transformed const& attr)
+ {
             post(val, attr, is_convertible<Transformed, Exposed>());
         }
 
@@ -449,18 +450,18 @@
     };
 
     template <typename Exposed, typename Transformed>
- struct transform_attribute<optional<Exposed>, Transformed,
+ struct transform_attribute<optional<Exposed>, Transformed,
         typename disable_if<is_same<optional<Exposed>, Transformed> >::type>
     {
         typedef Transformed& type;
- static Transformed& pre(optional<Exposed>& val)
- {
+ static Transformed& pre(optional<Exposed>& val)
+ {
             if (!val)
                 val = Transformed();
- return boost::get<Transformed>(val);
+ return boost::get<Transformed>(val);
         }
         static void post(optional<Exposed>&, Transformed const&) {}
- static void fail(optional<Exposed>& val)
+ static void fail(optional<Exposed>& val)
         {
              val = none_t(); // leave optional uninitialized if rhs failed
         }
@@ -572,11 +573,11 @@
     // make_attribute
     //
     // All parsers and generators have specific attribute types.
- // Spirit parsers and generators are passed an attribute; these are either
- // references to the expected type, or an unused_type -- to flag that we do
- // not care about the attribute. For semantic actions, however, we need to
+ // Spirit parsers and generators are passed an attribute; these are either
+ // references to the expected type, or an unused_type -- to flag that we do
+ // not care about the attribute. For semantic actions, however, we need to
     // have a real value to pass to the semantic action. If the client did not
- // provide one, we will have to synthesize the value. This class takes care
+ // provide one, we will have to synthesize the value. This class takes care
     // of that.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Attribute, typename ActualAttribute>
@@ -687,16 +688,16 @@
     };
 
     ///////////////////////////////////////////////////////////////////////////
- // meta function to return whether the argument is a one element fusion
+ // meta function to return whether the argument is a one element fusion
     // sequence
     ///////////////////////////////////////////////////////////////////////////
     template <typename T, bool IsSeq = fusion::traits::is_sequence<T>::value>
- struct one_element_sequence
+ struct one_element_sequence
       : mpl::false_
     {};
 
     template <typename T>
- struct one_element_sequence<T, true>
+ struct one_element_sequence<T, true>
       : mpl::bool_<mpl::size<T>::value == 1>
     {};
 
@@ -729,14 +730,14 @@
 
         // for fusion sequences
         template <typename T>
- void clear_impl2(T& val, mpl::true_)
+ void clear_impl2(T& val, mpl::true_)
         {
             fusion::for_each(val, clear_visitor());
         }
 
         // dispatch default or fusion sequence
         template <typename T>
- void clear_impl(T& val, mpl::false_)
+ void clear_impl(T& val, mpl::false_)
         {
             clear_impl2(val, fusion::traits::is_sequence<T>());
         }
@@ -764,7 +765,7 @@
     {
         static void call(optional<T>& val)
         {
- if (val)
+ if (val)
                 val = none_t(); // leave optional uninitialized
         }
     };
@@ -800,6 +801,81 @@
     inline void clear(unused_type)
     {
     }
+
+ template <typename Out, typename T>
+ void print_attribute(Out& out, T const& val);
+
+ namespace detail
+ {
+ // for stl container data types
+ template <typename Out, typename T>
+ void print_attribute_impl(Out& out, T const& val, mpl::true_)
+ {
+ out << '[';
+ if (!val.empty())
+ {
+ for (typename T::const_iterator i = val.begin(); i != val.end(); ++i)
+ {
+ if (i != val.begin())
+ out << ", ";
+ print_attribute(out, *i);
+ }
+
+ }
+ out << ']';
+ }
+
+ // for non-fusion data types
+ template <typename Out, typename T>
+ void print_attribute_impl2(Out& out, T const& val, mpl::false_)
+ {
+ out << val;
+ }
+
+ template <typename Out>
+ struct print_fusion_sequence
+ {
+ print_fusion_sequence(Out& out)
+ : out(out), is_first(true) {}
+
+ typedef void result_type;
+
+ template <typename T>
+ void operator()(T const& val) const
+ {
+ if (is_first)
+ is_first = false;
+ else
+ out << ", ";
+ print_attribute(out, val);
+ }
+
+ Out& out;
+ mutable bool is_first;
+ };
+
+ // for fusion data types
+ template <typename Out, typename T>
+ void print_attribute_impl2(Out& out, T const& val, mpl::true_)
+ {
+ out << '[';
+ fusion::for_each(val, print_fusion_sequence<Out>(out));
+ out << ']';
+ }
+
+ // for non-stl container data types
+ template <typename Out, typename T>
+ void print_attribute_impl(Out& out, T const& val, mpl::false_)
+ {
+ print_attribute_impl2(out, val, fusion::traits::is_sequence<T>());
+ }
+ }
+
+ template <typename Out, typename T>
+ inline void print_attribute(Out& out, T const& val)
+ {
+ detail::print_attribute_impl(out, val, is_container<T>());
+ }
 }}}
 
 ///////////////////////////////////////////////////////////////////////////////


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk