Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/c++/15/bits/parse_numbers.h
1 // Components for compile-time parsing of numbers -*- C++ -*- 2 3 // Copyright (C) 2013-2025 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 _GLIBCXX_PARSE_NUMBERS_H 31 #define _GLIBCXX_PARSE_NUMBERS_H 1 32 33 #ifdef _GLIBCXX_SYSHDR 34 #pragma GCC system_header 35 #endif 36 37 // From n3642.pdf except I added binary literals and digit separator '\''. 38 39 #if __cplusplus >= 201402L 40 41 #include <type_traits> 42 #include <ext/numeric_traits.h> 43 44 namespace std _GLIBCXX_VISIBILITY(default) 45 { 46 _GLIBCXX_BEGIN_NAMESPACE_VERSION 47 48 namespace __parse_int 49 { 50 template<unsigned _Base, char _Dig> 51 struct _Digit; 52 53 template<unsigned _Base> 54 struct _Digit<_Base, '0'> : integral_constant<unsigned, 0> 55 { 56 using __valid = true_type; 57 }; 58 59 template<unsigned _Base> 60 struct _Digit<_Base, '1'> : integral_constant<unsigned, 1> 61 { 62 using __valid = true_type; 63 }; 64 65 template<unsigned _Base, unsigned _Val> 66 struct _Digit_impl : integral_constant<unsigned, _Val> 67 { 68 static_assert(_Base > _Val, "invalid digit"); 69 using __valid = true_type; 70 }; 71 72 template<unsigned _Base> 73 struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2> 74 { }; 75 76 template<unsigned _Base> 77 struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3> 78 { }; 79 80 template<unsigned _Base> 81 struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4> 82 { }; 83 84 template<unsigned _Base> 85 struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5> 86 { }; 87 88 template<unsigned _Base> 89 struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6> 90 { }; 91 92 template<unsigned _Base> 93 struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7> 94 { }; 95 96 template<unsigned _Base> 97 struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8> 98 { }; 99 100 template<unsigned _Base> 101 struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9> 102 { }; 103 104 template<unsigned _Base> 105 struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa> 106 { }; 107 108 template<unsigned _Base> 109 struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa> 110 { }; 111 112 template<unsigned _Base> 113 struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb> 114 { }; 115 116 template<unsigned _Base> 117 struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb> 118 { }; 119 120 template<unsigned _Base> 121 struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc> 122 { }; 123 124 template<unsigned _Base> 125 struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc> 126 { }; 127 128 template<unsigned _Base> 129 struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd> 130 { }; 131 132 template<unsigned _Base> 133 struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd> 134 { }; 135 136 template<unsigned _Base> 137 struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe> 138 { }; 139 140 template<unsigned _Base> 141 struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe> 142 { }; 143 144 template<unsigned _Base> 145 struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf> 146 { }; 147 148 template<unsigned _Base> 149 struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf> 150 { }; 151 152 // Digit separator 153 template<unsigned _Base> 154 struct _Digit<_Base, '\''> : integral_constant<unsigned, 0> 155 { 156 using __valid = false_type; 157 }; 158 159 //------------------------------------------------------------------------------ 160 161 template<unsigned long long _Val> 162 using __ull_constant = integral_constant<unsigned long long, _Val>; 163 164 template<unsigned _Base, char _Dig, char... _Digs> 165 struct _Power_help 166 { 167 using __next = typename _Power_help<_Base, _Digs...>::type; 168 using __valid_digit = typename _Digit<_Base, _Dig>::__valid; 169 using type 170 = __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>; 171 }; 172 173 template<unsigned _Base, char _Dig> 174 struct _Power_help<_Base, _Dig> 175 { 176 using __valid_digit = typename _Digit<_Base, _Dig>::__valid; 177 using type = __ull_constant<__valid_digit::value>; 178 }; 179 180 template<unsigned _Base, char... _Digs> 181 struct _Power : _Power_help<_Base, _Digs...>::type 182 { }; 183 184 template<unsigned _Base> 185 struct _Power<_Base> : __ull_constant<0> 186 { }; 187 188 //------------------------------------------------------------------------------ 189 190 template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs> 191 struct _Number_help 192 { 193 using __digit = _Digit<_Base, _Dig>; 194 using __valid_digit = typename __digit::__valid; 195 using __next = _Number_help<_Base, 196 __valid_digit::value ? _Pow / _Base : _Pow, 197 _Digs...>; 198 using type = __ull_constant<_Pow * __digit::value + __next::type::value>; 199 static_assert((type::value / _Pow) == __digit::value, 200 "integer literal does not fit in unsigned long long"); 201 }; 202 203 // Skip past digit separators: 204 template<unsigned _Base, unsigned long long _Pow, char _Dig, char..._Digs> 205 struct _Number_help<_Base, _Pow, '\'', _Dig, _Digs...> 206 : _Number_help<_Base, _Pow, _Dig, _Digs...> 207 { }; 208 209 // Terminating case for recursion: 210 template<unsigned _Base, char _Dig> 211 struct _Number_help<_Base, 1ULL, _Dig> 212 { 213 using type = __ull_constant<_Digit<_Base, _Dig>::value>; 214 }; 215 216 template<unsigned _Base, char... _Digs> 217 struct _Number 218 : _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type 219 { }; 220 221 template<unsigned _Base> 222 struct _Number<_Base> 223 : __ull_constant<0> 224 { }; 225 226 //------------------------------------------------------------------------------ 227 228 template<char... _Digs> 229 struct _Parse_int; 230 231 template<char... _Digs> 232 struct _Parse_int<'0', 'b', _Digs...> 233 : _Number<2U, _Digs...>::type 234 { }; 235 236 template<char... _Digs> 237 struct _Parse_int<'0', 'B', _Digs...> 238 : _Number<2U, _Digs...>::type 239 { }; 240 241 template<char... _Digs> 242 struct _Parse_int<'0', 'x', _Digs...> 243 : _Number<16U, _Digs...>::type 244 { }; 245 246 template<char... _Digs> 247 struct _Parse_int<'0', 'X', _Digs...> 248 : _Number<16U, _Digs...>::type 249 { }; 250 251 template<char... _Digs> 252 struct _Parse_int<'0', _Digs...> 253 : _Number<8U, _Digs...>::type 254 { }; 255 256 template<char... _Digs> 257 struct _Parse_int 258 : _Number<10U, _Digs...>::type 259 { }; 260 261 } // namespace __parse_int 262 263 264 namespace __select_int 265 { 266 template<unsigned long long _Val, typename... _Ints> 267 struct _Select_int_base; 268 269 template<unsigned long long _Val, typename _IntType, typename... _Ints> 270 struct _Select_int_base<_Val, _IntType, _Ints...> 271 : __conditional_t<(_Val <= __gnu_cxx::__int_traits<_IntType>::__max), 272 integral_constant<_IntType, (_IntType)_Val>, 273 _Select_int_base<_Val, _Ints...>> 274 { }; 275 276 template<unsigned long long _Val> 277 struct _Select_int_base<_Val> 278 { }; 279 280 template<char... _Digs> 281 using _Select_int = typename _Select_int_base< 282 __parse_int::_Parse_int<_Digs...>::value, 283 unsigned char, 284 unsigned short, 285 unsigned int, 286 unsigned long, 287 unsigned long long 288 >::type; 289 290 } // namespace __select_int 291 292 _GLIBCXX_END_NAMESPACE_VERSION 293 } // namespace std 294 295 #endif // C++14 296 297 #endif // _GLIBCXX_PARSE_NUMBERS_H