uvw  2.12.1
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 
14 namespace uvw {
15 
16 namespace details {
17 
18 enum 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 
39 template<typename T>
40 struct 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 
57 private:
58  const Type value;
59 };
60 
61 template<typename T>
62 bool operator==(UVTypeWrapper<T> lhs, UVTypeWrapper<T> rhs) {
63  return !(lhs == rhs);
64 }
65 
66 } // namespace details
67 
78 template<typename E>
79 class 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 
88 public:
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 
189 private:
190  InnerType flags;
191 };
192 
196 struct WinSize {
197  int width;
198  int height;
199 };
200 
201 using HandleType = details::UVHandleType;
203 using HandleCategory = details::UVTypeWrapper<uv_handle_type>;
204 using FileHandle = details::UVTypeWrapper<uv_file>;
205 using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>;
206 using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>;
207 using PidType = details::UVTypeWrapper<uv_pid_t>;
209 constexpr FileHandle StdIN{0};
210 constexpr FileHandle StdOUT{1};
211 constexpr FileHandle StdERR{2};
213 using TimeSpec = uv_timespec_t;
214 using Stat = uv_stat_t;
215 using Statfs = uv_statfs_t;
216 using Uid = uv_uid_t;
217 using Gid = uv_gid_t;
219 using TimeVal = uv_timeval_t;
220 using TimeVal64 = uv_timeval64_t;
221 using RUsage = uv_rusage_t;
231 struct 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 
270 private:
271  std::shared_ptr<uv_passwd_t> passwd;
272 };
273 
283 struct 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 
310 private:
311  std::shared_ptr<uv_utsname_t> utsname;
312 };
313 
319 struct IPv4 {};
320 
326 struct IPv6 {};
327 
331 struct Addr {
332  std::string ip;
333  unsigned int port;
334 };
335 
339 struct 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 
365 namespace details {
366 
367 static constexpr std::size_t DEFAULT_SIZE = 128;
368 
369 template<typename>
370 struct IpTraits;
371 
372 template<>
373 struct 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 
386 template<>
387 struct 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 
400 template<typename I>
401 Addr 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 
415 template<typename I, typename F, typename H>
416 Addr 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 
431 template<typename F, typename... Args>
432 std::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 
459 struct 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 
840 template<class... Func>
841 struct Overloaded: Func... {
842  using Func::operator()...;
843 };
844 
849 template<class... Func>
850 Overloaded(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
static constexpr Flags< E > from()
Utility factory method to pack a set of values all at once.
Definition: util.h:96
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
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
Overloaded(Func...) -> Overloaded< Func... >
Deduction guide.
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