libstdc++: parse_numbers.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30#ifndef _GLIBCXX_PARSE_NUMBERS_H

31#define _GLIBCXX_PARSE_NUMBERS_H 1

32

33#pragma GCC system_header

34

35

36

37#if __cplusplus >= 201402L

38

41

42namespace std _GLIBCXX_VISIBILITY(default)

43{

44_GLIBCXX_BEGIN_NAMESPACE_VERSION

45

46namespace __parse_int

47{

48 template<unsigned _Base, char _Dig>

49 struct _Digit;

50

51 template<unsigned _Base>

52 struct _Digit<_Base, '0'> : integral_constant<unsigned, 0>

53 {

55 };

56

57 template<unsigned _Base>

58 struct _Digit<_Base, '1'> : integral_constant<unsigned, 1>

59 {

61 };

62

63 template<unsigned _Base, unsigned _Val>

64 struct _Digit_impl : integral_constant<unsigned, _Val>

65 {

66 static_assert(_Base > _Val, "invalid digit");

68 };

69

70 template<unsigned _Base>

71 struct _Digit<_Base, '2'> : _Digit_impl<_Base, 2>

72 { };

73

74 template<unsigned _Base>

75 struct _Digit<_Base, '3'> : _Digit_impl<_Base, 3>

76 { };

77

78 template<unsigned _Base>

79 struct _Digit<_Base, '4'> : _Digit_impl<_Base, 4>

80 { };

81

82 template<unsigned _Base>

83 struct _Digit<_Base, '5'> : _Digit_impl<_Base, 5>

84 { };

85

86 template<unsigned _Base>

87 struct _Digit<_Base, '6'> : _Digit_impl<_Base, 6>

88 { };

89

90 template<unsigned _Base>

91 struct _Digit<_Base, '7'> : _Digit_impl<_Base, 7>

92 { };

93

94 template<unsigned _Base>

95 struct _Digit<_Base, '8'> : _Digit_impl<_Base, 8>

96 { };

97

98 template<unsigned _Base>

99 struct _Digit<_Base, '9'> : _Digit_impl<_Base, 9>

100 { };

101

102 template<unsigned _Base>

103 struct _Digit<_Base, 'a'> : _Digit_impl<_Base, 0xa>

104 { };

105

106 template<unsigned _Base>

107 struct _Digit<_Base, 'A'> : _Digit_impl<_Base, 0xa>

108 { };

109

110 template<unsigned _Base>

111 struct _Digit<_Base, 'b'> : _Digit_impl<_Base, 0xb>

112 { };

113

114 template<unsigned _Base>

115 struct _Digit<_Base, 'B'> : _Digit_impl<_Base, 0xb>

116 { };

117

118 template<unsigned _Base>

119 struct _Digit<_Base, 'c'> : _Digit_impl<_Base, 0xc>

120 { };

121

122 template<unsigned _Base>

123 struct _Digit<_Base, 'C'> : _Digit_impl<_Base, 0xc>

124 { };

125

126 template<unsigned _Base>

127 struct _Digit<_Base, 'd'> : _Digit_impl<_Base, 0xd>

128 { };

129

130 template<unsigned _Base>

131 struct _Digit<_Base, 'D'> : _Digit_impl<_Base, 0xd>

132 { };

133

134 template<unsigned _Base>

135 struct _Digit<_Base, 'e'> : _Digit_impl<_Base, 0xe>

136 { };

137

138 template<unsigned _Base>

139 struct _Digit<_Base, 'E'> : _Digit_impl<_Base, 0xe>

140 { };

141

142 template<unsigned _Base>

143 struct _Digit<_Base, 'f'> : _Digit_impl<_Base, 0xf>

144 { };

145

146 template<unsigned _Base>

147 struct _Digit<_Base, 'F'> : _Digit_impl<_Base, 0xf>

148 { };

149

150

151 template<unsigned _Base>

152 struct _Digit<_Base, '\''> : integral_constant<unsigned, 0>

153 {

155 };

156

157

158

159 template<unsigned long long _Val>

160 using __ull_constant = integral_constant<unsigned long long, _Val>;

161

162 template<unsigned _Base, char _Dig, char... _Digs>

163 struct _Power_help

164 {

165 using __next = typename _Power_help<_Base, _Digs...>::type;

166 using __valid_digit = typename _Digit<_Base, _Dig>::__valid;

167 using type

168 = __ull_constant<__next::value * (__valid_digit{} ? _Base : 1ULL)>;

169 };

170

171 template<unsigned _Base, char _Dig>

172 struct _Power_help<_Base, _Dig>

173 {

174 using __valid_digit = typename _Digit<_Base, _Dig>::__valid;

175 using type = __ull_constant<__valid_digit::value>;

176 };

177

178 template<unsigned _Base, char... _Digs>

179 struct _Power : _Power_help<_Base, _Digs...>::type

180 { };

181

182 template<unsigned _Base>

183 struct _Power<_Base> : __ull_constant<0>

184 { };

185

186

187

188 template<unsigned _Base, unsigned long long _Pow, char _Dig, char... _Digs>

189 struct _Number_help

190 {

191 using __digit = _Digit<_Base, _Dig>;

192 using __valid_digit = typename __digit::__valid;

193 using __next = _Number_help<_Base,

194 __valid_digit::value ? _Pow / _Base : _Pow,

195 _Digs...>;

196 using type = __ull_constant<_Pow * __digit::value + __next::type::value>;

197 static_assert((type::value / _Pow) == __digit::value,

198 "integer literal does not fit in unsigned long long");

199 };

200

201

202 template<unsigned _Base, unsigned long long _Pow, char _Dig, char..._Digs>

203 struct _Number_help<_Base, _Pow, '\'', _Dig, _Digs...>

204 : _Number_help<_Base, _Pow, _Dig, _Digs...>

205 { };

206

207

208 template<unsigned _Base, char _Dig>

209 struct _Number_help<_Base, 1ULL, _Dig>

210 {

211 using type = __ull_constant<_Digit<_Base, _Dig>::value>;

212 };

213

214 template<unsigned _Base, char... _Digs>

215 struct _Number

216 : _Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::type

217 { };

218

219 template<unsigned _Base>

220 struct _Number<_Base>

221 : __ull_constant<0>

222 { };

223

224

225

226 template<char... _Digs>

227 struct _Parse_int;

228

229 template<char... _Digs>

230 struct _Parse_int<'0', 'b', _Digs...>

231 : _Number<2U, _Digs...>::type

232 { };

233

234 template<char... _Digs>

235 struct _Parse_int<'0', 'B', _Digs...>

236 : _Number<2U, _Digs...>::type

237 { };

238

239 template<char... _Digs>

240 struct _Parse_int<'0', 'x', _Digs...>

241 : _Number<16U, _Digs...>::type

242 { };

243

244 template<char... _Digs>

245 struct _Parse_int<'0', 'X', _Digs...>

246 : _Number<16U, _Digs...>::type

247 { };

248

249 template<char... _Digs>

250 struct _Parse_int<'0', _Digs...>

251 : _Number<8U, _Digs...>::type

252 { };

253

254 template<char... _Digs>

255 struct _Parse_int

256 : _Number<10U, _Digs...>::type

257 { };

258

259}

260

261

262namespace __select_int

263{

264 template<unsigned long long _Val, typename... _Ints>

265 struct _Select_int_base;

266

267 template<unsigned long long _Val, typename _IntType, typename... _Ints>

268 struct _Select_int_base<_Val, _IntType, _Ints...>

269 : __conditional_t<(_Val <= __gnu_cxx::__int_traits<_IntType>::__max),

270 integral_constant<_IntType, (_IntType)_Val>,

271 _Select_int_base<_Val, _Ints...>>

272 { };

273

274 template<unsigned long long _Val>

275 struct _Select_int_base<_Val>

276 { };

277

278 template<char... _Digs>

279 using _Select_int = typename _Select_int_base<

280 __parse_int::_Parse_int<_Digs...>::value,

281 unsigned char,

282 unsigned short,

283 unsigned int,

284 unsigned long,

285 unsigned long long

286 >::type;

287

288}

289

290_GLIBCXX_END_NAMESPACE_VERSION

291}

292

293#endif

294

295#endif

__bool_constant< true > true_type

The type used as a compile-time boolean with true value.

__bool_constant< false > false_type

The type used as a compile-time boolean with false value.

ISO C++ entities toplevel namespace is std.