11debfc3dSmrg // Components for compile-time parsing of numbers -*- C++ -*-
21debfc3dSmrg
3*8feb0f0bSmrg // Copyright (C) 2013-2020 Free Software Foundation, Inc.
41debfc3dSmrg //
51debfc3dSmrg // This file is part of the GNU ISO C++ Library. This library is free
61debfc3dSmrg // software; you can redistribute it and/or modify it under the
71debfc3dSmrg // terms of the GNU General Public License as published by the
81debfc3dSmrg // Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg // any later version.
101debfc3dSmrg
111debfc3dSmrg // This library is distributed in the hope that it will be useful,
121debfc3dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of
131debfc3dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
141debfc3dSmrg // GNU General Public License for more details.
151debfc3dSmrg
161debfc3dSmrg // Under Section 7 of GPL version 3, you are granted additional
171debfc3dSmrg // permissions described in the GCC Runtime Library Exception, version
181debfc3dSmrg // 3.1, as published by the Free Software Foundation.
191debfc3dSmrg
201debfc3dSmrg // You should have received a copy of the GNU General Public License and
211debfc3dSmrg // a copy of the GCC Runtime Library Exception along with this program;
221debfc3dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
231debfc3dSmrg // <http://www.gnu.org/licenses/>.
241debfc3dSmrg
251debfc3dSmrg /** @file bits/parse_numbers.h
261debfc3dSmrg * This is an internal header file, included by other library headers.
271debfc3dSmrg * Do not attempt to use it directly. @headername{chrono}
281debfc3dSmrg */
291debfc3dSmrg
301debfc3dSmrg #ifndef _GLIBCXX_PARSE_NUMBERS_H
311debfc3dSmrg #define _GLIBCXX_PARSE_NUMBERS_H 1
321debfc3dSmrg
331debfc3dSmrg #pragma GCC system_header
341debfc3dSmrg
351debfc3dSmrg // From n3642.pdf except I added binary literals and digit separator '\''.
361debfc3dSmrg
37*8feb0f0bSmrg #if __cplusplus >= 201402L
381debfc3dSmrg
39*8feb0f0bSmrg #include <ext/numeric_traits.h>
401debfc3dSmrg
_GLIBCXX_VISIBILITY(default)411debfc3dSmrg namespace std _GLIBCXX_VISIBILITY(default)
421debfc3dSmrg {
431debfc3dSmrg _GLIBCXX_BEGIN_NAMESPACE_VERSION
441debfc3dSmrg
451debfc3dSmrg namespace __parse_int
461debfc3dSmrg {
471debfc3dSmrg template<unsigned _Base, char _Dig>
481debfc3dSmrg struct _Digit;
491debfc3dSmrg
501debfc3dSmrg template<unsigned _Base>
511debfc3dSmrg struct _Digit<_Base, '0'> : integral_constant<unsigned, 0>
521debfc3dSmrg {
531debfc3dSmrg using __valid = true_type;
541debfc3dSmrg };
551debfc3dSmrg
561debfc3dSmrg template<unsigned _Base>
571debfc3dSmrg struct _Digit<_Base, '1'> : integral_constant<unsigned, 1>
581debfc3dSmrg {
591debfc3dSmrg using __valid = true_type;
601debfc3dSmrg };
611debfc3dSmrg
621debfc3dSmrg template<unsigned _Base, unsigned _Val>
631debfc3dSmrg struct _Digit_impl : integral_constant<unsigned, _Val>
641debfc3dSmrg {
651debfc3dSmrg static_assert(_Base > _Val, "invalid digit");
661debfc3dSmrg using __valid = true_type;
671debfc3dSmrg };
681debfc3dSmrg
691debfc3dSmrg template<unsigned _Base>
701debfc3dSmrg struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2>
711debfc3dSmrg { };
721debfc3dSmrg
731debfc3dSmrg template<unsigned _Base>
741debfc3dSmrg struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3>
751debfc3dSmrg { };
761debfc3dSmrg
771debfc3dSmrg template<unsigned _Base>
781debfc3dSmrg struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4>
791debfc3dSmrg { };
801debfc3dSmrg
811debfc3dSmrg template<unsigned _Base>
821debfc3dSmrg struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5>
831debfc3dSmrg { };
841debfc3dSmrg
851debfc3dSmrg template<unsigned _Base>
861debfc3dSmrg struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6>
871debfc3dSmrg { };
881debfc3dSmrg
891debfc3dSmrg template<unsigned _Base>
901debfc3dSmrg struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7>
911debfc3dSmrg { };
921debfc3dSmrg
931debfc3dSmrg template<unsigned _Base>
941debfc3dSmrg struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8>
951debfc3dSmrg { };
961debfc3dSmrg
971debfc3dSmrg template<unsigned _Base>
981debfc3dSmrg struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9>
991debfc3dSmrg { };
1001debfc3dSmrg
1011debfc3dSmrg template<unsigned _Base>
1021debfc3dSmrg struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa>
1031debfc3dSmrg { };
1041debfc3dSmrg
1051debfc3dSmrg template<unsigned _Base>
1061debfc3dSmrg struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa>
1071debfc3dSmrg { };
1081debfc3dSmrg
1091debfc3dSmrg template<unsigned _Base>
1101debfc3dSmrg struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb>
1111debfc3dSmrg { };
1121debfc3dSmrg
1131debfc3dSmrg template<unsigned _Base>
1141debfc3dSmrg struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb>
1151debfc3dSmrg { };
1161debfc3dSmrg
1171debfc3dSmrg template<unsigned _Base>
1181debfc3dSmrg struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc>
1191debfc3dSmrg { };
1201debfc3dSmrg
1211debfc3dSmrg template<unsigned _Base>
1221debfc3dSmrg struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc>
1231debfc3dSmrg { };
1241debfc3dSmrg
1251debfc3dSmrg template<unsigned _Base>
1261debfc3dSmrg struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd>
1271debfc3dSmrg { };
1281debfc3dSmrg
1291debfc3dSmrg template<unsigned _Base>
1301debfc3dSmrg struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd>
1311debfc3dSmrg { };
1321debfc3dSmrg
1331debfc3dSmrg template<unsigned _Base>
1341debfc3dSmrg struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe>
1351debfc3dSmrg { };
1361debfc3dSmrg
1371debfc3dSmrg template<unsigned _Base>
1381debfc3dSmrg struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe>
1391debfc3dSmrg { };
1401debfc3dSmrg
1411debfc3dSmrg template<unsigned _Base>
1421debfc3dSmrg struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf>
1431debfc3dSmrg { };
1441debfc3dSmrg
1451debfc3dSmrg template<unsigned _Base>
1461debfc3dSmrg struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf>
1471debfc3dSmrg { };
1481debfc3dSmrg
1491debfc3dSmrg // Digit separator
1501debfc3dSmrg template<unsigned _Base>
1511debfc3dSmrg struct _Digit<_Base, '\''> : integral_constant<unsigned, 0>
1521debfc3dSmrg {
1531debfc3dSmrg using __valid = false_type;
1541debfc3dSmrg };
1551debfc3dSmrg
1561debfc3dSmrg //------------------------------------------------------------------------------
1571debfc3dSmrg
1581debfc3dSmrg template<unsigned long long _Val>
1591debfc3dSmrg using __ull_constant = integral_constant<unsigned long long, _Val>;
1601debfc3dSmrg
1611debfc3dSmrg template<unsigned _Base, char _Dig, char... _Digs>
1621debfc3dSmrg struct _Power_help
1631debfc3dSmrg {
1641debfc3dSmrg using __next = typename _Power_help<_Base, _Digs...>::type;
1651debfc3dSmrg using __valid_digit = typename _Digit<_Base, _Dig>::__valid;
1661debfc3dSmrg using type
1671debfc3dSmrg = __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>;
1681debfc3dSmrg };
1691debfc3dSmrg
1701debfc3dSmrg template<unsigned _Base, char _Dig>
1711debfc3dSmrg struct _Power_help<_Base, _Dig>
1721debfc3dSmrg {
1731debfc3dSmrg using __valid_digit = typename _Digit<_Base, _Dig>::__valid;
1741debfc3dSmrg using type = __ull_constant<__valid_digit::value>;
1751debfc3dSmrg };
1761debfc3dSmrg
1771debfc3dSmrg template<unsigned _Base, char... _Digs>
1781debfc3dSmrg struct _Power : _Power_help<_Base, _Digs...>::type
1791debfc3dSmrg { };
1801debfc3dSmrg
1811debfc3dSmrg template<unsigned _Base>
1821debfc3dSmrg struct _Power<_Base> : __ull_constant<0>
1831debfc3dSmrg { };
1841debfc3dSmrg
1851debfc3dSmrg //------------------------------------------------------------------------------
1861debfc3dSmrg
1871debfc3dSmrg template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs>
1881debfc3dSmrg struct _Number_help
1891debfc3dSmrg {
1901debfc3dSmrg using __digit = _Digit<_Base, _Dig>;
1911debfc3dSmrg using __valid_digit = typename __digit::__valid;
1921debfc3dSmrg using __next = _Number_help<_Base,
1931debfc3dSmrg __valid_digit::value ? _Pow / _Base : _Pow,
1941debfc3dSmrg _Digs...>;
1951debfc3dSmrg using type = __ull_constant<_Pow * __digit::value + __next::type::value>;
1961debfc3dSmrg static_assert((type::value / _Pow) == __digit::value,
1971debfc3dSmrg "integer literal does not fit in unsigned long long");
1981debfc3dSmrg };
1991debfc3dSmrg
2001debfc3dSmrg // Skip past digit separators:
2011debfc3dSmrg template<unsigned _Base, unsigned long long _Pow, char _Dig, char..._Digs>
2021debfc3dSmrg struct _Number_help<_Base, _Pow, '\'', _Dig, _Digs...>
2031debfc3dSmrg : _Number_help<_Base, _Pow, _Dig, _Digs...>
2041debfc3dSmrg { };
2051debfc3dSmrg
2061debfc3dSmrg // Terminating case for recursion:
207a2dc1f3fSmrg template<unsigned _Base, char _Dig>
208a2dc1f3fSmrg struct _Number_help<_Base, 1ULL, _Dig>
2091debfc3dSmrg {
2101debfc3dSmrg using type = __ull_constant<_Digit<_Base, _Dig>::value>;
2111debfc3dSmrg };
2121debfc3dSmrg
2131debfc3dSmrg template<unsigned _Base, char... _Digs>
2141debfc3dSmrg struct _Number
2151debfc3dSmrg : _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type
2161debfc3dSmrg { };
2171debfc3dSmrg
2181debfc3dSmrg template<unsigned _Base>
2191debfc3dSmrg struct _Number<_Base>
2201debfc3dSmrg : __ull_constant<0>
2211debfc3dSmrg { };
2221debfc3dSmrg
2231debfc3dSmrg //------------------------------------------------------------------------------
2241debfc3dSmrg
2251debfc3dSmrg template<char... _Digs>
2261debfc3dSmrg struct _Parse_int;
2271debfc3dSmrg
2281debfc3dSmrg template<char... _Digs>
2291debfc3dSmrg struct _Parse_int<'0', 'b', _Digs...>
2301debfc3dSmrg : _Number<2U, _Digs...>::type
2311debfc3dSmrg { };
2321debfc3dSmrg
2331debfc3dSmrg template<char... _Digs>
2341debfc3dSmrg struct _Parse_int<'0', 'B', _Digs...>
2351debfc3dSmrg : _Number<2U, _Digs...>::type
2361debfc3dSmrg { };
2371debfc3dSmrg
2381debfc3dSmrg template<char... _Digs>
2391debfc3dSmrg struct _Parse_int<'0', 'x', _Digs...>
2401debfc3dSmrg : _Number<16U, _Digs...>::type
2411debfc3dSmrg { };
2421debfc3dSmrg
2431debfc3dSmrg template<char... _Digs>
2441debfc3dSmrg struct _Parse_int<'0', 'X', _Digs...>
2451debfc3dSmrg : _Number<16U, _Digs...>::type
2461debfc3dSmrg { };
2471debfc3dSmrg
2481debfc3dSmrg template<char... _Digs>
2491debfc3dSmrg struct _Parse_int<'0', _Digs...>
2501debfc3dSmrg : _Number<8U, _Digs...>::type
2511debfc3dSmrg { };
2521debfc3dSmrg
2531debfc3dSmrg template<char... _Digs>
2541debfc3dSmrg struct _Parse_int
2551debfc3dSmrg : _Number<10U, _Digs...>::type
2561debfc3dSmrg { };
2571debfc3dSmrg
2581debfc3dSmrg } // namespace __parse_int
2591debfc3dSmrg
2601debfc3dSmrg
2611debfc3dSmrg namespace __select_int
2621debfc3dSmrg {
2631debfc3dSmrg template<unsigned long long _Val, typename... _Ints>
2641debfc3dSmrg struct _Select_int_base;
2651debfc3dSmrg
2661debfc3dSmrg template<unsigned long long _Val, typename _IntType, typename... _Ints>
2671debfc3dSmrg struct _Select_int_base<_Val, _IntType, _Ints...>
268*8feb0f0bSmrg : conditional_t<(_Val <= __gnu_cxx::__int_traits<_IntType>::__max),
2691debfc3dSmrg integral_constant<_IntType, _Val>,
2701debfc3dSmrg _Select_int_base<_Val, _Ints...>>
2711debfc3dSmrg { };
2721debfc3dSmrg
2731debfc3dSmrg template<unsigned long long _Val>
2741debfc3dSmrg struct _Select_int_base<_Val>
2751debfc3dSmrg { };
2761debfc3dSmrg
2771debfc3dSmrg template<char... _Digs>
2781debfc3dSmrg using _Select_int = typename _Select_int_base<
2791debfc3dSmrg __parse_int::_Parse_int<_Digs...>::value,
2801debfc3dSmrg unsigned char,
2811debfc3dSmrg unsigned short,
2821debfc3dSmrg unsigned int,
2831debfc3dSmrg unsigned long,
2841debfc3dSmrg unsigned long long
2851debfc3dSmrg >::type;
2861debfc3dSmrg
2871debfc3dSmrg } // namespace __select_int
2881debfc3dSmrg
2891debfc3dSmrg _GLIBCXX_END_NAMESPACE_VERSION
2901debfc3dSmrg } // namespace std
2911debfc3dSmrg
292*8feb0f0bSmrg #endif // C++14
2931debfc3dSmrg
2941debfc3dSmrg #endif // _GLIBCXX_PARSE_NUMBERS_H
295