Release 1.39.0
[boost.git] / Boost_1_39_0 / boost / spirit / home / karma / nonterminal / rule.hpp
blobefe04b2dafc0364df5b6bda3e99208ad91eb688a
1 // Copyright (c) 2001-2007 Joel de Guzman
2 // Copyright (c) 2001-2009 Hartmut Kaiser
3 //
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
12 #endif
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
26 #endif
28 namespace boost { namespace spirit { namespace karma
30 template <typename OutputIterator, typename T0 = unused_type,
31 typename T1 = unused_type, typename T2 = unused_type>
32 struct rule
33 : make_nonterminal<rule<OutputIterator, T0, T1, T2>, T0, T1, T2>::type
35 typedef
36 make_nonterminal<rule<OutputIterator, T0, T1, T2>, T0, T1, T2>
37 make_nonterminal_;
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;
44 typedef
45 detail::virtual_component_base<
46 iterator_type,
47 typename base_type::context_type,
48 delimiter_type
50 virtual_component;
52 typedef intrusive_ptr<virtual_component> pointer_type;
54 rule() {}
55 ~rule() {}
57 rule(rule const& rhs)
58 : ptr(rhs.ptr)
62 rule& operator=(rule const& rhs)
64 ptr = rhs.ptr;
65 return *this;
68 template <typename Expr>
69 rule& operator=(Expr const& xpr)
71 typedef
72 spirit::traits::is_component<karma::domain, Expr>
73 is_component;
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_());
84 return *this;
87 template <typename Expr>
88 friend rule& operator%=(rule& r, Expr const& xpr)
90 typedef
91 spirit::traits::is_component<karma::domain, Expr>
92 is_component;
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_());
103 return r;
106 self_type alias() const
108 self_type result;
109 result.define(*this, mpl::false_());
110 return result;
113 typename
114 make_nonterminal_holder<
115 nonterminal_object<self_type>
116 , self_type
117 >::type
118 copy() const
120 typename
121 make_nonterminal_holder<
122 nonterminal_object<self_type>
123 , self_type
124 >::type
125 result = {{*this}};
126 return result;
129 std::string name() const
131 return name_;
134 void name(std::string const& str)
136 name_ = str;
139 private:
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)
147 typedef typename
148 result_of::as_component<karma::domain, Expr>::type
149 component;
150 typedef
151 detail::virtual_component<
152 iterator_type,
153 component,
154 typename base_type::context_type,
155 delimiter_type,
156 Auto
158 virtual_component;
159 ptr = new virtual_component(spirit::as_component(karma::domain(), xpr));
162 template <typename OutputIterator_, typename Context, typename Delimiter>
163 bool generate(
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
176 if (name_.empty())
178 if (ptr)
180 return "unnamed-rule";
182 else
184 return "empty-rule";
187 else
189 return name_;
193 friend struct nonterminal_director;
194 pointer_type ptr;
195 std::string name_;
200 #if defined(BOOST_MSVC)
201 # pragma warning(pop)
202 #endif
204 #endif