| // 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 |