xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/bits/parse_numbers.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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