1// Copyright (c) 2001-2011 Hartmut Kaiser
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_SPIRIT_KARMA_AUXILIARY_ATTR_CAST_HPP
7#define BOOST_SPIRIT_KARMA_AUXILIARY_ATTR_CAST_HPP
8
9#if defined(_MSC_VER)
10#pragma once
11#endif
12
13#include <boost/spirit/home/karma/meta_compiler.hpp>
14#include <boost/spirit/home/karma/generator.hpp>
15#include <boost/spirit/home/karma/domain.hpp>
16#include <boost/spirit/home/support/unused.hpp>
17#include <boost/spirit/home/support/info.hpp>
18#include <boost/spirit/home/support/common_terminals.hpp>
19#include <boost/spirit/home/karma/detail/attributes.hpp>
20#include <boost/spirit/home/support/auxiliary/attr_cast.hpp>
21
22namespace boost { namespace spirit
23{
24 ///////////////////////////////////////////////////////////////////////////
25 // enables attr_cast<>() pseudo generator
26 template <typename Expr, typename Exposed, typename Transformed>
27 struct use_terminal<karma::domain
28 , tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed> >
29 : mpl::true_ {};
30}}
31
32namespace boost { namespace spirit { namespace karma
33{
34 using spirit::attr_cast;
35
36 ///////////////////////////////////////////////////////////////////////////
37 // attr_cast_generator consumes the attribute of subject generator without
38 // generating anything
39 ///////////////////////////////////////////////////////////////////////////
40 template <typename Exposed, typename Transformed, typename Subject>
41 struct attr_cast_generator
42 : unary_generator<attr_cast_generator<Exposed, Transformed, Subject> >
43 {
44 typedef typename result_of::compile<karma::domain, Subject>::type
45 subject_type;
46
47 typedef mpl::int_<subject_type::properties::value> properties;
48
49 typedef typename mpl::eval_if<
50 traits::not_is_unused<Transformed>
51 , mpl::identity<Transformed>
52 , traits::attribute_of<subject_type> >::type
53 transformed_attribute_type;
54
55 attr_cast_generator(Subject const& subject)
56 : subject(subject)
57 {
58 // If you got an error_invalid_expression error message here,
59 // then the expression (Subject) is not a valid spirit karma
60 // expression.
61 BOOST_SPIRIT_ASSERT_MATCH(karma::domain, Subject);
62 }
63
64 // If Exposed is given, we use the given type, otherwise all we can do
65 // is to guess, so we expose our inner type as an attribute and
66 // deal with the passed attribute inside the parse function.
67 template <typename Context, typename Unused>
68 struct attribute
69 : mpl::if_<traits::not_is_unused<Exposed>, Exposed
70 , transformed_attribute_type>
71 {};
72
73 template <typename OutputIterator, typename Context, typename Delimiter
74 , typename Attribute>
75 bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d
76 , Attribute const& attr) const
77 {
78 typedef traits::transform_attribute<
79 Attribute const, transformed_attribute_type, domain>
80 transform;
81
82 return compile<karma::domain>(subject).generate(
83 sink, ctx, d, transform::pre(attr));
84 }
85
86 template <typename Context>
87 info what(Context& context) const
88 {
89 return info("attr_cast"
90 , compile<karma::domain>(subject).what(context));
91 }
92
93 Subject subject;
94 };
95
96 ///////////////////////////////////////////////////////////////////////////
97 // Generator generator: make_xxx function (objects)
98 ///////////////////////////////////////////////////////////////////////////
99 template <typename Expr, typename Exposed, typename Transformed
100 , typename Modifiers>
101 struct make_primitive<
102 tag::stateful_tag<Expr, tag::attr_cast, Exposed, Transformed>, Modifiers>
103 {
104 typedef attr_cast_generator<Exposed, Transformed, Expr> result_type;
105
106 template <typename Terminal>
107 result_type operator()(Terminal const& term, unused_type) const
108 {
109 typedef tag::stateful_tag<
110 Expr, tag::attr_cast, Exposed, Transformed> tag_type;
111 using spirit::detail::get_stateful_data;
112 return result_type(get_stateful_data<tag_type>::call(term));
113 }
114 };
115
116}}}
117
118#endif
119

source code of boost/libs/spirit/include/boost/spirit/home/karma/auxiliary/attr_cast.hpp