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