powerd++  0.4.4
utility.hpp
Go to the documentation of this file.
1 
7 #include <type_traits> /* std::underlying_type */
8 #include <charconv> /* std::from_chars() */
9 #include <cctype> /* std::isspace() */
10 #include <string>
11 
12 #include <cstdio> /* snprintf() */
13 
14 #ifndef _POWERDXX_UTILITY_HPP_
15 #define _POWERDXX_UTILITY_HPP_
16 
20 namespace utility {
21 
31 template <typename T, size_t Count>
32 constexpr size_t countof(T (&)[Count]) { return Count; }
33 
42 template <typename... Args>
43 inline void sprintf(Args...) {
44  /* Assert depends on Args so it can only be determined if
45  * the function is actually instantiated. */
46  static_assert(sizeof...(Args) && false,
47  "Use of sprintf() is unsafe, use sprintf_safe() instead");
48 }
49 
68 template <size_t Size, typename... Args>
69 inline int sprintf_safe(char (& dst)[Size], char const * const format,
70  Args const... args) {
71  return snprintf(dst, Size, format, args...);
72 }
73 
84 template <class ET, typename VT = typename std::underlying_type<ET>::type>
85 constexpr VT to_value(ET const op) {
86  return static_cast<VT>(op);
87 }
88 
105 template <size_t BufSize>
106 class Formatter {
107  private:
111  char const * const fmt;
112 
113  public:
117  constexpr Formatter(char const * const fmt) : fmt{fmt} {}
118 
129  template <typename... ArgTs>
130  std::string operator ()(ArgTs const &... args) const {
131  char buf[BufSize];
132  auto count = sprintf_safe(buf, this->fmt, args...);
133  if (count < 0) {
134  /* encoding error */
135  return {};
136  } else if (static_cast<size_t>(count) >= BufSize) {
137  /* does not fit into buffer */
138  return {buf, BufSize - 1};
139  }
140  return {buf, static_cast<size_t>(count)};
141  }
142 };
143 
147 namespace literals {
156 constexpr Formatter<16384> operator "" _fmt(char const * const fmt, size_t const) {
157  return {fmt};
158 }
159 } /* namespace literals */
160 
167 template <typename T>
168 class Sum {
169  private:
173  T value;
174 
175  public:
182  explicit constexpr Sum(T const & value) : value{value} {}
183 
187  constexpr Sum() : Sum{0} {}
188 
195  constexpr operator T const &() const {
196  return this->value;
197  }
198 
207  constexpr Sum & operator +=(T const & value) {
208  this->value += value;
209  return *this;
210  }
211 };
212 
219 template <typename T>
220 class Min {
221  private:
225  T value;
226 
227  public:
234  explicit constexpr Min(T const & value) : value{value} {}
235 
242  constexpr operator T const &() const {
243  return this->value;
244  }
245 
254  constexpr Min & operator =(T const & value) {
255  this->value = this->value <= value ? this->value : value;
256  return *this;
257  }
258 };
259 
266 template <typename T>
267 class Max {
268  private:
272  T value;
273 
274  public:
281  explicit constexpr Max(T const & value) : value{value} {}
282 
289  constexpr operator T const &() const {
290  return this->value;
291  }
292 
301  constexpr Max & operator =(T const & value) {
302  this->value = this->value >= value ? this->value : value;
303  return *this;
304  }
305 };
306 
311 struct FromChars {
315  char const * it;
316 
322  char const * const end;
323 
343  template <typename T>
344  [[nodiscard]] bool operator ()(T & dst) {
345  if (!this->it) {
346  return false;
347  }
348  auto [p, ec] = std::from_chars(this->it, this->end, dst);
349  if (this->it == p) {
350  return false;
351  }
352  for (; p != this->end && std::isspace(*p); ++p);
353  this->it = p;
354  return true;
355  }
356 
365  operator bool() const {
366  return this->it && this->end != this->it && *this->it;
367  }
368 
375  FromChars(char const * const start, char const * const end) :
376  it{start}, end{end} {
377  for (; this->it != end && std::isspace(*this->it); ++this->it);
378  }
379 
391  template <size_t CountV>
392  FromChars(char const (& str)[CountV], bool const terminator = true) :
393  FromChars{str, str + CountV - terminator} {}
394 
405  FromChars(std::string const & str) :
406  FromChars{str.data(), str.data() + str.size()} {}
407 };
408 
415 struct Underlined {
419  std::string text;
420 
424  std::string line;
425 
431  operator std::string() const {
432  return this->text + '\n' + this->line;
433  }
434 };
435 
460 Underlined highlight(std::string const & str, ptrdiff_t const offs,
461  ptrdiff_t const len = 1);
462 
463 } /* namespace utility */
464 
465 #endif /* _POWERDXX_UTILITY_HPP_ */
utility::Underlined::line
std::string line
Aligned underlining characters ^~~~.
Definition: utility.hpp:424
utility::Formatter
A formatting wrapper around string literals.
Definition: utility.hpp:106
utility::FromChars::FromChars
FromChars(std::string const &str)
Construct functor from a string.
Definition: utility.hpp:405
utility::Max
A simple value container that provides the maximum of assigned values.
Definition: utility.hpp:267
utility
A collection of generally useful functions.
Definition: utility.hpp:20
utility::sprintf
void sprintf(Args...)
This is a safeguard against accidentally using sprintf().
Definition: utility.hpp:43
utility::Max::Max
constexpr Max(T const &value)
Construct from an initial value.
Definition: utility.hpp:281
utility::countof
constexpr size_t countof(T(&)[Count])
Like sizeof(), but it returns the number of elements an array consists of instead of the number of by...
Definition: utility.hpp:32
utility::highlight
Underlined highlight(std::string const &str, ptrdiff_t const offs, ptrdiff_t const len=1)
Underline the given number of characters.
Definition: utility.cpp:12
utility::Sum::value
T value
The sum of values accumulated.
Definition: utility.hpp:173
utility::FromChars::operator()
bool operator()(T &dst)
Retrieve an integral or floating point value from the array.
Definition: utility.hpp:344
utility::to_value
constexpr VT to_value(ET const op)
Casts an enum to its underlying value.
Definition: utility.hpp:85
utility::Min::operator=
constexpr Min & operator=(T const &value)
Assign a new value, if it is less than the current value.
Definition: utility.hpp:254
utility::Sum::operator+=
constexpr Sum & operator+=(T const &value)
Add a value to the sum.
Definition: utility.hpp:207
utility::Max::operator=
constexpr Max & operator=(T const &value)
Assign a new value, if it is greater than the current value.
Definition: utility.hpp:301
utility::Min::value
T value
The minimum of the assigned values.
Definition: utility.hpp:225
utility::Underlined
A line of text and an underlining line.
Definition: utility.hpp:415
utility::FromChars::it
const char * it
The next character to read.
Definition: utility.hpp:315
utility::Underlined::text
std::string text
The text with printf-style escapes.
Definition: utility.hpp:419
utility::Sum
A simple value container only allowing += and copy assignment.
Definition: utility.hpp:168
utility::Sum::Sum
constexpr Sum()
Default construct.
Definition: utility.hpp:187
utility::FromChars::end
const char *const end
The first character of the same array that may not be read, this should usually point to a terminatin...
Definition: utility.hpp:322
utility::Formatter::operator()
std::string operator()(ArgTs const &... args) const
Returns a formatted string.
Definition: utility.hpp:130
utility::Sum::Sum
constexpr Sum(T const &value)
Construct from an initial value.
Definition: utility.hpp:182
utility::FromChars::FromChars
FromChars(char const *const start, char const *const end)
Range based constructor.
Definition: utility.hpp:375
utility::Formatter::fmt
const char *const fmt
Pointer to the string literal.
Definition: utility.hpp:111
utility::FromChars::FromChars
FromChars(char const (&str)[CountV], bool const terminator=true)
Construct from a character array.
Definition: utility.hpp:392
utility::Min::Min
constexpr Min(T const &value)
Construct from an initial value.
Definition: utility.hpp:234
utility::Max::value
T value
The maximum of the assigned values.
Definition: utility.hpp:272
utility::sprintf_safe
int sprintf_safe(char(&dst)[Size], char const *const format, Args const ... args)
A wrapper around snprintf() that automatically pulls in the destination buffer size.
Definition: utility.hpp:69
utility::Formatter::Formatter
constexpr Formatter(char const *const fmt)
Construct from string literal.
Definition: utility.hpp:117
utility::Min
A simple value container that provides the minimum of assigned values.
Definition: utility.hpp:220
utility::FromChars
A functor for reading numerical values from a string or character array.
Definition: utility.hpp:311