MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
hexadecimal.hpp
1#ifndef MSTL_CORE_UTILITY_HEXADECIMAL_HPP__
2#define MSTL_CORE_UTILITY_HEXADECIMAL_HPP__
3#include "../interface/iobject.hpp"
4#include "../string/format.hpp"
5#include "../string/to_numerics.hpp"
6#include "../config/undef_cmacro.hpp"
8
9struct MSTL_API hexadecimal : iobject<hexadecimal>, ipackage<hexadecimal, int64_t> {
10public:
11 using value_type = int64_t;
12 using base = ipackage<hexadecimal, int64_t>;
13
14private:
15
16 static MSTL_CONSTEXPR20 value_type parse_hex(const string_view s) {
17 if (s.empty()) return 0;
18
19 bool negative = false;
20 size_t start = 0;
21
22 while (start < s.size() && _MSTL is_space(s[start])) ++start;
23 if (start == s.size()) return 0;
24
25 if (s[start] == '-') {
26 negative = true;
27 ++start;
28 } else if (s[start] == '+') {
29 ++start;
30 }
31
32 if (start + 1 < s.size() && s[start] == '0' &&
33 (s[start+1] == 'x' || s[start+1] == 'X')) {
34 start += 2;
35 }
36
37 string hex_digits;
38 while (start < s.size()) {
39 const char c = s[start++];
40 if (_MSTL is_xdigit(c)) {
41 hex_digits += c;
42 } else if (!_MSTL is_space(c)) {
43 throw_exception(value_exception("Invalid hexadecimal character"));
44 }
45 }
46
47 if (hex_digits.empty()) return 0;
48
49 size_t pos = 0;
50 const uint64_t raw = _MSTL to_uint64(hex_digits.view(), &pos, 16);
51 if (pos != hex_digits.size()) {
52 throw_exception(value_exception("Invalid hexadecimal format"));
53 }
54
55 if (negative) {
56 if (raw > static_cast<uint64_t>(numeric_traits<int64_t>::max()) + 1) {
57 throw_exception(value_exception("Hexadecimal value out of range"));
58 }
59 return -static_cast<int64_t>(raw);
60 }
61 if (raw > static_cast<uint64_t>(numeric_traits<int64_t>::max())) {
62 throw_exception(value_exception("Hexadecimal value out of range"));
63 }
64 return static_cast<value_type>(raw);
65 }
66
67public:
68 explicit constexpr hexadecimal(const int16_t v) noexcept : base(v) {}
69 explicit constexpr hexadecimal(const int32_t v) noexcept : base(v) {}
70 explicit constexpr hexadecimal(const uint16_t v) noexcept : base(v) {}
71 explicit constexpr hexadecimal(const uint32_t v) noexcept : base(v) {}
72 explicit constexpr hexadecimal(const uint64_t v) noexcept : base(v) {}
73 MSTL_CONSTEXPR20 explicit hexadecimal(const string_view s) : base(parse_hex(s)) {}
74 MSTL_CONSTEXPR20 explicit hexadecimal(const char* s) : hexadecimal(string_view(s)) {}
75 MSTL_CONSTEXPR20 explicit hexadecimal(const string& s) : hexadecimal(s.view()) {}
76
77 MSTL_BUILD_PACKAGE_CONSTRUCTOR(hexadecimal)
78
79 MSTL_NODISCARD explicit constexpr operator bool() const noexcept {
80 return value_ != _MSTL initialize<value_type>();
81 }
82
83 MSTL_NODISCARD constexpr bool get_bit(const size_t position) const {
84 if (position >= 64) throw_exception(value_exception("Bit position out of range"));
85 return (value_ >> position) & 1;
86 }
87
88 constexpr hexadecimal& set_bit(const size_t position, const bool bit_value_ = true) {
89 if (position >= 64) throw_exception(value_exception("Bit position out of range"));
90 if (bit_value_) {
91 value_ |= (1ULL << position);
92 } else {
93 value_ &= ~(1ULL << position);
94 }
95 return *this;
96 }
97
98 constexpr hexadecimal& flip_bit(const size_t position) {
99 if (position >= 64) throw_exception(value_exception("Bit position out of range"));
100 value_ ^= (1ULL << position);
101 return *this;
102 }
103
104 MSTL_NODISCARD MSTL_CONSTEXPR20 string to_string() const;
105
106 MSTL_NODISCARD static MSTL_CONSTEXPR20 hexadecimal parse(const string_view str) {
107 return hexadecimal(str);
108 }
109};
110
111template <>
112struct unpackage<hexadecimal> {
113 using type = int64_t;
114};
115
116
117template <>
118struct formatter<hexadecimal> {
119 MSTL_CONSTEXPR20 string operator ()(const hexadecimal& value, const format_options& options) const {
120 return formatter<int64_t>()(value.value(), options);
121 }
122};
123
124MSTL_CONSTEXPR20 string hexadecimal::to_string() const {
125 return _MSTL format("{#x}", *this);
126}
127
128
129MSTL_CONSTEXPR20 hexadecimal to_hexadecimal(const string_view sv) {
130 return hexadecimal::parse(sv);
131}
132
133
135
136MSTL_CONSTEXPR20 hexadecimal operator ""_hex(const char* str, const size_t len) {
137 return hexadecimal{string_view(str, len)};
138}
139constexpr hexadecimal operator ""_hex(const unsigned long long value) {
140 return {static_cast<int64_t>(value)};
141}
142
144
146#endif // MSTL_CORE_UTILITY_HEXADECIMAL_HPP__
static MSTL_NODISCARD constexpr T max() noexcept
获取类型的最大值
MSTL_PURE_FUNCTION MSTL_CONSTEXPR14 bool is_space(const CharT c) noexcept
检查字符是否为空白字符
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 bool is_xdigit(const CharT c) noexcept
检查字符是否为十六进制数字
unsigned int uint32_t
32位无符号整数类型
long long int64_t
64位有符号整数类型
unsigned short uint16_t
16位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
short int16_t
16位有符号整数类型
int int32_t
32位有符号整数类型
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_LITERALS__
结束literals命名空间
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_LITERALS__
开始literals命名空间(内联)
constexpr T initialize() noexcept(is_nothrow_default_constructible< T >::value)
返回类型T的默认初始化值
类型解包器模板