Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_ioinsert.cc
Go to the documentation of this file.
1
30#include <rw/_select.h>
31
32
34
35
37template <class _CharT, class _Traits, class _NativeType>
38_STD::basic_ostream<_CharT, _Traits>&
39__rw_insert (_STD::basic_ostream<_CharT, _Traits> &__strm,
40 _NativeType __val)
41{
42 const typename _STD::basic_ostream<_CharT, _Traits>::sentry
43 __opfx (__strm);
44
45 _TRY {
46
47 typedef _STD::ostreambuf_iterator<_CharT, _Traits> _Iter;
48 typedef _STD::num_put<_CharT, _Iter> _NumPut;
49
50 if (__opfx && _STD_USE_FACET (_NumPut, __strm.getloc ())
51 .put (_Iter (__strm), __strm, __strm.fill (), __val).failed ()) {
52
53 // this may throw but the exception will just be caught
54 // and rethrown below; this optimizes for the common case
55 // (i.e., success) but pessimizes the case of failure
56 __strm.setstate (_STD::ios_base::badbit);
57 }
58 }
59 _CATCH (...) {
60 __strm.setstate (_STD::ios_base::badbit | _RW::__rw_rethrow);
61 }
62
63 return __strm;
64}
65
66
67// optimized for when stream's char_type is the same
68// as the type of the character string being inserted,
69// i.e., ostream and char* and wostream and wchar_t*
70template <class _CharT, class _Traits>
72__rw_sputn (_STD::basic_ostream<_CharT, _Traits> &__strm,
73 const _CharT *__s, _RWSTD_STREAMSIZE __len, __rw_true_t)
74{
75 _RWSTD_ASSERT (!__len || __len > 0 && 0 != __s);
76
77 if (1 == __len) {
78 typedef typename _Traits::int_type _IntT;
79
80 const _IntT __ic = __strm.rdbuf ()->sputc (*__s);
81
82 return 0 + !_Traits::eq_int_type (_Traits::eof (), __ic);
83 }
84
85 return __strm.rdbuf ()->sputn (__s, __len);
86}
87
88
89// special case for char* insertion into a stream whose
90// char_type is not char (e.g., wostream or user-defined)
91template <class _CharT, class _Traits>
93__rw_sputn (_STD::basic_ostream<_CharT, _Traits> &__strm,
94 const char *__s, _RWSTD_STREAMSIZE __len, __rw_false_t)
95{
96 _RWSTD_ASSERT (!__len || __len > 0 && 0 != __s);
97
98 const _STD::ctype<_CharT>& __ctp =
99 _STD_USE_FACET (_STD::ctype<_CharT>, __strm.getloc ());
100
101 for (_RWSTD_STREAMSIZE __i = 0; __i < __len; ++__i) {
102
103 typedef typename _Traits::int_type _IntT;
104
105 const _IntT __ic = __strm.rdbuf ()->sputc (__ctp.widen (__s [__i]));
106
107 if (_Traits::eq_int_type (__ic, _Traits::eof ()))
108 return __i;
109 }
110
111 return __len;
112}
113
114
116template<class _CharT, class _Traits, class _StringT>
117_STD::basic_ostream<_CharT, _Traits>&
118__rw_insert (_STD::basic_ostream<_CharT, _Traits> &__strm,
119 const _StringT *__s,
120 _RWSTD_STREAMSIZE __len,
121 _RWSTD_STREAMSIZE __width)
122{
123 _RWSTD_ASSERT (0 != __strm.rdbuf ());
124 _RWSTD_ASSERT (0 != __s);
125
126 _STD::ios_base::iostate __err = _STD::ios_base::goodbit;
127
128 // writes out max(len, width) characters, padding appropriately
129 // with the fill character if (len < width);
130 // calls width(0) if and only if the write has been successful
131 // (i.e., will leave it unchanged if sputn fails or throws an
132 // exception)
133
134 _TRY {
135
136 const typename _STD::basic_ostream<_CharT, _Traits>::sentry
137 __opfx (__strm);
138
139 if (__opfx) {
140
141 // compute the number of fill chars to pad with
142 // according to the rules described in 22.2.2.2.2, p19
143 const _RWSTD_STREAMSIZE __pad = __width - __len;
144
145 typedef typename
146 __rw_same_type<_CharT, _StringT>::_C_type _Same;
147
148 if (__pad > 0) {
149 const int __padbits =
150 _STD::ios_base::adjustfield & __strm.flags ();
151
152 // output left padding (output is right-aligned by default)
153 if ( _STD::ios_base::left != __padbits
154 && __pad != __strm._C_pad (__pad)
155 // write out (not necessarily null-terminated) string
156 || __len != __rw_sputn (__strm, __s, __len, _Same ())
157 // output right padding (output is left-aligned)
158 || _STD::ios_base::left == __padbits
159 && __pad != __strm._C_pad (__pad))
160 __err = _STD::ios_base::badbit;
161#ifndef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
162 else
163 __strm.width (0); // reset width only on success
164#else // if defined (_RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE)
165 __strm.width (0); // reset width unconditionally
166#endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
167 }
168 else if (__len == __rw_sputn (__strm, __s, __len, _Same ())) {
169 __strm.width (0); // reset width only on success
170 }
171 else {
172 __err = _STD::ios_base::badbit;
173
174#ifdef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
175 __strm.width (0);
176#endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
177 }
178 }
179 }
180 _CATCH (...) {
181 // set badbit and rethrow the caught exception if badbit
182 // is also set in exceptions()
183 __strm.setstate (_STD::ios_base::badbit | _RW::__rw_rethrow);
184 }
185
186 if (__err) {
187 // set badbit which may throw ios_base::failure
188 __strm.setstate (__err);
189 }
190
191 return __strm;
192}
193
194
195} // namespace __rw
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _STD_USE_FACET(type, arg)
Definition _defs.h:920
#define _RWSTD_STREAMSIZE
Definition _defs.h:762
#define _EXPORT
Definition _defs.h:498
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _CATCH(ex)
Definition _defs.h:851