concept_adapter.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2003-2007 Jonathan Turkanis
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
  5. // See http://www.boost.org/libs/iostreams for documentation.
  6. #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
  7. #define BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
  8. #include <boost/config.hpp> // SFINAE.
  9. #include <boost/iostreams/concepts.hpp>
  10. #include <boost/iostreams/categories.hpp>
  11. #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
  12. #include <boost/iostreams/detail/call_traits.hpp>
  13. #include <boost/iostreams/detail/char_traits.hpp>
  14. #include <boost/iostreams/detail/dispatch.hpp>
  15. #include <boost/iostreams/detail/error.hpp>
  16. #include <boost/iostreams/detail/streambuf.hpp> // pubsync.
  17. #include <boost/iostreams/detail/config/unreachable_return.hpp>
  18. #include <boost/iostreams/device/null.hpp>
  19. #include <boost/iostreams/traits.hpp>
  20. #include <boost/iostreams/operations.hpp>
  21. #include <boost/mpl/if.hpp>
  22. #include <boost/static_assert.hpp>
  23. #include <boost/throw_exception.hpp>
  24. // Must come last.
  25. #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
  26. namespace boost { namespace iostreams { namespace detail {
  27. template<typename Category> struct device_wrapper_impl;
  28. template<typename Category> struct flt_wrapper_impl;
  29. template<typename T>
  30. class concept_adapter {
  31. private:
  32. typedef typename detail::value_type<T>::type value_type;
  33. typedef typename dispatch<T, input, output>::type input_tag;
  34. typedef typename dispatch<T, output, input>::type output_tag;
  35. typedef typename
  36. mpl::if_<
  37. is_device<T>,
  38. device_wrapper_impl<input_tag>,
  39. flt_wrapper_impl<input_tag>
  40. >::type input_impl;
  41. typedef typename
  42. mpl::if_<
  43. is_device<T>,
  44. device_wrapper_impl<output_tag>,
  45. flt_wrapper_impl<output_tag>
  46. >::type output_impl;
  47. typedef typename
  48. mpl::if_<
  49. is_device<T>,
  50. device_wrapper_impl<any_tag>,
  51. flt_wrapper_impl<any_tag>
  52. >::type any_impl;
  53. public:
  54. typedef typename char_type_of<T>::type char_type;
  55. typedef typename category_of<T>::type category;
  56. explicit concept_adapter(const reference_wrapper<T>& ref) : t_(ref.get())
  57. { BOOST_STATIC_ASSERT(is_std_io<T>::value); }
  58. explicit concept_adapter(const T& t) : t_(t)
  59. { BOOST_STATIC_ASSERT(!is_std_io<T>::value); }
  60. T& operator*() { return t_; }
  61. T* operator->() { return &t_; }
  62. std::streamsize read(char_type* s, std::streamsize n)
  63. { return this->read(s, n, (basic_null_source<char_type>*) 0); }
  64. template<typename Source>
  65. std::streamsize read(char_type* s, std::streamsize n, Source* src)
  66. { return input_impl::read(t_, src, s, n); }
  67. std::streamsize write(const char_type* s, std::streamsize n)
  68. { return this->write(s, n, (basic_null_sink<char_type>*) 0); }
  69. template<typename Sink>
  70. std::streamsize write(const char_type* s, std::streamsize n, Sink* snk)
  71. { return output_impl::write(t_, snk, s, n); }
  72. std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
  73. BOOST_IOS::openmode which )
  74. {
  75. return this->seek( off, way, which,
  76. (basic_null_device<char_type, seekable>*) 0);
  77. }
  78. template<typename Device>
  79. std::streampos seek( stream_offset off, BOOST_IOS::seekdir way,
  80. BOOST_IOS::openmode which, Device* dev )
  81. { return any_impl::seek(t_, dev, off, way, which); }
  82. void close(BOOST_IOS::openmode which)
  83. { this->close(which, (basic_null_device<char_type, seekable>*) 0); }
  84. template<typename Device>
  85. void close(BOOST_IOS::openmode which, Device* dev)
  86. { any_impl::close(t_, dev, which); }
  87. template<typename Device>
  88. bool flush( Device* dev )
  89. {
  90. bool result = any_impl::flush(t_, dev);
  91. if (dev && dev->BOOST_IOSTREAMS_PUBSYNC() == -1)
  92. result = false;
  93. return result;
  94. }
  95. template<typename Locale> // Avoid dependency on <locale>
  96. void imbue(const Locale& loc) { iostreams::imbue(t_, loc); }
  97. std::streamsize optimal_buffer_size() const
  98. { return iostreams::optimal_buffer_size(t_); }
  99. private:
  100. BOOST_DELETED_FUNCTION(concept_adapter& operator=(const concept_adapter&));
  101. value_type t_;
  102. };
  103. //------------------Specializations of device_wrapper_impl--------------------//
  104. template<>
  105. struct device_wrapper_impl<any_tag> {
  106. template<typename Device, typename Dummy>
  107. static std::streampos
  108. seek( Device& dev, Dummy*, stream_offset off,
  109. BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
  110. {
  111. typedef typename category_of<Device>::type category;
  112. return seek(dev, off, way, which, category());
  113. }
  114. template<typename Device>
  115. static std::streampos
  116. seek( Device&, stream_offset, BOOST_IOS::seekdir,
  117. BOOST_IOS::openmode, any_tag )
  118. {
  119. boost::throw_exception(cant_seek());
  120. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0)
  121. }
  122. template<typename Device>
  123. static std::streampos
  124. seek( Device& dev, stream_offset off,
  125. BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
  126. random_access )
  127. {
  128. return iostreams::seek(dev, off, way, which);
  129. }
  130. template<typename Device, typename Dummy>
  131. static void close(Device& dev, Dummy*, BOOST_IOS::openmode which)
  132. { iostreams::close(dev, which); }
  133. template<typename Device, typename Dummy>
  134. static bool flush(Device& dev, Dummy*)
  135. { return iostreams::flush(dev); }
  136. };
  137. template<>
  138. struct device_wrapper_impl<input> : device_wrapper_impl<any_tag> {
  139. template<typename Device, typename Dummy>
  140. static std::streamsize
  141. read( Device& dev, Dummy*, typename char_type_of<Device>::type* s,
  142. std::streamsize n )
  143. { return iostreams::read(dev, s, n); }
  144. template<typename Device, typename Dummy>
  145. static std::streamsize
  146. write( Device&, Dummy*, const typename char_type_of<Device>::type*,
  147. std::streamsize )
  148. { boost::throw_exception(cant_write());
  149. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  150. };
  151. template<>
  152. struct device_wrapper_impl<output> {
  153. template<typename Device, typename Dummy>
  154. static std::streamsize
  155. read(Device&, Dummy*, typename char_type_of<Device>::type*, std::streamsize)
  156. { boost::throw_exception(cant_read());
  157. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  158. template<typename Device, typename Dummy>
  159. static std::streamsize
  160. write( Device& dev, Dummy*, const typename char_type_of<Device>::type* s,
  161. std::streamsize n )
  162. { return iostreams::write(dev, s, n); }
  163. };
  164. //------------------Specializations of flt_wrapper_impl--------------------//
  165. template<>
  166. struct flt_wrapper_impl<any_tag> {
  167. template<typename Filter, typename Device>
  168. static std::streampos
  169. seek( Filter& f, Device* dev, stream_offset off,
  170. BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
  171. {
  172. typedef typename category_of<Filter>::type category;
  173. return seek(f, dev, off, way, which, category());
  174. }
  175. template<typename Filter, typename Device>
  176. static std::streampos
  177. seek( Filter&, Device*, stream_offset,
  178. BOOST_IOS::seekdir, BOOST_IOS::openmode, any_tag )
  179. { boost::throw_exception(cant_seek());
  180. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  181. template<typename Filter, typename Device>
  182. static std::streampos
  183. seek( Filter& f, Device* dev, stream_offset off,
  184. BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
  185. random_access tag )
  186. {
  187. typedef typename category_of<Filter>::type category;
  188. return seek(f, dev, off, way, which, tag, category());
  189. }
  190. template<typename Filter, typename Device>
  191. static std::streampos
  192. seek( Filter& f, Device* dev, stream_offset off,
  193. BOOST_IOS::seekdir way, BOOST_IOS::openmode,
  194. random_access, any_tag )
  195. { return f.seek(*dev, off, way); }
  196. template<typename Filter, typename Device>
  197. static std::streampos
  198. seek( Filter& f, Device* dev, stream_offset off,
  199. BOOST_IOS::seekdir way, BOOST_IOS::openmode which,
  200. random_access, two_sequence )
  201. { return f.seek(*dev, off, way, which); }
  202. template<typename Filter, typename Device>
  203. static void close(Filter& f, Device* dev, BOOST_IOS::openmode which)
  204. { iostreams::close(f, *dev, which); }
  205. template<typename Filter, typename Device>
  206. static bool flush(Filter& f, Device* dev)
  207. { return iostreams::flush(f, *dev); }
  208. };
  209. template<>
  210. struct flt_wrapper_impl<input> {
  211. template<typename Filter, typename Source>
  212. static std::streamsize
  213. read( Filter& f, Source* src, typename char_type_of<Filter>::type* s,
  214. std::streamsize n )
  215. { return iostreams::read(f, *src, s, n); }
  216. template<typename Filter, typename Sink>
  217. static std::streamsize
  218. write( Filter&, Sink*, const typename char_type_of<Filter>::type*,
  219. std::streamsize )
  220. { boost::throw_exception(cant_write());
  221. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  222. };
  223. template<>
  224. struct flt_wrapper_impl<output> {
  225. template<typename Filter, typename Source>
  226. static std::streamsize
  227. read(Filter&, Source*, typename char_type_of<Filter>::type*,std::streamsize)
  228. { boost::throw_exception(cant_read());
  229. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  230. template<typename Filter, typename Sink>
  231. static std::streamsize
  232. write( Filter& f, Sink* snk, const typename char_type_of<Filter>::type* s,
  233. std::streamsize n )
  234. { return iostreams::write(f, *snk, s, n); }
  235. };
  236. //----------------------------------------------------------------------------//
  237. } } } // End namespaces detail, iostreams, boost.
  238. #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
  239. #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED