summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2019-06-27 13:42:50 -0400
committerBilly Donahue <billy.donahue@mongodb.com>2019-06-28 15:35:16 -0400
commit6e43dbc29112a7d7edce91cb89ec0d396463601e (patch)
tree76d5f9c75eb4600c9e8e08e25578bc012676e8af /src
parent2597e7fbe3c09683408b82b8b854023d6c2dbbf2 (diff)
downloadmongo-6e43dbc29112a7d7edce91cb89ec0d396463601e.tar.gz
SERVER-41495 HostAndPort streaming refactor
Diffstat (limited to 'src')
-rw-r--r--src/mongo/util/net/hostandport.cpp41
-rw-r--r--src/mongo/util/net/hostandport.h67
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