* @encode
*/
class IPAddress {
+ private:
+ template <typename F>
+ auto pick(F f) const {
+ return isV4() ? f(asV4()) : f(asV6());
+ }
+
public:
// returns true iff the input string can be parsed as an ip-address
static bool validate(StringPiece ip);
// @return true if this address is all zeros
bool isZero() const {
- return isV4() ? asV4().isZero()
- : asV6().isZero();
+ return pick([&](auto& _) { return _.isZero(); });
}
// Number of bits in the address representation.
size_t bitCount() const {
- return isV4() ? IPAddressV4::bitCount()
- : IPAddressV6::bitCount();
+ return pick([&](auto& _) { return _.bitCount(); });
}
// Number of bytes in the address representation.
size_t byteCount() const {
* {family:'AF_INET|AF_INET6', addr:'address', hash:long}.
*/
std::string toJson() const {
- return isV4() ? asV4().toJson()
- : asV6().toJson();
+ return pick([&](auto& _) { return _.toJson(); });
}
// Hash of address
std::size_t hash() const {
- return isV4() ? asV4().hash()
- : asV6().hash();
+ return pick([&](auto& _) { return _.hash(); });
}
// Return true if the address qualifies as localhost.
bool isLoopback() const {
- return isV4() ? asV4().isLoopback()
- : asV6().isLoopback();
+ return pick([&](auto& _) { return _.isLoopback(); });
}
// Return true if the address qualifies as link local
bool isLinkLocal() const {
- return isV4() ? asV4().isLinkLocal()
- : asV6().isLinkLocal();
+ return pick([&](auto& _) { return _.isLinkLocal(); });
}
// Return true if the address qualifies as broadcast.
bool isLinkLocalBroadcast() const {
- return isV4() ? asV4().isLinkLocalBroadcast()
- : asV6().isLinkLocalBroadcast();
+ return pick([&](auto& _) { return _.isLinkLocalBroadcast(); });
}
/**
* 2000::/3, ffxe::/16.
*/
bool isNonroutable() const {
- return isV4() ? asV4().isNonroutable()
- : asV6().isNonroutable();
+ return pick([&](auto& _) { return _.isNonroutable(); });
}
/**
* (for example, 192.168.xxx.xxx or fc00::/7 addresses)
*/
bool isPrivate() const {
- return isV4() ? asV4().isPrivate()
- : asV6().isPrivate();
+ return pick([&](auto& _) { return _.isPrivate(); });
}
// Return true if the address is a multicast address.
bool isMulticast() const {
- return isV4() ? asV4().isMulticast()
- : asV6().isMulticast();
+ return pick([&](auto& _) { return _.isMulticast(); });
}
/**
* @return IPAddress instance with bits set to 0
*/
IPAddress mask(uint8_t numBits) const {
- return isV4() ? IPAddress(asV4().mask(numBits))
- : IPAddress(asV6().mask(numBits));
+ return pick([&](auto& _) { return IPAddress(_.mask(numBits)); });
}
/**
* @throws IPAddressFormatException on inet_ntop error
*/
std::string str() const {
- return isV4() ? asV4().str()
- : asV6().str();
+ return pick([&](auto& _) { return _.str(); });
}
/**
* this is the hex representation with : characters inserted every 4 digits.
*/
std::string toFullyQualified() const {
- return isV4() ? asV4().toFullyQualified()
- : asV6().toFullyQualified();
+ return pick([&](auto& _) { return _.toFullyQualified(); });
}
/// Same as toFullyQualified but append to an output string.
void toFullyQualifiedAppend(std::string& out) const {
- return isV4() ? asV4().toFullyQualifiedAppend(out)
- : asV6().toFullyQualifiedAppend(out);
+ return pick([&](auto& _) { return _.toFullyQualifiedAppend(out); });
}
// Address version (4 or 6)
uint8_t version() const {
- return isV4() ? asV4().version()
- : asV6().version();
+ return pick([&](auto& _) { return _.version(); });
}
/**
* Access to address bytes, in network byte order.
*/
const unsigned char* bytes() const {
- return isV4() ? asV4().bytes() : asV6().bytes();
+ return pick([&](auto& _) { return _.bytes(); });
}
private: