2019-05-23 Jonathan Wakely <jwakely@redhat.com>
+ * include/experimental/any (__any_caster): Use RTTI if comparing
+ addresses fails, to support non-unique addresses in shared libraries.
+ * include/std/any (__any_caster): Likewise.
+
PR libstdc++/90220
* include/experimental/any (__any_caster): Constrain to only be
callable for object types. Use remove_cv_t instead of decay_t.
// is explicitly specialized and has a no-op _S_manage function.
using _Vp = conditional_t<__and_<__does_not_decay, __is_copyable>::value,
_Up, any::_Op>;
- if (__any->_M_manager != &any::_Manager<_Vp>::_S_manage)
- return nullptr;
- any::_Arg __arg;
- __any->_M_manager(any::_Op_access, __any, &__arg);
- return __arg._M_obj;
+ // First try comparing function addresses, which works without RTTI
+ if (__any->_M_manager == &any::_Manager<_Vp>::_S_manage
+#if __cpp_rtti
+ || __any->type() == typeid(_Tp)
+#endif
+ )
+ {
+ any::_Arg __arg;
+ __any->_M_manager(any::_Op_access, __any, &__arg);
+ return __arg._M_obj;
+ }
+ return nullptr;
}
// This overload exists so that std::any_cast<void(*)()>(a) is well-formed.
}
// @}
+ /// @cond undocumented
template<typename _Tp>
void* __any_caster(const any* __any)
{
// Only copy constructible types can be used for contained values:
else if constexpr (!is_copy_constructible_v<_Up>)
return nullptr;
- // This check is equivalent to __any->type() == typeid(_Tp)
- else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage)
+ // First try comparing function addresses, which works without RTTI
+ else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage
+#if __cpp_rtti
+ || __any->type() == typeid(_Tp)
+#endif
+ )
{
any::_Arg __arg;
__any->_M_manager(any::_Op_access, __any, &__arg);
}
return nullptr;
}
+ /// @endcond
/**
* @brief Access the contained object.