diff --git a/app/src/main/cpp/skyline/common/utils.h b/app/src/main/cpp/skyline/common/utils.h index e57fd2b9..e9dd44f7 100644 --- a/app/src/main/cpp/skyline/common/utils.h +++ b/app/src/main/cpp/skyline/common/utils.h @@ -70,7 +70,7 @@ namespace skyline::util { /** * @return The value aligned up to the next multiple - * @note The multiple needs to be a power of 2 + * @note The multiple **must** be a power of 2 */ template requires IsPointerOrUnsignedIntegral @@ -79,9 +79,20 @@ namespace skyline::util { return ValuePointer((PointerValue(value) + multiple) & ~(multiple)); } + /** + * @return The value aligned up to the next multiple, the multiple is not restricted to being a power of two (NPOT) + * @note This will round away from zero for negative numbers + * @note This is costlier to compute than the power of 2 version, it should be preferred over this when possible + */ + template + requires std::is_integral_v || std::is_pointer_v + constexpr TypeVal AlignUpNpot(TypeVal value, ssize_t multiple) { + return ValuePointer(((PointerValue(value) + multiple - 1) / multiple) * multiple); + } + /** * @return The value aligned down to the previous multiple - * @note The multiple needs to be a power of 2 + * @note The multiple **must** be a power of 2 */ template requires IsPointerOrUnsignedIntegral