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

source code of boost/boost/iostreams/checked_operations.hpp