source: NonGTP/Boost/boost/iostreams/detail/vc6/close.hpp @ 857

Revision 857, 3.6 KB checked in by igarcia, 18 years ago (diff)
Line 
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
7namespace boost { namespace iostreams {
8
9namespace detail {
10
11template<typename T>
12struct close_impl;
13
14} // End namespace detail.
15
16template<typename T>
17void 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
23template<typename T, typename Sink>
24void 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
30namespace detail {
31
32//------------------Definition of close_impl----------------------------------//
33
34template<typename T>
35struct 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
52template<typename T>
53struct 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
61template<>
62struct 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
82template<>
83struct 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
108template<>
109struct 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.
Note: See TracBrowser for help on using the repository browser.