Skip to content

Commit f8f1122

Browse files
authored
make locomotion_cast support new locomotion types (#34)
1 parent c213376 commit f8f1122

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

LocomotionClass.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,21 +177,32 @@ class LocomotionClass : public IPersistStream, public ILocomotion
177177
namespace detail
178178
{
179179
template<typename Base>
180-
concept LocoHasILocoVtbl = std::derived_from<Base, LocomotionClass> && !std::is_same_v<LocomotionClass, Base> && requires
181-
{
182-
{ Base::ILocoVTable }->std::convertible_to<const uintptr_t>;
183-
};
180+
concept LocoIsDerived = std::derived_from<Base, LocomotionClass> && !std::is_same_v<LocomotionClass, Base>;
181+
182+
template<typename Base>
183+
concept LocoHasILocoVtbl = requires { { Base::ILocoVTable }->std::convertible_to<const uintptr_t>; };
184184
}
185185

186186
template<typename T>
187-
concept LocoCastEligible = std::is_pointer_v<T> && detail::LocoHasILocoVtbl<std::remove_cvref_t<std::remove_const_t<std::remove_pointer_t<T>>>>;
187+
concept LocoCastEligible = std::is_pointer_v<T> && detail::LocoIsDerived<std::remove_cvref_t<std::remove_const_t<std::remove_pointer_t<T>>>>;
188188

189189

190190
template <LocoCastEligible T>
191191
__forceinline T locomotion_cast(ILocomotion* iLoco)
192192
{
193193
using Base = std::remove_cvref_t<std::remove_const_t<std::remove_pointer_t<T>>>;
194-
return VTable::Get(iLoco) == Base::ILocoVTable ? static_cast<T>(iLoco) : nullptr;
194+
195+
if constexpr (detail::LocoHasILocoVtbl<Base>)
196+
{
197+
return VTable::Get(iLoco) == Base::ILocoVTable ? static_cast<T>(iLoco) : nullptr;
198+
}
199+
else
200+
{
201+
CLSID clsid;
202+
IPersistPtr comPersist = iLoco;
203+
204+
return (SUCCEEDED(comPersist->GetClassID(&clsid)) && clsid == __uuidof(Base)) ? static_cast<T>(iLoco) : nullptr;
205+
}
195206
}
196207

197208
template<LocoCastEligible T>

0 commit comments

Comments
 (0)