69 [[nodiscard]] std::strong_ordering operator<=>(const
IPv4 &o) const noexcept {
return bits <=> o.bits; }
70 [[nodiscard]]
bool operator==(
const IPv4 &o)
const noexcept {
return (*this <=> o) == 0; }
71 [[nodiscard]]
bool operator!=(
const IPv4 &o)
const noexcept {
return (*this <=> o) != 0; }
72 [[nodiscard]]
bool operator<=(
const IPv4 &o)
const noexcept {
return (*this <=> o) <= 0; }
73 [[nodiscard]]
bool operator>=(
const IPv4 &o)
const noexcept {
return (*this <=> o) >= 0; }
74 [[nodiscard]]
bool operator<(
const IPv4 &o)
const noexcept {
return (*this <=> o) < 0; }
75 [[nodiscard]]
bool operator>(
const IPv4 &o)
const noexcept {
return (*this <=> o) > 0; }
93 const auto highCmp =
high <=> o.high;
94 const auto lowCmp =
low <=> o.low;
95 if (highCmp == std::strong_ordering::equal) {
100 [[nodiscard]]
bool operator==(
const IPv6 &o)
const noexcept {
return (*this <=> o) == 0; }
101 [[nodiscard]]
bool operator!=(
const IPv6 &o)
const noexcept {
return (*this <=> o) != 0; }
102 [[nodiscard]]
bool operator<=(
const IPv6 &o)
const noexcept {
return (*this <=> o) <= 0; }
103 [[nodiscard]]
bool operator>=(
const IPv6 &o)
const noexcept {
return (*this <=> o) >= 0; }
104 [[nodiscard]]
bool operator<(
const IPv6 &o)
const noexcept {
return (*this <=> o) < 0; }
105 [[nodiscard]]
bool operator>(
const IPv6 &o)
const noexcept {
return (*this <=> o) > 0; }
107 [[nodiscard]]
bool is_ip4() const noexcept {
108 return high == 0 && ((
low & 0xffffffff00000000ull) == 0x0000ffff00000000ull);
155 constexpr std::array<SubnetMaskV4, 33> init_ip4_masks() {
156 std::array<SubnetMaskV4, 33> res = {};
157 for (
size_t i = 1; i < res.size(); ++i) {
159 res[i].mask = (res[i - 1].mask >> 1) | 0b10000000000000000000000000000000;
164 constexpr auto ip4SubnetMasks = init_ip4_masks();
171 return impl::ip4SubnetMasks[
id];
206 constexpr std::array<SubnetMaskV6, 129> init_ip6_masks() {
207 std::array<SubnetMaskV6, 129> res = {};
208 for (
size_t i = 1; i < res.size(); ++i) {
210 if (res[i - 1].maskHigh != std::numeric_limits<u64>::max()) {
212 (res[i - 1].maskHigh >> 1) | 0b1000000000000000000000000000000000000000000000000000000000000000;
215 res[i].maskHigh = std::numeric_limits<u64>::max();
217 (res[i - 1].maskLow >> 1) | 0b1000000000000000000000000000000000000000000000000000000000000000;
223 constexpr auto ip6SubnetMasks = init_ip6_masks();
228 return impl::ip6SubnetMasks[
id];
288 template<WriterImpl WI>
290 const auto p1 = (val.bits >> 24) & 0xff;
291 const auto p2 = (val.bits >> 16) & 0xff;
292 const auto p3 = (val.bits >> 8) & 0xff;
293 const auto p4 = (val.bits >> 0) & 0xff;
294 return print(writer,
"{d}.{d}.{d}.{d}", p1, p2, p3, p4);
311 template<WriterImpl WI>
313 auto chunks = std::array{
314 (val.high >> 48) & 0xffff, (val.high >> 32) & 0xffff, (val.high >> 16) & 0xffff, (val.high >> 0) & 0xffff,
315 (val.low >> 48) & 0xffff, (val.low >> 32) & 0xffff, (val.low >> 16) & 0xffff, (val.low >> 0) & 0xffff,
319 auto fmtStr =
"{\\::0<4;x}";
326 auto prefix =
slice_from(
"0000:0000:0000:0000:0000:ffff:");
334 auto preRes = writer.write_all(prefix);
335 if (preRes.is_error()) {
336 return preRes.error();
338 written += prefix.size();
339 auto ip4 = val.to_ip4().value();
340 auto ip4Res =
format(writer, {}, ip4);
341 if (ip4Res.is_error()) {
342 return ip4Res.error();
344 written += ip4Res.value();
351 for (; i < data.size() && data[i] != 0; ++i) {}
354 ensure(skipStart.has_value());
356 auto skipEnd = skipEndOpt.has_value() ? skipEndOpt.value() + skipStart.value() : data.size();
358 auto printPart1 = data.sub(0, skipStart.value());
359 auto printPart2 = data.sub(skipEnd);
363 if (!printPart1.empty()) {
364 auto p1Res =
print(writer, fmtStr, printPart1);
365 if (p1Res.is_error()) {
366 return p1Res.error();
368 written += p1Res.value();
371 auto sepRes = writer.write_all(
slice_from(
"::"));
372 if (sepRes.is_error()) {
373 return sepRes.error();
377 if (!printPart2.empty()) {
378 auto p2Res =
print(writer, fmtStr, printPart2);
379 if (p2Res.is_error()) {
380 return p2Res.error();
382 written += p2Res.value();
388 return print(writer, fmtStr, data);
398 template<WriterImpl WI>
401 return print(writer,
"/{d}", val.id);
411 template<WriterImpl WI>
414 return print(writer,
"/{d}", val.id);
424 template<WriterImpl WI>
426 if (!val.is_valid()) {
439 template<WriterImpl WI>
441 if (!val.is_valid()) {
constexpr Slice< const char32_t > slice_from(char32_t *cstr)
Creates a slice from a utf32 string in the form of a c string.
mtcore::Optional< size_t > first_index(const Slice< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
mtcore::Optional< size_t > first_index_not(const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Gets the first index that a needle appears in the haystack, or nullopt if the needle does not appear ...
bool contains(const std::remove_const_t< T > &needle, const Slice< T > &haystack)
Checks whether a slice (the haystack) contains an element (the needle) Uses the equality operator of ...
IpInitError
Error when initializing an IP address.
Ip6ConversionError
Error when converting from IPv6 to IPv4.
SubnetMaskError
Error when creating a subnet mask.
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
uint64_t u64
Alias for 64-bit unsigned ints.
uint8_t u8
Alias for 8-bit unsigned ints.
uint32_t u32
Alias for 32-bit unsigned ints.
Result< size_t, typename Writer< WI >::ErrType > format(Writer< WI > &writer, const FormatOptions &opts, Arg arg)
Generic format function which takes a bunch of arguments (of the same type) and formatting options an...
Core library for C++ with Zig-related functionality.
Represents an IP version 4 address (32 bits) Can be converted to an IPv6.
Result< void, IpInitError > init(const std::string_view &str)
Result< void, IpInitError > init(const Slice< char > &str)
bool operator>=(const IPv4 &o) const noexcept
bool operator<=(const IPv4 &o) const noexcept
bool operator!=(const IPv4 &o) const noexcept
bool operator>(const IPv4 &o) const noexcept
bool operator==(const IPv4 &o) const noexcept
bool operator<(const IPv4 &o) const noexcept
Result< void, IpInitError > init(const Slice< const char > &str)
IPv6 to_v6() const noexcept
Result< void, IpInitError > init(const std::string &str)
Represents an IP version 6 address (128 bits) If it represents an IPv4 address, can be converted to a...
Result< void, IpInitError > init(const std::string &str)
bool operator!=(const IPv6 &o) const noexcept
bool operator<(const IPv6 &o) const noexcept
Result< void, IpInitError > init(const Slice< char > &str)
Result< IPv4, Ip6ConversionError > to_ip4() const
bool operator==(const IPv6 &o) const noexcept
bool operator>=(const IPv6 &o) const noexcept
bool is_ip4() const noexcept
std::strong_ordering operator<=>(const IPv6 &o) const noexcept
bool operator>(const IPv6 &o) const noexcept
Result< void, IpInitError > init(const std::string_view &str)
bool operator<=(const IPv6 &o) const noexcept
Result< void, IpInitError > init(const Slice< const char > &str)
Represents a Result that may have an error (error code) or a success value A type of "void" means the...
A Slice which is just a pointer + length Accessing elements through the array operator will do bounds...
Represents the bitwise mask for a version 4 subnet.
static constexpr bool valid_id(u8 id)
Checks if an id is a valid subnet mask id (0-32)
SubnetV4 subnet_ip(const IPv4 &ip)
Subnets an IP address based on the IP mask.
static SubnetMaskV4 by_id(u8 id)
Retrieves a subnet mask by id (valid ids is 0-32).
Gets a subnet mask for an IP version 6 subnet.
SubnetV6 subnet_ip(const IPv6 &ip)
Subnets an IP address using the subnet mask.
static constexpr bool valid_id(u8 id)
Checks if a subnet mask ID is valid (0-128)
static SubnetMaskV6 by_id(u8 id)
Gets a subnet mask by id.
A masked IP version 4 address.
bool operator!=(const SubnetV4 &o) const
bool operator==(const SubnetV4 &o) const
bool is_valid() const
Checks if a masked IP address is valid (i.e.
A masked IP version 6 address.
bool is_valid() const
Checks if a masked IP address is valid (i.e.
bool operator!=(const SubnetV6 &o) const
bool operator==(const SubnetV6 &o) const
A writer that writes data to some sort of stream or buffer Note: the data elements written should be ...