From d904f1d7c3de38e993f5cffa376b218328ad016d Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 4 Jan 2026 09:45:57 +0100 Subject: [PATCH 1/7] Fix first set of clang-tidy warnings --- .clang-tidy | 2 ++ .github/workflows/clang-tidy.yml | 2 +- include/skyr/core/check_input.hpp | 4 +-- include/skyr/core/schemes.hpp | 4 +-- include/skyr/core/url_parser_context.hpp | 8 ++--- include/skyr/domain/domain.hpp | 7 ++-- include/skyr/domain/punycode.hpp | 4 +-- include/skyr/network/ipv4_address.hpp | 6 ++-- include/skyr/network/ipv6_address.hpp | 4 +-- .../percent_encoding/percent_decode_range.hpp | 2 +- .../percent_encoding/percent_encoded_char.hpp | 16 +++++----- include/skyr/platform/endianness.hpp | 6 ++-- include/skyr/unicode/code_point.hpp | 16 +++++----- include/skyr/unicode/code_points/u16.hpp | 6 ++-- include/skyr/unicode/code_points/u8.hpp | 4 +-- include/skyr/unicode/core.hpp | 32 +++++++++---------- .../skyr/unicode/ranges/views/u16_view.hpp | 2 +- include/skyr/unicode/ranges/views/u8_view.hpp | 2 +- .../ranges/views/unchecked_u8_view.hpp | 2 +- 19 files changed, 64 insertions(+), 65 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 850b0734..f9718e45 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -5,6 +5,7 @@ Checks: > bugprone-*, -bugprone-exception-escape, -bugprone-easily-swappable-parameters, + -bugprone-branch-clone, clang-diagnostic-*, clang-analyzer-*, concurrency-*, @@ -17,6 +18,7 @@ Checks: > -cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-do-while, -cppcoreguidelines-pro-type-reinterpret-cast, + -cppcoreguidelines-missing-std-forward, misc-*, -misc-unused-parameters, -misc-non-private-member-variables-in-classes, diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 7002629f..01b02b8f 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -54,7 +54,7 @@ jobs: - name: Run clang-tidy on source files if: false # Disabled for now run: | - find tests -name '*.cpp' -print0 | \ + find examples -name '*.cpp' -print0 | \ xargs -0 -n1 -P$(nproc) clang-tidy-21 -p build - name: clang-tidy check passed diff --git a/include/skyr/core/check_input.hpp b/include/skyr/core/check_input.hpp index 0180c6b4..17ae4311 100644 --- a/include/skyr/core/check_input.hpp +++ b/include/skyr/core/check_input.hpp @@ -16,7 +16,7 @@ constexpr static auto is_c0_control_or_space = [](auto byte) { return std::iscntrl(byte, std::locale::classic()) || std::isspace(byte, std::locale::classic()); }; -constexpr inline auto remove_leading_c0_control_or_space(std::string_view input, bool* validation_error) { +constexpr auto remove_leading_c0_control_or_space(std::string_view input, bool* validation_error) { auto first = std::cbegin(input), last = std::cend(input); auto it = std::find_if_not(first, last, is_c0_control_or_space); *validation_error |= (it != first); @@ -24,7 +24,7 @@ constexpr inline auto remove_leading_c0_control_or_space(std::string_view input, return input; } -constexpr inline auto remove_trailing_c0_control_or_space(std::string_view input, bool* validation_error) { +constexpr auto remove_trailing_c0_control_or_space(std::string_view input, bool* validation_error) { auto first = std::crbegin(input), last = std::crend(input); auto it = std::find_if_not(first, last, is_c0_control_or_space); *validation_error |= (it != first); diff --git a/include/skyr/core/schemes.hpp b/include/skyr/core/schemes.hpp index 0836bf76..f7d41288 100644 --- a/include/skyr/core/schemes.hpp +++ b/include/skyr/core/schemes.hpp @@ -13,14 +13,14 @@ namespace skyr { /// \param scheme /// \returns -constexpr inline auto is_special(std::string_view scheme) noexcept -> bool { +constexpr auto is_special(std::string_view scheme) noexcept -> bool { return (scheme == "file") || (scheme == "ftp") || (scheme == "http") || (scheme == "https") || (scheme == "ws") || (scheme == "wss"); } /// \param scheme /// \returns -constexpr inline auto default_port(std::string_view scheme) noexcept -> std::optional { +constexpr auto default_port(std::string_view scheme) noexcept -> std::optional { if (scheme == "ftp") { return 21; } else if ((scheme == "http") || (scheme == "ws")) { diff --git a/include/skyr/core/url_parser_context.hpp b/include/skyr/core/url_parser_context.hpp index 7d7accaa..cbe684d9 100644 --- a/include/skyr/core/url_parser_context.hpp +++ b/include/skyr/core/url_parser_context.hpp @@ -28,7 +28,7 @@ using namespace std::string_literals; using namespace std::string_view_literals; namespace details { -constexpr inline auto contains(std::string_view view, char element) noexcept { +constexpr auto contains(std::string_view view, char element) noexcept { auto first = std::cbegin(view), last = std::cend(view); return last != std::find(first, last, element); } @@ -56,7 +56,7 @@ inline auto is_url_code_point(char byte) noexcept { return std::isalnum(byte, std::locale::classic()) || contains("!$&'()*+,-./:;=?@_~"sv, byte); } -constexpr inline auto is_windows_drive_letter(std::string_view segment) noexcept { +constexpr auto is_windows_drive_letter(std::string_view segment) noexcept { if (segment.size() < 2) { return false; } @@ -74,11 +74,11 @@ constexpr inline auto is_windows_drive_letter(std::string_view segment) noexcept return result; } -constexpr inline auto is_single_dot_path_segment(std::string_view segment) noexcept { +constexpr auto is_single_dot_path_segment(std::string_view segment) noexcept { return (segment == ".") || (segment == "%2e") || (segment == "%2E"); } -constexpr inline auto is_double_dot_path_segment(std::string_view segment) noexcept { +constexpr auto is_double_dot_path_segment(std::string_view segment) noexcept { return (segment == "..") || (segment == "%2e.") || (segment == ".%2e") || (segment == "%2e%2e") || (segment == "%2E.") || (segment == ".%2E") || (segment == "%2E%2E") || (segment == "%2E%2e") || (segment == "%2e%2E"); diff --git a/include/skyr/domain/domain.hpp b/include/skyr/domain/domain.hpp index e3d16b0d..6de17a19 100644 --- a/include/skyr/domain/domain.hpp +++ b/include/skyr/domain/domain.hpp @@ -21,10 +21,9 @@ #include namespace skyr { -constexpr inline auto validate_label(std::u32string_view label, [[maybe_unused]] bool use_std3_ascii_rules, - bool check_hyphens, [[maybe_unused]] bool check_bidi, - [[maybe_unused]] bool check_joiners, bool transitional_processing) - -> std::expected { +constexpr auto validate_label(std::u32string_view label, [[maybe_unused]] bool use_std3_ascii_rules, bool check_hyphens, + [[maybe_unused]] bool check_bidi, [[maybe_unused]] bool check_joiners, + bool transitional_processing) -> std::expected { /// https://www.unicode.org/reports/tr46/#Validity_Criteria; if (check_hyphens) { diff --git a/include/skyr/domain/punycode.hpp b/include/skyr/domain/punycode.hpp index c6a886bb..186c1aa2 100644 --- a/include/skyr/domain/punycode.hpp +++ b/include/skyr/domain/punycode.hpp @@ -30,7 +30,7 @@ constexpr auto initial_n = 0x80ul; constexpr auto delimiter = 0x2dul; } // namespace constants -constexpr inline auto adapt(uint32_t delta, uint32_t numpoints, bool firsttime) -> std::uint32_t { +constexpr auto adapt(uint32_t delta, uint32_t numpoints, bool firsttime) -> std::uint32_t { using namespace constants; delta = firsttime ? delta / damp : delta >> 1ul; @@ -154,7 +154,7 @@ inline auto punycode_encode(std::u32string_view input, std::string* output) -> s /// \param output The output UTF-32 string to store the decoded result /// \returns The decoded UTF-8 domain, or an error template -constexpr inline auto punycode_decode(StringView input, std::u32string* output) -> std::expected { +constexpr auto punycode_decode(StringView input, std::u32string* output) -> std::expected { using namespace punycode::constants; // decode_digit(cp) returns the numeric value of a basic code diff --git a/include/skyr/network/ipv4_address.hpp b/include/skyr/network/ipv4_address.hpp index 22580982..366c45d0 100644 --- a/include/skyr/network/ipv4_address.hpp +++ b/include/skyr/network/ipv4_address.hpp @@ -81,11 +81,11 @@ class ipv4_address { namespace details { /// Computes 256^exp efficiently using bit shifts (256 = 2^8, so 256^n = 2^(8n)) -constexpr inline auto pow256(unsigned int exp) noexcept -> std::uint64_t { +constexpr auto pow256(unsigned int exp) noexcept -> std::uint64_t { return 1ULL << (exp * 8); } -constexpr inline auto parse_ipv4_number(std::string_view input, bool* validation_error) +constexpr auto parse_ipv4_number(std::string_view input, bool* validation_error) -> std::expected { auto base = 10; @@ -116,7 +116,7 @@ constexpr inline auto parse_ipv4_number(std::string_view input, bool* validation /// \param input An input string /// \param validation_error Optional pointer to a bool that will be set if a validation error occurs /// \returns An `ipv4_address` object or an error -constexpr inline auto parse_ipv4_address(std::string_view input, bool* validation_error) +constexpr auto parse_ipv4_address(std::string_view input, bool* validation_error) -> std::expected { using namespace std::string_view_literals; diff --git a/include/skyr/network/ipv6_address.hpp b/include/skyr/network/ipv6_address.hpp index 1d72224b..cf585ea2 100644 --- a/include/skyr/network/ipv6_address.hpp +++ b/include/skyr/network/ipv6_address.hpp @@ -145,7 +145,7 @@ class ipv6_address { namespace details { template -constexpr inline auto hex_to_dec(charT byte) noexcept { +constexpr auto hex_to_dec(charT byte) noexcept { assert(std::isxdigit(byte, std::locale::classic())); if (std::isdigit(byte, std::locale::classic())) { @@ -160,7 +160,7 @@ constexpr inline auto hex_to_dec(charT byte) noexcept { /// \param input An input string /// \param validation_error Optional pointer to a bool that will be set if a validation error occurs /// \returns An `ipv6_address` object or an error -constexpr inline auto parse_ipv6_address(std::string_view input, bool* validation_error) +constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error) -> std::expected { using namespace std::string_view_literals; diff --git a/include/skyr/percent_encoding/percent_decode_range.hpp b/include/skyr/percent_encoding/percent_decode_range.hpp index 51b1ff9e..dd0be722 100644 --- a/include/skyr/percent_encoding/percent_decode_range.hpp +++ b/include/skyr/percent_encoding/percent_decode_range.hpp @@ -17,7 +17,7 @@ namespace skyr { namespace percent_encoding { namespace details { -constexpr inline auto alnum_to_hex(char value) noexcept -> std::expected { +constexpr auto alnum_to_hex(char value) noexcept -> std::expected { if ((value >= '0') && (value <= '9')) { return static_cast(value - '0'); } diff --git a/include/skyr/percent_encoding/percent_encoded_char.hpp b/include/skyr/percent_encoding/percent_encoded_char.hpp index 96db8e35..37bf4e37 100644 --- a/include/skyr/percent_encoding/percent_encoded_char.hpp +++ b/include/skyr/percent_encoding/percent_encoded_char.hpp @@ -16,7 +16,7 @@ namespace details { /// /// \param value /// \return -inline constexpr auto hex_to_alnum(std::byte value) noexcept { +constexpr auto hex_to_alnum(std::byte value) noexcept { if ((value >= std::byte(0x00)) && (value < std::byte(0x0a))) { return static_cast(std::to_integer(value) + '0'); } @@ -31,14 +31,14 @@ inline constexpr auto hex_to_alnum(std::byte value) noexcept { /// /// \param value /// \return -inline constexpr auto is_c0_control_byte(std::byte value) noexcept { +constexpr auto is_c0_control_byte(std::byte value) noexcept { return (value <= std::byte(0x1f)) || (value > std::byte(0x7e)); } /// /// \param value /// \return -inline constexpr auto is_fragment_byte(std::byte value) { +constexpr auto is_fragment_byte(std::byte value) { return is_c0_control_byte(value) || (value == std::byte(0x20)) || (value == std::byte(0x22)) || (value == std::byte(0x3c)) || (value == std::byte(0x3e)) || (value == std::byte(0x60)); } @@ -46,7 +46,7 @@ inline constexpr auto is_fragment_byte(std::byte value) { /// /// \param value /// \return -inline constexpr auto is_query_byte(std::byte value) { +constexpr auto is_query_byte(std::byte value) { return is_c0_control_byte(value) || (value == std::byte(0x20)) || (value == std::byte(0x22)) || (value == std::byte(0x23)) || (value == std::byte(0x3c)) || (value == std::byte(0x3e)); } @@ -54,14 +54,14 @@ inline constexpr auto is_query_byte(std::byte value) { /// /// \param value /// \return -inline constexpr auto is_special_query_byte(std::byte value) { +constexpr auto is_special_query_byte(std::byte value) { return is_query_byte(value) || (value == std::byte(0x27)); } /// /// \param value /// \return -inline constexpr auto is_path_byte(std::byte value) { +constexpr auto is_path_byte(std::byte value) { return is_query_byte(value) || (value == std::byte(0x3f)) || (value == std::byte(0x5e)) || (value == std::byte(0x60)) || (value == std::byte(0x7b)) || (value == std::byte(0x7d)); } @@ -69,7 +69,7 @@ inline constexpr auto is_path_byte(std::byte value) { /// /// \param value /// \return -inline constexpr auto is_userinfo_byte(std::byte value) { +constexpr auto is_userinfo_byte(std::byte value) { return is_path_byte(value) || (value == std::byte(0x2f)) || (value == std::byte(0x3a)) || (value == std::byte(0x3b)) || (value == std::byte(0x3d)) || (value == std::byte(0x40)) || (value == std::byte(0x5b)) || (value == std::byte(0x5c)) || (value == std::byte(0x5d)) || @@ -79,7 +79,7 @@ inline constexpr auto is_userinfo_byte(std::byte value) { /// /// \param value /// \return -inline constexpr auto is_component_byte(std::byte value) { +constexpr auto is_component_byte(std::byte value) { return is_userinfo_byte(value) || (value == std::byte(0x24)) || (value == std::byte(0x25)) || (value == std::byte(0x26)) || (value == std::byte(0x2b)) || (value == std::byte(0x2c)); } diff --git a/include/skyr/platform/endianness.hpp b/include/skyr/platform/endianness.hpp index 581dc47c..6477e656 100644 --- a/include/skyr/platform/endianness.hpp +++ b/include/skyr/platform/endianness.hpp @@ -14,7 +14,7 @@ namespace skyr { namespace details { template requires std::is_integral_v -constexpr inline auto swap_endianness(intT v) noexcept -> intT { +constexpr auto swap_endianness(intT v) noexcept -> intT { constexpr auto byte_count = sizeof(v); constexpr auto bit_count = 8ul; std::array bytes{}; @@ -31,13 +31,13 @@ constexpr inline auto swap_endianness(intT v) noexcept -> intT { template requires std::is_integral_v -constexpr inline auto to_network_byte_order(intT v) noexcept -> intT { +constexpr auto to_network_byte_order(intT v) noexcept -> intT { return (std::endian::big == std::endian::native) ? v : details::swap_endianness(v); // NOLINT } template requires std::is_integral_v -constexpr inline auto from_network_byte_order(intT v) noexcept -> intT { +constexpr auto from_network_byte_order(intT v) noexcept -> intT { return (std::endian::big == std::endian::native) ? v : details::swap_endianness(v); // NOLINT } } // namespace skyr diff --git a/include/skyr/unicode/code_point.hpp b/include/skyr/unicode/code_point.hpp index 5f5b2f26..32ad5766 100644 --- a/include/skyr/unicode/code_point.hpp +++ b/include/skyr/unicode/code_point.hpp @@ -18,7 +18,7 @@ namespace skyr::unicode { /// \param code_point /// \return template -constexpr inline auto u32_value(u8_code_point_view code_point) noexcept +constexpr auto u32_value(u8_code_point_view code_point) noexcept -> std::expected { constexpr auto to_value = [](auto&& state) { return state.value; }; return find_code_point(code_point.begin()).transform(to_value); @@ -29,7 +29,7 @@ constexpr inline auto u32_value(u8_code_point_view code_point) no /// \param code_point /// \return template -constexpr inline auto u32_value(std::expected, unicode_errc> code_point) noexcept +constexpr auto u32_value(std::expected, unicode_errc> code_point) noexcept -> std::expected { constexpr auto to_u32 = [](auto&& code_point) { return u32_value(code_point); }; return code_point.and_then(to_u32); @@ -38,14 +38,14 @@ constexpr inline auto u32_value(std::expected, /// /// \param code_point /// \return -constexpr inline auto u32_value(u16_code_point_t code_point) noexcept -> std::expected { +constexpr auto u32_value(u16_code_point_t code_point) noexcept -> std::expected { return code_point.u32_value(); } /// /// \param code_point /// \return -constexpr inline auto u32_value(std::expected code_point) noexcept +constexpr auto u32_value(std::expected code_point) noexcept -> std::expected { constexpr auto to_u32 = [](auto code_point) { return code_point.u32_value(); }; return code_point.and_then(to_u32); @@ -54,14 +54,14 @@ constexpr inline auto u32_value(std::expected co /// /// \param code_point /// \return -constexpr inline auto u32_value(char32_t code_point) noexcept -> std::expected { +constexpr auto u32_value(char32_t code_point) noexcept -> std::expected { return code_point; } /// /// \param code_point /// \return -constexpr inline auto u32_value(std::expected code_point) noexcept +constexpr auto u32_value(std::expected code_point) noexcept -> std::expected { return code_point; } @@ -71,7 +71,7 @@ constexpr inline auto u32_value(std::expected code_point /// \param code_point /// \return template -constexpr inline auto u16_value(u8_code_point_view code_point) +constexpr auto u16_value(u8_code_point_view code_point) -> std::expected { return u16_code_point(u32_value(code_point)); } @@ -81,7 +81,7 @@ constexpr inline auto u16_value(u8_code_point_view code_point) /// \param code_point /// \return template -constexpr inline auto u16_value(std::expected, unicode_errc> code_point) { +constexpr auto u16_value(std::expected, unicode_errc> code_point) { constexpr auto to_u16 = [](auto code_point) { return u16_code_point(code_point); }; return u32_value(code_point).transform(to_u16); } diff --git a/include/skyr/unicode/code_points/u16.hpp b/include/skyr/unicode/code_points/u16.hpp index b5d90cf7..03241878 100644 --- a/include/skyr/unicode/code_points/u16.hpp +++ b/include/skyr/unicode/code_points/u16.hpp @@ -60,14 +60,14 @@ class u16_code_point_t { /// /// \param code_point /// \return -inline constexpr auto u16_code_point(char32_t code_point) { +constexpr auto u16_code_point(char32_t code_point) { return u16_code_point_t(code_point); } /// /// \param code_point /// \return -inline constexpr auto u16_code_point(char16_t code_point) { +constexpr auto u16_code_point(char16_t code_point) { return u16_code_point_t(code_point); } @@ -75,7 +75,7 @@ inline constexpr auto u16_code_point(char16_t code_point) { /// \param lead_code_unit /// \param trail_code_unit /// \return -inline constexpr auto u16_code_point(char16_t lead_code_unit, char16_t trail_code_unit) { +constexpr auto u16_code_point(char16_t lead_code_unit, char16_t trail_code_unit) { return u16_code_point_t(lead_code_unit, trail_code_unit); } } // namespace skyr::unicode diff --git a/include/skyr/unicode/code_points/u8.hpp b/include/skyr/unicode/code_points/u8.hpp index c6c76bd6..cbc3442d 100644 --- a/include/skyr/unicode/code_points/u8.hpp +++ b/include/skyr/unicode/code_points/u8.hpp @@ -98,7 +98,7 @@ class u8_code_point_view { /// \param range /// \return template -inline constexpr auto u8_code_point(const OctetRange& range) +constexpr auto u8_code_point(const OctetRange& range) -> std::expected>, unicode_errc> { auto first = std::begin(range), last = std::end(range); auto length = sequence_length(*first); @@ -115,7 +115,7 @@ inline constexpr auto u8_code_point(const OctetRange& range) /// \param range /// \return template -inline constexpr auto checked_u8_code_point(const OctetRange& range) { +constexpr auto checked_u8_code_point(const OctetRange& range) { using result_type = std::expected>, unicode_errc>; constexpr auto check_code_point = [](auto&& code_point) -> result_type { diff --git a/include/skyr/unicode/core.hpp b/include/skyr/unicode/core.hpp index 029d5273..191029a9 100644 --- a/include/skyr/unicode/core.hpp +++ b/include/skyr/unicode/core.hpp @@ -19,7 +19,7 @@ namespace skyr::unicode { /// \param octet /// \return template -constexpr inline auto mask8(uintT value) { +constexpr auto mask8(uintT value) { static_assert(std::is_unsigned_v, "unsigned integral types only"); return static_cast(0xffu & value); } @@ -28,7 +28,7 @@ constexpr inline auto mask8(uintT value) { /// \param value /// \return template -constexpr inline auto mask16(uintT value) { +constexpr auto mask16(uintT value) { static_assert(std::is_unsigned_v, "unsigned integral types only"); return static_cast(0xffffu & value); } @@ -36,42 +36,42 @@ constexpr inline auto mask16(uintT value) { /// /// \param octet /// \return -constexpr inline auto is_trail(uint8_t octet) { +constexpr auto is_trail(uint8_t octet) { return ((mask8(octet) >> 6u) == 0x2u); } /// /// \param code_point /// \return -constexpr inline auto is_lead_surrogate(char16_t code_point) { +constexpr auto is_lead_surrogate(char16_t code_point) { return (code_point >= constants::surrogates::lead_min) && (code_point <= constants::surrogates::lead_max); } /// /// \param value /// \return -constexpr inline auto is_trail_surrogate(char16_t value) { +constexpr auto is_trail_surrogate(char16_t value) { return (value >= constants::surrogates::trail_min) && (value <= constants::surrogates::trail_max); } /// /// \param value /// \return -constexpr inline auto is_surrogate(char16_t value) { +constexpr auto is_surrogate(char16_t value) { return (value >= constants::surrogates::lead_min) && (value <= constants::surrogates::trail_max); } /// Tests if the code point is a valid value. /// \param code_point /// \return \c true if it has a valid value, \c false otherwise -constexpr inline auto is_valid_code_point(char32_t code_point) { +constexpr auto is_valid_code_point(char32_t code_point) { return (code_point <= constants::code_points::max) && !is_surrogate(static_cast(code_point)); } /// Returns the size of the sequnce given the lead octet value. /// \param lead_value /// \return 1, 2, 3 or 4 -constexpr inline auto sequence_length(uint8_t lead_value) { +constexpr auto sequence_length(uint8_t lead_value) { auto lead = mask8(lead_value); if (lead < 0x80u) { return 1; @@ -107,7 +107,7 @@ struct sequence_state { /// \return A sequence_state with a value of 0, and the iterator /// pointing to the lead value template -constexpr inline auto make_state(OctetIterator it) -> std::expected, unicode_errc> { +constexpr auto make_state(OctetIterator it) -> std::expected, unicode_errc> { return sequence_state(it, 0); } @@ -118,8 +118,7 @@ constexpr inline auto make_state(OctetIterator it) -> std::expected -constexpr inline auto update_value(sequence_state state, char32_t value) - -> sequence_state { +constexpr auto update_value(sequence_state state, char32_t value) -> sequence_state { return {state.it, value}; } @@ -129,7 +128,7 @@ constexpr inline auto update_value(sequence_state state, char32_t /// \return The new state with the updated iterator, on an error if /// the sequence isn't valid template -constexpr inline auto increment(sequence_state state) +constexpr auto increment(sequence_state state) -> std::expected, unicode_errc> { ++state.it; if (!is_trail(*state.it)) { @@ -144,7 +143,7 @@ namespace details { /// \param state /// \return template -constexpr inline auto mask_byte(sequence_state state) +constexpr auto mask_byte(sequence_state state) -> std::expected, unicode_errc> { return update_value(state, static_cast(mask8(static_cast(*state.it)))); } @@ -175,7 +174,7 @@ constexpr auto from_two_byte_sequence(OctetIterator first) /// \param first /// \return template -constexpr inline auto from_three_byte_sequence(OctetIterator first) +constexpr auto from_three_byte_sequence(OctetIterator first) -> std::expected, unicode_errc> { using result_type = std::expected, unicode_errc>; @@ -202,7 +201,7 @@ constexpr inline auto from_three_byte_sequence(OctetIterator first) /// \param first /// \return template -constexpr inline auto from_four_byte_sequence(OctetIterator first) +constexpr auto from_four_byte_sequence(OctetIterator first) -> std::expected, unicode_errc> { using result_type = std::expected, unicode_errc>; @@ -237,8 +236,7 @@ constexpr inline auto from_four_byte_sequence(OctetIterator first) /// \param first /// \return template -constexpr inline auto find_code_point(OctetIterator first) - -> std::expected, unicode_errc> { +constexpr auto find_code_point(OctetIterator first) -> std::expected, unicode_errc> { const auto length = sequence_length(*first); switch (length) { case 1: diff --git a/include/skyr/unicode/ranges/views/u16_view.hpp b/include/skyr/unicode/ranges/views/u16_view.hpp index c187918c..8803ee97 100644 --- a/include/skyr/unicode/ranges/views/u16_view.hpp +++ b/include/skyr/unicode/ranges/views/u16_view.hpp @@ -174,7 +174,7 @@ namespace views { /// \param range /// \return template -constexpr inline auto as_u16(const U16Range& range) { +constexpr auto as_u16(const U16Range& range) { static_assert(sizeof(traits::range_value_t) >= 2); return view_u16_range{range}; } diff --git a/include/skyr/unicode/ranges/views/u8_view.hpp b/include/skyr/unicode/ranges/views/u8_view.hpp index ba2fff7a..979aa04c 100644 --- a/include/skyr/unicode/ranges/views/u8_view.hpp +++ b/include/skyr/unicode/ranges/views/u8_view.hpp @@ -165,7 +165,7 @@ namespace views { /// \param range /// \return template -constexpr inline auto as_u8(const OctetRange& range) { +constexpr auto as_u8(const OctetRange& range) { static_assert(sizeof(traits::range_value_t) >= 1); return view_u8_range{range}; } diff --git a/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp b/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp index 9e501b0f..7ec2eaa1 100644 --- a/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp +++ b/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp @@ -160,7 +160,7 @@ namespace views { /// \param range /// \return template -[[maybe_unused]] constexpr inline auto unchecked_u8(const OctetRange& range) { +[[maybe_unused]] constexpr auto unchecked_u8(const OctetRange& range) { return view_unchecked_u8_range{range}; } } // namespace views From 7e7910324bc547515e6757f70d403881824f83a4 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 4 Jan 2026 11:07:11 +0100 Subject: [PATCH 2/7] Resolve 'cppcoreguidelines-pro-type-member-init' clang-tidy warnings --- .github/workflows/documentation.yml | 3 ++ include/skyr/containers/static_vector.hpp | 2 +- include/skyr/core/host.hpp | 2 +- include/skyr/core/parse_query.hpp | 4 +-- include/skyr/core/url_parser_context.hpp | 8 ++--- include/skyr/core/url_record.hpp | 16 +++++----- include/skyr/domain/domain.hpp | 30 +++++++++---------- .../percent_encoding/percent_decode_range.hpp | 2 +- .../percent_encoding/percent_encoded_char.hpp | 2 +- .../ranges/transforms/u8_transform.hpp | 2 +- include/skyr/unicode/ranges/views/u8_view.hpp | 4 +-- .../ranges/views/unchecked_u8_view.hpp | 2 +- include/skyr/url.hpp | 8 ++--- include/skyr/url_search_parameters.hpp | 4 +-- 14 files changed, 46 insertions(+), 43 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 4c9dafb6..75a554fd 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -43,6 +43,7 @@ jobs: run: | git clone https://github.com/Microsoft/vcpkg.git ./vcpkg/bootstrap-vcpkg.sh + vcpkg install nlohmann-json - name: Configure CMake run: | @@ -51,6 +52,8 @@ jobs: -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -Dskyr_BUILD_TESTS=OFF \ + -Dskyr_BUILD_DOCS=ON \ . - name: Build documentation diff --git a/include/skyr/containers/static_vector.hpp b/include/skyr/containers/static_vector.hpp index 40319650..cf699bb4 100644 --- a/include/skyr/containers/static_vector.hpp +++ b/include/skyr/containers/static_vector.hpp @@ -20,7 +20,7 @@ namespace skyr { template class static_vector { private: - alignas(T) std::array storage_; + alignas(T) std::array storage_{}; std::size_t size_ = 0; auto data_ptr() noexcept -> T* { diff --git a/include/skyr/core/host.hpp b/include/skyr/core/host.hpp index 783b5c66..eb723e54 100644 --- a/include/skyr/core/host.hpp +++ b/include/skyr/core/host.hpp @@ -139,7 +139,7 @@ class host { } private: - host_types host_; + host_types host_{}; }; namespace details { diff --git a/include/skyr/core/parse_query.hpp b/include/skyr/core/parse_query.hpp index 425de6b7..81aa3e8a 100644 --- a/include/skyr/core/parse_query.hpp +++ b/include/skyr/core/parse_query.hpp @@ -15,8 +15,8 @@ namespace skyr { /// struct query_parameter { - std::string name; - std::optional value; + std::string name{}; + std::optional value{}; /// Constructor query_parameter() = default; diff --git a/include/skyr/core/url_parser_context.hpp b/include/skyr/core/url_parser_context.hpp index cbe684d9..c5e39a8c 100644 --- a/include/skyr/core/url_parser_context.hpp +++ b/include/skyr/core/url_parser_context.hpp @@ -101,12 +101,12 @@ class url_parser_context { private: url_record url; url_parse_state state; - std::string_view input; - std::string_view::const_iterator input_it; + std::string_view input{}; + std::string_view::const_iterator input_it{}; bool* validation_error; const url_record* base; - std::optional state_override; - std::string buffer; + std::optional state_override{}; + std::string buffer{}; bool at_flag; bool square_braces_flag; diff --git a/include/skyr/core/url_record.hpp b/include/skyr/core/url_record.hpp index e8bea79e..aa889c62 100644 --- a/include/skyr/core/url_record.hpp +++ b/include/skyr/core/url_record.hpp @@ -23,23 +23,23 @@ class url_record { using string_type = std::string; /// An ASCII string that identifies the type of URL - string_type scheme; + string_type scheme{}; /// An ASCII string identifying a username - string_type username; + string_type username{}; /// An ASCII string identifying a password - string_type password; + string_type password{}; /// An optional URL host, either a domain, IPv4 or IPv6 address, /// an opaque host, or empty - std::optional<::skyr::host> host; + std::optional<::skyr::host> host{}; /// An optional network port - std::optional port; + std::optional port{}; /// A list of zero or more ASCII strings, used to identify a /// location in a hierarchical form - std::vector path; + std::vector path{}; /// An optional ASCII string - std::optional query; + std::optional query{}; /// An optional ASCII string - std::optional fragment; + std::optional fragment{}; /// A Boolean value indicating whether this URL can be used as a /// base URL diff --git a/include/skyr/domain/domain.hpp b/include/skyr/domain/domain.hpp index 6de17a19..6333aa3e 100644 --- a/include/skyr/domain/domain.hpp +++ b/include/skyr/domain/domain.hpp @@ -65,21 +65,21 @@ constexpr auto validate_label(std::u32string_view label, [[maybe_unused]] bool u /// struct domain_to_ascii_context { /// Stores the domain as UTF-32 - std::u32string domain_name; + std::u32string domain_name{}; /// Parameters - std::string* ascii_domain; - bool check_hyphens; - bool check_bidi; - bool check_joiners; - bool use_std3_ascii_rules; - bool transitional_processing; - bool verify_dns_length; + std::string* ascii_domain{}; + bool check_hyphens{}; + bool check_bidi{}; + bool check_joiners{}; + bool use_std3_ascii_rules{}; + bool transitional_processing{}; + bool verify_dns_length{}; // These are intermediate buffers - std::vector labels; - std::string punycode_encoded; - std::u32string punycode_decoded; + std::vector labels{}; + std::string punycode_encoded{}; + std::u32string punycode_decoded{}; }; /// @@ -296,15 +296,15 @@ inline auto domain_to_ascii(std::string_view domain_name, std::string* ascii_dom } struct domain_to_u8_context { - std::string_view domain_name; + std::string_view domain_name{}; /// Parameters - std::string* u8_domain; + std::string* u8_domain{}; - std::vector labels; + std::vector labels{}; /// This is used as an intermediate buffer - std::u32string punycode_decoded; + std::u32string punycode_decoded{}; }; /// diff --git a/include/skyr/percent_encoding/percent_decode_range.hpp b/include/skyr/percent_encoding/percent_decode_range.hpp index dd0be722..c33e36e0 100644 --- a/include/skyr/percent_encoding/percent_decode_range.hpp +++ b/include/skyr/percent_encoding/percent_decode_range.hpp @@ -118,7 +118,7 @@ class percent_decode_iterator { remainder_.remove_prefix(step); } - std::string_view remainder_; + std::string_view remainder_{}; }; /// diff --git a/include/skyr/percent_encoding/percent_encoded_char.hpp b/include/skyr/percent_encoding/percent_encoded_char.hpp index 37bf4e37..41ab0bc1 100644 --- a/include/skyr/percent_encoding/percent_encoded_char.hpp +++ b/include/skyr/percent_encoding/percent_encoded_char.hpp @@ -187,7 +187,7 @@ struct percent_encoded_char { } private: - impl_type impl_; + impl_type impl_{}; }; /// diff --git a/include/skyr/unicode/ranges/transforms/u8_transform.hpp b/include/skyr/unicode/ranges/transforms/u8_transform.hpp index 78b35e45..8f33b56f 100644 --- a/include/skyr/unicode/ranges/transforms/u8_transform.hpp +++ b/include/skyr/unicode/ranges/transforms/u8_transform.hpp @@ -205,7 +205,7 @@ class transform_u8_range { } private: - iterator_type first_; + iterator_type first_{}; }; /// diff --git a/include/skyr/unicode/ranges/views/u8_view.hpp b/include/skyr/unicode/ranges/views/u8_view.hpp index 979aa04c..1640ff6d 100644 --- a/include/skyr/unicode/ranges/views/u8_view.hpp +++ b/include/skyr/unicode/ranges/views/u8_view.hpp @@ -96,7 +96,7 @@ class u8_range_iterator { } private: - iterator_type it_; + iterator_type it_{}; }; /// @@ -156,7 +156,7 @@ class view_u8_range { } private: - iterator_type it_; + iterator_type it_{}; }; namespace views { diff --git a/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp b/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp index 7ec2eaa1..4932bd4f 100644 --- a/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp +++ b/include/skyr/unicode/ranges/views/unchecked_u8_view.hpp @@ -151,7 +151,7 @@ class view_unchecked_u8_range { } private: - iterator_type it_; + iterator_type it_{}; }; namespace views { diff --git a/include/skyr/url.hpp b/include/skyr/url.hpp index 642d7fe7..e410af11 100644 --- a/include/skyr/url.hpp +++ b/include/skyr/url.hpp @@ -52,7 +52,7 @@ class url_parse_error : public std::runtime_error { } private: - std::error_code code_; + std::error_code code_{}; }; /// This class represents a URL. Parsing on construction is @@ -1242,9 +1242,9 @@ class url { } url_record url_; - std::string href_; - string_view view_; - url_search_parameters parameters_; + std::string href_{}; + string_view view_{}; + url_search_parameters parameters_{}; }; /// Swaps two `url` objects diff --git a/include/skyr/url_search_parameters.hpp b/include/skyr/url_search_parameters.hpp index 9aeed350..ee2470d9 100644 --- a/include/skyr/url_search_parameters.hpp +++ b/include/skyr/url_search_parameters.hpp @@ -31,7 +31,7 @@ struct is_name { return name_ == parameter.name; } - std::string_view name_; + std::string_view name_{}; }; } // namespace details @@ -250,7 +250,7 @@ class url_search_parameters { void update(); - std::vector parameters_; + std::vector parameters_{}; url* url_ = nullptr; }; From 9c394b42e9803b33d808dc5b9975aba1aefdd592 Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Sun, 4 Jan 2026 11:52:33 +0100 Subject: [PATCH 3/7] Address cppcoreguidelines-avoid-magic-numbers warnings --- include/skyr/core/schemes.hpp | 6 ++-- include/skyr/domain/punycode.hpp | 10 ++++--- include/skyr/network/ipv4_address.hpp | 30 +++++++++++-------- include/skyr/network/ipv6_address.hpp | 25 +++++++++------- include/skyr/unicode/code_points/u16.hpp | 13 +++++--- include/skyr/unicode/core.hpp | 14 ++++----- .../ranges/transforms/u8_transform.hpp | 6 ++-- 7 files changed, 60 insertions(+), 44 deletions(-) diff --git a/include/skyr/core/schemes.hpp b/include/skyr/core/schemes.hpp index f7d41288..a5e06d44 100644 --- a/include/skyr/core/schemes.hpp +++ b/include/skyr/core/schemes.hpp @@ -22,11 +22,11 @@ constexpr auto is_special(std::string_view scheme) noexcept -> bool { /// \returns constexpr auto default_port(std::string_view scheme) noexcept -> std::optional { if (scheme == "ftp") { - return 21; + return 21; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } else if ((scheme == "http") || (scheme == "ws")) { - return 80; + return 80; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } else if ((scheme == "https") || (scheme == "wss")) { - return 443; + return 443; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } return std::nullopt; } diff --git a/include/skyr/domain/punycode.hpp b/include/skyr/domain/punycode.hpp index 186c1aa2..076c3530 100644 --- a/include/skyr/domain/punycode.hpp +++ b/include/skyr/domain/punycode.hpp @@ -41,7 +41,7 @@ constexpr auto adapt(uint32_t delta, uint32_t numpoints, bool firsttime) -> std: delta /= base - tmin; k += base; } - return k + (base - tmin + 1ul) * delta / (delta + skew); + return k + ((base - tmin + 1ul) * delta / (delta + skew)); } } // namespace punycode @@ -54,7 +54,7 @@ constexpr auto adapt(uint32_t delta, uint32_t numpoints, bool firsttime) -> std: inline auto punycode_encode(std::u32string_view input, std::string* output) -> std::expected { using namespace punycode::constants; - constexpr auto is_ascii_value = [](auto c) { return c < 0x80; }; + constexpr auto is_ascii_value = [](auto c) { return c < 0x80; }; // NOLINT(cppcoreguidelines-avoid-magic-numbers) constexpr auto to_char = [](auto c) { return static_cast(c); }; // encode_digit(d,flag) returns the basic code point whose value @@ -62,8 +62,10 @@ inline auto punycode_encode(std::u32string_view input, std::string* output) -> s // the range 0 to base-1. The lowercase form is used unless flag is // nonzero, in which case the uppercase form is used. The behavior // is undefined if flag is nonzero and digit d has no uppercase form. - constexpr auto encode_digit = [](std::uint32_t d, std::uint32_t flag) -> char { - return d + 0x16ul + (0x4bul * (d < 0x1aul)) - ((flag != 0ul) << 0x5ul); + constexpr auto encode_digit = [](const std::uint32_t d, const std::uint32_t flag) -> char { + return static_cast(d + 0x16ul + (0x4bul * (d < 0x1aul)) - + ((flag != 0ul) << 0x5ul) // NOLINT(cppcoreguidelines-avoid-magic-numbers) + ); // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 }; diff --git a/include/skyr/network/ipv4_address.hpp b/include/skyr/network/ipv4_address.hpp index 366c45d0..1154f814 100644 --- a/include/skyr/network/ipv4_address.hpp +++ b/include/skyr/network/ipv4_address.hpp @@ -57,9 +57,11 @@ class ipv4_address { /// The address in bytes in network byte order /// \returns The address in bytes [[nodiscard]] constexpr auto to_bytes() const noexcept -> std::array { - auto addr = address(); - return {{static_cast(addr >> 24u), static_cast(addr >> 16u), - static_cast(addr >> 8u), static_cast(addr)}}; + const auto addr = address(); + return {{static_cast(addr >> 24u), + static_cast(addr >> 16u), // NOLINT(cppcoreguidelines-avoid-magic-numbers) + static_cast(addr >> 8u), + static_cast(addr)}}; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// \returns The address as a string @@ -67,13 +69,15 @@ class ipv4_address { using namespace std::string_literals; using namespace std::string_view_literals; - constexpr auto separator = [](auto i) { return (i < 4) ? "."sv : ""sv; }; + constexpr auto separator = [](auto i) { + return (i < 4) ? "."sv : ""sv; + }; // NOLINT(cppcoreguidelines-avoid-magic-numbers) auto output = ""s; auto n = address(); for (auto i = 1U; i <= 4U; ++i) { output = std::format("{}{}{}", separator(i), n % 256, output); - n >>= 8; + n >>= 8; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } return output; } @@ -82,21 +86,21 @@ class ipv4_address { namespace details { /// Computes 256^exp efficiently using bit shifts (256 = 2^8, so 256^n = 2^(8n)) constexpr auto pow256(unsigned int exp) noexcept -> std::uint64_t { - return 1ULL << (exp * 8); + return 1ULL << (exp * 8); // NOLINT(cppcoreguidelines-avoid-magic-numbers) } constexpr auto parse_ipv4_number(std::string_view input, bool* validation_error) -> std::expected { - auto base = 10; + auto base = 10; // NOLINT(cppcoreguidelines-avoid-magic-numbers) if ((input.size() >= 2) && (input[0] == '0') && (std::tolower(input[1], std::locale::classic()) == 'x')) { *validation_error |= true; input = input.substr(2); - base = 16; + base = 16; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } else if ((input.size() >= 2) && (input[0] == '0')) { *validation_error |= true; input = input.substr(1); - base = 8; + base = 8; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } if (input.empty()) { @@ -162,7 +166,9 @@ constexpr auto parse_ipv4_address(std::string_view input, bool* validation_error numbers.push_back(number.value()); } - constexpr auto greater_than_255 = [](auto number) { return number > 255; }; + constexpr auto greater_than_255 = [](auto number) { + return number > 255; + }; // NOLINT(cppcoreguidelines-avoid-magic-numbers) if (std::ranges::cend(numbers) != std::ranges::find_if(numbers, greater_than_255)) { *validation_error |= true; @@ -176,7 +182,7 @@ constexpr auto parse_ipv4_address(std::string_view input, bool* validation_error return std::unexpected(ipv4_address_errc::overflow); } - if (numbers.back() >= details::pow256(5 - numbers.size())) { + if (numbers.back() >= details::pow256(5 - numbers.size())) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) *validation_error |= true; return std::unexpected(ipv4_address_errc::overflow); } @@ -186,7 +192,7 @@ constexpr auto parse_ipv4_address(std::string_view input, bool* validation_error auto counter = 0UL; for (auto&& number : numbers) { - ipv4 += number * details::pow256(3 - counter); + ipv4 += number * details::pow256(3 - counter); // NOLINT(cppcoreguidelines-avoid-magic-numbers) ++counter; } return ipv4_address(static_cast(ipv4)); diff --git a/include/skyr/network/ipv6_address.hpp b/include/skyr/network/ipv6_address.hpp index cf585ea2..ca658514 100644 --- a/include/skyr/network/ipv6_address.hpp +++ b/include/skyr/network/ipv6_address.hpp @@ -120,7 +120,7 @@ class ipv6_address { } auto ignore0 = false; - for (auto i = 0UL; i <= 7UL; ++i) { + for (auto i = 0UL; i <= 7UL; ++i) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) if (ignore0 && (address[i] == 0)) { // NOLINT continue; } else if (ignore0) { @@ -181,7 +181,7 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error } while (it != last) { - if (piece_index == 8) { + if (piece_index == 8) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) *validation_error |= true; return std::unexpected(ipv6_address_errc::invalid_piece); } @@ -202,7 +202,8 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error auto length = 0; while ((it != last) && ((length < 4) && std::isxdigit(*it, std::locale::classic()))) { - value = value * 0x10 + details::hex_to_dec(*it); + value = + (value * 0x10) + details::hex_to_dec(*it); // NOLINT(cppcoreguidelines-avoid-magic-numbers) ++it; ++length; } @@ -215,7 +216,7 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error std::ranges::advance(it, -length); - if (piece_index > 6) { + if (piece_index > 6) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) *validation_error |= true; return std::unexpected(ipv6_address_errc::invalid_ipv4_segment_number); } @@ -226,7 +227,7 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error auto ipv4_piece = std::optional(); if (numbers_seen > 0) { - if ((*it == '.') && (numbers_seen < 4)) { + if ((*it == '.') && (numbers_seen < 4)) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) ++it; } else { *validation_error |= true; @@ -247,10 +248,10 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error *validation_error |= true; return std::unexpected(ipv6_address_errc::invalid_ipv4_segment_number); } else { - ipv4_piece = ipv4_piece.value() * 10 + number; + ipv4_piece = (ipv4_piece.value() * 10) + number; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } - if (ipv4_piece.value() > 255) { + if (ipv4_piece.value() > 255) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) *validation_error |= true; return std::unexpected(ipv6_address_errc::invalid_ipv4_segment_number); } @@ -258,7 +259,8 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error ++it; } - address[piece_index] = static_cast((address[piece_index] << 8) + ipv4_piece.value()); // NOLINT + address[piece_index] = static_cast( + (address[piece_index] << 8) + ipv4_piece.value()); // NOLINT(cppcoreguidelines-avoid-magic-numbers) ++numbers_seen; if ((numbers_seen == 2) || (numbers_seen == 4)) { @@ -288,13 +290,14 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error if (compress) { auto swaps = piece_index - compress.value(); - piece_index = 7; + piece_index = 7; // NOLINT(cppcoreguidelines-avoid-magic-numbers) while ((piece_index != 0) && (swaps > 0)) { - std::swap(address[piece_index], address[compress.value() + swaps - 1]); // NOLINT + std::swap(address[piece_index], + address[compress.value() + swaps - 1]); // NOLINT(cppcoreguidelines-avoid-magic-numbers) --piece_index; --swaps; } - } else if (!compress && (piece_index != 8)) { + } else if (!compress && (piece_index != 8)) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) *validation_error |= true; return std::unexpected(ipv6_address_errc::compress_expected); } diff --git a/include/skyr/unicode/code_points/u16.hpp b/include/skyr/unicode/code_points/u16.hpp index 03241878..66a281a4 100644 --- a/include/skyr/unicode/code_points/u16.hpp +++ b/include/skyr/unicode/code_points/u16.hpp @@ -27,7 +27,8 @@ class u16_code_point_t { } constexpr u16_code_point_t(char16_t lead_value, char16_t trail_value) - : code_point_((lead_value << 10U) + trail_value + constants::surrogates::offset) { + : code_point_((lead_value << 10U) + trail_value + + constants::surrogates::offset) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// @@ -39,14 +40,18 @@ class u16_code_point_t { /// /// \return [[nodiscard]] auto lead_value() const { - return is_surrogate_pair() ? static_cast((code_point_ >> 10U) + constants::surrogates::lead_offset) - : static_cast(code_point_); + return is_surrogate_pair() + ? static_cast( + (code_point_ >> 10U) + + constants::surrogates::lead_offset) // NOLINT(cppcoreguidelines-avoid-magic-numbers) + : static_cast(code_point_); } /// /// \return [[nodiscard]] constexpr auto trail_value() const { - return is_surrogate_pair() ? static_cast((code_point_ & 0x3ffU) + constants::surrogates::trail_min) : 0; + return is_surrogate_pair() ? static_cast((code_point_ & 0x3ffU) + constants::surrogates::trail_min) + : 0; // NOLINT(cppcoreguidelines-avoid-magic-numbers) } [[nodiscard]] constexpr auto u32_value() const noexcept -> std::expected { diff --git a/include/skyr/unicode/core.hpp b/include/skyr/unicode/core.hpp index 191029a9..ec13c284 100644 --- a/include/skyr/unicode/core.hpp +++ b/include/skyr/unicode/core.hpp @@ -21,7 +21,7 @@ namespace skyr::unicode { template constexpr auto mask8(uintT value) { static_assert(std::is_unsigned_v, "unsigned integral types only"); - return static_cast(0xffu & value); + return static_cast(0xffu & value); // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// @@ -30,14 +30,14 @@ constexpr auto mask8(uintT value) { template constexpr auto mask16(uintT value) { static_assert(std::is_unsigned_v, "unsigned integral types only"); - return static_cast(0xffffu & value); + return static_cast(0xffffu & value); // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// /// \param octet /// \return constexpr auto is_trail(uint8_t octet) { - return ((mask8(octet) >> 6u) == 0x2u); + return ((mask8(octet) >> 6u) == 0x2u); // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// @@ -73,13 +73,13 @@ constexpr auto is_valid_code_point(char32_t code_point) { /// \return 1, 2, 3 or 4 constexpr auto sequence_length(uint8_t lead_value) { auto lead = mask8(lead_value); - if (lead < 0x80u) { + if (lead < 0x80u) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 1; - } else if ((lead >> 5u) == 0x6u) { + } else if ((lead >> 5u) == 0x6u) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 2; - } else if ((lead >> 4u) == 0xeu) { + } else if ((lead >> 4u) == 0xeu) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 3; - } else if ((lead >> 3u) == 0x1eu) { + } else if ((lead >> 3u) == 0x1eu) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 4; } return 0; diff --git a/include/skyr/unicode/ranges/transforms/u8_transform.hpp b/include/skyr/unicode/ranges/transforms/u8_transform.hpp index 8f33b56f..c6ddabb3 100644 --- a/include/skyr/unicode/ranges/transforms/u8_transform.hpp +++ b/include/skyr/unicode/ranges/transforms/u8_transform.hpp @@ -121,11 +121,11 @@ class u8_transform_iterator { private: constexpr void increment() { constexpr auto octet_count = [](char32_t code_point) { - if (code_point < 0x80u) { + if (code_point < 0x80u) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 1; - } else if (code_point < 0x800u) { + } else if (code_point < 0x800u) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 2; - } else if (code_point < 0x10000u) { + } else if (code_point < 0x10000u) { // NOLINT(cppcoreguidelines-avoid-magic-numbers) return 3; } else { return 4; From bb8f3bb1ee96eaa2f66fa87ea849f8754423595f Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Tue, 9 Jun 2026 19:50:05 +0200 Subject: [PATCH 4/7] Replace forward with move --- include/skyr/domain/domain.hpp | 6 +++--- include/skyr/unicode/ranges/transforms/u16_transform.hpp | 4 ++-- include/skyr/unicode/ranges/transforms/u32_transform.hpp | 4 ++-- include/skyr/unicode/ranges/transforms/u8_transform.hpp | 2 +- include/skyr/url.hpp | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/skyr/domain/domain.hpp b/include/skyr/domain/domain.hpp index 6333aa3e..83b20ad3 100644 --- a/include/skyr/domain/domain.hpp +++ b/include/skyr/domain/domain.hpp @@ -117,7 +117,7 @@ inline auto create_domain_to_ascii_context(std::string_view domain_name, std::st /// /// \param context /// \return -inline auto domain_to_ascii_impl(domain_to_ascii_context&& context) -> std::expected { +inline auto domain_to_ascii_impl(domain_to_ascii_context context) -> std::expected { /// https://www.unicode.org/reports/tr46/#ToASCII constexpr auto map_domain_name = @@ -209,7 +209,7 @@ inline auto domain_to_ascii_impl(domain_to_ascii_context&& context) -> std::expe return std::move(ctx); }; - constexpr auto copy_to_output = [](domain_to_ascii_context&& ctx) -> std::expected { + constexpr auto copy_to_output = [](domain_to_ascii_context ctx) -> std::expected { for (auto it = ctx.labels.begin(); it != ctx.labels.end(); ++it) { if (it != ctx.labels.begin()) { ctx.ascii_domain->push_back('.'); @@ -310,7 +310,7 @@ struct domain_to_u8_context { /// /// \param context /// \return -inline auto domain_to_u8_impl(domain_to_u8_context&& context) -> std::expected { +inline auto domain_to_u8_impl(domain_to_u8_context context) -> std::expected { static constexpr auto to_string_view = [](auto&& label) { return std::string_view(std::addressof(*std::begin(label)), std::ranges::distance(label)); }; diff --git a/include/skyr/unicode/ranges/transforms/u16_transform.hpp b/include/skyr/unicode/ranges/transforms/u16_transform.hpp index 7a98edd7..ab7d49b1 100644 --- a/include/skyr/unicode/ranges/transforms/u16_transform.hpp +++ b/include/skyr/unicode/ranges/transforms/u16_transform.hpp @@ -106,7 +106,7 @@ class transform_u16_range { /// /// \param range - explicit constexpr transform_u16_range(CodePointRange&& range) : range_{std::forward(range)} { + explicit constexpr transform_u16_range(CodePointRange&& range) : range_{std::move(range)} { } /// Returns an iterator to the beginning @@ -175,7 +175,7 @@ static constexpr transform_u16_range_fn to_u16; /// \param range /// \return template -auto as(transform_u16_range&& range) -> std::expected { +auto as(const transform_u16_range& range) -> std::expected { auto result = Output{}; for (auto it = std::cbegin(range); it != std::cend(range); ++it) { diff --git a/include/skyr/unicode/ranges/transforms/u32_transform.hpp b/include/skyr/unicode/ranges/transforms/u32_transform.hpp index 9520dc0a..8c6bc8dd 100644 --- a/include/skyr/unicode/ranges/transforms/u32_transform.hpp +++ b/include/skyr/unicode/ranges/transforms/u32_transform.hpp @@ -99,7 +99,7 @@ class transform_u32_range { /// /// \param range - explicit constexpr transform_u32_range(CodePointRange&& range) : range_(std::forward(range)) { + explicit constexpr transform_u32_range(CodePointRange&& range) : range_(std::move(range)) { } /// @@ -168,7 +168,7 @@ static constexpr transform_u32_range_fn to_u32; /// \param range /// \return template -constexpr auto as(transform_u32_range&& range) -> std::expected { +constexpr auto as(const transform_u32_range& range) -> std::expected { auto result = Output{}; for (auto it = std::cbegin(range); it != std::cend(range); ++it) { diff --git a/include/skyr/unicode/ranges/transforms/u8_transform.hpp b/include/skyr/unicode/ranges/transforms/u8_transform.hpp index c6ddabb3..e07ad34b 100644 --- a/include/skyr/unicode/ranges/transforms/u8_transform.hpp +++ b/include/skyr/unicode/ranges/transforms/u8_transform.hpp @@ -239,7 +239,7 @@ static constexpr u8_range_fn to_u8; /// \param range /// \return template -constexpr auto as(transform_u8_range&& range) -> std::expected { +constexpr auto as(const transform_u8_range& range) -> std::expected { auto result = Output{}; for (auto it = std::cbegin(range); it != std::cend(range); ++it) { diff --git a/include/skyr/url.hpp b/include/skyr/url.hpp index e410af11..10463dcd 100644 --- a/include/skyr/url.hpp +++ b/include/skyr/url.hpp @@ -124,7 +124,7 @@ class url { /// /// \param input A URL record explicit url(url_record&& input) : url() { - update_record(std::forward(input)); + update_record(std::move(input)); } /// Copy constructor From bd146a2ebc10314f4cc1691449283bbec672f86d Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Tue, 9 Jun 2026 19:59:00 +0200 Subject: [PATCH 5/7] Fix some readability issues --- include/skyr/core/check_input.hpp | 6 ++++-- include/skyr/core/url_parser_context.hpp | 3 ++- include/skyr/domain/idna.hpp | 9 ++++++--- include/skyr/network/ipv6_address.hpp | 6 ++++-- include/skyr/unicode/code_points/u8.hpp | 3 ++- include/skyr/url_search_parameters.hpp | 15 ++++++++++----- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/include/skyr/core/check_input.hpp b/include/skyr/core/check_input.hpp index 17ae4311..693b0438 100644 --- a/include/skyr/core/check_input.hpp +++ b/include/skyr/core/check_input.hpp @@ -17,7 +17,8 @@ constexpr static auto is_c0_control_or_space = [](auto byte) { }; constexpr auto remove_leading_c0_control_or_space(std::string_view input, bool* validation_error) { - auto first = std::cbegin(input), last = std::cend(input); + auto first = std::cbegin(input); + auto last = std::cend(input); auto it = std::find_if_not(first, last, is_c0_control_or_space); *validation_error |= (it != first); input.remove_prefix(std::distance(first, it)); @@ -25,7 +26,8 @@ constexpr auto remove_leading_c0_control_or_space(std::string_view input, bool* } constexpr auto remove_trailing_c0_control_or_space(std::string_view input, bool* validation_error) { - auto first = std::crbegin(input), last = std::crend(input); + auto first = std::crbegin(input); + auto last = std::crend(input); auto it = std::find_if_not(first, last, is_c0_control_or_space); *validation_error |= (it != first); input.remove_suffix(std::distance(first, it)); diff --git a/include/skyr/core/url_parser_context.hpp b/include/skyr/core/url_parser_context.hpp index c5e39a8c..3120250c 100644 --- a/include/skyr/core/url_parser_context.hpp +++ b/include/skyr/core/url_parser_context.hpp @@ -29,7 +29,8 @@ using namespace std::string_view_literals; namespace details { constexpr auto contains(std::string_view view, char element) noexcept { - auto first = std::cbegin(view), last = std::cend(view); + auto first = std::cbegin(view); + auto last = std::cend(view); return last != std::find(first, last, element); } diff --git a/include/skyr/domain/idna.hpp b/include/skyr/domain/idna.hpp index ba510dd0..dda3524c 100644 --- a/include/skyr/domain/idna.hpp +++ b/include/skyr/domain/idna.hpp @@ -19,7 +19,8 @@ namespace skyr::idna { constexpr auto code_point_status(char32_t code_point) -> idna_status { constexpr auto less = [](const auto& range, auto code_point) { return range.last < code_point; }; - auto first = std::cbegin(details::statuses), last = std::cend(details::statuses); + auto first = std::cbegin(details::statuses); + auto last = std::cend(details::statuses); auto it = std::lower_bound(first, last, code_point, less); return (it == last) || !((code_point >= (*it).first) && (code_point <= (*it).last)) ? idna_status::valid : it->status; } @@ -28,7 +29,8 @@ namespace details { constexpr auto map_code_point_16(char16_t code_point) -> char16_t { constexpr auto less = [](const auto& lhs, auto rhs) { return lhs.code_point < rhs; }; - auto first = std::cbegin(mapped_16), last = std::cend(mapped_16); + auto first = std::cbegin(mapped_16); + auto last = std::cend(mapped_16); auto it = std::lower_bound(first, last, code_point, less); return (it != last) ? it->mapped : code_point; } @@ -45,7 +47,8 @@ constexpr auto map_code_point(char32_t code_point) -> char32_t { return static_cast(details::map_code_point_16(static_cast(code_point))); } - auto first = std::cbegin(details::mapped_32), last = std::cend(details::mapped_32); + auto first = std::cbegin(details::mapped_32); + auto last = std::cend(details::mapped_32); auto it = std::lower_bound(first, last, code_point, less); return (it != last) ? it->mapped : code_point; } diff --git a/include/skyr/network/ipv6_address.hpp b/include/skyr/network/ipv6_address.hpp index ca658514..79fcca3c 100644 --- a/include/skyr/network/ipv6_address.hpp +++ b/include/skyr/network/ipv6_address.hpp @@ -81,7 +81,8 @@ class ipv6_address { auto sequences = static_vector, 8>{}; auto in_sequence = false; - auto first = std::cbegin(address), last = std::cend(address); + auto first = std::cbegin(address); + auto last = std::cend(address); auto it = first; while (true) { if (*it == 0) { @@ -168,7 +169,8 @@ constexpr auto parse_ipv6_address(std::string_view input, bool* validation_error auto piece_index = 0; auto compress = std::optional(); - auto first = std::cbegin(input), last = std::cend(input); + auto first = std::cbegin(input); + auto last = std::cend(input); auto it = first; if (input.starts_with("::"sv)) { diff --git a/include/skyr/unicode/code_points/u8.hpp b/include/skyr/unicode/code_points/u8.hpp index cbc3442d..ad72c539 100644 --- a/include/skyr/unicode/code_points/u8.hpp +++ b/include/skyr/unicode/code_points/u8.hpp @@ -100,7 +100,8 @@ class u8_code_point_view { template constexpr auto u8_code_point(const OctetRange& range) -> std::expected>, unicode_errc> { - auto first = std::begin(range), last = std::end(range); + auto first = std::begin(range); + auto last = std::end(range); auto length = sequence_length(*first); if (std::distance(first, last) > length) { return std::unexpected(unicode_errc::overflow); diff --git a/include/skyr/url_search_parameters.hpp b/include/skyr/url_search_parameters.hpp index ee2470d9..d5bc87fb 100644 --- a/include/skyr/url_search_parameters.hpp +++ b/include/skyr/url_search_parameters.hpp @@ -98,7 +98,8 @@ class url_search_parameters { /// /// \param name The name of the parameter to remove void remove(std::string_view name) { - auto first = std::begin(parameters_), last = std::end(parameters_); + auto first = std::begin(parameters_); + auto last = std::end(parameters_); auto it = std::remove_if(first, last, details::is_name(name)); parameters_.erase(it, last); update(); @@ -107,7 +108,8 @@ class url_search_parameters { /// \param name The search parameter name /// \returns The first search parameter value with the given name [[nodiscard]] auto get(std::string_view name) const -> std::optional { - auto first = std::cbegin(parameters_), last = std::cend(parameters_); + auto first = std::cbegin(parameters_); + auto last = std::cend(parameters_); auto it = std::find_if(first, last, details::is_name(name)); return (it != last) ? it->value : std::nullopt; } @@ -134,7 +136,8 @@ class url_search_parameters { /// \returns `true` if the value is in the search parameters, /// `false` otherwise. [[nodiscard]] auto contains(std::string_view name) const noexcept -> bool { - auto first = std::cbegin(parameters_), last = std::cend(parameters_); + auto first = std::cbegin(parameters_); + auto last = std::cend(parameters_); return std::find_if(first, last, details::is_name(name)) != last; } @@ -143,7 +146,8 @@ class url_search_parameters { /// \param name The search parameter name /// \param value The search parameter value void set(std::string_view name, std::string_view value) { - auto first = std::begin(parameters_), last = std::end(parameters_); + auto first = std::begin(parameters_); + auto last = std::end(parameters_); auto it = std::find_if(first, last, details::is_name(name)); if (it != last) { it->value = value; @@ -178,7 +182,8 @@ class url_search_parameters { void sort() { static constexpr auto less_name = [](const auto& lhs, const auto& rhs) { return lhs.name < rhs.name; }; - auto first = std::begin(parameters_), last = std::end(parameters_); + auto first = std::begin(parameters_); + auto last = std::end(parameters_); std::sort(first, last, less_name); update(); } From 5bcf89313dfc7b83340f8c9988697991107cccea Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Tue, 9 Jun 2026 20:02:59 +0200 Subject: [PATCH 6/7] Set enum size --- include/skyr/core/errors.hpp | 3 ++- include/skyr/core/url_parse_state.hpp | 3 ++- include/skyr/core/url_parser_context.hpp | 2 +- include/skyr/domain/errors.hpp | 4 +++- include/skyr/domain/idna_status.hpp | 4 +++- include/skyr/filesystem/path.hpp | 3 ++- include/skyr/json/json.hpp | 3 ++- include/skyr/network/ipv4_address.hpp | 2 +- include/skyr/network/ipv6_address.hpp | 2 +- include/skyr/percent_encoding/errors.hpp | 4 +++- include/skyr/percent_encoding/percent_encoded_char.hpp | 3 ++- include/skyr/unicode/errors.hpp | 4 +++- include/skyr/url_format.hpp | 3 ++- 13 files changed, 27 insertions(+), 13 deletions(-) diff --git a/include/skyr/core/errors.hpp b/include/skyr/core/errors.hpp index 70094484..636bad6d 100644 --- a/include/skyr/core/errors.hpp +++ b/include/skyr/core/errors.hpp @@ -6,12 +6,13 @@ #ifndef SKYR_CORE_ERRORS_HPP #define SKYR_CORE_ERRORS_HPP +#include #include namespace skyr { /// \enum url_parse_errc /// Enumerates URL parser errors -enum class url_parse_errc { +enum class url_parse_errc : std::uint8_t { /// The string contains an invalid Unicode character invalid_unicode_character = 1, /// A character is not a valid scheme character diff --git a/include/skyr/core/url_parse_state.hpp b/include/skyr/core/url_parse_state.hpp index ad0352bd..39167cb7 100644 --- a/include/skyr/core/url_parse_state.hpp +++ b/include/skyr/core/url_parse_state.hpp @@ -6,6 +6,7 @@ #ifndef SKYR_URL_PARSE_STATE_HPP #define SKYR_URL_PARSE_STATE_HPP +#include #include #include #include @@ -14,7 +15,7 @@ namespace skyr { /// States of the URL parser -enum class url_parse_state { +enum class url_parse_state : std::uint8_t { /// Pointer is at the scheme start scheme_start, /// Pointer is at the scheme part diff --git a/include/skyr/core/url_parser_context.hpp b/include/skyr/core/url_parser_context.hpp index 3120250c..0f9ed7d0 100644 --- a/include/skyr/core/url_parser_context.hpp +++ b/include/skyr/core/url_parser_context.hpp @@ -92,7 +92,7 @@ inline void shorten_path(std::string_view scheme, std::vector& path } } // namespace details -enum class url_parse_action { +enum class url_parse_action : std::uint8_t { success = 0, increment, continue_, diff --git a/include/skyr/domain/errors.hpp b/include/skyr/domain/errors.hpp index 83ca3be7..5b0023ff 100644 --- a/include/skyr/domain/errors.hpp +++ b/include/skyr/domain/errors.hpp @@ -6,10 +6,12 @@ #ifndef SKYR_DOMAIN_ERRORS_HPP #define SKYR_DOMAIN_ERRORS_HPP +#include + namespace skyr { /// \enum domain_errc /// Enumerates domain processing errors -enum class domain_errc { +enum class domain_errc : std::uint8_t { /// The domain code point is disallowed disallowed_code_point = 1, /// The encoder or decoder received bad input diff --git a/include/skyr/domain/idna_status.hpp b/include/skyr/domain/idna_status.hpp index 8d21af5b..977e65b9 100644 --- a/include/skyr/domain/idna_status.hpp +++ b/include/skyr/domain/idna_status.hpp @@ -6,13 +6,15 @@ #ifndef SKYR_DOMAIN_IDNA_STATUS_HPP #define SKYR_DOMAIN_IDNA_STATUS_HPP +#include + namespace skyr::idna { /// \enum idna_status /// The status values come from the IDNA mapping table in domain TR46: /// /// https://domain.org/reports/tr46/#IDNA_Mapping_Table /// -enum class idna_status { +enum class idna_status : std::uint8_t { /// The code point is disallowed disallowed = 1, /// The code point is disallowed, but can be treated as valid when using std 3 diff --git a/include/skyr/filesystem/path.hpp b/include/skyr/filesystem/path.hpp index 98a6ce75..e9696e66 100644 --- a/include/skyr/filesystem/path.hpp +++ b/include/skyr/filesystem/path.hpp @@ -6,6 +6,7 @@ #ifndef SKYR_FILESYSTEM_PATH_HPP #define SKYR_FILESYSTEM_PATH_HPP +#include #include #include @@ -18,7 +19,7 @@ namespace skyr { /// vice versa namespace filesystem { /// -enum class path_errc { +enum class path_errc : std::uint8_t { /// invalid_path = 1, /// diff --git a/include/skyr/json/json.hpp b/include/skyr/json/json.hpp index 7085307c..ab391713 100644 --- a/include/skyr/json/json.hpp +++ b/include/skyr/json/json.hpp @@ -6,6 +6,7 @@ #ifndef SKYR_JSON_JSON_HPP #define SKYR_JSON_JSON_HPP +#include #include #include #include @@ -21,7 +22,7 @@ namespace skyr { namespace json { /// -enum class json_errc { +enum class json_errc : std::uint8_t { /// invalid_query = 1, }; diff --git a/include/skyr/network/ipv4_address.hpp b/include/skyr/network/ipv4_address.hpp index 1154f814..c045f6b5 100644 --- a/include/skyr/network/ipv4_address.hpp +++ b/include/skyr/network/ipv4_address.hpp @@ -24,7 +24,7 @@ namespace skyr { /// Enumerates IPv4 address parsing errors -enum class ipv4_address_errc { +enum class ipv4_address_errc : std::uint8_t { /// The input contains more than 4 segments too_many_segments, /// The input contains an empty segment diff --git a/include/skyr/network/ipv6_address.hpp b/include/skyr/network/ipv6_address.hpp index 79fcca3c..4c551192 100644 --- a/include/skyr/network/ipv6_address.hpp +++ b/include/skyr/network/ipv6_address.hpp @@ -22,7 +22,7 @@ namespace skyr { /// Enumerates IPv6 address parsing errors -enum class ipv6_address_errc { +enum class ipv6_address_errc : std::uint8_t { /// IPv6 address does not start with a double colon does_not_start_with_double_colon, /// IPv6 piece is not valid diff --git a/include/skyr/percent_encoding/errors.hpp b/include/skyr/percent_encoding/errors.hpp index e3c5fe2d..9fc49a08 100644 --- a/include/skyr/percent_encoding/errors.hpp +++ b/include/skyr/percent_encoding/errors.hpp @@ -6,10 +6,12 @@ #ifndef SKYR_PERCENT_ENCODING_ERRORS_HPP #define SKYR_PERCENT_ENCODING_ERRORS_HPP +#include + namespace skyr { namespace percent_encoding { /// Enumerates percent encoding errors -enum class percent_encode_errc { +enum class percent_encode_errc : std::uint8_t { /// Input was not a hex value non_hex_input, /// Overflow diff --git a/include/skyr/percent_encoding/percent_encoded_char.hpp b/include/skyr/percent_encoding/percent_encoded_char.hpp index 41ab0bc1..a8936d3d 100644 --- a/include/skyr/percent_encoding/percent_encoded_char.hpp +++ b/include/skyr/percent_encoding/percent_encoded_char.hpp @@ -7,6 +7,7 @@ #define SKYR_PERCENT_ENCODING_PERCENT_ENCODED_CHAR_HPP #include +#include #include #include @@ -86,7 +87,7 @@ constexpr auto is_component_byte(std::byte value) { } // namespace details /// -enum class encode_set { +enum class encode_set : std::uint8_t { /// any = 0, /// diff --git a/include/skyr/unicode/errors.hpp b/include/skyr/unicode/errors.hpp index 01ec88e7..fe47f410 100644 --- a/include/skyr/unicode/errors.hpp +++ b/include/skyr/unicode/errors.hpp @@ -6,10 +6,12 @@ #ifndef SKYR_UNICODE_ERRORS_HPP #define SKYR_UNICODE_ERRORS_HPP +#include + namespace skyr::unicode { /// \enum unicode_errc /// Enumerates Unicode errors -enum class unicode_errc { +enum class unicode_errc : std::uint8_t { /// Overflow overflow, /// Invalid lead code point diff --git a/include/skyr/url_format.hpp b/include/skyr/url_format.hpp index 6f3f11ad..29b0230f 100644 --- a/include/skyr/url_format.hpp +++ b/include/skyr/url_format.hpp @@ -6,6 +6,7 @@ #ifndef SKYR_URL_FORMAT_HPP #define SKYR_URL_FORMAT_HPP +#include #include #include @@ -45,7 +46,7 @@ namespace std { template <> struct formatter { - enum class format_type { + enum class format_type : std::uint8_t { full, // Full URL (default) scheme, // s - scheme hostname, // h - hostname From e0ecd6656ad93cac78d00ac0117b09fd10f9ad2f Mon Sep 17 00:00:00 2001 From: Glyn Matthews Date: Tue, 9 Jun 2026 20:07:33 +0200 Subject: [PATCH 7/7] Fix some naming issues --- include/skyr/concepts/url_concepts.hpp | 20 +- include/skyr/core/host.hpp | 12 +- include/skyr/core/url_parser_context.hpp | 492 +++++++++++------------ include/skyr/json/json.hpp | 16 +- include/skyr/network/ipv6_address.hpp | 8 +- include/skyr/platform/endianness.hpp | 22 +- include/skyr/unicode/code_points/u8.hpp | 13 +- include/skyr/unicode/core.hpp | 16 +- include/skyr/url.hpp | 26 +- include/skyr/url_format.hpp | 34 +- include/skyr/url_search_parameters.hpp | 12 +- 11 files changed, 336 insertions(+), 335 deletions(-) diff --git a/include/skyr/concepts/url_concepts.hpp b/include/skyr/concepts/url_concepts.hpp index ca1d1c13..0cfe6c83 100644 --- a/include/skyr/concepts/url_concepts.hpp +++ b/include/skyr/concepts/url_concepts.hpp @@ -11,22 +11,22 @@ #include namespace skyr { -template -concept is_basic_string = std::is_same_v, std::basic_string>; +template +concept is_basic_string = std::is_same_v, std::basic_string>; -template -concept is_basic_string_view = std::is_same_v, std::basic_string_view>; +template +concept is_basic_string_view = std::is_same_v, std::basic_string_view>; -template +template concept is_char_array = - std::conjunction_v, std::is_same>, charT>>; + std::conjunction_v, std::is_same>, CharT>>; -template -concept is_char_pointer = std::conjunction_v, std::is_same, charT>>; +template +concept is_char_pointer = std::conjunction_v, std::is_same, CharT>>; -template +template concept is_string_container = - is_basic_string || is_basic_string_view || is_char_array || is_char_pointer; + is_basic_string || is_basic_string_view || is_char_array || is_char_pointer; template concept is_u8_convertible = diff --git a/include/skyr/core/host.hpp b/include/skyr/core/host.hpp index eb723e54..539e4629 100644 --- a/include/skyr/core/host.hpp +++ b/include/skyr/core/host.hpp @@ -67,17 +67,17 @@ class host { /// /// \return The host as a string [[nodiscard]] auto serialize() const { - constexpr static auto serialize = [](auto&& host) -> std::string { - using T = std::decay_t; + constexpr static auto serialize = [](T&& host) -> std::string { + using host_t = std::decay_t; - if constexpr (std::is_same_v) { + if constexpr (std::is_same_v) { return host.serialize(); - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v) { return std::format("[{}]", host.serialize()); - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v) { return host.name; } else { - return std::string(); + return {}; } }; diff --git a/include/skyr/core/url_parser_context.hpp b/include/skyr/core/url_parser_context.hpp index 0f9ed7d0..9d2721ae 100644 --- a/include/skyr/core/url_parser_context.hpp +++ b/include/skyr/core/url_parser_context.hpp @@ -100,53 +100,53 @@ enum class url_parse_action : std::uint8_t { class url_parser_context { private: - url_record url; - url_parse_state state; - std::string_view input{}; - std::string_view::const_iterator input_it{}; - bool* validation_error; - const url_record* base; - std::optional state_override{}; - std::string buffer{}; - - bool at_flag; - bool square_braces_flag; + url_record url_; + url_parse_state state_; + std::string_view input_{}; + std::string_view::const_iterator input_it_{}; + bool* validation_error_; + const url_record* base_; + std::optional state_override_{}; + std::string buffer_{}; + + bool at_flag_; + bool square_braces_flag_; public: url_parser_context(std::string_view input, bool* validation_error, const url_record* base, const url_record* url, std::optional state_override) - : url(url ? *url : url_record{}) - , state(state_override ? state_override.value() : url_parse_state::scheme_start) - , input(input) - , input_it(begin(input)) - , validation_error(validation_error) - , base(base) - , state_override(state_override) - , buffer() - , at_flag(false) - , square_braces_flag(false) { + : url_(url ? *url : url_record{}) + , state_(state_override ? state_override.value() : url_parse_state::scheme_start) + , input_(input) + , input_it_(begin(input_)) + , validation_error_(validation_error) + , base_(base) + , state_override_(state_override) + , buffer_() + , at_flag_(false) + , square_braces_flag_(false) { } [[nodiscard]] auto get_url() && -> url_record&& { - return std::move(url); + return std::move(url_); } [[nodiscard]] auto is_eof() const noexcept { - return input_it == std::end(input); + return input_it_ == std::end(input_); } [[nodiscard]] auto next_byte() const noexcept { - return !is_eof() ? *input_it : '\0'; + return !is_eof() ? *input_it_ : '\0'; } void increment() noexcept { - assert(input_it != std::end(input)); - ++input_it; + assert(input_it_ != std::end(input_)); + ++input_it_; } auto parse_next() -> std::expected { auto byte = next_byte(); - switch (state) { + switch (state_) { case url_parse_state::scheme_start: return parse_scheme_start(byte); case url_parse_state::scheme: @@ -195,20 +195,20 @@ class url_parser_context { private: void decrement() noexcept { - assert(input_it != std::begin(input)); - --input_it; + assert(input_it_ != std::begin(input_)); + --input_it_; } void restart_from_beginning() noexcept { - input_it = std::begin(input); + input_it_ = std::begin(input_); } void restart_from_beginning_of_buffer() noexcept { - input_it -= (buffer.size() + 1); + input_it_ -= (buffer_.size() + 1); } [[nodiscard]] auto still_to_process() const noexcept -> std::string_view { - return input.substr(std::distance(std::begin(input), input_it)); + return input_.substr(std::distance(std::begin(input_), input_it_)); } [[nodiscard]] auto remaining_starts_with(std::string_view chars) const noexcept -> bool { @@ -218,14 +218,14 @@ class url_parser_context { auto parse_scheme_start(char byte) -> std::expected { if (std::isalpha(byte, std::locale::classic())) { auto lower = std::tolower(byte, std::locale::classic()); - buffer.push_back(lower); - state = url_parse_state::scheme; - } else if (!state_override) { - state = url_parse_state::no_scheme; + buffer_.push_back(lower); + state_ = url_parse_state::scheme; + } else if (!state_override_) { + state_ = url_parse_state::no_scheme; restart_from_beginning(); return url_parse_action::continue_; } else { - *validation_error |= true; + *validation_error_ |= true; return std::unexpected(url_parse_errc::invalid_scheme_character); } @@ -235,45 +235,45 @@ class url_parser_context { auto parse_scheme(char byte) -> std::expected { if (std::isalnum(byte, std::locale::classic()) || details::contains("+-."sv, byte)) { auto lower = std::tolower(byte, std::locale::classic()); - buffer.push_back(lower); + buffer_.push_back(lower); } else if (byte == ':') { - if (state_override) { - if ((url.is_special() && !is_special(buffer)) || (!url.is_special() && is_special(buffer)) || - ((url.includes_credentials() || url.port) && (buffer == "file")) || - ((url.scheme == "file") && (!url.host || url.host.value().is_empty()))) { + if (state_override_) { + if ((url_.is_special() && !is_special(buffer_)) || (!url_.is_special() && is_special(buffer_)) || + ((url_.includes_credentials() || url_.port) && (buffer_ == "file")) || + ((url_.scheme == "file") && (!url_.host || url_.host.value().is_empty()))) { return std::unexpected(url_parse_errc::cannot_override_scheme); } } set_scheme_from_buffer(); - if (state_override) { - if (url.port == default_port(url.scheme)) { + if (state_override_) { + if (url_.port == default_port(url_.scheme)) { clear_port(); } return url_parse_action::success; } - buffer.clear(); + buffer_.clear(); - if (url.scheme == "file") { + if (url_.scheme == "file") { if (!remaining_starts_with("//"sv)) { - *validation_error |= true; + *validation_error_ |= true; } - state = url_parse_state::file; - } else if (url.is_special() && base && (base->scheme == url.scheme)) { - state = url_parse_state::special_relative_or_authority; - } else if (url.is_special()) { - state = url_parse_state::special_authority_slashes; + state_ = url_parse_state::file; + } else if (url_.is_special() && base_ && (base_->scheme == url_.scheme)) { + state_ = url_parse_state::special_relative_or_authority; + } else if (url_.is_special()) { + state_ = url_parse_state::special_authority_slashes; } else if (remaining_starts_with("/"sv)) { - state = url_parse_state::path_or_authority; + state_ = url_parse_state::path_or_authority; increment(); } else { set_cannot_be_a_base_url_flag(); add_empty_path_element(); - state = url_parse_state::cannot_be_a_base_url_path; + state_ = url_parse_state::cannot_be_a_base_url_path; } - } else if (!state_override) { - buffer.clear(); - state = url_parse_state::no_scheme; + } else if (!state_override_) { + buffer_.clear(); + state_ = url_parse_state::no_scheme; restart_from_beginning(); return url_parse_action::continue_; } else { @@ -284,22 +284,22 @@ class url_parser_context { } auto parse_no_scheme(char byte) -> std::expected { - if (!base || (base->cannot_be_a_base_url && (byte != '#'))) { - *validation_error |= true; + if (!base_ || (base_->cannot_be_a_base_url && (byte != '#'))) { + *validation_error_ |= true; return std::unexpected(url_parse_errc::not_an_absolute_url_with_fragment); - } else if (base->cannot_be_a_base_url && (byte == '#')) { + } else if (base_->cannot_be_a_base_url && (byte == '#')) { set_scheme_from_base(); set_path_from_base(); set_query_from_base(); set_empty_fragment(); set_cannot_be_a_base_url_flag(); - state = url_parse_state::fragment; - } else if (base->scheme != "file") { - state = url_parse_state::relative; + state_ = url_parse_state::fragment; + } else if (base_->scheme != "file") { + state_ = url_parse_state::relative; restart_from_beginning(); return url_parse_action::continue_; } else { - state = url_parse_state::file; + state_ = url_parse_state::file; restart_from_beginning(); return url_parse_action::continue_; } @@ -309,20 +309,20 @@ class url_parser_context { auto parse_special_relative_or_authority(char byte) -> std::expected { if ((byte == '/') && remaining_starts_with("/"sv)) { increment(); - state = url_parse_state::special_authority_ignore_slashes; + state_ = url_parse_state::special_authority_ignore_slashes; } else { - *validation_error |= true; + *validation_error_ |= true; decrement(); - state = url_parse_state::relative; + state_ = url_parse_state::relative; } return url_parse_action::increment; } auto parse_path_or_authority(char byte) -> std::expected { if (byte == '/') { - state = url_parse_state::authority; + state_ = url_parse_state::authority; } else { - state = url_parse_state::path; + state_ = url_parse_state::path; decrement(); } return url_parse_action::increment; @@ -335,31 +335,31 @@ class url_parser_context { set_path_from_base(); set_query_from_base(); } else if (byte == '/') { - state = url_parse_state::relative_slash; + state_ = url_parse_state::relative_slash; } else if (byte == '?') { set_authority_from_base(); set_path_from_base(); set_empty_query(); - state = url_parse_state::query; + state_ = url_parse_state::query; } else if (byte == '#') { set_authority_from_base(); set_path_from_base(); set_query_from_base(); set_empty_fragment(); - state = url_parse_state::fragment; + state_ = url_parse_state::fragment; } else { - if (url.is_special() && (byte == '\\')) { - *validation_error |= true; - state = url_parse_state::relative_slash; + if (url_.is_special() && (byte == '\\')) { + *validation_error_ |= true; + state_ = url_parse_state::relative_slash; } else { set_authority_from_base(); set_path_from_base(); - if (!url.path.empty()) { - url.path.pop_back(); + if (!url_.path.empty()) { + url_.path.pop_back(); } - state = url_parse_state::path; + state_ = url_parse_state::path; - if (input_it == begin(input)) { + if (input_it_ == begin(input_)) { return url_parse_action::continue_; } @@ -371,16 +371,16 @@ class url_parser_context { } auto parse_relative_slash(char byte) -> std::expected { - if (url.is_special() && ((byte == '/') || (byte == '\\'))) { + if (url_.is_special() && ((byte == '/') || (byte == '\\'))) { if (byte == '\\') { - *validation_error |= true; + *validation_error_ |= true; } - state = url_parse_state::special_authority_ignore_slashes; + state_ = url_parse_state::special_authority_ignore_slashes; } else if (byte == '/') { - state = url_parse_state::authority; + state_ = url_parse_state::authority; } else { set_authority_from_base(); - state = url_parse_state::path; + state_ = url_parse_state::path; decrement(); } @@ -390,11 +390,11 @@ class url_parser_context { auto parse_special_authority_slashes(char byte) -> std::expected { if ((byte == '/') && remaining_starts_with("/"sv)) { increment(); - state = url_parse_state::special_authority_ignore_slashes; + state_ = url_parse_state::special_authority_ignore_slashes; } else { - *validation_error |= true; + *validation_error_ |= true; decrement(); - state = url_parse_state::special_authority_ignore_slashes; + state_ = url_parse_state::special_authority_ignore_slashes; } return url_parse_action::increment; @@ -403,64 +403,64 @@ class url_parser_context { auto parse_special_authority_ignore_slashes(char byte) -> std::expected { if ((byte != '/') && (byte != '\\')) { decrement(); - state = url_parse_state::authority; + state_ = url_parse_state::authority; } else { - *validation_error |= true; + *validation_error_ |= true; } return url_parse_action::increment; } auto parse_authority(char byte) -> std::expected { if (byte == '@') { - *validation_error |= true; - if (at_flag) { + *validation_error_ |= true; + if (at_flag_) { // Subsequent @ characters // If we already have a password (from first @ segment containing ':'), // append to password. Otherwise, parse normally as username:password. - if (!url.password.empty()) { - url.password += "%40"; - for (auto c : buffer) { + if (!url_.password.empty()) { + url_.password += "%40"; + for (auto c : buffer_) { auto pct_encoded = percent_encode_byte(std::byte(c), percent_encoding::encode_set::userinfo); - url.password += pct_encoded.to_string(); + url_.password += pct_encoded.to_string(); } - buffer.clear(); + buffer_.clear(); } else { - buffer.insert(0, "%40"); + buffer_.insert(0, "%40"); set_credentials_from_buffer(); - buffer.clear(); + buffer_.clear(); } } else { - at_flag = true; + at_flag_ = true; set_credentials_from_buffer(); - buffer.clear(); + buffer_.clear(); } } else if (((is_eof()) || (byte == '/') || (byte == '?') || (byte == '#')) || - (url.is_special() && (byte == '\\'))) { - if (at_flag && buffer.empty()) { - *validation_error |= true; + (url_.is_special() && (byte == '\\'))) { + if (at_flag_ && buffer_.empty()) { + *validation_error_ |= true; return std::unexpected(url_parse_errc::empty_hostname); } restart_from_beginning_of_buffer(); - state = url_parse_state::host; - buffer.clear(); + state_ = url_parse_state::host; + buffer_.clear(); return url_parse_action::increment; } else { - buffer.push_back(byte); + buffer_.push_back(byte); } return url_parse_action::increment; } auto parse_hostname(char byte) -> std::expected { - if (state_override && (url.scheme == "file")) { - state = url_parse_state::file_host; - if (input_it == begin(input)) { + if (state_override_ && (url_.scheme == "file")) { + state_ = url_parse_state::file_host; + if (input_it_ == begin(input_)) { return url_parse_action::continue_; } decrement(); - } else if ((byte == ':') && !square_braces_flag) { - if (buffer.empty()) { - *validation_error |= true; + } else if ((byte == ':') && !square_braces_flag_) { + if (buffer_.empty()) { + *validation_error_ |= true; return std::unexpected(url_parse_errc::empty_hostname); } @@ -468,22 +468,22 @@ class url_parser_context { if (!result) { return std::unexpected(result.error()); } - buffer.clear(); - state = url_parse_state::port; + buffer_.clear(); + state_ = url_parse_state::port; - if (state_override && (state_override.value() == url_parse_state::hostname)) { + if (state_override_ && (state_override_.value() == url_parse_state::hostname)) { return url_parse_action::success; } - } else if ((is_eof() || (byte == '/') || (byte == '?') || (byte == '#')) || (url.is_special() && (byte == '\\'))) { - if (input_it != begin(input)) { + } else if ((is_eof() || (byte == '/') || (byte == '?') || (byte == '#')) || (url_.is_special() && (byte == '\\'))) { + if (input_it_ != begin(input_)) { decrement(); } - if (url.is_special() && buffer.empty()) { - *validation_error |= true; + if (url_.is_special() && buffer_.empty()) { + *validation_error_ |= true; return std::unexpected(url_parse_errc::empty_hostname); - } else if (state_override && buffer.empty() && (url.includes_credentials() || url.port)) { - *validation_error |= true; + } else if (state_override_ && buffer_.empty() && (url_.includes_credentials() || url_.port)) { + *validation_error_ |= true; return url_parse_action::success; } @@ -491,42 +491,42 @@ class url_parser_context { if (!result) { return std::unexpected(result.error()); } - buffer.clear(); - state = url_parse_state::path_start; + buffer_.clear(); + state_ = url_parse_state::path_start; - if (state_override) { + if (state_override_) { return url_parse_action::success; } } else { if (byte == '[') { - square_braces_flag = true; + square_braces_flag_ = true; } else if (byte == ']') { - square_braces_flag = false; + square_braces_flag_ = false; } - buffer += byte; + buffer_ += byte; } return url_parse_action::increment; } auto parse_port(char byte) -> std::expected { if (std::isdigit(byte, std::locale::classic())) { - buffer += byte; + buffer_ += byte; } else if (((is_eof()) || (byte == '/') || (byte == '?') || (byte == '#')) || - (url.is_special() && (byte == '\\')) || state_override) { + (url_.is_special() && (byte == '\\')) || state_override_) { auto result = set_port_from_buffer(); if (!result) { return std::unexpected(result.error()); } - buffer.clear(); + buffer_.clear(); - if (state_override) { + if (state_override_) { return url_parse_action::success; } decrement(); - state = url_parse_state::path_start; + state_ = url_parse_state::path_start; } else { - *validation_error |= true; + *validation_error_ |= true; return std::unexpected(url_parse_errc::invalid_port); } @@ -539,36 +539,36 @@ class url_parser_context { if ((byte == '/') || (byte == '\\')) { if (byte == '\\') { - *validation_error |= true; + *validation_error_ |= true; } - state = url_parse_state::file_slash; - } else if (base && (base->scheme == "file")) { + state_ = url_parse_state::file_slash; + } else if (base_ && (base_->scheme == "file")) { set_host_from_base(); set_path_from_base(); set_query_from_base(); if (byte == '?') { set_empty_query(); - state = url_parse_state::query; + state_ = url_parse_state::query; } else if (byte == '#') { set_empty_fragment(); - state = url_parse_state::fragment; + state_ = url_parse_state::fragment; } else { clear_query(); if (!details::is_windows_drive_letter(still_to_process())) { - details::shorten_path(url.scheme, url.path); + details::shorten_path(url_.scheme, url_.path); } else { - *validation_error |= true; + *validation_error_ |= true; clear_path(); } - state = url_parse_state::path; - if (input_it == std::begin(input)) { + state_ = url_parse_state::path; + if (input_it_ == std::begin(input_)) { return url_parse_action::continue_; } decrement(); } } else { - state = url_parse_state::path; - if (input_it == std::begin(input)) { + state_ = url_parse_state::path; + if (input_it_ == std::begin(input_)) { return url_parse_action::continue_; } decrement(); @@ -580,19 +580,19 @@ class url_parser_context { auto parse_file_slash(char byte) -> std::expected { if ((byte == '/') || (byte == '\\')) { if (byte == '\\') { - *validation_error |= true; + *validation_error_ |= true; } - state = url_parse_state::file_host; + state_ = url_parse_state::file_host; } else { - if (base && (base->scheme == "file")) { + if (base_ && (base_->scheme == "file")) { set_host_from_base(); if (!details::is_windows_drive_letter(still_to_process()) && - (!base->path.empty() && details::is_windows_drive_letter(base->path[0]))) { + (!base_->path.empty() && details::is_windows_drive_letter(base_->path[0]))) { set_path_from_base0(); } } - state = url_parse_state::path; + state_ = url_parse_state::path; decrement(); } @@ -601,67 +601,67 @@ class url_parser_context { auto parse_file_host(char byte) -> std::expected { if ((is_eof()) || (byte == '/') || (byte == '\\') || (byte == '?') || (byte == '#')) { - bool at_begin = (input_it == begin(input)); + bool at_begin = (input_it_ == begin(input_)); if (!at_begin) { decrement(); } - if (!state_override && details::is_windows_drive_letter(buffer)) { - *validation_error |= true; - state = url_parse_state::path; - } else if (buffer.empty()) { + if (!state_override_ && details::is_windows_drive_letter(buffer_)) { + *validation_error_ |= true; + state_ = url_parse_state::path; + } else if (buffer_.empty()) { set_empty_host(); - if (state_override) { + if (state_override_) { return url_parse_action::success; } - state = url_parse_state::path_start; + state_ = url_parse_state::path_start; } else { auto result = set_host_from_buffer(); if (!result) { return std::unexpected(result.error()); } - if (url.host.value().serialize() == "localhost") { - url.host = host{empty_host{}}; + if (url_.host.value().serialize() == "localhost") { + url_.host = host{empty_host{}}; } - if (state_override) { + if (state_override_) { return url_parse_action::success; } - buffer.clear(); + buffer_.clear(); - state = url_parse_state::path_start; + state_ = url_parse_state::path_start; } } else { - buffer.push_back(byte); + buffer_.push_back(byte); } return url_parse_action::increment; } auto parse_path_start(char byte) -> std::expected { - bool at_begin = (input_it == begin(input)); - if (url.is_special()) { + bool at_begin = (input_it_ == begin(input_)); + if (url_.is_special()) { if (byte == '\\') { - *validation_error |= true; + *validation_error_ |= true; } - state = url_parse_state::path; + state_ = url_parse_state::path; if ((byte != '/') && (byte != '\\')) { if (at_begin) { return url_parse_action::continue_; } decrement(); } - } else if (!state_override && (byte == '?')) { + } else if (!state_override_ && (byte == '?')) { set_empty_query(); - state = url_parse_state::query; - } else if (!state_override && (byte == '#')) { + state_ = url_parse_state::query; + } else if (!state_override_ && (byte == '#')) { set_empty_fragment(); - state = url_parse_state::fragment; + state_ = url_parse_state::fragment; } else if (!is_eof()) { - state = url_parse_state::path; + state_ = url_parse_state::path; if (byte != '/') { if (at_begin) { return url_parse_action::continue_; @@ -673,60 +673,60 @@ class url_parser_context { } auto parse_path(char byte) -> std::expected { - if (((is_eof()) || (byte == '/')) || (url.is_special() && (byte == '\\')) || - (!state_override && ((byte == '?') || (byte == '#')))) { - if (url.is_special() && (byte == '\\')) { - *validation_error |= true; + if (((is_eof()) || (byte == '/')) || (url_.is_special() && (byte == '\\')) || + (!state_override_ && ((byte == '?') || (byte == '#')))) { + if (url_.is_special() && (byte == '\\')) { + *validation_error_ |= true; } - if (details::is_double_dot_path_segment(buffer)) { - details::shorten_path(url.scheme, url.path); - if (!((byte == '/') || (url.is_special() && (byte == '\\')))) { + if (details::is_double_dot_path_segment(buffer_)) { + details::shorten_path(url_.scheme, url_.path); + if (!((byte == '/') || (url_.is_special() && (byte == '\\')))) { add_empty_path_element(); } - } else if (details::is_single_dot_path_segment(buffer) && - !((byte == '/') || (url.is_special() && (byte == '\\')))) { + } else if (details::is_single_dot_path_segment(buffer_) && + !((byte == '/') || (url_.is_special() && (byte == '\\')))) { add_empty_path_element(); - } else if (!details::is_single_dot_path_segment(buffer)) { - if ((url.scheme == "file") && url.path.empty() && details::is_windows_drive_letter(buffer)) { + } else if (!details::is_single_dot_path_segment(buffer_)) { + if ((url_.scheme == "file") && url_.path.empty() && details::is_windows_drive_letter(buffer_)) { // For file URLs with Windows drive letters, the host should be empty // UNLESS it was inherited from a file base URL (per WPT test expectations) - bool inherited_from_file_base = (base && base->scheme == "file"); - if (!inherited_from_file_base && (!url.host || !url.host.value().is_empty())) { - *validation_error |= true; + bool inherited_from_file_base = (base_ && base_->scheme == "file"); + if (!inherited_from_file_base && (!url_.host || !url_.host.value().is_empty())) { + *validation_error_ |= true; set_empty_host(); } - buffer[1] = ':'; + buffer_[1] = ':'; } add_path_element_from_buffer(); } - buffer.clear(); + buffer_.clear(); - if ((url.scheme == "file") && (is_eof() || (byte == '?') || (byte == '#'))) { - while ((url.path.size() > 1) && url.path[0].empty()) { - *validation_error |= true; + if ((url_.scheme == "file") && (is_eof() || (byte == '?') || (byte == '#'))) { + while ((url_.path.size() > 1) && url_.path[0].empty()) { + *validation_error_ |= true; remove_path_element(); } } if (byte == '?') { set_empty_query(); - state = url_parse_state::query; + state_ = url_parse_state::query; } if (byte == '#') { set_empty_fragment(); - state = url_parse_state::fragment; + state_ = url_parse_state::fragment; } } else { if (!details::is_url_code_point(byte) && (byte != '%')) { - *validation_error |= true; + *validation_error_ |= true; } auto pct_encoded = percent_encode_byte(std::byte(byte), percent_encoding::encode_set::path); - buffer += pct_encoded.to_string(); + buffer_ += pct_encoded.to_string(); } return url_parse_action::increment; @@ -736,16 +736,16 @@ class url_parser_context { if (byte == '?') { encode_trailing_spaces_in_path0(); set_empty_query(); - state = url_parse_state::query; + state_ = url_parse_state::query; } else if (byte == '#') { encode_trailing_spaces_in_path0(); set_empty_fragment(); - state = url_parse_state::fragment; + state_ = url_parse_state::fragment; } else { if (!is_eof() && (!details::is_url_code_point(byte) && (byte != '%'))) { - *validation_error |= true; + *validation_error_ |= true; } else if ((byte == '%') && !percent_encoding::is_percent_encoded(still_to_process())) { - *validation_error |= true; + *validation_error_ |= true; } if (!is_eof()) { append_to_path0(byte); @@ -755,12 +755,12 @@ class url_parser_context { } auto parse_query(char byte) -> std::expected { - if (!state_override && (byte == '#')) { + if (!state_override_ && (byte == '#')) { set_empty_fragment(); - state = url_parse_state::fragment; + state_ = url_parse_state::fragment; } else if (!is_eof()) { if ((byte < '!') || (byte > '~') || (details::contains(R"("#<>)"sv, byte)) || - ((byte == '\'') && url.is_special())) { + ((byte == '\'') && url_.is_special())) { pct_encode_and_append_to_query(byte); } else { append_to_query(byte); @@ -772,11 +772,11 @@ class url_parser_context { auto parse_fragment(char byte) -> std::expected { if (!is_eof()) { if (!details::is_url_code_point(byte) && (byte != '%')) { - *validation_error |= true; + *validation_error_ |= true; } if ((byte == '%') && !percent_encoding::is_percent_encoded(still_to_process())) { - *validation_error |= true; + *validation_error_ |= true; } append_to_fragment(byte); @@ -785,20 +785,20 @@ class url_parser_context { } void set_scheme_from_buffer() { - url.scheme = buffer; + url_.scheme = buffer_; } void set_file_scheme() { - url.scheme = "file"; + url_.scheme = "file"; } void set_scheme_from_base() { - url.scheme = base->scheme; + url_.scheme = base_->scheme; } void set_credentials_from_buffer() { auto password_token_seen_flag = false; - for (auto c : buffer) { + for (auto c : buffer_) { if ((c == ':') && !password_token_seen_flag) { password_token_seen_flag = true; continue; @@ -806,98 +806,98 @@ class url_parser_context { auto pct_encoded = percent_encode_byte(std::byte(c), percent_encoding::encode_set::userinfo); if (password_token_seen_flag) { - url.password += pct_encoded.to_string(); + url_.password += pct_encoded.to_string(); } else { - url.username += pct_encoded.to_string(); + url_.username += pct_encoded.to_string(); } } } auto set_host_from_buffer() -> std::expected { - auto host = parse_host(buffer, !url.is_special(), validation_error); - if (!host) { - return std::unexpected(host.error()); + auto new_host = parse_host(buffer_, !url_.is_special(), validation_error_); + if (!new_host) { + return std::unexpected(new_host.error()); } - url.host = host.value(); + url_.host = new_host.value(); return {}; } void set_empty_host() { - url.host = host{empty_host{}}; + url_.host = host{empty_host{}}; } void set_host_from_base() { - url.host = base->host; + url_.host = base_->host; } auto set_port_from_buffer() -> std::expected { - if (!buffer.empty()) { - auto port = details::port_number(buffer); + if (!buffer_.empty()) { + auto port = details::port_number(buffer_); if (!port) { - *validation_error |= true; + *validation_error_ |= true; return std::unexpected(port.error()); } - auto dport = default_port(url.scheme); + auto dport = default_port(url_.scheme); if (dport && (dport.value() == port.value())) { - url.port = std::nullopt; + url_.port = std::nullopt; } else { - url.port = port.value(); + url_.port = port.value(); } } return {}; } void clear_port() { - url.port = std::nullopt; + url_.port = std::nullopt; } void set_authority_from_base() { - url.username = base->username; - url.password = base->password; - url.host = base->host; - url.port = base->port; + url_.username = base_->username; + url_.password = base_->password; + url_.host = base_->host; + url_.port = base_->port; } void set_cannot_be_a_base_url_flag() { - url.cannot_be_a_base_url = true; + url_.cannot_be_a_base_url = true; } void clear_path() { - url.path.clear(); + url_.path.clear(); } void add_empty_path_element() { - url.path.emplace_back(); + url_.path.emplace_back(); } void add_path_element_from_buffer() { - url.path.emplace_back(buffer); + url_.path.emplace_back(buffer_); } void remove_path_element() { - url.path.erase(url.path.begin()); + url_.path.erase(url_.path.begin()); } void set_path_from_base() { - url.path = base->path; + url_.path = base_->path; } void set_path_from_base0() { - url.path.push_back(base->path[0]); + url_.path.push_back(base_->path[0]); } void append_to_path0(char byte) { auto pct_encoded = percent_encode_byte(std::byte(byte), percent_encoding::encode_set::c0_control); - url.path[0] += pct_encoded.to_string(); + url_.path[0] += pct_encoded.to_string(); } void encode_trailing_spaces_in_path0() { - if (url.path.empty()) { + if (url_.path.empty()) { return; } - auto& path = url.path[0]; + auto& path = url_.path[0]; // Only encode the LAST space if it's trailing if (!path.empty() && path.back() == ' ') { path.pop_back(); @@ -906,42 +906,42 @@ class url_parser_context { } void clear_query() { - url.query = std::nullopt; + url_.query = std::nullopt; } void set_empty_query() { - url.query = std::string(); + url_.query = std::string(); } void set_query_from_base() { - url.query = base->query; + url_.query = base_->query; } void pct_encode_and_append_to_query(char byte) { - if (!url.query) { + if (!url_.query) { set_empty_query(); } auto pct_encoded = percent_encode_byte(std::byte(byte), percent_encoding::encode_set::any); - url.query.value() += std::move(pct_encoded).to_string(); + url_.query.value() += std::move(pct_encoded).to_string(); } void append_to_query(char byte) { - if (!url.query) { + if (!url_.query) { set_empty_query(); } - url.query.value().push_back(byte); + url_.query.value().push_back(byte); } void set_empty_fragment() { - url.fragment = std::string(); + url_.fragment = std::string(); } void append_to_fragment(char byte) { - if (!url.fragment) { + if (!url_.fragment) { set_empty_fragment(); } auto pct_encoded = percent_encode_byte(std::byte(byte), percent_encoding::encode_set::fragment); - url.fragment.value() += pct_encoded.to_string(); + url_.fragment.value() += pct_encoded.to_string(); } }; } // namespace skyr diff --git a/include/skyr/json/json.hpp b/include/skyr/json/json.hpp index ab391713..33440c42 100644 --- a/include/skyr/json/json.hpp +++ b/include/skyr/json/json.hpp @@ -60,21 +60,21 @@ inline auto decode_query(std::string_view query) -> nlohmann::json { auto parameters = parse_query(query); if (parameters) { for (auto&& [name, value] : parameters.value()) { - const auto name_ = ::skyr::percent_decode(name).value(); - const auto value_ = value ? ::skyr::percent_decode(value.value()).value() : std::string(); + const auto decoded_name = ::skyr::percent_decode(name).value(); + const auto decoded_value = value ? ::skyr::percent_decode(value.value()).value() : std::string(); - if (object.contains(name_)) { - auto current_value = object[name_]; + if (object.contains(decoded_name)) { + auto current_value = object[decoded_name]; if (current_value.is_string()) { auto prev_value = current_value.get(); - object[name_] = std::vector{prev_value, value_}; + object[decoded_name] = std::vector{prev_value, decoded_value}; } else if (current_value.is_array()) { auto values = current_value.get>(); - values.emplace_back(value_); - object[name_] = values; + values.emplace_back(decoded_value); + object[decoded_name] = values; } } else { - object[name_] = value_; + object[decoded_name] = decoded_value; } } } diff --git a/include/skyr/network/ipv6_address.hpp b/include/skyr/network/ipv6_address.hpp index 4c551192..7a3b9d06 100644 --- a/include/skyr/network/ipv6_address.hpp +++ b/include/skyr/network/ipv6_address.hpp @@ -145,15 +145,15 @@ class ipv6_address { }; namespace details { -template -constexpr auto hex_to_dec(charT byte) noexcept { +template +constexpr auto hex_to_dec(CharT byte) noexcept { assert(std::isxdigit(byte, std::locale::classic())); if (std::isdigit(byte, std::locale::classic())) { - return static_cast(byte - '0'); + return static_cast(byte - '0'); } - return static_cast(std::tolower(byte, std::locale::classic()) - 'a' + 10); + return static_cast(std::tolower(byte, std::locale::classic()) - 'a' + 10); } } // namespace details diff --git a/include/skyr/platform/endianness.hpp b/include/skyr/platform/endianness.hpp index 6477e656..a74b180d 100644 --- a/include/skyr/platform/endianness.hpp +++ b/include/skyr/platform/endianness.hpp @@ -12,32 +12,32 @@ namespace skyr { namespace details { -template - requires std::is_integral_v -constexpr auto swap_endianness(intT v) noexcept -> intT { +template + requires std::is_integral_v +constexpr auto swap_endianness(IntT v) noexcept -> IntT { constexpr auto byte_count = sizeof(v); constexpr auto bit_count = 8ul; std::array bytes{}; for (auto i = 0ul; i < byte_count; ++i) { bytes[i] = static_cast(v >> (i * bit_count)); } - intT result = 0; + IntT result = 0; for (auto i = 0ul; i < byte_count; ++i) { - result |= (static_cast(bytes[byte_count - 1 - i]) << (i * bit_count)); + result |= (static_cast(bytes[byte_count - 1 - i]) << (i * bit_count)); } return result; } } // namespace details -template - requires std::is_integral_v -constexpr auto to_network_byte_order(intT v) noexcept -> intT { +template + requires std::is_integral_v +constexpr auto to_network_byte_order(IntT v) noexcept -> IntT { return (std::endian::big == std::endian::native) ? v : details::swap_endianness(v); // NOLINT } -template - requires std::is_integral_v -constexpr auto from_network_byte_order(intT v) noexcept -> intT { +template + requires std::is_integral_v +constexpr auto from_network_byte_order(IntT v) noexcept -> IntT { return (std::endian::big == std::endian::native) ? v : details::swap_endianness(v); // NOLINT } } // namespace skyr diff --git a/include/skyr/unicode/code_points/u8.hpp b/include/skyr/unicode/code_points/u8.hpp index ad72c539..161960cd 100644 --- a/include/skyr/unicode/code_points/u8.hpp +++ b/include/skyr/unicode/code_points/u8.hpp @@ -42,7 +42,7 @@ class u8_code_point_view { /// \brief Constructor /// \param first An iterator at the beginning of the code point /// \param last An iterator at the end of the code point - constexpr u8_code_point_view(OctetIterator first, OctetIterator last) : first(first), last(last) { + constexpr u8_code_point_view(OctetIterator first, OctetIterator last) : first_(first), last_(last) { } /// \brief Constructor. The length of the code point sequence is @@ -55,13 +55,13 @@ class u8_code_point_view { /// Returns an iterator to the beginning /// \return \c const_iterator [[nodiscard]] constexpr auto begin() const noexcept { - return first; + return first_; } /// Returns an iterator to the end /// \return \c const_iterator [[nodiscard]] constexpr auto end() const noexcept { - return last; + return last_; } /// Returns an iterator to the beginning @@ -79,18 +79,19 @@ class u8_code_point_view { /// \brief Returns the length in bytes of this code point. /// \return [[nodiscard]] constexpr auto size() const noexcept -> size_type { - return sequence_length(*first); + return sequence_length(*first_); } /// /// \return [[nodiscard]] constexpr auto u32_value() const noexcept { constexpr auto to_u32 = [](auto&& state) { return state.value; }; - return find_code_point(first).transform(to_u32).value(); + return find_code_point(first_).transform(to_u32).value(); } private: - OctetIterator first, last; + OctetIterator first_; + OctetIterator last_; }; /// diff --git a/include/skyr/unicode/core.hpp b/include/skyr/unicode/core.hpp index ec13c284..5ac3111d 100644 --- a/include/skyr/unicode/core.hpp +++ b/include/skyr/unicode/core.hpp @@ -18,19 +18,19 @@ namespace skyr::unicode { /// /// \param octet /// \return -template -constexpr auto mask8(uintT value) { - static_assert(std::is_unsigned_v, "unsigned integral types only"); - return static_cast(0xffu & value); // NOLINT(cppcoreguidelines-avoid-magic-numbers) +template +constexpr auto mask8(UintT value) { + static_assert(std::is_unsigned_v, "unsigned integral types only"); + return static_cast(0xffu & value); // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// /// \param value /// \return -template -constexpr auto mask16(uintT value) { - static_assert(std::is_unsigned_v, "unsigned integral types only"); - return static_cast(0xffffu & value); // NOLINT(cppcoreguidelines-avoid-magic-numbers) +template +constexpr auto mask16(UintT value) { + static_assert(std::is_unsigned_v, "unsigned integral types only"); + return static_cast(0xffffu & value); // NOLINT(cppcoreguidelines-avoid-magic-numbers) } /// diff --git a/include/skyr/url.hpp b/include/skyr/url.hpp index 10463dcd..8c5ad9df 100644 --- a/include/skyr/url.hpp +++ b/include/skyr/url.hpp @@ -262,10 +262,10 @@ class url { /// \param protocol The new URL protocol /// \returns An error on failure to parse the new URL auto set_protocol(string_view protocol) -> std::error_code { - auto protocol_ = static_cast(protocol); - if (protocol_.back() != ':') { - protocol_ += ':'; - protocol = string_view(protocol_); + auto protocol_copy = static_cast(protocol); + if (protocol_copy.back() != ':') { + protocol_copy += ':'; + protocol = string_view(protocol_copy); } bool validation_error = false; @@ -531,8 +531,8 @@ class url { /// Returns the [URL port](https://url.spec.whatwg.org/#dom-url-port) /// /// \returns The [URL port](https://url.spec.whatwg.org/#dom-url-port) - template - [[nodiscard]] auto port(std::enable_if_t>* = nullptr) const -> std::optional { + template + [[nodiscard]] auto port(std::enable_if_t>* = nullptr) const -> std::optional { auto p = port(); if (p.empty()) { return std::nullopt; @@ -540,7 +540,7 @@ class url { const char* port_first = p.data(); char* port_last = nullptr; - return static_cast(std::strtoul(port_first, &port_last, 10)); + return static_cast(std::strtoul(port_first, &port_last, 10)); } /// Sets the [URL port](https://url.spec.whatwg.org/#dom-url-port) @@ -563,9 +563,9 @@ class url { /// \tparam intT The input type /// \param port The new port /// \returns An error on failure to parse the new URL - template - requires std::is_integral_v - auto set_port(intT port) -> std::error_code { + template + requires std::is_integral_v + auto set_port(IntT port) -> std::error_code { return set_port(string_view(std::to_string(port))); } @@ -971,9 +971,9 @@ class url { /// \tparam intT An integral type /// \param port The new port number /// \returns A new URL with the updated port, or an error on validation failure - template - requires std::is_integral_v - [[nodiscard]] auto with_port(intT port) const -> std::expected { + template + requires std::is_integral_v + [[nodiscard]] auto with_port(IntT port) const -> std::expected { auto result = *this; if (auto ec = result.set_port(port)) { return std::unexpected(ec); diff --git a/include/skyr/url_format.hpp b/include/skyr/url_format.hpp index 29b0230f..cf14dc7c 100644 --- a/include/skyr/url_format.hpp +++ b/include/skyr/url_format.hpp @@ -57,47 +57,47 @@ struct formatter { origin // o - origin }; - format_type type_ = format_type::full; - bool decode_ = false; // 'd' modifier for decoded output + format_type type = format_type::full; + bool decode = false; // 'd' modifier for decoded output constexpr auto parse(std::format_parse_context& ctx) -> std::format_parse_context::iterator { auto it = ctx.begin(); const auto end = ctx.end(); if (it == end || *it == '}') { - type_ = format_type::full; - decode_ = false; + type = format_type::full; + decode = false; return it; } // Parse format spec switch (*it) { case 's': - type_ = format_type::scheme; + type = format_type::scheme; ++it; break; case 'h': - type_ = format_type::hostname; + type = format_type::hostname; ++it; break; case 'p': - type_ = format_type::port; + type = format_type::port; ++it; break; case 'P': - type_ = format_type::pathname; + type = format_type::pathname; ++it; break; case 'q': - type_ = format_type::query; + type = format_type::query; ++it; break; case 'f': - type_ = format_type::fragment; + type = format_type::fragment; ++it; break; case 'o': - type_ = format_type::origin; + type = format_type::origin; ++it; break; default: @@ -106,7 +106,7 @@ struct formatter { // Check for 'd' (decode) modifier if (it != end && *it == 'd') { - decode_ = true; + decode = true; ++it; } @@ -118,7 +118,7 @@ struct formatter { } auto format(const skyr::url& url, std::format_context& ctx) const { - switch (type_) { + switch (type) { case format_type::full: return std::format_to(ctx.out(), "{}", url.href()); @@ -126,7 +126,7 @@ struct formatter { return std::format_to(ctx.out(), "{}", url.scheme()); case format_type::hostname: - if (decode_) { + if (decode) { // Try to get unicode domain, fall back to ASCII if not available if (auto domain = url.u8domain()) { return std::format_to(ctx.out(), "{}", domain.value()); @@ -139,7 +139,7 @@ struct formatter { case format_type::pathname: { auto pathname = url.pathname(); - if (decode_) { + if (decode) { // Try to percent-decode, fall back to encoded if decode fails if (auto decoded = skyr::percent_decode(pathname)) { return std::format_to(ctx.out(), "{}", decoded.value()); @@ -150,7 +150,7 @@ struct formatter { case format_type::query: { auto search = url.search(); - if (decode_ && !search.empty()) { + if (decode && !search.empty()) { // Decode the query string (skip the leading '?') auto query_part = search.substr(1); // Remove '?' if (auto decoded = skyr::percent_decode(query_part)) { @@ -162,7 +162,7 @@ struct formatter { case format_type::fragment: { auto hash = url.hash(); - if (decode_ && !hash.empty()) { + if (decode && !hash.empty()) { // Decode the fragment (skip the leading '#') auto fragment_part = hash.substr(1); // Remove '#' if (auto decoded = skyr::percent_decode(fragment_part)) { diff --git a/include/skyr/url_search_parameters.hpp b/include/skyr/url_search_parameters.hpp index d5bc87fb..dec5ab94 100644 --- a/include/skyr/url_search_parameters.hpp +++ b/include/skyr/url_search_parameters.hpp @@ -24,14 +24,14 @@ class url; namespace details { struct is_name { - explicit is_name(std::string_view name) : name_(name) { + explicit is_name(std::string_view input_name) : name(input_name) { } auto operator()(const query_parameter& parameter) noexcept { - return name_ == parameter.name; + return name == parameter.name; } - std::string_view name_{}; + std::string_view name{}; }; } // namespace details @@ -246,9 +246,9 @@ class url_search_parameters { void initialize(std::string_view query) { if (auto parameters = parse_query(query); parameters) { for (auto [name, value] : parameters.value()) { - auto name_ = percent_decode(name).value_or(std::string(name)); - auto value_ = value ? percent_decode(value.value()).value_or(std::string(value.value())) : std::string(); - parameters_.emplace_back(name_, value_); + auto decoded_name = percent_decode(name).value_or(std::string(name)); + auto decoded_value = value ? percent_decode(value.value()).value_or(std::string(value.value())) : std::string(); + parameters_.emplace_back(decoded_name, decoded_value); } } }