Skip to content

Commit

Permalink
Fixed breaks the constant expression analyzer in code editors for som…
Browse files Browse the repository at this point in the history
…e toolchains
  • Loading branch information
VladimirShaleev committed May 26, 2024
1 parent 5ce3b3f commit 0c6c29c
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 251 deletions.
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ Checks: 'bugprone-argument-comment,
modernize-avoid-bind,
modernize-deprecated-headers,
modernize-deprecated-ios-base-aliases,
modernize-loop-convert,
modernize-macro-to-enum,
modernize-make-shared,
modernize-make-unique,
Expand Down Expand Up @@ -350,6 +349,7 @@ Checks: 'bugprone-argument-comment,
#misc-use-anonymous-namespace,
#modernize-avoid-c-arrays,
#modernize-concat-nested-namespaces,
#modernize-loop-convert,
#modernize-return-braced-init-list,
#modernize-use-nodiscard,
#modernize-use-trailing-return-type,
Expand Down
28 changes: 22 additions & 6 deletions include/ipaddress/base-v6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@ class base_v6 {
}

auto ip = ip_address_base<Ext>(parse_parts(parts, value, std::get<0>(result), std::get<1>(result), std::get<2>(result), code));
ip.set_scope_id(ip_and_scope.scope_id);

#if IPADDRESS_IPV6_SCOPE_MAX_LENGTH > 0
if (code != error_code::no_error) {
return {};
}

if (ip_and_scope.scope_id[0] != '\0') {
ip._data.scope_id = make_fixed_string(ip_and_scope.scope_id, code);
}
#endif // IPADDRESS_IPV6_SCOPE_MAX_LENGTH

