diff options
author | Chris Robinson <[email protected]> | 2022-02-22 03:03:44 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-02-22 03:03:44 -0800 |
commit | d06ed618d356a713292de95f0ab2c6017c305e17 (patch) | |
tree | ad84c64155c782cd13158db020d623b3ea5f370b /core/hrtf.cpp | |
parent | 72ddb6351e1102b104ab45bdbb3c7cfb9cb49d08 (diff) |
Avoid using an if_constexpr macro
It doesn't actually use if constexpr, and compilers are smart enough to
optimize. Some functions can use templates instead.
Diffstat (limited to 'core/hrtf.cpp')
-rw-r--r-- | core/hrtf.cpp | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/core/hrtf.cpp b/core/hrtf.cpp index e8d3310a..d94c0569 100644 --- a/core/hrtf.cpp +++ b/core/hrtf.cpp @@ -447,32 +447,47 @@ void MirrorLeftHrirs(const al::span<const HrtfStore::Elevation> elevs, HrirArray } +template<size_t num_bits, typename T> +constexpr std::enable_if_t<std::is_signed<T>::value && num_bits < sizeof(T)*8, +T> fixsign(T value) noexcept +{ + constexpr auto signbit = static_cast<T>(1u << (num_bits-1)); + return static_cast<T>((value^signbit) - signbit); +} + +template<size_t num_bits, typename T> +constexpr std::enable_if_t<!std::is_signed<T>::value || num_bits == sizeof(T)*8, +T> fixsign(T value) noexcept +{ return value; } + template<typename T, size_t num_bits=sizeof(T)*8> -inline T readle(std::istream &data) +inline std::enable_if_t<al::endian::native == al::endian::little, +T> readle(std::istream &data) { static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type"); T ret{}; - if_constexpr(al::endian::native == al::endian::little) - { - if(!data.read(reinterpret_cast<char*>(&ret), num_bits/8)) - return static_cast<T>(EOF); - } - else - { - al::byte b[sizeof(T)]{}; - if(!data.read(reinterpret_cast<char*>(b), num_bits/8)) - return static_cast<T>(EOF); - std::reverse_copy(std::begin(b), std::end(b), reinterpret_cast<al::byte*>(&ret)); - } + if(!data.read(reinterpret_cast<char*>(&ret), num_bits/8)) + return static_cast<T>(EOF); - if_constexpr(std::is_signed<T>::value && num_bits < sizeof(T)*8) - { - constexpr auto signbit = static_cast<T>(1u << (num_bits-1)); - return static_cast<T>((ret^signbit) - signbit); - } - return ret; + return fixsign<num_bits>(ret); +} + +template<typename T, size_t num_bits=sizeof(T)*8> +inline std::enable_if_t<al::endian::native == al::endian::big, +T> readle(std::istream &data) +{ + static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); + static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type"); + + T ret{}; + al::byte b[sizeof(T)]{}; + if(!data.read(reinterpret_cast<char*>(b), num_bits/8)) + return static_cast<T>(EOF); + std::reverse_copy(std::begin(b), std::end(b), reinterpret_cast<al::byte*>(&ret)); + + return fixsign<num_bits>(ret); } template<> |