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 write_device_impl;
|
---|
13 |
|
---|
14 | template<typename T>
|
---|
15 | struct write_filter_impl;
|
---|
16 |
|
---|
17 | } // End namespace detail.
|
---|
18 |
|
---|
19 | template<typename T>
|
---|
20 | bool put(T& t, typename char_type_of<T>::type c)
|
---|
21 | {
|
---|
22 | typedef typename detail::unwrapped_type<T>::type unwrapped;
|
---|
23 | return detail::write_device_impl<T>::inner<unwrapped>::put(detail::unwrap(t), c);
|
---|
24 | }
|
---|
25 |
|
---|
26 | template<typename T>
|
---|
27 | inline std::streamsize write
|
---|
28 | (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
|
---|
29 | {
|
---|
30 | typedef typename detail::unwrapped_type<T>::type unwrapped;
|
---|
31 | return detail::write_device_impl<T>::inner<unwrapped>::write(detail::unwrap(t), s, n);
|
---|
32 | }
|
---|
33 |
|
---|
34 | template<typename T, typename Sink>
|
---|
35 | inline std::streamsize
|
---|
36 | write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
|
---|
37 | std::streamsize n )
|
---|
38 | {
|
---|
39 | typedef typename detail::unwrapped_type<T>::type unwrapped;
|
---|
40 | return detail::write_filter_impl<T>::inner<unwrapped>::write(detail::unwrap(t), snk, s, n);
|
---|
41 | }
|
---|
42 |
|
---|
43 | namespace detail {
|
---|
44 |
|
---|
45 | //------------------Definition of write_device_impl---------------------------//
|
---|
46 |
|
---|
47 | template<typename T>
|
---|
48 | struct write_device_impl
|
---|
49 | : mpl::if_<
|
---|
50 | is_custom<T>,
|
---|
51 | operations<T>,
|
---|
52 | write_device_impl<
|
---|
53 | BOOST_DEDUCED_TYPENAME
|
---|
54 | dispatch<
|
---|
55 | T, ostream_tag, streambuf_tag, output
|
---|
56 | >::type
|
---|
57 | >
|
---|
58 | >::type
|
---|
59 | { };
|
---|
60 |
|
---|
61 | template<>
|
---|
62 | struct write_device_impl<ostream_tag> {
|
---|
63 | template<typename T>
|
---|
64 | struct inner {
|
---|
65 | static bool put(T& t, typename char_type_of<T>::type c)
|
---|
66 | {
|
---|
67 | typedef typename char_type_of<T>::type char_type;
|
---|
68 | typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type;
|
---|
69 | return !traits_type::eq_int_type( t.rdbuf()->s.sputc(),
|
---|
70 | traits_type::eof() );
|
---|
71 | }
|
---|
72 |
|
---|
73 | static std::streamsize write
|
---|
74 | (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
|
---|
75 | { return t.rdbuf()->sputn(s, n); }
|
---|
76 | };
|
---|
77 | };
|
---|
78 |
|
---|
79 | template<>
|
---|
80 | struct write_device_impl<streambuf_tag> {
|
---|
81 | template<typename T>
|
---|
82 | struct inner {
|
---|
83 | static bool put(T& t, typename char_type_of<T>::type c)
|
---|
84 | {
|
---|
85 | typedef typename char_type_of<T>::type char_type;
|
---|
86 | typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type;
|
---|
87 | return !traits_type::eq_int_type(t.sputc(c), traits_type::eof());
|
---|
88 | }
|
---|
89 |
|
---|
90 | template<typename T>
|
---|
91 | static std::streamsize write
|
---|
92 | (T& t, const typename char_type_of<T>::type* s, std::streamsize n)
|
---|
93 | { return t.sputn(s, n); }
|
---|
94 | };
|
---|
95 | };
|
---|
96 |
|
---|
97 | template<>
|
---|
98 | struct write_device_impl<output> {
|
---|
99 | template<typename T>
|
---|
100 | struct inner {
|
---|
101 | static bool put(T& t, typename char_type_of<T>::type c)
|
---|
102 | { return t.write(&c, 1) == 1; }
|
---|
103 |
|
---|
104 | template<typename T>
|
---|
105 | static std::streamsize
|
---|
106 | write(T& t, const typename char_type_of<T>::type* s, std::streamsize n)
|
---|
107 | { return t.write(s, n); }
|
---|
108 | };
|
---|
109 | };
|
---|
110 |
|
---|
111 | //------------------Definition of write_filter_impl---------------------------//
|
---|
112 |
|
---|
113 | template<typename T>
|
---|
114 | struct write_filter_impl
|
---|
115 | : mpl::if_<
|
---|
116 | is_custom<T>,
|
---|
117 | operations<T>,
|
---|
118 | write_filter_impl<
|
---|
119 | BOOST_DEDUCED_TYPENAME
|
---|
120 | dispatch<
|
---|
121 | T, multichar_tag, any_tag
|
---|
122 | >::type
|
---|
123 | >
|
---|
124 | >::type
|
---|
125 | { };
|
---|
126 |
|
---|
127 | template<>
|
---|
128 | struct write_filter_impl<multichar_tag> {
|
---|
129 | template<typename T>
|
---|
130 | struct inner {
|
---|
131 | template<typename Sink>
|
---|
132 | static std::streamsize
|
---|
133 | write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
|
---|
134 | std::streamsize n )
|
---|
135 | { return t.write(snk, s, n); }
|
---|
136 | };
|
---|
137 | };
|
---|
138 |
|
---|
139 | template<>
|
---|
140 | struct write_filter_impl<any_tag> {
|
---|
141 | template<typename T>
|
---|
142 | struct inner {
|
---|
143 | template<typename Sink>
|
---|
144 | static std::streamsize
|
---|
145 | write( T& t, Sink& snk, const typename char_type_of<T>::type* s,
|
---|
146 | std::streamsize n )
|
---|
147 | {
|
---|
148 | for (std::streamsize off = 0; off < n; ++off)
|
---|
149 | if (!t.put(snk, s[off]))
|
---|
150 | return off;
|
---|
151 | return n;
|
---|
152 | }
|
---|
153 | };
|
---|
154 | };
|
---|
155 |
|
---|
156 | } // End namespace detail.
|
---|
157 |
|
---|
158 | } } // End namespaces iostreams, boost.
|
---|