1 // Copyright (c) 2001-2011 Hartmut Kaiser
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)
6 #if !defined(BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM)
7 #define BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM
13 #include <boost/spirit/include/version.hpp>
15 // we support Phoenix attributes only starting with V2.2
16 #if SPIRIT_VERSION >= 0x2020
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>
22 #include <boost/spirit/include/phoenix_core.hpp>
23 #include <boost/utility/result_of.hpp>
25 ///////////////////////////////////////////////////////////////////////////////
26 namespace boost { namespace spirit { namespace traits
28 ///////////////////////////////////////////////////////////////////////////
29 // Provide customization points allowing the use of phoenix expressions as
30 // generator functions in the context of generators expecting a container
31 // attribute (Kleene, plus, list, repeat, etc.)
32 ///////////////////////////////////////////////////////////////////////////
33 template <typename Eval>
34 struct is_container<phoenix::actor<Eval> const>
35 : is_container<typename boost::result_of<phoenix::actor<Eval>()>::type>
38 template <typename Eval>
39 struct container_iterator<phoenix::actor<Eval> const>
41 typedef phoenix::actor<Eval> const& type;
44 template <typename Eval>
45 struct begin_container<phoenix::actor<Eval> const>
47 typedef phoenix::actor<Eval> const& type;
48 static type call(phoenix::actor<Eval> const& f)
54 template <typename Eval>
55 struct end_container<phoenix::actor<Eval> const>
57 typedef phoenix::actor<Eval> const& type;
58 static type call(phoenix::actor<Eval> const& f)
64 template <typename Eval>
65 struct deref_iterator<phoenix::actor<Eval> const>
67 typedef typename boost::result_of<phoenix::actor<Eval>()>::type type;
68 static type call(phoenix::actor<Eval> const& f)
74 template <typename Eval>
75 struct next_iterator<phoenix::actor<Eval> const>
77 typedef phoenix::actor<Eval> const& type;
78 static type call(phoenix::actor<Eval> const& f)
84 template <typename Eval>
85 struct compare_iterators<phoenix::actor<Eval> const>
88 call(phoenix::actor<Eval> const&, phoenix::actor<Eval> const&)
94 template <typename Eval>
95 struct container_value<phoenix::actor<Eval> >
97 typedef phoenix::actor<Eval> const& type;
100 template <typename Eval>
101 struct make_indirect_iterator<phoenix::actor<Eval> const>
103 typedef phoenix::actor<Eval> const& type;
106 ///////////////////////////////////////////////////////////////////////////
107 // Handle Phoenix actors as attributes, just invoke the function object
108 // and deal with the result as the attribute.
109 ///////////////////////////////////////////////////////////////////////////
110 template <typename Eval, typename Exposed>
111 struct extract_from_attribute<phoenix::actor<Eval>, Exposed>
113 typedef typename boost::result_of<phoenix::actor<Eval>()>::type type;
115 template <typename Context>
116 static type call(phoenix::actor<Eval> const& f, Context& context)
118 return f(unused, context);