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(SPIRIT_KARMA_DUPLICATE_JUL_11_2010_0954AM) Chris@16: #define SPIRIT_KARMA_DUPLICATE_JUL_11_2010_0954AM 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: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace spirit Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Enablers Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template <> Chris@16: struct use_directive // enables duplicate Chris@16: : mpl::true_ {}; Chris@16: }} Chris@16: Chris@16: namespace boost { namespace spirit { namespace karma Chris@16: { Chris@16: #ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS Chris@16: using spirit::duplicate; Chris@16: #endif Chris@16: using spirit::duplicate_type; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: namespace detail Chris@16: { Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template ::value> Chris@16: struct attribute_count Chris@16: : fusion::result_of::size Chris@16: {}; Chris@16: Chris@16: template <> Chris@16: struct attribute_count Chris@16: : mpl::int_<0> Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct attribute_count Chris@16: : mpl::int_<1> Chris@16: {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template ::value> Chris@16: struct first_attribute_of_subject Chris@16: : fusion::result_of::at_c Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct first_attribute_of_subject Chris@16: : mpl::identity Chris@16: {}; Chris@16: Chris@16: template Chris@16: struct first_attribute_of Chris@16: : first_attribute_of_subject< Chris@16: typename traits::attribute_of::type> Chris@16: {}; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct duplicate_sequence_attribute Chris@16: { Chris@16: typedef typename fusion::result_of::make_cons< Chris@16: reference_wrapper Chris@16: , typename duplicate_sequence_attribute::type Chris@16: >::type type; Chris@16: Chris@16: static type call(T const& t) Chris@16: { Chris@16: return fusion::make_cons(boost::cref(t) Chris@16: , duplicate_sequence_attribute::call(t)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duplicate_sequence_attribute Chris@16: { Chris@16: typedef typename fusion::result_of::make_cons< Chris@16: reference_wrapper >::type type; Chris@16: Chris@16: static type call(T const& t) Chris@16: { Chris@16: return fusion::make_cons(boost::cref(t)); Chris@16: } Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////// Chris@16: template ::value Chris@16: , bool IsSequence = fusion::traits::is_sequence::value> Chris@16: struct duplicate_attribute Chris@16: { Chris@16: BOOST_SPIRIT_ASSERT_MSG(N > 0, invalid_duplication_count, (Attribute)); Chris@16: Chris@16: typedef typename duplicate_sequence_attribute::type Chris@16: cons_type; Chris@16: typedef typename fusion::result_of::as_vector::type type; Chris@16: Chris@16: static type call(T const& t) Chris@16: { Chris@16: return fusion::as_vector( Chris@16: duplicate_sequence_attribute::call(t)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duplicate_attribute Chris@16: { Chris@16: typedef unused_type type; Chris@16: Chris@16: static type call(T const&) Chris@16: { Chris@16: return unused; Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct duplicate_attribute Chris@16: { Chris@16: typedef Attribute const& type; Chris@16: Chris@16: static type call(T const& t) Chris@16: { Chris@16: return t; Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: inline typename detail::duplicate_attribute::type Chris@16: duplicate_attribute(T const& t) Chris@16: { Chris@16: return detail::duplicate_attribute::call(t); Chris@16: } Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // duplicate_directive duplicate its attribute for all elements of the Chris@16: // subject generator without generating anything itself Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct duplicate_directive : unary_generator > Chris@16: { Chris@16: typedef Subject subject_type; Chris@16: typedef typename subject_type::properties properties; Chris@16: Chris@16: duplicate_directive(Subject const& subject) Chris@16: : subject(subject) {} Chris@16: Chris@16: template Chris@16: struct attribute Chris@16: : detail::first_attribute_of Chris@16: {}; Chris@16: Chris@16: template Chris@16: bool generate(OutputIterator& sink, Context& ctx, Delimiter const& d Chris@16: , Attribute const& attr) const Chris@16: { Chris@16: typedef typename traits::attribute_of::type Chris@16: subject_attr_type; Chris@16: return subject.generate(sink, ctx, d Chris@16: , duplicate_attribute(attr)); Chris@16: } Chris@16: Chris@16: template Chris@16: info what(Context& context) const Chris@16: { Chris@16: return info("duplicate", subject.what(context)); Chris@16: } Chris@16: Chris@16: Subject subject; Chris@16: }; Chris@16: Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: // Generator generators: make_xxx function (objects) Chris@16: /////////////////////////////////////////////////////////////////////////// Chris@16: template Chris@16: struct make_directive Chris@16: { Chris@16: typedef duplicate_directive result_type; Chris@16: result_type operator()(unused_type, Subject const& subject Chris@16: , unused_type) const Chris@16: { Chris@16: return result_type(subject); 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: : unary_has_semantic_action {}; 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