File indexing completed on 2025-01-18 09:38:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
0016 #define BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
0017
0018 #if defined(_MSC_VER)
0019 # pragma once
0020 #endif
0021
0022 #include <iosfwd> // stream types, char_traits.
0023 #include <boost/config.hpp> // partial spec, deduced typename.
0024 #include <boost/detail/workaround.hpp>
0025 #include <boost/iostreams/categories.hpp>
0026 #include <boost/iostreams/detail/bool_trait_def.hpp>
0027 #include <boost/iostreams/detail/config/wide_streams.hpp>
0028 #include <boost/iostreams/detail/is_iterator_range.hpp>
0029 #include <boost/iostreams/detail/select.hpp>
0030 #include <boost/iostreams/detail/select_by_size.hpp>
0031 #include <boost/iostreams/detail/wrap_unwrap.hpp>
0032 #include <boost/iostreams/traits_fwd.hpp>
0033 #include <boost/mpl/bool.hpp>
0034 #include <boost/mpl/eval_if.hpp>
0035 #include <boost/mpl/identity.hpp>
0036 #include <boost/mpl/int.hpp>
0037 #include <boost/mpl/or.hpp>
0038 #include <boost/range/iterator_range.hpp>
0039 #include <boost/range/value_type.hpp>
0040 #include <boost/ref.hpp>
0041 #include <boost/type_traits/is_convertible.hpp>
0042
0043
0044 #include <boost/iostreams/detail/config/disable_warnings.hpp>
0045
0046 namespace boost { namespace iostreams {
0047
0048
0049
0050 #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
0051
0052 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2)
0053 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2)
0054 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2)
0055 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2)
0056 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream, std::basic_ifstream, 2)
0057 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream, std::basic_ofstream, 2)
0058 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream, std::basic_fstream, 2)
0059 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf, std::basic_filebuf, 2)
0060 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream, std::basic_istringstream, 3)
0061 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream, std::basic_ostringstream, 3)
0062 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3)
0063 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3)
0064
0065 #else
0066
0067 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0)
0068 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0)
0069 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0)
0070 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0)
0071
0072 #endif
0073
0074 template<typename T>
0075 struct is_std_io
0076 : mpl::or_< is_istream<T>, is_ostream<T>, is_streambuf<T> >
0077 { };
0078
0079 template<typename T>
0080 struct is_std_file_device
0081 : mpl::or_<
0082 is_ifstream<T>,
0083 is_ofstream<T>,
0084 is_fstream<T>,
0085 is_filebuf<T>
0086 >
0087 { };
0088
0089 template<typename T>
0090 struct is_std_string_device
0091 : mpl::or_<
0092 is_istringstream<T>,
0093 is_ostringstream<T>,
0094 is_stringstream<T>,
0095 is_stringbuf<T>
0096 >
0097 { };
0098
0099 template<typename Device, typename Tr, typename Alloc>
0100 struct stream;
0101
0102 template<typename T, typename Tr, typename Alloc, typename Mode>
0103 class stream_buffer;
0104
0105 template< typename Mode, typename Ch, typename Tr,
0106 typename Alloc, typename Access >
0107 class filtering_stream;
0108
0109 template< typename Mode, typename Ch, typename Tr,
0110 typename Alloc, typename Access >
0111 class wfiltering_stream;
0112
0113 template< typename Mode, typename Ch, typename Tr,
0114 typename Alloc, typename Access >
0115 class filtering_streambuf;
0116
0117 template< typename Mode, typename Ch, typename Tr,
0118 typename Alloc, typename Access >
0119 class filtering_wstreambuf;
0120
0121 namespace detail {
0122
0123 template<typename T, typename Tr>
0124 class linked_streambuf;
0125
0126 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream,
0127 boost::iostreams::stream,
0128 3 )
0129 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer,
0130 boost::iostreams::stream_buffer,
0131 4 )
0132 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl,
0133 boost::iostreams::filtering_stream,
0134 5 )
0135 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl,
0136 boost::iostreams::wfiltering_stream,
0137 5 )
0138 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl,
0139 boost::iostreams::filtering_streambuf,
0140 5 )
0141 BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl,
0142 boost::iostreams::filtering_wstreambuf,
0143 5 )
0144 BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2)
0145
0146 template<typename T>
0147 struct is_filtering_stream
0148 : mpl::or_<
0149 is_filtering_stream_impl<T>,
0150 is_filtering_wstream_impl<T>
0151 >
0152 { };
0153
0154 template<typename T>
0155 struct is_filtering_streambuf
0156 : mpl::or_<
0157 is_filtering_streambuf_impl<T>,
0158 is_filtering_wstreambuf_impl<T>
0159 >
0160 { };
0161
0162 template<typename T>
0163 struct is_boost
0164 : mpl::or_<
0165 is_boost_stream<T>,
0166 is_boost_stream_buffer<T>,
0167 is_filtering_stream<T>,
0168 is_filtering_streambuf<T>
0169 >
0170 { };
0171
0172 }
0173
0174
0175
0176 namespace detail {
0177
0178 template<typename T>
0179 struct member_char_type { typedef typename T::char_type type; };
0180
0181 }
0182
0183 # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
0184
0185 template<typename T>
0186 struct char_type_of
0187 : detail::member_char_type<
0188 typename detail::unwrapped_type<T>::type
0189 >
0190 { };
0191
0192 # else
0193
0194 template<typename T>
0195 struct char_type_of {
0196 typedef typename detail::unwrapped_type<T>::type U;
0197 typedef typename
0198 mpl::eval_if<
0199 is_std_io<U>,
0200 mpl::identity<char>,
0201 detail::member_char_type<U>
0202 >::type type;
0203 };
0204
0205 # endif
0206
0207 template<typename Iter>
0208 struct char_type_of< iterator_range<Iter> > {
0209 typedef typename iterator_value<Iter>::type type;
0210 };
0211
0212
0213
0214
0215 namespace detail {
0216
0217 template<typename T>
0218 struct member_category { typedef typename T::category type; };
0219
0220 }
0221
0222 template<typename T>
0223 struct category_of {
0224 template<typename U>
0225 struct member_category {
0226 typedef typename U::category type;
0227 };
0228 typedef typename detail::unwrapped_type<T>::type U;
0229 typedef typename
0230 mpl::eval_if<
0231 mpl::and_<
0232 is_std_io<U>,
0233 mpl::not_< detail::is_boost<U> >
0234 >,
0235 iostreams::select<
0236 is_filebuf<U>, filebuf_tag,
0237 is_ifstream<U>, ifstream_tag,
0238 is_ofstream<U>, ofstream_tag,
0239 is_fstream<U>, fstream_tag,
0240 is_stringbuf<U>, stringbuf_tag,
0241 is_istringstream<U>, istringstream_tag,
0242 is_ostringstream<U>, ostringstream_tag,
0243 is_stringstream<U>, stringstream_tag,
0244 is_streambuf<U>, generic_streambuf_tag,
0245 is_iostream<U>, generic_iostream_tag,
0246 is_istream<U>, generic_istream_tag,
0247 is_ostream<U>, generic_ostream_tag
0248 >,
0249 detail::member_category<U>
0250 >::type type;
0251 };
0252
0253
0254
0255 template<typename T>
0256 struct category_of< reference_wrapper<T> >
0257 : category_of<T>
0258 { };
0259
0260
0261
0262
0263
0264
0265
0266 template<typename T>
0267 inline typename category_of<T>::type get_category(const T&)
0268 { typedef typename category_of<T>::type category; return category(); }
0269
0270
0271
0272 template<typename T>
0273 struct int_type_of {
0274 #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
0275 typedef std::char_traits<
0276 BOOST_DEDUCED_TYPENAME char_type_of<T>::type
0277 > traits_type;
0278 typedef typename traits_type::int_type type;
0279 #else
0280 typedef int type;
0281 #endif
0282 };
0283
0284
0285
0286 namespace detail {
0287
0288 template<int N> struct io_mode_impl;
0289
0290 #define BOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \
0291 case_<id_> io_mode_impl_helper(tag_); \
0292 template<> struct io_mode_impl<id_> { typedef tag_ type; }; \
0293
0294 BOOST_IOSTREAMS_MODE_HELPER(input, 1)
0295 BOOST_IOSTREAMS_MODE_HELPER(output, 2)
0296 BOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3)
0297 BOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4)
0298 BOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5)
0299 BOOST_IOSTREAMS_MODE_HELPER(seekable, 6)
0300 BOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7)
0301 BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8)
0302 BOOST_IOSTREAMS_MODE_HELPER(dual_use, 9)
0303 #undef BOOST_IOSTREAMS_MODE_HELPER
0304
0305 template<typename T>
0306 struct io_mode_id {
0307 typedef typename category_of<T>::type category;
0308 BOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category()));
0309 };
0310
0311 }
0312
0313 template<typename T>
0314 struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { };
0315
0316
0317
0318 template<typename T>
0319 struct mode_of< reference_wrapper<T> >
0320 : mode_of<T>
0321 { };
0322
0323
0324
0325
0326 namespace detail {
0327
0328 template<typename T, typename Tag>
0329 struct has_trait_impl {
0330 typedef typename category_of<T>::type category;
0331 BOOST_STATIC_CONSTANT(bool, value = (is_convertible<category, Tag>::value));
0332 };
0333
0334 template<typename T, typename Tag>
0335 struct has_trait
0336 : mpl::bool_<has_trait_impl<T, Tag>::value>
0337 { };
0338
0339 }
0340
0341 template<typename T>
0342 struct is_device : detail::has_trait<T, device_tag> { };
0343
0344 template<typename T>
0345 struct is_filter : detail::has_trait<T, filter_tag> { };
0346
0347 template<typename T>
0348 struct is_direct : detail::has_trait<T, direct_tag> { };
0349
0350
0351
0352 #define BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \
0353 typedef Tr traits_type; \
0354 typedef typename traits_type::int_type int_type; \
0355 typedef typename traits_type::off_type off_type; \
0356 typedef typename traits_type::pos_type pos_type; \
0357
0358
0359 } }
0360
0361 #include <boost/iostreams/detail/config/enable_warnings.hpp>
0362
0363 #endif