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.
|
---|