1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM) 7 #define BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM 8 9 #if defined(_MSC_VER) 10 #pragma once 11 #endif 12 13 #include <boost/spirit/include/version.hpp> 14 15 // we support Phoenix attributes only starting with V2.2 16 #if SPIRIT_VERSION >= 0x2020 17 18 #include <boost/spirit/home/karma/detail/attributes.hpp> 19 #include <boost/spirit/home/karma/detail/indirect_iterator.hpp> 20 #include <boost/spirit/home/support/container.hpp> 21 22 #include <boost/utility/result_of.hpp> 23 24 /////////////////////////////////////////////////////////////////////////////// 25 namespace boost { namespace phoenix 26 { 27 template <typename Expr> 28 struct actor; 29 }} 30 31 /////////////////////////////////////////////////////////////////////////////// 32 namespace boost { namespace spirit { namespace traits 33 { 34 /////////////////////////////////////////////////////////////////////////// 35 // Provide customization points allowing the use of phoenix expressions as 36 // generator functions in the context of generators expecting a container 37 // attribute (Kleene, plus, list, repeat, etc.) 38 /////////////////////////////////////////////////////////////////////////// 39 template <typename Eval> 40 struct is_container<phoenix::actor<Eval> const> 41 : is_container<typename boost::result_of<phoenix::actor<Eval>()>::type> 42 {}; 43 44 template <typename Eval> 45 struct container_iterator<phoenix::actor<Eval> const> 46 { 47 typedef phoenix::actor<Eval> const& type; 48 }; 49 50 template <typename Eval> 51 struct begin_container<phoenix::actor<Eval> const> 52 { 53 typedef phoenix::actor<Eval> const& type; callboost::spirit::traits::begin_container54 static type call(phoenix::actor<Eval> const& f) 55 { 56 return f; 57 } 58 }; 59 60 template <typename Eval> 61 struct end_container<phoenix::actor<Eval> const> 62 { 63 typedef phoenix::actor<Eval> const& type; callboost::spirit::traits::end_container64 static type call(phoenix::actor<Eval> const& f) 65 { 66 return f; 67 } 68 }; 69 70 template <typename Eval> 71 struct deref_iterator<phoenix::actor<Eval> const> 72 { 73 typedef typename boost::result_of<phoenix::actor<Eval>()>::type type; callboost::spirit::traits::deref_iterator74 static type call(phoenix::actor<Eval> const& f) 75 { 76 return f(); 77 } 78 }; 79 80 template <typename Eval> 81 struct next_iterator<phoenix::actor<Eval> const> 82 { 83 typedef phoenix::actor<Eval> const& type; callboost::spirit::traits::next_iterator84 static type call(phoenix::actor<Eval> const& f) 85 { 86 return f; 87 } 88 }; 89 90 template <typename Eval> 91 struct compare_iterators<phoenix::actor<Eval> const> 92 { 93 static bool callboost::spirit::traits::compare_iterators94 call(phoenix::actor<Eval> const&, phoenix::actor<Eval> const&) 95 { 96 return false; 97 } 98 }; 99 100 template <typename Eval> 101 struct container_value<phoenix::actor<Eval> > 102 { 103 typedef phoenix::actor<Eval> const& type; 104 }; 105 106 template <typename Eval> 107 struct make_indirect_iterator<phoenix::actor<Eval> const> 108 { 109 typedef phoenix::actor<Eval> const& type; 110 }; 111 112 /////////////////////////////////////////////////////////////////////////// 113 // Handle Phoenix actors as attributes, just invoke the function object 114 // and deal with the result as the attribute. 115 /////////////////////////////////////////////////////////////////////////// 116 template <typename Eval, typename Exposed> 117 struct extract_from_attribute<phoenix::actor<Eval>, Exposed> 118 { 119 typedef typename boost::result_of<phoenix::actor<Eval>()>::type type; 120 121 template <typename Context> callboost::spirit::traits::extract_from_attribute122 static type call(phoenix::actor<Eval> const& f, Context& context) 123 { 124 return f(unused, context); 125 } 126 }; 127 }}} 128 129 #endif 130 #endif 131