diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 50bff884..d3a01262 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -89,6 +89,31 @@ protected: : Handle{std::move(rt), std::move(ref)} { } + template> + Addr address(F &&f) { + sockaddr_storage ssto; + int len = sizeof(ssto); + char name[sizeof(ssto)]; + std::pair addr{ "", 0 }; + + int err = std::forward(f)(this->template get(), reinterpret_cast(&ssto), &len); + + if(!err) { + typename Traits::Type *aptr = reinterpret_cast(&ssto); + err = Traits::NameFunc(aptr, name, len); + + if(!err) { + addr = { std::string{name}, ntohs(aptr->sin_port) }; + } + } + + /** + * See Boost/Mutant idiom: + * https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant + */ + return reinterpret_cast(addr); + } + public: void shutdown() { std::weak_ptr weak = this->shared_from_this(); diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index 31743c08..bfd7d701 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -1,6 +1,7 @@ #pragma once +#include #include #include #include @@ -43,37 +44,16 @@ class Tcp final: public Stream { : Stream{HandleType{}, std::move(ref)} { } - template> - Addr address(F &&f) { - sockaddr_storage ssto; - int len = sizeof(ssto); - char name[sizeof(ssto)]; - std::pair addr{ "", 0 }; - - int err = std::forward(f)(get(), reinterpret_cast(&ssto), &len); - - if(!err) { - typename Traits::Type *aptr = reinterpret_cast(&ssto); - err = Traits::NameFunc(aptr, name, len); - - if(!err) { - addr = { std::string{name}, ntohs(aptr->sin_port) }; - } - } - - /** - * See Boost/Mutant idiom: - * https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Boost_mutant - */ - return reinterpret_cast(addr); - } - public: using Time = std::chrono::seconds; using IPv4 = details::IPv4; using IPv6 = details::IPv6; + enum class Bind: std::underlying_type_t { + IPV6ONLY = UV_TCP_IPV6ONLY + }; + template static std::shared_ptr create(Args&&... args) { return std::shared_ptr{new Tcp{std::forward(args)...}}; @@ -90,27 +70,22 @@ public: } template> - void bind(std::string ip, unsigned int port, bool ipv6only = false) { + void bind(std::string ip, unsigned int port, Flags flags = Flags{}) { typename Traits::Type addr; Traits::AddrFunc(ip.c_str(), port, &addr); - unsigned int flags = ipv6only ? UV_TCP_IPV6ONLY : 0; invoke(&uv_tcp_bind, get(), reinterpret_cast(&addr), flags); } template> - void bind(Addr addr, bool ipv6only = false) { - bind(addr.ip, addr.port, ipv6only); + void bind(Addr addr, Flags flags = Flags{}) { + bind(addr.ip, addr.port, flags); } template> - Addr address() { - return address(uv_tcp_getsockname); - } + Addr address() { return Stream::address(uv_tcp_getsockname); } template> - Addr remote() { - return address(uv_tcp_getpeername); - } + Addr remote() { return Stream::address(uv_tcp_getpeername); } template> void connect(std::string ip, unsigned int port) { @@ -131,9 +106,7 @@ public: } template> - void connect(Addr addr) { - connect(addr.ip, addr.port); - } + void connect(Addr addr) { connect(addr.ip, addr.port); } void accept(Tcp &tcp) { invoke(&uv_accept, get(), tcp.get());