diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2019-06-27 13:42:50 -0400 |
---|---|---|
committer | Billy Donahue <billy.donahue@mongodb.com> | 2019-06-28 15:35:16 -0400 |
commit | 6e43dbc29112a7d7edce91cb89ec0d396463601e (patch) | |
tree | 76d5f9c75eb4600c9e8e08e25578bc012676e8af /src | |
parent | 2597e7fbe3c09683408b82b8b854023d6c2dbbf2 (diff) | |
download | mongo-6e43dbc29112a7d7edce91cb89ec0d396463601e.tar.gz |
SERVER-41495 HostAndPort streaming refactor
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/util/net/hostandport.cpp | 41 | ||||
-rw-r--r-- | src/mongo/util/net/hostandport.h | 67 |
2 files changed, 57 insertions, 51 deletions
diff --git a/src/mongo/util/net/hostandport.cpp b/src/mongo/util/net/hostandport.cpp index 927754c4421..ed74befa3a7 100644 --- a/src/mongo/util/net/hostandport.cpp +++ b/src/mongo/util/net/hostandport.cpp @@ -102,40 +102,25 @@ bool HostAndPort::isDefaultRoute() const { std::string HostAndPort::toString() const { StringBuilder ss; - append(ss); + ss << *this; return ss.str(); } -template <typename SinkFunc> -static void appendGeneric(const HostAndPort& hp, const SinkFunc& write) { +void HostAndPort::_appendToVisitor(AppendVisitor& write) const { // wrap ipv6 addresses in []s for roundtrip-ability - if (hp.host().find(':') != std::string::npos) { + if (host().find(':') != std::string::npos) { write("["); - write(hp.host()); + write(host()); write("]"); } else { - write(hp.host()); + write(host()); } - if (hp.host().find('/') == std::string::npos) { + if (host().find('/') == std::string::npos) { write(":"); - write(hp.port()); + write(port()); } } -template <typename Stream> -static Stream& appendToStream(const HostAndPort& hp, Stream& sink) { - appendGeneric(hp, [&sink](const auto& v) { sink << v; }); - return sink; -} - -void HostAndPort::append(StringBuilder& sink) const { - appendToStream(*this, sink); -} - -void HostAndPort::append(fmt::writer& sink) const { - appendGeneric(*this, [&sink](const auto& v) { sink.write(v); }); -} - bool HostAndPort::empty() const { return _host.empty() && _port < 0; } @@ -214,16 +199,4 @@ Status HostAndPort::initialize(StringData s) { return Status::OK(); } -std::ostream& operator<<(std::ostream& os, const HostAndPort& hp) { - return appendToStream(hp, os); -} - -StringBuilder& operator<<(StringBuilder& os, const HostAndPort& hp) { - return appendToStream(hp, os); -} - -StackStringBuilder& operator<<(StackStringBuilder& os, const HostAndPort& hp) { - return appendToStream(hp, os); -} - } // namespace mongo diff --git a/src/mongo/util/net/hostandport.h b/src/mongo/util/net/hostandport.h index 87b8a6c528b..055c09634f5 100644 --- a/src/mongo/util/net/hostandport.h +++ b/src/mongo/util/net/hostandport.h @@ -116,12 +116,6 @@ struct HostAndPort { std::string toString() const; /** - * Like toString(), but writes to various `sink` instead. - */ - void append(StringBuilder& sink) const; - void append(fmt::writer& sink) const; - - /** * Returns true if this object represents no valid HostAndPort. */ bool empty() const; @@ -141,29 +135,68 @@ struct HostAndPort { } private: + friend struct fmt::formatter<HostAndPort>; + + struct AppendVisitor { + virtual void operator()(StringData v) = 0; + virtual void operator()(std::uint16_t v) = 0; + virtual ~AppendVisitor() = default; + }; + + void _appendToVisitor(AppendVisitor& sink) const; + + template <typename F> + void _appendToPolymorphicFunc(F f) const; + + template <typename Stream> + Stream& _appendToStream(Stream& os) const { + _appendToPolymorphicFunc([&](const auto& v) { os << v; }); + return os; + } + + friend std::ostream& operator<<(std::ostream& os, const HostAndPort& hp) { + return hp._appendToStream(os); + } + friend StringBuilder& operator<<(StringBuilder& os, const HostAndPort& hp) { + return hp._appendToStream(os); + } + friend StackStringBuilder& operator<<(StackStringBuilder& os, const HostAndPort& hp) { + return hp._appendToStream(os); + } + std::string _host; int _port; // -1 indicates unspecified }; -std::ostream& operator<<(std::ostream& os, const HostAndPort& hp); - -StringBuilder& operator<<(StringBuilder& os, const HostAndPort& hp); - -StackStringBuilder& operator<<(StackStringBuilder& os, const HostAndPort& hp); +template <typename F> +void HostAndPort::_appendToPolymorphicFunc(F f) const { + struct Vis : AppendVisitor { + explicit Vis(F f) : _f{std::move(f)} {} + void operator()(StringData v) override { + _f(v); + } + void operator()(std::uint16_t v) override { + _f(v); + } + F _f; + }; + Vis visitor(std::move(f)); + _appendToVisitor(visitor); +} } // namespace mongo +namespace fmt { template <> -struct fmt::formatter<mongo::HostAndPort> { +struct formatter<mongo::HostAndPort> { template <typename ParseContext> - auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + constexpr auto parse(ParseContext& ctx) { return ctx.begin(); } - template <typename FormatContext> - auto format(const mongo::HostAndPort& hp, FormatContext& ctx) -> decltype(ctx.out()) { - fmt::writer w(ctx.out()); - hp.append(w); + auto format(const mongo::HostAndPort& hp, FormatContext& ctx) { + hp._appendToPolymorphicFunc([&](const auto& v) { fmt::format_to(ctx.out(), "{}", v); }); return ctx.out(); } }; +} // namespace fmt |