summaryrefslogtreecommitdiff
path: root/boost/spirit/home/x3/support/traits/print_attribute.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/spirit/home/x3/support/traits/print_attribute.hpp')
-rw-r--r--boost/spirit/home/x3/support/traits/print_attribute.hpp150
1 files changed, 150 insertions, 0 deletions
diff --git a/boost/spirit/home/x3/support/traits/print_attribute.hpp b/boost/spirit/home/x3/support/traits/print_attribute.hpp
new file mode 100644
index 0000000000..47bffce1a1
--- /dev/null
+++ b/boost/spirit/home/x3/support/traits/print_attribute.hpp
@@ -0,0 +1,150 @@
+/*=============================================================================
+ 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
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#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>
+
+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 plain data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, unused_attribute)
+ {
+ out << "unused";
+ }
+
+ // for plain data types
+ template <typename T_>
+ static void call(Out& out, T_ const& val, plain_attribute)
+ {
+ out << val;
+ }
+
+ // 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