return ip;
}
Expand All @@ -104,7 +113,8 @@ class base_v6 {
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE size_t ip_to_chars(const base_type& bytes, const fixed_string<IPADDRESS_IPV6_SCOPE_MAX_LENGTH>& scope_id, format fmt, char (&result)[base_max_string_len + 1]) IPADDRESS_NOEXCEPT {
char hextets[base_size >> 1][5] = {};
constexpr auto hextets_count = size_t(base_size >> 1);
char hextets[hextets_count][5] = {};
const size_t max_hextets = base_size >> 1;
for (size_t i = 0; i < max_hextets; ++i) {
const uint16_t value = (uint16_t(bytes[i * 2]) << 8) | uint16_t(bytes[i * 2 + 1]);
Expand All @@ -116,7 +126,8 @@ class base_v6 {
auto has_doublecolon_end = false;

if (fmt == format::compact || fmt == format::compressed) {
for (auto& hextet : hextets) {
for (size_t i = 0; i < hextets_count; ++i) {
auto& hextet = hextets[i];
for (size_t h = 0; h < 3; ++h) {
if (hextet[0] != '0') {
break;
Expand Down Expand Up @@ -198,8 +209,9 @@ class base_v6 {
}
if (!scope_id.empty()) {
result[offset++] = '%';
for (const auto c : scope_id) {
result[offset++] = c;
const auto scope_id_size = scope_id.size();
for (size_t i = 0; i < scope_id_size; ++i) {
result[offset++] = scope_id[i];
}
}
result[offset] = '\0';
Expand Down Expand Up @@ -267,6 +279,10 @@ class base_v6 {
return address;
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_invalid_scope_id_symbol(char c) IPADDRESS_NOEXCEPT {
return c == '%' || c == '/' || c == ' ' || (c >= '\t' && c <= '\r');
}

private:
template <typename Iter>
struct ip_and_scope {
Expand All @@ -292,7 +308,7 @@ class base_v6 {
error = error_code::scope_id_is_too_long;
return result;
}
if (c == '%' || c == '/' || uint32_t(c) > 127) {
if (is_invalid_scope_id_symbol(c)) {
error = error_code::invalid_scope_id;
return result;
}
Expand Down
227 changes: 138 additions & 89 deletions include/ipaddress/ip-networks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,133 +220,182 @@ constexpr ipv6_network networks<T>::ipv6_is_site_local;

using nets = networks<int>;

} // namespace IPADDRESS_NAMESPACE::internal
template <typename T, int N>
IPADDRESS_NODISCARD constexpr IPADDRESS_FORCE_INLINE int array_size(const T (&)[N]) IPADDRESS_NOEXCEPT {
return N;
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_network::is_private() const IPADDRESS_NOEXCEPT {
const auto& address = network_address();
const auto broadcast = broadcast_address();
for (const auto& private_network : internal::nets::ipv4_private_networks) {
if (private_network.contains(address) && private_network.contains(broadcast)) {
return true;
template <typename>
struct props;

template <>
struct props<ipv4_network> {
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv4_network& net) IPADDRESS_NOEXCEPT {
const auto& address = net.network_address();
const auto broadcast = net.broadcast_address();
constexpr auto count = array_size(nets::ipv4_private_networks);
for (int i = 0; i < count; ++i) {
if (nets::ipv4_private_networks[i].contains(address) && nets::ipv4_private_networks[i].contains(broadcast)) {
return true;
}
}
return false;
}
return false;
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv4_network& net) IPADDRESS_NOEXCEPT {
const auto& network = nets::ipv4_is_public_network;
const auto& address = net.network_address();
const auto broadcast = net.broadcast_address();
return !(network.contains(address) && network.contains(broadcast)) && !is_private(net);
}
};

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_network::is_private() const IPADDRESS_NOEXCEPT {
const auto& address = network_address();
const auto broadcast = broadcast_address();
for (const auto& private_network : internal::nets::ipv6_private_networks) {
if (private_network.contains(address) && private_network.contains(broadcast)) {
return true;
template <>
struct props<ipv6_network> {
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv6_network& net) IPADDRESS_NOEXCEPT {
const auto& address = net.network_address();
const auto broadcast = net.broadcast_address();
constexpr auto count = array_size(nets::ipv6_private_networks);
for (int i = 0; i < count; ++i) {
if (nets::ipv6_private_networks[i].contains(address) && nets::ipv6_private_networks[i].contains(broadcast)) {
return true;
}
}
return false;
}
return false;
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv6_network& net) IPADDRESS_NOEXCEPT {
return !is_private(net);
}
};

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_network::is_global() const IPADDRESS_NOEXCEPT {
const auto& network = internal::nets::ipv4_is_public_network;
const auto& address = network_address();
const auto broadcast = broadcast_address();
return !(network.contains(address) && network.contains(broadcast)) && !is_private();
}
template <>
struct props<ipv4_address> {
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
constexpr auto count = array_size(nets::ipv4_private_networks);
for (int i = 0; i < count; ++i) {
if (nets::ipv4_private_networks[i].contains(ip)) {
return true;
}
}
return false;
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_network::is_global() const IPADDRESS_NOEXCEPT {
return !is_private();
}
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
return !nets::ipv4_is_public_network.contains(ip) && !is_private(ip);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_address::is_multicast() const IPADDRESS_NOEXCEPT {
return internal::nets::ipv4_is_multicast.contains(*this);
}
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_multicast(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
return nets::ipv4_is_multicast.contains(ip);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address::is_multicast() const IPADDRESS_NOEXCEPT {
return internal::nets::ipv6_is_multicast.contains(*this);
}
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_reserved(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
return nets::ipv4_reserved_network.contains(ip);
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_loopback(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
return nets::ipv4_is_loopback.contains(ip);
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_link_local(const ipv4_address& ip) IPADDRESS_NOEXCEPT {
return nets::ipv4_is_link_local.contains(ip);
}
};

template <>
struct props<ipv6_address> {
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_private(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
const auto ipv4 = ip.ipv4_mapped();

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_address::is_private() const IPADDRESS_NOEXCEPT {
for (const auto& private_network : internal::nets::ipv4_private_networks) {
if (private_network.contains(*this)) {
return true;
if (ipv4) {
return ipv4->is_private();
}

constexpr auto count = array_size(nets::ipv6_private_networks);
for (int i = 0; i < count; ++i) {
if (nets::ipv6_private_networks[i].contains(ip)) {
return true;
}
}

return false;
}
return false;
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address::is_private() const IPADDRESS_NOEXCEPT {
const auto ipv4 = this->ipv4_mapped();
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_global(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
return !is_private(ip);
}

if (ipv4) {
return ipv4->is_private();
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_multicast(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
return nets::ipv6_is_multicast.contains(ip);
}

for (const auto& private_network : internal::nets::ipv6_private_networks) {
if (private_network.contains(*this)) {
return true;
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_reserved(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
constexpr auto count = array_size(nets::ipv6_reserved_networks);
for (int i = 0; i < count; ++i) {
if (nets::ipv6_reserved_networks[i].contains(ip)) {
return true;
}
}
return false;
}

return false;
}
IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_loopback(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
const auto& b = ip.bytes();
return b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0
&& b[4] == 0 && b[5] == 0 && b[6] == 0 && b[7] == 0
&& b[8] == 0 && b[9] == 0 && b[10] == 0 && b[11] == 0
&& b[12] == 0 && b[13] == 0 && b[14] == 0 && b[15] == 1;
}

IPADDRESS_NODISCARD static IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool is_link_local(const ipv6_address& ip) IPADDRESS_NOEXCEPT {
return nets::ipv6_is_link_local.contains(ip);
}
};

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_address::is_global() const IPADDRESS_NOEXCEPT {
return !internal::nets::ipv4_is_public_network.contains(*this) && !is_private();
} // namespace IPADDRESS_NAMESPACE::internal

template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_network_base<Base>::is_private() const IPADDRESS_NOEXCEPT {
return internal::props<ip_network_base<Base>>::is_private(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address::is_global() const IPADDRESS_NOEXCEPT {
return !is_private();
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_network_base<Base>::is_global() const IPADDRESS_NOEXCEPT {
return internal::props<ip_network_base<Base>>::is_global(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_address::is_reserved() const IPADDRESS_NOEXCEPT {
return internal::nets::ipv4_reserved_network.contains(*this);
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_address_base<Base>::is_private() const IPADDRESS_NOEXCEPT {
return internal::props<ip_address_base<Base>>::is_private(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address::is_reserved() const IPADDRESS_NOEXCEPT {
for (const auto& reserved_network : internal::nets::ipv6_reserved_networks) {
if (reserved_network.contains(*this)) {
return true;
}
}
return false;
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_address_base<Base>::is_global() const IPADDRESS_NOEXCEPT {
return internal::props<ip_address_base<Base>>::is_global(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_address::is_loopback() const IPADDRESS_NOEXCEPT {
return internal::nets::ipv4_is_loopback.contains(*this);
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_address_base<Base>::is_multicast() const IPADDRESS_NOEXCEPT {
return internal::props<ip_address_base<Base>>::is_multicast(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address::is_loopback() const IPADDRESS_NOEXCEPT {
const auto b = bytes();
return b[0] == 0 && b[1] == 0 && b[2] == 0 && b[3] == 0
&& b[4] == 0 && b[5] == 0 && b[6] == 0 && b[7] == 0
&& b[8] == 0 && b[9] == 0 && b[10] == 0 && b[11] == 0
&& b[12] == 0 && b[13] == 0 && b[14] == 0 && b[15] == 1;
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_address_base<Base>::is_reserved() const IPADDRESS_NOEXCEPT {
return internal::props<ip_address_base<Base>>::is_reserved(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv4_address::is_link_local() const IPADDRESS_NOEXCEPT {
return internal::nets::ipv4_is_link_local.contains(*this);
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_address_base<Base>::is_loopback() const IPADDRESS_NOEXCEPT {
return internal::props<ip_address_base<Base>>::is_loopback(*this);
}

template<>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address::is_link_local() const IPADDRESS_NOEXCEPT {
return internal::nets::ipv6_is_link_local.contains(*this);
template <typename Base>
IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ip_address_base<Base>::is_link_local() const IPADDRESS_NOEXCEPT {
return internal::props<ip_address_base<Base>>::is_link_local(*this);
}

IPADDRESS_NODISCARD IPADDRESS_CONSTEXPR IPADDRESS_FORCE_INLINE bool ipv6_address_base::is_site_local() const IPADDRESS_NOEXCEPT {
ipv6_address address(this->bytes());
ipv6_address address(bytes());
return internal::nets::ipv6_is_site_local.contains(address);
}

Expand Down
Loading

0 comments on commit 0c6c29c

Please sign in to comment.