uvw 2.12.1
Loading...
Searching...
No Matches
util.h
1#ifndef UVW_UTIL_INCLUDE_H
2#define UVW_UTIL_INCLUDE_H
3
4#include <array>
5#include <cstddef>
6#include <memory>
7#include <string>
8#include <string_view>
9#include <type_traits>
10#include <utility>
11#include <vector>
12#include <uv.h>
13
14namespace uvw {
15
16namespace details {
17
18enum class UVHandleType : std::underlying_type_t<uv_handle_type> {
19 UNKNOWN = UV_UNKNOWN_HANDLE,
20 ASYNC = UV_ASYNC,
21 CHECK = UV_CHECK,
22 FS_EVENT = UV_FS_EVENT,
23 FS_POLL = UV_FS_POLL,
24 HANDLE = UV_HANDLE,
25 IDLE = UV_IDLE,
26 PIPE = UV_NAMED_PIPE,
27 POLL = UV_POLL,
28 PREPARE = UV_PREPARE,
29 PROCESS = UV_PROCESS,
30 STREAM = UV_STREAM,
31 TCP = UV_TCP,
32 TIMER = UV_TIMER,
33 TTY = UV_TTY,
34 UDP = UV_UDP,
35 SIGNAL = UV_SIGNAL,
36 FILE = UV_FILE
37};
38
39template<typename T>
40struct UVTypeWrapper {
41 using Type = T;
42
43 constexpr UVTypeWrapper()
44 : value{} {}
45
46 constexpr UVTypeWrapper(Type val)
47 : value{val} {}
48
49 constexpr operator Type() const noexcept {
50 return value;
51 }
52
53 bool operator==(UVTypeWrapper other) const noexcept {
54 return value == other.value;
55 }
56
57private:
58 const Type value;
59};
60
61template<typename T>
62bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
63 return !(lhs == rhs);
64}
65
66} // namespace details
67
78template<typename E>
79class Flags final {
80 static_assert(std::is_enum_v<E>);
81
82 using InnerType = std::underlying_type_t<E>;
83
84 constexpr InnerType toInnerType(E flag) const noexcept {
85 return static_cast<InnerType>(flag);
86 }
87
88public:
89 using Type = InnerType;
90
95 template<E... V>
96 static constexpr Flags<E> from() {
97 return (Flags<E>{} | ... | V);
98 }
99
104 constexpr Flags(E flag) noexcept
105 : flags{toInnerType(flag)} {}
106
112 constexpr Flags(Type f)
113 : flags{f} {}
114
118 constexpr Flags()
119 : flags{} {}
120
121 constexpr Flags(const Flags &f) noexcept
122 : flags{f.flags} {}
123
124 constexpr Flags(Flags &&f) noexcept
125 : flags{std::move(f.flags)} {}
126
127 constexpr Flags &operator=(const Flags &f) noexcept {
128 flags = f.flags;
129 return *this;
130 }
131
132 constexpr Flags &operator=(Flags &&f) noexcept {
133 flags = std::move(f.flags);
134 return *this;
135 }
136
142 constexpr Flags operator|(const Flags &f) const noexcept {
143 return Flags{flags | f.flags};
144 }
145
151 constexpr Flags operator|(E flag) const noexcept {
152 return Flags{flags | toInnerType(flag)};
153 }
154
160 constexpr Flags operator&(const Flags &f) const noexcept {
161 return Flags{flags & f.flags};
162 }
163
169 constexpr Flags operator&(E flag) const noexcept {
170 return Flags{flags & toInnerType(flag)};
171 }
172
177 explicit constexpr operator bool() const noexcept {
178 return !(flags == InnerType{});
179 }
180
185 constexpr operator Type() const noexcept {
186 return flags;
187 }
188
189private:
190 InnerType flags;
191};
192
196struct WinSize {
197 int width;
198 int height;
199};
200
201using HandleType = details::UVHandleType;
203using HandleCategory = details::UVTypeWrapper<uv_handle_type>;
204using FileHandle = details::UVTypeWrapper<uv_file>;
205using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>;
206using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>;
207using PidType = details::UVTypeWrapper<uv_pid_t>;
209constexpr FileHandle StdIN{0};
210constexpr FileHandle StdOUT{1};
211constexpr FileHandle StdERR{2};
213using TimeSpec = uv_timespec_t;
214using Stat = uv_stat_t;
215using Statfs = uv_statfs_t;
216using Uid = uv_uid_t;
217using Gid = uv_gid_t;
219using TimeVal = uv_timeval_t;
220using TimeVal64 = uv_timeval64_t;
221using RUsage = uv_rusage_t;
231struct Passwd {
232 Passwd(std::shared_ptr<uv_passwd_t> pwd);
233
238 std::string username() const noexcept;
239
244 decltype(uv_passwd_t::uid) uid() const noexcept;
245
250 decltype(uv_passwd_t::gid) gid() const noexcept;
251
256 std::string shell() const noexcept;
257
262 std::string homedir() const noexcept;
263
268 operator bool() const noexcept;
269
270private:
271 std::shared_ptr<uv_passwd_t> passwd;
272};
273
283struct UtsName {
284 UtsName(std::shared_ptr<uv_utsname_t> utsname);
285
290 std::string sysname() const noexcept;
291
296 std::string release() const noexcept;
297
302 std::string version() const noexcept;
303
308 std::string machine() const noexcept;
309
310private:
311 std::shared_ptr<uv_utsname_t> utsname;
312};
313
319struct IPv4 {};
320
326struct IPv6 {};
327
331struct Addr {
332 std::string ip;
333 unsigned int port;
334};
335
339struct CPUInfo {
340 using CPUTime = decltype(uv_cpu_info_t::cpu_times);
341
342 std::string model;
343 int speed;
351 CPUTime times;
352};
353
358 std::string name;
359 char physical[6];
360 bool internal;
363};
364
365namespace details {
366
367static constexpr std::size_t DEFAULT_SIZE = 128;
368
369template<typename>
370struct IpTraits;
371
372template<>
373struct IpTraits<IPv4> {
374 using Type = sockaddr_in;
375 using AddrFuncType = int (*)(const char *, int, Type *);
376 using NameFuncType = int (*)(const Type *, char *, std::size_t);
377
378 inline static const AddrFuncType addrFunc = &uv_ip4_addr;
379 inline static const NameFuncType nameFunc = &uv_ip4_name;
380
381 static constexpr auto sinPort(const Type *addr) {
382 return addr->sin_port;
383 }
384};
385
386template<>
387struct IpTraits<IPv6> {
388 using Type = sockaddr_in6;
389 using AddrFuncType = int (*)(const char *, int, Type *);
390 using NameFuncType = int (*)(const Type *, char *, std::size_t);
391
392 inline static const AddrFuncType addrFunc = &uv_ip6_addr;
393 inline static const NameFuncType nameFunc = &uv_ip6_name;
394
395 static constexpr auto sinPort(const Type *addr) {
396 return addr->sin6_port;
397 }
398};
399
400template<typename I>
401Addr address(const typename details::IpTraits<I>::Type *aptr) noexcept {
402 Addr addr{};
403 char name[DEFAULT_SIZE];
404
405 int err = details::IpTraits<I>::nameFunc(aptr, name, DEFAULT_SIZE);
406
407 if(0 == err) {
408 addr.port = ntohs(details::IpTraits<I>::sinPort(aptr));
409 addr.ip = std::string{name};
410 }
411
412 return addr;
413}
414
415template<typename I, typename F, typename H>
416Addr address(F &&f, const H *handle) noexcept {
417 sockaddr_storage ssto;
418 int len = sizeof(ssto);
419 Addr addr{};
420
421 int err = std::forward<F>(f)(handle, reinterpret_cast<sockaddr *>(&ssto), &len);
422
423 if(0 == err) {
424 typename IpTraits<I>::Type *aptr = reinterpret_cast<typename IpTraits<I>::Type *>(&ssto);
425 addr = address<I>(aptr);
426 }
427
428 return addr;
429}
430
431template<typename F, typename... Args>
432std::string tryRead(F &&f, Args &&...args) noexcept {
433 std::size_t size = DEFAULT_SIZE;
434 char buf[DEFAULT_SIZE];
435 std::string str{};
436 auto err = std::forward<F>(f)(args..., buf, &size);
437
438 if(UV_ENOBUFS == err) {
439 std::unique_ptr<char[]> data{new char[size]};
440 err = std::forward<F>(f)(args..., data.get(), &size);
441
442 if(0 == err) {
443 str = data.get();
444 }
445 } else if(0 == err) {
446 str.assign(buf, size);
447 }
448
449 return str;
450}
451
452} // namespace details
453
459struct Utilities {
460 using MallocFuncType = void *(*)(size_t);
461 using ReallocFuncType = void *(*)(void *, size_t);
462 using CallocFuncType = void *(*)(size_t, size_t);
463 using FreeFuncType = void (*)(void *);
464
468 struct OS {
478 static PidType pid() noexcept;
479
489 static PidType parent() noexcept;
490
501 static std::string homedir() noexcept;
502
512 static std::string tmpdir() noexcept;
513
520 static std::string env(const std::string &name) noexcept;
521
529 static bool env(const std::string &name, const std::string &value) noexcept;
530
544 template<typename Func>
545 static std::enable_if_t<std::is_invocable_v<Func, std::string_view, std::string_view>, bool>
546 env(Func func) noexcept {
547 uv_env_item_t *items = nullptr;
548 int count{};
549
550 const bool ret = (uv_os_environ(&items, &count) == 0);
551
552 if(ret) {
553 for(int pos = 0; pos < count; ++pos) {
554 func(std::string_view{items[pos].name}, std::string_view{items[pos].value});
555 }
556
557 uv_os_free_environ(items, count);
558 }
559
560 return ret;
561 }
562
567 static std::string hostname() noexcept;
568
578 static UtsName uname() noexcept;
579
592 static Passwd passwd() noexcept;
593
607 static int priority(PidType pid);
608
624 static bool priority(PidType pid, int prio);
625 };
626
632 static HandleType guessHandle(HandleCategory category) noexcept;
633
652 static HandleType guessHandle(FileHandle file) noexcept;
653
661 static std::vector<CPUInfo> cpuInfo() noexcept;
662
671 static std::vector<InterfaceAddress> interfaceAddresses() noexcept;
672
686 static std::string indexToName(unsigned int index) noexcept;
687
698 static std::string indexToIid(unsigned int index) noexcept;
699
723 static bool replaceAllocator(MallocFuncType mallocFunc, ReallocFuncType reallocFunc, CallocFuncType callocFunc, FreeFuncType freeFunc) noexcept;
724
729 static std::array<double, 3> loadAverage() noexcept;
730
738 static char **setupArgs(int argc, char **argv);
739
744 static std::string processTitle();
745
751 static bool processTitle(const std::string &title);
752
757 static uint64_t totalMemory() noexcept;
758
770 static uint64_t constrainedMemory() noexcept;
771
776 static double uptime() noexcept;
777
782 static RUsage rusage() noexcept;
783
794 static uint64_t hrtime() noexcept;
795
800 static std::string path() noexcept;
801
806 static std::string cwd() noexcept;
807
813 static bool chdir(const std::string &dir) noexcept;
814
820 static TimeVal64 timeOfDay() noexcept;
821
826 static void sleep(unsigned int msec) noexcept;
827
833 static unsigned int availableParallelism() noexcept;
834};
835
840template<class... Func>
841struct Overloaded: Func... {
842 using Func::operator()...;
843};
844
849template<class... Func>
850Overloaded(Func...) -> Overloaded<Func...>;
851
852} // namespace uvw
853
854#ifndef UVW_AS_LIB
855# include "util.cpp"
856#endif
857
858#endif // UVW_UTIL_INCLUDE_H
Utility class to handle flags.
Definition: util.h:79
constexpr Flags()
Constructs an uninitialized Flags object.
Definition: util.h:118
constexpr Flags operator|(const Flags &f) const noexcept
Or operator.
Definition: util.h:142
constexpr Flags(Type f)
Constructs a Flags object from an instance of the underlying type of the enum E.
Definition: util.h:112
constexpr Flags operator|(E flag) const noexcept
Or operator.
Definition: util.h:151
constexpr Flags operator&(const Flags &f) const noexcept
And operator.
Definition: util.h:160
static constexpr Flags< E > from()
Utility factory method to pack a set of values all at once.
Definition: util.h:96
constexpr Flags(E flag) noexcept
Constructs a Flags object from a value of the enum E.
Definition: util.h:104
constexpr Flags operator&(E flag) const noexcept
And operator.
Definition: util.h:169
uvw default namespace.
Definition: async.h:8
uv_uid_t Uid
Definition: util.h:216
details::UVTypeWrapper< uv_file > FileHandle
Definition: util.h:204
uv_statfs_t Statfs
Definition: util.h:215
details::UVTypeWrapper< uv_os_sock_t > OSSocketHandle
Definition: util.h:205
constexpr FileHandle StdIN
Definition: util.h:209
uv_timespec_t TimeSpec
Definition: util.h:213
uv_timeval_t TimeVal
Definition: util.h:219
uv_gid_t Gid
Definition: util.h:217
constexpr FileHandle StdOUT
Definition: util.h:210
uv_rusage_t RUsage
Definition: util.h:221
details::UVTypeWrapper< uv_handle_type > HandleCategory
Definition: util.h:203
details::UVTypeWrapper< uv_pid_t > PidType
Definition: util.h:207
constexpr FileHandle StdERR
Definition: util.h:211
uv_stat_t Stat
Definition: util.h:214
details::UVTypeWrapper< uv_os_fd_t > OSFileDescriptor
Definition: util.h:206
uv_timeval64_t TimeVal64
Definition: util.h:220
Address representation.
Definition: util.h:331
unsigned int port
Definition: util.h:333
std::string ip
Definition: util.h:332
CPU information.
Definition: util.h:339
CPUTime times
CPU times.
Definition: util.h:351
std::string model
Definition: util.h:342
int speed
Definition: util.h:343
The IPv4 tag.
Definition: util.h:319
The IPv6 tag.
Definition: util.h:326
Interface address.
Definition: util.h:357
std::string name
Definition: util.h:358
Helper type for visitors.
Definition: util.h:841
Utility class.
Definition: util.h:231
std::string homedir() const noexcept
Gets the homedir.
std::string username() const noexcept
Gets the username.
decltype(uv_passwd_t::gid) gid() const noexcept
Gets the gid.
decltype(uv_passwd_t::uid) uid() const noexcept
Gets the uid.
std::string shell() const noexcept
Gets the shell.
OS dedicated utilities.
Definition: util.h:468
static std::string hostname() noexcept
Returns the hostname.
static PidType pid() noexcept
Returns the current process id.
Miscellaneous utilities.
Definition: util.h:459
Utility class.
Definition: util.h:283
std::string sysname() const noexcept
Gets the operating system name (like "Linux").
Windows size representation.
Definition: util.h:196
int height
Definition: util.h:198
int width
Definition: util.h:197