blob: ead6320d85da89ec9b943e16ee358124444a6c19 [file] [log] [blame]
// Copyright (c) 2001-2009 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_STREAM_MAY_01_2007_0310PM)
#define BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_0310PM
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once // MS compatible compilers support #pragma once
#endif
#include <boost/spirit/home/karma/stream/detail/format_manip.hpp>
#include <boost/spirit/home/karma/stream/detail/iterator_ostream.hpp>
#include <boost/spirit/home/support/detail/hold_any.hpp>
#include <iosfwd>
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
// overload the streaming operators for the unused_type
template <typename Char, typename Traits>
inline std::basic_ostream<Char, Traits>&
operator<< (std::basic_ostream<Char, Traits>& os, unused_type)
{
return os;
}
}}
///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit { namespace karma
{
template <typename Char>
struct any_stream
{
template <typename Component, typename Context, typename Unused>
struct attribute
{
typedef spirit::hold_any type;
};
// any_stream has a parameter attached
// this overload will be used in the normal case (not called from
// format_manip).
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)
{
typedef
karma::detail::iterator_sink<OutputIterator, Char>
sink_device;
iostreams::stream<sink_device> ostr(sink);
ostr << param << std::flush; // use existing operator<<()
if (ostr.good()) {
karma::delimit(sink, d); // always do post-delimiting
return true;
}
return false;
}
// this is a special overload to detect if the output iterator has been
// generated by a format_manip object.
template <
typename Component, typename T, typename Traits,
typename Context, typename Delimiter, typename Parameter
>
static bool
generate(Component const& component,
karma::detail::output_iterator<
karma::detail::ostream_iterator<T, Char, Traits>
>& sink, Context&, Delimiter const& d, Parameter const& param)
{
typedef karma::detail::output_iterator<
karma::detail::ostream_iterator<T, Char, Traits>
> output_iterator;
typedef
karma::detail::iterator_sink<output_iterator, Char>
sink_device;
iostreams::stream<sink_device> ostr(sink);
ostr.imbue(sink.get_ostream().getloc());
ostr << param << std::flush; // use existing operator<<()
if (ostr.good()) {
karma::delimit(sink, d); // always do post-delimiting
return true;
}
return false;
}
// this any_stream has no parameter attached, it needs to have been
// initialized from a value/variable
template <typename Component, typename OutputIterator,
typename Context, typename Delimiter>
static bool
generate(Component const&, OutputIterator&, Context&, Delimiter const&,
unused_type)
{
BOOST_MPL_ASSERT_MSG(false, stream__not_usable_without_attribute,
(Component, OutputIterator, Delimiter));
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "any-stream";
}
};
///////////////////////////////////////////////////////////////////////////
template <typename Char>
struct stream_director
{
template <typename Component, typename Context, typename Unused>
struct attribute
{
typedef unused_type type;
};
// stream_director has a parameter attached
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&)
{
typedef
karma::detail::iterator_sink<OutputIterator, Char>
sink_device;
// use existing operator<<()
iostreams::stream<sink_device> ostr(sink);
ostr << fusion::at_c<0>(component.elements) << std::flush;
if (ostr.good()) {
karma::delimit(sink, d); // always do post-delimiting
return true;
}
return false;
}
// this is a special overload to detect if the output iterator has been
// generated by a format_manip object.
template <
typename Component, typename T, typename Traits,
typename Context, typename Delimiter, typename Parameter
>
static bool
generate(Component const& component,
karma::detail::output_iterator<
karma::detail::ostream_iterator<T, Char, Traits>
>& sink, Context&, Delimiter const& d, Parameter const&)
{
typedef karma::detail::output_iterator<
karma::detail::ostream_iterator<T, Char, Traits>
> output_iterator;
typedef
karma::detail::iterator_sink<output_iterator, Char>
sink_device;
// use existing operator<<()
iostreams::stream<sink_device> ostr(sink);
ostr.imbue(sink.get_ostream().getloc());
ostr << fusion::at_c<0>(component.elements) << std::flush;
if (ostr.good()) {
karma::delimit(sink, d); // always do post-delimiting
return true;
}
return false;
}
template <typename Component, typename Context>
static std::string what(Component const& component, Context const& ctx)
{
return "stream";
}
};
}}}
#endif