SlHelpers
Misc.h
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #pragma once
4 
5 #include <chrono>
6 #include <cstddef>
7 #include <iomanip>
8 #include <optional>
9 #include <sstream>
10 #include <string>
11 
12 #include "String.h"
13 
14 namespace SlHelpers {
15 
19 struct Version {
20  Version() = delete;
21 
23  static auto versionSplit(std::string_view version) noexcept {
24  return String::splitSV(version, ".-");
25  }
26 
28  static unsigned versionPart(std::string_view version, bool rc = false) noexcept {
29  if (rc && version.starts_with("rc"))
30  version.remove_prefix(2);
31  if (const auto verPart = String::toNum(version))
32  return *verPart;
33  return 0;
34  }
35 
41  static unsigned versionSum(std::string_view version) noexcept {
42  const auto arr = Version::versionSplit(version);
43  unsigned ret = 0;
44  for (auto i = 0U; i < 3; ++i) {
45  ret <<= 8;
46  if (i < arr.size())
47  ret += Version::versionPart(arr[i], i == 2);
48  }
49  return ret;
50  }
51 
52 };
53 
57 struct CmpVersions {
64  bool operator()(std::string_view ver1, std::string_view ver2) const noexcept
65  {
66  const auto arr1 = Version::versionSplit(ver1);
67  const auto arr2 = Version::versionSplit(ver2);
68  for (auto i = 0U; i < 2U; ++i) {
69  auto ver1 = Version::versionPart(arr1[i]);
70  auto ver2 = Version::versionPart(arr2[i]);
71  if (ver1 != ver2)
72  return ver1 < ver2;
73  const auto arr1Last = arr1.size() == i + 1;
74  const auto arr2Last = arr2.size() == i + 1;
75  if (arr1Last && arr2Last)
76  return false;
77  if (arr1Last || arr2Last)
78  return arr1Last;
79  }
80 
81  return Version::versionPart(arr1[2], true) < Version::versionPart(arr2[2], true);
82  }
83 };
84 
88 struct Env {
94  template <typename T = std::string>
95  static std::optional<T> get(const std::string &name) noexcept {
96  if (const auto env = std::getenv(name.c_str()))
97  return env;
98  return std::nullopt;
99  }
100 };
101 
105 template <typename Rep = double, typename Period = std::milli>
106 class Measure {
107  using Clock = std::chrono::steady_clock;
108  using TimePoint = Clock::time_point;
109  using Dur = std::chrono::duration<Rep, Period>;
110 public:
111  Measure() noexcept : m_start(Clock::now()) {}
112 
114  void reset(TimePoint point = Clock::now()) noexcept { m_start = point; }
115 
117  Dur elapsed() const noexcept {
118  return std::chrono::duration_cast<Dur>(Clock::now() - m_start);
119  }
120 
122  Dur lap() noexcept {
123  auto now = Clock::now();
124  auto ret = std::chrono::duration_cast<Dur>(now - m_start);
125  reset(now);
126  return ret;
127  }
128 
130  template <typename Func, typename... Args>
131  static Dur profile(Func &&func, Args&&... args) {
132  Measure m;
133  std::forward<Func>(func)(std::forward<Args>(args)...);
134  return m.elapsed();
135  }
136 private:
137  TimePoint m_start;
138 };
139 
143 struct Unit {
151  static std::string human(const size_t bytes, const unsigned precision = 2,
152  const bool fixed = true) noexcept {
153  static constexpr const std::string_view units[] {
154  "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"
155  };
156 
157  auto unit = 0U;
158  auto bytesD = static_cast<double>(bytes);
159  while (bytesD >= 1024.) {
160  bytesD /= 1024.;
161  unit++;
162  }
163 
164  std::ostringstream s;
165  if (fixed)
166  s << std::fixed << std::setprecision(precision);
167  s << bytesD << ' ' << units[unit];
168  return s.str();
169  }
170 };
171 
172 }
static std::vector< std::string_view > splitSV(std::string_view str, std::string_view delim, std::optional< char > comment=std::nullopt) noexcept
Split str by delim into a vector, ignoring everything after comment.
Definition: String.h:128
requires static std::is_integral_v< I > std::optional< I > toNum(std::string_view str, int base=10) noexcept
Convert str to a number.
Definition: String.h:67
A helper for environment variables.
Definition: Misc.h:88
void reset(TimePoint point=Clock::now()) noexcept
Reset to count from point (or now)
Definition: Misc.h:114
Dur elapsed() const noexcept
Returns the duration it took from the construction (or last reset())
Definition: Misc.h:117
Parse a version string into numbers.
Definition: Misc.h:19
static unsigned versionSum(std::string_view version) noexcept
Sum up version parts as parsed from version.
Definition: Misc.h:41
bool operator()(std::string_view ver1, std::string_view ver2) const noexcept
Comparator for versions ver1 and ver2.
Definition: Misc.h:64
Compare versions, to be used as Compare in containers.
Definition: Misc.h:57
static auto versionSplit(std::string_view version) noexcept
Split version into a string array.
Definition: Misc.h:23
static Dur profile(Func &&func, Args &&... args)
Run func with args and return how long it took.
Definition: Misc.h:131
static std::string human(const size_t bytes, const unsigned precision=2, const bool fixed=true) noexcept
Convert bytes into human readable form (1 Kib, 20.5 MiB, ...)
Definition: Misc.h:151
Measure elapsed times.
Definition: Misc.h:106
A helper to convert units.
Definition: Misc.h:143
Dur lap() noexcept
Returns the duration it took from the construction (or last reset()) and reset.
Definition: Misc.h:122
static unsigned versionPart(std::string_view version, bool rc=false) noexcept
Convert version into a number.
Definition: Misc.h:28
Definition: Color.h:8