123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
- // (C) Copyright 2003-2007 Jonathan Turkanis
- // 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.)
- // See http://www.boost.org/libs/iostreams for documentation.
- // To do: add support for random-access.
- #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
- #define BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
- #if defined(_MSC_VER)
- # pragma once
- #endif
- #include <boost/config.hpp> // NO_STD_LOCALE, DEDUCED_TYPENAME.
- #ifndef BOOST_NO_STD_LOCALE
- # include <locale>
- #endif
- #include <boost/iostreams/detail/ios.hpp>
- #include <boost/iostreams/detail/wrap_unwrap.hpp>
- #include <boost/iostreams/traits.hpp>
- #include <boost/iostreams/operations.hpp>
- #include <boost/mpl/if.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/type_traits/is_convertible.hpp>
- #include <boost/type_traits/is_same.hpp>
- // Must come last.
- #include <boost/iostreams/detail/config/disable_warnings.hpp>
- namespace boost { namespace iostreams {
- namespace detail {
- //
- // Template name: combined_device.
- // Description: Model of Device defined in terms of a Source/Sink pair.
- // Template parameters:
- // Source - A model of Source, with the same char_type and traits_type
- // as Sink.
- // Sink - A model of Sink, with the same char_type and traits_type
- // as Source.
- //
- template<typename Source, typename Sink>
- class combined_device {
- private:
- typedef typename category_of<Source>::type in_category;
- typedef typename category_of<Sink>::type out_category;
- typedef typename char_type_of<Sink>::type sink_char_type;
- public:
- typedef typename char_type_of<Source>::type char_type;
- struct category
- : bidirectional,
- device_tag,
- closable_tag,
- localizable_tag
- { };
- BOOST_STATIC_ASSERT(is_device<Source>::value);
- BOOST_STATIC_ASSERT(is_device<Sink>::value);
- BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
- BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
- BOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::value));
- combined_device(const Source& src, const Sink& snk);
- std::streamsize read(char_type* s, std::streamsize n);
- std::streamsize write(const char_type* s, std::streamsize n);
- void close(BOOST_IOS::openmode);
- #ifndef BOOST_NO_STD_LOCALE
- void imbue(const std::locale& loc);
- #endif
- private:
- Source src_;
- Sink sink_;
- };
- //
- // Template name: combined_filter.
- // Description: Model of Device defined in terms of a Source/Sink pair.
- // Template parameters:
- // InputFilter - A model of InputFilter, with the same char_type as
- // OutputFilter.
- // OutputFilter - A model of OutputFilter, with the same char_type as
- // InputFilter.
- //
- template<typename InputFilter, typename OutputFilter>
- class combined_filter {
- private:
- typedef typename category_of<InputFilter>::type in_category;
- typedef typename category_of<OutputFilter>::type out_category;
- typedef typename char_type_of<OutputFilter>::type output_char_type;
- public:
- typedef typename char_type_of<InputFilter>::type char_type;
- struct category
- : multichar_bidirectional_filter_tag,
- closable_tag,
- localizable_tag
- { };
- BOOST_STATIC_ASSERT(is_filter<InputFilter>::value);
- BOOST_STATIC_ASSERT(is_filter<OutputFilter>::value);
- BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
- BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
- BOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
- combined_filter(const InputFilter& in, const OutputFilter& out);
- template<typename Source>
- std::streamsize read(Source& src, char_type* s, std::streamsize n)
- { return boost::iostreams::read(in_, src, s, n); }
- template<typename Sink>
- std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
- { return boost::iostreams::write(out_, snk, s, n); }
- template<typename Sink>
- void close(Sink& snk, BOOST_IOS::openmode which)
- {
- if (which == BOOST_IOS::in) {
- if (is_convertible<in_category, dual_use>::value) {
- iostreams::close(in_, snk, BOOST_IOS::in);
- } else {
- detail::close_all(in_, snk);
- }
- }
- if (which == BOOST_IOS::out) {
- if (is_convertible<out_category, dual_use>::value) {
- iostreams::close(out_, snk, BOOST_IOS::out);
- } else {
- detail::close_all(out_, snk);
- }
- }
- }
- #ifndef BOOST_NO_STD_LOCALE
- void imbue(const std::locale& loc);
- #endif
- private:
- InputFilter in_;
- OutputFilter out_;
- };
- template<typename In, typename Out>
- struct combination_traits
- : mpl::if_<
- is_device<In>,
- combined_device<
- typename wrapped_type<In>::type,
- typename wrapped_type<Out>::type
- >,
- combined_filter<
- typename wrapped_type<In>::type,
- typename wrapped_type<Out>::type
- >
- >
- { };
- } // End namespace detail.
- template<typename In, typename Out>
- struct combination : detail::combination_traits<In, Out>::type {
- typedef typename detail::combination_traits<In, Out>::type base_type;
- typedef typename detail::wrapped_type<In>::type in_type;
- typedef typename detail::wrapped_type<Out>::type out_type;
- combination(const in_type& in, const out_type& out)
- : base_type(in, out) { }
- };
- namespace detail {
- // Workaround for VC6 ETI bug.
- template<typename In, typename Out>
- struct combine_traits {
- typedef combination<
- BOOST_DEDUCED_TYPENAME detail::unwrapped_type<In>::type,
- BOOST_DEDUCED_TYPENAME detail::unwrapped_type<Out>::type
- > type;
- };
- } // End namespace detail.
- //
- // Template name: combine.
- // Description: Takes a Source/Sink pair or InputFilter/OutputFilter pair and
- // returns a Source or Filter which performs input using the first member
- // of the pair and output using the second member of the pair.
- // Template parameters:
- // In - A model of Source or InputFilter, with the same char_type as Out.
- // Out - A model of Sink or OutputFilter, with the same char_type as In.
- //
- template<typename In, typename Out>
- typename detail::combine_traits<In, Out>::type
- combine(const In& in, const Out& out)
- {
- typedef typename detail::combine_traits<In, Out>::type return_type;
- return return_type(in, out);
- }
- //----------------------------------------------------------------------------//
- namespace detail {
- //--------------Implementation of combined_device-----------------------------//
- template<typename Source, typename Sink>
- inline combined_device<Source, Sink>::combined_device
- (const Source& src, const Sink& snk)
- : src_(src), sink_(snk) { }
- template<typename Source, typename Sink>
- inline std::streamsize
- combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
- { return iostreams::read(src_, s, n); }
- template<typename Source, typename Sink>
- inline std::streamsize
- combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
- { return iostreams::write(sink_, s, n); }
- template<typename Source, typename Sink>
- inline void
- combined_device<Source, Sink>::close(BOOST_IOS::openmode which)
- {
- if (which == BOOST_IOS::in)
- detail::close_all(src_);
- if (which == BOOST_IOS::out)
- detail::close_all(sink_);
- }
- #ifndef BOOST_NO_STD_LOCALE
- template<typename Source, typename Sink>
- void combined_device<Source, Sink>::imbue(const std::locale& loc)
- {
- iostreams::imbue(src_, loc);
- iostreams::imbue(sink_, loc);
- }
- #endif
- //--------------Implementation of filter_pair---------------------------------//
- template<typename InputFilter, typename OutputFilter>
- inline combined_filter<InputFilter, OutputFilter>::combined_filter
- (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out)
- { }
- #ifndef BOOST_NO_STD_LOCALE
- template<typename InputFilter, typename OutputFilter>
- void combined_filter<InputFilter, OutputFilter>::imbue
- (const std::locale& loc)
- {
- iostreams::imbue(in_, loc);
- iostreams::imbue(out_, loc);
- }
- #endif
- } // End namespace detail.
- } } // End namespaces iostreams, boost.
- #include <boost/iostreams/detail/config/enable_warnings.hpp>
- #endif // #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
|