Chris@16
|
1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
|
Chris@16
|
2 // (C) Copyright 2005-2007 Jonathan Turkanis
|
Chris@16
|
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
|
Chris@16
|
5
|
Chris@16
|
6 // See http://www.boost.org/libs/iostreams for documentation.
|
Chris@16
|
7
|
Chris@16
|
8 namespace boost { namespace iostreams {
|
Chris@16
|
9
|
Chris@16
|
10 namespace detail {
|
Chris@16
|
11
|
Chris@16
|
12 template<typename T>
|
Chris@16
|
13 struct close_impl;
|
Chris@16
|
14
|
Chris@16
|
15 } // End namespace detail.
|
Chris@16
|
16
|
Chris@16
|
17 template<typename T>
|
Chris@16
|
18 void close(T& t) { detail::close_all(t); }
|
Chris@16
|
19
|
Chris@16
|
20 template<typename T>
|
Chris@16
|
21 void close(T& t, BOOST_IOS::openmode which)
|
Chris@16
|
22 {
|
Chris@16
|
23 typedef typename detail::unwrapped_type<T>::type unwrapped;
|
Chris@16
|
24 detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), which);
|
Chris@16
|
25 }
|
Chris@16
|
26
|
Chris@16
|
27 template<typename T, typename Sink>
|
Chris@16
|
28 void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
Chris@16
|
29 {
|
Chris@16
|
30 typedef typename detail::unwrapped_type<T>::type unwrapped;
|
Chris@16
|
31 detail::close_impl<T>::inner<unwrapped>::close(detail::unwrap(t), snk, which);
|
Chris@16
|
32 }
|
Chris@16
|
33
|
Chris@16
|
34 namespace detail {
|
Chris@16
|
35
|
Chris@16
|
36 //------------------Definition of close_impl----------------------------------//
|
Chris@16
|
37
|
Chris@16
|
38 template<typename T>
|
Chris@16
|
39 struct close_tag {
|
Chris@16
|
40 typedef typename category_of<T>::type category;
|
Chris@16
|
41 typedef typename
|
Chris@16
|
42 mpl::eval_if<
|
Chris@16
|
43 is_convertible<category, closable_tag>,
|
Chris@16
|
44 mpl::if_<
|
Chris@16
|
45 mpl::or_<
|
Chris@16
|
46 is_convertible<category, two_sequence>,
|
Chris@16
|
47 is_convertible<category, dual_use>
|
Chris@16
|
48 >,
|
Chris@16
|
49 two_sequence,
|
Chris@16
|
50 closable_tag
|
Chris@16
|
51 >,
|
Chris@16
|
52 mpl::identity<any_tag>
|
Chris@16
|
53 >::type type;
|
Chris@16
|
54 };
|
Chris@16
|
55
|
Chris@16
|
56 template<typename T>
|
Chris@16
|
57 struct close_impl
|
Chris@16
|
58 : mpl::if_<
|
Chris@16
|
59 is_custom<T>,
|
Chris@16
|
60 operations<T>,
|
Chris@16
|
61 close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
|
Chris@16
|
62 >::type
|
Chris@16
|
63 { };
|
Chris@16
|
64
|
Chris@16
|
65 template<>
|
Chris@16
|
66 struct close_impl<any_tag> {
|
Chris@16
|
67 template<typename T>
|
Chris@16
|
68 struct inner {
|
Chris@16
|
69 static void close(T& t, BOOST_IOS::openmode which)
|
Chris@16
|
70 {
|
Chris@16
|
71 if (which == BOOST_IOS::out)
|
Chris@16
|
72 iostreams::flush(t);
|
Chris@16
|
73 }
|
Chris@16
|
74
|
Chris@16
|
75 template<typename Sink>
|
Chris@16
|
76 static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
Chris@16
|
77 {
|
Chris@16
|
78 if (which == BOOST_IOS::out) {
|
Chris@16
|
79 non_blocking_adapter<Sink> nb(snk);
|
Chris@16
|
80 iostreams::flush(t, nb);
|
Chris@16
|
81 }
|
Chris@16
|
82 }
|
Chris@16
|
83 };
|
Chris@16
|
84 };
|
Chris@16
|
85
|
Chris@16
|
86 template<>
|
Chris@16
|
87 struct close_impl<closable_tag> {
|
Chris@16
|
88 template<typename T>
|
Chris@16
|
89 struct inner {
|
Chris@16
|
90 static void close(T& t, BOOST_IOS::openmode which)
|
Chris@16
|
91 {
|
Chris@16
|
92 typedef typename category_of<T>::type category;
|
Chris@16
|
93 const bool in = is_convertible<category, input>::value &&
|
Chris@16
|
94 !is_convertible<category, output>::value;
|
Chris@16
|
95 if (in == (which == BOOST_IOS::in))
|
Chris@16
|
96 t.close();
|
Chris@16
|
97 }
|
Chris@16
|
98 template<typename Sink>
|
Chris@16
|
99 static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
Chris@16
|
100 {
|
Chris@16
|
101 typedef typename category_of<T>::type category;
|
Chris@16
|
102 const bool in = is_convertible<category, input>::value &&
|
Chris@16
|
103 !is_convertible<category, output>::value;
|
Chris@16
|
104 if (in == (which == BOOST_IOS::in)) {
|
Chris@16
|
105 non_blocking_adapter<Sink> nb(snk);
|
Chris@16
|
106 t.close(nb);
|
Chris@16
|
107 }
|
Chris@16
|
108 }
|
Chris@16
|
109 };
|
Chris@16
|
110 };
|
Chris@16
|
111
|
Chris@16
|
112 template<>
|
Chris@16
|
113 struct close_impl<two_sequence> {
|
Chris@16
|
114 template<typename T>
|
Chris@16
|
115 struct inner {
|
Chris@16
|
116 static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
|
Chris@16
|
117
|
Chris@16
|
118 template<typename Sink>
|
Chris@16
|
119 static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
Chris@16
|
120 {
|
Chris@16
|
121 non_blocking_adapter<Sink> nb(snk);
|
Chris@16
|
122 t.close(nb, which);
|
Chris@16
|
123 }
|
Chris@16
|
124 };
|
Chris@16
|
125 };
|
Chris@16
|
126
|
Chris@16
|
127 } // End namespace detail.
|
Chris@16
|
128
|
Chris@16
|
129 } } // End namespaces iostreams, boost.
|