blob: 2fbeaa131abf10f78a267e5f8e0e438d249f4c37 [file] [log] [blame]
// Copyright (c) 2001-2008 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_CONFIX_AUG_19_2008_1041AM)
#define BOOST_SPIRIT_KARMA_CONFIX_AUG_19_2008_1041AM
#include <boost/spirit/home/karma/domain.hpp>
#include <boost/spirit/home/karma/delimit.hpp>
#include <boost/spirit/home/support/component.hpp>
#include <boost/spirit/home/support/attribute_of.hpp>
#include <boost/spirit/home/support/unused.hpp>
#include <boost/spirit/home/support/auxiliary/confix.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
///////////////////////////////////////////////////////////////////////////
// the director for a confix() generated generator
struct confix_director
{
template <typename Component, typename Context, typename Unused>
struct attribute
{
typedef typename
result_of::subject<Component>::type
subject_type;
typedef typename
traits::attribute_of<karma::domain, subject_type, Context>::type
type;
};
private:
///////////////////////////////////////////////////////////////////////
template <typename OutputIterator, typename Context,
typename Delimiter, typename Expr>
static void
generate_helper(OutputIterator& sink, Context& ctx, Delimiter const& d,
Expr const& e)
{
BOOST_MPL_ASSERT_MSG(
(spirit::traits::is_component<karma::domain, Expr>::value),
expression_is_not_convertible_to_a_generator, (Context, Expr));
typedef
typename result_of::as_component<karma::domain, Expr>::type
expr;
expr eg = spirit::as_component(karma::domain(), e);
typedef typename expr::director director;
director::generate(eg, sink, ctx, d, unused);
}
template <typename Context, typename Expr>
static std::string what_helper(Expr const& e, Context& ctx)
{
typedef
typename result_of::as_component<karma::domain, Expr>::type
expr;
expr eg = spirit::as_component(karma::domain(), e);
typedef typename expr::director director;
return director::what(eg, ctx);
}
public:
///////////////////////////////////////////////////////////////////////
template <typename Component, typename OutputIterator,
typename Context, typename Delimiter, typename Parameter>
static bool
generate(Component const& component, OutputIterator& sink,
Context& ctx, Delimiter const& d, Parameter const& param)
{
// generate the prefix
generate_helper(sink, ctx, d,
spirit::detail::confix_extractor::prefix(
proto::child_c<0>(spirit::argument1(component))));
// generate the embedded items
typedef typename
spirit::result_of::subject<Component>::type::director
director;
bool result = director::generate(spirit::subject(component), sink,
ctx, d, param);
// append the suffix
generate_helper(sink, ctx, d,
spirit::detail::confix_extractor::suffix(
proto::child_c<0>(spirit::argument1(component))));
return result;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
std::string result = "confix(";
result += what_helper(spirit::detail::confix_extractor::prefix(
proto::child_c<0>(spirit::argument1(component))), ctx);
result += ", ";
result += what_helper(spirit::detail::confix_extractor::suffix(
proto::child_c<0>(spirit::argument1(component))), ctx);
result += ")[";
typedef typename
spirit::result_of::subject<Component>::type::director
director;
result += director::what(spirit::subject(component), ctx);
result += "]";
return result;
}
};
}}}
#endif