2013-05-30 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / libstdc++-v3 / include / bits / parse_numbers.h
blobeaa3d27a18ac4c6c38ac579b907846b15070f09d
1 // Components for compile-time parsing of numbers -*- C++ -*-
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.
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>
46 struct _Digit;
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};
222 // Digit separator
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>
234 struct _Digits_help
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>
249 struct _Digits
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>
263 struct _Power_help
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>
278 struct _Power
280 static constexpr unsigned value{_Power_help<_Base, _Digs...>::value};
283 template<unsigned _Base>
284 struct _Power<_Base>
286 static constexpr unsigned value{0U};
289 //------------------------------------------------------------------------------
291 template<unsigned _Base, unsigned _Pow, char _Dig, char... _Digs>
292 struct _Number_help
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>
310 struct _Number
312 static constexpr unsigned
313 value{_Number_help<_Base, _Power<_Base, _Digs...>::value,
314 _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>
327 struct _Parse_int;
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>
365 struct _Parse_int
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...>
381 : integral_constant
383 typename conditional
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
392 { };
394 template<unsigned long long _Val>
395 struct _Select_int_base<_Val> : integral_constant<unsigned long long, _Val>
396 { };
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
408 { };
410 } // namespace __select_int
412 _GLIBCXX_END_NAMESPACE_VERSION
413 } // namespace std
415 #endif // __cplusplus > 201103L
417 #endif // _PARSE_NUMBERS_H