]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/iostreams/close.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / iostreams / close.hpp
CommitLineData
7c673cae
FG
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
6// See http://www.boost.org/libs/iostreams for documentation.
7
8#ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
9#define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
10
11#if defined(_MSC_VER)
12# pragma once
13#endif
14
15#include <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
16#include <boost/detail/workaround.hpp>
17#include <boost/iostreams/categories.hpp>
18#include <boost/iostreams/flush.hpp>
19#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
20#include <boost/iostreams/detail/ios.hpp> // BOOST_IOS
21#include <boost/iostreams/detail/select.hpp>
22#include <boost/iostreams/detail/wrap_unwrap.hpp>
23#include <boost/iostreams/operations_fwd.hpp>
24#include <boost/iostreams/traits.hpp>
25#include <boost/mpl/identity.hpp>
26#include <boost/mpl/if.hpp>
27#include <boost/type_traits/is_convertible.hpp>
28#include <boost/type_traits/is_integral.hpp>
29#include <boost/type_traits/remove_cv.hpp>
30#include <boost/type_traits/remove_reference.hpp>
31
32// Must come last.
33#include <boost/iostreams/detail/config/disable_warnings.hpp>
34
35namespace boost { namespace iostreams {
36
37template<typename T>
38void close(T& t);
39
40template<typename T>
41void close(T& t, BOOST_IOS::openmode which);
42
43template<typename T, typename Sink>
44void close(T& t, Sink& snk, BOOST_IOS::openmode which);
45
46namespace detail {
47
48template<typename T>
49void close_all(T& t)
50{
51 try {
52 boost::iostreams::close(t, BOOST_IOS::in);
53 } catch (...) {
54 try {
55 boost::iostreams::close(t, BOOST_IOS::out);
56 } catch (...) { }
57 throw;
58 }
59 boost::iostreams::close(t, BOOST_IOS::out);
60}
61
62template<typename T, typename Sink>
63void close_all(T& t, Sink& snk)
64{
65 try {
66 boost::iostreams::close(t, snk, BOOST_IOS::in);
67 } catch (...) {
68 try {
69 boost::iostreams::close(t, snk, BOOST_IOS::out);
70 } catch (...) { }
71 throw;
72 }
73 boost::iostreams::close(t, snk, BOOST_IOS::out);
74}
75
76} // End namespace detail.
77
78} } // End namespaces iostreams, boost.
79
80namespace boost { namespace iostreams {
81
82namespace detail {
83
84template<typename T>
85struct close_impl;
86
87} // End namespace detail.
88
89template<typename T>
90void close(T& t) { detail::close_all(t); }
91
92template<typename T>
93void close(T& t, BOOST_IOS::openmode which)
94{
95#ifdef BOOST_IOSTREAMS_STRICT
96 BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out);
97#else
98 if (which == (BOOST_IOS::in | BOOST_IOS::out)) {
99 detail::close_all(t);
100 return;
101 }
102#endif
103 detail::close_impl<T>::close(detail::unwrap(t), which);
104}
105
106template<typename T, typename Sink>
107void close(T& t, Sink& snk, BOOST_IOS::openmode which)
108{
109#ifdef BOOST_IOSTREAMS_STRICT
110 BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out);
111#else
112 if (which == (BOOST_IOS::in | BOOST_IOS::out)) {
113 detail::close_all(t, snk);
114 return;
115 }
116#endif
117 detail::close_impl<T>::close(detail::unwrap(t), snk, which);
118}
119
120namespace detail {
121
122//------------------Definition of close_impl----------------------------------//
123
124struct close_boost_stream { };
125struct close_filtering_stream { };
126
127template<typename T>
128struct close_tag {
129 typedef typename category_of<T>::type category;
130 typedef typename detail::unwrapped_type<T>::type unwrapped;
131 typedef typename
132 iostreams::select<
133 mpl::not_< is_convertible<category, closable_tag> >,
134 any_tag,
135 mpl::or_<
136 is_boost_stream<unwrapped>,
137 is_boost_stream_buffer<unwrapped>
138 >,
139 close_boost_stream,
140 mpl::or_<
141 is_filtering_stream<unwrapped>,
142 is_filtering_streambuf<unwrapped>
143 >,
144 close_filtering_stream,
145 mpl::or_<
146 is_convertible<category, two_sequence>,
147 is_convertible<category, dual_use>
148 >,
149 two_sequence,
150 else_,
151 closable_tag
152 >::type type;
153};
154
155template<typename T>
156struct close_impl
157 : mpl::if_<
158 is_custom<T>,
159 operations<T>,
160 close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
161 >::type
162 { };
163
164template<>
165struct close_impl<any_tag> {
166 template<typename T>
167 static void close(T& t, BOOST_IOS::openmode which)
168 {
169 if (which == BOOST_IOS::out)
170 iostreams::flush(t);
171 }
172
173 template<typename T, typename Sink>
174 static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
175 {
176 if (which == BOOST_IOS::out) {
177 non_blocking_adapter<Sink> nb(snk);
178 iostreams::flush(t, nb);
179 }
180 }
181};
182
183template<>
184struct close_impl<close_boost_stream> {
185 template<typename T>
186 static void close(T& t)
187 {
188 t.close();
189 }
190 template<typename T>
191 static void close(T& t, BOOST_IOS::openmode which)
192 {
193 if (which == BOOST_IOS::out)
194 t.close();
195 }
196};
197
198template<>
199struct close_impl<close_filtering_stream> {
200 template<typename T>
201 static void close(T& t, BOOST_IOS::openmode which)
202 {
203 typedef typename category_of<T>::type category;
204 const bool in = is_convertible<category, input>::value &&
205 !is_convertible<category, output>::value;
206 if (in == (which == BOOST_IOS::in) && t.is_complete())
207 t.pop();
208 }
209};
210
211template<>
212struct close_impl<closable_tag> {
213 template<typename T>
214 static void close(T& t, BOOST_IOS::openmode which)
215 {
216 typedef typename category_of<T>::type category;
217 const bool in = is_convertible<category, input>::value &&
218 !is_convertible<category, output>::value;
219 if (in == (which == BOOST_IOS::in))
220 t.close();
221 }
222 template<typename T, typename Sink>
223 static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
224 {
225 typedef typename category_of<T>::type category;
226 const bool in = is_convertible<category, input>::value &&
227 !is_convertible<category, output>::value;
228 if (in == (which == BOOST_IOS::in)) {
229 non_blocking_adapter<Sink> nb(snk);
230 t.close(nb);
231 }
232 }
233};
234
235template<>
236struct close_impl<two_sequence> {
237 template<typename T>
238 static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
239 template<typename T, typename Sink>
240 static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
241 {
242 non_blocking_adapter<Sink> nb(snk);
243 t.close(nb, which);
244 }
245};
246
247} // End namespace detail.
248
249} } // End namespaces iostreams, boost.
250
251#include <boost/iostreams/detail/config/enable_warnings.hpp>
252
253#endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED