// Copyright (c) 2001-2007 Joel de Guzman // Copyright (c) 2001-2008 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_KARMA_RULE_MAR_05_2007_0455PM) #define BOOST_SPIRIT_KARMA_RULE_MAR_05_2007_0455PM #if defined(_MSC_VER) && (_MSC_VER >= 1020) #pragma once // MS compatible compilers support #pragma once #endif #include #include #include #include #include #include #include #include #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable: 4355) // 'this' : used in base member initializer list warning #endif namespace boost { namespace spirit { namespace karma { template struct rule : make_nonterminal, T0, T1, T2>::type { typedef make_nonterminal, T0, T1, T2> make_nonterminal_; typedef typename make_nonterminal_::delimiter_type delimiter_type; typedef typename make_nonterminal_::type base_type; typedef detail::output_iterator iterator_type; typedef rule self_type; typedef detail::virtual_component_base< iterator_type, typename base_type::context_type, delimiter_type > virtual_component; typedef intrusive_ptr pointer_type; rule() {} ~rule() {} rule(rule const& rhs) : ptr(rhs.ptr) { } rule& operator=(rule const& rhs) { ptr = rhs.ptr; return *this; } template rule& operator=(Expr const& xpr) { typedef spirit::traits::is_component is_component; // report invalid expression error as early as possible // BOOST_MPL_ASSERT_MSG( // is_component::value, // xpr_is_not_convertible_to_a_generator, ()); // temp workaround for mpl problem BOOST_STATIC_ASSERT(is_component::value); define(xpr, mpl::false_()); return *this; } template friend rule& operator%=(rule& r, Expr const& xpr) { typedef spirit::traits::is_component is_component; // report invalid expression error as early as possible // BOOST_MPL_ASSERT_MSG( // is_component::value, // xpr_is_not_convertible_to_a_generator, ()); // temp workaround for mpl problem BOOST_STATIC_ASSERT(is_component::value); r.define(xpr, mpl::true_()); return r; } self_type alias() const { self_type result; result.define(*this, mpl::false_()); return result; } typename make_nonterminal_holder< nonterminal_object , self_type >::type copy() const { typename make_nonterminal_holder< nonterminal_object , self_type >::type result = {{*this}}; return result; } std::string name() const { return name_; } void name(std::string const& str) { name_ = str; } private: template friend struct grammar; template void define(Expr const& xpr, Auto) { typedef typename result_of::as_component::type component; typedef detail::virtual_component< iterator_type, component, typename base_type::context_type, delimiter_type, Auto > virtual_component; ptr = new virtual_component(spirit::as_component(karma::domain(), xpr)); } template bool generate( OutputIterator_& sink, Context& context, Delimiter const& delim) const { // If the following line produces a compilation error stating the // 3rd parameter is not convertible to the expected type, then you // are probably trying to use this rule instance with a delimiter // which is not compatible with the delimiter type used while // defining the type of this rule instance. return ptr->generate(sink, context, delim); } std::string what() const { if (name_.empty()) { if (ptr) { return "unnamed-rule"; } else { return "empty-rule"; } } else { return name_; } } friend struct nonterminal_director; pointer_type ptr; std::string name_; }; }}} #if defined(BOOST_MSVC) # pragma warning(pop) #endif #endif