summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/alignment.h37
-rw-r--r--src/common/lz4_compression.cpp6
-rw-r--r--src/common/lz4_compression.h2
3 files changed, 41 insertions, 4 deletions
diff --git a/src/common/alignment.h b/src/common/alignment.h
index fa715d497..fc5c26898 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -3,6 +3,7 @@
#pragma once
+#include <bit>
#include <cstddef>
#include <new>
#include <type_traits>
@@ -10,8 +11,10 @@
namespace Common {
template <typename T>
- requires std::is_unsigned_v<T>
-[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
+ requires std::is_integral_v<T>
+[[nodiscard]] constexpr T AlignUp(T value_, size_t size) {
+ using U = typename std::make_unsigned_t<T>;
+ auto value{static_cast<U>(value_)};
auto mod{static_cast<T>(value % size)};
value -= mod;
return static_cast<T>(mod == T{0} ? value : value + size);
@@ -24,8 +27,10 @@ template <typename T>
}
template <typename T>
- requires std::is_unsigned_v<T>
-[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
+ requires std::is_integral_v<T>
+[[nodiscard]] constexpr T AlignDown(T value_, size_t size) {
+ using U = typename std::make_unsigned_t<T>;
+ const auto value{static_cast<U>(value_)};
return static_cast<T>(value - value % size);
}
@@ -55,6 +60,30 @@ template <typename T, typename U>
return (x + (y - 1)) / y;
}
+template <typename T>
+ requires std::is_integral_v<T>
+[[nodiscard]] constexpr T LeastSignificantOneBit(T x) {
+ return x & ~(x - 1);
+}
+
+template <typename T>
+ requires std::is_integral_v<T>
+[[nodiscard]] constexpr T ResetLeastSignificantOneBit(T x) {
+ return x & (x - 1);
+}
+
+template <typename T>
+ requires std::is_integral_v<T>
+[[nodiscard]] constexpr bool IsPowerOfTwo(T x) {
+ return x > 0 && ResetLeastSignificantOneBit(x) == 0;
+}
+
+template <typename T>
+ requires std::is_integral_v<T>
+[[nodiscard]] constexpr T FloorPowerOfTwo(T x) {
+ return T{1} << (sizeof(T) * 8 - std::countl_zero(x) - 1);
+}
+
template <typename T, size_t Align = 16>
class AlignmentAllocator {
public:
diff --git a/src/common/lz4_compression.cpp b/src/common/lz4_compression.cpp
index ffb32fecf..d85ab1742 100644
--- a/src/common/lz4_compression.cpp
+++ b/src/common/lz4_compression.cpp
@@ -71,4 +71,10 @@ std::vector<u8> DecompressDataLZ4(std::span<const u8> compressed, std::size_t un
return uncompressed;
}
+int DecompressDataLZ4(void* dst, size_t dst_size, const void* src, size_t src_size) {
+ // This is just a thin wrapper around LZ4.
+ return LZ4_decompress_safe(reinterpret_cast<const char*>(src), reinterpret_cast<char*>(dst),
+ static_cast<int>(src_size), static_cast<int>(dst_size));
+}
+
} // namespace Common::Compression
diff --git a/src/common/lz4_compression.h b/src/common/lz4_compression.h
index 7fd53a960..3ae17c2bb 100644
--- a/src/common/lz4_compression.h
+++ b/src/common/lz4_compression.h
@@ -56,4 +56,6 @@ namespace Common::Compression {
[[nodiscard]] std::vector<u8> DecompressDataLZ4(std::span<const u8> compressed,
std::size_t uncompressed_size);
+[[nodiscard]] int DecompressDataLZ4(void* dst, size_t dst_size, const void* src, size_t src_size);
+
} // namespace Common::Compression