123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*=============================================================================
- Copyright (c) 2001-2014 Joel de Guzman
- Copyright (c) 2001-2011 Hartmut Kaiser
- Distributed under the Boost Software License, Version 1.0. (See accompanying
- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- ================================================_==============================*/
- #if !defined(BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM)
- #define BOOST_SPIRIT_X3_PRINT_ATTRIBUTE_JANUARY_20_2013_0814AM
- #include <boost/variant.hpp>
- #include <boost/optional/optional.hpp>
- #include <boost/fusion/include/is_sequence.hpp>
- #include <boost/fusion/include/for_each.hpp>
- #include <boost/spirit/home/x3/support/traits/attribute_category.hpp>
- #include <boost/spirit/home/x3/support/traits/is_variant.hpp>
- #ifdef BOOST_SPIRIT_X3_UNICODE
- # include <boost/spirit/home/support/char_encoding/unicode.hpp>
- #endif
- namespace boost { namespace spirit { namespace x3 { namespace traits
- {
- template <typename Out, typename T>
- void print_attribute(Out& out, T const& val);
- template <typename Out>
- inline void print_attribute(Out&, unused_type) {}
- ///////////////////////////////////////////////////////////////////////////
- namespace detail
- {
- 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 << ", ";
- x3::traits::print_attribute(out, val);
- }
- Out& out;
- mutable bool is_first;
- };
- // print elements in a variant
- template <typename Out>
- struct print_visitor : static_visitor<>
- {
- print_visitor(Out& out) : out(out) {}
- template <typename T>
- void operator()(T const& val) const
- {
- x3::traits::print_attribute(out, val);
- }
- Out& out;
- };
- }
- template <typename Out, typename T, typename Enable = void>
- struct print_attribute_debug
- {
- // for unused_type
- static void call(Out& out, unused_type, unused_attribute)
- {
- out << "unused";
- }
- // for plain data types
- template <typename T_>
- static void call(Out& out, T_ const& val, plain_attribute)
- {
- out << val;
- }
- #ifdef BOOST_SPIRIT_X3_UNICODE
- static void call(Out& out, char_encoding::unicode::char_type val, plain_attribute)
- {
- if (val >= 0 && val < 127)
- {
- if (iscntrl(val))
- out << "\\" << std::oct << int(val) << std::dec;
- else if (isprint(val))
- out << char(val);
- else
- out << "\\x" << std::hex << int(val) << std::dec;
- }
- else
- out << "\\x" << std::hex << int(val) << std::dec;
- }
- static void call(Out& out, char val, plain_attribute tag)
- {
- call(out, static_cast<char_encoding::unicode::char_type>(val), tag);
- }
- #endif
- // for fusion data types
- template <typename T_>
- static void call(Out& out, T_ const& val, tuple_attribute)
- {
- out << '[';
- fusion::for_each(val, detail::print_fusion_sequence<Out>(out));
- out << ']';
- }
- // stl container
- template <typename T_>
- static void call(Out& out, T_ const& val, container_attribute)
- {
- out << '[';
- if (!traits::is_empty(val))
- {
- bool first = true;
- typename container_iterator<T_ const>::type iend = traits::end(val);
- for (typename container_iterator<T_ const>::type i = traits::begin(val);
- !traits::compare(i, iend); traits::next(i))
- {
- if (!first)
- out << ", ";
- first = false;
- x3::traits::print_attribute(out, traits::deref(i));
- }
- }
- out << ']';
- }
- // for variant types
- template <typename T_>
- static void call(Out& out, T_ const& val, variant_attribute)
- {
- apply_visitor(detail::print_visitor<Out>(out), val);
- }
- // for optional types
- template <typename T_>
- static void call(Out& out, T_ const& val, optional_attribute)
- {
- if (val)
- x3::traits::print_attribute(out, *val);
- else
- out << "[empty]";
- }
- // main entry point
- static void call(Out& out, T const& val)
- {
- call(out, val, typename attribute_category<T>::type());
- }
- };
- ///////////////////////////////////////////////////////////////////////////
- template <typename Out, typename T>
- inline void print_attribute(Out& out, T const& val)
- {
- print_attribute_debug<Out, T>::call(out, val);
- }
- }}}}
- #endif
|