source: mainline/uspace/lib/cpp/include/__bits/locale/num_put.hpp@ b57ba05

Last change on this file since b57ba05 was b57ba05, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 3 years ago

Update headers in C++ files

  • Property mode set to 100644
File size: 11.7 KB
Line 
1/*
2 * SPDX-FileCopyrightText: 2018 Jaroslav Jindrak
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef LIBCPP_BITS_LOCALE_NUM_PUT
8#define LIBCPP_BITS_LOCALE_NUM_PUT
9
10#include <__bits/locale/locale.hpp>
11#include <__bits/locale/numpunct.hpp>
12#include <ios>
13#include <iterator>
14
15namespace std
16{
17 /**
18 * 22.4.2.2, class template num_put:
19 */
20
21 template<class Char, class OutputIterator = ostreambuf_iterator<Char>>
22 class num_put: public locale::facet
23 {
24 public:
25 using char_type = Char;
26 using iter_type = OutputIterator;
27
28 explicit num_put(size_t refs = 0)
29 { /* DUMMY BODY */ }
30
31 iter_type put(iter_type it, ios_base& base, char_type fill, bool v) const
32 {
33 return do_put(it, base, fill, v);
34 }
35
36 iter_type put(iter_type it, ios_base& base, char_type fill, long v) const
37 {
38 return do_put(it, base, fill, v);
39 }
40
41 iter_type put(iter_type it, ios_base& base, char_type fill, long long v) const
42 {
43 return do_put(it, base, fill, v);
44 }
45
46 iter_type put(iter_type it, ios_base& base, char_type fill, unsigned long v) const
47 {
48 return do_put(it, base, fill, v);
49 }
50
51 iter_type put(iter_type it, ios_base& base, char_type fill, unsigned long long v) const
52 {
53 return do_put(it, base, fill, v);
54 }
55
56 iter_type put(iter_type it, ios_base& base, char_type fill, double v) const
57 {
58 return do_put(it, base, fill, v);
59 }
60
61 iter_type put(iter_type it, ios_base& base, char_type fill, long double v) const
62 {
63 return do_put(it, base, fill, v);
64 }
65
66 iter_type put(iter_type it, ios_base& base, char_type fill, const void* v) const
67 {
68 return do_put(it, base, fill, v);
69 }
70
71 ~num_put()
72 { /* DUMMY BODY */ }
73
74 protected:
75 iter_type do_put(iter_type it, ios_base& base, char_type fill, bool v) const
76 {
77 auto loc = base.getloc();
78
79 if ((base.flags() & ios_base::boolalpha) == 0)
80 return do_put(it, base, fill, (long)v);
81 else
82 {
83 auto s = v ? use_facet<numpunct<char_type>>(loc).truename()
84 : use_facet<numpunct<char_type>>(loc).falsename();
85 for (auto c: s)
86 *it++ = c;
87 }
88
89 return it;
90 }
91
92 iter_type do_put(iter_type it, ios_base& base, char_type fill, long v) const
93 {
94 auto basefield = (base.flags() & ios_base::basefield);
95 auto uppercase = (base.flags() & ios_base::uppercase);
96
97 int ret{};
98 if (basefield == ios_base::oct)
99 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lo", v);
100 else if ((basefield == ios_base::hex) && !uppercase)
101 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lx", v);
102 else if (basefield == ios_base::hex)
103 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lX", v);
104 else
105 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%ld", v);
106
107 return put_adjusted_buffer_(it, base, fill, ret);
108 }
109
110 iter_type do_put(iter_type it, ios_base& base, char_type fill, long long v) const
111 {
112 auto basefield = (base.flags() & ios_base::basefield);
113 auto uppercase = (base.flags() & ios_base::uppercase);
114
115 int ret{};
116 if (basefield == ios_base::oct)
117 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llo", v);
118 else if ((basefield == ios_base::hex) && !uppercase)
119 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llx", v);
120 else if (basefield == ios_base::hex)
121 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llX", v);
122 else
123 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lld", v);
124
125 return put_adjusted_buffer_(it, base, fill, ret);
126 }
127
128 iter_type do_put(iter_type it, ios_base& base, char_type fill, unsigned long v) const
129 {
130 auto basefield = (base.flags() & ios_base::basefield);
131 auto uppercase = (base.flags() & ios_base::uppercase);
132
133 int ret{};
134 if (basefield == ios_base::oct)
135 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lo", v);
136 else if ((basefield == ios_base::hex) && !uppercase)
137 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lx", v);
138 else if (basefield == ios_base::hex)
139 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lX", v);
140 else
141 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%lu", v);
142
143 return put_adjusted_buffer_(it, base, fill, ret);
144 }
145
146 iter_type do_put(iter_type it, ios_base& base, char_type fill, unsigned long long v) const
147 {
148 auto basefield = (base.flags() & ios_base::basefield);
149 auto uppercase = (base.flags() & ios_base::uppercase);
150
151 // TODO: showbase
152 int ret{};
153 if (basefield == ios_base::oct)
154 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llo", v);
155 else if ((basefield == ios_base::hex) && !uppercase)
156 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llx", v);
157 else if (basefield == ios_base::hex)
158 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llX", v);
159 else
160 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%llu", v);
161
162 return put_adjusted_buffer_(it, base, fill, ret);
163 }
164
165 iter_type do_put(iter_type it, ios_base& base, char_type fill, double v) const
166 {
167 auto floatfield = (base.flags() & ios_base::floatfield);
168 auto uppercase = (base.flags() & ios_base::uppercase);
169
170 // TODO: showbase
171 // TODO: precision
172 int ret{};
173 if (floatfield == ios_base::fixed)
174 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%f", v);
175 else if (floatfield == ios_base::scientific && !uppercase)
176 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%e", v);
177 else if (floatfield == ios_base::scientific)
178 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%E", v);
179 else if (floatfield == (ios_base::fixed | ios_base::scientific) && !uppercase)
180 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%a", v);
181 else if (floatfield == (ios_base::fixed | ios_base::scientific))
182 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%A", v);
183 else if (!uppercase)
184 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%g", v);
185 else
186 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%G", v);
187
188 return put_adjusted_buffer_(it, base, fill, ret);
189 }
190
191 iter_type do_put(iter_type it, ios_base& base, char_type fill, long double v) const
192 {
193 /**
194 * Note: Long double is not support at the moment in snprintf.
195 */
196 auto floatfield = (base.flags() & ios_base::floatfield);
197 auto uppercase = (base.flags() & ios_base::uppercase);
198
199 // TODO: showbase
200 // TODO: precision
201 int ret{};
202 if (floatfield == ios_base::fixed)
203 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%Lf", v);
204 else if (floatfield == ios_base::scientific && !uppercase)
205 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%Le", v);
206 else if (floatfield == ios_base::scientific)
207 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%LE", v);
208 else if (floatfield == (ios_base::fixed | ios_base::scientific) && !uppercase)
209 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%La", v);
210 else if (floatfield == (ios_base::fixed | ios_base::scientific))
211 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%LA", v);
212 else if (!uppercase)
213 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%Lg", v);
214 else
215 ret = snprintf(base.buffer_, ios_base::buffer_size_, "%LG", v);
216
217 return put_adjusted_buffer_(it, base, fill, ret);
218 }
219
220 iter_type do_put(iter_type it, ios_base& base, char_type fill, const void* v) const
221 {
222 int ret = snprintf(base.buffer_, ios_base::buffer_size_, "%p", v);
223
224 return put_adjusted_buffer_(it, base, fill, ret);
225 }
226
227 private:
228 iter_type put_adjusted_buffer_(iter_type it, ios_base& base, char_type fill, size_t size) const
229 {
230 auto adjustfield = (base.flags() & ios_base::adjustfield);
231
232 size_t to_fill{};
233 size_t width = static_cast<size_t>(base.width());
234
235 if (base.width() > 0 && size < width)
236 to_fill = width - size;
237
238 if (to_fill > 0)
239 {
240 if (adjustfield == ios_base::left)
241 {
242 it = put_buffer_(it, base, fill, 0, size);
243 for (size_t i = 0; i < to_fill; ++i)
244 *it++ = fill;
245 }
246 else if (adjustfield == ios_base::right)
247 {
248 for (size_t i = 0; i < to_fill; ++i)
249 *it++ = fill;
250 it = put_buffer_(it, base, fill, 0, size);
251 }
252 else if (adjustfield == ios_base::internal)
253 {
254 // TODO: pad after - or 0x/0X
255 }
256 else
257 {
258 for (size_t i = 0; i < to_fill; ++i)
259 *it++ = fill;
260 it = put_buffer_(it, base, fill, 0, size);
261 }
262 }
263 else
264 it = put_buffer_(it, base, fill, 0, size);
265 base.width(0);
266
267 return it;
268 }
269
270 iter_type put_buffer_(iter_type it, ios_base& base, char_type fill, size_t start, size_t size) const
271 {
272 const auto& loc = base.getloc();
273 const auto& ct = use_facet<ctype<char_type>>(loc);
274 const auto& punct = use_facet<numpunct<char_type>>(loc);
275
276 for (size_t i = start; i < size; ++i)
277 {
278 if (base.buffer_[i] == '.')
279 *it++ = punct.decimal_point();
280 else
281 *it++ = ct.widen(base.buffer_[i]);
282 // TODO: Should do grouping & thousands_sep, but that's a low
283 // priority for now.
284 }
285
286 return it;
287 }
288 };
289}
290
291#endif
Note: See TracBrowser for help on using the repository browser.