1 // Copyright (c) 2001-2011 Joel de Guzman 2 // Copyright (c) 2001-2011 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) 6 7 #if !defined(BOOST_SPIRIT_KARMA_REFERENCE_APR_17_2009_1057PM) 8 #define BOOST_SPIRIT_KARMA_REFERENCE_APR_17_2009_1057PM 9 10 #if defined(_MSC_VER) 11 #pragma once 12 #endif 13 14 #include <boost/spirit/home/karma/meta_compiler.hpp> 15 #include <boost/spirit/home/karma/generator.hpp> 16 #include <boost/spirit/home/support/info.hpp> 17 #include <boost/spirit/home/support/handles_container.hpp> 18 #include <boost/type_traits/remove_const.hpp> 19 #include <boost/ref.hpp> 20 21 namespace boost { namespace spirit { namespace karma 22 { 23 /////////////////////////////////////////////////////////////////////////// 24 // reference is a generator that references another generator (its Subject) 25 /////////////////////////////////////////////////////////////////////////// 26 template <typename Subject> 27 struct reference : generator<reference<Subject> > 28 { 29 typedef mpl::int_<generator_properties::all_properties> properties; 30 31 typedef Subject subject_type; 32 referenceboost::spirit::karma::reference33 reference(Subject& subject) 34 : ref(subject) {} 35 36 template <typename Context, typename Unused> 37 struct attribute : Subject::template attribute<Context, Unused> {}; 38 39 // Default overload, used whenever the attribute is not unused and not 40 // used from an aliased rule. 41 template <typename OutputIterator, typename Context 42 , typename Delimiter, typename Attribute> generateboost::spirit::karma::reference43 bool generate(OutputIterator& sink, Context& context 44 , Delimiter const& delim, Attribute const& attr) const 45 { 46 return ref.get().generate(sink, context, delim, attr); 47 } 48 49 // This overload gets called from an aliased rule only, we take the 50 // attribute from the context provided from the wrapper rule. 51 template <typename OutputIterator, typename Context 52 , typename Delimiter> generateboost::spirit::karma::reference53 bool generate(OutputIterator& sink, Context& context 54 , Delimiter const& delim, unused_type) const 55 { 56 return ref.get().generate(sink, context, delim, context.attributes); 57 } 58 59 // This overload is used whenever no attribute is given and it is used 60 // not from an aliased rule. 61 template <typename OutputIterator, typename Delimiter> generateboost::spirit::karma::reference62 bool generate(OutputIterator& sink, unused_type 63 , Delimiter const& delim, unused_type) const 64 { 65 return ref.get().generate(sink, unused, delim, unused); 66 } 67 68 template <typename Context> whatboost::spirit::karma::reference69 info what(Context& context) const 70 { 71 // the reference is transparent (does not add any info) 72 return ref.get().what(context); 73 } 74 75 boost::reference_wrapper<Subject> ref; 76 }; 77 }}} 78 79 namespace boost { namespace spirit { namespace traits 80 { 81 /////////////////////////////////////////////////////////////////////////// 82 template <typename Subject, typename Attribute, typename Context 83 , typename Iterator> 84 struct handles_container<karma::reference<Subject>, Attribute 85 , Context, Iterator> 86 : handles_container<typename remove_const<Subject>::type, Attribute 87 , Context, Iterator> 88 {}; 89 }}} 90 91 #endif 92