Chris@16: // Copyright (c) 2001-2011 Hartmut Kaiser Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #if !defined(BOOST_SPIRIT_KARMA_ACTION_MAR_07_2007_0851AM) Chris@16: #define BOOST_SPIRIT_KARMA_ACTION_MAR_07_2007_0851AM Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit { namespace karma Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: BOOST_PP_REPEAT(SPIRIT_ARGUMENTS_LIMIT, SPIRIT_USING_ARGUMENT, _) Chris@16: Chris@16: template Chris@16: struct action : unary_generator > Chris@16: { Chris@16: typedef Subject subject_type; Chris@16: typedef typename subject_type::properties properties; Chris@16: Chris@16: template Chris@16: struct attribute Chris@16: : traits::attribute_of Chris@16: {}; Chris@16: Chris@16: action(Subject const& subject, Action f) Chris@16: : subject(subject), f(f) {} Chris@16: Chris@16: template < Chris@16: typename OutputIterator, typename Context, typename Delimiter Chris@16: , typename Attribute> Chris@16: bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d Chris@16: , Attribute const& attr_) const Chris@16: { Chris@16: typedef typename attribute::type attr_type; Chris@16: typedef traits::make_attribute make_attribute; Chris@16: Chris@16: // create a attribute if none is supplied Chris@16: // this creates a _copy_ of the attribute because the semantic Chris@16: // action will likely change parts of this Chris@16: typedef traits::transform_attribute< Chris@16: typename make_attribute::type, attr_type, domain> transform; Chris@16: Chris@16: typename transform::type attr = Chris@16: traits::pre_transform(make_attribute::call(attr_)); Chris@16: Chris@16: // call the function, passing the attribute, the context and a bool Chris@16: // flag that the client can set to false to fail generating. Chris@16: return traits::action_dispatch()(f, attr, ctx) && Chris@16: subject.generate(sink, ctx, d, attr); Chris@16: } Chris@16: Chris@16: template Chris@16: info what(Context& context) const Chris@16: { Chris@16: // the action is transparent (does not add any info) Chris@16: return subject.what(context); Chris@16: } Chris@16: Chris@16: subject_type subject; Chris@16: Action f; Chris@16: }; Chris@16: Chris@16: }}} Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Karma action meta-compiler Chris@16: template <> Chris@16: struct make_component Chris@16: { Chris@16: template Chris@16: struct result; Chris@16: Chris@16: template Chris@16: struct result Chris@16: { Chris@16: typedef typename Chris@16: remove_const::type Chris@16: subject_type; Chris@16: Chris@16: typedef typename Chris@16: remove_const::type Chris@16: action_type; Chris@16: Chris@16: typedef karma::action type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename result::type Chris@16: operator()(Elements const& elements, unused_type) const Chris@16: { Chris@16: typename result::type Chris@16: result(elements.car, elements.cdr.car); Chris@16: return result; Chris@16: } Chris@16: }; Chris@16: }} Chris@16: Chris@16: namespace boost { namespace spirit { namespace traits Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct has_semantic_action > Chris@16: : mpl::true_ {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct handles_container, Attribute Chris@16: , Context, Iterator> Chris@16: : unary_handles_container {}; Chris@16: }}} Chris@16: Chris@16: #endif