File indexing completed on 2025-01-18 09:38:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
0011 #define BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
0012
0013 #if defined(_MSC_VER)
0014 # pragma once
0015 #endif
0016
0017 #include <boost/config.hpp> // NO_STD_LOCALE, DEDUCED_TYPENAME.
0018 #ifndef BOOST_NO_STD_LOCALE
0019 # include <locale>
0020 #endif
0021 #include <boost/iostreams/detail/ios.hpp>
0022 #include <boost/iostreams/detail/wrap_unwrap.hpp>
0023 #include <boost/iostreams/traits.hpp>
0024 #include <boost/iostreams/operations.hpp>
0025 #include <boost/mpl/if.hpp>
0026 #include <boost/static_assert.hpp>
0027 #include <boost/type_traits/is_convertible.hpp>
0028 #include <boost/type_traits/is_same.hpp>
0029
0030
0031 #include <boost/iostreams/detail/config/disable_warnings.hpp>
0032
0033 namespace boost { namespace iostreams {
0034
0035 namespace detail {
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 template<typename Source, typename Sink>
0047 class combined_device {
0048 private:
0049 typedef typename category_of<Source>::type in_category;
0050 typedef typename category_of<Sink>::type out_category;
0051 typedef typename char_type_of<Sink>::type sink_char_type;
0052 public:
0053 typedef typename char_type_of<Source>::type char_type;
0054 struct category
0055 : bidirectional,
0056 device_tag,
0057 closable_tag,
0058 localizable_tag
0059 { };
0060 BOOST_STATIC_ASSERT(is_device<Source>::value);
0061 BOOST_STATIC_ASSERT(is_device<Sink>::value);
0062 BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
0063 BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
0064 BOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::value));
0065 combined_device(const Source& src, const Sink& snk);
0066 std::streamsize read(char_type* s, std::streamsize n);
0067 std::streamsize write(const char_type* s, std::streamsize n);
0068 void close(BOOST_IOS::openmode);
0069 #ifndef BOOST_NO_STD_LOCALE
0070 void imbue(const std::locale& loc);
0071 #endif
0072 private:
0073 Source src_;
0074 Sink sink_;
0075 };
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 template<typename InputFilter, typename OutputFilter>
0087 class combined_filter {
0088 private:
0089 typedef typename category_of<InputFilter>::type in_category;
0090 typedef typename category_of<OutputFilter>::type out_category;
0091 typedef typename char_type_of<OutputFilter>::type output_char_type;
0092 public:
0093 typedef typename char_type_of<InputFilter>::type char_type;
0094 struct category
0095 : multichar_bidirectional_filter_tag,
0096 closable_tag,
0097 localizable_tag
0098 { };
0099 BOOST_STATIC_ASSERT(is_filter<InputFilter>::value);
0100 BOOST_STATIC_ASSERT(is_filter<OutputFilter>::value);
0101 BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
0102 BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
0103 BOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
0104 combined_filter(const InputFilter& in, const OutputFilter& out);
0105
0106 template<typename Source>
0107 std::streamsize read(Source& src, char_type* s, std::streamsize n)
0108 { return boost::iostreams::read(in_, src, s, n); }
0109
0110 template<typename Sink>
0111 std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
0112 { return boost::iostreams::write(out_, snk, s, n); }
0113
0114 template<typename Sink>
0115 void close(Sink& snk, BOOST_IOS::openmode which)
0116 {
0117 if (which == BOOST_IOS::in) {
0118 if (is_convertible<in_category, dual_use>::value) {
0119 iostreams::close(in_, snk, BOOST_IOS::in);
0120 } else {
0121 detail::close_all(in_, snk);
0122 }
0123 }
0124 if (which == BOOST_IOS::out) {
0125 if (is_convertible<out_category, dual_use>::value) {
0126 iostreams::close(out_, snk, BOOST_IOS::out);
0127 } else {
0128 detail::close_all(out_, snk);
0129 }
0130 }
0131 }
0132 #ifndef BOOST_NO_STD_LOCALE
0133 void imbue(const std::locale& loc);
0134 #endif
0135 private:
0136 InputFilter in_;
0137 OutputFilter out_;
0138 };
0139
0140 template<typename In, typename Out>
0141 struct combination_traits
0142 : mpl::if_<
0143 is_device<In>,
0144 combined_device<
0145 typename wrapped_type<In>::type,
0146 typename wrapped_type<Out>::type
0147 >,
0148 combined_filter<
0149 typename wrapped_type<In>::type,
0150 typename wrapped_type<Out>::type
0151 >
0152 >
0153 { };
0154
0155 }
0156
0157 template<typename In, typename Out>
0158 struct combination : detail::combination_traits<In, Out>::type {
0159 typedef typename detail::combination_traits<In, Out>::type base_type;
0160 typedef typename detail::wrapped_type<In>::type in_type;
0161 typedef typename detail::wrapped_type<Out>::type out_type;
0162 combination(const in_type& in, const out_type& out)
0163 : base_type(in, out) { }
0164 };
0165
0166 namespace detail {
0167
0168
0169 template<typename In, typename Out>
0170 struct combine_traits {
0171 typedef combination<
0172 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<In>::type,
0173 BOOST_DEDUCED_TYPENAME detail::unwrapped_type<Out>::type
0174 > type;
0175 };
0176
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 template<typename In, typename Out>
0189 typename detail::combine_traits<In, Out>::type
0190 combine(const In& in, const Out& out)
0191 {
0192 typedef typename detail::combine_traits<In, Out>::type return_type;
0193 return return_type(in, out);
0194 }
0195
0196
0197
0198 namespace detail {
0199
0200
0201
0202 template<typename Source, typename Sink>
0203 inline combined_device<Source, Sink>::combined_device
0204 (const Source& src, const Sink& snk)
0205 : src_(src), sink_(snk) { }
0206
0207 template<typename Source, typename Sink>
0208 inline std::streamsize
0209 combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
0210 { return iostreams::read(src_, s, n); }
0211
0212 template<typename Source, typename Sink>
0213 inline std::streamsize
0214 combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
0215 { return iostreams::write(sink_, s, n); }
0216
0217 template<typename Source, typename Sink>
0218 inline void
0219 combined_device<Source, Sink>::close(BOOST_IOS::openmode which)
0220 {
0221 if (which == BOOST_IOS::in)
0222 detail::close_all(src_);
0223 if (which == BOOST_IOS::out)
0224 detail::close_all(sink_);
0225 }
0226
0227 #ifndef BOOST_NO_STD_LOCALE
0228 template<typename Source, typename Sink>
0229 void combined_device<Source, Sink>::imbue(const std::locale& loc)
0230 {
0231 iostreams::imbue(src_, loc);
0232 iostreams::imbue(sink_, loc);
0233 }
0234 #endif
0235
0236
0237
0238 template<typename InputFilter, typename OutputFilter>
0239 inline combined_filter<InputFilter, OutputFilter>::combined_filter
0240 (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out)
0241 { }
0242
0243 #ifndef BOOST_NO_STD_LOCALE
0244 template<typename InputFilter, typename OutputFilter>
0245 void combined_filter<InputFilter, OutputFilter>::imbue
0246 (const std::locale& loc)
0247 {
0248 iostreams::imbue(in_, loc);
0249 iostreams::imbue(out_, loc);
0250 }
0251 #endif
0252
0253
0254 }
0255
0256 } }
0257
0258 #include <boost/iostreams/detail/config/enable_warnings.hpp>
0259
0260 #endif