aboutsummaryrefslogtreecommitdiffstats
path: root/core/hrtf.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-02-22 03:03:44 -0800
committerChris Robinson <[email protected]>2022-02-22 03:03:44 -0800
commitd06ed618d356a713292de95f0ab2c6017c305e17 (patch)
treead84c64155c782cd13158db020d623b3ea5f370b /core/hrtf.cpp
parent72ddb6351e1102b104ab45bdbb3c7cfb9cb49d08 (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.cpp53
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<>