added a clang-format file, updated the whole codebase

This commit is contained in:
Michele Caini 2022-03-08 12:59:19 +01:00
parent 25b8fad800
commit 5664b04075
82 changed files with 850 additions and 1599 deletions

41
.clang-format Normal file
View File

@ -0,0 +1,41 @@
BasedOnStyle: llvm
---
AccessModifierOffset: -4
AlignEscapedNewlines: DontAlign
AllowShortBlocksOnASingleLine: Empty
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeTernaryOperators: true
ColumnLimit: 0
DerivePointerAlignment: false
IncludeCategories:
- Regex: '<[[:alnum:]_]+>'
Priority: 1
- Regex: '<(gtest|gmock)/'
Priority: 2
- Regex: '<[[:alnum:]_./]+>'
Priority: 3
- Regex: '<entt/'
Priority: 4
- Regex: '.*'
Priority: 5
IndentPPDirectives: AfterHash
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceAroundPointerQualifiers: After
SpaceBeforeCaseColon: false
SpaceBeforeCtorInitializerColon: false
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: false
Standard: Latest
TabWidth: 4
UseTab: Never

View File

@ -1,27 +1,22 @@
#ifdef UVW_AS_LIB
#include "async.h"
# include "async.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE void AsyncHandle::sendCallback(uv_async_t *handle) {
AsyncHandle &async = *(static_cast<AsyncHandle *>(handle->data));
async.publish(AsyncEvent{});
}
UVW_INLINE bool AsyncHandle::init() {
return initialize(&uv_async_init, &sendCallback);
}
UVW_INLINE void AsyncHandle::send() {
invoke(&uv_async_send, get());
}
}
} // namespace uvw

View File

@ -1,15 +1,12 @@
#ifndef UVW_ASYNC_INCLUDE_H
#define UVW_ASYNC_INCLUDE_H
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
namespace uvw {
/**
* @brief AsyncEvent event.
*
@ -17,7 +14,6 @@ namespace uvw {
*/
struct AsyncEvent {};
/**
* @brief The AsyncHandle handle.
*
@ -55,12 +51,10 @@ public:
void send();
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "async.cpp"
# include "async.cpp"
#endif
#endif // UVW_ASYNC_INCLUDE_H

View File

@ -1,32 +1,26 @@
#ifdef UVW_AS_LIB
#include "check.h"
# include "check.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE void CheckHandle::startCallback(uv_check_t *handle) {
CheckHandle &check = *(static_cast<CheckHandle *>(handle->data));
check.publish(CheckEvent{});
}
UVW_INLINE bool CheckHandle::init() {
return initialize(&uv_check_init);
}
UVW_INLINE void CheckHandle::start() {
invoke(&uv_check_start, get(), &startCallback);
}
UVW_INLINE void CheckHandle::stop() {
invoke(&uv_check_stop, get());
}
}
} // namespace uvw

View File

@ -1,15 +1,12 @@
#ifndef UVW_CHECK_INCLUDE_H
#define UVW_CHECK_INCLUDE_H
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
namespace uvw {
/**
* @brief CheckEvent event.
*
@ -17,7 +14,6 @@ namespace uvw {
*/
struct CheckEvent {};
/**
* @brief The CheckHandle handle.
*
@ -52,12 +48,10 @@ public:
void stop();
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "check.cpp"
# include "check.cpp"
#endif
#endif // UVW_CHECK_INCLUDE_H

View File

@ -1,12 +1,10 @@
#ifndef UVW_CONFIG_H
#define UVW_CONFIG_H
#ifndef UVW_AS_LIB
#define UVW_INLINE inline
# define UVW_INLINE inline
#else
#define UVW_INLINE
# define UVW_INLINE
#endif
#endif

View File

@ -1,100 +1,73 @@
#ifdef UVW_AS_LIB
#include "dns.h"
# include "dns.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE AddrInfoEvent::AddrInfoEvent(std::unique_ptr<addrinfo, Deleter> addr)
: data{std::move(addr)}
{}
: data{std::move(addr)} {}
UVW_INLINE NameInfoEvent::NameInfoEvent(const char *host, const char *serv)
: hostname{host}, service{serv}
{}
: hostname{host}, service{serv} {}
UVW_INLINE void GetAddrInfoReq::addrInfoCallback(uv_getaddrinfo_t *req, int status, addrinfo *res) {
auto ptr = reserve(req);
if(status) {
if(auto ptr = reserve(req); status) {
ptr->publish(ErrorEvent{status});
} else {
auto data = std::unique_ptr<addrinfo, void (*)(addrinfo *)>{res, [](addrinfo *addr) {
uv_freeaddrinfo(addr);
}};
auto data = std::unique_ptr<addrinfo, void (*)(addrinfo *)>{res, [](addrinfo *addr) { uv_freeaddrinfo(addr); }};
ptr->publish(AddrInfoEvent{std::move(data)});
}
}
UVW_INLINE void GetAddrInfoReq::nodeAddrInfo(const char *node, const char *service, addrinfo *hints) {
invoke(&uv_getaddrinfo, parent(), get(), &addrInfoCallback, node, service, hints);
}
UVW_INLINE auto GetAddrInfoReq::nodeAddrInfoSync(const char *node, const char *service, addrinfo *hints) {
auto req = get();
auto err = uv_getaddrinfo(parent(), req, nullptr, node, service, hints);
auto data = std::unique_ptr<addrinfo, void (*)(addrinfo *)>{req->addrinfo, [](addrinfo *addr) {
uv_freeaddrinfo(addr);
}};
auto data = std::unique_ptr<addrinfo, void (*)(addrinfo *)>{req->addrinfo, [](addrinfo *addr) { uv_freeaddrinfo(addr); }};
return std::make_pair(!err, std::move(data));
}
UVW_INLINE void GetAddrInfoReq::nodeAddrInfo(const std::string &node, addrinfo *hints) {
nodeAddrInfo(node.data(), nullptr, hints);
}
UVW_INLINE std::pair<bool, std::unique_ptr<addrinfo, GetAddrInfoReq::Deleter>> GetAddrInfoReq::nodeAddrInfoSync(const std::string &node, addrinfo *hints) {
return nodeAddrInfoSync(node.data(), nullptr, hints);
}
UVW_INLINE void GetAddrInfoReq::serviceAddrInfo(const std::string &service, addrinfo *hints) {
nodeAddrInfo(nullptr, service.data(), hints);
}
UVW_INLINE std::pair<bool, std::unique_ptr<addrinfo, GetAddrInfoReq::Deleter>> GetAddrInfoReq::serviceAddrInfoSync(const std::string &service, addrinfo *hints) {
return nodeAddrInfoSync(nullptr, service.data(), hints);
}
UVW_INLINE void GetAddrInfoReq::addrInfo(const std::string &node, const std::string &service, addrinfo *hints) {
nodeAddrInfo(node.data(), service.data(), hints);
}
UVW_INLINE std::pair<bool, std::unique_ptr<addrinfo, GetAddrInfoReq::Deleter>> GetAddrInfoReq::addrInfoSync(const std::string &node, const std::string &service, addrinfo *hints) {
return nodeAddrInfoSync(node.data(), service.data(), hints);
}
UVW_INLINE void GetNameInfoReq::nameInfoCallback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service) {
auto ptr = reserve(req);
if(status) {
if(auto ptr = reserve(req); status) {
ptr->publish(ErrorEvent{status});
} else {
ptr->publish(NameInfoEvent{hostname, service});
}
}
UVW_INLINE void GetNameInfoReq::nameInfo(const sockaddr &addr, int flags) {
invoke(&uv_getnameinfo, parent(), get(), &nameInfoCallback, &addr, flags);
}
template<typename I>
UVW_INLINE void GetNameInfoReq::nameInfo(const std::string &ip, unsigned int port, int flags) {
typename details::IpTraits<I>::Type addr;
@ -113,7 +86,6 @@ UVW_INLINE std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq
return std::make_pair(!err, std::make_pair(req->host, req->service));
}
template<typename I>
UVW_INLINE std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync(const std::string &ip, unsigned int port, int flags) {
typename details::IpTraits<I>::Type addr;
@ -121,13 +93,11 @@ UVW_INLINE std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq
return nameInfoSync(reinterpret_cast<const sockaddr &>(addr), flags);
}
template<typename I>
UVW_INLINE std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync(Addr addr, int flags) {
return nameInfoSync<I>(std::move(addr.ip), addr.port, flags);
}
// explicit instantiations
#ifdef UVW_AS_LIB
template void GetNameInfoReq::nameInfo<IPv4>(const std::string &, unsigned int, int);
@ -143,5 +113,4 @@ template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::
template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(Addr, int);
#endif // UVW_AS_LIB
}
} // namespace uvw

View File

@ -1,26 +1,23 @@
#ifndef UVW_DNS_INCLUDE_H
#define UVW_DNS_INCLUDE_H
#include <utility>
#include <memory>
#include <string>
#include <utility>
#include <uv.h>
#include "loop.h"
#include "request.hpp"
#include "util.h"
#include "loop.h"
namespace uvw {
/**
* @brief AddrInfoEvent event.
*
* It will be emitted by GetAddrInfoReq according with its functionalities.
*/
struct AddrInfoEvent {
using Deleter = void(*)(addrinfo *);
using Deleter = void (*)(addrinfo *);
AddrInfoEvent(std::unique_ptr<addrinfo, Deleter> addr);
@ -33,7 +30,6 @@ struct AddrInfoEvent {
std::unique_ptr<addrinfo, Deleter> data;
};
/**
* @brief NameInfoEvent event.
*
@ -48,7 +44,7 @@ struct NameInfoEvent {
* See [getnameinfo](http://linux.die.net/man/3/getnameinfo) for further
* details.
*/
const char * hostname;
const char *hostname;
/**
* @brief A valid service name.
@ -56,10 +52,9 @@ struct NameInfoEvent {
* See [getnameinfo](http://linux.die.net/man/3/getnameinfo) for further
* details.
*/
const char * service;
const char *service;
};
/**
* @brief The GetAddrInfoReq request.
*
@ -74,7 +69,7 @@ class GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> {
auto nodeAddrInfoSync(const char *node, const char *service, addrinfo *hints = nullptr);
public:
using Deleter = void(*)(addrinfo *);
using Deleter = void (*)(addrinfo *);
using Request::Request;
@ -144,7 +139,6 @@ public:
std::pair<bool, std::unique_ptr<addrinfo, Deleter>> addrInfoSync(const std::string &node, const std::string &service, addrinfo *hints = nullptr);
};
/**
* @brief The GetNameInfoReq request.
*
@ -229,13 +223,11 @@ public:
std::pair<bool, std::pair<const char *, const char *>> nameInfoSync(Addr addr, int flags = 0);
};
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
// (extern) explicit instantiations
#ifdef UVW_AS_LIB
extern template void GetNameInfoReq::nameInfo<IPv4>(const std::string &, unsigned int, int);
@ -251,19 +243,15 @@ extern template std::pair<bool, std::pair<const char *, const char *>> GetNameIn
extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(Addr, int);
#endif // UVW_AS_LIB
/**
* Internal details not to be documented.
* @endcond
*/
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "dns.cpp"
# include "dns.cpp"
#endif
#endif // UVW_DNS_INCLUDE_H

View File

@ -1,37 +1,29 @@
#ifdef UVW_AS_LIB
#include "emitter.h"
# include "emitter.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE int ErrorEvent::translate(int sys) noexcept {
return uv_translate_sys_error(sys);
}
UVW_INLINE const char * ErrorEvent::what() const noexcept {
UVW_INLINE const char *ErrorEvent::what() const noexcept {
return uv_strerror(ec);
}
UVW_INLINE const char * ErrorEvent::name() const noexcept {
UVW_INLINE const char *ErrorEvent::name() const noexcept {
return uv_err_name(ec);
}
UVW_INLINE int ErrorEvent::code() const noexcept {
return ec;
}
UVW_INLINE ErrorEvent::operator bool() const noexcept {
return ec < 0;
}
}
} // namespace uvw

View File

@ -1,22 +1,19 @@
#ifndef UVW_EMITTER_INCLUDE_H
#define UVW_EMITTER_INCLUDE_H
#include <type_traits>
#include <functional>
#include <algorithm>
#include <utility>
#include <cstddef>
#include <unordered_map>
#include <memory>
#include <functional>
#include <list>
#include <memory>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <uv.h>
#include "type_info.hpp"
namespace uvw {
/**
* @brief The ErrorEvent event.
*
@ -25,8 +22,7 @@ namespace uvw {
struct ErrorEvent {
template<typename U, typename = std::enable_if_t<std::is_integral_v<U>>>
explicit ErrorEvent(U val) noexcept
: ec{static_cast<int>(val)}
{}
: ec{static_cast<int>(val)} {}
/**
* @brief Returns the `libuv` error code equivalent to the given platform dependent error code.
@ -49,7 +45,7 @@ struct ErrorEvent {
*
* @return The error message for the given error code.
*/
const char * what() const noexcept;
const char *what() const noexcept;
/**
* @brief Returns the error name for the given error code.
@ -58,7 +54,7 @@ struct ErrorEvent {
*
* @return The error name for the given error code.
*/
const char * name() const noexcept;
const char *name() const noexcept;
/**
* @brief Gets the underlying error code, that is an error constant of `libuv`.
@ -76,7 +72,6 @@ private:
const int ec;
};
/**
* @brief Event emitter base class.
*
@ -99,15 +94,14 @@ class Emitter {
using Connection = typename ListenerList::iterator;
bool empty() const noexcept override {
auto pred = [](auto &&element){ return element.first; };
auto pred = [](auto &&element) { return element.first; };
return std::all_of(onceL.cbegin(), onceL.cend(), pred) &&
std::all_of(onL.cbegin(), onL.cend(), pred);
return std::all_of(onceL.cbegin(), onceL.cend(), pred) && std::all_of(onL.cbegin(), onL.cend(), pred);
}
void clear() noexcept override {
if(publishing) {
auto func = [](auto &&element){ element.first = true; };
auto func = [](auto &&element) { element.first = true; };
std::for_each(onceL.begin(), onceL.end(), func);
std::for_each(onL.begin(), onL.end(), func);
} else {
@ -128,7 +122,7 @@ class Emitter {
conn->first = true;
if(!publishing) {
auto pred = [](auto &&element){ return element.first; };
auto pred = [](auto &&element) { return element.first; };
onceL.remove_if(pred);
onL.remove_if(pred);
}
@ -149,7 +143,7 @@ class Emitter {
publishing = false;
onL.remove_if([](auto &&element){ return element.first; });
onL.remove_if([](auto &&element) { return element.first; });
}
private:
@ -159,20 +153,20 @@ class Emitter {
};
template<typename E>
Handler<E> & handler() noexcept {
Handler<E> &handler() noexcept {
auto id = type<E>();
if(!handlers.count(id)) {
handlers[id] = std::make_unique<Handler<E>>();
handlers[id] = std::make_unique<Handler<E>>();
}
return static_cast<Handler<E>&>(*handlers.at(id));
return static_cast<Handler<E> &>(*handlers.at(id));
}
protected:
template<typename E>
void publish(E event) {
handler<E>().publish(std::move(event), *static_cast<T*>(this));
handler<E>().publish(std::move(event), *static_cast<T *>(this));
}
public:
@ -188,18 +182,18 @@ public:
*/
template<typename E>
struct Connection: private Handler<E>::Connection {
template<typename> friend class Emitter;
template<typename>
friend class Emitter;
Connection() = default;
Connection(const Connection &) = default;
Connection(Connection &&) = default;
Connection(typename Handler<E>::Connection conn)
: Handler<E>::Connection{std::move(conn)}
{}
: Handler<E>::Connection{std::move(conn)} {}
Connection & operator=(const Connection &) = default;
Connection & operator=(Connection &&) = default;
Connection &operator=(const Connection &) = default;
Connection &operator=(Connection &&) = default;
};
virtual ~Emitter() noexcept {
@ -267,8 +261,7 @@ public:
* @brief Disconnects all the listeners.
*/
void clear() noexcept {
std::for_each(handlers.begin(), handlers.end(),
[](auto &&hdlr){ if(hdlr.second) { hdlr.second->clear(); } });
std::for_each(handlers.begin(), handlers.end(), [](auto &&hdlr) { if(hdlr.second) { hdlr.second->clear(); } });
}
/**
@ -280,8 +273,7 @@ public:
bool empty() const noexcept {
auto id = type<E>();
return (!handlers.count(id) ||
static_cast<Handler<E>&>(*handlers.at(id)).empty());
return (!handlers.count(id) || static_cast<Handler<E> &>(*handlers.at(id)).empty());
}
/**
@ -290,20 +282,17 @@ public:
* false otherwise.
*/
bool empty() const noexcept {
return std::all_of(handlers.cbegin(), handlers.cend(),
[](auto &&hdlr){ return !hdlr.second || hdlr.second->empty(); });
return std::all_of(handlers.cbegin(), handlers.cend(), [](auto &&hdlr) { return !hdlr.second || hdlr.second->empty(); });
}
private:
std::unordered_map<std::uint32_t, std::unique_ptr<BaseHandler>> handlers{};
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "emitter.cpp"
# include "emitter.cpp"
#endif
#endif // UVW_EMITTER_INCLUDE_H

View File

@ -1,13 +1,11 @@
#ifdef UVW_AS_LIB
#include "fs.h"
# include "fs.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE void FileReq::fsOpenCallback(uv_fs_t *req) {
auto ptr = reserve(req);
@ -19,7 +17,6 @@ UVW_INLINE void FileReq::fsOpenCallback(uv_fs_t *req) {
}
}
UVW_INLINE void FileReq::fsCloseCallback(uv_fs_t *req) {
auto ptr = reserve(req);
@ -31,7 +28,6 @@ UVW_INLINE void FileReq::fsCloseCallback(uv_fs_t *req) {
}
}
UVW_INLINE void FileReq::fsReadCallback(uv_fs_t *req) {
auto ptr = reserve(req);
@ -42,17 +38,14 @@ UVW_INLINE void FileReq::fsReadCallback(uv_fs_t *req) {
}
}
UVW_INLINE FileReq::~FileReq() noexcept {
uv_fs_req_cleanup(get());
}
UVW_INLINE void FileReq::close() {
cleanupAndInvoke(&uv_fs_close, parent(), get(), file, &fsCloseCallback);
}
UVW_INLINE bool FileReq::closeSync() {
auto req = get();
@ -65,12 +58,10 @@ UVW_INLINE bool FileReq::closeSync() {
return !(req->result < 0);
}
UVW_INLINE void FileReq::open(const std::string &path, Flags<FileOpen> flags, int mode) {
cleanupAndInvoke(&uv_fs_open, parent(), get(), path.data(), flags, mode, &fsOpenCallback);
}
UVW_INLINE bool FileReq::openSync(const std::string &path, Flags<FileOpen> flags, int mode) {
auto req = get();
@ -83,7 +74,6 @@ UVW_INLINE bool FileReq::openSync(const std::string &path, Flags<FileOpen> flags
return !(req->result < 0);
}
UVW_INLINE void FileReq::read(int64_t offset, unsigned int len) {
current = std::unique_ptr<char[]>{new char[len]};
buffer = uv_buf_init(current.get(), len);
@ -91,7 +81,6 @@ UVW_INLINE void FileReq::read(int64_t offset, unsigned int len) {
cleanupAndInvoke(&uv_fs_read, parent(), get(), file, bufs, 1, offset, &fsReadCallback);
}
UVW_INLINE std::pair<bool, std::pair<std::unique_ptr<const char[]>, std::size_t>> FileReq::readSync(int64_t offset, unsigned int len) {
current = std::unique_ptr<char[]>{new char[len]};
buffer = uv_buf_init(current.get(), len);
@ -102,20 +91,17 @@ UVW_INLINE std::pair<bool, std::pair<std::unique_ptr<const char[]>, std::size_t>
return std::make_pair(!err, std::make_pair(std::move(current), err ? 0 : std::size_t(req->result)));
}
UVW_INLINE void FileReq::write(std::unique_ptr<char[]> buf, unsigned int len, int64_t offset) {
current = std::move(buf);
uv_buf_t bufs[] = {uv_buf_init(current.get(), len)};
cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsResultCallback<Type::WRITE>);
}
UVW_INLINE void FileReq::write(char *buf, unsigned int len, int64_t offset) {
uv_buf_t bufs[] = {uv_buf_init(buf, len)};
cleanupAndInvoke(&uv_fs_write, parent(), get(), file, bufs, 1, offset, &fsResultCallback<Type::WRITE>);
}
UVW_INLINE std::pair<bool, std::size_t> FileReq::writeSync(std::unique_ptr<char[]> buf, unsigned int len, int64_t offset) {
current = std::move(buf);
uv_buf_t bufs[] = {uv_buf_init(current.get(), len)};
@ -125,60 +111,50 @@ UVW_INLINE std::pair<bool, std::size_t> FileReq::writeSync(std::unique_ptr<char[
return std::make_pair(!err, err ? 0 : std::size_t(req->result));
}
UVW_INLINE void FileReq::stat() {
cleanupAndInvoke(&uv_fs_fstat, parent(), get(), file, &fsStatCallback<Type::FSTAT>);
}
UVW_INLINE std::pair<bool, Stat> FileReq::statSync() {
auto req = get();
cleanupAndInvokeSync(&uv_fs_fstat, parent(), req, file);
return std::make_pair(!(req->result < 0), req->statbuf);
}
UVW_INLINE void FileReq::sync() {
cleanupAndInvoke(&uv_fs_fsync, parent(), get(), file, &fsGenericCallback<Type::FSYNC>);
}
UVW_INLINE bool FileReq::syncSync() {
auto req = get();
cleanupAndInvokeSync(&uv_fs_fsync, parent(), req, file);
return !(req->result < 0);
}
UVW_INLINE void FileReq::datasync() {
cleanupAndInvoke(&uv_fs_fdatasync, parent(), get(), file, &fsGenericCallback<Type::FDATASYNC>);
}
UVW_INLINE bool FileReq::datasyncSync() {
auto req = get();
cleanupAndInvokeSync(&uv_fs_fdatasync, parent(), req, file);
return !(req->result < 0);
}
UVW_INLINE void FileReq::truncate(int64_t offset) {
cleanupAndInvoke(&uv_fs_ftruncate, parent(), get(), file, offset, &fsGenericCallback<Type::FTRUNCATE>);
}
UVW_INLINE bool FileReq::truncateSync(int64_t offset) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_ftruncate, parent(), req, file, offset);
return !(req->result < 0);
}
UVW_INLINE void FileReq::sendfile(FileHandle out, int64_t offset, std::size_t length) {
cleanupAndInvoke(&uv_fs_sendfile, parent(), get(), out, file, offset, length, &fsResultCallback<Type::SENDFILE>);
}
UVW_INLINE std::pair<bool, std::size_t> FileReq::sendfileSync(FileHandle out, int64_t offset, std::size_t length) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_sendfile, parent(), req, out, file, offset, length);
@ -186,48 +162,40 @@ UVW_INLINE std::pair<bool, std::size_t> FileReq::sendfileSync(FileHandle out, in
return std::make_pair(!err, err ? 0 : std::size_t(req->result));
}
UVW_INLINE void FileReq::chmod(int mode) {
cleanupAndInvoke(&uv_fs_fchmod, parent(), get(), file, mode, &fsGenericCallback<Type::FCHMOD>);
}
UVW_INLINE bool FileReq::chmodSync(int mode) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_fchmod, parent(), req, file, mode);
return !(req->result < 0);
}
UVW_INLINE void FileReq::futime(FsRequest::Time atime, FsRequest::Time mtime) {
cleanupAndInvoke(&uv_fs_futime, parent(), get(), file, atime.count(), mtime.count(), &fsGenericCallback<Type::FUTIME>);
}
UVW_INLINE bool FileReq::futimeSync(FsRequest::Time atime, FsRequest::Time mtime) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_futime, parent(), req, file, atime.count(), mtime.count());
return !(req->result < 0);
}
UVW_INLINE void FileReq::chown(Uid uid, Gid gid) {
cleanupAndInvoke(&uv_fs_fchown, parent(), get(), file, uid, gid, &fsGenericCallback<Type::FCHOWN>);
}
UVW_INLINE bool FileReq::chownSync(Uid uid, Gid gid) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_fchown, parent(), req, file, uid, gid);
return !(req->result < 0);
}
UVW_INLINE FileReq::operator FileHandle() const noexcept {
return file;
}
UVW_INLINE void FsReq::fsReadlinkCallback(uv_fs_t *req) {
auto ptr = reserve(req);
@ -238,7 +206,6 @@ UVW_INLINE void FsReq::fsReadlinkCallback(uv_fs_t *req) {
}
}
UVW_INLINE void FsReq::fsReaddirCallback(uv_fs_t *req) {
auto ptr = reserve(req);
@ -250,53 +217,44 @@ UVW_INLINE void FsReq::fsReaddirCallback(uv_fs_t *req) {
}
}
UVW_INLINE FsReq::~FsReq() noexcept {
uv_fs_req_cleanup(get());
}
UVW_INLINE void FsReq::unlink(const std::string &path) {
cleanupAndInvoke(&uv_fs_unlink, parent(), get(), path.data(), &fsGenericCallback<Type::UNLINK>);
}
UVW_INLINE bool FsReq::unlinkSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_unlink, parent(), req, path.data());
return !(req->result < 0);
}
UVW_INLINE void FsReq::mkdir(const std::string &path, int mode) {
cleanupAndInvoke(&uv_fs_mkdir, parent(), get(), path.data(), mode, &fsGenericCallback<Type::MKDIR>);
}
UVW_INLINE bool FsReq::mkdirSync(const std::string &path, int mode) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_mkdir, parent(), req, path.data(), mode);
return !(req->result < 0);
}
UVW_INLINE void FsReq::mkdtemp(const std::string &tpl) {
cleanupAndInvoke(&uv_fs_mkdtemp, parent(), get(), tpl.data(), &fsGenericCallback<Type::MKDTEMP>);
}
UVW_INLINE std::pair<bool, const char *> FsReq::mkdtempSync(const std::string &tpl) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_mkdtemp, parent(), req, tpl.data());
return std::make_pair(!(req->result < 0), req->path);
}
UVW_INLINE void FsReq::mkstemp(const std::string &tpl) {
cleanupAndInvoke(&uv_fs_mkstemp, parent(), get(), tpl.data(), &fsResultCallback<Type::MKSTEMP>);
}
UVW_INLINE std::pair<bool, std::pair<std::string, std::size_t>> FsReq::mkstempSync(const std::string &tpl) {
std::pair<bool, std::pair<std::string, std::size_t>> ret{false, {}};
auto req = get();
@ -311,36 +269,30 @@ UVW_INLINE std::pair<bool, std::pair<std::string, std::size_t>> FsReq::mkstempSy
return ret;
}
UVW_INLINE void FsReq::lutime(const std::string &path, Time atime, Time mtime) {
cleanupAndInvoke(&uv_fs_lutime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback<Type::LUTIME>);
}
UVW_INLINE bool FsReq::lutimeSync(const std::string &path, Time atime, Time mtime) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_lutime, parent(), req, path.data(), atime.count(), mtime.count());
return !(req->result < 0);
}
UVW_INLINE void FsReq::rmdir(const std::string &path) {
cleanupAndInvoke(&uv_fs_rmdir, parent(), get(), path.data(), &fsGenericCallback<Type::RMDIR>);
}
UVW_INLINE bool FsReq::rmdirSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_rmdir, parent(), req, path.data());
return !(req->result < 0);
}
UVW_INLINE void FsReq::scandir(const std::string &path, int flags) {
cleanupAndInvoke(&uv_fs_scandir, parent(), get(), path.data(), flags, &fsResultCallback<Type::SCANDIR>);
}
UVW_INLINE std::pair<bool, std::size_t> FsReq::scandirSync(const std::string &path, int flags) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_scandir, parent(), req, path.data(), flags);
@ -348,9 +300,8 @@ UVW_INLINE std::pair<bool, std::size_t> FsReq::scandirSync(const std::string &pa
return std::make_pair(!err, err ? 0 : std::size_t(req->result));
}
UVW_INLINE std::pair<bool, std::pair<FsReq::EntryType, const char *>> FsReq::scandirNext() {
std::pair<bool, std::pair<EntryType, const char *>> ret{false, { EntryType::UNKNOWN, nullptr }};
std::pair<bool, std::pair<EntryType, const char *>> ret{false, {EntryType::UNKNOWN, nullptr}};
// we cannot use cleanupAndInvokeSync because of the return value of uv_fs_scandir_next
uv_fs_req_cleanup(get());
@ -365,132 +316,110 @@ UVW_INLINE std::pair<bool, std::pair<FsReq::EntryType, const char *>> FsReq::sca
return ret;
}
UVW_INLINE void FsReq::stat(const std::string &path) {
cleanupAndInvoke(&uv_fs_stat, parent(), get(), path.data(), &fsStatCallback<Type::STAT>);
}
UVW_INLINE std::pair<bool, Stat> FsReq::statSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_stat, parent(), req, path.data());
return std::make_pair(!(req->result < 0), req->statbuf);
}
UVW_INLINE void FsReq::lstat(const std::string &path) {
cleanupAndInvoke(&uv_fs_lstat, parent(), get(), path.data(), &fsStatCallback<Type::LSTAT>);
}
UVW_INLINE std::pair<bool, Stat> FsReq::lstatSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_lstat, parent(), req, path.data());
return std::make_pair(!(req->result < 0), req->statbuf);
}
UVW_INLINE void FsReq::statfs(const std::string &path) {
cleanupAndInvoke(&uv_fs_statfs, parent(), get(), path.data(), &fsStatfsCallback);
}
UVW_INLINE std::pair<bool, Statfs> FsReq::statfsSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_statfs, parent(), req, path.data());
return std::make_pair(!(req->result < 0), *static_cast<uv_statfs_t *>(req->ptr));
}
UVW_INLINE void FsReq::rename(const std::string &old, const std::string &path) {
cleanupAndInvoke(&uv_fs_rename, parent(), get(), old.data(), path.data(), &fsGenericCallback<Type::RENAME>);
}
UVW_INLINE bool FsReq::renameSync(const std::string &old, const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_rename, parent(), req, old.data(), path.data());
return !(req->result < 0);
}
UVW_INLINE void FsReq::copyfile(const std::string &old, const std::string &path, Flags<CopyFile> flags) {
cleanupAndInvoke(&uv_fs_copyfile, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback<Type::COPYFILE>);
}
UVW_INLINE bool FsReq::copyfileSync(const std::string &old, const std::string &path, Flags<CopyFile> flags) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_copyfile, parent(), get(), old.data(), path.data(), flags);
return !(req->result < 0);
}
UVW_INLINE void FsReq::access(const std::string &path, int mode) {
cleanupAndInvoke(&uv_fs_access, parent(), get(), path.data(), mode, &fsGenericCallback<Type::ACCESS>);
}
UVW_INLINE bool FsReq::accessSync(const std::string &path, int mode) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_access, parent(), req, path.data(), mode);
return !(req->result < 0);
}
UVW_INLINE void FsReq::chmod(const std::string &path, int mode) {
cleanupAndInvoke(&uv_fs_chmod, parent(), get(), path.data(), mode, &fsGenericCallback<Type::CHMOD>);
}
UVW_INLINE bool FsReq::chmodSync(const std::string &path, int mode) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_chmod, parent(), req, path.data(), mode);
return !(req->result < 0);
}
UVW_INLINE void FsReq::utime(const std::string &path, FsRequest::Time atime, FsRequest::Time mtime) {
cleanupAndInvoke(&uv_fs_utime, parent(), get(), path.data(), atime.count(), mtime.count(), &fsGenericCallback<Type::UTIME>);
}
UVW_INLINE bool FsReq::utimeSync(const std::string &path, FsRequest::Time atime, FsRequest::Time mtime) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_utime, parent(), req, path.data(), atime.count(), mtime.count());
return !(req->result < 0);
}
UVW_INLINE void FsReq::link(const std::string &old, const std::string &path) {
cleanupAndInvoke(&uv_fs_link, parent(), get(), old.data(), path.data(), &fsGenericCallback<Type::LINK>);
}
UVW_INLINE bool FsReq::linkSync(const std::string &old, const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_link, parent(), req, old.data(), path.data());
return !(req->result < 0);
}
UVW_INLINE void FsReq::symlink(const std::string &old, const std::string &path, Flags<SymLink> flags) {
cleanupAndInvoke(&uv_fs_symlink, parent(), get(), old.data(), path.data(), flags, &fsGenericCallback<Type::SYMLINK>);
}
UVW_INLINE bool FsReq::symlinkSync(const std::string &old, const std::string &path, Flags<SymLink> flags) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_symlink, parent(), req, old.data(), path.data(), flags);
return !(req->result < 0);
}
UVW_INLINE void FsReq::readlink(const std::string &path) {
cleanupAndInvoke(&uv_fs_readlink, parent(), get(), path.data(), &fsReadlinkCallback);
}
UVW_INLINE std::pair<bool, std::pair<const char *, std::size_t>> FsReq::readlinkSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_readlink, parent(), req, path.data());
@ -498,62 +427,52 @@ UVW_INLINE std::pair<bool, std::pair<const char *, std::size_t>> FsReq::readlink
return std::make_pair(!err, std::make_pair(static_cast<char *>(req->ptr), err ? 0 : std::size_t(req->result)));
}
UVW_INLINE void FsReq::realpath(const std::string &path) {
cleanupAndInvoke(&uv_fs_realpath, parent(), get(), path.data(), &fsGenericCallback<Type::REALPATH>);
}
UVW_INLINE std::pair<bool, const char *> FsReq::realpathSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_realpath, parent(), req, path.data());
return std::make_pair(!(req->result < 0), req->path);
}
UVW_INLINE void FsReq::chown(const std::string &path, Uid uid, Gid gid) {
cleanupAndInvoke(&uv_fs_chown, parent(), get(), path.data(), uid, gid, &fsGenericCallback<Type::CHOWN>);
}
UVW_INLINE bool FsReq::chownSync(const std::string &path, Uid uid, Gid gid) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_chown, parent(), req, path.data(), uid, gid);
return !(req->result < 0);
}
UVW_INLINE void FsReq::lchown(const std::string &path, Uid uid, Gid gid) {
cleanupAndInvoke(&uv_fs_lchown, parent(), get(), path.data(), uid, gid, &fsGenericCallback<Type::LCHOWN>);
}
UVW_INLINE bool FsReq::lchownSync(const std::string &path, Uid uid, Gid gid) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_lchown, parent(), req, path.data(), uid, gid);
return !(req->result < 0);
}
UVW_INLINE void FsReq::opendir(const std::string &path) {
cleanupAndInvoke(&uv_fs_opendir, parent(), get(), path.data(), &fsGenericCallback<Type::OPENDIR>);
}
UVW_INLINE bool FsReq::opendirSync(const std::string &path) {
auto req = get();
cleanupAndInvokeSync(&uv_fs_opendir, parent(), req, path.data());
return !(req->result < 0);
}
UVW_INLINE void FsReq::closedir() {
auto req = get();
auto *dir = static_cast<uv_dir_t *>(req->ptr);
cleanupAndInvoke(&uv_fs_closedir, parent(), req, dir, &fsGenericCallback<Type::CLOSEDIR>);
}
UVW_INLINE bool FsReq::closedirSync() {
auto req = get();
auto *dir = static_cast<uv_dir_t *>(req->ptr);
@ -561,7 +480,6 @@ UVW_INLINE bool FsReq::closedirSync() {
return !(req->result < 0);
}
UVW_INLINE void FsReq::readdir() {
auto req = get();
auto *dir = static_cast<uv_dir_t *>(req->ptr);
@ -570,25 +488,21 @@ UVW_INLINE void FsReq::readdir() {
cleanupAndInvoke(&uv_fs_readdir, parent(), req, dir, &fsReaddirCallback);
}
UVW_INLINE std::pair<bool, std::pair<FsReq::EntryType, const char *>> FsReq::readdirSync() {
auto req = get();
auto *dir = static_cast<uv_dir_t *>(req->ptr);
dir->dirents = dirents;
dir->nentries = 1;
cleanupAndInvokeSync(&uv_fs_readdir, parent(), req, dir);
return {req->result != 0, { static_cast<EntryType>(dirents[0].type), dirents[0].name }};
return {req->result != 0, {static_cast<EntryType>(dirents[0].type), dirents[0].name}};
}
UVW_INLINE OSFileDescriptor FsHelper::handle(FileHandle file) noexcept {
return uv_get_osfhandle(file);
}
UVW_INLINE FileHandle FsHelper::open(OSFileDescriptor descriptor) noexcept {
return uv_open_osfhandle(descriptor);
}
}
} // namespace uvw

View File

@ -1,24 +1,20 @@
#ifndef UVW_FS_INCLUDE_H
#define UVW_FS_INCLUDE_H
#include <utility>
#include <chrono>
#include <memory>
#include <string>
#include <chrono>
#include <utility>
#include <uv.h>
#include "loop.h"
#include "request.hpp"
#include "util.h"
#include "loop.h"
namespace uvw {
namespace details {
enum class UVFsType: std::underlying_type_t<uv_fs_type> {
enum class UVFsType : std::underlying_type_t<uv_fs_type> {
UNKNOWN = UV_FS_UNKNOWN,
CUSTOM = UV_FS_CUSTOM,
OPEN = UV_FS_OPEN,
@ -59,8 +55,7 @@ enum class UVFsType: std::underlying_type_t<uv_fs_type> {
LUTIME = UV_FS_LUTIME
};
enum class UVDirentTypeT: std::underlying_type_t<uv_dirent_type_t> {
enum class UVDirentTypeT : std::underlying_type_t<uv_dirent_type_t> {
UNKNOWN = UV_DIRENT_UNKNOWN,
FILE = UV_DIRENT_FILE,
DIR = UV_DIRENT_DIR,
@ -71,8 +66,7 @@ enum class UVDirentTypeT: std::underlying_type_t<uv_dirent_type_t> {
BLOCK = UV_DIRENT_BLOCK
};
enum class UVFileOpenFlags: int {
enum class UVFileOpenFlags : int {
APPEND = UV_FS_O_APPEND,
CREAT = UV_FS_O_CREAT,
DIRECT = UV_FS_O_DIRECT,
@ -97,22 +91,18 @@ enum class UVFileOpenFlags: int {
WRONLY = UV_FS_O_WRONLY
};
enum class UVCopyFileFlags: int {
enum class UVCopyFileFlags : int {
EXCL = UV_FS_COPYFILE_EXCL,
FICLONE = UV_FS_COPYFILE_FICLONE,
FICLONE_FORCE = UV_FS_COPYFILE_FICLONE_FORCE
};
enum class UVSymLinkFlags: int {
enum class UVSymLinkFlags : int {
DIR = UV_FS_SYMLINK_DIR,
JUNCTION = UV_FS_SYMLINK_JUNCTION
};
}
} // namespace details
/**
* @brief Default FsEvent event.
@ -167,12 +157,12 @@ enum class UVSymLinkFlags: int {
*/
template<details::UVFsType e>
struct FsEvent {
FsEvent(const char *pathname) noexcept: path{pathname} {}
FsEvent(const char *pathname) noexcept
: path{pathname} {}
const char * path; /*!< The path affecting the request. */
const char *path; /*!< The path affecting the request. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::READ`.
*
@ -182,15 +172,13 @@ struct FsEvent {
template<>
struct FsEvent<details::UVFsType::READ> {
FsEvent(const char *pathname, std::unique_ptr<const char[]> buf, std::size_t sz) noexcept
: path{pathname}, data{std::move(buf)}, size{sz}
{}
: path{pathname}, data{std::move(buf)}, size{sz} {}
const char * path; /*!< The path affecting the request. */
const char *path; /*!< The path affecting the request. */
std::unique_ptr<const char[]> data; /*!< A bunch of data read from the given path. */
std::size_t size; /*!< The amount of data read from the given path. */
std::size_t size; /*!< The amount of data read from the given path. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::WRITE`.
*
@ -200,14 +188,12 @@ struct FsEvent<details::UVFsType::READ> {
template<>
struct FsEvent<details::UVFsType::WRITE> {
FsEvent(const char *pathname, std::size_t sz) noexcept
: path{pathname}, size{sz}
{}
: path{pathname}, size{sz} {}
const char * path; /*!< The path affecting the request. */
const char *path; /*!< The path affecting the request. */
std::size_t size; /*!< The amount of data written to the given path. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::SENDFILE`.
*
@ -217,14 +203,12 @@ struct FsEvent<details::UVFsType::WRITE> {
template<>
struct FsEvent<details::UVFsType::SENDFILE> {
FsEvent(const char *pathname, std::size_t sz) noexcept
: path{pathname}, size{sz}
{}
: path{pathname}, size{sz} {}
const char * path; /*!< The path affecting the request. */
const char *path; /*!< The path affecting the request. */
std::size_t size; /*!< The amount of data transferred. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::STAT`.
*
@ -234,14 +218,12 @@ struct FsEvent<details::UVFsType::SENDFILE> {
template<>
struct FsEvent<details::UVFsType::STAT> {
FsEvent(const char *pathname, Stat curr) noexcept
: path{pathname}, stat{std::move(curr)}
{}
: path{pathname}, stat{std::move(curr)} {}
const char * path; /*!< The path affecting the request. */
Stat stat; /*!< An initialized instance of Stat. */
const char *path; /*!< The path affecting the request. */
Stat stat; /*!< An initialized instance of Stat. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::FSTAT`.
*
@ -251,14 +233,12 @@ struct FsEvent<details::UVFsType::STAT> {
template<>
struct FsEvent<details::UVFsType::FSTAT> {
FsEvent(const char *pathname, Stat curr) noexcept
: path{pathname}, stat{std::move(curr)}
{}
: path{pathname}, stat{std::move(curr)} {}
const char * path; /*!< The path affecting the request. */
Stat stat; /*!< An initialized instance of Stat. */
const char *path; /*!< The path affecting the request. */
Stat stat; /*!< An initialized instance of Stat. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::LSTAT`.
*
@ -268,14 +248,12 @@ struct FsEvent<details::UVFsType::FSTAT> {
template<>
struct FsEvent<details::UVFsType::LSTAT> {
FsEvent(const char *pathname, Stat curr) noexcept
: path{pathname}, stat{std::move(curr)}
{}
: path{pathname}, stat{std::move(curr)} {}
const char * path; /*!< The path affecting the request. */
Stat stat; /*!< An initialized instance of Stat. */
const char *path; /*!< The path affecting the request. */
Stat stat; /*!< An initialized instance of Stat. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::STATFS`.
*
@ -285,14 +263,12 @@ struct FsEvent<details::UVFsType::LSTAT> {
template<>
struct FsEvent<details::UVFsType::STATFS> {
FsEvent(const char *pathname, Statfs curr) noexcept
: path{pathname}, statfs{std::move(curr)}
{}
: path{pathname}, statfs{std::move(curr)} {}
const char * path; /*!< The path affecting the request. */
Statfs statfs; /*!< An initialized instance of Statfs. */
const char *path; /*!< The path affecting the request. */
Statfs statfs; /*!< An initialized instance of Statfs. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::MKSTEMP`.
*
@ -302,14 +278,12 @@ struct FsEvent<details::UVFsType::STATFS> {
template<>
struct FsEvent<details::UVFsType::MKSTEMP> {
FsEvent(const char *pathname, std::size_t desc) noexcept
: path{pathname}, descriptor{desc}
{}
: path{pathname}, descriptor{desc} {}
const char * path; /*!< The created file path. */
const char *path; /*!< The created file path. */
std::size_t descriptor; /*!< The file descriptor as an integer. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::SCANDIR`.
*
@ -319,14 +293,12 @@ struct FsEvent<details::UVFsType::MKSTEMP> {
template<>
struct FsEvent<details::UVFsType::SCANDIR> {
FsEvent(const char *pathname, std::size_t sz) noexcept
: path{pathname}, size{sz}
{}
: path{pathname}, size{sz} {}
const char * path; /*!< The path affecting the request. */
const char *path; /*!< The path affecting the request. */
std::size_t size; /*!< The number of directory entries selected. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::READLINK`.
*
@ -336,15 +308,13 @@ struct FsEvent<details::UVFsType::SCANDIR> {
template<>
struct FsEvent<details::UVFsType::READLINK> {
explicit FsEvent(const char *pathname, const char *buf, std::size_t sz) noexcept
: path{pathname}, data{buf}, size{sz}
{}
: path{pathname}, data{buf}, size{sz} {}
const char * path; /*!< The path affecting the request. */
const char * data; /*!< A bunch of data read from the given path. */
const char *path; /*!< The path affecting the request. */
const char *data; /*!< A bunch of data read from the given path. */
std::size_t size; /*!< The amount of data read from the given path. */
};
/**
* @brief FsEvent event specialization for `FsRequest::Type::READDIR`.
*
@ -356,15 +326,13 @@ struct FsEvent<details::UVFsType::READDIR> {
using EntryType = details::UVDirentTypeT;
FsEvent(const char *name, EntryType type, bool eos) noexcept
: name{name}, type{type}, eos{eos}
{}
: name{name}, type{type}, eos{eos} {}
const char * name; /*!< The name of the last entry. */
EntryType type; /*!< The entry type. */
bool eos; /*!< True if there a no more entries to read. */
const char *name; /*!< The name of the last entry. */
EntryType type; /*!< The entry type. */
bool eos; /*!< True if there a no more entries to read. */
};
/**
* @brief Base class for FsReq and/or FileReq.
*
@ -375,39 +343,47 @@ class FsRequest: public Request<T, uv_fs_t> {
protected:
template<details::UVFsType e>
static void fsGenericCallback(uv_fs_t *req) {
auto ptr = Request<T, uv_fs_t>::reserve(req);
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
else { ptr->publish(FsEvent<e>{req->path}); }
if(auto ptr = Request<T, uv_fs_t>::reserve(req); req->result < 0) {
ptr->publish(ErrorEvent{req->result});
} else {
ptr->publish(FsEvent<e>{req->path});
}
}
template<details::UVFsType e>
static void fsResultCallback(uv_fs_t *req) {
auto ptr = Request<T, uv_fs_t>::reserve(req);
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
else { ptr->publish(FsEvent<e>{req->path, static_cast<std::size_t>(req->result)}); }
if(auto ptr = Request<T, uv_fs_t>::reserve(req); req->result < 0) {
ptr->publish(ErrorEvent{req->result});
} else {
ptr->publish(FsEvent<e>{req->path, static_cast<std::size_t>(req->result)});
}
}
template<details::UVFsType e>
static void fsStatCallback(uv_fs_t *req) {
auto ptr = Request<T, uv_fs_t>::reserve(req);
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
else { ptr->publish(FsEvent<e>{req->path, req->statbuf}); }
if(auto ptr = Request<T, uv_fs_t>::reserve(req); req->result < 0) {
ptr->publish(ErrorEvent{req->result});
} else {
ptr->publish(FsEvent<e>{req->path, req->statbuf});
}
}
static void fsStatfsCallback(uv_fs_t *req) {
auto ptr = Request<T, uv_fs_t>::reserve(req);
if(req->result < 0) { ptr->publish(ErrorEvent{req->result}); }
else { ptr->publish(FsEvent<Type::STATFS>{req->path, *static_cast<Statfs *>(req->ptr)}); }
if(auto ptr = Request<T, uv_fs_t>::reserve(req); req->result < 0) {
ptr->publish(ErrorEvent{req->result});
} else {
ptr->publish(FsEvent<Type::STATFS>{req->path, *static_cast<Statfs *>(req->ptr)});
}
}
template<typename... Args>
void cleanupAndInvoke(Args&&... args) {
void cleanupAndInvoke(Args &&...args) {
uv_fs_req_cleanup(this->get());
this->invoke(std::forward<Args>(args)...);
}
template<typename F, typename... Args>
void cleanupAndInvokeSync(F &&f, Args&&... args) {
void cleanupAndInvokeSync(F &&f, Args &&...args) {
uv_fs_req_cleanup(this->get());
std::forward<F>(f)(std::forward<Args>(args)..., nullptr);
}
@ -420,7 +396,6 @@ public:
using Request<T, uv_fs_t>::Request;
};
/**
* @brief The FileReq request.
*
@ -771,7 +746,6 @@ private:
uv_file file{BAD_FD};
};
/**
* @brief The FsReq request.
*
@ -1423,7 +1397,6 @@ private:
uv_dirent_t dirents[1];
};
/*! @brief Helper functions. */
struct FsHelper {
/**
@ -1451,13 +1424,10 @@ struct FsHelper {
static FileHandle open(OSFileDescriptor descriptor) noexcept;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "fs.cpp"
# include "fs.cpp"
#endif
#endif // UVW_FS_INCLUDE_H

View File

@ -1,18 +1,14 @@
#ifdef UVW_AS_LIB
#include "fs_event.h"
# include "fs_event.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE FsEventEvent::FsEventEvent(const char * pathname, Flags<details::UVFsEvent> events)
: filename{pathname}, flags{std::move(events)}
{}
UVW_INLINE FsEventEvent::FsEventEvent(const char *pathname, Flags<details::UVFsEvent> events)
: filename{pathname}, flags{std::move(events)} {}
UVW_INLINE void FsEventHandle::startCallback(uv_fs_event_t *handle, const char *filename, int events, int status) {
FsEventHandle &fsEvent = *(static_cast<FsEventHandle *>(handle->data));
@ -24,30 +20,24 @@ UVW_INLINE void FsEventHandle::startCallback(uv_fs_event_t *handle, const char *
}
}
UVW_INLINE bool FsEventHandle::init() {
return initialize(&uv_fs_event_init);
}
UVW_INLINE void FsEventHandle::start(const std::string &path, Flags<Event> flags) {
invoke(&uv_fs_event_start, get(), &startCallback, path.data(), flags);
}
UVW_INLINE void FsEventHandle::start(const std::string &path, FsEventHandle::Event flag) {
start(std::move(path), Flags<Event>{flag});
}
UVW_INLINE void FsEventHandle::stop() {
invoke(&uv_fs_event_stop, get());
}
UVW_INLINE std::string FsEventHandle::path() noexcept {
return details::tryRead(&uv_fs_event_getpath, get());
}
}
} // namespace uvw

View File

@ -1,36 +1,29 @@
#ifndef UVW_FS_EVENT_INCLUDE_H
#define UVW_FS_EVENT_INCLUDE_H
#include <type_traits>
#include <string>
#include <type_traits>
#include <uv.h>
#include "handle.hpp"
#include "util.h"
#include "loop.h"
#include "util.h"
namespace uvw {
namespace details {
enum class UVFsEventFlags: std::underlying_type_t<uv_fs_event_flags> {
enum class UVFsEventFlags : std::underlying_type_t<uv_fs_event_flags> {
WATCH_ENTRY = UV_FS_EVENT_WATCH_ENTRY,
STAT = UV_FS_EVENT_STAT,
RECURSIVE = UV_FS_EVENT_RECURSIVE
};
enum class UVFsEvent: std::underlying_type_t<uv_fs_event> {
enum class UVFsEvent : std::underlying_type_t<uv_fs_event> {
RENAME = UV_RENAME,
CHANGE = UV_CHANGE
};
}
} // namespace details
/**
* @brief FsEventEvent event.
@ -38,7 +31,7 @@ enum class UVFsEvent: std::underlying_type_t<uv_fs_event> {
* It will be emitted by FsEventHandle according with its functionalities.
*/
struct FsEventEvent {
FsEventEvent(const char * pathname, Flags<details::UVFsEvent> events);
FsEventEvent(const char *pathname, Flags<details::UVFsEvent> events);
/**
* @brief The path to the file being monitored.
@ -46,7 +39,7 @@ struct FsEventEvent {
* If the handle was started with a directory, the filename parameter will
* be a relative path to a file contained in the directory.
*/
const char * filename;
const char *filename;
/**
* @brief Detected events all in one.
@ -59,7 +52,6 @@ struct FsEventEvent {
Flags<details::UVFsEvent> flags;
};
/**
* @brief The FsEventHandle handle.
*
@ -138,13 +130,10 @@ public:
std::string path() noexcept;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "fs_event.cpp"
# include "fs_event.cpp"
#endif
#endif // UVW_FS_EVENT_INCLUDE_H

View File

@ -1,19 +1,15 @@
#ifdef UVW_AS_LIB
#include "fs_poll.h"
# include "fs_poll.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE FsPollEvent::FsPollEvent(Stat previous, Stat current) noexcept
: prev{std::move(previous)}, curr{std::move(current)}
{}
: prev{std::move(previous)}, curr{std::move(current)} {}
UVW_INLINE void FsPollHandle::startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr) {
FsPollHandle &fsPoll = *(static_cast<FsPollHandle *>(handle->data));
@ -25,25 +21,20 @@ UVW_INLINE void FsPollHandle::startCallback(uv_fs_poll_t *handle, int status, co
}
}
UVW_INLINE bool FsPollHandle::init() {
return initialize(&uv_fs_poll_init);
}
UVW_INLINE void FsPollHandle::start(const std::string &file, FsPollHandle::Time interval) {
invoke(&uv_fs_poll_start, get(), &startCallback, file.data(), interval.count());
}
UVW_INLINE void FsPollHandle::stop() {
invoke(&uv_fs_poll_stop, get());
}
UVW_INLINE std::string FsPollHandle::path() noexcept {
return details::tryRead(&uv_fs_poll_getpath, get());
}
}
} // namespace uvw

View File

@ -1,18 +1,15 @@
#ifndef UVW_FS_POLL_INCLUDE_H
#define UVW_FS_POLL_INCLUDE_H
#include <string>
#include <chrono>
#include <string>
#include <uv.h>
#include "handle.hpp"
#include "util.h"
#include "loop.h"
#include "util.h"
namespace uvw {
/**
* @brief FsPollEvent event.
*
@ -25,7 +22,6 @@ struct FsPollEvent {
Stat curr; /*!< The new Stat struct. */
};
/**
* @brief The FsPollHandle handle.
*
@ -72,13 +68,10 @@ public:
std::string path() noexcept;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "fs_poll.cpp"
# include "fs_poll.cpp"
#endif
#endif // UVW_FS_POLL_INCLUDE_H

View File

@ -1,18 +1,15 @@
#ifndef UVW_HANDLE_INCLUDE_H
#define UVW_HANDLE_INCLUDE_H
#include <cstddef>
#include <utility>
#include <memory>
#include <utility>
#include <uv.h>
#include "resource.hpp"
#include "util.h"
namespace uvw {
/**
* @brief CloseEvent event.
*
@ -20,7 +17,6 @@ namespace uvw {
*/
struct CloseEvent {};
/**
* @brief Handle base class.
*
@ -29,249 +25,245 @@ struct CloseEvent {};
template<typename T, typename U>
class Handle: public Resource<T, U> {
protected:
static void closeCallback(uv_handle_t *handle) {
Handle<T, U> &ref = *(static_cast<T*>(handle->data));
auto ptr = ref.shared_from_this();
(void)ptr;
ref.reset();
ref.publish(CloseEvent{});
}
static void closeCallback(uv_handle_t *handle) {
Handle<T, U> &ref = *(static_cast<T *>(handle->data));
[[maybe_unused]] auto ptr = ref.shared_from_this();
ref.reset();
ref.publish(CloseEvent{});
}
static void allocCallback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf) {
auto size = static_cast<unsigned int>(suggested);
*buf = uv_buf_init(new char[size], size);
}
static void allocCallback(uv_handle_t *, std::size_t suggested, uv_buf_t *buf) {
auto size = static_cast<unsigned int>(suggested);
*buf = uv_buf_init(new char[size], size);
}
template<typename F, typename... Args>
bool initialize(F &&f, Args&&... args) {
if(!this->self()) {
auto err = std::forward<F>(f)(this->parent(), this->get(), std::forward<Args>(args)...);
template<typename F, typename... Args>
bool initialize(F &&f, Args &&...args) {
if(!this->self()) {
if(auto err = std::forward<F>(f)(this->parent(), this->get(), std::forward<Args>(args)...); err) {
this->publish(ErrorEvent{err});
} else {
this->leak();
}
}
if(err) {
this->publish(ErrorEvent{err});
} else {
this->leak();
}
}
return this->self();
}
return this->self();
}
template<typename F, typename... Args>
void invoke(F &&f, Args&&... args) {
auto err = std::forward<F>(f)(std::forward<Args>(args)...);
if(err) { Emitter<T>::publish(ErrorEvent{err}); }
}
template<typename F, typename... Args>
void invoke(F &&f, Args &&...args) {
auto err = std::forward<F>(f)(std::forward<Args>(args)...);
if(err) { Emitter<T>::publish(ErrorEvent{err}); }
}
public:
using Resource<T, U>::Resource;
using Resource<T, U>::Resource;
/**
* @brief Gets the category of the handle.
*
* A base handle offers no functionality to promote it to the actual handle
* type. By means of this function, an opaque value that identifies the
* category of the handle is made available to the users.
*
* @return The actual category of the handle.
*/
HandleCategory category() const noexcept {
return HandleCategory{this->template get<uv_handle_t>()->type};
}
/**
* @brief Gets the category of the handle.
*
* A base handle offers no functionality to promote it to the actual handle
* type. By means of this function, an opaque value that identifies the
* category of the handle is made available to the users.
*
* @return The actual category of the handle.
*/
HandleCategory category() const noexcept {
return HandleCategory{this->template get<uv_handle_t>()->type};
}
/**
* @brief Gets the type of the handle.
*
* A base handle offers no functionality to promote it to the actual handle
* type. By means of this function, the type of the underlying handle as
* specified by HandleType is made available to the users.
*
* @return The actual type of the handle.
*/
HandleType type() const noexcept {
return Utilities::guessHandle(category());
}
/**
* @brief Gets the type of the handle.
*
* A base handle offers no functionality to promote it to the actual handle
* type. By means of this function, the type of the underlying handle as
* specified by HandleType is made available to the users.
*
* @return The actual type of the handle.
*/
HandleType type() const noexcept {
return Utilities::guessHandle(category());
}
/**
* @brief Checks if the handle is active.
*
* What _active_ means depends on the type of handle:
*
* * An AsyncHandle handle is always active and cannot be deactivated,
* except by closing it with uv_close().
* * A PipeHandle, TCPHandle, UDPHandle, etc. handle - basically any handle
* that deals with I/O - is active when it is doing something that involves
* I/O, like reading, writing, connecting, accepting new connections, etc.
* * A CheckHandle, IdleHandle, TimerHandle, etc. handle is active when it
* has been started with a call to `start()`.
*
* Rule of thumb: if a handle of type `FooHandle` has a `start()` member
* method, then its active from the moment that method is called. Likewise,
* `stop()` deactivates the handle again.
*
* @return True if the handle is active, false otherwise.
*/
bool active() const noexcept {
return !(uv_is_active(this->template get<uv_handle_t>()) == 0);
}
/**
* @brief Checks if the handle is active.
*
* What _active_ means depends on the type of handle:
*
* * An AsyncHandle handle is always active and cannot be deactivated,
* except by closing it with uv_close().
* * A PipeHandle, TCPHandle, UDPHandle, etc. handle - basically any handle
* that deals with I/O - is active when it is doing something that involves
* I/O, like reading, writing, connecting, accepting new connections, etc.
* * A CheckHandle, IdleHandle, TimerHandle, etc. handle is active when it
* has been started with a call to `start()`.
*
* Rule of thumb: if a handle of type `FooHandle` has a `start()` member
* method, then its active from the moment that method is called. Likewise,
* `stop()` deactivates the handle again.
*
* @return True if the handle is active, false otherwise.
*/
bool active() const noexcept {
return !(uv_is_active(this->template get<uv_handle_t>()) == 0);
}
/**
* @brief Checks if a handle is closing or closed.
*
* This function should only be used between the initialization of the
* handle and the arrival of the close callback.
*
* @return True if the handle is closing or closed, false otherwise.
*/
bool closing() const noexcept {
return !(uv_is_closing(this->template get<uv_handle_t>()) == 0);
}
/**
* @brief Checks if a handle is closing or closed.
*
* This function should only be used between the initialization of the
* handle and the arrival of the close callback.
*
* @return True if the handle is closing or closed, false otherwise.
*/
bool closing() const noexcept {
return !(uv_is_closing(this->template get<uv_handle_t>()) == 0);
}
/**
* @brief Request handle to be closed.
*
* This **must** be called on each handle before memory is released.<br/>
* In-progress requests are cancelled and this can result in an ErrorEvent
* emitted.
*
* The handle will emit a CloseEvent when finished.
*/
void close() noexcept {
if(!closing()) {
uv_close(this->template get<uv_handle_t>(), &Handle<T, U>::closeCallback);
}
}
/**
* @brief Request handle to be closed.
*
* This **must** be called on each handle before memory is released.<br/>
* In-progress requests are cancelled and this can result in an ErrorEvent
* emitted.
*
* The handle will emit a CloseEvent when finished.
*/
void close() noexcept {
if(!closing()) {
uv_close(this->template get<uv_handle_t>(), &Handle<T, U>::closeCallback);
}
}
/**
* @brief Reference the given handle.
*
* References are idempotent, that is, if a handle is already referenced
* calling this function again will have no effect.
*/
void reference() noexcept {
uv_ref(this->template get<uv_handle_t>());
}
/**
* @brief Reference the given handle.
*
* References are idempotent, that is, if a handle is already referenced
* calling this function again will have no effect.
*/
void reference() noexcept {
uv_ref(this->template get<uv_handle_t>());
}
/**
* @brief Unreference the given handle.
*
* References are idempotent, that is, if a handle is not referenced calling
* this function again will have no effect.
*/
void unreference() noexcept {
uv_unref(this->template get<uv_handle_t>());
}
/**
* @brief Unreference the given handle.
*
* References are idempotent, that is, if a handle is not referenced calling
* this function again will have no effect.
*/
void unreference() noexcept {
uv_unref(this->template get<uv_handle_t>());
}
/**
* @brief Checks if the given handle referenced.
* @return True if the handle referenced, false otherwise.
*/
bool referenced() const noexcept {
return !(uv_has_ref(this->template get<uv_handle_t>()) == 0);
}
/**
* @brief Checks if the given handle referenced.
* @return True if the handle referenced, false otherwise.
*/
bool referenced() const noexcept {
return !(uv_has_ref(this->template get<uv_handle_t>()) == 0);
}
/**
* @brief Returns the size of the underlying handle type.
* @return The size of the underlying handle type.
*/
std::size_t size() const noexcept {
return uv_handle_size(this->template get<uv_handle_t>()->type);
}
/**
* @brief Returns the size of the underlying handle type.
* @return The size of the underlying handle type.
*/
std::size_t size() const noexcept {
return uv_handle_size(this->template get<uv_handle_t>()->type);
}
/**
* @brief Gets the size of the send buffer used for the socket.
*
* Gets the size of the send buffer that the operating system uses for the
* socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will return double the size of the original set value.
*
* @return The size of the send buffer, 0 in case of errors.
*/
int sendBufferSize() {
int value = 0;
auto err = uv_send_buffer_size(this->template get<uv_handle_t>(), &value);
return err ? 0 : value;
}
/**
* @brief Gets the size of the send buffer used for the socket.
*
* Gets the size of the send buffer that the operating system uses for the
* socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will return double the size of the original set value.
*
* @return The size of the send buffer, 0 in case of errors.
*/
int sendBufferSize() {
int value = 0;
auto err = uv_send_buffer_size(this->template get<uv_handle_t>(), &value);
return err ? 0 : value;
}
/**
* @brief Sets the size of the send buffer used for the socket.
*
* Sets the size of the send buffer that the operating system uses for the
* socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will set double the size.
*
* @return True in case of success, false otherwise.
*/
bool sendBufferSize(int value) {
return (0 == uv_send_buffer_size(this->template get<uv_handle_t>(), &value));
}
/**
* @brief Sets the size of the send buffer used for the socket.
*
* Sets the size of the send buffer that the operating system uses for the
* socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will set double the size.
*
* @return True in case of success, false otherwise.
*/
bool sendBufferSize(int value) {
return (0 == uv_send_buffer_size(this->template get<uv_handle_t>(), &value));
}
/**
* @brief Gets the size of the receive buffer used for the socket.
*
* Gets the size of the receive buffer that the operating system uses for
* the socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will return double the size of the original set value.
*
* @return The size of the receive buffer, 0 in case of errors.
*/
int recvBufferSize() {
int value = 0;
auto err = uv_recv_buffer_size(this->template get<uv_handle_t>(), &value);
return err ? 0 : value;
}
/**
* @brief Gets the size of the receive buffer used for the socket.
*
* Gets the size of the receive buffer that the operating system uses for
* the socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will return double the size of the original set value.
*
* @return The size of the receive buffer, 0 in case of errors.
*/
int recvBufferSize() {
int value = 0;
auto err = uv_recv_buffer_size(this->template get<uv_handle_t>(), &value);
return err ? 0 : value;
}
/**
* @brief Sets the size of the receive buffer used for the socket.
*
* Sets the size of the receive buffer that the operating system uses for
* the socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will set double the size.
*
* @return True in case of success, false otherwise.
*/
bool recvBufferSize(int value) {
return (0 == uv_recv_buffer_size(this->template get<uv_handle_t>(), &value));
}
/**
* @brief Sets the size of the receive buffer used for the socket.
*
* Sets the size of the receive buffer that the operating system uses for
* the socket.<br/>
* This function works for TCPHandle, PipeHandle and UDPHandle handles on
* Unix and for TCPHandle and UDPHandle handles on Windows.<br/>
* Note that Linux will set double the size.
*
* @return True in case of success, false otherwise.
*/
bool recvBufferSize(int value) {
return (0 == uv_recv_buffer_size(this->template get<uv_handle_t>(), &value));
}
/**
* @brief Gets the platform dependent file descriptor equivalent.
*
* Supported handles:
*
* * TCPHandle
* * PipeHandle
* * TTYHandle
* * UDPHandle
* * PollHandle
*
* It will emit an ErrorEvent event if invoked on any other handle.<br/>
* If a handle doesnt have an attached file descriptor yet or the handle
* itself has been closed, an ErrorEvent event will be emitted.
*
* See the official
* [documentation](http://docs.libuv.org/en/v1.x/handle.html#c.uv_fileno)
* for further details.
*
* @return The file descriptor attached to the hande or a negative value in
* case of errors.
*/
OSFileDescriptor fd() const {
uv_os_fd_t fd;
uv_fileno(this->template get<uv_handle_t>(), &fd);
return fd;
}
/**
* @brief Gets the platform dependent file descriptor equivalent.
*
* Supported handles:
*
* * TCPHandle
* * PipeHandle
* * TTYHandle
* * UDPHandle
* * PollHandle
*
* It will emit an ErrorEvent event if invoked on any other handle.<br/>
* If a handle doesnt have an attached file descriptor yet or the handle
* itself has been closed, an ErrorEvent event will be emitted.
*
* See the official
* [documentation](http://docs.libuv.org/en/v1.x/handle.html#c.uv_fileno)
* for further details.
*
* @return The file descriptor attached to the hande or a negative value in
* case of errors.
*/
OSFileDescriptor fd() const {
uv_os_fd_t fd;
uv_fileno(this->template get<uv_handle_t>(), &fd);
return fd;
}
};
}
} // namespace uvw
#endif // UVW_HANDLE_INCLUDE_H

View File

@ -1,32 +1,26 @@
#ifdef UVW_AS_LIB
#include "idle.h"
# include "idle.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE void IdleHandle::startCallback(uv_idle_t *handle) {
IdleHandle &idle = *(static_cast<IdleHandle *>(handle->data));
idle.publish(IdleEvent{});
}
UVW_INLINE bool IdleHandle::init() {
return initialize(&uv_idle_init);
}
UVW_INLINE void IdleHandle::start() {
invoke(&uv_idle_start, get(), &startCallback);
}
UVW_INLINE void IdleHandle::stop() {
invoke(&uv_idle_stop, get());
}
}
} // namespace uvw

View File

@ -1,15 +1,12 @@
#ifndef UVW_IDLE_INCLUDE_H
#define UVW_IDLE_INCLUDE_H
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
namespace uvw {
/**
* @brief IdleEvent event.
*
@ -17,7 +14,6 @@ namespace uvw {
*/
struct IdleEvent {};
/**
* @brief The IdleHandle handle.
*
@ -60,12 +56,10 @@ public:
void stop();
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "idle.cpp"
# include "idle.cpp"
#endif
#endif // UVW_IDLE_INCLUDE_H

View File

@ -1,35 +1,28 @@
#ifdef UVW_AS_LIB
#include "lib.h"
# include "lib.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE SharedLib::SharedLib(UnderlyingType<SharedLib, uv_lib_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref, const std::string &filename) noexcept
: UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
opened = (0 == uv_dlopen(filename.data(), get()));
}
UVW_INLINE SharedLib::~SharedLib() noexcept {
uv_dlclose(get());
}
UVW_INLINE SharedLib::operator bool() const noexcept {
return opened;
}
UVW_INLINE const char *SharedLib::error() const noexcept {
return uv_dlerror(get());
}
}
} // namespace uvw

View File

@ -1,7 +1,6 @@
#ifndef UVW_LIB_INCLUDE_H
#define UVW_LIB_INCLUDE_H
#include <memory>
#include <string>
#include <type_traits>
@ -9,10 +8,8 @@
#include "loop.h"
#include "underlying_type.hpp"
namespace uvw {
/**
* @brief The SharedLib class.
*
@ -41,10 +38,10 @@ public:
* @return A valid function pointer in case of success, `nullptr` otherwise.
*/
template<typename F>
F * sym(const std::string &name) {
F *sym(const std::string &name) {
static_assert(std::is_function_v<F>);
F *func;
auto err = uv_dlsym(get(), name.data(), reinterpret_cast<void**>(&func));
auto err = uv_dlsym(get(), name.data(), reinterpret_cast<void **>(&func));
if(err) { func = nullptr; }
return func;
}
@ -53,19 +50,16 @@ public:
* @brief Returns the last error message, if any.
* @return The last error message, if any.
*/
const char * error() const noexcept;
const char *error() const noexcept;
private:
bool opened;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "lib.cpp"
# include "lib.cpp"
#endif
#endif // UVW_LIB_INCLUDE_H

View File

@ -1,22 +1,18 @@
#ifdef UVW_AS_LIB
#include "loop.h"
# include "loop.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE Loop::Loop(std::unique_ptr<uv_loop_t, Deleter> ptr) noexcept
: loop{std::move(ptr)}
{}
: loop{std::move(ptr)} {}
UVW_INLINE std::shared_ptr<Loop> Loop::create() {
auto ptr = std::unique_ptr<uv_loop_t, Deleter>{new uv_loop_t, [](uv_loop_t *l) {
delete l;
}};
delete l;
}};
auto loop = std::shared_ptr<Loop>{new Loop{std::move(ptr)}};
@ -27,13 +23,11 @@ UVW_INLINE std::shared_ptr<Loop> Loop::create() {
return loop;
}
UVW_INLINE std::shared_ptr<Loop> Loop::create(uv_loop_t *loop) {
auto ptr = std::unique_ptr<uv_loop_t, Deleter>{loop, [](uv_loop_t *) {}};
return std::shared_ptr<Loop>{new Loop{std::move(ptr)}};
}
UVW_INLINE std::shared_ptr<Loop> Loop::getDefault() {
static std::weak_ptr<Loop> ref;
std::shared_ptr<Loop> loop;
@ -54,20 +48,17 @@ UVW_INLINE std::shared_ptr<Loop> Loop::getDefault() {
return loop;
}
UVW_INLINE Loop::~Loop() noexcept {
if(loop) {
close();
}
}
UVW_INLINE void Loop::close() {
auto err = uv_loop_close(loop.get());
return err ? publish(ErrorEvent{err}) : loop.reset();
}
template<Loop::Mode mode>
bool Loop::run() noexcept {
auto utm = static_cast<std::underlying_type_t<Mode>>(mode);
@ -75,43 +66,35 @@ bool Loop::run() noexcept {
return (uv_run(loop.get(), uvrm) == 0);
}
UVW_INLINE bool Loop::alive() const noexcept {
return !(uv_loop_alive(loop.get()) == 0);
}
UVW_INLINE void Loop::stop() noexcept {
uv_stop(loop.get());
}
UVW_INLINE int Loop::descriptor() const noexcept {
return uv_backend_fd(loop.get());
}
UVW_INLINE std::pair<bool, Loop::Time> Loop::timeout() const noexcept {
auto to = uv_backend_timeout(loop.get());
return std::make_pair(to == -1, Time{to});
}
UVW_INLINE Loop::Time Loop::idleTime() const noexcept {
return Time{uv_metrics_idle_time(loop.get())};
}
UVW_INLINE Loop::Time Loop::now() const noexcept {
return Time{uv_now(loop.get())};
}
UVW_INLINE void Loop::update() const noexcept {
return uv_update_time(loop.get());
}
UVW_INLINE void Loop::fork() noexcept {
auto err = uv_loop_fork(loop.get());
@ -120,22 +103,18 @@ UVW_INLINE void Loop::fork() noexcept {
}
}
UVW_INLINE void Loop::data(std::shared_ptr<void> uData) {
userData = std::move(uData);
}
UVW_INLINE const uv_loop_t *Loop::raw() const noexcept {
return loop.get();
}
UVW_INLINE uv_loop_t *Loop::raw() noexcept {
return const_cast<uv_loop_t *>(const_cast<const Loop *>(this)->raw());
}
// explicit instantiations
#ifdef UVW_AS_LIB
template bool Loop::run<Loop::Mode::DEFAULT>() noexcept;
@ -143,4 +122,4 @@ template bool Loop::run<Loop::Mode::ONCE>() noexcept;
template bool Loop::run<Loop::Mode::NOWAIT>() noexcept;
#endif // UVW_AS_LIB
}
} // namespace uvw

View File

@ -1,24 +1,21 @@
#ifndef UVW_LOOP_INCLUDE_H
#define UVW_LOOP_INCLUDE_H
#ifdef _WIN32
#include <ciso646>
# include <ciso646>
#endif
#include <chrono>
#include <functional>
#include <memory>
#include <utility>
#include <type_traits>
#include <chrono>
#include <utility>
#include <uv.h>
#include "emitter.h"
#include "util.h"
namespace uvw {
class AsyncHandle;
class CheckHandle;
class FsEventHandle;
@ -34,25 +31,20 @@ class TimerHandle;
class TTYHandle;
class UDPHandle;
namespace details {
enum class UVLoopOption: std::underlying_type_t<uv_loop_option> {
enum class UVLoopOption : std::underlying_type_t<uv_loop_option> {
BLOCK_SIGNAL = UV_LOOP_BLOCK_SIGNAL,
IDLE_TIME = UV_METRICS_IDLE_TIME
};
enum class UVRunMode: std::underlying_type_t<uv_run_mode> {
enum class UVRunMode : std::underlying_type_t<uv_run_mode> {
DEFAULT = UV_RUN_DEFAULT,
ONCE = UV_RUN_ONCE,
NOWAIT = UV_RUN_NOWAIT
};
}
} // namespace details
/**
* @brief The Loop class.
@ -63,20 +55,20 @@ enum class UVRunMode: std::underlying_type_t<uv_run_mode> {
* different sources of events.
*/
class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> {
using Deleter = void(*)(uv_loop_t *);
using Deleter = void (*)(uv_loop_t *);
template<typename, typename>
friend class Resource;
template<typename R, typename... Args>
auto create_resource(int, Args&&... args) -> decltype(std::declval<R>().init(), std::shared_ptr<R>{}) {
auto create_resource(int, Args &&...args) -> decltype(std::declval<R>().init(), std::shared_ptr<R>{}) {
auto ptr = R::create(shared_from_this(), std::forward<Args>(args)...);
ptr = ptr->init() ? ptr : nullptr;
return ptr;
}
template<typename R, typename... Args>
std::shared_ptr<R> create_resource(char, Args&&... args) {
std::shared_ptr<R> create_resource(char, Args &&...args) {
return R::create(shared_from_this(), std::forward<Args>(args)...);
}
@ -121,8 +113,9 @@ public:
Loop(const Loop &) = delete;
Loop(Loop &&other) = delete;
Loop & operator=(const Loop &) = delete;
Loop & operator=(Loop &&other) = delete;
Loop &operator=(const Loop &) = delete;
Loop &operator=(Loop &&other) = delete;
~Loop() noexcept;
@ -146,7 +139,7 @@ public:
* for further details.
*/
template<typename... Args>
void configure(Configure flag, Args&&... args) {
void configure(Configure flag, Args &&...args) {
auto option = static_cast<std::underlying_type_t<Configure>>(flag);
auto err = uv_loop_configure(loop.get(), static_cast<uv_loop_option>(option), std::forward<Args>(args)...);
if(err) { publish(ErrorEvent{err}); }
@ -163,7 +156,7 @@ public:
* @return A pointer to the newly created resource.
*/
template<typename R, typename... Args>
std::shared_ptr<R> resource(Args&&... args) {
std::shared_ptr<R> resource(Args &&...args) {
return create_resource<R>(0, std::forward<Args>(args)...);
}
@ -234,10 +227,10 @@ public:
std::pair<bool, Time> timeout() const noexcept;
/**
* @brief Returns the amount of time the event loop has been idle. The call
* is thread safe.
* @return The accumulated time spent idle.
*/
* @brief Returns the amount of time the event loop has been idle. The call
* is thread safe.
* @return The accumulated time spent idle.
*/
Time idleTime() const noexcept;
/**
@ -274,8 +267,7 @@ public:
*/
template<typename Func>
void walk(Func callback) {
// remember: non-capturing lambdas decay to pointers to functions
uv_walk(loop.get(), [](uv_handle_t *handle, void *func) {
auto func = [](uv_handle_t *handle, void *func) {
if(handle->data) {
auto &cb = *static_cast<Func *>(func);
@ -327,7 +319,9 @@ public:
break;
}
}
}, &callback);
};
uv_walk(loop.get(), func, &callback);
}
/**
@ -392,7 +386,7 @@ public:
*
* @return The underlying raw data structure.
*/
const uv_loop_t * raw() const noexcept;
const uv_loop_t *raw() const noexcept;
/**
* @brief Gets the underlying raw data structure.
@ -409,14 +403,13 @@ public:
*
* @return The underlying raw data structure.
*/
uv_loop_t * raw() noexcept;
uv_loop_t *raw() noexcept;
private:
std::unique_ptr<uv_loop_t, Deleter> loop;
std::shared_ptr<void> userData{nullptr};
};
// (extern) explicit instantiations
#ifdef UVW_AS_LIB
extern template bool Loop::run<Loop::Mode::DEFAULT>() noexcept;
@ -424,11 +417,10 @@ extern template bool Loop::run<Loop::Mode::ONCE>() noexcept;
extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept;
#endif // UVW_AS_LIB
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "loop.cpp"
# include "loop.cpp"
#endif
#endif // UVW_LOOP_INCLUDE_H

View File

@ -1,34 +1,27 @@
#ifdef UVW_AS_LIB
#include "pipe.h"
# include "pipe.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE PipeHandle::PipeHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, bool pass)
: StreamHandle{ca, std::move(ref)}, ipc{pass}
{}
: StreamHandle{ca, std::move(ref)}, ipc{pass} {}
UVW_INLINE bool PipeHandle::init() {
return initialize(&uv_pipe_init, ipc);
}
UVW_INLINE void PipeHandle::open(FileHandle file) {
invoke(&uv_pipe_open, get(), file);
}
UVW_INLINE void PipeHandle::bind(const std::string &name) {
invoke(&uv_pipe_bind, get(), name.data());
}
UVW_INLINE void PipeHandle::connect(const std::string &name) {
auto listener = [ptr = shared_from_this()](const auto &event, const auto &) {
ptr->publish(event);
@ -40,36 +33,29 @@ UVW_INLINE void PipeHandle::connect(const std::string &name) {
connect->connect(&uv_pipe_connect, get(), name.data());
}
UVW_INLINE std::string PipeHandle::sock() const noexcept {
return details::tryRead(&uv_pipe_getsockname, get());
}
UVW_INLINE std::string PipeHandle::peer() const noexcept {
return details::tryRead(&uv_pipe_getpeername, get());
}
UVW_INLINE void PipeHandle::pending(int count) noexcept {
uv_pipe_pending_instances(get(), count);
}
UVW_INLINE int PipeHandle::pending() noexcept {
return uv_pipe_pending_count(get());
}
UVW_INLINE HandleType PipeHandle::receive() noexcept {
HandleCategory category = uv_pipe_pending_type(get());
return Utilities::guessHandle(category);
}
UVW_INLINE bool PipeHandle::chmod(Flags<Chmod> flags) noexcept {
return (0 == uv_pipe_chmod(get(), flags));
}
}
} // namespace uvw

View File

@ -1,32 +1,26 @@
#ifndef UVW_PIPE_INCLUDE_H
#define UVW_PIPE_INCLUDE_H
#include <type_traits>
#include <memory>
#include <string>
#include <type_traits>
#include <uv.h>
#include "loop.h"
#include "request.hpp"
#include "stream.h"
#include "util.h"
#include "loop.h"
namespace uvw {
namespace details {
enum class UVChmodFlags: std::underlying_type_t<uv_poll_event> {
enum class UVChmodFlags : std::underlying_type_t<uv_poll_event> {
READABLE = UV_READABLE,
WRITABLE = UV_WRITABLE
};
}
/**
* @brief The PipeHandle handle.
*
@ -156,13 +150,10 @@ private:
bool ipc;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "pipe.cpp"
# include "pipe.cpp"
#endif
#endif // UVW_PIPE_INCLUDE_H

View File

@ -1,29 +1,21 @@
#ifdef UVW_AS_LIB
#include "poll.h"
# include "poll.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE PollEvent::PollEvent(Flags<details::UVPollEvent> events) noexcept
: flags{std::move(events)}
{}
: flags{std::move(events)} {}
UVW_INLINE PollHandle::PollHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, int desc)
: Handle{ca, std::move(ref)}, tag{FD}, file_desc{desc}
{}
: Handle{ca, std::move(ref)}, tag{FD}, file_desc{desc} {}
UVW_INLINE PollHandle::PollHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, OSSocketHandle sock)
: Handle{ca, std::move(ref)}, tag{SOCKET}, socket{sock}
{}
: Handle{ca, std::move(ref)}, tag{SOCKET}, socket{sock} {}
UVW_INLINE void PollHandle::startCallback(uv_poll_t *handle, int status, int events) {
PollHandle &poll = *(static_cast<PollHandle *>(handle->data));
@ -35,25 +27,20 @@ UVW_INLINE void PollHandle::startCallback(uv_poll_t *handle, int status, int eve
}
}
UVW_INLINE bool PollHandle::init() {
return (tag == SOCKET) ? initialize(&uv_poll_init_socket, socket) : initialize(&uv_poll_init, file_desc);
}
UVW_INLINE void PollHandle::start(Flags<PollHandle::Event> flags) {
invoke(&uv_poll_start, get(), flags, &startCallback);
}
UVW_INLINE void PollHandle::start(PollHandle::Event event) {
start(Flags<Event>{event});
}
UVW_INLINE void PollHandle::stop() {
invoke(&uv_poll_stop, get());
}
}
} // namespace uvw

View File

@ -1,31 +1,25 @@
#ifndef UVW_POLL_INCLUDE_H
#define UVW_POLL_INCLUDE_H
#include <type_traits>
#include <memory>
#include <type_traits>
#include <uv.h>
#include "handle.hpp"
#include "util.h"
namespace uvw {
namespace details {
enum class UVPollEvent: std::underlying_type_t<uv_poll_event> {
enum class UVPollEvent : std::underlying_type_t<uv_poll_event> {
READABLE = UV_READABLE,
WRITABLE = UV_WRITABLE,
DISCONNECT = UV_DISCONNECT,
PRIORITIZED = UV_PRIORITIZED
};
}
/**
* @brief PollEvent event.
*
@ -47,7 +41,6 @@ struct PollEvent {
Flags<details::UVPollEvent> flags;
};
/**
* @brief The PollHandle handle.
*
@ -127,19 +120,21 @@ public:
void stop();
private:
enum { FD, SOCKET } tag;
enum {
FD,
SOCKET
} tag;
union {
int file_desc;
OSSocketHandle::Type socket;
};
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "poll.cpp"
# include "poll.cpp"
#endif
#endif // UVW_POLL_INCLUDE_H

View File

@ -1,32 +1,26 @@
#ifdef UVW_AS_LIB
#include "prepare.h"
# include "prepare.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE void PrepareHandle::startCallback(uv_prepare_t *handle) {
PrepareHandle &prepare = *(static_cast<PrepareHandle *>(handle->data));
prepare.publish(PrepareEvent{});
}
UVW_INLINE bool PrepareHandle::init() {
return initialize(&uv_prepare_init);
}
UVW_INLINE void PrepareHandle::start() {
invoke(&uv_prepare_start, get(), &startCallback);
}
UVW_INLINE void PrepareHandle::stop() {
invoke(&uv_prepare_stop, get());
}
}
} // namespace uvw

View File

@ -1,15 +1,12 @@
#ifndef UVW_PREPARE_INCLUDE_H
#define UVW_PREPARE_INCLUDE_H
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
namespace uvw {
/**
* @brief PrepareEvent event.
*
@ -17,7 +14,6 @@ namespace uvw {
*/
struct PrepareEvent {};
/**
* @brief The PrepareHandle handle.
*
@ -54,12 +50,10 @@ public:
void stop();
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "prepare.cpp"
# include "prepare.cpp"
#endif
#endif // UVW_PREPARE_INCLUDE_H

View File

@ -1,47 +1,37 @@
#ifdef UVW_AS_LIB
#include "process.h"
# include "process.h"
#endif
#include <algorithm>
#include "config.h"
namespace uvw {
UVW_INLINE ExitEvent::ExitEvent(int64_t code, int sig) noexcept
: status{code}, signal{sig}
{}
: status{code}, signal{sig} {}
UVW_INLINE void ProcessHandle::exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal) {
ProcessHandle &process = *(static_cast<ProcessHandle *>(handle->data));
process.publish(ExitEvent{exitStatus, termSignal});
}
UVW_INLINE ProcessHandle::ProcessHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref)
: Handle{ca, std::move(ref)}
{}
: Handle{ca, std::move(ref)} {}
UVW_INLINE void ProcessHandle::disableStdIOInheritance() noexcept {
uv_disable_stdio_inheritance();
}
UVW_INLINE bool ProcessHandle::kill(int pid, int signum) noexcept {
return (0 == uv_kill(pid, signum));
}
UVW_INLINE bool ProcessHandle::init() {
// deferred initialization: libuv initializes process handles only when
// uv_spawn is invoked and uvw stays true to the underlying library
return true;
}
UVW_INLINE void ProcessHandle::spawn(const char *file, char **args, char **env) {
uv_process_options_t po;
@ -71,29 +61,24 @@ UVW_INLINE void ProcessHandle::spawn(const char *file, char **args, char **env)
invoke(&uv_spawn, parent(), get(), &po);
}
UVW_INLINE void ProcessHandle::kill(int signum) {
invoke(&uv_process_kill, get(), signum);
}
UVW_INLINE int ProcessHandle::pid() noexcept {
return get()->pid;
}
UVW_INLINE ProcessHandle &ProcessHandle::cwd(const std::string &path) noexcept {
poCwd = path;
return *this;
}
UVW_INLINE ProcessHandle &ProcessHandle::flags(Flags<Process> flags) noexcept {
poFlags = flags;
return *this;
}
UVW_INLINE ProcessHandle &ProcessHandle::stdio(FileHandle fd, Flags<StdIO> flags) {
auto fgs = static_cast<uv_stdio_flags>(Flags<StdIO>::Type{flags});
@ -116,17 +101,14 @@ UVW_INLINE ProcessHandle &ProcessHandle::stdio(FileHandle fd, Flags<StdIO> flags
return *this;
}
UVW_INLINE ProcessHandle &ProcessHandle::uid(Uid id) {
poUid = id;
return *this;
}
UVW_INLINE ProcessHandle &ProcessHandle::gid(Gid id) {
poGid = id;
return *this;
}
}
} // namespace uvw

View File

@ -1,25 +1,21 @@
#ifndef UVW_PROCESS_INCLUDE_H
#define UVW_PROCESS_INCLUDE_H
#include <utility>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
#include "stream.h"
#include "util.h"
#include "loop.h"
namespace uvw {
namespace details {
enum class UVProcessFlags: std::underlying_type_t<uv_process_flags> {
enum class UVProcessFlags : std::underlying_type_t<uv_process_flags> {
SETUID = UV_PROCESS_SETUID,
SETGID = UV_PROCESS_SETGID,
WINDOWS_VERBATIM_ARGUMENTS = UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
@ -29,8 +25,7 @@ enum class UVProcessFlags: std::underlying_type_t<uv_process_flags> {
WINDOWS_HIDE_GUI = UV_PROCESS_WINDOWS_HIDE_GUI
};
enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> {
enum class UVStdIOFlags : std::underlying_type_t<uv_stdio_flags> {
IGNORE_STREAM = UV_IGNORE,
CREATE_PIPE = UV_CREATE_PIPE,
INHERIT_FD = UV_INHERIT_FD,
@ -40,9 +35,7 @@ enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> {
OVERLAPPED_PIPE = UV_OVERLAPPED_PIPE
};
}
} // namespace details
/**
* @brief ExitEvent event.
@ -53,7 +46,7 @@ struct ExitEvent {
explicit ExitEvent(int64_t code, int sig) noexcept;
int64_t status; /*!< The exit status. */
int signal; /*!< The signal that caused the process to terminate, if any. */
int signal; /*!< The signal that caused the process to terminate, if any. */
};
/**
@ -137,7 +130,7 @@ public:
* @param path The working directory to be used when `spawn()` is invoked.
* @return A reference to this process handle.
*/
ProcessHandle & cwd(const std::string &path) noexcept;
ProcessHandle &cwd(const std::string &path) noexcept;
/**
* @brief Sets flags that control how `spawn()` behaves.
@ -159,7 +152,7 @@ public:
* @param flags A valid set of flags.
* @return A reference to this process handle.
*/
ProcessHandle & flags(Flags<Process> flags) noexcept;
ProcessHandle &flags(Flags<Process> flags) noexcept;
/**
* @brief Makes a `stdio` handle available to the child process.
@ -183,7 +176,7 @@ public:
* @return A reference to this process handle.
*/
template<typename T, typename U>
ProcessHandle & stdio(StreamHandle<T, U> &stream, Flags<StdIO> flags) {
ProcessHandle &stdio(StreamHandle<T, U> &stream, Flags<StdIO> flags) {
uv_stdio_container_t container;
Flags<StdIO>::Type fgs = flags;
container.flags = static_cast<uv_stdio_flags>(fgs);
@ -218,21 +211,21 @@ public:
* @param flags A valid set of flags.
* @return A reference to this process handle.
*/
ProcessHandle & stdio(FileHandle fd, Flags<StdIO> flags);
ProcessHandle &stdio(FileHandle fd, Flags<StdIO> flags);
/**
* @brief Sets the child process' user id.
* @param id A valid user id to be used.
* @return A reference to this process handle.
*/
ProcessHandle & uid(Uid id);
ProcessHandle &uid(Uid id);
/**
* @brief Sets the child process' group id.
* @param id A valid group id to be used.
* @return A reference to this process handle.
*/
ProcessHandle & gid(Gid id);
ProcessHandle &gid(Gid id);
private:
std::string poCwd;
@ -243,13 +236,10 @@ private:
Gid poGid;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "process.cpp"
# include "process.cpp"
#endif
#endif // UVW_PROCESS_INCLUDE_H

View File

@ -1,17 +1,14 @@
#ifndef UVW_REQUEST_INCLUDE_H
#define UVW_REQUEST_INCLUDE_H
#include <memory>
#include <type_traits>
#include <utility>
#include <memory>
#include <uv.h>
#include "resource.hpp"
namespace uvw {
/**
* @brief Request base class.
*
@ -21,27 +18,31 @@ template<typename T, typename U>
class Request: public Resource<T, U> {
protected:
static auto reserve(U *req) {
auto ptr = static_cast<T*>(req->data)->shared_from_this();
auto ptr = static_cast<T *>(req->data)->shared_from_this();
ptr->reset();
return ptr;
}
template<typename E>
static void defaultCallback(U *req, int status) {
auto ptr = reserve(req);
if(status) { ptr->publish(ErrorEvent{status}); }
else { ptr->publish(E{}); }
if(auto ptr = reserve(req); status) {
ptr->publish(ErrorEvent{status});
} else {
ptr->publish(E{});
}
}
template<typename F, typename... Args>
auto invoke(F &&f, Args&&... args) {
auto invoke(F &&f, Args &&...args) {
if constexpr(std::is_void_v<std::invoke_result_t<F, Args...>>) {
std::forward<F>(f)(std::forward<Args>(args)...);
this->leak();
} else {
auto err = std::forward<F>(f)(std::forward<Args>(args)...);
if(err) { Emitter<T>::publish(ErrorEvent{err}); }
else { this->leak(); }
if(auto err = std::forward<F>(f)(std::forward<Args>(args)...); err) {
Emitter<T>::publish(ErrorEvent{err});
} else {
this->leak();
}
}
}
@ -49,32 +50,31 @@ public:
using Resource<T, U>::Resource;
/**
* @brief Cancels a pending request.
*
* This method fails if the request is executing or has finished
* executing.<br/>
* It can emit an ErrorEvent event in case of errors.
*
* See the official
* [documentation](http://docs.libuv.org/en/v1.x/request.html#c.uv_cancel)
* for further details.
*
* @return True in case of success, false otherwise.
*/
* @brief Cancels a pending request.
*
* This method fails if the request is executing or has finished
* executing.<br/>
* It can emit an ErrorEvent event in case of errors.
*
* See the official
* [documentation](http://docs.libuv.org/en/v1.x/request.html#c.uv_cancel)
* for further details.
*
* @return True in case of success, false otherwise.
*/
bool cancel() {
return (0 == uv_cancel(this->template get<uv_req_t>()));
}
/**
* @brief Returns the size of the underlying request type.
* @return The size of the underlying request type.
*/
* @brief Returns the size of the underlying request type.
* @return The size of the underlying request type.
*/
std::size_t size() const noexcept {
return uv_req_size(this->template get<uv_req_t>()->type);
}
};
}
} // namespace uvw
#endif // UVW_REQUEST_INCLUDE_H

View File

@ -1,16 +1,13 @@
#ifndef UVW_RESOURCE_INCLUDE_H
#define UVW_RESOURCE_INCLUDE_H
#include <memory>
#include <utility>
#include "emitter.h"
#include "underlying_type.hpp"
namespace uvw {
/**
* @brief Common class for almost all the resources available in `uvw`.
*
@ -39,8 +36,7 @@ protected:
public:
explicit Resource(ConstructorAccess ca, std::shared_ptr<Loop> ref)
: UnderlyingType<T, U>{ca, std::move(ref)}
{
: UnderlyingType<T, U>{ca, std::move(ref)} {
this->get()->data = this;
}
@ -66,6 +62,6 @@ private:
std::shared_ptr<void> sPtr{nullptr};
};
}
} // namespace uvw
#endif // UVW_RESOURCE_INCLUDE_H

View File

@ -1,47 +1,37 @@
#ifdef UVW_AS_LIB
#include "signal.h"
# include "signal.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE SignalEvent::SignalEvent(int sig) noexcept
: signum{sig}
{}
: signum{sig} {}
UVW_INLINE void SignalHandle::startCallback(uv_signal_t *handle, int signum) {
SignalHandle &signal = *(static_cast<SignalHandle *>(handle->data));
signal.publish(SignalEvent{signum});
}
UVW_INLINE bool SignalHandle::init() {
return initialize(&uv_signal_init);
}
UVW_INLINE void SignalHandle::start(int signum) {
invoke(&uv_signal_start, get(), &startCallback, signum);
}
UVW_INLINE void SignalHandle::oneShot(int signum) {
invoke(&uv_signal_start_oneshot, get(), &startCallback, signum);
}
UVW_INLINE void SignalHandle::stop() {
invoke(&uv_signal_stop, get());
}
UVW_INLINE int SignalHandle::signal() const noexcept {
return get()->signum;
}
}
} // namespace uvw

View File

@ -1,15 +1,12 @@
#ifndef UVW_SIGNAL_INCLUDE_H
#define UVW_SIGNAL_INCLUDE_H
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
namespace uvw {
/**
* @brief SignalEvent event.
*
@ -21,7 +18,6 @@ struct SignalEvent {
int signum; /*!< The signal being monitored by this handle. */
};
/**
* @brief The SignalHandle handle.
*
@ -78,12 +74,10 @@ public:
int signal() const noexcept;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "signal.cpp"
# include "signal.cpp"
#endif
#endif // UVW_SIGNAL_INCLUDE_H

View File

@ -1,21 +1,16 @@
#ifdef UVW_AS_LIB
#include "stream.h"
# include "stream.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE DataEvent::DataEvent(std::unique_ptr<char[]> buf, std::size_t len) noexcept
: data{std::move(buf)}, length{len}
{}
: data{std::move(buf)}, length{len} {}
UVW_INLINE void details::ShutdownReq::shutdown(uv_stream_t *handle) {
invoke(&uv_shutdown, get(), handle, &defaultCallback<ShutdownEvent>);
}
}
} // namespace uvw

View File

@ -1,21 +1,18 @@
#ifndef UVW_STREAM_INCLUDE_H
#define UVW_STREAM_INCLUDE_H
#include <algorithm>
#include <iterator>
#include <cstddef>
#include <utility>
#include <iterator>
#include <memory>
#include <utility>
#include <uv.h>
#include "request.hpp"
#include "handle.hpp"
#include "loop.h"
#include "request.hpp"
namespace uvw {
/**
* @brief ConnectEvent event.
*
@ -23,7 +20,6 @@ namespace uvw {
*/
struct ConnectEvent {};
/**
* @brief EndEvent event.
*
@ -31,7 +27,6 @@ struct ConnectEvent {};
*/
struct EndEvent {};
/**
* @brief ListenEvent event.
*
@ -39,7 +34,6 @@ struct EndEvent {};
*/
struct ListenEvent {};
/**
* @brief ShutdownEvent event.
*
@ -47,7 +41,6 @@ struct ListenEvent {};
*/
struct ShutdownEvent {};
/**
* @brief WriteEvent event.
*
@ -55,7 +48,6 @@ struct ShutdownEvent {};
*/
struct WriteEvent {};
/**
* @brief DataEvent event.
*
@ -65,30 +57,26 @@ struct DataEvent {
explicit DataEvent(std::unique_ptr<char[]> buf, std::size_t len) noexcept;
std::unique_ptr<char[]> data; /*!< A bunch of data read on the stream. */
std::size_t length; /*!< The amount of data read on the stream. */
std::size_t length; /*!< The amount of data read on the stream. */
};
namespace details {
struct ConnectReq final: public Request<ConnectReq, uv_connect_t> {
using Request::Request;
template<typename F, typename... Args>
void connect(F &&f, Args&&... args) {
void connect(F &&f, Args &&...args) {
invoke(std::forward<F>(f), get(), std::forward<Args>(args)..., &defaultCallback<ConnectEvent>);
}
};
struct ShutdownReq final: public Request<ShutdownReq, uv_shutdown_t> {
using Request::Request;
void shutdown(uv_stream_t *handle);
};
template<typename Deleter>
class WriteReq final: public Request<WriteReq<Deleter>, uv_write_t> {
using ConstructorAccess = typename Request<WriteReq<Deleter>, uv_write_t>::ConstructorAccess;
@ -97,8 +85,7 @@ public:
WriteReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<char[], Deleter> dt, unsigned int len)
: Request<WriteReq<Deleter>, uv_write_t>{ca, std::move(loop)},
data{std::move(dt)},
buf{uv_buf_init(data.get(), len)}
{}
buf{uv_buf_init(data.get(), len)} {}
void write(uv_stream_t *handle) {
this->invoke(&uv_write, this->get(), handle, &buf, 1, &this->template defaultCallback<WriteEvent>);
@ -113,9 +100,7 @@ private:
uv_buf_t buf;
};
}
} // namespace details
/**
* @brief The StreamHandle handle.
@ -129,7 +114,7 @@ class StreamHandle: public Handle<T, U> {
static constexpr unsigned int DEFAULT_BACKLOG = 128;
static void readCallback(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
T &ref = *(static_cast<T*>(handle->data));
T &ref = *(static_cast<T *>(handle->data));
// data will be destroyed no matter of what the value of nread is
std::unique_ptr<char[]> data{buf->base};
@ -150,16 +135,17 @@ class StreamHandle: public Handle<T, U> {
}
static void listenCallback(uv_stream_t *handle, int status) {
T &ref = *(static_cast<T*>(handle->data));
if(status) { ref.publish(ErrorEvent{status}); }
else { ref.publish(ListenEvent{}); }
if(T &ref = *(static_cast<T *>(handle->data)); status) {
ref.publish(ErrorEvent{status});
} else {
ref.publish(ListenEvent{});
}
}
public:
#ifdef _MSC_VER
StreamHandle(typename Handle<T, U>::ConstructorAccess ca, std::shared_ptr<Loop> ref)
: Handle<T, U>{ca, std::move(ref)}
{}
: Handle<T, U>{ca, std::move(ref)} {}
#else
using Handle<T, U>::Handle;
#endif
@ -277,7 +263,7 @@ public:
* @param len The lenght of the submitted data.
*/
void write(char *data, unsigned int len) {
auto req = this->loop().template resource<details::WriteReq<void(*)(char *)>>(std::unique_ptr<char[], void(*)(char *)>{data, [](char *) {}}, len);
auto req = this->loop().template resource<details::WriteReq<void (*)(char *)>>(std::unique_ptr<char[], void (*)(char *)>{data, [](char *) {}}, len);
auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) {
ptr->publish(event);
};
@ -339,7 +325,7 @@ public:
*/
template<typename S>
void write(S &send, char *data, unsigned int len) {
auto req = this->loop().template resource<details::WriteReq<void(*)(char *)>>(std::unique_ptr<char[], void(*)(char *)>{data, [](char *) {}}, len);
auto req = this->loop().template resource<details::WriteReq<void (*)(char *)>>(std::unique_ptr<char[], void (*)(char *)>{data, [](char *) {}}, len);
auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) {
ptr->publish(event);
};
@ -361,7 +347,7 @@ public:
* @return Number of bytes written.
*/
int tryWrite(std::unique_ptr<char[]> data, unsigned int len) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
uv_buf_t bufs[] = {uv_buf_init(data.get(), len)};
auto bw = uv_try_write(this->template get<uv_stream_t>(), bufs, 1);
if(bw < 0) {
@ -377,7 +363,7 @@ public:
*
* Same as `tryWrite` for sending handles over a pipe.<br/>
* An ErrorEvent event will be emitted in case of errors.
*
*
* @param data The data to be written to the stream.
* @param len The lenght of the submitted data.
* @param send A valid handle suitable for the purpose.
@ -385,7 +371,7 @@ public:
*/
template<typename V, typename W>
int tryWrite(std::unique_ptr<char[]> data, unsigned int len, StreamHandle<V, W> &send) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
uv_buf_t bufs[] = {uv_buf_init(data.get(), len)};
auto bw = uv_try_write2(this->template get<uv_stream_t>(), bufs, 1, send.raw());
if(bw < 0) {
@ -408,7 +394,7 @@ public:
* @return Number of bytes written.
*/
int tryWrite(char *data, unsigned int len) {
uv_buf_t bufs[] = { uv_buf_init(data, len) };
uv_buf_t bufs[] = {uv_buf_init(data, len)};
auto bw = uv_try_write(this->template get<uv_stream_t>(), bufs, 1);
if(bw < 0) {
@ -432,7 +418,7 @@ public:
*/
template<typename V, typename W>
int tryWrite(char *data, unsigned int len, StreamHandle<V, W> &send) {
uv_buf_t bufs[] = { uv_buf_init(data, len) };
uv_buf_t bufs[] = {uv_buf_init(data, len)};
auto bw = uv_try_write2(this->template get<uv_stream_t>(), bufs, 1, send.raw());
if(bw < 0) {
@ -487,12 +473,10 @@ public:
}
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "stream.cpp"
# include "stream.cpp"
#endif
#endif // UVW_STREAM_INCLUDE_H

View File

@ -1,75 +1,60 @@
#ifdef UVW_AS_LIB
#include "tcp.h"
# include "tcp.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE TCPHandle::TCPHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int f)
: StreamHandle{ca, std::move(ref)}, tag{f ? FLAGS : DEFAULT}, flags{f}
{}
: StreamHandle{ca, std::move(ref)}, tag{f ? FLAGS : DEFAULT}, flags{f} {}
UVW_INLINE bool TCPHandle::init() {
return (tag == FLAGS) ? initialize(&uv_tcp_init_ex, flags) : initialize(&uv_tcp_init);
}
UVW_INLINE void TCPHandle::open(OSSocketHandle socket) {
invoke(&uv_tcp_open, get(), socket);
}
UVW_INLINE bool TCPHandle::noDelay(bool value) {
return (0 == uv_tcp_nodelay(get(), value));
}
UVW_INLINE bool TCPHandle::keepAlive(bool enable, TCPHandle::Time time) {
return (0 == uv_tcp_keepalive(get(), enable, time.count()));
}
UVW_INLINE bool TCPHandle::simultaneousAccepts(bool enable) {
return (0 == uv_tcp_simultaneous_accepts(get(), enable));
}
UVW_INLINE void TCPHandle::bind(const sockaddr &addr, Flags<Bind> opts) {
invoke(&uv_tcp_bind, get(), &addr, opts);
}
template<typename I>
UVW_INLINE void TCPHandle::bind(const std::string &ip, unsigned int port, Flags<Bind> opts)
{
UVW_INLINE void TCPHandle::bind(const std::string &ip, unsigned int port, Flags<Bind> opts) {
typename details::IpTraits<I>::Type addr;
details::IpTraits<I>::addrFunc(ip.data(), port, &addr);
bind(reinterpret_cast<const sockaddr &>(addr), std::move(opts));
}
template<typename I>
UVW_INLINE void TCPHandle::bind(Addr addr, Flags<Bind> opts) {
bind<I>(std::move(addr.ip), addr.port, std::move(opts));
}
template<typename I>
UVW_INLINE Addr TCPHandle::sock() const noexcept {
return details::address<I>(&uv_tcp_getsockname, get());
}
template<typename I>
UVW_INLINE Addr TCPHandle::peer() const noexcept {
return details::address<I>(&uv_tcp_getpeername, get());
}
template<typename I>
UVW_INLINE void TCPHandle::connect(const std::string &ip, unsigned int port) {
typename details::IpTraits<I>::Type addr;
@ -77,13 +62,11 @@ UVW_INLINE void TCPHandle::connect(const std::string &ip, unsigned int port) {
connect(reinterpret_cast<const sockaddr &>(addr));
}
template<typename I>
UVW_INLINE void TCPHandle::connect(Addr addr) {
connect<I>(std::move(addr.ip), addr.port);
}
UVW_INLINE void TCPHandle::connect(const sockaddr &addr) {
auto listener = [ptr = shared_from_this()](const auto &event, const auto &) {
ptr->publish(event);
@ -95,12 +78,10 @@ UVW_INLINE void TCPHandle::connect(const sockaddr &addr) {
req->connect(&uv_tcp_connect, get(), &addr);
}
UVW_INLINE void TCPHandle::closeReset() {
invoke(&uv_tcp_close_reset, get(), &this->closeCallback);
}
// explicit instantiations
#ifdef UVW_AS_LIB
template void TCPHandle::bind<IPv4>(const std::string &, unsigned int, Flags<Bind>);
@ -122,5 +103,4 @@ template void TCPHandle::connect<IPv4>(Addr addr);
template void TCPHandle::connect<IPv6>(Addr addr);
#endif // UVW_AS_LIB
}
} // namespace uvw

View File

@ -1,32 +1,26 @@
#ifndef UVW_TCP_INCLUDE_H
#define UVW_TCP_INCLUDE_H
#include <type_traits>
#include <utility>
#include <chrono>
#include <memory>
#include <string>
#include <chrono>
#include <type_traits>
#include <utility>
#include <uv.h>
#include "request.hpp"
#include "stream.h"
#include "util.h"
namespace uvw {
namespace details {
enum class UVTCPFlags: std::underlying_type_t<uv_tcp_flags> {
enum class UVTCPFlags : std::underlying_type_t<uv_tcp_flags> {
IPV6ONLY = UV_TCP_IPV6ONLY
};
}
/**
* @brief The TCPHandle handle.
*
@ -225,17 +219,19 @@ public:
void closeReset();
private:
enum { DEFAULT, FLAGS } tag;
enum {
DEFAULT,
FLAGS
} tag;
unsigned int flags;
};
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
// (extern) explicit instantiations
#ifdef UVW_AS_LIB
extern template void TCPHandle::bind<IPv4>(const std::string &, unsigned int, Flags<Bind>);
@ -257,19 +253,15 @@ extern template void TCPHandle::connect<IPv4>(Addr addr);
extern template void TCPHandle::connect<IPv6>(Addr addr);
#endif // UVW_AS_LIB
/**
* Internal details not to be documented.
* @endcond
*/
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "tcp.cpp"
# include "tcp.cpp"
#endif
#endif // UVW_TCP_INCLUDE_H

View File

@ -1,76 +1,60 @@
#ifdef UVW_AS_LIB
#include "thread.h"
# include "thread.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE Thread::Thread(ConstructorAccess ca, std::shared_ptr<Loop> ref, Task t, std::shared_ptr<void> d) noexcept
: UnderlyingType{ca, std::move(ref)}, data{std::move(d)}, task{std::move(t)}
{}
: UnderlyingType{ca, std::move(ref)}, data{std::move(d)}, task{std::move(t)} {}
UVW_INLINE void Thread::createCallback(void *arg) {
Thread &thread = *(static_cast<Thread *>(arg));
thread.task(thread.data);
}
UVW_INLINE Thread::Type Thread::self() noexcept {
return uv_thread_self();
}
UVW_INLINE bool Thread::equal(const Thread &tl, const Thread &tr) noexcept {
return !(0 == uv_thread_equal(tl.get(), tr.get()));
}
UVW_INLINE Thread::~Thread() noexcept {
join();
}
UVW_INLINE bool Thread::run() noexcept {
return (0 == uv_thread_create(get(), &createCallback, this));
}
UVW_INLINE bool Thread::run(Flags<Options> opts, std::size_t stack) noexcept {
uv_thread_options_t params{static_cast<unsigned int>(opts), stack};
return (0 == uv_thread_create_ex(get(), &params, &createCallback, this));
}
UVW_INLINE bool Thread::join() noexcept {
return (0 == uv_thread_join(get()));
}
UVW_INLINE ThreadLocalStorage::ThreadLocalStorage(UnderlyingType<ThreadLocalStorage, uv_key_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept
:UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
uv_key_create(UnderlyingType::get());
}
UVW_INLINE ThreadLocalStorage::~ThreadLocalStorage() noexcept {
uv_key_delete(UnderlyingType::get());
}
UVW_INLINE uv_once_t *Once::guard() noexcept {
static uv_once_t once = UV_ONCE_INIT;
return &once;
}
UVW_INLINE Mutex::Mutex(UnderlyingType<Mutex, uv_mutex_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref, bool recursive) noexcept
: UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
if(recursive) {
uv_mutex_init_recursive(get());
} else {
@ -78,143 +62,112 @@ UVW_INLINE Mutex::Mutex(UnderlyingType<Mutex, uv_mutex_t>::ConstructorAccess ca,
}
}
UVW_INLINE Mutex::~Mutex() noexcept {
uv_mutex_destroy(get());
}
UVW_INLINE void Mutex::lock() noexcept {
uv_mutex_lock(get());
}
UVW_INLINE bool Mutex::tryLock() noexcept {
return (0 == uv_mutex_trylock(get()));
}
UVW_INLINE void Mutex::unlock() noexcept {
uv_mutex_unlock(get());
}
UVW_INLINE RWLock::RWLock(UnderlyingType<RWLock, uv_rwlock_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept
: UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
uv_rwlock_init(get());
}
UVW_INLINE RWLock::~RWLock() noexcept {
uv_rwlock_destroy(get());
}
UVW_INLINE void RWLock::rdLock() noexcept {
uv_rwlock_rdlock(get());
}
UVW_INLINE bool RWLock::tryRdLock() noexcept {
return (0 == uv_rwlock_tryrdlock(get()));
}
UVW_INLINE void RWLock::rdUnlock() noexcept {
uv_rwlock_rdunlock(get());
}
UVW_INLINE void RWLock::wrLock() noexcept {
uv_rwlock_wrlock(get());
}
UVW_INLINE bool RWLock::tryWrLock() noexcept {
return (0 == uv_rwlock_trywrlock(get()));
}
UVW_INLINE void RWLock::wrUnlock() noexcept {
uv_rwlock_wrunlock(get());
}
UVW_INLINE Semaphore::Semaphore(UnderlyingType<Semaphore, uv_sem_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int value) noexcept
: UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
uv_sem_init(get(), value);
}
UVW_INLINE Semaphore::~Semaphore() noexcept {
uv_sem_destroy(get());
}
UVW_INLINE void Semaphore::post() noexcept {
uv_sem_post(get());
}
UVW_INLINE void Semaphore::wait() noexcept {
uv_sem_wait(get());
}
UVW_INLINE bool Semaphore::tryWait() noexcept {
return (0 == uv_sem_trywait(get()));
}
UVW_INLINE Condition::Condition(UnderlyingType<Condition, uv_cond_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept
: UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
uv_cond_init(get());
}
UVW_INLINE Condition::~Condition() noexcept {
uv_cond_destroy(get());
}
UVW_INLINE void Condition::signal() noexcept {
uv_cond_signal(get());
}
UVW_INLINE void Condition::broadcast() noexcept {
uv_cond_broadcast(get());
}
UVW_INLINE void Condition::wait(Mutex &mutex) noexcept {
uv_cond_wait(get(), mutex.get());
}
UVW_INLINE bool Condition::timedWait(Mutex &mutex, uint64_t timeout) noexcept {
return (0 == uv_cond_timedwait(get(), mutex.get(), timeout));
}
UVW_INLINE Barrier::Barrier(UnderlyingType<Barrier, uv_barrier_t>::ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int count) noexcept
: UnderlyingType{ca, std::move(ref)}
{
: UnderlyingType{ca, std::move(ref)} {
uv_barrier_init(get(), count);
}
UVW_INLINE Barrier::~Barrier() noexcept {
uv_barrier_destroy(get());
}
UVW_INLINE bool Barrier::wait() noexcept {
return (0 == uv_barrier_wait(get()));
}
}
} // namespace uvw

View File

@ -1,32 +1,26 @@
#ifndef UVW_THREAD_INCLUDE_H
#define UVW_THREAD_INCLUDE_H
#include <cstddef>
#include <memory>
#include <string>
#include <cstddef>
#include <type_traits>
#include <utility>
#include <uv.h>
#include "loop.h"
#include "underlying_type.hpp"
namespace uvw {
namespace details {
enum class UVThreadCreateFlags: std::underlying_type_t<uv_thread_create_flags> {
enum class UVThreadCreateFlags : std::underlying_type_t<uv_thread_create_flags> {
THREAD_NO_FLAGS = UV_THREAD_NO_FLAGS,
THREAD_HAS_STACK_SIZE = UV_THREAD_HAS_STACK_SIZE
};
}
class Thread;
class ThreadLocalStorage;
class Once;
@ -36,7 +30,6 @@ class Semaphore;
class Condition;
class Barrier;
/**
* @brief The Thread wrapper.
*
@ -106,7 +99,6 @@ private:
Task task;
};
/**
* @brief The ThreadLocalStorage wrapper.
*
@ -126,8 +118,8 @@ public:
* @return A pointer to the given variable.
*/
template<typename T>
T* get() noexcept {
return static_cast<T*>(uv_key_get(UnderlyingType::get()));
T *get() noexcept {
return static_cast<T *>(uv_key_get(UnderlyingType::get()));
}
/**
@ -141,7 +133,6 @@ public:
}
};
/**
* @brief The Once wrapper.
*
@ -149,7 +140,7 @@ public:
* callers except one (its unspecified which one).
*/
class Once final: public UnderlyingType<Once, uv_once_t> {
static uv_once_t* guard() noexcept;
static uv_once_t *guard() noexcept;
public:
using UnderlyingType::UnderlyingType;
@ -165,14 +156,13 @@ public:
*/
template<typename F>
static void once(F &&f) noexcept {
using CallbackType = void(*)(void);
using CallbackType = void (*)(void);
static_assert(std::is_convertible_v<F, CallbackType>);
CallbackType cb = f;
uv_once(guard(), cb);
}
};
/**
* @brief The Mutex wrapper.
*
@ -206,7 +196,6 @@ public:
void unlock() noexcept;
};
/**
* @brief The RWLock wrapper.
*/
@ -249,7 +238,6 @@ public:
void wrUnlock() noexcept;
};
/**
* @brief The Semaphore wrapper.
*
@ -280,7 +268,6 @@ public:
bool tryWait() noexcept;
};
/**
* @brief The Condition wrapper.
*/
@ -334,7 +321,6 @@ public:
bool timedWait(Mutex &mutex, uint64_t timeout) noexcept;
};
/**
* @brief The Barrier wrapper.
*
@ -357,12 +343,10 @@ public:
bool wait() noexcept;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "thread.cpp"
# include "thread.cpp"
#endif
#endif // UVW_THREAD_INCLUDE_H

View File

@ -1,52 +1,42 @@
#ifdef UVW_AS_LIB
#include "timer.h"
# include "timer.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE void TimerHandle::startCallback(uv_timer_t *handle) {
TimerHandle &timer = *(static_cast<TimerHandle *>(handle->data));
timer.publish(TimerEvent{});
}
UVW_INLINE bool TimerHandle::init() {
return initialize(&uv_timer_init);
}
UVW_INLINE void TimerHandle::start(TimerHandle::Time timeout, TimerHandle::Time repeat) {
invoke(&uv_timer_start, get(), &startCallback, timeout.count(), repeat.count());
}
UVW_INLINE void TimerHandle::stop() {
invoke(&uv_timer_stop, get());
}
UVW_INLINE void TimerHandle::again() {
invoke(&uv_timer_again, get());
}
UVW_INLINE void TimerHandle::repeat(TimerHandle::Time repeat) {
uv_timer_set_repeat(get(), repeat.count());
}
UVW_INLINE TimerHandle::Time TimerHandle::repeat() {
return Time{uv_timer_get_repeat(get())};
}
UVW_INLINE TimerHandle::Time TimerHandle::dueIn() {
return Time{uv_timer_get_due_in(get())};
}
}
} // namespace uvw

View File

@ -1,16 +1,13 @@
#ifndef UVW_TIMER_INCLUDE_H
#define UVW_TIMER_INCLUDE_H
#include <chrono>
#include <uv.h>
#include "handle.hpp"
#include "loop.h"
namespace uvw {
/**
* @brief TimerEvent event.
*
@ -18,7 +15,6 @@ namespace uvw {
*/
struct TimerEvent {};
/**
* @brief The TimerHandle handle.
*
@ -97,20 +93,18 @@ public:
/**
* @brief Gets the timer due value.
*
*
* The time is relative to `Loop::now()`.
*
*
* @return The timer due value or 0 if it has expired.
*/
Time dueIn();
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "timer.cpp"
# include "timer.cpp"
#endif
#endif // UVW_TIMER_INCLUDE_H

View File

@ -1,27 +1,22 @@
#ifdef UVW_AS_LIB
#include "tty.h"
# include "tty.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE details::ResetModeMemo::~ResetModeMemo() {
uv_tty_reset_mode();
}
UVW_INLINE TTYHandle::TTYHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, FileHandle desc, bool readable)
: StreamHandle{ca, std::move(ref)},
memo{resetModeMemo()},
fd{desc},
rw{readable}
{}
rw{readable} {}
UVW_INLINE std::shared_ptr<details::ResetModeMemo> TTYHandle::resetModeMemo() {
static std::weak_ptr<details::ResetModeMemo> weak;
@ -30,22 +25,18 @@ UVW_INLINE std::shared_ptr<details::ResetModeMemo> TTYHandle::resetModeMemo() {
return shared;
};
UVW_INLINE bool TTYHandle::init() {
return initialize(&uv_tty_init, fd, rw);
}
UVW_INLINE bool TTYHandle::mode(TTYHandle::Mode m) {
return (0 == uv_tty_set_mode(get(), static_cast<std::underlying_type_t<Mode>>(m)));
}
UVW_INLINE bool TTYHandle::reset() noexcept {
return (0 == uv_tty_reset_mode());
}
UVW_INLINE WinSize TTYHandle::getWinSize() {
WinSize size;
@ -57,24 +48,21 @@ UVW_INLINE WinSize TTYHandle::getWinSize() {
return size;
}
UVW_INLINE void TTYHandle::vtermState(TTYHandle::VTermState s) const noexcept {
switch(s) {
case VTermState::SUPPORTED:
uv_tty_set_vterm_state(uv_tty_vtermstate_t::UV_TTY_SUPPORTED);
break;
case VTermState::UNSUPPORTED:
uv_tty_set_vterm_state(uv_tty_vtermstate_t::UV_TTY_UNSUPPORTED);
break;
case VTermState::SUPPORTED:
uv_tty_set_vterm_state(uv_tty_vtermstate_t::UV_TTY_SUPPORTED);
break;
case VTermState::UNSUPPORTED:
uv_tty_set_vterm_state(uv_tty_vtermstate_t::UV_TTY_UNSUPPORTED);
break;
}
}
UVW_INLINE TTYHandle::VTermState TTYHandle::vtermState() const noexcept {
uv_tty_vtermstate_t state;
uv_tty_get_vterm_state(&state);
return VTermState{state};
}
}
} // namespace uvw

View File

@ -1,40 +1,32 @@
#ifndef UVW_TTY_INCLUDE_H
#define UVW_TTY_INCLUDE_H
#include <type_traits>
#include <memory>
#include <type_traits>
#include <uv.h>
#include "stream.h"
#include "util.h"
namespace uvw {
namespace details {
struct ResetModeMemo {
~ResetModeMemo();
};
enum class UVTTYModeT: std::underlying_type_t<uv_tty_mode_t> {
enum class UVTTYModeT : std::underlying_type_t<uv_tty_mode_t> {
NORMAL = UV_TTY_MODE_NORMAL,
RAW = UV_TTY_MODE_RAW,
IO = UV_TTY_MODE_IO
};
enum class UVTTYVTermStateT: std::underlying_type_t<uv_tty_vtermstate_t> {
enum class UVTTYVTermStateT : std::underlying_type_t<uv_tty_vtermstate_t> {
SUPPORTED = UV_TTY_SUPPORTED,
UNSUPPORTED = UV_TTY_UNSUPPORTED
};
}
} // namespace details
/**
* @brief The TTYHandle handle.
@ -144,12 +136,10 @@ private:
int rw;
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "tty.cpp"
# include "tty.cpp"
#endif
#endif // UVW_TTY_INCLUDE_H

View File

@ -1,23 +1,18 @@
#ifndef UVW_TYPE_INFO_INCLUDE_HPP
#define UVW_TYPE_INFO_INCLUDE_HPP
#include <cstddef>
#include <string_view>
namespace uvw {
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
namespace internal {
// Fowler-Noll-Vo hash function v. 1a - the good
[[nodiscard]] static constexpr std::uint32_t fnv1a(const char *curr) noexcept {
constexpr std::uint32_t offset = 2166136261;
@ -31,29 +26,24 @@ namespace internal {
return value;
}
[[nodiscard]] static inline std::uint32_t counter() noexcept {
static std::uint32_t cnt{};
return cnt++;
}
template<typename Type>
[[nodiscard]] static std::uint32_t fake() noexcept {
static std::uint32_t local = counter();
return local;
}
}
} // namespace internal
/**
* Internal details not to be documented.
* @endcond
*/
/**
* @brief Returns a numerical identifier for a given type.
* @tparam Type The type for which to return the numerical identifier.
@ -70,7 +60,6 @@ template<typename Type>
#endif
}
}
} // namespace uvw
#endif // UVW_TYPE_INFO_INCLUDE_HPP

View File

@ -1,55 +1,42 @@
#ifdef UVW_AS_LIB
#include "udp.h"
# include "udp.h"
#endif
#include "config.h"
namespace uvw {
UVW_INLINE UDPDataEvent::UDPDataEvent(Addr sndr, std::unique_ptr<char[]> buf, std::size_t len, bool part) noexcept
: data{std::move(buf)}, length{len}, sender{std::move(sndr)}, partial{part}
{}
: data{std::move(buf)}, length{len}, sender{std::move(sndr)}, partial{part} {}
UVW_INLINE details::SendReq::SendReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<char[], Deleter> dt, unsigned int len)
: Request<SendReq, uv_udp_send_t>{ca, std::move(loop)},
data{std::move(dt)},
buf{uv_buf_init(data.get(), len)}
{}
buf{uv_buf_init(data.get(), len)} {}
UVW_INLINE void details::SendReq::send(uv_udp_t *handle, const struct sockaddr *addr) {
invoke(&uv_udp_send, get(), handle, &buf, 1, addr, &defaultCallback<SendEvent>);
}
UVW_INLINE UDPHandle::UDPHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int f)
: Handle{ca, std::move(ref)}, tag{FLAGS}, flags{f}
{}
: Handle{ca, std::move(ref)}, tag{FLAGS}, flags{f} {}
UVW_INLINE bool UDPHandle::init() {
return (tag == FLAGS) ? initialize(&uv_udp_init_ex, flags) : initialize(&uv_udp_init);
}
UVW_INLINE void UDPHandle::open(OSSocketHandle socket) {
invoke(&uv_udp_open, get(), socket);
}
UVW_INLINE void UDPHandle::bind(const sockaddr &addr, Flags<UDPHandle::Bind> opts) {
invoke(&uv_udp_bind, get(), &addr, opts);
}
UVW_INLINE void UDPHandle::connect(const sockaddr &addr) {
invoke(&uv_udp_connect, get(), &addr);
}
template<typename I>
UVW_INLINE void UDPHandle::connect(const std::string &ip, unsigned int port) {
typename details::IpTraits<I>::Type addr;
@ -57,24 +44,20 @@ UVW_INLINE void UDPHandle::connect(const std::string &ip, unsigned int port) {
connect(reinterpret_cast<const sockaddr &>(addr));
}
template<typename I>
UVW_INLINE void UDPHandle::connect(Addr addr) {
connect<I>(std::move(addr.ip), addr.port);
}
UVW_INLINE void UDPHandle::disconnect() {
invoke(&uv_udp_connect, get(), nullptr);
}
template<typename I>
UVW_INLINE Addr UDPHandle::peer() const noexcept {
return details::address<I>(&uv_udp_getpeername, get());
}
template<typename I>
UVW_INLINE void UDPHandle::bind(const std::string &ip, unsigned int port, Flags<Bind> opts) {
typename details::IpTraits<I>::Type addr;
@ -82,56 +65,44 @@ UVW_INLINE void UDPHandle::bind(const std::string &ip, unsigned int port, Flags<
bind(reinterpret_cast<const sockaddr &>(addr), std::move(opts));
}
template<typename I>
UVW_INLINE void UDPHandle::bind(Addr addr, Flags<Bind> opts) {
bind<I>(std::move(addr.ip), addr.port, std::move(opts));
}
template<typename I>
UVW_INLINE Addr UDPHandle::sock() const noexcept {
return details::address<I>(&uv_udp_getsockname, get());
}
template<typename I>
UVW_INLINE bool UDPHandle::multicastMembership(const std::string &multicast, const std::string &iface, Membership membership) {
return (0 == uv_udp_set_membership(get(), multicast.data(), iface.data(), static_cast<uv_membership>(membership)));
}
UVW_INLINE bool UDPHandle::multicastLoop(bool enable) {
return (0 == uv_udp_set_multicast_loop(get(), enable));
}
UVW_INLINE bool UDPHandle::multicastTtl(int val) {
return (0 == uv_udp_set_multicast_ttl(get(), val > 255 ? 255 : val));
}
template<typename I>
UVW_INLINE bool UDPHandle::multicastInterface(const std::string &iface) {
return (0 == uv_udp_set_multicast_interface(get(), iface.data()));
}
UVW_INLINE bool UDPHandle::broadcast(bool enable) {
return (0 == uv_udp_set_broadcast(get(), enable));
}
UVW_INLINE bool UDPHandle::ttl(int val) {
return (0 == uv_udp_set_ttl(get(), val > 255 ? 255 : val));
}
UVW_INLINE void UDPHandle::send(const sockaddr &addr, std::unique_ptr<char[]> data, unsigned int len) {
auto req = loop().resource<details::SendReq>(
std::unique_ptr<char[], details::SendReq::Deleter>{data.release(), [](char *ptr) {
delete[] ptr;
}}, len);
auto req = loop().resource<details::SendReq>(std::unique_ptr<char[], details::SendReq::Deleter>{data.release(), [](char *ptr) { delete[] ptr; }}, len);
auto listener = [ptr = shared_from_this()](const auto &event, const auto &) {
ptr->publish(event);
@ -142,7 +113,6 @@ UVW_INLINE void UDPHandle::send(const sockaddr &addr, std::unique_ptr<char[]> da
req->send(get(), &addr);
}
template<typename I>
UVW_INLINE void UDPHandle::send(const std::string &ip, unsigned int port, std::unique_ptr<char[]> data, unsigned int len) {
typename details::IpTraits<I>::Type addr;
@ -150,17 +120,13 @@ UVW_INLINE void UDPHandle::send(const std::string &ip, unsigned int port, std::u
send(reinterpret_cast<const sockaddr &>(addr), std::move(data), len);
}
template<typename I>
UVW_INLINE void UDPHandle::send(Addr addr, std::unique_ptr<char[]> data, unsigned int len) {
send<I>(std::move(addr.ip), addr.port, std::move(data), len);
}
UVW_INLINE void UDPHandle::send(const sockaddr &addr, char *data, unsigned int len) {
auto req = loop().resource<details::SendReq>(
std::unique_ptr<char[], details::SendReq::Deleter>{data, [](char *) {
}}, len);
auto req = loop().resource<details::SendReq>(std::unique_ptr<char[], details::SendReq::Deleter>{data, [](char *) {}}, len);
auto listener = [ptr = shared_from_this()](const auto &event, const auto &) {
ptr->publish(event);
@ -171,7 +137,6 @@ UVW_INLINE void UDPHandle::send(const sockaddr &addr, char *data, unsigned int l
req->send(get(), &addr);
}
template<typename I>
UVW_INLINE void UDPHandle::send(const std::string &ip, unsigned int port, char *data, unsigned int len) {
typename details::IpTraits<I>::Type addr;
@ -179,16 +144,14 @@ UVW_INLINE void UDPHandle::send(const std::string &ip, unsigned int port, char *
send(reinterpret_cast<const sockaddr &>(addr), data, len);
}
template<typename I>
UVW_INLINE void UDPHandle::send(Addr addr, char *data, unsigned int len) {
send<I>(std::move(addr.ip), addr.port, data, len);
}
template<typename I>
UVW_INLINE int UDPHandle::trySend(const sockaddr &addr, std::unique_ptr<char[]> data, unsigned int len) {
uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
uv_buf_t bufs[] = {uv_buf_init(data.get(), len)};
auto bw = uv_udp_try_send(get(), bufs, 1, &addr);
if(bw < 0) {
@ -199,7 +162,6 @@ UVW_INLINE int UDPHandle::trySend(const sockaddr &addr, std::unique_ptr<char[]>
return bw;
}
template<typename I>
UVW_INLINE int UDPHandle::trySend(const std::string &ip, unsigned int port, std::unique_ptr<char[]> data, unsigned int len) {
typename details::IpTraits<I>::Type addr;
@ -207,16 +169,14 @@ UVW_INLINE int UDPHandle::trySend(const std::string &ip, unsigned int port, std:
return trySend(reinterpret_cast<const sockaddr &>(addr), std::move(data), len);
}
template<typename I>
UVW_INLINE int UDPHandle::trySend(Addr addr, std::unique_ptr<char[]> data, unsigned int len) {
return trySend<I>(std::move(addr.ip), addr.port, std::move(data), len);
}
template<typename I>
UVW_INLINE int UDPHandle::trySend(const sockaddr &addr, char *data, unsigned int len) {
uv_buf_t bufs[] = { uv_buf_init(data, len) };
uv_buf_t bufs[] = {uv_buf_init(data, len)};
auto bw = uv_udp_try_send(get(), bufs, 1, &addr);
if(bw < 0) {
@ -227,7 +187,6 @@ UVW_INLINE int UDPHandle::trySend(const sockaddr &addr, char *data, unsigned int
return bw;
}
template<typename I>
UVW_INLINE int UDPHandle::trySend(const std::string &ip, unsigned int port, char *data, unsigned int len) {
typename details::IpTraits<I>::Type addr;
@ -235,34 +194,28 @@ UVW_INLINE int UDPHandle::trySend(const std::string &ip, unsigned int port, char
return trySend(reinterpret_cast<const sockaddr &>(addr), data, len);
}
template<typename I>
UVW_INLINE int UDPHandle::trySend(Addr addr, char *data, unsigned int len) {
return trySend<I>(std::move(addr.ip), addr.port, data, len);
}
template<typename I>
UVW_INLINE void UDPHandle::recv() {
invoke(&uv_udp_recv_start, get(), &allocCallback, &recvCallback<I>);
}
UVW_INLINE void UDPHandle::stop() {
invoke(&uv_udp_recv_stop, get());
}
UVW_INLINE size_t UDPHandle::sendQueueSize() const noexcept {
return uv_udp_get_send_queue_size(get());
}
UVW_INLINE size_t UDPHandle::sendQueueCount() const noexcept {
return uv_udp_get_send_queue_count(get());
}
// explicit instantiations
#ifdef UVW_AS_LIB
template void UDPHandle::connect<IPv4>(const std::string &, unsigned int);
@ -323,5 +276,4 @@ template void UDPHandle::recv<IPv4>();
template void UDPHandle::recv<IPv6>();
#endif // UVW_AS_LIB
}
} // namespace uvw

View File

@ -1,21 +1,18 @@
#ifndef UVW_UDP_INCLUDE_H
#define UVW_UDP_INCLUDE_H
#include <type_traits>
#include <utility>
#include <cstddef>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <uv.h>
#include "request.hpp"
#include "handle.hpp"
#include "request.hpp"
#include "util.h"
namespace uvw {
/**
* @brief SendEvent event.
*
@ -23,7 +20,6 @@ namespace uvw {
*/
struct SendEvent {};
/**
* @brief UDPDataEvent event.
*
@ -33,16 +29,14 @@ struct UDPDataEvent {
explicit UDPDataEvent(Addr sndr, std::unique_ptr<char[]> buf, std::size_t len, bool part) noexcept;
std::unique_ptr<char[]> data; /*!< A bunch of data read on the stream. */
std::size_t length; /*!< The amount of data read on the stream. */
Addr sender; /*!< A valid instance of Addr. */
bool partial; /*!< True if the message was truncated, false otherwise. */
std::size_t length; /*!< The amount of data read on the stream. */
Addr sender; /*!< A valid instance of Addr. */
bool partial; /*!< True if the message was truncated, false otherwise. */
};
namespace details {
enum class UVUDPFlags: std::underlying_type_t<uv_udp_flags> {
enum class UVUDPFlags : std::underlying_type_t<uv_udp_flags> {
IPV6ONLY = UV_UDP_IPV6ONLY,
UDP_PARTIAL = UV_UDP_PARTIAL,
REUSEADDR = UV_UDP_REUSEADDR,
@ -52,29 +46,25 @@ enum class UVUDPFlags: std::underlying_type_t<uv_udp_flags> {
UDP_RECVMMSG = UV_UDP_RECVMMSG
};
enum class UVMembership: std::underlying_type_t<uv_membership> {
enum class UVMembership : std::underlying_type_t<uv_membership> {
LEAVE_GROUP = UV_LEAVE_GROUP,
JOIN_GROUP = UV_JOIN_GROUP
};
class SendReq final: public Request<SendReq, uv_udp_send_t> {
public:
using Deleter = void(*)(char *);
using Deleter = void (*)(char *);
SendReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<char[], Deleter> dt, unsigned int len);
void send(uv_udp_t *handle, const struct sockaddr* addr);
void send(uv_udp_t *handle, const struct sockaddr *addr);
private:
std::unique_ptr<char[], Deleter> data;
uv_buf_t buf;
};
}
} // namespace details
/**
* @brief The UDPHandle handle.
@ -97,7 +87,7 @@ class UDPHandle final: public Handle<UDPHandle, uv_udp_t> {
static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) {
const typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr);
UDPHandle &udp = *(static_cast<UDPHandle*>(handle->data));
UDPHandle &udp = *(static_cast<UDPHandle *>(handle->data));
// data will be destroyed no matter of what the value of nread is
std::unique_ptr<char[]> data{buf->base};
@ -578,17 +568,19 @@ public:
size_t sendQueueCount() const noexcept;
private:
enum { DEFAULT, FLAGS } tag{DEFAULT};
enum {
DEFAULT,
FLAGS
} tag{DEFAULT};
unsigned int flags{};
};
/**
* @cond TURN_OFF_DOXYGEN
* Internal details not to be documented.
*/
// (extern) explicit instantiations
#ifdef UVW_AS_LIB
extern template void UDPHandle::connect<IPv4>(const std::string &, unsigned int);
@ -649,19 +641,15 @@ extern template void UDPHandle::recv<IPv4>();
extern template void UDPHandle::recv<IPv6>();
#endif // UVW_AS_LIB
/**
* Internal details not to be documented.
* @endcond
*/
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "udp.cpp"
# include "udp.cpp"
#endif
#endif // UVW_UDP_INCLUDE_H

View File

@ -1,16 +1,13 @@
#ifndef UVW_UNDERLYING_TYPE_INCLUDE_H
#define UVW_UNDERLYING_TYPE_INCLUDE_H
#include <memory>
#include <type_traits>
#include <utility>
#include "loop.h"
namespace uvw {
/**
* @brief Wrapper class for underlying types.
*
@ -22,7 +19,9 @@ class UnderlyingType {
friend class UnderlyingType;
protected:
struct ConstructorAccess { explicit ConstructorAccess(int) {} };
struct ConstructorAccess {
explicit ConstructorAccess(int) {}
};
template<typename R = U>
auto get() noexcept {
@ -41,8 +40,7 @@ protected:
public:
explicit UnderlyingType(ConstructorAccess, std::shared_ptr<Loop> ref) noexcept
: pLoop{std::move(ref)}, resource{}
{}
: pLoop{std::move(ref)}, resource{} {}
UnderlyingType(const UnderlyingType &) = delete;
UnderlyingType(UnderlyingType &&) = delete;
@ -51,8 +49,8 @@ public:
static_assert(std::is_base_of_v<UnderlyingType<T, U>, T>);
}
UnderlyingType & operator=(const UnderlyingType &) = delete;
UnderlyingType & operator=(UnderlyingType &&) = delete;
UnderlyingType &operator=(const UnderlyingType &) = delete;
UnderlyingType &operator=(UnderlyingType &&) = delete;
/**
* @brief Creates a new resource of the given type.
@ -60,7 +58,7 @@ public:
* @return A pointer to the newly created resource.
*/
template<typename... Args>
static std::shared_ptr<T> create(Args&&... args) {
static std::shared_ptr<T> create(Args &&...args) {
return std::make_shared<T>(ConstructorAccess{0}, std::forward<Args>(args)...);
}
@ -68,7 +66,9 @@ public:
* @brief Gets the loop from which the resource was originated.
* @return A reference to a loop instance.
*/
Loop & loop() const noexcept { return *pLoop; }
Loop &loop() const noexcept {
return *pLoop;
}
/**
* @brief Gets the underlying raw data structure.
@ -85,7 +85,7 @@ public:
*
* @return The underlying raw data structure.
*/
const U * raw() const noexcept {
const U *raw() const noexcept {
return &resource;
}
@ -104,7 +104,7 @@ public:
*
* @return The underlying raw data structure.
*/
U * raw() noexcept {
U *raw() noexcept {
return const_cast<U *>(const_cast<const UnderlyingType *>(this)->raw());
}
@ -113,7 +113,6 @@ private:
U resource;
};
}
} // namespace uvw
#endif // UVW_UNDERLYING_TYPE_INCLUDE_H

View File

@ -1,119 +1,95 @@
#ifdef UVW_AS_LIB
#include "util.h"
# include "util.h"
#endif
#include <algorithm>
#include "config.h"
namespace uvw {
UVW_INLINE Passwd::Passwd(std::shared_ptr<uv_passwd_t> pwd)
: passwd{pwd}
{}
: passwd{pwd} {}
UVW_INLINE std::string Passwd::username() const noexcept {
return ((passwd && passwd->username) ? passwd->username : "");
}
UVW_INLINE decltype(uv_passwd_t::uid) Passwd::uid() const noexcept {
return (passwd ? passwd->uid : decltype(uv_passwd_t::uid){});
}
UVW_INLINE decltype(uv_passwd_t::gid) Passwd::gid() const noexcept {
return (passwd ? passwd->gid : decltype(uv_passwd_t::gid){});
return (passwd ? passwd->gid : decltype(uv_passwd_t::gid){});
}
UVW_INLINE std::string Passwd::shell() const noexcept {
return ((passwd && passwd->shell) ? passwd->shell : "");
}
UVW_INLINE std::string Passwd::homedir() const noexcept {
return ((passwd && passwd->homedir) ? passwd->homedir: "");
return ((passwd && passwd->homedir) ? passwd->homedir : "");
}
UVW_INLINE Passwd::operator bool() const noexcept {
return static_cast<bool>(passwd);
}
UVW_INLINE UtsName::UtsName(std::shared_ptr<uv_utsname_t> utsname)
: utsname{utsname}
{}
: utsname{utsname} {}
UVW_INLINE std::string UtsName::sysname() const noexcept {
return utsname ? utsname->sysname : "";
}
UVW_INLINE std::string UtsName::release() const noexcept {
return utsname ? utsname->release : "";
}
UVW_INLINE std::string UtsName::version() const noexcept {
return utsname ? utsname->version : "";
}
UVW_INLINE std::string UtsName::machine() const noexcept {
return utsname ? utsname->machine : "";
}
UVW_INLINE PidType Utilities::OS::pid() noexcept {
return uv_os_getpid();
}
UVW_INLINE PidType Utilities::OS::parent() noexcept {
return uv_os_getppid();
}
UVW_INLINE std::string Utilities::OS::homedir() noexcept {
return details::tryRead(&uv_os_homedir);
}
UVW_INLINE std::string Utilities::OS::tmpdir() noexcept {
return details::tryRead(&uv_os_tmpdir);
}
UVW_INLINE std::string Utilities::OS::env(const std::string &name) noexcept {
return details::tryRead(&uv_os_getenv, name.c_str());
}
UVW_INLINE bool Utilities::OS::env(const std::string &name, const std::string &value) noexcept {
return (0 == (value.empty() ? uv_os_unsetenv(name.c_str()) : uv_os_setenv(name.c_str(), value.c_str())));
}
UVW_INLINE std::string Utilities::OS::hostname() noexcept {
return details::tryRead(&uv_os_gethostname);
}
UVW_INLINE UtsName Utilities::OS::uname() noexcept {
auto ptr = std::make_shared<uv_utsname_t>();
uv_os_uname(ptr.get());
return ptr;
}
UVW_INLINE Passwd Utilities::OS::passwd() noexcept {
auto deleter = [](uv_passwd_t *passwd){
auto deleter = [](uv_passwd_t *passwd) {
uv_os_free_passwd(passwd);
delete passwd;
};
@ -123,7 +99,6 @@ UVW_INLINE Passwd Utilities::OS::passwd() noexcept {
return ptr;
}
UVW_INLINE int Utilities::OS::priority(PidType pid) {
int prio = 0;
@ -134,12 +109,10 @@ UVW_INLINE int Utilities::OS::priority(PidType pid) {
return prio;
}
UVW_INLINE bool Utilities::OS::priority(PidType pid, int prio) {
return 0 == uv_os_setpriority(pid, prio);
}
UVW_INLINE HandleType Utilities::guessHandle(HandleCategory category) noexcept {
switch(category) {
case UV_ASYNC:
@ -181,13 +154,11 @@ UVW_INLINE HandleType Utilities::guessHandle(HandleCategory category) noexcept {
}
}
UVW_INLINE HandleType Utilities::guessHandle(FileHandle file) noexcept {
HandleCategory category = uv_guess_handle(file);
return guessHandle(category);
}
UVW_INLINE std::vector<CPUInfo> Utilities::cpuInfo() noexcept {
std::vector<CPUInfo> cpuinfos;
@ -195,8 +166,8 @@ UVW_INLINE std::vector<CPUInfo> Utilities::cpuInfo() noexcept {
int count;
if(0 == uv_cpu_info(&infos, &count)) {
std::for_each(infos, infos+count, [&cpuinfos](const auto &info) {
cpuinfos.push_back({ info.model, info.speed, info.cpu_times });
std::for_each(infos, infos + count, [&cpuinfos](const auto &info) {
cpuinfos.push_back({info.model, info.speed, info.cpu_times});
});
uv_free_cpu_info(infos, count);
@ -205,7 +176,6 @@ UVW_INLINE std::vector<CPUInfo> Utilities::cpuInfo() noexcept {
return cpuinfos;
}
UVW_INLINE std::vector<InterfaceAddress> Utilities::interfaceAddresses() noexcept {
std::vector<InterfaceAddress> interfaces;
@ -213,11 +183,11 @@ UVW_INLINE std::vector<InterfaceAddress> Utilities::interfaceAddresses() noexcep
int count{0};
if(0 == uv_interface_addresses(&ifaces, &count)) {
std::for_each(ifaces, ifaces+count, [&interfaces](const auto &iface) {
std::for_each(ifaces, ifaces + count, [&interfaces](const auto &iface) {
InterfaceAddress interfaceAddress;
interfaceAddress.name = iface.name;
std::copy(iface.phys_addr, (iface.phys_addr+6), interfaceAddress.physical);
std::copy(iface.phys_addr, (iface.phys_addr + 6), interfaceAddress.physical);
interfaceAddress.internal = iface.is_internal == 0 ? false : true;
if(iface.address.address4.sin_family == AF_INET) {
@ -237,34 +207,28 @@ UVW_INLINE std::vector<InterfaceAddress> Utilities::interfaceAddresses() noexcep
return interfaces;
}
UVW_INLINE std::string Utilities::indexToName(unsigned int index) noexcept {
return details::tryRead(&uv_if_indextoname, index);
}
UVW_INLINE std::string Utilities::indexToIid(unsigned int index) noexcept {
return details::tryRead(&uv_if_indextoiid, index);
}
UVW_INLINE bool Utilities::replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept {
return (0 == uv_replace_allocator(mallocFunc, reallocFunc, callocFunc, freeFunc));
}
UVW_INLINE std::array<double, 3> Utilities::loadAverage() noexcept {
std::array<double, 3> avg;
uv_loadavg(avg.data());
return avg;
}
UVW_INLINE char ** Utilities::setupArgs(int argc, char** argv) {
UVW_INLINE char **Utilities::setupArgs(int argc, char **argv) {
return uv_setup_args(argc, argv);
}
UVW_INLINE std::string Utilities::processTitle() {
std::size_t size = details::DEFAULT_SIZE;
char buf[details::DEFAULT_SIZE];
@ -277,22 +241,18 @@ UVW_INLINE std::string Utilities::processTitle() {
return str;
}
UVW_INLINE bool Utilities::processTitle(const std::string &title) {
return (0 == uv_set_process_title(title.c_str()));
}
UVW_INLINE uint64_t Utilities::totalMemory() noexcept {
return uv_get_total_memory();
}
UVW_INLINE uint64_t Utilities::constrainedMemory() noexcept {
return uv_get_constrained_memory();
}
UVW_INLINE double Utilities::uptime() noexcept {
double ret;
@ -303,44 +263,36 @@ UVW_INLINE double Utilities::uptime() noexcept {
return ret;
}
UVW_INLINE RUsage Utilities::rusage() noexcept {
RUsage ru;
auto err = uv_getrusage(&ru);
return err ? RUsage{} : ru;
}
UVW_INLINE uint64_t Utilities::hrtime() noexcept {
return uv_hrtime();
}
UVW_INLINE std::string Utilities::path() noexcept {
return details::tryRead(&uv_exepath);
}
UVW_INLINE std::string Utilities::cwd() noexcept {
return details::tryRead(&uv_cwd);
}
UVW_INLINE bool Utilities::chdir(const std::string &dir) noexcept {
return (0 == uv_chdir(dir.data()));
}
UVW_INLINE TimeVal64 Utilities::timeOfDay() noexcept {
uv_timeval64_t ret;
uv_gettimeofday(&ret);
return ret;
}
UVW_INLINE void Utilities::sleep(unsigned int msec) noexcept {
uv_sleep(msec);
}
}
} // namespace uvw

View File

@ -1,25 +1,21 @@
#ifndef UVW_UTIL_INCLUDE_H
#define UVW_UTIL_INCLUDE_H
#include <array>
#include <cstddef>
#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <cstddef>
#include <utility>
#include <string>
#include <vector>
#include <memory>
#include <array>
#include <uv.h>
namespace uvw {
namespace details {
enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
enum class UVHandleType : std::underlying_type_t<uv_handle_type> {
UNKNOWN = UV_UNKNOWN_HANDLE,
ASYNC = UV_ASYNC,
CHECK = UV_CHECK,
@ -40,15 +36,19 @@ enum class UVHandleType: std::underlying_type_t<uv_handle_type> {
FILE = UV_FILE
};
template<typename T>
struct UVTypeWrapper {
using Type = T;
constexpr UVTypeWrapper(): value{} {}
constexpr UVTypeWrapper(Type val): value{val} {}
constexpr UVTypeWrapper()
: value{} {}
constexpr operator Type() const noexcept { return value; }
constexpr UVTypeWrapper(Type val)
: value{val} {}
constexpr operator Type() const noexcept {
return value;
}
bool operator==(UVTypeWrapper other) const noexcept {
return value == other.value;
@ -58,15 +58,12 @@ private:
const Type value;
};
template<typename T>
bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
return !(lhs == rhs);
}
}
} // namespace details
/**
* @brief Utility class to handle flags.
@ -80,9 +77,13 @@ bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
*/
template<typename E>
class Flags final {
static_assert(std::is_enum_v<E>);
using InnerType = std::underlying_type_t<E>;
constexpr InnerType toInnerType(E flag) const noexcept { return static_cast<InnerType>(flag); }
constexpr InnerType toInnerType(E flag) const noexcept {
return static_cast<InnerType>(flag);
}
public:
using Type = InnerType;
@ -100,31 +101,35 @@ public:
* @brief Constructs a Flags object from a value of the enum `E`.
* @param flag A value of the enum `E`.
*/
constexpr Flags(E flag) noexcept: flags{toInnerType(flag)} {}
constexpr Flags(E flag) noexcept
: flags{toInnerType(flag)} {}
/**
* @brief Constructs a Flags object from an instance of the underlying type
* of the enum `E`.
* @param f An instance of the underlying type of the enum `E`.
*/
constexpr Flags(Type f): flags{f} {}
constexpr Flags(Type f)
: flags{f} {}
/**
* @brief Constructs an uninitialized Flags object.
*/
constexpr Flags(): flags{} {}
constexpr Flags()
: flags{} {}
constexpr Flags(const Flags &f) noexcept: flags{f.flags} { }
constexpr Flags(Flags &&f) noexcept: flags{std::move(f.flags)} { }
constexpr Flags(const Flags &f) noexcept
: flags{f.flags} {}
~Flags() noexcept { static_assert(std::is_enum_v<E>); }
constexpr Flags(Flags &&f) noexcept
: flags{std::move(f.flags)} {}
constexpr Flags & operator=(const Flags &f) noexcept {
constexpr Flags &operator=(const Flags &f) noexcept {
flags = f.flags;
return *this;
}
constexpr Flags & operator=(Flags &&f) noexcept {
constexpr Flags &operator=(Flags &&f) noexcept {
flags = std::move(f.flags);
return *this;
}
@ -134,77 +139,86 @@ public:
* @param f A valid instance of Flags.
* @return This instance _or-ed_ with `f`.
*/
constexpr Flags operator|(const Flags &f) const noexcept { return Flags{flags | f.flags}; }
constexpr Flags operator|(const Flags &f) const noexcept {
return Flags{flags | f.flags};
}
/**
* @brief Or operator.
* @param flag A value of the enum `E`.
* @return This instance _or-ed_ with `flag`.
*/
constexpr Flags operator|(E flag) const noexcept { return Flags{flags | toInnerType(flag)}; }
constexpr Flags operator|(E flag) const noexcept {
return Flags{flags | toInnerType(flag)};
}
/**
* @brief And operator.
* @param f A valid instance of Flags.
* @return This instance _and-ed_ with `f`.
*/
constexpr Flags operator&(const Flags &f) const noexcept { return Flags{flags & f.flags}; }
constexpr Flags operator&(const Flags &f) const noexcept {
return Flags{flags & f.flags};
}
/**
* @brief And operator.
* @param flag A value of the enum `E`.
* @return This instance _and-ed_ with `flag`.
*/
constexpr Flags operator&(E flag) const noexcept { return Flags{flags & toInnerType(flag)}; }
constexpr Flags operator&(E flag) const noexcept {
return Flags{flags & toInnerType(flag)};
}
/**
* @brief Checks if this instance is initialized.
* @return False if it's uninitialized, true otherwise.
*/
explicit constexpr operator bool() const noexcept { return !(flags == InnerType{}); }
explicit constexpr operator bool() const noexcept {
return !(flags == InnerType{});
}
/**
* @brief Casts the instance to the underlying type of `E`.
* @return An integral representation of the contained flags.
*/
constexpr operator Type() const noexcept { return flags; }
constexpr operator Type() const noexcept {
return flags;
}
private:
InnerType flags;
};
/**
* @brief Windows size representation.
*/
struct WinSize {
int width; /*!< The _width_ of the given window. */
int width; /*!< The _width_ of the given window. */
int height; /*!< The _height_ of the given window. */
};
using HandleType = details::UVHandleType; /*!< The type of a handle. */
using HandleCategory = details::UVTypeWrapper<uv_handle_type>; /*!< Utility class that wraps an internal handle type. */
using FileHandle = details::UVTypeWrapper<uv_file>; /*!< Utility class that wraps an internal file handle. */
using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>; /*!< Utility class that wraps an os socket handle. */
using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>; /*!< Utility class that wraps an os file descriptor. */
using PidType = details::UVTypeWrapper<uv_pid_t>; /*!< Utility class that wraps a cross platform representation of a pid. */
using FileHandle = details::UVTypeWrapper<uv_file>; /*!< Utility class that wraps an internal file handle. */
using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>; /*!< Utility class that wraps an os socket handle. */
using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>; /*!< Utility class that wraps an os file descriptor. */
using PidType = details::UVTypeWrapper<uv_pid_t>; /*!< Utility class that wraps a cross platform representation of a pid. */
constexpr FileHandle StdIN{0}; /*!< Placeholder for stdin descriptor. */
constexpr FileHandle StdIN{0}; /*!< Placeholder for stdin descriptor. */
constexpr FileHandle StdOUT{1}; /*!< Placeholder for stdout descriptor. */
constexpr FileHandle StdERR{2}; /*!< Placeholder for stderr descriptor. */
using TimeSpec = uv_timespec_t; /*!< Library equivalent for uv_timespec_t. */
using Stat = uv_stat_t; /*!< Library equivalent for uv_stat_t. */
using Statfs = uv_statfs_t; /*!< Library equivalent for uv_statfs_t. */
using Uid = uv_uid_t; /*!< Library equivalent for uv_uid_t. */
using Gid = uv_gid_t; /*!< Library equivalent for uv_gid_t. */
using Stat = uv_stat_t; /*!< Library equivalent for uv_stat_t. */
using Statfs = uv_statfs_t; /*!< Library equivalent for uv_statfs_t. */
using Uid = uv_uid_t; /*!< Library equivalent for uv_uid_t. */
using Gid = uv_gid_t; /*!< Library equivalent for uv_gid_t. */
using TimeVal = uv_timeval_t; /*!< Library equivalent for uv_timeval_t. */
using TimeVal = uv_timeval_t; /*!< Library equivalent for uv_timeval_t. */
using TimeVal64 = uv_timeval64_t; /*!< Library equivalent for uv_timeval64_t. */
using RUsage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */
using RUsage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */
/**
* @brief Utility class.
@ -257,7 +271,6 @@ private:
std::shared_ptr<uv_passwd_t> passwd;
};
/**
* @brief Utility class.
*
@ -298,7 +311,6 @@ private:
std::shared_ptr<uv_utsname_t> utsname;
};
/**
* @brief The IPv4 tag.
*
@ -306,7 +318,6 @@ private:
*/
struct IPv4 {};
/**
* @brief The IPv6 tag.
*
@ -314,16 +325,14 @@ struct IPv4 {};
*/
struct IPv6 {};
/**
* @brief Address representation.
*/
struct Addr {
std::string ip; /*!< Either an IPv4 or an IPv6. */
std::string ip; /*!< Either an IPv4 or an IPv6. */
unsigned int port; /*!< A valid service identifier. */
};
/**
* \brief CPU information.
*/
@ -331,7 +340,7 @@ struct CPUInfo {
using CPUTime = decltype(uv_cpu_info_t::cpu_times);
std::string model; /*!< The model of the CPU. */
int speed; /*!< The frequency of the CPU. */
int speed; /*!< The frequency of the CPU. */
/**
* @brief CPU times.
@ -342,50 +351,51 @@ struct CPUInfo {
CPUTime times;
};
/**
* \brief Interface address.
*/
struct InterfaceAddress {
std::string name; /*!< The name of the interface (as an example _eth0_). */
char physical[6]; /*!< The physical address. */
bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */
Addr address; /*!< The address of the given interface. */
Addr netmask; /*!< The netmask of the given interface. */
bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */
Addr address; /*!< The address of the given interface. */
Addr netmask; /*!< The netmask of the given interface. */
};
namespace details {
static constexpr std::size_t DEFAULT_SIZE = 128;
template<typename>
struct IpTraits;
template<>
struct IpTraits<IPv4> {
using Type = sockaddr_in;
using AddrFuncType = int(*)(const char *, int, Type *);
using NameFuncType = int(*)(const Type *, char *, std::size_t);
using AddrFuncType = int (*)(const char *, int, Type *);
using NameFuncType = int (*)(const Type *, char *, std::size_t);
inline static const AddrFuncType addrFunc = &uv_ip4_addr;
inline static const NameFuncType nameFunc = &uv_ip4_name;
static constexpr auto sinPort(const Type *addr) { return addr->sin_port; }
};
static constexpr auto sinPort(const Type *addr) {
return addr->sin_port;
}
};
template<>
struct IpTraits<IPv6> {
using Type = sockaddr_in6;
using AddrFuncType = int(*)(const char *, int, Type *);
using NameFuncType = int(*)(const Type *, char *, std::size_t);
using AddrFuncType = int (*)(const char *, int, Type *);
using NameFuncType = int (*)(const Type *, char *, std::size_t);
inline static const AddrFuncType addrFunc = &uv_ip6_addr;
inline static const NameFuncType nameFunc = &uv_ip6_name;
static constexpr auto sinPort(const Type *addr) { return addr->sin6_port; }
};
static constexpr auto sinPort(const Type *addr) {
return addr->sin6_port;
}
};
template<typename I>
Addr address(const typename details::IpTraits<I>::Type *aptr) noexcept {
@ -402,7 +412,6 @@ Addr address(const typename details::IpTraits<I>::Type *aptr) noexcept {
return addr;
}
template<typename I, typename F, typename H>
Addr address(F &&f, const H *handle) noexcept {
sockaddr_storage ssto;
@ -419,9 +428,8 @@ Addr address(F &&f, const H *handle) noexcept {
return addr;
}
template<typename F, typename... Args>
std::string tryRead(F &&f, Args&&... args) noexcept {
std::string tryRead(F &&f, Args &&...args) noexcept {
std::size_t size = DEFAULT_SIZE;
char buf[DEFAULT_SIZE];
std::string str{};
@ -441,9 +449,7 @@ std::string tryRead(F &&f, Args&&... args) noexcept {
return str;
}
}
} // namespace details
/**
* @brief Miscellaneous utilities.
@ -451,10 +457,10 @@ std::string tryRead(F &&f, Args&&... args) noexcept {
* Miscellaneous functions that dont really belong to any other class.
*/
struct Utilities {
using MallocFuncType = void*(*)(size_t);
using ReallocFuncType = void*(*)(void*, size_t);
using CallocFuncType = void*(*)(size_t, size_t);
using FreeFuncType = void(*)(void*);
using MallocFuncType = void *(*)(size_t);
using ReallocFuncType = void *(*)(void *, size_t);
using CallocFuncType = void *(*)(size_t, size_t);
using FreeFuncType = void (*)(void *);
/**
* @brief OS dedicated utilities.
@ -729,7 +735,7 @@ struct Utilities {
*
* @return Arguments that haven't been consumed internally.
*/
static char ** setupArgs(int argc, char** argv);
static char **setupArgs(int argc, char **argv);
/**
* @brief Gets the title of the current process.
@ -820,7 +826,6 @@ struct Utilities {
static void sleep(unsigned int msec) noexcept;
};
/**
* @brief Helper type for visitors.
* @tparam Func Types of function objects.
@ -830,7 +835,6 @@ struct Overloaded: Func... {
using Func::operator()...;
};
/**
* @brief Deduction guide.
* @tparam Func Types of function objects.
@ -838,13 +842,10 @@ struct Overloaded: Func... {
template<class... Func>
Overloaded(Func...) -> Overloaded<Func...>;
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "util.cpp"
# include "util.cpp"
#endif
#endif // UVW_UTIL_INCLUDE_H

View File

@ -1,29 +1,22 @@
#ifdef UVW_AS_LIB
#include "work.h"
# include "work.h"
#endif
#include <utility>
#include "config.h"
namespace uvw {
UVW_INLINE WorkReq::WorkReq(ConstructorAccess ca, std::shared_ptr<Loop> ref, InternalTask t)
: Request{ca, std::move(ref)}, task{t}
{}
: Request{ca, std::move(ref)}, task{t} {}
UVW_INLINE void WorkReq::workCallback(uv_work_t *req) {
static_cast<WorkReq*>(req->data)->task();
static_cast<WorkReq *>(req->data)->task();
}
UVW_INLINE void WorkReq::queue() {
invoke(&uv_queue_work, parent(), get(), &workCallback, &defaultCallback<WorkEvent>);
}
}
} // namespace uvw

View File

@ -1,17 +1,14 @@
#ifndef UVW_WORK_INCLUDE_H
#define UVW_WORK_INCLUDE_H
#include <functional>
#include <memory>
#include <uv.h>
#include "request.hpp"
#include "loop.h"
#include "request.hpp"
namespace uvw {
/**
* @brief WorkEvent event.
*
@ -19,7 +16,6 @@ namespace uvw {
*/
struct WorkEvent {};
/**
* @brief The WorkReq request.
*
@ -57,12 +53,10 @@ private:
Task task{};
};
}
} // namespace uvw
#ifndef UVW_AS_LIB
#include "work.cpp"
# include "work.cpp"
#endif
#endif // UVW_WORK_INCLUDE_H

View File

@ -1,9 +1,8 @@
#include <uvw.hpp>
#include <cassert>
#include <chrono>
#include <iostream>
#include <memory>
#include <chrono>
#include <uvw.hpp>
void listen(uvw::Loop &loop) {
std::shared_ptr<uvw::TCPHandle> tcp = loop.resource<uvw::TCPHandle>();
@ -52,7 +51,6 @@ void listen(uvw::Loop &loop) {
tcp->listen();
}
void conn(uvw::Loop &loop) {
auto tcp = loop.resource<uvw::TCPHandle>();
tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); });
@ -65,11 +63,11 @@ void conn(uvw::Loop &loop) {
tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::TCPHandle &handle) {
std::cout << "connect" << std::endl;
auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{ 'a' });
auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{'a'});
int bw = handle.tryWrite(std::move(dataTryWrite), 1);
std::cout << "written: " << ((int)bw) << std::endl;
auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' });
auto dataWrite = std::unique_ptr<char[]>(new char[2]{'b', 'c'});
handle.write(std::move(dataWrite), 2);
});

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/async.h>
TEST(Async, Send) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::AsyncHandle>();
@ -27,7 +26,6 @@ TEST(Async, Send) {
ASSERT_TRUE(checkAsyncEvent);
}
TEST(Async, Fake) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::AsyncHandle>();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/check.h>
TEST(Check, StartAndStop) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::CheckHandle>();
@ -28,7 +27,6 @@ TEST(Check, StartAndStop) {
ASSERT_TRUE(checkCheckEvent);
}
TEST(Check, Fake) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::CheckHandle>();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/dns.h>
TEST(GetAddrInfo, GetNodeAddrInfo) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetAddrInfoReq>();
@ -22,7 +21,6 @@ TEST(GetAddrInfo, GetNodeAddrInfo) {
ASSERT_TRUE(checkAddrInfoEvent);
}
TEST(GetAddrInfo, GetNodeAddrInfoSync) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetAddrInfoReq>();
@ -33,7 +31,6 @@ TEST(GetAddrInfo, GetNodeAddrInfoSync) {
loop->run();
}
TEST(GetAddrInfo, GetServiceAddrInfo) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetAddrInfoReq>();
@ -52,7 +49,6 @@ TEST(GetAddrInfo, GetServiceAddrInfo) {
ASSERT_TRUE(checkErrorEvent);
}
TEST(GetAddrInfo, GetServiceAddrInfoSync) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetAddrInfoReq>();
@ -62,7 +58,6 @@ TEST(GetAddrInfo, GetServiceAddrInfoSync) {
loop->run();
}
TEST(GetAddrInfo, GetAddrInfo) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetAddrInfoReq>();
@ -83,7 +78,6 @@ TEST(GetAddrInfo, GetAddrInfo) {
ASSERT_TRUE(checkAddrInfoEvent);
}
TEST(GetAddrInfo, GetAddrInfoSync) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetAddrInfoReq>();
@ -94,7 +88,6 @@ TEST(GetAddrInfo, GetAddrInfoSync) {
loop->run();
}
TEST(GetNameInfo, GetNameInfo) {
auto loop = uvw::Loop::getDefault();
auto koRequest = loop->resource<uvw::GetNameInfoReq>();
@ -113,7 +106,7 @@ TEST(GetNameInfo, GetNameInfo) {
checkNameInfoEvent = true;
});
koRequest->nameInfo(uvw::Addr{ "", 0 }, -1);
koRequest->nameInfo(uvw::Addr{"", 0}, -1);
okRequest->nameInfo("irc.freenode.net", 6667);
loop->run();
@ -122,12 +115,11 @@ TEST(GetNameInfo, GetNameInfo) {
ASSERT_TRUE(checkNameInfoEvent);
}
TEST(GetNameInfo, GetNameInfoSync) {
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::GetNameInfoReq>();
ASSERT_FALSE(request->nameInfoSync(uvw::Addr{ "", 0 }, -1).first);
ASSERT_FALSE(request->nameInfoSync(uvw::Addr{"", 0}, -1).first);
ASSERT_TRUE(request->nameInfoSync("irc.freenode.net", 6667).first);
loop->run();

View File

@ -2,14 +2,14 @@
#include <gtest/gtest.h>
#include <uvw/emitter.h>
struct FakeEvent { };
struct FakeEvent {};
struct TestEmitter: uvw::Emitter<TestEmitter> {
void emit() { publish(FakeEvent{}); }
void emit() {
publish(FakeEvent{});
}
};
TEST(ErrorEvent, Functionalities) {
auto ecode = static_cast<std::underlying_type_t<uv_errno_t>>(UV_EADDRINUSE);
@ -24,13 +24,12 @@ TEST(ErrorEvent, Functionalities) {
ASSERT_TRUE(static_cast<bool>(uvw::ErrorEvent{ecode}));
}
TEST(Emitter, EmptyAndClear) {
TestEmitter emitter{};
ASSERT_TRUE(emitter.empty());
emitter.on<uvw::ErrorEvent>([](const auto &, auto &){});
emitter.on<uvw::ErrorEvent>([](const auto &, auto &) {});
ASSERT_FALSE(emitter.empty());
ASSERT_FALSE(emitter.empty<uvw::ErrorEvent>());
@ -48,8 +47,8 @@ TEST(Emitter, EmptyAndClear) {
ASSERT_TRUE(emitter.empty<uvw::ErrorEvent>());
ASSERT_TRUE(emitter.empty<FakeEvent>());
emitter.on<uvw::ErrorEvent>([](const auto &, auto &){});
emitter.on<FakeEvent>([](const auto &, auto &){});
emitter.on<uvw::ErrorEvent>([](const auto &, auto &) {});
emitter.on<FakeEvent>([](const auto &, auto &) {});
ASSERT_FALSE(emitter.empty());
ASSERT_FALSE(emitter.empty<uvw::ErrorEvent>());
@ -62,11 +61,10 @@ TEST(Emitter, EmptyAndClear) {
ASSERT_TRUE(emitter.empty<FakeEvent>());
}
TEST(Emitter, On) {
TestEmitter emitter{};
emitter.on<FakeEvent>([](const auto &, auto &){});
emitter.on<FakeEvent>([](const auto &, auto &) {});
ASSERT_FALSE(emitter.empty());
ASSERT_FALSE(emitter.empty<FakeEvent>());
@ -77,11 +75,10 @@ TEST(Emitter, On) {
ASSERT_FALSE(emitter.empty<FakeEvent>());
}
TEST(Emitter, Once) {
TestEmitter emitter{};
emitter.once<FakeEvent>([](const auto &, auto &){});
emitter.once<FakeEvent>([](const auto &, auto &) {});
ASSERT_FALSE(emitter.empty());
ASSERT_FALSE(emitter.empty<FakeEvent>());
@ -92,11 +89,10 @@ TEST(Emitter, Once) {
ASSERT_TRUE(emitter.empty<FakeEvent>());
}
TEST(Emitter, OnceAndErase) {
TestEmitter emitter{};
auto conn = emitter.once<FakeEvent>([](const auto &, auto &){});
auto conn = emitter.once<FakeEvent>([](const auto &, auto &) {});
ASSERT_FALSE(emitter.empty());
ASSERT_FALSE(emitter.empty<FakeEvent>());
@ -107,11 +103,10 @@ TEST(Emitter, OnceAndErase) {
ASSERT_TRUE(emitter.empty<FakeEvent>());
}
TEST(Emitter, OnAndErase) {
TestEmitter emitter{};
auto conn = emitter.on<FakeEvent>([](const auto &, auto &){});
auto conn = emitter.on<FakeEvent>([](const auto &, auto &) {});
ASSERT_FALSE(emitter.empty());
ASSERT_FALSE(emitter.empty<FakeEvent>());
@ -122,12 +117,11 @@ TEST(Emitter, OnAndErase) {
ASSERT_TRUE(emitter.empty<FakeEvent>());
}
TEST(Emitter, CallbackClear) {
TestEmitter emitter{};
emitter.on<FakeEvent>([](const auto &, auto &ref) {
ref.template on<FakeEvent>([](const auto &, auto &){});
ref.template on<FakeEvent>([](const auto &, auto &) {});
ref.clear();
});
@ -141,7 +135,7 @@ TEST(Emitter, CallbackClear) {
emitter.on<FakeEvent>([](const auto &, auto &ref) {
ref.clear();
ref.template on<FakeEvent>([](const auto &, auto &){});
ref.template on<FakeEvent>([](const auto &, auto &) {});
});
ASSERT_FALSE(emitter.empty());

View File

@ -1,13 +1,12 @@
#include <chrono>
#include <gtest/gtest.h>
#include <uvw/fs.h>
#include <chrono>
#ifdef _WIN32
#define _CRT_DECLARE_NONSTDC_NAMES 1
#include <fcntl.h>
# define _CRT_DECLARE_NONSTDC_NAMES 1
# include <fcntl.h>
#endif
TEST(FileReq, OpenAndCloseErr) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/err.file"};
@ -38,7 +37,6 @@ TEST(FileReq, OpenAndCloseErr) {
ASSERT_TRUE(checkFileCloseErrorEvent);
}
TEST(FileReq, OpenAndCloseErrSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/err.file"};
@ -51,7 +49,6 @@ TEST(FileReq, OpenAndCloseErrSync) {
loop->run();
}
TEST(FileReq, OpenAndClose) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -83,7 +80,6 @@ TEST(FileReq, OpenAndClose) {
ASSERT_TRUE(checkFileCloseEvent);
}
TEST(FileReq, OpenAndCloseSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -96,7 +92,6 @@ TEST(FileReq, OpenAndCloseSync) {
loop->run();
}
TEST(FileReq, RWChecked) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -122,7 +117,7 @@ TEST(FileReq, RWChecked) {
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.write(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);
req.write(std::unique_ptr<char[]>{new char[1]{42}}, 1, 0);
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
@ -134,10 +129,9 @@ TEST(FileReq, RWChecked) {
ASSERT_TRUE(checkFileReadEvent);
}
TEST(FileReq, RWUnchecked) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
std::unique_ptr<char[]> data{new char[1]{ 42 }};
std::unique_ptr<char[]> data{new char[1]{42}};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
@ -173,7 +167,6 @@ TEST(FileReq, RWUnchecked) {
ASSERT_TRUE(checkFileReadEvent);
}
TEST(FileReq, RWSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -182,7 +175,7 @@ TEST(FileReq, RWSync) {
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
auto writeR = request->writeSync(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);
auto writeR = request->writeSync(std::unique_ptr<char[]>{new char[1]{42}}, 1, 0);
ASSERT_TRUE(writeR.first);
ASSERT_EQ(writeR.second, std::size_t{1});
@ -197,7 +190,6 @@ TEST(FileReq, RWSync) {
loop->run();
}
TEST(FileReq, Stat) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -226,7 +218,6 @@ TEST(FileReq, Stat) {
ASSERT_TRUE(checkFileStatEvent);
}
TEST(FileReq, StatSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -243,7 +234,6 @@ TEST(FileReq, StatSync) {
loop->run();
}
TEST(FileReq, Sync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -272,7 +262,6 @@ TEST(FileReq, Sync) {
ASSERT_TRUE(checkFileSyncEvent);
}
TEST(FileReq, SyncSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -286,7 +275,6 @@ TEST(FileReq, SyncSync) {
loop->run();
}
TEST(FileReq, Datasync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -315,7 +303,6 @@ TEST(FileReq, Datasync) {
ASSERT_TRUE(checkFileDatasyncEvent);
}
TEST(FileReq, DatasyncSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -329,7 +316,6 @@ TEST(FileReq, DatasyncSync) {
loop->run();
}
TEST(FileReq, Truncate) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -358,7 +344,6 @@ TEST(FileReq, Truncate) {
ASSERT_TRUE(checkFileTruncateEvent);
}
TEST(FileReq, TruncateSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -372,7 +357,6 @@ TEST(FileReq, TruncateSync) {
loop->run();
}
TEST(FileReq, Chmod) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -401,7 +385,6 @@ TEST(FileReq, Chmod) {
ASSERT_TRUE(checkFileChmodEvent);
}
TEST(FileReq, ChmodSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -415,7 +398,6 @@ TEST(FileReq, ChmodSync) {
loop->run();
}
TEST(FileReq, Futime) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -447,7 +429,6 @@ TEST(FileReq, Futime) {
ASSERT_TRUE(checkFileUtimeEvent);
}
TEST(FileReq, FutimeSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -467,7 +448,6 @@ TEST(FileReq, FutimeSync) {
loop->run();
}
TEST(FileReq, Chown) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
@ -502,7 +482,6 @@ TEST(FileReq, Chown) {
ASSERT_TRUE(checkFileChownEvent);
}
TEST(FileReq, ChownSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};

View File

@ -1,10 +1,10 @@
#include <chrono>
#include <gtest/gtest.h>
#include <uvw/fs.h>
#include <chrono>
#ifdef _WIN32
#define _CRT_DECLARE_NONSTDC_NAMES 1
#include <fcntl.h>
# define _CRT_DECLARE_NONSTDC_NAMES 1
# include <fcntl.h>
#endif
TEST(FileReq, SendFile) {
@ -44,7 +44,6 @@ TEST(FileReq, SendFile) {
ASSERT_TRUE(checkFileSendFileEvent);
}
TEST(FileReq, SendFileSync) {
const std::string srcFilename = std::string{TARGET_FILE_REQ_SENDFILE_DIR} + std::string{"/src.file"};
const std::string dstFilename = std::string{TARGET_FILE_REQ_SENDFILE_DIR} + std::string{"/dst.file"};
@ -64,4 +63,3 @@ TEST(FileReq, SendFileSync) {
loop->run();
}

View File

@ -2,7 +2,6 @@
#include <uvw/fs.h>
#include <uvw/fs_event.h>
TEST(FsEvent, Functionalities) {
const std::string filename = std::string{TARGET_FS_EVENT_DIR} + std::string{"/test.file"};
@ -29,7 +28,7 @@ TEST(FsEvent, Functionalities) {
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.write(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);
req.write(std::unique_ptr<char[]>{new char[1]{42}}, 1, 0);
});
handle->start(std::string{TARGET_FS_EVENT_DIR}, uvw::FsEventHandle::Event::RECURSIVE);

View File

@ -3,7 +3,6 @@
#include <uvw/fs_event.h>
#include <uvw/fs_poll.h>
TEST(FsPoll, Functionalities) {
const std::string filename = std::string{TARGET_FS_POLL_DIR} + std::string{"/test.file"};
@ -30,7 +29,7 @@ TEST(FsPoll, Functionalities) {
request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0755);
handle->start(filename, uvw::FsPollHandle::Time{1000});
request->write(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);
request->write(std::unique_ptr<char[]>{new char[1]{42}}, 1, 0);
ASSERT_EQ(handle->path(), filename);
ASSERT_TRUE(handle->active());

View File

@ -1,13 +1,12 @@
#include <chrono>
#include <gtest/gtest.h>
#include <uvw/fs.h>
#include <chrono>
#ifdef _WIN32
#define _CRT_DECLARE_NONSTDC_NAMES 1
#include <fcntl.h>
# define _CRT_DECLARE_NONSTDC_NAMES 1
# include <fcntl.h>
#endif
TEST(FsReq, MkdirAndRmdir) {
const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir"};
@ -38,7 +37,6 @@ TEST(FsReq, MkdirAndRmdir) {
ASSERT_TRUE(checkFsRmdirEvent);
}
TEST(FsReq, MkdirAndRmdirSync) {
const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir"};
@ -51,7 +49,6 @@ TEST(FsReq, MkdirAndRmdirSync) {
loop->run();
}
TEST(FsReq, MkdtempAndRmdir) {
const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir.XXXXXX"};
@ -83,7 +80,6 @@ TEST(FsReq, MkdtempAndRmdir) {
ASSERT_TRUE(checkFsRmdirEvent);
}
TEST(FsReq, MkdtempAndRmdirSync) {
const std::string dirname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.dir.XXXXXX"};
@ -99,7 +95,6 @@ TEST(FsReq, MkdtempAndRmdirSync) {
loop->run();
}
TEST(FsReq, Stat) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -133,7 +128,6 @@ TEST(FsReq, Stat) {
ASSERT_TRUE(checkFsStatEvent);
}
TEST(FsReq, StatSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -151,7 +145,6 @@ TEST(FsReq, StatSync) {
loop->run();
}
TEST(FsReq, Lstat) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -185,7 +178,6 @@ TEST(FsReq, Lstat) {
ASSERT_TRUE(checkFsLstatEvent);
}
TEST(FsReq, LstatSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -203,7 +195,6 @@ TEST(FsReq, LstatSync) {
loop->run();
}
TEST(FsReq, Rename) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string rename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.rename"};
@ -238,7 +229,6 @@ TEST(FsReq, Rename) {
ASSERT_TRUE(checkFsRenameEvent);
}
TEST(FsReq, RenameSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string rename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.rename"};
@ -254,7 +244,6 @@ TEST(FsReq, RenameSync) {
loop->run();
}
TEST(FsReq, Access) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -288,7 +277,6 @@ TEST(FsReq, Access) {
ASSERT_TRUE(checkFsAccessEvent);
}
TEST(FsReq, AccessSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -303,7 +291,6 @@ TEST(FsReq, AccessSync) {
loop->run();
}
TEST(FsReq, Chmod) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -337,7 +324,6 @@ TEST(FsReq, Chmod) {
ASSERT_TRUE(checkFsChmodEvent);
}
TEST(FsReq, ChmodSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -352,7 +338,6 @@ TEST(FsReq, ChmodSync) {
loop->run();
}
TEST(FsReq, Utime) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -389,7 +374,6 @@ TEST(FsReq, Utime) {
ASSERT_TRUE(checkFsUtimeEvent);
}
TEST(FsReq, UtimeSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -409,7 +393,6 @@ TEST(FsReq, UtimeSync) {
loop->run();
}
TEST(FsReq, LinkAndUnlink) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"};
@ -452,7 +435,6 @@ TEST(FsReq, LinkAndUnlink) {
ASSERT_TRUE(checkFsUnlinkEvent);
}
TEST(FsReq, LinkAndUnlinkSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"};
@ -469,7 +451,6 @@ TEST(FsReq, LinkAndUnlinkSync) {
loop->run();
}
TEST(FsReq, SymlinkAndUnlink) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"};
@ -512,7 +493,6 @@ TEST(FsReq, SymlinkAndUnlink) {
ASSERT_TRUE(checkFsUnlinkEvent);
}
TEST(FsReq, SymlinkAndUnlinkSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"};
@ -529,7 +509,6 @@ TEST(FsReq, SymlinkAndUnlinkSync) {
loop->run();
}
TEST(FsReq, Readlink) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"};
@ -569,7 +548,6 @@ TEST(FsReq, Readlink) {
ASSERT_TRUE(checkFsReadlinkEvent);
}
TEST(FsReq, ReadlinkSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
const std::string linkname = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.link"};
@ -590,7 +568,6 @@ TEST(FsReq, ReadlinkSync) {
loop->run();
}
TEST(FsReq, Realpath) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -625,7 +602,6 @@ TEST(FsReq, Realpath) {
ASSERT_TRUE(checkFsRealpathEvent);
}
TEST(FsReq, RealpathSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -644,7 +620,6 @@ TEST(FsReq, RealpathSync) {
loop->run();
}
TEST(FsReq, Chown) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -684,7 +659,6 @@ TEST(FsReq, Chown) {
ASSERT_TRUE(checkFsChownEvent);
}
TEST(FsReq, ChownSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -705,7 +679,6 @@ TEST(FsReq, ChownSync) {
loop->run();
}
TEST(FsReq, Lchown) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -745,7 +718,6 @@ TEST(FsReq, Lchown) {
ASSERT_TRUE(checkFsLChownEvent);
}
TEST(FsReq, LchownSync) {
const std::string filename = std::string{TARGET_FS_REQ_DIR} + std::string{"/test.file"};
@ -785,7 +757,7 @@ TEST(FsReq, ReadDir) {
fsReq->on<uvw::FsEvent<uvw::FsReq::Type::READDIR>>([&checkFsReadDirEvent](const auto &event, auto &hndl) {
ASSERT_FALSE(checkFsReadDirEvent);
if (!event.eos) {
if(!event.eos) {
hndl.readdir();
} else {
checkFsReadDirEvent = true;

View File

@ -2,18 +2,19 @@
#include <uvw/async.h>
#include <uvw/handle.hpp>
struct fake_handle_t { void *data; };
struct fake_handle_t {
void *data;
};
struct FakeHandle: uvw::Handle<FakeHandle, fake_handle_t> {
using Handle::Handle;
template<typename... Args>
bool init(Args&&...) { return initialize([](auto...){ return true; }); }
bool init(Args &&...) {
return initialize([](auto...) { return true; });
}
};
TEST(Handle, Functionalities) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::AsyncHandle>();
@ -46,7 +47,6 @@ TEST(Handle, Functionalities) {
ASSERT_NO_THROW(handle->fd());
}
TEST(Handle, InitializationFailure) {
auto loop = uvw::Loop::getDefault();
auto resource = loop->resource<FakeHandle>();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/idle.h>
TEST(Idle, StartAndStop) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::IdleHandle>();
@ -28,7 +27,6 @@ TEST(Idle, StartAndStop) {
ASSERT_TRUE(checkIdleEvent);
}
TEST(Idle, Fake) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::IdleHandle>();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/lib.h>
TEST(SharedLib, Failure) {
auto loop = uvw::Loop::getDefault();
auto lib = loop->resource<uvw::SharedLib>("foobar.so");
@ -14,7 +13,6 @@ TEST(SharedLib, Failure) {
lib.reset();
}
TEST(SharedLib, Success) {
auto loop = uvw::Loop::getDefault();
auto lib = loop->resource<uvw::SharedLib>(TARGET_LIB_SO);

View File

@ -1,8 +1,7 @@
#include <gtest/gtest.h>
#include <uvw/loop.h>
#include <uvw/prepare.h>
#include <uvw/work.h>
#include <uvw/loop.h>
TEST(Loop, DefaultLoop) {
auto def = uvw::Loop::getDefault();
@ -17,11 +16,10 @@ TEST(Loop, DefaultLoop) {
ASSERT_EQ(def, def2);
}
TEST(Loop, Functionalities) {
auto loop = uvw::Loop::create();
auto handle = loop->resource<uvw::PrepareHandle>();
auto req = loop->resource<uvw::WorkReq>([]{});
auto req = loop->resource<uvw::WorkReq>([] {});
loop->on<uvw::ErrorEvent>([](auto &&...) { FAIL(); });
req->on<uvw::ErrorEvent>([](auto &&...) { FAIL(); });
@ -64,7 +62,6 @@ TEST(Loop, Functionalities) {
ASSERT_FALSE(loop->alive());
}
TEST(Loop, UserData) {
auto loop = uvw::Loop::create();
loop->data(std::make_shared<int>(42));
@ -78,21 +75,18 @@ TEST(Loop, UserData) {
ASSERT_EQ(*loop->data<int>(), 42);
}
TEST(Loop, Configure) {
auto loop = uvw::Loop::create();
ASSERT_NO_THROW(loop->configure(uvw::Loop::Configure::BLOCK_SIGNAL, 9));
ASSERT_NO_THROW(loop->run());
}
TEST(Loop, IdleTime) {
auto loop = uvw::Loop::create();
loop->configure(uvw::Loop::Configure::IDLE_TIME);
ASSERT_EQ(loop->idleTime().count(), 0u);
}
TEST(Loop, Raw) {
auto loop = uvw::Loop::getDefault();
const auto &cloop = uvw::Loop::getDefault();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/pipe.h>
TEST(Pipe, ReadWrite) {
#ifdef _MSC_VER
const std::string sockname{"\\\\.\\pipe\\test.sock"};
@ -14,8 +13,8 @@ TEST(Pipe, ReadWrite) {
auto client = loop->resource<uvw::PipeHandle>();
server->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
client->on<uvw::ErrorEvent>([](const auto &, auto &) {
FAIL();
client->on<uvw::ErrorEvent>([](const auto &, auto &) {
FAIL();
});
server->once<uvw::ListenEvent>([](const uvw::ListenEvent &, uvw::PipeHandle &handle) {
@ -37,7 +36,7 @@ TEST(Pipe, ReadWrite) {
ASSERT_TRUE(handle.writable());
ASSERT_TRUE(handle.readable());
auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'x', 'y' });
auto dataWrite = std::unique_ptr<char[]>(new char[2]{'x', 'y'});
handle.write(std::move(dataWrite), 2);
});
@ -48,11 +47,10 @@ TEST(Pipe, ReadWrite) {
loop->run();
}
TEST(Pipe, SockPeer) {
#ifdef _MSC_VER
const std::string sockname{"\\\\.\\pipe\\test.sock"};
const std::string peername{ "\\\\?\\pipe\\test.sock" };
const std::string peername{"\\\\?\\pipe\\test.sock"};
#else
const std::string sockname = std::string{TARGET_PIPE_DIR} + std::string{"/test.sock"};
const auto peername = sockname;
@ -91,7 +89,6 @@ TEST(Pipe, SockPeer) {
loop->run();
}
TEST(Pipe, Shutdown) {
#ifdef _MSC_VER
const std::string sockname{"\\\\.\\pipe\\test.sock"};
@ -99,7 +96,7 @@ TEST(Pipe, Shutdown) {
const std::string sockname = std::string{TARGET_PIPE_DIR} + std::string{"/test.sock"};
#endif
auto data = std::unique_ptr<char[]>(new char[3]{ 'a', 'b', 'c' });
auto data = std::unique_ptr<char[]>(new char[3]{'a', 'b', 'c'});
auto loop = uvw::Loop::getDefault();
auto server = loop->resource<uvw::PipeHandle>();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/prepare.h>
TEST(Prepare, StartAndStop) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::PrepareHandle>();
@ -28,7 +27,6 @@ TEST(Prepare, StartAndStop) {
ASSERT_TRUE(checkPrepareEvent);
}
TEST(Prepare, Fake) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::PrepareHandle>();

View File

@ -2,7 +2,6 @@
#include <uvw/pipe.h>
#include <uvw/process.h>
TEST(Process, Pid) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::ProcessHandle>();
@ -12,7 +11,6 @@ TEST(Process, Pid) {
loop->run();
}
TEST(Process, Cwd) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::ProcessHandle>();
@ -22,7 +20,6 @@ TEST(Process, Cwd) {
loop->run();
}
TEST(Process, StdIO) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::ProcessHandle>();

View File

@ -1,11 +1,10 @@
#include <gtest/gtest.h>
#include <uvw/work.h>
#include <uvw/request.hpp>
#include <uvw/work.h>
TEST(Request, Functionalities) {
auto loop = uvw::Loop::getDefault();
auto req = loop->resource<uvw::WorkReq>([](){});
auto req = loop->resource<uvw::WorkReq>([]() {});
ASSERT_NE(req->size(), decltype(req->size()){0});
ASSERT_FALSE(req->cancel());

View File

@ -4,9 +4,7 @@
#include <uvw/async.h>
#include <uvw/request.hpp>
struct Res: uvw::Resource<Res, int> { };
struct Res: uvw::Resource<Res, int> {};
TEST(Resource, Functionalities) {
ASSERT_FALSE(std::is_copy_constructible<uvw::AsyncHandle>::value);

View File

@ -2,7 +2,6 @@
#include <uvw/check.h>
#include <uvw/signal.h>
TEST(Signal, Start) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::SignalHandle>();

View File

@ -1,13 +1,15 @@
#include <gtest/gtest.h>
#include <uvw/stream.h>
struct fake_stream_t { void *data; };
struct fake_stream_t {
void *data;
};
struct FakeStreamHandle: uvw::StreamHandle<FakeStreamHandle, fake_stream_t> {
using StreamHandle::StreamHandle;
template<typename... Args>
bool init(Args&&...) { return true; }
bool init(Args &&...) {
return true;
}
};

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/tcp.h>
TEST(TCP, Functionalities) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::TCPHandle>();
@ -14,7 +13,6 @@ TEST(TCP, Functionalities) {
loop->run();
}
TEST(TCP, ReadWrite) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;
@ -45,9 +43,9 @@ TEST(TCP, ReadWrite) {
ASSERT_TRUE(handle.writable());
ASSERT_TRUE(handle.readable());
auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{ 'a' });
auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{'a'});
handle.tryWrite(std::move(dataTryWrite), 1);
auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' });
auto dataWrite = std::unique_ptr<char[]>(new char[2]{'b', 'c'});
handle.write(std::move(dataWrite), 2);
});
@ -58,7 +56,6 @@ TEST(TCP, ReadWrite) {
loop->run();
}
TEST(TCP, SockPeer) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;
@ -93,14 +90,13 @@ TEST(TCP, SockPeer) {
handle.close();
});
server->bind(uvw::Addr{ address, port });
server->bind(uvw::Addr{address, port});
server->listen();
client->connect(uvw::Addr{ address, port });
client->connect(uvw::Addr{address, port});
loop->run();
}
TEST(TCP, Shutdown) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;
@ -138,7 +134,6 @@ TEST(TCP, Shutdown) {
loop->run();
}
TEST(TCP, WriteError) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::TCPHandle>();

View File

@ -4,12 +4,13 @@
TEST(Thread, Run) {
auto loop = uvw::Loop::getDefault();
auto has_run = std::make_shared<bool>();
auto handle = loop->resource<uvw::Thread>([](std::shared_ptr<void> data) {
auto cb = [](std::shared_ptr<void> data) {
if(auto has_run = std::static_pointer_cast<bool>(data); has_run) {
*has_run = true;
}
}, has_run);
};
auto handle = loop->resource<uvw::Thread>(cb, has_run);
ASSERT_TRUE(handle->run());
ASSERT_TRUE(handle->join());

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/timer.h>
TEST(Timer, StartAndStop) {
auto loop = uvw::Loop::getDefault();
auto handleNoRepeat = loop->resource<uvw::TimerHandle>();
@ -47,7 +46,6 @@ TEST(Timer, StartAndStop) {
ASSERT_TRUE(checkTimerRepeatEvent);
}
TEST(Timer, Again) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::TimerHandle>();
@ -92,7 +90,6 @@ TEST(Timer, Again) {
ASSERT_TRUE(checkTimerEvent);
}
TEST(Timer, Repeat) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::TimerHandle>();
@ -106,7 +103,6 @@ TEST(Timer, Repeat) {
loop->run();
}
TEST(Timer, Fake) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::TimerHandle>();
@ -123,16 +119,14 @@ TEST(Timer, Fake) {
loop->run();
}
TEST(Timer, BaseHandleWalk) {
auto loop = uvw::Loop::getDefault();
auto timer = loop->resource<uvw::TimerHandle>();
timer->on<uvw::TimerEvent>([](const auto &, uvw::TimerHandle &handle) {
handle.loop().walk(uvw::Overloaded{
[](uvw::TimerHandle &h){ h.close(); },
[](auto &&){}
});
[](uvw::TimerHandle &h) { h.close(); },
[](auto &&) {}});
});
timer->start(uvw::TimerHandle::Time{100}, uvw::TimerHandle::Time{100});

View File

@ -2,7 +2,6 @@
#include <uvw/timer.h>
#include <uvw/tty.h>
TEST(TTY, Functionalities) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::TTYHandle>(uvw::StdOUT, false);
@ -10,13 +9,13 @@ TEST(TTY, Functionalities) {
bool checkWriteEvent = false;
handle->on<uvw::WriteEvent>([&checkWriteEvent](const auto &, auto &hndl){
handle->on<uvw::WriteEvent>([&checkWriteEvent](const auto &, auto &hndl) {
ASSERT_FALSE(checkWriteEvent);
checkWriteEvent = true;
hndl.close();
});
timer->on<uvw::TimerEvent>([handle](const auto &, auto &hndl){
timer->on<uvw::TimerEvent>([handle](const auto &, auto &hndl) {
auto data = std::make_unique<char[]>('*');
handle->write(std::move(data), 1);
hndl.close();

View File

@ -1,7 +1,6 @@
#include <gtest/gtest.h>
#include <uvw/udp.h>
TEST(UDP, Functionalities) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::UDPHandle>();
@ -20,7 +19,6 @@ TEST(UDP, Functionalities) {
loop->run();
}
TEST(UDP, BindRecvStop) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;
@ -38,7 +36,6 @@ TEST(UDP, BindRecvStop) {
loop->run();
}
TEST(UDP, ReadTrySend) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;
@ -55,21 +52,20 @@ TEST(UDP, ReadTrySend) {
handle.close();
});
server->bind(uvw::Addr{ address, port });
server->bind(uvw::Addr{address, port});
server->recv();
auto dataTrySend = std::unique_ptr<char[]>(new char[1]{ 'a' });
auto dataTrySend = std::unique_ptr<char[]>(new char[1]{'a'});
client->trySend(uvw::Addr{ address, port }, dataTrySend.get(), 1);
client->trySend(uvw::Addr{address, port}, dataTrySend.get(), 1);
client->trySend(address, port, nullptr, 0);
client->trySend(uvw::Addr{ address, port }, std::move(dataTrySend), 1);
client->trySend(uvw::Addr{address, port}, std::move(dataTrySend), 1);
client->trySend(address, port, std::unique_ptr<char[]>{}, 0);
loop->run();
}
TEST(UDP, ReadSend) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;
@ -92,18 +88,17 @@ TEST(UDP, ReadSend) {
server->bind(address, port);
server->recv();
auto dataSend = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' });
auto dataSend = std::unique_ptr<char[]>(new char[2]{'b', 'c'});
client->send(uvw::Addr{ address , port }, dataSend.get(), 2);
client->send(uvw::Addr{address, port}, dataSend.get(), 2);
client->send(address, port, nullptr, 0);
client->send(uvw::Addr{ address , port }, std::move(dataSend), 2);
client->send(uvw::Addr{address, port}, std::move(dataSend), 2);
client->send(address, port, std::unique_ptr<char[]>{}, 0);
loop->run();
}
TEST(UDP, Sock) {
const std::string address = std::string{"127.0.0.1"};
const unsigned int port = 4242;

View File

@ -2,7 +2,6 @@
#include <uvw/async.h>
#include <uvw/underlying_type.hpp>
TEST(UnderlyingType, Functionalities) {
auto loop = uvw::Loop::getDefault();
auto handle = uvw::AsyncHandle::create(loop);

View File

@ -1,14 +1,18 @@
#include <memory>
#include <cstdlib>
#include <memory>
#include <gtest/gtest.h>
#include <uvw.hpp>
template<typename T>
struct tag { using type = T; };
TEST(Util, UnscopedFlags) {
enum class UnscopedEnum { FOO = 1, BAR = 2, BAZ = 4, QUUX = 8 };
enum class UnscopedEnum {
FOO = 1,
BAR = 2,
BAZ = 4,
QUUX = 8
};
uvw::Flags<UnscopedEnum> flags{};
@ -38,9 +42,13 @@ TEST(Util, UnscopedFlags) {
ASSERT_TRUE(flags & uvw::Flags<UnscopedEnum>::from<UnscopedEnum::QUUX>());
}
TEST(Util, ScopedFlags) {
enum class ScopedEnum { FOO = 1, BAR = 2, BAZ = 4, QUUX = 8 };
enum class ScopedEnum {
FOO = 1,
BAR = 2,
BAZ = 4,
QUUX = 8
};
uvw::Flags<ScopedEnum> flags{};
@ -70,7 +78,6 @@ TEST(Util, ScopedFlags) {
ASSERT_TRUE(flags & uvw::Flags<ScopedEnum>::from<ScopedEnum::QUUX>());
}
TEST(Util, Utilities) {
ASSERT_EQ(uvw::PidType{}, uvw::PidType{});
@ -141,8 +148,7 @@ TEST(Util, Utilities) {
[](size_t size) { return malloc(size); },
[](void *ptr, size_t size) { return realloc(ptr, size); },
[](size_t num, size_t size) { return calloc(num, size); },
[](void *ptr) { return free(ptr); }
));
[](void *ptr) { return free(ptr); }));
ASSERT_NO_THROW(uvw::Utilities::loadAverage());
ASSERT_NE(uvw::Utilities::totalMemory(), decltype(uvw::Utilities::totalMemory()){0});
@ -153,7 +159,7 @@ TEST(Util, Utilities) {
ASSERT_FALSE(uvw::Utilities::cwd().empty());
ASSERT_TRUE(uvw::Utilities::chdir(uvw::Utilities::cwd()));
std::unique_ptr<char[], void(*)(void *)> fake{new char[1], [](void *ptr) { delete[] static_cast<char *>(ptr); }};
std::unique_ptr<char[], void (*)(void *)> fake{new char[1], [](void *ptr) { delete[] static_cast<char *>(ptr); }};
char *argv = fake.get();
argv[0] = '\0';

View File

@ -3,7 +3,6 @@
#include <uvw/timer.h>
#include <uvw/work.h>
TEST(Work, RunTask) {
auto loop = uvw::Loop::getDefault();
auto handle = loop->resource<uvw::CheckHandle>();