2
3
4
5
6
7
8
9
10
11
13#ifndef IPADDRESS_UNICODE_HPP
14#define IPADDRESS_UNICODE_HPP
28 uint32_t error_symbol = 0;
30 const auto result = char_reader<T>::next_or_error(it, end, code, error_symbol);
32 raise_error(code, error_symbol, begin, end - begin);
38#ifdef IPADDRESS_MODULE
56 auto symbol = utf8_code_point(uint8_t(*it), correct);
58 switch (symbol.length) {
63 symbol.value = (symbol.value << 6) | trailing_utf8_code_point(it, end, correct);
67 symbol.value = (symbol.value << 6) | trailing_utf8_code_point(it, end, correct);
68 symbol.value = (symbol.value << 6) | trailing_utf8_code_point(it, end, correct);
72 symbol.value = (symbol.value << 6) | trailing_utf8_code_point(it, end, correct);
73 symbol.value = (symbol.value << 6) | trailing_utf8_code_point(it, end, correct);
74 symbol.value = (symbol.value << 6) | trailing_utf8_code_point(it, end, correct);
86 }
else if (symbol.value > 127) {
88 error_symbol = symbol.value;
91 return char(symbol.value);
95 if ((byte & 0b10000000) == 0b00000000) {
96 return {
static_cast<uint32_t>(byte), 1};
98 if ((byte & 0b11100000) == 0b11000000) {
99 return {
static_cast<uint32_t>(byte & 0b00011111), 2};
101 if ((byte & 0b11110000) == 0b11100000) {
102 return {
static_cast<uint32_t>(byte & 0b00001111), 3};
104 if ((byte & 0b11111000) == 0b11110000) {
105 return {
static_cast<uint32_t>(byte & 0b00000111), 4};
116 if ((uint8_t(*it) & 0b11000000) == 0b10000000) {
118 return uint8_t(*it) & 0b00111111;
131 auto symbol = utf16_code_point(uint16_t(*it));
132 switch (symbol.length) {
134 symbol.value = uint32_t(*it);
142 if ((*it & 0b1111110000000000) == 0b1101110000000000) {
143 symbol.value = ((symbol.value << 10) | (uint16_t(*it) & 0b0000001111111111)) + 0x10000;
157 }
else if (symbol.value > 127) {
159 error_symbol = symbol.value;
162 return char(symbol.value);
166 if ((value & 0b1111110000000000) == 0b1101100000000000) {
167 return {
static_cast<uint32_t>(value & 0b0000001111111111), 2};
179 if (uint32_t(*it) > 127) {
181 error_symbol = uint32_t(*it++);
189struct char_reader<
char>
190#ifdef IPADDRESS_CHAR_IS_UTF8
191: utf8_reader<
char>, char_or_throw<
char>
194#ifdef IPADDRESS_CHAR_IS_UTF8
196 IPADDRESS_NODISCARD
static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE
char next_or_error(
const char*& it,
const char* end, error_code& error, uint32_t& error_symbol) IPADDRESS_NOEXCEPT {
197 return utf8_next_or_error(it, end, error, error_symbol);
213#ifdef IPADDRESS_MODULE
222#if __cpp_char8_t >= 201811L
225struct char_reader<char8_t> : utf8_reader<char8_t>, char_or_throw<char8_t> {
226 IPADDRESS_NODISCARD
static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE
char next_or_error(
const char8_t*& it,
const char8_t* end, error_code& error, uint32_t& error_symbol) IPADDRESS_NOEXCEPT {
227 return utf8_next_or_error(it, end, error, error_symbol);
234struct char_reader<
char16_t> : utf16_reader<
char16_t>, char_or_throw<
char16_t> {
236 return utf16_next_or_error(it, end, error, error_symbol);
241struct char_reader<
char32_t> : utf32_reader<
char32_t>, char_or_throw<
char32_t> {
243 return utf32_next_or_error(it, end, error, error_symbol);
248struct char_reader<
wchar_t> : utf16_reader<
wchar_t>, utf32_reader<
wchar_t>, char_or_throw<
wchar_t> {
253 if (
sizeof(
wchar_t) ==
sizeof(
char16_t)) {
254 return utf16_next_or_error(it, end, error, error_symbol);
257 if (
sizeof(
wchar_t) ==
sizeof(
char32_t)) {
258 return utf32_next_or_error(it, end, error, error_symbol);
263 error_symbol = uint32_t(*it++);
272 return internal::char_reader<T>::next(it, begin, end);
277 return internal::char_reader<T>::next_or_error(it, end, error, error_symbol);
281struct string_converter {
283 return std::basic_string<T, std::char_traits<T>, std::allocator<T>>(str.cbegin(), str.cend());
288struct string_converter<
char> {
295 out <<
"{U+" << std::setw(4) << std::setfill(
'0') << std::hex << symbol <<
'}';
301 internal::print_symbol_code(out, arg.value);
305template <
typename T, size_t N>
308 uint32_t error_symbol = 0;
310 const T* end = str + N;
312 const auto result = internal::next_char_or_error(it, end, code, error_symbol);
314 if (result ==
'\0') {
319 if (error_symbol == 0) {
322 internal::print_symbol_code(out, error_symbol);
The primary exception class used by the IP address library.
Definition errors.hpp:114
#define IPADDRESS_NOEXCEPT_WHEN_NO_EXCEPTIONS
Definition config.hpp:93
#define IPADDRESS_NODISCARD
Definition config.hpp:98
#define IPADDRESS_FORCE_INLINE
Definition config.hpp:112
#define IPADDRESS_NAMESPACE
Definition config.hpp:38
#define IPADDRESS_NOEXCEPT
Definition config.hpp:89
#define IPADDRESS_NODISCARD_WHEN_NO_EXCEPTIONS
Definition config.hpp:102
error_code
Enumeration of error codes for IP address parsing and validation.
Definition errors.hpp:52
@ unexpected_symbol
The input string contains an unexpected character.
@ wrong_encoding_sequence
Incorrect byte sequence in Unicode encoding.
@ no_error
Indicates the absence of any errors.