// Copyright (c) 2001-2011 Hartmut Kaiser | |
// | |
// Distributed under the Boost Software License, Version 1.0. (See accompanying | |
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
#if !defined(BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM) | |
#define BOOST_SPIRIT_KARMA_PHOENIX_ATTRIBUTES_OCT_01_2009_1128AM | |
#if defined(_MSC_VER) | |
#pragma once | |
#endif | |
#include <boost/spirit/include/version.hpp> | |
// we support Phoenix attributes only starting with V2.2 | |
#if SPIRIT_VERSION >= 0x2020 | |
#include <boost/spirit/home/karma/detail/attributes.hpp> | |
#include <boost/spirit/home/support/container.hpp> | |
#include <boost/spirit/include/phoenix_core.hpp> | |
#include <boost/utility/result_of.hpp> | |
/////////////////////////////////////////////////////////////////////////////// | |
namespace boost { namespace spirit { namespace traits | |
{ | |
/////////////////////////////////////////////////////////////////////////// | |
// Provide customization points allowing the use of phoenix expressions as | |
// generator functions in the context of generators expecting a container | |
// attribute (Kleene, plus, list, repeat, etc.) | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename Eval> | |
struct is_container<phoenix::actor<Eval> const> | |
: is_container<typename boost::result_of<phoenix::actor<Eval>()>::type> | |
{}; | |
template <typename Eval> | |
struct container_iterator<phoenix::actor<Eval> const> | |
{ | |
typedef phoenix::actor<Eval> const& type; | |
}; | |
template <typename Eval> | |
struct begin_container<phoenix::actor<Eval> const> | |
{ | |
typedef phoenix::actor<Eval> const& type; | |
static type call(phoenix::actor<Eval> const& f) | |
{ | |
return f; | |
} | |
}; | |
template <typename Eval> | |
struct end_container<phoenix::actor<Eval> const> | |
{ | |
typedef phoenix::actor<Eval> const& type; | |
static type call(phoenix::actor<Eval> const& f) | |
{ | |
return f; | |
} | |
}; | |
template <typename Eval> | |
struct deref_iterator<phoenix::actor<Eval> const> | |
{ | |
typedef typename boost::result_of<phoenix::actor<Eval>()>::type type; | |
static type call(phoenix::actor<Eval> const& f) | |
{ | |
return f(); | |
} | |
}; | |
template <typename Eval> | |
struct next_iterator<phoenix::actor<Eval> const> | |
{ | |
typedef phoenix::actor<Eval> const& type; | |
static type call(phoenix::actor<Eval> const& f) | |
{ | |
return f; | |
} | |
}; | |
template <typename Eval> | |
struct compare_iterators<phoenix::actor<Eval> const> | |
{ | |
static bool | |
call(phoenix::actor<Eval> const&, phoenix::actor<Eval> const&) | |
{ | |
return false; | |
} | |
}; | |
/////////////////////////////////////////////////////////////////////////// | |
// Handle Phoenix actors as attributes, just invoke the function object | |
// and deal with the result as the attribute. | |
/////////////////////////////////////////////////////////////////////////// | |
template <typename Eval, typename Exposed> | |
struct extract_from_attribute<phoenix::actor<Eval>, Exposed> | |
{ | |
typedef typename boost::result_of<phoenix::actor<Eval>()>::type type; | |
template <typename Context> | |
static type call(phoenix::actor<Eval> const& f, Context& context) | |
{ | |
return f(unused, context); | |
} | |
}; | |
}}} | |
#endif | |
#endif |