sl@0: // (C) Copyright Jonathan Turkanis 2005.
sl@0: // Distributed under the Boost Software License, Version 1.0. (See accompanying
sl@0: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
sl@0: 
sl@0: // See http://www.boost.org/libs/iostreams for documentation.
sl@0: 
sl@0: // Contains implementations of get, read, put, write and seek which
sl@0: // check a device's mode at runtime instead of compile time.
sl@0: 
sl@0: #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
sl@0: #define BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
sl@0: 
sl@0: #include <boost/iostreams/categories.hpp>
sl@0: #include <boost/iostreams/detail/dispatch.hpp>
sl@0: #include <boost/iostreams/detail/error.hpp>
sl@0: #include <boost/iostreams/get.hpp>
sl@0: #include <boost/iostreams/put.hpp>
sl@0: #include <boost/iostreams/read.hpp>
sl@0: #include <boost/iostreams/seek.hpp>
sl@0: #include <boost/iostreams/traits.hpp>
sl@0: #include <boost/iostreams/write.hpp>
sl@0: 
sl@0: // Must come last.
sl@0: #include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
sl@0: 
sl@0: namespace boost { namespace iostreams {
sl@0: 
sl@0: namespace detail {
sl@0: 
sl@0: template<typename T> 
sl@0: struct read_write_if_impl;
sl@0: 
sl@0: template<typename T> 
sl@0: struct seek_if_impl;
sl@0: 
sl@0: } // End namespace detail.
sl@0: 
sl@0: template<typename T>
sl@0: typename int_type_of<T>::type get_if(T& t)
sl@0: { 
sl@0:     typedef typename detail::dispatch<T, input, output>::type tag;
sl@0:     return detail::read_write_if_impl<tag>::get(t);
sl@0: }
sl@0: 
sl@0: template<typename T>
sl@0: inline std::streamsize
sl@0: read_if(T& t, typename char_type_of<T>::type* s, std::streamsize n)
sl@0: { 
sl@0:     typedef typename detail::dispatch<T, input, output>::type tag;
sl@0:     return detail::read_write_if_impl<tag>::read(t, s, n);
sl@0: }
sl@0: 
sl@0: template<typename T>
sl@0: bool put_if(T& t, typename char_type_of<T>::type c)
sl@0: { 
sl@0:     typedef typename detail::dispatch<T, output, input>::type tag;
sl@0:     return detail::read_write_if_impl<tag>::put(t, c);
sl@0: }
sl@0: 
sl@0: template<typename T>
sl@0: inline std::streamsize write_if
sl@0:     (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
sl@0: { 
sl@0:     typedef typename detail::dispatch<T, output, input>::type tag;
sl@0:     return detail::read_write_if_impl<tag>::write(t, s, n);
sl@0: }
sl@0: 
sl@0: template<typename T>
sl@0: inline std::streampos
sl@0: seek_if( T& t, stream_offset off, BOOST_IOS::seekdir way, 
sl@0:          BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out )
sl@0: { 
sl@0:     using namespace detail;
sl@0:     typedef typename dispatch<T, random_access, any_tag>::type tag;
sl@0:     return seek_if_impl<tag>::seek(t, off, way, which);
sl@0: }
sl@0: 
sl@0: namespace detail {
sl@0: 
sl@0: //------------------Specializations of read_write_if_impl---------------------//
sl@0: 
sl@0: template<>
sl@0: struct read_write_if_impl<input> {
sl@0:     template<typename T>
sl@0:     static typename int_type_of<T>::type get(T& t)
sl@0:     { return iostreams::get(t); }
sl@0: 
sl@0:     template<typename T>
sl@0:     static std::streamsize
sl@0:     read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
sl@0:     { return iostreams::read(t, s, n); }
sl@0: 
sl@0:     template<typename T>
sl@0:     static bool put(T&, typename char_type_of<T>::type)
sl@0:     { throw cant_write(); }
sl@0: 
sl@0:     template<typename T>
sl@0:     static std::streamsize 
sl@0:     write(T&, const typename char_type_of<T>::type*, std::streamsize)
sl@0:     { throw cant_write(); }
sl@0: };
sl@0: 
sl@0: template<>
sl@0: struct read_write_if_impl<output> {
sl@0:     template<typename T>
sl@0:     static typename int_type_of<T>::type get(T&)
sl@0:     { throw cant_read(); }
sl@0: 
sl@0:     template<typename T>
sl@0:     static std::streamsize
sl@0:     read(T&, typename char_type_of<T>::type*, std::streamsize)
sl@0:     { throw cant_read(); }
sl@0: 
sl@0:     template<typename T>
sl@0:     static bool put(T& t, typename char_type_of<T>::type c)
sl@0:     { return iostreams::put(t, c); }
sl@0: 
sl@0:     template<typename T>
sl@0:     static std::streamsize 
sl@0:     write( T& t, const typename char_type_of<T>::type* s, 
sl@0:            std::streamsize n )
sl@0:     { return iostreams::write(t, s, n); }
sl@0: };
sl@0: 
sl@0: //------------------Specializations of seek_if_impl---------------------------//
sl@0: 
sl@0: template<>
sl@0: struct seek_if_impl<random_access> {
sl@0:     template<typename T>
sl@0:     static stream_offset 
sl@0:     seek( T& t, stream_offset off, BOOST_IOS::seekdir way, 
sl@0:           BOOST_IOS::openmode which )
sl@0:     { return iostreams::seek(t, off, way, which); }
sl@0: };
sl@0: 
sl@0: template<>
sl@0: struct seek_if_impl<any_tag> {
sl@0:     template<typename T>
sl@0:     static stream_offset 
sl@0:     seek(T&, stream_offset, BOOST_IOS::seekdir, BOOST_IOS::openmode)
sl@0:     { throw cant_seek(); }
sl@0: };
sl@0: 
sl@0: } // End namespace detail.
sl@0: 
sl@0: } } // End namespaces iostreams, boost.
sl@0: 
sl@0: #include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
sl@0: 
sl@0: #endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED