Motion Master 6.0.0-alpha.50
Next-generation motion control software
Loading...
Searching...
No Matches
util.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <bit>
6#include <charconv>
7#include <cstddef>
8#include <cstdint>
9#include <optional>
10#include <span>
11#include <string_view>
12#include <type_traits>
13
14namespace mm::core {
15
28inline bool isUrlSafeId(std::string_view s) {
29 constexpr std::size_t kMaxLength = 64;
30 if (s.empty() || s.size() > kMaxLength) {
31 return false;
32 }
33 return std::all_of(s.begin(), s.end(), [](const char c) {
34 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' ||
35 c == '_' || c == '-';
36 });
37}
38
49template <typename T>
50std::optional<T> parseHexOrDec(std::string_view s) {
51 T value{};
52 std::from_chars_result r;
53 if (s.size() >= 2 && (s[0] == '0' || s[0] == '#') && (s[1] == 'x' || s[1] == 'X')) {
54 r = std::from_chars(s.data() + 2, s.data() + s.size(), value, 16);
55 } else {
56 r = std::from_chars(s.data(), s.data() + s.size(), value);
57 }
58 if (r.ec != std::errc{} || r.ptr != s.data() + s.size()) { // NOLINT(whitespace/braces)
59 return std::nullopt;
60 }
61 return value;
62}
63
77template <typename T>
78std::array<uint8_t, sizeof(T)> toBytes(T value, std::endian order = std::endian::little) {
79 static_assert(std::is_integral_v<T>, "toBytes is for integral types");
80 using U = std::make_unsigned_t<T>;
81 const auto u = static_cast<U>(value);
82 std::array<uint8_t, sizeof(T)> out{};
83 for (std::size_t i = 0; i < sizeof(T); ++i) {
84 const std::size_t byte = (order == std::endian::little) ? i : (sizeof(T) - 1 - i);
85 out[byte] = static_cast<uint8_t>((u >> (8 * i)) & 0xFFu);
86 }
87 return out;
88}
89
101template <typename T>
102T fromBytes(std::span<const uint8_t> bytes, std::endian order = std::endian::little) {
103 static_assert(std::is_integral_v<T>, "fromBytes is for integral types");
104 using U = std::make_unsigned_t<T>;
105 U v = 0;
106 const std::size_t n = std::min(sizeof(T), bytes.size());
107 for (std::size_t i = 0; i < n; ++i) {
108 const std::size_t shift = (order == std::endian::little) ? (8 * i) : (8 * (n - 1 - i));
109 v |= static_cast<U>(bytes[i]) << shift;
110 }
111 return static_cast<T>(v);
112}
113
114} // namespace mm::core
Definition cyclic_timer.h:6
std::optional< T > parseHexOrDec(std::string_view s)
Parses an unsigned integer from a string in decimal or hexadecimal notation.
Definition util.h:50
std::array< uint8_t, sizeof(T)> toBytes(T value, std::endian order=std::endian::little)
Encodes an integer into a fixed-width byte array in the given byte order.
Definition util.h:78
bool isUrlSafeId(std::string_view s)
Whether s is a valid URL-safe identifier usable as a path segment and pub/sub topic.
Definition util.h:28
T fromBytes(std::span< const uint8_t > bytes, std::endian order=std::endian::little)
Decodes an integer from a raw byte buffer interpreted in the given byte order.
Definition util.h:102