checked_operations.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2. // (C) Copyright 2005-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. // Contains implementations of get, read, put, write and seek which
  7. // check a device's mode at runtime instead of compile time.
  8. #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
  9. #define BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
  10. #include <boost/iostreams/categories.hpp>
  11. #include <boost/iostreams/detail/dispatch.hpp>
  12. #include <boost/iostreams/detail/error.hpp>
  13. #include <boost/iostreams/detail/config/unreachable_return.hpp>
  14. #include <boost/iostreams/get.hpp>
  15. #include <boost/iostreams/put.hpp>
  16. #include <boost/iostreams/read.hpp>
  17. #include <boost/iostreams/seek.hpp>
  18. #include <boost/iostreams/traits.hpp>
  19. #include <boost/iostreams/write.hpp>
  20. #include <boost/throw_exception.hpp>
  21. // Must come last.
  22. #include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
  23. namespace boost { namespace iostreams {
  24. namespace detail {
  25. template<typename T>
  26. struct read_write_if_impl;
  27. template<typename T>
  28. struct seek_if_impl;
  29. } // End namespace detail.
  30. template<typename T>
  31. typename int_type_of<T>::type get_if(T& t)
  32. {
  33. typedef typename detail::dispatch<T, input, output>::type tag;
  34. return detail::read_write_if_impl<tag>::get(t);
  35. }
  36. template<typename T>
  37. inline std::streamsize
  38. read_if(T& t, typename char_type_of<T>::type* s, std::streamsize n)
  39. {
  40. typedef typename detail::dispatch<T, input, output>::type tag;
  41. return detail::read_write_if_impl<tag>::read(t, s, n);
  42. }
  43. template<typename T>
  44. bool put_if(T& t, typename char_type_of<T>::type c)
  45. {
  46. typedef typename detail::dispatch<T, output, input>::type tag;
  47. return detail::read_write_if_impl<tag>::put(t, c);
  48. }
  49. template<typename T>
  50. inline std::streamsize write_if
  51. (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
  52. {
  53. typedef typename detail::dispatch<T, output, input>::type tag;
  54. return detail::read_write_if_impl<tag>::write(t, s, n);
  55. }
  56. template<typename T>
  57. inline std::streampos
  58. seek_if( T& t, stream_offset off, BOOST_IOS::seekdir way,
  59. BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
  60. {
  61. using namespace detail;
  62. typedef typename dispatch<T, random_access, any_tag>::type tag;
  63. return seek_if_impl<tag>::seek(t, off, way, which);
  64. }
  65. namespace detail {
  66. //------------------Specializations of read_write_if_impl---------------------//
  67. template<>
  68. struct read_write_if_impl<input> {
  69. template<typename T>
  70. static typename int_type_of<T>::type get(T& t)
  71. { return iostreams::get(t); }
  72. template<typename T>
  73. static std::streamsize
  74. read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
  75. { return iostreams::read(t, s, n); }
  76. template<typename T>
  77. static bool put(T&, typename char_type_of<T>::type)
  78. { boost::throw_exception(cant_write());
  79. BOOST_IOSTREAMS_UNREACHABLE_RETURN(false) }
  80. template<typename T>
  81. static std::streamsize
  82. write(T&, const typename char_type_of<T>::type*, std::streamsize)
  83. { boost::throw_exception(cant_write());
  84. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  85. };
  86. template<>
  87. struct read_write_if_impl<output> {
  88. template<typename T>
  89. static typename int_type_of<T>::type get(T&)
  90. { boost::throw_exception(cant_read());
  91. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  92. template<typename T>
  93. static std::streamsize
  94. read(T&, typename char_type_of<T>::type*, std::streamsize)
  95. { boost::throw_exception(cant_read());
  96. BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
  97. template<typename T>
  98. static bool put(T& t, typename char_type_of<T>::type c)
  99. { return iostreams::put(t, c); }
  100. template<typename T>
  101. static std::streamsize
  102. write( T& t, const typename char_type_of<T>::type* s,
  103. std::streamsize n )
  104. { return iostreams::write(t, s, n); }
  105. };
  106. //------------------Specializations of seek_if_impl---------------------------//
  107. template<>
  108. struct seek_if_impl<random_access> {
  109. template<typename T>
  110. static std::streampos
  111. seek( T& t, stream_offset off, BOOST_IOS::seekdir way,
  112. BOOST_IOS::openmode which )
  113. { return iostreams::seek(t, off, way, which); }
  114. };
  115. template<>
  116. struct seek_if_impl<any_tag> {
  117. template<typename T>
  118. static std::streampos
  119. seek(T&, stream_offset, BOOST_IOS::seekdir, BOOST_IOS::openmode)
  120. { boost::throw_exception(cant_seek());
  121. BOOST_IOSTREAMS_UNREACHABLE_RETURN(std::streampos()) }
  122. };
  123. } // End namespace detail.
  124. } } // End namespaces iostreams, boost.
  125. #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
  126. #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED