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