1 // Components for compile-time parsing of numbers -*- C++ -*-
3 // Copyright (C) 2013 Free Software Foundation, Inc.
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)
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.
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.
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/>.
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}
30 #ifndef _PARSE_NUMBERS_H
31 #define _PARSE_NUMBERS_H 1
33 #pragma GCC system_header
35 // From n3642.pdf except I added binary literals and digit separator '`'.
37 #if __cplusplus > 201103L
39 namespace std
_GLIBCXX_VISIBILITY(default)
41 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43 namespace __parse_int
{
45 template<unsigned _Base
, char _Dig
>
48 template<unsigned _Base
>
49 struct _Digit
<_Base
, '0'>
51 static constexpr bool valid
{true};
52 static constexpr unsigned value
{0};
55 template<unsigned _Base
>
56 struct _Digit
<_Base
, '1'>
58 static constexpr bool valid
{true};
59 static constexpr unsigned value
{1};
62 template<unsigned _Base
>
63 struct _Digit
<_Base
, '2'>
65 static_assert(_Base
> 2, "invalid digit");
66 static constexpr bool valid
{true};
67 static constexpr unsigned value
{2};
70 template<unsigned _Base
>
71 struct _Digit
<_Base
, '3'>
73 static_assert(_Base
> 3, "invalid digit");
74 static constexpr bool valid
{true};
75 static constexpr unsigned value
{3};
78 template<unsigned _Base
>
79 struct _Digit
<_Base
, '4'>
81 static_assert(_Base
> 4, "invalid digit");
82 static constexpr bool valid
{true};
83 static constexpr unsigned value
{4};
86 template<unsigned _Base
>
87 struct _Digit
<_Base
, '5'>
89 static_assert(_Base
> 5, "invalid digit");
90 static constexpr bool valid
{true};
91 static constexpr unsigned value
{5};
94 template<unsigned _Base
>
95 struct _Digit
<_Base
, '6'>
97 static_assert(_Base
> 6, "invalid digit");
98 static constexpr bool valid
{true};
99 static constexpr unsigned value
{6};
102 template<unsigned _Base
>
103 struct _Digit
<_Base
, '7'>
105 static_assert(_Base
> 7, "invalid digit");
106 static constexpr bool valid
{true};
107 static constexpr unsigned value
{7};
110 template<unsigned _Base
>
111 struct _Digit
<_Base
, '8'>
113 static_assert(_Base
> 8, "invalid digit");
114 static constexpr bool valid
{true};
115 static constexpr unsigned value
{8};
118 template<unsigned _Base
>
119 struct _Digit
<_Base
, '9'>
121 static_assert(_Base
> 9, "invalid digit");
122 static constexpr bool valid
{true};
123 static constexpr unsigned value
{9};
126 template<unsigned _Base
>
127 struct _Digit
<_Base
, 'a'>
129 static_assert(_Base
> 0xa, "invalid digit");
130 static constexpr bool valid
{true};
131 static constexpr unsigned value
{0xa};
134 template<unsigned _Base
>
135 struct _Digit
<_Base
, 'A'>
137 static_assert(_Base
> 0xa, "invalid digit");
138 static constexpr bool valid
{true};
139 static constexpr unsigned value
{0xa};
142 template<unsigned _Base
>
143 struct _Digit
<_Base
, 'b'>
145 static_assert(_Base
> 0xb, "invalid digit");
146 static constexpr bool valid
{true};
147 static constexpr unsigned value
{0xb};
150 template<unsigned _Base
>
151 struct _Digit
<_Base
, 'B'>
153 static_assert(_Base
> 0xb, "invalid digit");
154 static constexpr bool valid
{true};
155 static constexpr unsigned value
{0xb};
158 template<unsigned _Base
>
159 struct _Digit
<_Base
, 'c'>
161 static_assert(_Base
> 0xc, "invalid digit");
162 static constexpr bool valid
{true};
163 static constexpr unsigned value
{0xc};
166 template<unsigned _Base
>
167 struct _Digit
<_Base
, 'C'>
169 static_assert(_Base
> 0xc, "invalid digit");
170 static constexpr bool valid
{true};
171 static constexpr unsigned value
{0xc};
174 template<unsigned _Base
>
175 struct _Digit
<_Base
, 'd'>
177 static_assert(_Base
> 0xd, "invalid digit");
178 static constexpr bool valid
{true};
179 static constexpr unsigned value
{0xd};
182 template<unsigned _Base
>
183 struct _Digit
<_Base
, 'D'>
185 static_assert(_Base
> 0xd, "invalid digit");
186 static constexpr bool valid
{true};
187 static constexpr unsigned value
{0xd};
190 template<unsigned _Base
>
191 struct _Digit
<_Base
, 'e'>
193 static_assert(_Base
> 0xe, "invalid digit");
194 static constexpr bool valid
{true};
195 static constexpr unsigned value
{0xe};
198 template<unsigned _Base
>
199 struct _Digit
<_Base
, 'E'>
201 static_assert(_Base
> 0xe, "invalid digit");
202 static constexpr bool valid
{true};
203 static constexpr unsigned value
{0xe};
206 template<unsigned _Base
>
207 struct _Digit
<_Base
, 'f'>
209 static_assert(_Base
> 0xf, "invalid digit");
210 static constexpr bool valid
{true};
211 static constexpr unsigned value
{0xf};
214 template<unsigned _Base
>
215 struct _Digit
<_Base
, 'F'>
217 static_assert(_Base
> 0xf, "invalid digit");
218 static constexpr bool valid
{true};
219 static constexpr unsigned value
{0xf};
223 template<unsigned _Base
>
224 struct _Digit
<_Base
, '`'>
226 static constexpr bool valid
{false};
227 static constexpr unsigned value
{0};
231 //------------------------------------------------------------------------------
233 template<unsigned _Base
, char _Dig
, char... _Digs
>
236 static constexpr unsigned
237 value
{_Digit
<_Base
, _Dig
>::valid
?
238 1U + _Digits_help
<_Base
, _Digs
...>::value
:
239 _Digits_help
<_Base
, _Digs
...>::value
};
242 template<unsigned _Base
, char _Dig
>
243 struct _Digits_help
<_Base
, _Dig
>
245 static constexpr unsigned value
{_Digit
<_Base
, _Dig
>::valid
? 1U : 0U};
248 template<unsigned _Base
, char... _Digs
>
251 static constexpr unsigned value
{_Digits_help
<_Base
, _Digs
...>::value
};
254 template<unsigned _Base
>
255 struct _Digits
<_Base
>
257 static constexpr unsigned value
{0U};
260 //------------------------------------------------------------------------------
262 template<unsigned _Base
, char _Dig
, char... _Digs
>
265 static constexpr unsigned
266 value
{_Digit
<_Base
, _Dig
>::valid
?
267 _Base
* _Power_help
<_Base
, _Digs
...>::value
:
268 _Power_help
<_Base
, _Digs
...>::value
};
271 template<unsigned _Base
, char _Dig
>
272 struct _Power_help
<_Base
, _Dig
>
274 static constexpr unsigned value
{_Digit
<_Base
, _Dig
>::valid
? 1U : 0U};
277 template<unsigned _Base
, char... _Digs
>
280 static constexpr unsigned value
{_Power_help
<_Base
, _Digs
...>::value
};
283 template<unsigned _Base
>
286 static constexpr unsigned value
{0U};
289 //------------------------------------------------------------------------------
291 template<unsigned _Base
, unsigned _Pow
, char _Dig
, char... _Digs
>
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
};
301 template<unsigned _Base
, unsigned _Pow
, char _Dig
>
302 struct _Number_help
<_Base
, _Pow
, _Dig
>
304 //static_assert(_Pow == 1U, "power should be one");
305 static constexpr unsigned
306 value
{_Digit
<_Base
, _Dig
>::valid
? _Digit
<_Base
, _Dig
>::value
: 0U};
309 template<unsigned _Base
, char... _Digs
>
312 static constexpr unsigned
313 value
{_Number_help
<_Base
, _Power
<_Base
, _Digs
...>::value
,
317 template<unsigned _Base
>
318 struct _Number
<_Base
>
320 static constexpr unsigned value
{0U};
323 //------------------------------------------------------------------------------
324 // This _Parse_int is the same 'level' as the old _Base_dispatch.
326 template<char... _Digs
>
329 template<char... _Digs
>
330 struct _Parse_int
<'0', 'b', _Digs
...>
332 static constexpr unsigned long long
333 value
{_Number
<2U, _Digs
...>::value
};
336 template<char... _Digs
>
337 struct _Parse_int
<'0', 'B', _Digs
...>
339 static constexpr unsigned long long
340 value
{_Number
<2U, _Digs
...>::value
};
343 template<char... _Digs
>
344 struct _Parse_int
<'0', 'x', _Digs
...>
346 static constexpr unsigned long long
347 value
{_Number
<16U, _Digs
...>::value
};
350 template<char... _Digs
>
351 struct _Parse_int
<'0', 'X', _Digs
...>
353 static constexpr unsigned long long
354 value
{_Number
<16U, _Digs
...>::value
};
357 template<char... _Digs
>
358 struct _Parse_int
<'0', _Digs
...>
360 static constexpr unsigned long long
361 value
{_Number
<8U, _Digs
...>::value
};
364 template<char... _Digs
>
367 static constexpr unsigned long long
368 value
{_Number
<10U, _Digs
...>::value
};
371 } // namespace __parse_int
374 namespace __select_int
{
376 template<unsigned long long _Val
, typename
... _Ints
>
377 struct _Select_int_base
;
379 template<unsigned long long _Val
, typename _IntType
, typename
... _Ints
>
380 struct _Select_int_base
<_Val
, _IntType
, _Ints
...>
385 _Val
<= static_cast<unsigned long long>
386 (std::numeric_limits
<_IntType
>::max()),
388 typename _Select_int_base
<_Val
, _Ints
...>::value_type
394 template<unsigned long long _Val
>
395 struct _Select_int_base
<_Val
> : integral_constant
<unsigned long long, _Val
>
398 template<char... _Digs
>
401 __parse_int::_Parse_int
<_Digs
...>::value
,
410 } // namespace __select_int
412 _GLIBCXX_END_NAMESPACE_VERSION
415 #endif // __cplusplus > 201103L
417 #endif // _PARSE_NUMBERS_H