From af5dc89dec39f4f60323808388a94d946fe826d7 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 24 Nov 2016 17:02:23 +0100 Subject: [PATCH] review (thanks to Tushar for the suggestion) --- src/uvw/async.hpp | 13 +++------- src/uvw/check.hpp | 13 +++------- src/uvw/dns.hpp | 26 +++++--------------- src/uvw/emitter.hpp | 2 +- src/uvw/fs.hpp | 30 +++++++---------------- src/uvw/fs_event.hpp | 13 +++------- src/uvw/fs_poll.hpp | 13 +++------- src/uvw/handle.hpp | 4 ++-- src/uvw/idle.hpp | 13 +++------- src/uvw/pipe.hpp | 22 +++++++---------- src/uvw/poll.hpp | 40 ++++++++++--------------------- src/uvw/prepare.hpp | 13 +++------- src/uvw/process.hpp | 11 +-------- src/uvw/request.hpp | 4 ++-- src/uvw/resource.hpp | 29 +++++++++++++++------- src/uvw/signal.hpp | 13 +++------- src/uvw/stream.hpp | 32 +++++++------------------ src/uvw/tcp.hpp | 41 +++++++++++++------------------ src/uvw/timer.hpp | 13 +++------- src/uvw/tty.hpp | 57 +++++++++++++++++++------------------------- src/uvw/udp.hpp | 52 +++++++++++++++------------------------- src/uvw/work.hpp | 21 ++++++---------- test/uvw/emitter.cpp | 4 ++-- 23 files changed, 163 insertions(+), 316 deletions(-) diff --git a/src/uvw/async.hpp b/src/uvw/async.hpp index 7be97fea..a8117c3b 100644 --- a/src/uvw/async.hpp +++ b/src/uvw/async.hpp @@ -25,6 +25,8 @@ struct AsyncEvent: Event { }; * * Async handles allow the user to _wakeup_ the event loop and get an event * emitted from another thread. + * + * To create an `AsyncHandle` through a `Loop`, no arguments are required. */ class AsyncHandle final: public Handle { static void sendCallback(uv_async_t *handle) { @@ -32,17 +34,8 @@ class AsyncHandle final: public Handle { async.publish(AsyncEvent{}); } - using Handle::Handle; - public: - /** - * @brief Creates a new async handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new AsyncHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/check.hpp b/src/uvw/check.hpp index c437c634..320010b9 100644 --- a/src/uvw/check.hpp +++ b/src/uvw/check.hpp @@ -16,6 +16,8 @@ namespace uvw { * @brief CheckEvent event. * * It will be emitted by CheckHandle according with its functionalities. + * + * To create a `CheckHandle` through a `Loop`, no arguments are required. */ struct CheckEvent: Event { }; @@ -32,17 +34,8 @@ class CheckHandle final: public Handle { check.publish(CheckEvent{}); } - using Handle::Handle; - public: - /** - * @brief Creates a new check handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new CheckHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/dns.hpp b/src/uvw/dns.hpp index 34ff2228..d784e667 100644 --- a/src/uvw/dns.hpp +++ b/src/uvw/dns.hpp @@ -69,6 +69,8 @@ struct NameInfoEvent: Event { * * Wrapper for [getaddrinfo](http://linux.die.net/man/3/getaddrinfo).
* It offers either asynchronous and synchronous access methods. + * + * To create a `GetAddrInfoReq` through a `Loop`, no arguments are required. */ class GetAddrInfoReq final: public Request { static void getAddrInfoCallback(uv_getaddrinfo_t *req, int status, addrinfo *res) { @@ -84,8 +86,6 @@ class GetAddrInfoReq final: public Request { } } - using Request::Request; - void getNodeAddrInfo(const char *node, const char *service, addrinfo *hints = nullptr) { invoke(&uv_getaddrinfo, parent(), get(), &getAddrInfoCallback, node, service, hints); } @@ -100,14 +100,7 @@ class GetAddrInfoReq final: public Request { public: using Deleter = void(*)(addrinfo *); - /** - * @brief Creates a new `getaddrinfo` wrapper request. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new GetAddrInfoReq{std::move(loop)}}; - } + using Request::Request; /** * @brief Async [getaddrinfo](http://linux.die.net/man/3/getaddrinfo). @@ -196,6 +189,8 @@ public: * * Wrapper for [getnameinfo](http://linux.die.net/man/3/getnameinfo).
* It offers either asynchronous and synchronous access methods. + * + * To create a `GetNameInfoReq` through a `Loop`, no arguments are required. */ class GetNameInfoReq final: public Request { static void getNameInfoCallback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service) { @@ -204,17 +199,8 @@ class GetNameInfoReq final: public Request { else { ptr->publish(NameInfoEvent{hostname, service}); } } - using Request::Request; - public: - /** - * @brief Creates a new `getnameinfo` wrapper request. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new GetNameInfoReq{std::move(loop)}}; - } + using Request::Request; /** * @brief Async [getnameinfo](http://linux.die.net/man/3/getnameinfo). diff --git a/src/uvw/emitter.hpp b/src/uvw/emitter.hpp index 27d28636..54f654d1 100644 --- a/src/uvw/emitter.hpp +++ b/src/uvw/emitter.hpp @@ -194,7 +194,7 @@ public: /** * @brief Disconnects all the listeners. */ - void clearAll() noexcept { + void clear() noexcept { std::for_each(handlers.begin(), handlers.end(), [](auto &&handler){ if(handler) { handler->clear(); } }); } diff --git a/src/uvw/fs.hpp b/src/uvw/fs.hpp index 52553fde..b118a5a2 100644 --- a/src/uvw/fs.hpp +++ b/src/uvw/fs.hpp @@ -301,8 +301,6 @@ protected: else { ptr->publish(FsEvent{req->path, req->statbuf}); } } - using Request::Request; - template void cleanupAndInvoke(Args&&... args) { uv_fs_req_cleanup(this->get()); @@ -320,6 +318,8 @@ public: using Type = details::UVFsType; using EntryType = details::UVDirentTypeT; using Entry = std::pair; + + using Request::Request; }; @@ -329,6 +329,8 @@ public: * Cross-platform sync and async filesystem operations.
* All file operations are run on the threadpool. * + * To create a `FileReq` through a `Loop`, no arguments are required. + * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html) * for further details. @@ -364,17 +366,8 @@ class FileReq final: public FsRequest { else { ptr->publish(FsEvent{req->path, std::move(ptr->data), req->result}); } } - using FsRequest::FsRequest; - public: - /** - * @brief Creates a new file request. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created request. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new FileReq{std::move(loop)}}; - } + using FsRequest::FsRequest; ~FileReq() noexcept { uv_fs_req_cleanup(get()); @@ -722,6 +715,8 @@ private: * Cross-platform sync and async filesystem operations.
* All file operations are run on the threadpool. * + * To create a `FsReq` through a `Loop`, no arguments are required. + * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs.html) * for further details. @@ -733,17 +728,8 @@ class FsReq final: public FsRequest { else { ptr->publish(FsEvent{req->path, static_cast(req->ptr), req->result}); } } - using FsRequest::FsRequest; - public: - /** - * @brief Creates a new file request. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created request. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new FsReq{std::move(loop)}}; - } + using FsRequest::FsRequest; ~FsReq() noexcept { uv_fs_req_cleanup(get()); diff --git a/src/uvw/fs_event.hpp b/src/uvw/fs_event.hpp index c7a81faf..32486e08 100644 --- a/src/uvw/fs_event.hpp +++ b/src/uvw/fs_event.hpp @@ -70,6 +70,8 @@ struct FsEventEvent: Event { * example, if the file was renamed or there was a generic change in it. The * best backend for the job on each platform is chosen by the handle. * + * To create a `FsEventHandle` through a `Loop`, no arguments are required. + * * See the official * [documentation](http://docs.libuv.org/en/v1.x/fs_event.html) * for further details. @@ -81,20 +83,11 @@ class FsEventHandle final: public Handle { else { fsEvent.publish(FsEventEvent{filename, static_cast>(events)}); } } - using Handle::Handle; - public: using Watch = details::UVFsEvent; using Event = details::UVFsEventFlags; - /** - * @brief Creates a new fs event handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new FsEventHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/fs_poll.hpp b/src/uvw/fs_poll.hpp index d63b65b4..4aba35db 100644 --- a/src/uvw/fs_poll.hpp +++ b/src/uvw/fs_poll.hpp @@ -35,6 +35,8 @@ struct FsPollEvent: Event { * It allows the user to monitor a given path for changes. Unlike FsEventHandle * handles, FsPollHandle handles use stat to detect when a file has changed so * they can work on file systems where FsEventHandle handles can’t. + * + * To create a `FsPollHandle` through a `Loop`, no arguments are required. */ class FsPollHandle final: public Handle { static void startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr) { @@ -43,17 +45,8 @@ class FsPollHandle final: public Handle { else { fsPoll.publish(FsPollEvent{ *prev, *curr }); } } - using Handle::Handle; - public: - /** - * @brief Creates a new fs poll handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new FsPollHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp index 9edd0b85..f748eeef 100644 --- a/src/uvw/handle.hpp +++ b/src/uvw/handle.hpp @@ -37,8 +37,6 @@ class Handle: public BaseHandle, public Resource } protected: - using Resource::Resource; - static void allocCallback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf) { *buf = uv_buf_init(new char[suggested], suggested); } @@ -66,6 +64,8 @@ protected: } public: + using Resource::Resource; + /** * @brief Checks if the handle is active. * diff --git a/src/uvw/idle.hpp b/src/uvw/idle.hpp index 4bc6ee12..ef933b38 100644 --- a/src/uvw/idle.hpp +++ b/src/uvw/idle.hpp @@ -32,6 +32,8 @@ struct IdleEvent: Event { }; * * **Note**: despite the name, idle handles will emit events on every loop * iteration, not when the loop is actually _idle_. + * + * To create an `IdleHandle` through a `Loop`, no arguments are required. */ class IdleHandle final: public Handle { static void startCallback(uv_idle_t *handle) { @@ -39,17 +41,8 @@ class IdleHandle final: public Handle { idle.publish(IdleEvent{}); } - using Handle::Handle; - public: - /** - * @brief Creates a new check handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new IdleHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/pipe.hpp b/src/uvw/pipe.hpp index 6f73e1f1..442da4fe 100644 --- a/src/uvw/pipe.hpp +++ b/src/uvw/pipe.hpp @@ -21,23 +21,17 @@ namespace uvw { * * Pipe handles provide an abstraction over local domain sockets on Unix and * named pipes on Windows. + * + * To create a `PipeHandle` through a `Loop`, arguments follow: + * + * * An optional boolean value that indicates if this pipe will be used for + * handle passing between processes. */ class PipeHandle final: public StreamHandle { - explicit PipeHandle(std::shared_ptr ref, bool pass = false) - : StreamHandle{std::move(ref)}, ipc{pass} - { } - public: - /** - * @brief Creates a new poll handle. - * @param loop A pointer to the loop from which the handle generated. - * @param pass An optional boolean value (_ipc_) that indicates if this pipe - * will be used for handle passing between processes. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop, bool pass) { - return std::shared_ptr{new PipeHandle{std::move(loop), pass}}; - } + explicit PipeHandle(ConstructorAccess ca, std::shared_ptr ref, bool pass = false) + : StreamHandle{std::move(ca), std::move(ref)}, ipc{pass} + { } /** * @brief Initializes the handle. diff --git a/src/uvw/poll.hpp b/src/uvw/poll.hpp index cf1f4888..e2abf358 100644 --- a/src/uvw/poll.hpp +++ b/src/uvw/poll.hpp @@ -55,6 +55,12 @@ struct PollEvent: Event { * Poll handles are used to watch file descriptors for readability, writability * and disconnection. * + * To create a `PollHandle` through a `Loop`, arguments follow: + * + * * A descriptor that can be: + * * either an `int` file descriptor + * * or a `OSSocketHandle` socket descriptor + * * See the official * [documentation](http://docs.libuv.org/en/v1.x/poll.html) * for further details. @@ -66,36 +72,16 @@ class PollHandle final: public Handle { else { poll.publish(PollEvent{static_cast>(events)}); } } - explicit PollHandle(std::shared_ptr ref, int desc) - : Handle{std::move(ref)}, tag{FD}, fd{desc} - { } - - explicit PollHandle(std::shared_ptr ref, OSSocketHandle sock) - : Handle{std::move(ref)}, tag{SOCKET}, socket{sock} - { } - public: using Event = details::UVPollEvent; - /** - * @brief Creates a new poll handle. - * @param args - * - * * A pointer to the loop from which the handle generated. - * * A descriptor that can be: - * * either an `int` file descriptor - * * or a `OSSocketHandle` socket descriptor - * - * See the official - * [documentation](http://docs.libuv.org/en/v1.x/poll.html) - * for further details. - * - * @return A pointer to the newly created handle. - */ - template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new PollHandle{std::forward(args)...}}; - } + explicit PollHandle(ConstructorAccess ca, std::shared_ptr ref, int desc) + : Handle{std::move(ca), std::move(ref)}, tag{FD}, fd{desc} + { } + + explicit PollHandle(ConstructorAccess ca, std::shared_ptr ref, OSSocketHandle sock) + : Handle{std::move(ca), std::move(ref)}, tag{SOCKET}, socket{sock} + { } /** * @brief Initializes the handle. diff --git a/src/uvw/prepare.hpp b/src/uvw/prepare.hpp index d5f1ddea..df4b40d5 100644 --- a/src/uvw/prepare.hpp +++ b/src/uvw/prepare.hpp @@ -16,6 +16,8 @@ namespace uvw { * @brief PrepareEvent event. * * It will be emitted by PrepareHandle according with its functionalities. + * + * To create a `PrepareHandle` through a `Loop`, no arguments are required. */ struct PrepareEvent: Event { }; @@ -32,17 +34,8 @@ class PrepareHandle final: public Handle { prepare.publish(PrepareEvent{}); } - using Handle::Handle; - public: - /** - * @brief Creates a new check handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new PrepareHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/process.hpp b/src/uvw/process.hpp index 004de09f..e902c558 100644 --- a/src/uvw/process.hpp +++ b/src/uvw/process.hpp @@ -60,20 +60,11 @@ class ProcessHandle final: public Handle { process.publish(ExitEvent{}); } - using Handle::Handle; - public: using Process = details::UVProcessFlags; using StdIO = details::UVStdIOFlags; - /** - * @brief Creates a new check handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new ProcessHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Disables inheritance for file descriptors/handles. diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index 55231858..b58455e7 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -14,8 +14,6 @@ namespace uvw { template class Request: public Resource { protected: - using Resource::Resource; - static auto reserve(U *req) { auto ptr = static_cast(req->data)->shared_from_this(); ptr->reset(); @@ -46,6 +44,8 @@ protected: } public: + using Resource::Resource; + /** * @brief Cancels a pending request. * diff --git a/src/uvw/resource.hpp b/src/uvw/resource.hpp index decd14b6..4bc1d09a 100644 --- a/src/uvw/resource.hpp +++ b/src/uvw/resource.hpp @@ -23,14 +23,7 @@ class Resource: public Emitter, public std::enable_shared_from_this { friend class Resource; protected: - explicit Resource(std::shared_ptr ref) - : Emitter{}, - std::enable_shared_from_this{}, - pLoop{std::move(ref)}, - resource{} - { - resource.data = static_cast(this); - } + struct ConstructorAccess { explicit ConstructorAccess(int) {} }; auto parent() const noexcept { return pLoop->loop.get(); @@ -69,6 +62,15 @@ protected: } public: + explicit Resource(ConstructorAccess, std::shared_ptr ref) + : Emitter{}, + std::enable_shared_from_this{}, + pLoop{std::move(ref)}, + resource{} + { + resource.data = static_cast(this); + } + Resource(const Resource &) = delete; Resource(Resource &&) = delete; @@ -79,6 +81,17 @@ public: Resource& operator=(const Resource &) = delete; Resource& operator=(Resource &&) = delete; + /** + * @brief Creates a new resource of the given type. + * @param loop A pointer to the loop from which the handle generated. + * @param args Arguments to be forwarded to the actual constructor (if any). + * @return A pointer to the newly created resource. + */ + template + static std::shared_ptr create(std::shared_ptr loop, Args&&... args) { + return std::make_shared(ConstructorAccess{0}, std::move(loop), std::forward(args)...); + } + /** * @brief Gets the loop from which the resource was originated. * @return A reference to a loop instance. diff --git a/src/uvw/signal.hpp b/src/uvw/signal.hpp index ca8f6eb7..5e90a02e 100644 --- a/src/uvw/signal.hpp +++ b/src/uvw/signal.hpp @@ -31,6 +31,8 @@ struct SignalEvent: Event { * bases.
* Reception of some signals is emulated on Windows. * + * To create a `SignalHandle` through a `Loop`, no arguments are required. + * * See the official * [documentation](http://docs.libuv.org/en/v1.x/signal.html) * for further details. @@ -41,17 +43,8 @@ class SignalHandle final: public Handle { signal.publish(SignalEvent{signum}); } - using Handle::Handle; - public: - /** - * @brief Creates a new signal handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new SignalHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/stream.hpp b/src/uvw/stream.hpp index 74b20e9a..239f7dde 100644 --- a/src/uvw/stream.hpp +++ b/src/uvw/stream.hpp @@ -74,14 +74,9 @@ struct DataEvent: Event { namespace details { -class ConnectReq final: public Request { +struct ConnectReq final: public Request { using Request::Request; -public: - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new ConnectReq{std::move(loop)}}; - } - template void connect(F &&f, Args... args) { invoke(std::forward(f), get(), std::forward(args)..., &defaultCallback); @@ -89,14 +84,9 @@ public: }; -class ShutdownReq final: public Request { +struct ShutdownReq final: public Request { using Request::Request; -public: - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new ShutdownReq{std::move(loop)}}; - } - void shutdown(uv_stream_t *handle) { invoke(&uv_shutdown, get(), handle, &defaultCallback); } @@ -112,21 +102,16 @@ class WriteReq final: public Request { delete[] bufs; } +public: template - WriteReq(std::shared_ptr loop, const uv_buf_t (&arr)[N]) - : Request{std::move(loop)}, + WriteReq(ConstructorAccess ca, std::shared_ptr loop, const uv_buf_t (&arr)[N]) + : Request{std::move(ca), std::move(loop)}, bufs{new uv_buf_t[N], &deleter}, nbufs{N} { std::copy_n(std::begin(arr), N, bufs.get()); } -public: - template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new WriteReq{std::forward(args)...}}; - } - void write(uv_stream_t *handle) { invoke(&uv_write, get(), handle, bufs.get(), nbufs, &defaultCallback); } @@ -178,16 +163,15 @@ class StreamHandle: public Handle { else { ref.publish(ListenEvent{}); } } -protected: +public: #ifdef _WIN32 - StreamHandle(std::shared_ptr ref) - : Handle{std::move(ref)} + StreamHandle(ConstructorAccess ca, std::shared_ptr ref) + : Handle{std::move(ca), std::move(ref)} { } #else using Handle::Handle; #endif -public: /** * @brief Shutdowns the outgoing (write) side of a duplex stream. * diff --git a/src/uvw/tcp.hpp b/src/uvw/tcp.hpp index 71d14a71..64f1237f 100644 --- a/src/uvw/tcp.hpp +++ b/src/uvw/tcp.hpp @@ -33,39 +33,30 @@ enum class UVTcpFlags: std::underlying_type_t { * TCP handles are used to represent both TCP streams and servers.
* By default, _IPv4_ is used as a template parameter. The handle already * supports _IPv6_ out-of-the-box by using `uvw::IPv6`. + * + * To create a `TcpHandle` through a `Loop`, arguments follow: + * + * * An optional integer value that indicates the flags used to initialize + * the socket. + * + * See the official + * [documentation](http://docs.libuv.org/en/v1.x/tcp.html#c.uv_tcp_init_ex) + * for further details. */ class TcpHandle final: public StreamHandle { - explicit TcpHandle(std::shared_ptr ref) - : StreamHandle{std::move(ref)}, tag{DEFAULT}, flags{} - { } - - explicit TcpHandle(std::shared_ptr ref, unsigned int f) - : StreamHandle{std::move(ref)}, tag{FLAGS}, flags{f} - { } - public: using Time = std::chrono::seconds; using Bind = details::UVTcpFlags; using IPv4 = uvw::IPv4; using IPv6 = uvw::IPv6; - /** - * @brief Creates a new tcp handle. - * @param args - * - * * A pointer to the loop from which the handle generated. - * * An optional integer value (_flags_) that indicates optional flags used - * to initialize the socket.
- * See the official - * [documentation](http://docs.libuv.org/en/v1.x/tcp.html#c.uv_tcp_init_ex) - * for further details. - * - * @return A pointer to the newly created handle. - */ - template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new TcpHandle{std::forward(args)...}}; - } + explicit TcpHandle(ConstructorAccess ca, std::shared_ptr ref) + : StreamHandle{std::move(ca), std::move(ref)}, tag{DEFAULT}, flags{} + { } + + explicit TcpHandle(ConstructorAccess ca, std::shared_ptr ref, unsigned int f) + : StreamHandle{std::move(ca), std::move(ref)}, tag{FLAGS}, flags{f} + { } /** * @brief Initializes the handle. No socket is created as of yet. diff --git a/src/uvw/timer.hpp b/src/uvw/timer.hpp index 0d656c08..43171ead 100644 --- a/src/uvw/timer.hpp +++ b/src/uvw/timer.hpp @@ -25,6 +25,8 @@ struct TimerEvent: Event { }; * @brief The TimerHandle handle. * * Timer handles are used to schedule events to be emitted in the future. + * + * To create a `TimerHandle` through a `Loop`, no arguments are required. */ class TimerHandle final: public Handle { static void startCallback(uv_timer_t *handle) { @@ -32,19 +34,10 @@ class TimerHandle final: public Handle { timer.publish(TimerEvent{}); } - using Handle::Handle; - public: using Time = std::chrono::milliseconds; - /** - * @brief Creates a new check handle. - * @param loop A pointer to the loop from which the handle generated. - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop) { - return std::shared_ptr{new TimerHandle{std::move(loop)}}; - } + using Handle::Handle; /** * @brief Initializes the handle. diff --git a/src/uvw/tty.hpp b/src/uvw/tty.hpp index 4c742a95..097fd22c 100644 --- a/src/uvw/tty.hpp +++ b/src/uvw/tty.hpp @@ -37,44 +37,37 @@ enum class UVTTYModeT: std::underlying_type_t { * @brief The TTYHandle handle. * * TTY handles represent a stream for the console. + * + * To create a `TTYHandle` through a `Loop`, arguments follow: + * + * * A valid FileHandle. Usually the file descriptor will be: + * * `0` = `stdin` + * * `1` = `stdout` + * * `2` = `stderr` + * * A boolean value that specifies the plan on calling `read()` with this + * stream. Remember that `stdin` is readable, `stdout` is not. + * + * See the official + * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_init) + * for further details. */ class TTYHandle final: public StreamHandle { - explicit TTYHandle(std::shared_ptr ref, - FileHandle desc, - bool readable, - std::shared_ptr rmm) - : StreamHandle{std::move(ref)}, - memo{std::move(rmm)}, - fd{desc}, - rw{readable} - { } + static auto resetModeMemo() { + static std::weak_ptr weak; + auto shared = weak.lock(); + if(!shared) { weak = shared = std::make_shared(); } + return shared; + } public: using Mode = details::UVTTYModeT; - /** - * @brief Creates a new tty handle. - * @param loop A pointer to the loop from which the handle generated. - * @param desc A valid FileHandle. Usually the file descriptor will be: - * * `0` = `stdin` - * * `1` = `stdout` - * * `2` = `stderr` - * @param readable A boolean value (_readable_) that specifies the plan on - * calling `read()` with this stream. Remember that `stdin` is readable, - * `stdout` is not. - * - * See the official - * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_init) - * for further details. - * - * @return A pointer to the newly created handle. - */ - static std::shared_ptr create(std::shared_ptr loop, FileHandle desc, bool readable) { - static std::weak_ptr rmm; - auto ptr = rmm.lock(); - if(!ptr) { rmm = ptr = std::make_shared(); } - return std::shared_ptr{new TTYHandle{std::move(loop), std::move(desc), readable, ptr}}; - } + explicit TTYHandle(ConstructorAccess ca, std::shared_ptr ref, FileHandle desc, bool readable) + : StreamHandle{std::move(ca), std::move(ref)}, + memo{resetModeMemo()}, + fd{desc}, + rw{readable} + { } /** * @brief Initializes the handle. diff --git a/src/uvw/udp.hpp b/src/uvw/udp.hpp index 45bd3b22..1816bc04 100644 --- a/src/uvw/udp.hpp +++ b/src/uvw/udp.hpp @@ -67,21 +67,16 @@ class SendReq final: public Request { delete[] bufs; } +public: template - SendReq(std::shared_ptr loop, const uv_buf_t (&arr)[N]) - : Request{std::move(loop)}, + SendReq(ConstructorAccess ca, std::shared_ptr loop, const uv_buf_t (&arr)[N]) + : Request{std::move(ca), std::move(loop)}, bufs{new uv_buf_t[N], &deleter}, nbufs{N} { std::copy_n(std::begin(arr), N, bufs.get()); } -public: - template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new SendReq{std::forward(args)...}}; - } - void send(uv_udp_t *handle, const struct sockaddr* addr) { invoke(&uv_udp_send, get(), handle, bufs.get(), nbufs, addr, &defaultCallback); } @@ -101,6 +96,15 @@ private: * UDP handles encapsulate UDP communication for both clients and servers.
* By default, _IPv4_ is used as a template parameter. The handle already * supports _IPv6_ out-of-the-box by using `uvw::IPv6`. + * + * To create an `UDPHandle` through a `Loop`, arguments follow: + * + * * An optional integer value that indicates optional flags used to initialize + * the socket. + * + * See the official + * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_init_ex) + * for further details. */ class UDPHandle final: public Handle { template @@ -125,37 +129,19 @@ class UDPHandle final: public Handle { } } - explicit UDPHandle(std::shared_ptr ref) - : Handle{std::move(ref)}, tag{DEFAULT}, flags{} - { } - - explicit UDPHandle(std::shared_ptr ref, unsigned int f) - : Handle{std::move(ref)}, tag{FLAGS}, flags{f} - { } - public: using Membership = details::UVMembership; using Bind = details::UVUdpFlags; using IPv4 = uvw::IPv4; using IPv6 = uvw::IPv6; - /** - * @brief Creates a new udp handle. - * @param args - * - * * A pointer to the loop from which the handle generated. - * * An optional integer value (_flags_) that indicates optional flags used - * to initialize the socket.
- * See the official - * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_init_ex) - * for further details. - * - * @return A pointer to the newly created handle. - */ - template - static std::shared_ptr create(Args&&... args) { - return std::shared_ptr{new UDPHandle{std::forward(args)...}}; - } + explicit UDPHandle(ConstructorAccess ca, std::shared_ptr ref) + : Handle{std::move(ca), std::move(ref)}, tag{DEFAULT}, flags{} + { } + + explicit UDPHandle(ConstructorAccess ca, std::shared_ptr ref, unsigned int f) + : Handle{std::move(ca), std::move(ref)}, tag{FLAGS}, flags{f} + { } /** * @brief Initializes the handle. The actual socket is created lazily. diff --git a/src/uvw/work.hpp b/src/uvw/work.hpp index 9bdbabf4..91869ff0 100644 --- a/src/uvw/work.hpp +++ b/src/uvw/work.hpp @@ -27,6 +27,10 @@ struct WorkEvent: Event { }; * It runs user code using a thread from the threadpool and gets notified in the * loop thread by means of an event. * + * To create a `WorkReq` through a `Loop`, arguments follow: + * + * * A valid instance of a `Task`, that is of type `std::function`. + * * See the official * [documentation](http://docs.libuv.org/en/v1.x/threadpool.html) * for further details. @@ -38,23 +42,12 @@ class WorkReq final: public Request { static_cast(req->data)->task(); } - explicit WorkReq(std::shared_ptr ref, InternalTask t) - : Request{std::move(ref)}, task{t} - { } - public: using Task = InternalTask; - /** - * @brief Creates a new work request. - * @param loop A pointer to the loop from which the handle generated. - * @param task A valid instance of a `Task`, that is of type - * `std::function`. - * @return A pointer to the newly created request. - */ - static std::shared_ptr create(std::shared_ptr loop, Task task) { - return std::shared_ptr{new WorkReq{std::move(loop), std::move(task)}}; - } + explicit WorkReq(ConstructorAccess ca, std::shared_ptr ref, InternalTask t) + : Request{std::move(ca), std::move(ref)}, task{t} + { } /** * @brief Runs the given task in a separate thread. diff --git a/test/uvw/emitter.cpp b/test/uvw/emitter.cpp index a32f2302..28f24203 100644 --- a/test/uvw/emitter.cpp +++ b/test/uvw/emitter.cpp @@ -10,7 +10,7 @@ struct TestEmitter: uvw::Emitter { }; -TEST(Emitter, ClearAndClearAll) { +TEST(Emitter, ClearAndClear) { TestEmitter emitter{}; ASSERT_TRUE(emitter.empty()); @@ -40,7 +40,7 @@ TEST(Emitter, ClearAndClearAll) { ASSERT_FALSE(emitter.empty()); ASSERT_FALSE(emitter.empty()); - emitter.clearAll(); + emitter.clear(); ASSERT_TRUE(emitter.empty()); ASSERT_TRUE(emitter.empty());