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