diff --git a/src/buffer.cpp b/src/buffer.cpp index 6f9f224..184b555 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -182,15 +182,18 @@ Buffer::Buffer(DSound8OAL &parent, bool is8, IDirectSoundBuffer *original) noexc if(original) { -#ifdef __MINGW32__ /* MinGW headers do not have IDirectSoundBuffer8 inherit from * IDirectSoundBuffer, which MSVC apparently does. Reverse the cast * done for Buffer -> IDirectSoundBuffer. */ - Buffer *orig{static_cast(ds::bit_cast(original))}; -#else - Buffer *orig{static_cast(original)}; -#endif + auto upcast = [](auto *orig) + { + if constexpr(std::is_base_of_v,Buffer>) + return static_cast(orig); + else + return static_cast(ds::bit_cast(orig)); + }; + Buffer *orig{upcast(original)}; mBuffer = orig->mBuffer; /* According to MSDN, volume isn't copied. */ diff --git a/src/buffer.h b/src/buffer.h index 74ba9cf..948aef3 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -229,17 +230,19 @@ class Buffer final : IDirectSoundBuffer8 { DWORD getCurrentMode() const noexcept { return mImmediate.dwMode; } template - T as() noexcept { return static_cast(this); } + T as() noexcept + { + /* MinGW headers do not have IDirectSoundBuffer8 inherit from + * IDirectSoundBuffer, which MSVC apparently does. IDirectSoundBuffer + * is a strict subset of IDirectSoundBuffer8, so the interface is ABI + * compatible. + */ + if constexpr(std::is_same_v + && !std::is_base_of_v) + return ds::bit_cast(static_cast(this)); + else + return static_cast(this); + } }; -#ifdef __MINGW32__ -/* MinGW headers do not have IDirectSoundBuffer8 inherit from - * IDirectSoundBuffer, which MSVC apparently does. IDirectSoundBuffer is a - * subset of IDirectSoundBuffer8, so it should be ABI-compatible. - */ -template<> -inline IDirectSoundBuffer *Buffer::as() noexcept -{ return ds::bit_cast(static_cast(this)); } -#endif - #endif // BUFFER_H diff --git a/src/dsoundoal.h b/src/dsoundoal.h index d90ada4..21a3bed 100644 --- a/src/dsoundoal.h +++ b/src/dsoundoal.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -215,20 +216,21 @@ class DSound8OAL final : IDirectSound8 { std::vector &get3dBuffers() noexcept { return m3dBuffers; } template [[nodiscard]] - T as() noexcept { return static_cast(this); } + T as() noexcept + { + /* MinGW headers do not have IDirectSound8 inherit from IDirectSound, + * which MSVC apparently does. IDirectSound is a strict subset of + * IDirectSound8, so the interface is ABI compatible. + */ + if constexpr(std::is_same_v + && !std::is_base_of_v) + return ds::bit_cast(static_cast(this)); + else + return static_cast(this); + } [[nodiscard]] static ComPtr Create(bool is8); }; -#ifdef __MINGW32__ -/* MinGW headers do not have IDirectSound8 inherit from IDirectSound, which - * MSVC apparently does. IDirectSound is a subset of IDirectSoundBuffer, so it - * should be ABI-compatible. - */ -template<> -inline IDirectSound *DSound8OAL::as() noexcept -{ return ds::bit_cast(static_cast(this)); } -#endif - #endif // DSOUNDOAL_H