1 // Copyright (c) 2001-2007 Joel de Guzman
2 // Copyright (c) 2001-2009 Hartmut Kaiser
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 #if !defined(BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM)
8 #define BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM
10 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
11 #pragma once // MS compatible compilers support #pragma once
14 #include <boost/spirit/home/support/unused.hpp>
15 #include <boost/spirit/home/karma/nonterminal/nonterminal.hpp>
16 #include <boost/spirit/home/karma/nonterminal/grammar_fwd.hpp>
17 #include <boost/spirit/home/karma/nonterminal/detail/rule.hpp>
18 #include <boost/spirit/home/karma/domain.hpp>
19 #include <boost/spirit/home/karma/detail/output_iterator.hpp>
20 #include <boost/mpl/if.hpp>
21 #include <boost/mpl/assert.hpp>
23 #if defined(BOOST_MSVC)
24 # pragma warning(push)
25 # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning
28 namespace boost
{ namespace spirit
{ namespace karma
30 template <typename OutputIterator
, typename T0
= unused_type
,
31 typename T1
= unused_type
, typename T2
= unused_type
>
33 : make_nonterminal
<rule
<OutputIterator
, T0
, T1
, T2
>, T0
, T1
, T2
>::type
36 make_nonterminal
<rule
<OutputIterator
, T0
, T1
, T2
>, T0
, T1
, T2
>
39 typedef typename
make_nonterminal_::delimiter_type delimiter_type
;
40 typedef typename
make_nonterminal_::type base_type
;
41 typedef detail::output_iterator
<OutputIterator
> iterator_type
;
42 typedef rule
<OutputIterator
, T0
, T1
, T2
> self_type
;
45 detail::virtual_component_base
<
47 typename
base_type::context_type
,
52 typedef intrusive_ptr
<virtual_component
> pointer_type
;
62 rule
& operator=(rule
const& rhs
)
68 template <typename Expr
>
69 rule
& operator=(Expr
const& xpr
)
72 spirit::traits::is_component
<karma::domain
, Expr
>
75 // report invalid expression error as early as possible
76 // BOOST_MPL_ASSERT_MSG(
77 // is_component::value,
78 // xpr_is_not_convertible_to_a_generator, ());
80 // temp workaround for mpl problem
81 BOOST_STATIC_ASSERT(is_component::value
);
83 define(xpr
, mpl::false_());
87 template <typename Expr
>
88 friend rule
& operator%=(rule
& r
, Expr
const& xpr
)
91 spirit::traits::is_component
<karma::domain
, Expr
>
94 // report invalid expression error as early as possible
95 // BOOST_MPL_ASSERT_MSG(
96 // is_component::value,
97 // xpr_is_not_convertible_to_a_generator, ());
99 // temp workaround for mpl problem
100 BOOST_STATIC_ASSERT(is_component::value
);
102 r
.define(xpr
, mpl::true_());
106 self_type
alias() const
109 result
.define(*this, mpl::false_());
114 make_nonterminal_holder
<
115 nonterminal_object
<self_type
>
121 make_nonterminal_holder
<
122 nonterminal_object
<self_type
>
129 std::string
name() const
134 void name(std::string
const& str
)
141 template <typename Iterator_
, typename T0_
, typename T1_
, typename T2_
>
142 friend struct grammar
;
144 template <typename Expr
, typename Auto
>
145 void define(Expr
const& xpr
, Auto
)
148 result_of::as_component
<karma::domain
, Expr
>::type
151 detail::virtual_component
<
154 typename
base_type::context_type
,
159 ptr
= new virtual_component(spirit::as_component(karma::domain(), xpr
));
162 template <typename OutputIterator_
, typename Context
, typename Delimiter
>
164 OutputIterator_
& sink
, Context
& context
, Delimiter
const& delim
) const
166 // If the following line produces a compilation error stating the
167 // 3rd parameter is not convertible to the expected type, then you
168 // are probably trying to use this rule instance with a delimiter
169 // which is not compatible with the delimiter type used while
170 // defining the type of this rule instance.
171 return ptr
->generate(sink
, context
, delim
);
174 std::string
what() const
180 return "unnamed-rule";
193 friend struct nonterminal_director
;
200 #if defined(BOOST_MSVC)
201 # pragma warning(pop)