Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_num_put.cc
Go to the documentation of this file.
1
29#include <loc/_locale.h> // for use_facet
30#include <loc/_ctype.h> // for ctype
31
33
34_RWSTD_EXPORT _RWSTD_SIZE_T
35__rw_put_num (char**, _RWSTD_SIZE_T, unsigned, int, _RWSTD_STREAMSIZE,
36 const void*, const char*);
37
38_RWSTD_EXPORT extern const unsigned char
39__rw_digit_map[];
40
41
42template <class _OutputIter>
43inline bool
44__rw_iter_failed (const _OutputIter&) { return false; }
45
46// const commented to resolve ambiguity on MSVC 7.0:
47// error C2667: '__rw_iter_failed' : none of 2 overloads have a best conversion
48template <class _CharT, class _Traits>
49inline bool
50__rw_iter_failed (/*const */_STD::ostreambuf_iterator<_CharT, _Traits> &__it)
51{
52 return __it.failed ();
53}
54
55} // namespace __rw
56
57
59
60
61template <class _CharT, class _OutputIter>
62_RW::__rw_facet_id num_put<_CharT, _OutputIter>::id;
63
64
65template <class _CharT, class _OutputIter /* = ostreambuf_iterator<_CharT> */>
66/* virtual */ num_put<_CharT, _OutputIter>::~num_put ()
67{
68 // no-op
69}
70
71
72template <class _CharT, class _OutputIter /* = ostreambuf_iterator<_CharT> */>
73typename num_put<_CharT, _OutputIter>::iter_type
74num_put<_CharT, _OutputIter>::
75_C_put (iter_type __it, ios_base &__flags, char_type __fill, int __type,
76 const void *__pval) const
77{
78 const numpunct<char_type> &__np =
79 _RWSTD_USE_FACET (numpunct<char_type>, __flags.getloc ());
80
81 char __buf [_RWSTD_DBL_MAX_10_EXP];
82
83 // will grow as necessary and may need to be deleted
84 char *__pbuf = __buf;
85
86 const string __grouping = __np.grouping ();
87 const char* const __grp = __grouping.c_str ();
88 const _RWSTD_STREAMSIZE __prec = __flags.precision ();
89
90 const int __f = __flags.flags ();
91
92 // format value, ignore C++ decimal_point and thousands_sep
93 _RWSTD_SIZE_T __res =
94 _RW::__rw_put_num (&__pbuf, sizeof __buf, __f, __type,
95 __prec, __pval, __grp);
96
97 // for bool values and boolalpha bit set, retrieve the "truth" string
98 basic_string<char_type, char_traits<char_type>, allocator<char_type> >
99 __boolstr;
100
101 if (!__res) {
102 // avoid an IBM VAC++ 7.0 code generation bug that causes
103 // local string objects to get incorrectly destroyed (see
104 // bug #546)
105 // __boolstr = __pval ? __np.truename () : __np.falsename ();
106
107 if (__pval)
108 __boolstr = __np.truename ();
109 else
110 __boolstr = __np.falsename ();
111
112 __res = __boolstr.size ();
113 }
114
115 // number of fill chars to pad with
116 streamsize __pad = __flags.width () - streamsize (__res);
117
118#ifdef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
119
120 // unconditionally reset width before inserting anything
121 // in case the insertion causes an exception to be thrown
122 __flags.width (0);
123
124#endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
125
126 // adjustfield bits (left, internal, or the default right)
127 const int __adj = __f & _RWSTD_IOS_ADJUSTFIELD;
128
129 if (__pad > 0 && !(__adj & (_RWSTD_IOS_LEFT | _RWSTD_IOS_INTERNAL))) {
130
131 // right justify if either no justification or
132 // right justification specified in adjustfield
133
134 for (; __pad--; ++__it)
135 *__it = __fill;
136 }
137
138 const ctype<char_type> &__ctp =
139 _RWSTD_USE_FACET (ctype<char_type>, __flags.getloc ());
140
141 const char *__p = __pbuf;
142
143 if (__pad > 0 && _RWSTD_IOS_INTERNAL == __adj) {
144
145 typedef unsigned char _UChar;
146
147 // internal padding only between the leading "0x"
148 // prefix or the leading sign and the number
149
150 if (43 /* '+' or '-' */ == _RW::__rw_digit_map [_UChar (*__p)])
151 *__it++ = __ctp.widen (*__p++);
152 else if ( '0' == *__p && __res > 2
153 && 33 == /* 'X' */ _RW::__rw_digit_map [_UChar (__p [1])]) {
154 *__it++ = __ctp.widen (*__p++);
155 *__it++ = __ctp.widen (*__p++);
156 }
157
158 // right justify if not internally padded
159 for (; __pad--; ++__it)
160 *__it = __fill;
161 }
162
163 if (__type & _RW::__rw_facet::_C_integral && !*__grp && __prec >= 0) {
164 // optimized for integer output, no grouping
165 for (const char *__end = __pbuf + __res; __p != __end; ++__p, ++__it)
166 *__it = __ctp.widen (*__p);
167 }
168 else if (_RW::__rw_facet::_C_bool == __type) {
169 // boolalpha output
170 for (_RWSTD_SIZE_T __i = 0; __i != __res; ++__i, ++__it)
171 *__it = __boolstr [__i];
172 }
173 else {
174 // all other numeric output
175 for (const char *__end = __pbuf + __res; __p != __end; ++__p, ++__it) {
176 switch (*__p) {
177 // replace either the period or the comma with the
178 // decimal point in case a setlocale() call made by
179 // the program changed the default '.' to ','
180 case '.':
181 case ',': *__it = __np.decimal_point (); break;
182 case ';': *__it = __np.thousands_sep (); break;
183 default: *__it = __ctp.widen (*__p); break;
184 }
185 }
186 }
187
188 // delete if the buffer was dynamically allocated
189 if (__pbuf != __buf)
190 delete[] __pbuf;
191
192 // left justify if necessary
193 for (; __pad > 0; ++__it, --__pad)
194 *__it = __fill;
195
196#ifndef _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
197
198 // reset width only if the insertion has been successful
199 // (i.e., no exception and the iterator has not failed)
200 if (!_RW::__rw_iter_failed (__it))
201 __flags.width (0);
202
203#endif // _RWSTD_NO_EXT_KEEP_WIDTH_ON_FAILURE
204
205 return __it;
206}
207
208
209} // namespace std
const int __f
#define _RWSTD_IOS_ADJUSTFIELD
Definition _defs.h:792
#define _RWSTD_EXPORT
Definition _defs.h:485
#define _RWSTD_USE_FACET(type, arg)
Definition _defs.h:949
#define _RWSTD_IOS_LEFT
Definition _defs.h:771
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_STREAMSIZE
Definition _defs.h:762
#define _RWSTD_IOS_INTERNAL
Definition _defs.h:770
Definition json.h:5363