1 // This file is part of CAF, the C++ Actor Framework. See the file LICENSE in 2 // the main distribution directory for license terms and copyright or visit 3 // https://github.com/actor-framework/actor-framework/blob/master/LICENSE. 4 5 #pragma once 6 7 #include <array> 8 #include <cstdint> 9 #include <initializer_list> 10 #include <string> 11 12 #include "caf/byte_address.hpp" 13 #include "caf/detail/comparable.hpp" 14 #include "caf/detail/core_export.hpp" 15 #include "caf/fwd.hpp" 16 #include "caf/ipv4_address.hpp" 17 18 namespace caf { 19 20 class CAF_CORE_EXPORT ipv6_address 21 : public byte_address<ipv6_address>, 22 detail::comparable<ipv6_address>, 23 detail::comparable<ipv6_address, ipv4_address> { 24 public: 25 // -- constants -------------------------------------------------------------- 26 27 static constexpr size_t num_bytes = 16; 28 29 // -- member types ----------------------------------------------------------- 30 31 using super = byte_address<ipv6_address>; 32 33 using array_type = std::array<uint8_t, num_bytes>; 34 35 using u16_array_type = std::array<uint16_t, 8>; 36 37 using uint16_ilist = std::initializer_list<uint16_t>; 38 39 // -- constructors, destructors, and assignment operators -------------------- 40 41 /// Constructs an all-zero address. 42 ipv6_address(); 43 44 /// Constructs an address from given prefix and suffix. 45 /// @pre `prefix.size() + suffix.size() <= 8` 46 /// @warning assumes network byte order for prefix and suffix 47 ipv6_address(uint16_ilist prefix, uint16_ilist suffix); 48 49 /// Embeds an IPv4 address into an IPv6 address. 50 explicit ipv6_address(ipv4_address addr); 51 52 /// Constructs an IPv6 address from given bytes. 53 explicit ipv6_address(array_type bytes); 54 55 // -- comparison ------------------------------------------------------------- 56 57 /// Returns a negative number if `*this < other`, zero if `*this == other` 58 /// and a positive number if `*this > other`. 59 int compare(ipv6_address other) const noexcept; 60 61 /// Returns a negative number if `*this < other`, zero if `*this == other` 62 /// and a positive number if `*this > other`. 63 int compare(ipv4_address other) const noexcept; 64 65 // -- properties ------------------------------------------------------------- 66 67 /// Returns whether this address embeds an IPv4 address. 68 bool embeds_v4() const noexcept; 69 70 /// Returns an embedded IPv4 address. 71 /// @pre `embeds_v4()` 72 ipv4_address embedded_v4() const noexcept; 73 74 /// Returns whether this is a loopback address. 75 bool is_loopback() const noexcept; 76 77 /// Returns the bytes of the IP address as array. bytes()78 array_type& bytes() noexcept { 79 return bytes_; 80 } 81 82 /// Returns the bytes of the IP address as array. bytes() const83 const array_type& bytes() const noexcept { 84 return bytes_; 85 } 86 87 /// Alias for `bytes()`. data()88 array_type& data() noexcept { 89 return bytes_; 90 } 91 92 /// Alias for `bytes()`. data() const93 const array_type& data() const noexcept { 94 return bytes_; 95 } 96 97 /// Returns whether this address contains only zeros, i.e., equals `::`. zero() const98 bool zero() const noexcept { 99 return half_segments_[0] == 0 && half_segments_[1] == 0; 100 } 101 102 // -- inspection ------------------------------------------------------------- 103 104 template <class Inspector> inspect(Inspector & f,ipv6_address & x)105 friend bool inspect(Inspector& f, ipv6_address& x) { 106 return f.object(x).fields(f.field("bytes", x.bytes_)); 107 } 108 109 friend CAF_CORE_EXPORT std::string to_string(ipv6_address x); 110 111 private: 112 // -- member variables ------------------------------------------------------- 113 114 union { 115 std::array<uint64_t, 2> half_segments_; 116 std::array<uint32_t, 4> quad_segments_; 117 u16_array_type oct_segments_; 118 array_type bytes_; 119 }; 120 }; 121 122 CAF_CORE_EXPORT error parse(string_view str, ipv6_address& dest); 123 124 } // namespace caf 125