diff options
author | Fernando S <fsahmkow27@gmail.com> | 2023-08-21 16:29:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-21 16:29:04 +0200 |
commit | 861597eb2e32663dba37813273ff91434566523a (patch) | |
tree | a05b7c596209f754a822c03cca162c6f32b6a565 /src/common/alignment.h | |
parent | 6a5db5679b61d3d73244e42682f1b34d401e7736 (diff) | |
parent | 775bf8e215c8c771b45f383b0b2ce46fa37ebe95 (diff) |
Merge pull request #11284 from liamwhite/nca-release
vfs: expand support for NCA reading
Diffstat (limited to 'src/common/alignment.h')
-rw-r--r-- | src/common/alignment.h | 37 |
1 files changed, 33 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: |