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.)
6 // See http://www.boost.org/libs/iostreams for documentation.
8 #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
9 #define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
11 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
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>
33 #include <boost/iostreams/detail/config/disable_warnings.hpp>
35 namespace boost
{ namespace iostreams
{
41 void close(T
& t
, BOOST_IOS::openmode which
);
43 template<typename T
, typename Sink
>
44 void close(T
& t
, Sink
& snk
, BOOST_IOS::openmode which
);
52 boost::iostreams::close(t
, BOOST_IOS::in
);
55 boost::iostreams::close(t
, BOOST_IOS::out
);
59 boost::iostreams::close(t
, BOOST_IOS::out
);
62 template<typename T
, typename Sink
>
63 void close_all(T
& t
, Sink
& snk
)
66 boost::iostreams::close(t
, snk
, BOOST_IOS::in
);
69 boost::iostreams::close(t
, snk
, BOOST_IOS::out
);
73 boost::iostreams::close(t
, snk
, BOOST_IOS::out
);
76 } // End namespaces detail.
78 } } // End namespaces iostreams, boost.
80 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------//
81 # include <boost/iostreams/detail/vc6/close.hpp>
82 #else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------//
84 namespace boost
{ namespace iostreams
{
91 } // End namespace detail.
94 void close(T
& t
) { detail::close_all(t
); }
97 void close(T
& t
, BOOST_IOS::openmode which
)
99 #ifdef BOOST_IOSTREAMS_STRICT
100 assert(which
== BOOST_IOS::in
|| which
== BOOST_IOS::out
);
102 if (which
== (BOOST_IOS::in
| BOOST_IOS::out
)) {
103 detail::close_all(t
);
107 detail::close_impl
<T
>::close(detail::unwrap(t
), which
);
110 template<typename T
, typename Sink
>
111 void close(T
& t
, Sink
& snk
, BOOST_IOS::openmode which
)
113 #ifdef BOOST_IOSTREAMS_STRICT
114 assert(which
== BOOST_IOS::in
|| which
== BOOST_IOS::out
);
116 if (which
== (BOOST_IOS::in
| BOOST_IOS::out
)) {
117 detail::close_all(t
, snk
);
121 detail::close_impl
<T
>::close(detail::unwrap(t
), snk
, which
);
126 //------------------Definition of close_impl----------------------------------//
128 struct close_boost_stream
{ };
129 struct close_filtering_stream
{ };
133 typedef typename category_of
<T
>::type category
;
134 typedef typename
detail::unwrapped_type
<T
>::type unwrapped
;
137 mpl::not_
< is_convertible
<category
, closable_tag
> >,
140 is_boost_stream
<unwrapped
>,
141 is_boost_stream_buffer
<unwrapped
>
145 is_filtering_stream
<unwrapped
>,
146 is_filtering_streambuf
<unwrapped
>
148 close_filtering_stream
,
150 is_convertible
<category
, two_sequence
>,
151 is_convertible
<category
, dual_use
>
164 close_impl
<BOOST_DEDUCED_TYPENAME close_tag
<T
>::type
>
169 struct close_impl
<any_tag
> {
171 static void close(T
& t
, BOOST_IOS::openmode which
)
173 if (which
== BOOST_IOS::out
)
177 template<typename T
, typename Sink
>
178 static void close(T
& t
, Sink
& snk
, BOOST_IOS::openmode which
)
180 if (which
== BOOST_IOS::out
) {
181 non_blocking_adapter
<Sink
> nb(snk
);
182 iostreams::flush(t
, nb
);
188 struct close_impl
<close_boost_stream
> {
190 static void close(T
& t
)
195 static void close(T
& t
, BOOST_IOS::openmode which
)
197 if (which
== BOOST_IOS::out
)
203 struct close_impl
<close_filtering_stream
> {
205 static void close(T
& t
, BOOST_IOS::openmode which
)
207 typedef typename category_of
<T
>::type category
;
208 const bool in
= is_convertible
<category
, input
>::value
&&
209 !is_convertible
<category
, output
>::value
;
210 if (in
== (which
== BOOST_IOS::in
) && t
.is_complete())
215 #include <boost/iostreams/detail/config/disable_warnings.hpp> // Borland.
217 struct close_impl
<closable_tag
> {
219 static void close(T
& t
, BOOST_IOS::openmode which
)
221 typedef typename category_of
<T
>::type category
;
222 const bool in
= is_convertible
<category
, input
>::value
&&
223 !is_convertible
<category
, output
>::value
;
224 if (in
== (which
== BOOST_IOS::in
))
227 template<typename T
, typename Sink
>
228 static void close(T
& t
, Sink
& snk
, BOOST_IOS::openmode which
)
230 typedef typename category_of
<T
>::type category
;
231 const bool in
= is_convertible
<category
, input
>::value
&&
232 !is_convertible
<category
, output
>::value
;
233 if (in
== (which
== BOOST_IOS::in
)) {
234 non_blocking_adapter
<Sink
> nb(snk
);
241 struct close_impl
<two_sequence
> {
243 static void close(T
& t
, BOOST_IOS::openmode which
) { t
.close(which
); }
244 template<typename T
, typename Sink
>
245 static void close(T
& t
, Sink
& snk
, BOOST_IOS::openmode which
)
247 non_blocking_adapter
<Sink
> nb(snk
);
252 } // End namespace detail.
254 } } // End namespaces iostreams, boost.
256 #endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------//
258 #include <boost/iostreams/detail/config/enable_warnings.hpp>
260 #endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED