Introduce non-throwing try* methods for IPAddress{,V4,V6}.
Summary:
Now there is no interface to create `IPAddress{,V4,V6}` from a string or
`ByteRange` that doesn't throw. All available static methods throw
`IPAddressFormatException`.
It has a few disadvantages:
== 1. It's unsafe ==
Caller is not forced to catch exception, it's very easy to write
`IPAddress(potentiallyInvalidString)` and discover that it can throw when it's
already in prod.
== 2. It's inconvenient ==
if caller is aware about exception, (s)he's forced to write `try {} catch` that
is inconvenient and leads to code like this:
folly::IPAddress taskIp;
try {
taskIp = folly::IPAddress(kv.second.taskIp);
} catch (const folly::IPAddressFormatException&) {
// Error handling ..
}
// Use IP ..
== 3. It's expensive ==
Amended benchmark shows that `IPAddress` constructor is ~10 times slower when a
string with invalid IP is passed to it.
---
The diff introduces two non-throwing interfaces for all tree flavors of `IPAddress`:
`tryFromString()` tries to create IP address from string and returns either
corresponding IP address or `enum class IPAddressFormatError` using
`folly::Expected`.
`tryFromBinary()` does same thing but for `ByteRange` input.
The code can be as short as:
if (auto maybeIp = IPAddress::tryFromString(ipStr)) {
// Use maybeIp.value() ..
}
The `try` prefix is chosen to be consistent with other interfaces in folly,
e.g. `to` and `tryTo`.
Reviewed By: yfeldblum
Differential Revision:
D6211182
fbshipit-source-id:
f27cf90997c100a5fd42138e66ff9bb172204c20