DRY some methods in IPAddress
[folly.git] / folly / IPAddress.h
index 4ce7d3887594ac34aff5b624758e468c8b486743..853fcd600b0b88b995196aff45d4bef90fce006f 100644 (file)
@@ -65,6 +65,12 @@ typedef std::pair<IPAddress, uint8_t> CIDRNetwork;
  * @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);
@@ -267,14 +273,12 @@ class IPAddress {
 
   // @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 {
@@ -302,32 +306,27 @@ class IPAddress {
    * {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(); });
   }
 
   /**
@@ -337,8 +336,7 @@ class IPAddress {
    * 2000::/3, ffxe::/16.
    */
   bool isNonroutable() const {
-    return isV4() ? asV4().isNonroutable()
-                  : asV6().isNonroutable();
+    return pick([&](auto& _) { return _.isNonroutable(); });
   }
 
   /**
@@ -346,14 +344,12 @@ class IPAddress {
    * (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(); });
   }
 
   /**
@@ -363,8 +359,7 @@ class IPAddress {
    * @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)); });
   }
 
   /**
@@ -373,8 +368,7 @@ class IPAddress {
    * @throws IPAddressFormatException on inet_ntop error
    */
   std::string str() const {
-    return isV4() ? asV4().str()
-                  : asV6().str();
+    return pick([&](auto& _) { return _.str(); });
   }
 
   /**
@@ -383,27 +377,24 @@ class IPAddress {
    * 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: