File indexing completed on 2025-01-18 09:38:48
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
0010
0011 #include <boost/config.hpp> // SFINAE.
0012 #include <boost/iostreams/concepts.hpp>
0013 #include <boost/iostreams/categories.hpp>
0014 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
0015 #include <boost/iostreams/detail/call_traits.hpp>
0016 #include <boost/iostreams/detail/char_traits.hpp>
0017 #include <boost/iostreams/detail/dispatch.hpp>
0018 #include <boost/iostreams/detail/error.hpp>
0019 #include <boost/iostreams/detail/streambuf.hpp> // pubsync.
0020 #include <boost/iostreams/detail/config/unreachable_return.hpp>
0021 #include <boost/iostreams/device/null.hpp>
0022 #include <boost/iostreams/traits.hpp>
0023 #include <boost/iostreams/operations.hpp>
0024 #include <boost/mpl/if.hpp>
0025 #include <boost/static_assert.hpp>
0026 #include <boost/throw_exception.hpp>
0027
0028
0029 #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
0030
0031
0032 namespace boost { namespace iostreams { namespace detail {
0033
0034 template<typename Category> struct device_wrapper_impl;
0035 template<typename Category> struct flt_wrapper_impl;
0036
0037 template<typename T>
0038 class concept_adapter {
0039 private:
0040 typedef typename detail::value_type<T>::type value_type;
0041 typedef typename dispatch<T, input, output>::type input_tag;
0042 typedef typename dispatch<T, output, input>::type output_tag;
0043 typedef typename
0044 mpl::if_<
0045 is_device<T>,
0046 device_wrapper_impl<input_tag>,
0047 flt_wrapper_impl<input_tag>
0048 >::type input_impl;
0049 typedef typename
0050 mpl::if_<
0051 is_device<T>,
0052 device_wrapper_impl<output_tag>,
0053 flt_wrapper_impl<output_tag>
0054 >::type output_impl;
0055 typedef typename
0056 mpl::if_<
0057 is_device<T>,
0058 device_wrapper_impl<any_tag>,
0059 flt_wrapper_impl<any_tag>
0060 >::type any_impl;
0061 public:
0062 typedef typename char_type_of<T>::type char_type;
0063 typedef typename category_of<T>::type category;
0064
0065 explicit concept_adapter(const reference_wrapper<T>& ref) : t_(ref.get())
0066 { BOOST_STATIC_ASSERT(is_std_io<T>::value); }
0067 explicit concept_adapter(const T& t) : t_(t)
0068 { BOOST_STATIC_ASSERT(!is_std_io<T>::value); }
0069
0070 T& operator*() { return t_; }
0071 T* operator->() { return &t_; }
0072
0073 std::streamsize read(char_type* s, std::streamsize n)
0074 { return this->read(s, n, (basic_null_source<char_type>*) 0); }
0075
0076 template<typename Source>
0077 std::streamsize read(char_type* s, std::streamsize n, Source* src)
0078 { return input_impl::read(t_, src, s, n); }
0079
0080 std::streamsize write(const char_type* s, std::streamsize n)
0081 { return this->write(s, n, (basic_null_sink<char_type>*) 0); }
0082
0083 template<typename Sink>
0084 std::streamsize write(const char_type* s, std::streamsize n, Sink* snk)
0085 { return output_impl::write(t_, snk, s, n); }
0086
0087 std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
0088 BOOST_IOS::openmode which )
0089 {
0090 return this->seek( off, way, which,
0091 (basic_null_device<char_type, seekable>*) 0);
0092 }
0093
0094 template<typename Device>
0095 std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
0096 BOOST_IOS::openmode which, Device* dev )
0097 { return any_impl::seek(t_, dev, off, way, which); }
0098
0099 void close(BOOST_IOS::openmode which)
0100 { this->close(which, (basic_null_device<char_type, seekable>*) 0); }
0101
0102 template<typename Device>
0103 void close(BOOST_IOS::openmode which, Device* dev)
0104 { any_impl::close(t_, dev, which); }
0105
0106 template<typename Device>
0107 bool flush( Device* dev )
0108 {
0109 bool result = any_impl::flush(t_, dev);
0110 if (dev && dev->BOOST_IOSTREAMS_PUBSYNC() == -1)
0111 result = false;
0112 return result;
0113 }
0114
0115 template<typename Locale>
0116 void imbue(const Locale& loc) { iostreams::imbue(t_, loc); }
0117
0118 std::streamsize optimal_buffer_size() const
0119 { return iostreams::optimal_buffer_size(t_); }
0120 private:
0121 BOOST_DELETED_FUNCTION(concept_adapter& operator=(const concept_adapter&))
0122 value_type t_;
0123 };
0124
0125
0126
0127 template<>
0128 struct device_wrapper_impl<any_tag> {
0129 template<typename Device, typename Dummy>
0130 static std::streampos
0131 seek( Device& dev, Dummy*, stream_offset off,
0132 BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
0133 {
0134 typedef typename category_of<Device>::type category;
0135 return seek(dev, off, way, which, category());
0136 }
0137
0138 template<typename Device>
0139 static std::streampos
0140 seek( Device&, stream_offset, BOOST_IOS::seekdir,
0141 BOOST_IOS::openmode, any_tag )
0142 {
0143 boost::throw_exception(cant_seek());
0144 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0)
0145 }
0146
0147 template<typename Device>
0148 static std::streampos
0149 seek( Device& dev, stream_offset off,
0150 BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
0151 random_access )
0152 {
0153 return iostreams::seek(dev, off, way, which);
0154 }
0155
0156 template<typename Device, typename Dummy>
0157 static void close(Device& dev, Dummy*, BOOST_IOS::openmode which)
0158 { iostreams::close(dev, which); }
0159
0160 template<typename Device, typename Dummy>
0161 static bool flush(Device& dev, Dummy*)
0162 { return iostreams::flush(dev); }
0163 };
0164
0165
0166 template<>
0167 struct device_wrapper_impl<input> : device_wrapper_impl<any_tag> {
0168 template<typename Device, typename Dummy>
0169 static std::streamsize
0170 read( Device& dev, Dummy*, typename char_type_of<Device>::type* s,
0171 std::streamsize n )
0172 { return iostreams::read(dev, s, n); }
0173
0174 template<typename Device, typename Dummy>
0175 static std::streamsize
0176 write( Device&, Dummy*, const typename char_type_of<Device>::type*,
0177 std::streamsize )
0178 { boost::throw_exception(cant_write());
0179 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
0180 };
0181
0182 template<>
0183 struct device_wrapper_impl<output> {
0184 template<typename Device, typename Dummy>
0185 static std::streamsize
0186 read(Device&, Dummy*, typename char_type_of<Device>::type*, std::streamsize)
0187 { boost::throw_exception(cant_read());
0188 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
0189
0190 template<typename Device, typename Dummy>
0191 static std::streamsize
0192 write( Device& dev, Dummy*, const typename char_type_of<Device>::type* s,
0193 std::streamsize n )
0194 { return iostreams::write(dev, s, n); }
0195 };
0196
0197
0198
0199 template<>
0200 struct flt_wrapper_impl<any_tag> {
0201 template<typename Filter, typename Device>
0202 static std::streampos
0203 seek( Filter& f, Device* dev, stream_offset off,
0204 BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
0205 {
0206 typedef typename category_of<Filter>::type category;
0207 return seek(f, dev, off, way, which, category());
0208 }
0209
0210 template<typename Filter, typename Device>
0211 static std::streampos
0212 seek( Filter&, Device*, stream_offset,
0213 BOOST_IOS::seekdir, BOOST_IOS::openmode, any_tag )
0214 { boost::throw_exception(cant_seek());
0215 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
0216
0217 template<typename Filter, typename Device>
0218 static std::streampos
0219 seek( Filter& f, Device* dev, stream_offset off,
0220 BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
0221 random_access tag )
0222 {
0223 typedef typename category_of<Filter>::type category;
0224 return seek(f, dev, off, way, which, tag, category());
0225 }
0226
0227 template<typename Filter, typename Device>
0228 static std::streampos
0229 seek( Filter& f, Device* dev, stream_offset off,
0230 BOOST_IOS::seekdir way, BOOST_IOS::openmode,
0231 random_access, any_tag )
0232 { return f.seek(*dev, off, way); }
0233
0234 template<typename Filter, typename Device>
0235 static std::streampos
0236 seek( Filter& f, Device* dev, stream_offset off,
0237 BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
0238 random_access, two_sequence )
0239 { return f.seek(*dev, off, way, which); }
0240
0241 template<typename Filter, typename Device>
0242 static void close(Filter& f, Device* dev, BOOST_IOS::openmode which)
0243 { iostreams::close(f, *dev, which); }
0244
0245 template<typename Filter, typename Device>
0246 static bool flush(Filter& f, Device* dev)
0247 { return iostreams::flush(f, *dev); }
0248 };
0249
0250 template<>
0251 struct flt_wrapper_impl<input> {
0252 template<typename Filter, typename Source>
0253 static std::streamsize
0254 read( Filter& f, Source* src, typename char_type_of<Filter>::type* s,
0255 std::streamsize n )
0256 { return iostreams::read(f, *src, s, n); }
0257
0258 template<typename Filter, typename Sink>
0259 static std::streamsize
0260 write( Filter&, Sink*, const typename char_type_of<Filter>::type*,
0261 std::streamsize )
0262 { boost::throw_exception(cant_write());
0263 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
0264 };
0265
0266 template<>
0267 struct flt_wrapper_impl<output> {
0268 template<typename Filter, typename Source>
0269 static std::streamsize
0270 read(Filter&, Source*, typename char_type_of<Filter>::type*,std::streamsize)
0271 { boost::throw_exception(cant_read());
0272 BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
0273
0274 template<typename Filter, typename Sink>
0275 static std::streamsize
0276 write( Filter& f, Sink* snk, const typename char_type_of<Filter>::type* s,
0277 std::streamsize n )
0278 { return iostreams::write(f, *snk, s, n); }
0279 };
0280
0281
0282
0283 } } }
0284
0285 #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
0286
0287 #endif