Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/spirit/home/karma/stream/stream.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/spirit/home/karma/stream/stream.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,379 @@ +// 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_STREAM_MAY_01_2007_0310PM) +#define BOOST_SPIRIT_KARMA_STREAM_MAY_01_2007_0310PM + +#if defined(_MSC_VER) +#pragma once +#endif + +#include <boost/spirit/home/support/common_terminals.hpp> +#include <boost/spirit/home/support/info.hpp> +#include <boost/spirit/home/support/container.hpp> +#include <boost/spirit/home/support/detail/hold_any.hpp> +#include <boost/spirit/home/support/detail/get_encoding.hpp> +#include <boost/spirit/home/support/detail/is_spirit_tag.hpp> +#include <boost/spirit/home/karma/domain.hpp> +#include <boost/spirit/home/karma/meta_compiler.hpp> +#include <boost/spirit/home/karma/delimit_out.hpp> +#include <boost/spirit/home/karma/auxiliary/lazy.hpp> +#include <boost/spirit/home/karma/stream/detail/format_manip.hpp> +#include <boost/spirit/home/karma/stream/detail/iterator_sink.hpp> +#include <boost/spirit/home/karma/detail/get_casetag.hpp> +#include <boost/spirit/home/karma/detail/extract_from.hpp> +#include <boost/fusion/include/at.hpp> +#include <boost/fusion/include/vector.hpp> +#include <boost/fusion/include/cons.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <iosfwd> + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit +{ + namespace tag + { + template <typename Char = char> + struct stream_tag + { + BOOST_SPIRIT_IS_TAG() + }; + } + + namespace karma + { + /////////////////////////////////////////////////////////////////////// + // This one is the class that the user can instantiate directly in + // order to create a customized int generator + template <typename Char = char> + struct stream_generator + : spirit::terminal<tag::stream_tag<Char> > + {}; + } + + /////////////////////////////////////////////////////////////////////////// + // Enablers + /////////////////////////////////////////////////////////////////////////// + template <> + struct use_terminal<karma::domain, tag::stream> // enables stream + : mpl::true_ {}; + + template <> + struct use_terminal<karma::domain, tag::wstream> // enables wstream + : mpl::true_ {}; + + template <typename A0> + struct use_terminal<karma::domain // enables stream(...) + , terminal_ex<tag::stream, fusion::vector1<A0> > + > : mpl::true_ {}; + + template <typename A0> + struct use_terminal<karma::domain // enables wstream(...) + , terminal_ex<tag::wstream, fusion::vector1<A0> > + > : mpl::true_ {}; + + template <> // enables stream(f) + struct use_lazy_terminal< + karma::domain, tag::stream, 1 /*arity*/ + > : mpl::true_ {}; + + template <> // enables wstream(f) + struct use_lazy_terminal< + karma::domain, tag::wstream, 1 /*arity*/ + > : mpl::true_ {}; + + // enables stream_generator<char_type> + template <typename Char> + struct use_terminal<karma::domain, tag::stream_tag<Char> > + : mpl::true_ {}; + + template <typename Char, typename A0> + struct use_terminal<karma::domain + , terminal_ex<tag::stream_tag<Char>, fusion::vector1<A0> > + > : mpl::true_ {}; + + template <typename Char> + struct use_lazy_terminal< + karma::domain, tag::stream_tag<Char>, 1 /*arity*/ + > : mpl::true_ {}; + +}} + +/////////////////////////////////////////////////////////////////////////////// +namespace boost { namespace spirit { namespace karma +{ +#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS + using spirit::stream; + using spirit::wstream; +#endif + using spirit::stream_type; + using spirit::wstream_type; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename CharEncoding, typename Tag> + struct any_stream_generator + : primitive_generator<any_stream_generator<Char, CharEncoding, Tag> > + { + template <typename Context, typename Unused = unused_type> + struct attribute + { + typedef spirit::basic_hold_any<Char> type; + }; + + // any_stream_generator has an attached attribute + template < + typename OutputIterator, typename Context, typename Delimiter + , typename Attribute + > + static bool generate(OutputIterator& sink, Context& context + , Delimiter const& d, Attribute const& attr) + { + typedef karma::detail::iterator_sink< + OutputIterator, Char, CharEncoding, Tag + > sink_device; + + if (!traits::has_optional_value(attr)) + return false; + + // use existing operator<<() + typedef typename attribute<Context>::type attribute_type; + + { + boost::iostreams::stream<sink_device> ostr(sink); + ostr << traits::extract_from<attribute_type>(attr, context) << std::flush; + + if (!ostr.good()) + return false; + } + + return karma::delimit_out(sink, d); // always do post-delimiting + } + + // this is a special overload to detect if the output iterator has been + // generated by a format_manip object. + template < + typename T, typename Traits, typename Properties, typename Context + , typename Delimiter, typename Attribute + > + static bool generate( + karma::detail::output_iterator< + karma::ostream_iterator<T, Char, Traits>, Properties + >& sink, Context& context, Delimiter const& d + , Attribute const& attr) + { + typedef karma::detail::output_iterator< + karma::ostream_iterator<T, Char, Traits>, Properties + > output_iterator; + typedef karma::detail::iterator_sink< + output_iterator, Char, CharEncoding, Tag + > sink_device; + + if (!traits::has_optional_value(attr)) + return false; + + // use existing operator<<() + typedef typename attribute<Context>::type attribute_type; + + { + boost::iostreams::stream<sink_device> ostr(sink); + ostr.imbue(sink.get_ostream().getloc()); + ostr << traits::extract_from<attribute_type>(attr, context) + << std::flush; + if (!ostr.good()) + return false; + } + + return karma::delimit_out(sink, d); // always do post-delimiting + } + + // this any_stream has no parameter attached, it needs to have been + // initialized from a value/variable + template <typename OutputIterator, typename Context + , typename Delimiter> + static bool + generate(OutputIterator&, Context&, Delimiter const&, unused_type) + { + // It is not possible (doesn't make sense) to use stream generators + // without providing any attribute, as the generator doesn't 'know' + // what to output. The following assertion fires if this situation + // is detected in your code. + BOOST_SPIRIT_ASSERT_FAIL(OutputIterator, stream_not_usable_without_attribute, ()); + return false; + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("stream"); + } + }; + + template <typename T, typename Char, typename CharEncoding, typename Tag> + struct lit_stream_generator + : primitive_generator<lit_stream_generator<T, Char, CharEncoding, Tag> > + { + template <typename Context, typename Unused> + struct attribute + { + typedef unused_type type; + }; + + lit_stream_generator(typename add_reference<T>::type t) + : t_(t) + {} + + // lit_stream_generator has an attached parameter + + // this overload will be used in the normal case (not called from + // format_manip). + template < + typename OutputIterator, typename Context, typename Delimiter + , typename Attribute> + bool generate(OutputIterator& sink, Context&, Delimiter const& d + , Attribute const&) const + { + typedef karma::detail::iterator_sink< + OutputIterator, Char, CharEncoding, Tag + > sink_device; + + boost::iostreams::stream<sink_device> ostr(sink); + ostr << t_ << std::flush; // use existing operator<<() + + if (ostr.good()) + return karma::delimit_out(sink, d); // always do post-delimiting + return false; + } + + // this is a special overload to detect if the output iterator has been + // generated by a format_manip object. + template < + typename T1, typename Traits, typename Properties + , typename Context, typename Delimiter, typename Attribute> + bool generate( + karma::detail::output_iterator< + karma::ostream_iterator<T1, Char, Traits>, Properties + >& sink, Context&, Delimiter const& d, Attribute const&) const + { + typedef karma::detail::output_iterator< + karma::ostream_iterator<T1, Char, Traits>, Properties + > output_iterator; + typedef karma::detail::iterator_sink< + output_iterator, Char, CharEncoding, Tag + > sink_device; + + { + boost::iostreams::stream<sink_device> ostr(sink); + ostr.imbue(sink.get_ostream().getloc()); + ostr << t_ << std::flush; // use existing operator<<() + + if (!ostr.good()) + return false; + } + + return karma::delimit_out(sink, d); // always do post-delimiting + } + + template <typename Context> + info what(Context& /*context*/) const + { + return info("any-stream"); + } + + T t_; + + private: + // silence MSVC warning C4512: assignment operator could not be generated + lit_stream_generator& operator= (lit_stream_generator const&); + }; + + /////////////////////////////////////////////////////////////////////////// + // Generator generators: make_xxx function (objects) + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename Modifiers> + struct make_stream + { + static bool const lower = + has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value; + + static bool const upper = + has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value; + + typedef any_stream_generator< + Char + , typename spirit::detail::get_encoding_with_case< + Modifiers, unused_type, lower || upper>::type + , typename detail::get_casetag<Modifiers, lower || upper>::type + > result_type; + + result_type operator()(unused_type, unused_type) const + { + return result_type(); + } + }; + + // stream + template <typename Modifiers> + struct make_primitive<tag::stream, Modifiers> + : make_stream<char, Modifiers> {}; + + // wstream + template <typename Modifiers> + struct make_primitive<tag::wstream, Modifiers> + : make_stream<wchar_t, Modifiers> {}; + + // any_stream_generator<char_type> + template <typename Char, typename Modifiers> + struct make_primitive<tag::stream_tag<Char>, Modifiers> + : make_stream<Char, Modifiers> {}; + + /////////////////////////////////////////////////////////////////////////// + template <typename Char, typename A0, typename Modifiers> + struct make_any_stream + { + static bool const lower = + has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value; + + static bool const upper = + has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value; + + typedef typename add_const<A0>::type const_attribute; + typedef lit_stream_generator< + const_attribute, Char + , typename spirit::detail::get_encoding_with_case< + Modifiers, unused_type, lower || upper>::type + , typename detail::get_casetag<Modifiers, lower || upper>::type + > result_type; + + template <typename Terminal> + result_type operator()(Terminal const& term, unused_type) const + { + return result_type(fusion::at_c<0>(term.args)); + } + }; + + // stream(...) + template <typename Modifiers, typename A0> + struct make_primitive< + terminal_ex<tag::stream, fusion::vector1<A0> >, Modifiers> + : make_any_stream<char, A0, Modifiers> {}; + + // wstream(...) + template <typename Modifiers, typename A0> + struct make_primitive< + terminal_ex<tag::wstream, fusion::vector1<A0> >, Modifiers> + : make_any_stream<wchar_t, A0, Modifiers> {}; + + // any_stream_generator<char_type>(...) + template <typename Char, typename Modifiers, typename A0> + struct make_primitive< + terminal_ex<tag::stream_tag<Char>, fusion::vector1<A0> > + , Modifiers> + : make_any_stream<Char, A0, Modifiers> {}; + +}}} + +#endif