Ugly, not-to-be-pushed sucking in of all of Boost to get windows to work.
[dyninst.git] / external / boost / iostreams / detail / vc6 / close.hpp
1 // (C) Copyright Jonathan Turkanis 2005.
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 namespace boost { namespace iostreams {
8
9 namespace detail {
10
11 template<typename T>
12 struct close_impl;
13
14 } // End namespace detail.
15
16 template<typename T>
17 void close(T& t, BOOST_IOS::openmode which)
18 {
19     typedef typename detail::unwrapped_type<T>::type unwrapped;
20     detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), which);
21 }
22
23 template<typename T, typename Sink>
24 void close(T& t, Sink& snk, BOOST_IOS::openmode which)
25 {
26     typedef typename detail::unwrapped_type<T>::type unwrapped;
27     detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), snk, which);
28 }
29
30 namespace detail {
31
32 //------------------Definition of close_impl----------------------------------//
33
34 template<typename T>
35 struct close_tag {
36     typedef typename category_of<T>::type category;
37     typedef typename
38             mpl::eval_if<
39                 is_convertible<category, closable_tag>,
40                 mpl::if_<
41                     mpl::or_<
42                         is_convertible<category, two_sequence>,
43                         is_convertible<category, dual_use>
44                     >,
45                     two_sequence,
46                     closable_tag
47                 >,
48                 mpl::identity<any_tag>
49             >::type type;
50 };
51
52 template<typename T>
53 struct close_impl
54     : mpl::if_<
55           is_custom<T>,
56           operations<T>,
57           close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
58       >::type
59     { };
60
61 template<>
62 struct close_impl<any_tag> {
63     template<typename T>
64     struct inner {
65         static void close(T& t, BOOST_IOS::openmode which)
66         {
67             if ((which & BOOST_IOS::out) != 0)
68                 iostreams::flush(t);
69         }
70
71         template<typename Sink>
72         static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
73         {
74             if ((which & BOOST_IOS::out) != 0) {
75                 non_blocking_adapter<Sink> nb(snk);
76                 iostreams::flush(t, nb);
77             }
78         }
79     };
80 };
81
82 template<>
83 struct close_impl<closable_tag> {
84     template<typename T>
85     struct inner {
86         static void close(T& t, BOOST_IOS::openmode which)
87         {
88             typedef typename category_of<T>::type category;
89             const bool in =  is_convertible<category, input>::value &&
90                             !is_convertible<category, output>::value;
91             if (in == ((which & BOOST_IOS::in) != 0))
92                 t.close();
93         }
94         template<typename Sink>
95         static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
96         {
97             typedef typename category_of<T>::type category;
98             const bool in =  is_convertible<category, input>::value &&
99                             !is_convertible<category, output>::value;
100             if (in == ((which & BOOST_IOS::in) != 0)) {
101                 non_blocking_adapter<Sink> nb(snk);
102                 t.close(nb);
103             }
104         }
105     };
106 };
107
108 template<>
109 struct close_impl<two_sequence> {
110     template<typename T>
111     struct inner {
112         static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
113
114         template<typename Sink>
115         static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
116         {
117             non_blocking_adapter<Sink> nb(snk);
118             t.close(nb, which);
119         }
120     };
121 };
122
123 } // End namespace detail.
124
125 } } // End namespaces iostreams, boost.