]> git.lyx.org Git - lyx.git/blob - boost/boost/iostreams/close.hpp
Replace gzstream by boost::iostreams::gzip_(de)compressor: by Bo Peng (ben.bob@gmail...
[lyx.git] / boost / boost / iostreams / close.hpp
1 // (C) Copyright Jonathan Turkanis 2003.
2 // Distributed under the Boost Software License, Version 1.0. (See accompanying
3 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
4
5 // See http://www.boost.org/libs/iostreams for documentation.
6
7 #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
8 #define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
9
10 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
11 # pragma once
12 #endif
13
14 #include <boost/config.hpp>  // DEDUCED_TYPENAME, MSVC.
15 #include <boost/detail/workaround.hpp>
16 #include <boost/iostreams/categories.hpp>
17 #include <boost/iostreams/flush.hpp>
18 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
19 #include <boost/iostreams/detail/wrap_unwrap.hpp>
20 #include <boost/iostreams/operations_fwd.hpp>
21 #include <boost/iostreams/traits.hpp>
22 #include <boost/mpl/identity.hpp>
23 #include <boost/mpl/if.hpp>
24 #include <boost/type_traits/is_convertible.hpp>
25
26 // Must come last.
27 #include <boost/iostreams/detail/config/disable_warnings.hpp>
28
29 #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-----------------------------------//
30 # include <boost/iostreams/detail/vc6/close.hpp>
31 #else // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //--------------------------//
32
33 namespace boost { namespace iostreams {
34
35 namespace detail {
36
37 template<typename T>
38 struct close_impl;
39
40 } // End namespace detail.
41
42 template<typename T>
43 void close(T& t, BOOST_IOS::openmode which)
44 { detail::close_impl<T>::close(detail::unwrap(t), which); }
45
46 template<typename T, typename Sink>
47 void close(T& t, Sink& snk, BOOST_IOS::openmode which)
48 { detail::close_impl<T>::close(detail::unwrap(t), snk, which); }
49
50 namespace detail {
51
52 //------------------Definition of close_impl----------------------------------//
53
54 template<typename T>
55 struct close_tag {
56     typedef typename category_of<T>::type category;
57     typedef typename
58             mpl::eval_if<
59                 is_convertible<category, closable_tag>,
60                 mpl::if_<
61                     mpl::or_<
62                         is_convertible<category, two_sequence>,
63                         is_convertible<category, dual_use>
64                     >,
65                     two_sequence,
66                     closable_tag
67                 >,
68                 mpl::identity<any_tag>
69             >::type type;
70 };
71
72 template<typename T>
73 struct close_impl
74     : mpl::if_<
75           is_custom<T>,
76           operations<T>,
77           close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
78       >::type
79     { };
80
81 template<>
82 struct close_impl<any_tag> {
83     template<typename T>
84     static void close(T& t, BOOST_IOS::openmode which)
85     {
86         if ((which & BOOST_IOS::out) != 0)
87             iostreams::flush(t);
88     }
89
90     template<typename T, typename Sink>
91     static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
92     {
93         if ((which & BOOST_IOS::out) != 0) {
94             non_blocking_adapter<Sink> nb(snk);
95             iostreams::flush(t, nb);
96         }
97     }
98 };
99
100 #include <boost/iostreams/detail/config/disable_warnings.hpp> // Borland.
101 template<>
102 struct close_impl<closable_tag> {
103     template<typename T>
104     static void close(T& t, BOOST_IOS::openmode which)
105     {
106         typedef typename category_of<T>::type category;
107         const bool in =  is_convertible<category, input>::value &&
108                         !is_convertible<category, output>::value;
109         if (in == ((which & BOOST_IOS::in) != 0))
110             t.close();
111     }
112     template<typename T, typename Sink>
113     static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
114     {
115         typedef typename category_of<T>::type category;
116         const bool in =  is_convertible<category, input>::value &&
117                         !is_convertible<category, output>::value;
118         if (in == ((which & BOOST_IOS::in) != 0)) {
119             non_blocking_adapter<Sink> nb(snk);
120             t.close(nb);
121         }
122     }
123 };
124
125 template<>
126 struct close_impl<two_sequence> {
127     template<typename T>
128     static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
129     template<typename T, typename Sink>
130     static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
131     {
132         non_blocking_adapter<Sink> nb(snk);
133         t.close(nb, which);
134     }
135 };
136
137 } // End namespace detail.
138
139 } } // End namespaces iostreams, boost.
140
141 #endif // #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) //-------------------------//
142
143 #include <boost/iostreams/detail/config/enable_warnings.hpp>
144
145 #endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED