Implement N3642 - User-defined Literals for Standard Library Types
[gcc.git] / libstdc++-v3 / include / bits / parse_numbers.h
1 // Components for compile-time parsing of numbers -*- C++ -*-
2
3 // Copyright (C) 2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24
25 /** @file bits/parse_numbers.h
26 * This is an internal header file, included by other library headers.
27 * Do not attempt to use it directly. @headername{chrono}
28 */
29
30 #ifndef _PARSE_NUMBERS_H
31 #define _PARSE_NUMBERS_H 1
32
33 #pragma GCC system_header
34
35 // From n3642.pdf except I added binary literals and digit separator '`'.
36
37 #if __cplusplus > 201103L
38
39 namespace std _GLIBCXX_VISIBILITY(default)
40 {
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
42
43 namespace __parse_int {
44
45 template<unsigned _Base, char _Dig>
46 struct _Digit;
47
48 template<unsigned _Base>
49 struct _Digit<_Base, '0'>
50 {
51 static constexpr bool valid{true};
52 static constexpr unsigned value{0};
53 };
54
55 template<unsigned _Base>
56 struct _Digit<_Base, '1'>
57 {
58 static constexpr bool valid{true};
59 static constexpr unsigned value{1};
60 };
61
62 template<unsigned _Base>
63 struct _Digit<_Base, '2'>
64 {
65 static_assert(_Base > 2, "invalid digit");
66 static constexpr bool valid{true};
67 static constexpr unsigned value{2};
68 };
69
70 template<unsigned _Base>
71 struct _Digit<_Base, '3'>
72 {
73 static_assert(_Base > 3, "invalid digit");
74 static constexpr bool valid{true};
75 static constexpr unsigned value{3};
76 };
77
78 template<unsigned _Base>
79 struct _Digit<_Base, '4'>
80 {
81 static_assert(_Base > 4, "invalid digit");
82 static constexpr bool valid{true};
83 static constexpr unsigned value{4};
84 };
85
86 template<unsigned _Base>
87 struct _Digit<_Base, '5'>
88 {
89 static_assert(_Base > 5, "invalid digit");
90 static constexpr bool valid{true};
91 static constexpr unsigned value{5};
92 };
93
94 template<unsigned _Base>
95 struct _Digit<_Base, '6'>
96 {
97 static_assert(_Base > 6, "invalid digit");
98 static constexpr bool valid{true};
99 static constexpr unsigned value{6};
100 };
101
102 template<unsigned _Base>
103 struct _Digit<_Base, '7'>
104 {
105 static_assert(_Base > 7, "invalid digit");
106 static constexpr bool valid{true};
107 static constexpr unsigned value{7};
108 };
109
110 template<unsigned _Base>
111 struct _Digit<_Base, '8'>
112 {
113 static_assert(_Base > 8, "invalid digit");
114 static constexpr bool valid{true};
115 static constexpr unsigned value{8};
116 };
117
118 template<unsigned _Base>
119 struct _Digit<_Base, '9'>
120 {
121 static_assert(_Base > 9, "invalid digit");
122 static constexpr bool valid{true};
123 static constexpr unsigned value{9};
124 };
125
126 template<unsigned _Base>
127 struct _Digit<_Base, 'a'>
128 {
129 static_assert(_Base > 0xa, "invalid digit");
130 static constexpr bool valid{true};
131 static constexpr unsigned value{0xa};
132 };
133
134 template<unsigned _Base>
135 struct _Digit<_Base, 'A'>
136 {
137 static_assert(_Base > 0xa, "invalid digit");
138 static constexpr bool valid{true};
139 static constexpr unsigned value{0xa};
140 };
141
142 template<unsigned _Base>
143 struct _Digit<_Base, 'b'>
144 {
145 static_assert(_Base > 0xb, "invalid digit");
146 static constexpr bool valid{true};
147 static constexpr unsigned value{0xb};
148 };
149
150 template<unsigned _Base>
151 struct _Digit<_Base, 'B'>
152 {
153 static_assert(_Base > 0xb, "invalid digit");
154 static constexpr bool valid{true};
155 static constexpr unsigned value{0xb};
156 };
157
158 template<unsigned _Base>
159 struct _Digit<_Base, 'c'>
160 {
161 static_assert(_Base > 0xc, "invalid digit");
162 static constexpr bool valid{true};
163 static constexpr unsigned value{0xc};
164 };
165
166 template<unsigned _Base>
167 struct _Digit<_Base, 'C'>
168 {
169 static_assert(_Base > 0xc, "invalid digit");
170 static constexpr bool valid{true};
171 static constexpr unsigned value{0xc};
172 };
173
174 template<unsigned _Base>
175 struct _Digit<_Base, 'd'>
176 {
177 static_assert(_Base > 0xd, "invalid digit");
178 static constexpr bool valid{true};
179 static constexpr unsigned value{0xd};
180 };
181
182 template<unsigned _Base>
183 struct _Digit<_Base, 'D'>
184 {
185 static_assert(_Base > 0xd, "invalid digit");
186 static constexpr bool valid{true};
187 static constexpr unsigned value{0xd};
188 };
189
190 template<unsigned _Base>
191 struct _Digit<_Base, 'e'>
192 {
193 static_assert(_Base > 0xe, "invalid digit");
194 static constexpr bool valid{true};
195 static constexpr unsigned value{0xe};
196 };
197
198 template<unsigned _Base>
199 struct _Digit<_Base, 'E'>
200 {
201 static_assert(_Base > 0xe, "invalid digit");
202 static constexpr bool valid{true};
203 static constexpr unsigned value{0xe};
204 };
205
206 template<unsigned _Base>
207 struct _Digit<_Base, 'f'>
208 {
209 static_assert(_Base > 0xf, "invalid digit");
210 static constexpr bool valid{true};
211 static constexpr unsigned value{0xf};
212 };
213
214 template<unsigned _Base>
215 struct _Digit<_Base, 'F'>
216 {
217 static_assert(_Base > 0xf, "invalid digit");
218 static constexpr bool valid{true};
219 static constexpr unsigned value{0xf};
220 };
221
222 // Digit separator
223 template<unsigned _Base>
224 struct _Digit<_Base, '`'>
225 {
226 static constexpr bool valid{false};
227 static constexpr unsigned value{0};
228 };
229
230
231 //------------------------------------------------------------------------------
232
233 template<unsigned _Base, char _Dig, char... _Digs>
234 struct _Digits_help
235 {
236 static constexpr unsigned
237 value{_Digit<_Base, _Dig>::valid ?
238 1U + _Digits_help<_Base, _Digs...>::value :
239 _Digits_help<_Base, _Digs...>::value};
240 };
241
242 template<unsigned _Base, char _Dig>
243 struct _Digits_help<_Base, _Dig>
244 {
245 static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U};
246 };
247
248 template<unsigned _Base, char... _Digs>
249 struct _Digits
250 {
251 static constexpr unsigned value{_Digits_help<_Base, _Digs...>::value};
252 };
253
254 template<unsigned _Base>
255 struct _Digits<_Base>
256 {
257 static constexpr unsigned value{0U};
258 };
259
260 //------------------------------------------------------------------------------
261
262 template<unsigned _Base, char _Dig, char... _Digs>
263 struct _Power_help
264 {
265 static constexpr unsigned
266 value{_Digit<_Base, _Dig>::valid ?
267 _Base * _Power_help<_Base, _Digs...>::value :
268 _Power_help<_Base, _Digs...>::value};
269 };
270
271 template<unsigned _Base, char _Dig>
272 struct _Power_help<_Base, _Dig>
273 {
274 static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U};
275 };
276
277 template<unsigned _Base, char... _Digs>
278 struct _Power
279 {
280 static constexpr unsigned value{_Power_help<_Base, _Digs...>::value};
281 };
282
283 template<unsigned _Base>
284 struct _Power<_Base>
285 {
286 static constexpr unsigned value{0U};
287 };
288
289 //------------------------------------------------------------------------------
290
291 template<unsigned _Base, unsigned _Pow, char _Dig, char... _Digs>
292 struct _Number_help
293 {
294 static constexpr unsigned
295 value{_Digit<_Base, _Dig>::valid ?
296 _Pow * _Digit<_Base, _Dig>::value
297 + _Number_help<_Base, _Pow / _Base, _Digs...>::value :
298 _Number_help<_Base, _Pow, _Digs...>::value};
299 };
300
301 template<unsigned _Base, unsigned _Pow, char _Dig>
302 struct _Number_help<_Base, _Pow, _Dig>
303 {
304 //static_assert(_Pow == 1U, "power should be one");
305 static constexpr unsigned
306 value{_Digit<_Base, _Dig>::valid ? _Digit<_Base, _Dig>::value : 0U};
307 };
308
309 template<unsigned _Base, char... _Digs>
310 struct _Number
311 {
312 static constexpr unsigned
313 value{_Number_help<_Base, _Power<_Base, _Digs...>::value,
314 _Digs...>::value};
315 };
316
317 template<unsigned _Base>
318 struct _Number<_Base>
319 {
320 static constexpr unsigned value{0U};
321 };
322
323 //------------------------------------------------------------------------------
324 // This _Parse_int is the same 'level' as the old _Base_dispatch.
325
326 template<char... _Digs>
327 struct _Parse_int;
328
329 template<char... _Digs>
330 struct _Parse_int<'0', 'b', _Digs...>
331 {
332 static constexpr unsigned long long
333 value{_Number<2U, _Digs...>::value};
334 };
335
336 template<char... _Digs>
337 struct _Parse_int<'0', 'B', _Digs...>
338 {
339 static constexpr unsigned long long
340 value{_Number<2U, _Digs...>::value};
341 };
342
343 template<char... _Digs>
344 struct _Parse_int<'0', 'x', _Digs...>
345 {
346 static constexpr unsigned long long
347 value{_Number<16U, _Digs...>::value};
348 };
349
350 template<char... _Digs>
351 struct _Parse_int<'0', 'X', _Digs...>
352 {
353 static constexpr unsigned long long
354 value{_Number<16U, _Digs...>::value};
355 };
356
357 template<char... _Digs>
358 struct _Parse_int<'0', _Digs...>
359 {
360 static constexpr unsigned long long
361 value{_Number<8U, _Digs...>::value};
362 };
363
364 template<char... _Digs>
365 struct _Parse_int
366 {
367 static constexpr unsigned long long
368 value{_Number<10U, _Digs...>::value};
369 };
370
371 } // namespace __parse_int
372
373
374 namespace __select_int {
375
376 template<unsigned long long _Val, typename... _Ints>
377 struct _Select_int_base;
378
379 template<unsigned long long _Val, typename _IntType, typename... _Ints>
380 struct _Select_int_base<_Val, _IntType, _Ints...>
381 : integral_constant
382 <
383 typename conditional
384 <
385 _Val <= static_cast<unsigned long long>
386 (std::numeric_limits<_IntType>::max()),
387 _IntType,
388 typename _Select_int_base<_Val, _Ints...>::value_type
389 >::type,
390 _Val
391 >
392 { };
393
394 template<unsigned long long _Val>
395 struct _Select_int_base<_Val> : integral_constant<unsigned long long, _Val>
396 { };
397
398 template<char... _Digs>
399 struct _Select_int
400 : _Select_int_base<
401 __parse_int::_Parse_int<_Digs...>::value,
402 unsigned char,
403 unsigned short,
404 unsigned int,
405 unsigned long,
406 unsigned long long
407 >
408 { };
409
410 } // namespace __select_int
411
412 _GLIBCXX_END_NAMESPACE_VERSION
413 } // namespace std
414
415 #endif // __cplusplus > 201103L
416
417 #endif // _PARSE_NUMBERS_H