SI  2.5.4
A header only c++ library that provides type safety and user defined literals for handling physical values defined in the International System of Units.
number_parser.h
Go to the documentation of this file.
1 
12 #pragma once
13 
14 #include <cstdint>
15 #include <limits>
16 
18 
21 template <std::intmax_t _base, char _str_digit> struct Digit_impl {
22  static_assert((_str_digit >= '0' && _str_digit <= '9') ||
23  (_str_digit >= 'a' && _str_digit <= 'f') ||
24  (_str_digit >= 'A' && _str_digit <= 'F') || _str_digit == '\'');
25 
26  static_assert(_base >= 2, "minimum representation is binary (base = 2)");
27  static_assert(_base < 17, "maximum representation is hex (base == 16)");
28 
29  static constexpr bool is_valid_digit = _str_digit == '\'' ? false : true;
30  static constexpr std::intmax_t value =
31  (_str_digit >= '0' && _str_digit <= '9') ? _str_digit - '0'
32  : (_str_digit >= 'a' && _str_digit <= 'f') ? 10 + (_str_digit - 'a')
33  : (_str_digit >= 'A' && _str_digit <= 'F')
34  ? 10 + (_str_digit - 'A')
35  : std::numeric_limits<std::intmax_t>::quiet_NaN();
36  static_assert(!is_valid_digit || value < _base, "Digit is valid for base");
37 };
38 
39 // Interface class to access Digit
40 template <std::intmax_t _base, char _str_digit>
41 struct Digit : public Digit_impl<_base, _str_digit> {};
42 
45 template <std::intmax_t _base, char _digit, char... _digits> struct Power_impl {
46 
48  using recursive_power = Power_impl<_base, _digits...>;
49  static constexpr std::intmax_t power = digit::is_valid_digit
50  ? (recursive_power::power * _base)
52 };
53 
55 template <std::intmax_t _base, char _digit> struct Power_impl<_base, _digit> {
56  static constexpr std::intmax_t power = 1;
57 };
58 
60 template <std::intmax_t _base, char... _digits>
61 struct Power : Power_impl<_base, _digits...> {};
62 
64 template <std::intmax_t _base> struct Power<_base> {
65  static constexpr std::intmax_t power = 1;
66 };
67 
68 template <std::intmax_t _base, char _digit, char... _digits> struct Magnitude {
70  static constexpr std::intmax_t recursive_magnitude =
71  Magnitude<_base, _digits...>::value;
72  static constexpr std::intmax_t value =
74 };
75 
76 template <std::intmax_t _base, char _digit> struct Magnitude<_base, _digit> {
77  static constexpr std::intmax_t value = 0;
78 };
79 
81 template <std::intmax_t _base, char _digit, char... _digits>
82 struct Number_impl {
83 
84  static constexpr std::intmax_t base = _base;
86  static constexpr std::intmax_t magnitude =
87  Magnitude<_base, _digit, _digits...>::value;
88  static constexpr std::intmax_t power = Power<base, _digit, _digits...>::power;
89 
90  using recursive_number = Number_impl<_base, _digits...>;
91  static constexpr std::intmax_t value =
94  static_assert(!digit::is_valid_digit || value / power == digit::value,
95  "integer literal overflows");
96 };
97 
99 template <std::intmax_t _base, char _digit> struct Number_impl<_base, _digit> {
100 
102  static_assert(digit::is_valid_digit, "digit is valid");
103  static constexpr std::intmax_t value = digit::value;
104  static constexpr std::intmax_t magnitude = 0;
105  static constexpr std::intmax_t base = _base;
106  static constexpr std::intmax_t power = Power<base>::power;
107  static_assert(power == 1, "power should be one");
108 };
109 
111 template <char... _digits> struct Number : Number_impl<10, _digits...> {};
112 
114 template <char... _digits>
115 struct Number<'0', 'x', _digits...> : Number_impl<16, _digits...> {};
116 
118 template <char... _digits>
119 struct Number<'0', 'X', _digits...> : Number_impl<16, _digits...> {};
120 
122 template <char... _digits>
123 struct Number<'0', 'b', _digits...> : Number_impl<2, _digits...> {};
124 
126 template <char... _digits>
127 struct Number<'0', 'B', _digits...> : Number_impl<2, _digits...> {};
128 
130 template <char... _digits>
131 struct Number<'0', _digits...> : Number_impl<8, _digits...> {};
132 
133 } // namespace SI::detail::parsing
Definition: number_parser.h:17
Definition: number_parser.h:21
static constexpr std::intmax_t value
Definition: number_parser.h:30
static constexpr bool is_valid_digit
Definition: number_parser.h:29
Definition: number_parser.h:41
Definition: number_parser.h:68
static constexpr std::intmax_t value
Definition: number_parser.h:72
static constexpr std::intmax_t recursive_magnitude
Definition: number_parser.h:70
recursive struct that builds the number
Definition: number_parser.h:82
static constexpr std::intmax_t magnitude
Definition: number_parser.h:86
static constexpr std::intmax_t value
Definition: number_parser.h:91
static constexpr std::intmax_t base
Definition: number_parser.h:84
static constexpr std::intmax_t power
Definition: number_parser.h:88
interface class for number
Definition: number_parser.h:111
Definition: number_parser.h:45
static constexpr std::intmax_t power
Definition: number_parser.h:49
interface class for power calculation
Definition: number_parser.h:61