diff --git a/src/openrct2/common.h b/src/openrct2/common.h index 3194c29206..54379a710c 100644 --- a/src/openrct2/common.h +++ b/src/openrct2/common.h @@ -20,10 +20,14 @@ #endif #include "Diagnostic.h" +#include "core/Numerics.hpp" #include +#include #include +using namespace Numerics; + using utf8 = char; using utf8string = utf8*; using const_utf8string = const utf8*; @@ -41,14 +45,14 @@ using utf16string = utf16*; using codepoint_t = uint32_t; using colour_t = uint8_t; -#define rol8(x, shift) (((uint8_t)(x) << (shift)) | ((uint8_t)(x) >> (8 - (shift)))) -#define ror8(x, shift) (((uint8_t)(x) >> (shift)) | ((uint8_t)(x) << (8 - (shift)))) -#define rol16(x, shift) (((uint16_t)(x) << (shift)) | ((uint16_t)(x) >> (16 - (shift)))) -#define ror16(x, shift) (((uint16_t)(x) >> (shift)) | ((uint16_t)(x) << (16 - (shift)))) -#define rol32(x, shift) (((uint32_t)(x) << (shift)) | ((uint32_t)(x) >> (32 - (shift)))) -#define ror32(x, shift) (((uint32_t)(x) >> (shift)) | ((uint32_t)(x) << (32 - (shift)))) -#define rol64(x, shift) (((uint64_t)(x) << (shift)) | ((uint64_t)(x) >> (64 - (shift)))) -#define ror64(x, shift) (((uint64_t)(x) >> (shift)) | ((uint64_t)(x) << (64 - (shift)))) +const constexpr auto rol8 = rol; +const constexpr auto ror8 = ror; +const constexpr auto rol16 = rol; +const constexpr auto ror16 = ror; +const constexpr auto rol32 = rol; +const constexpr auto ror32 = ror; +const constexpr auto rol64 = rol; +const constexpr auto ror64 = ror; // Rounds an integer down to the given power of 2. y must be a power of 2. #define floor2(x, y) ((x) & (~((y)-1))) diff --git a/src/openrct2/core/Numerics.hpp b/src/openrct2/core/Numerics.hpp new file mode 100644 index 0000000000..8152347204 --- /dev/null +++ b/src/openrct2/core/Numerics.hpp @@ -0,0 +1,47 @@ +/***************************************************************************** + * Copyright (c) 2014-2019 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include +#include +#include +#include + +namespace Numerics +{ + /** + * Bitwise left rotate + * @tparam _UIntType unsigned integral type + * @param x value + * @param shift positions to shift + * @return rotated value + */ + template constexpr _UIntType rol(_UIntType x, size_t shift) + { + static_assert(std::is_unsigned<_UIntType>::value, "result_type must be an unsigned integral type"); + using limits = typename std::numeric_limits<_UIntType>; + return (((_UIntType)(x) << shift) | ((_UIntType)(x) >> (limits::digits - shift))); + } + + /** + * Bitwise right rotate + * @tparam _UIntType unsigned integral type + * @param x value + * @param shift positions to shift + * @return rotated value + */ + template constexpr _UIntType ror(_UIntType x, size_t shift) + { + static_assert(std::is_unsigned<_UIntType>::value, "result_type must be an unsigned integral type"); + using limits = std::numeric_limits<_UIntType>; + return (((_UIntType)(x) >> shift) | ((_UIntType)(x) << (limits::digits - shift))); + } + +} // namespace Numerics