Author: ericwf Date: Sun Oct 16 06:56:38 2016 New Revision: 284333 URL: http://llvm.org/viewvc/llvm-project?rev=284333&view=rev Log: Make any_cast<void()>(nullptr) compile
Modified: libcxx/trunk/include/any libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp Modified: libcxx/trunk/include/any URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/any?rev=284333&r1=284332&r2=284333&view=diff ============================================================================== --- libcxx/trunk/include/any (original) +++ libcxx/trunk/include/any Sun Oct 16 06:56:38 2016 @@ -622,6 +622,18 @@ any_cast(any const * __any) _NOEXCEPT return _VSTD::any_cast<_ValueType>(const_cast<any *>(__any)); } +template <class _RetType> +inline _LIBCPP_INLINE_VISIBILITY +_RetType __pointer_or_func_cast(void* __p, /*IsFunction*/false_type) noexcept { + return static_cast<_RetType>(__p); +} + +template <class _RetType> +inline _LIBCPP_INLINE_VISIBILITY +_RetType __pointer_or_func_cast(void*, /*IsFunction*/true_type) noexcept { + return nullptr; +} + template <class _ValueType> add_pointer_t<_ValueType> any_cast(any * __any) _NOEXCEPT @@ -631,15 +643,15 @@ any_cast(any * __any) _NOEXCEPT "_ValueType may not be a reference."); typedef typename add_pointer<_ValueType>::type _ReturnType; if (__any && __any->__h) { - return static_cast<_ReturnType>( - __any->__call(_Action::_Get, nullptr, + void *__p = __any->__call(_Action::_Get, nullptr, #if !defined(_LIBCPP_NO_RTTI) &typeid(_ValueType), #else nullptr, #endif - __any_imp::__get_fallback_typeid<_ValueType>() - )); + __any_imp::__get_fallback_typeid<_ValueType>()); + return _VSTD::__pointer_or_func_cast<_ReturnType>( + __p, is_function<_ValueType>{}); } return nullptr; } Modified: libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp?rev=284333&r1=284332&r2=284333&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/any/any.nonmembers/any.cast/any_cast_pointer.pass.cpp Sun Oct 16 06:56:38 2016 @@ -147,6 +147,18 @@ void test_cast_non_copyable_type() assert(std::any_cast<NoCopy>(&ca) == nullptr); } +void test_fn() {} + +void test_cast_function_pointer() { + using T = void(*)(); + std::any a(test_fn); + // An any can never store a function type, but we should at least be able + // to ask. + assert(std::any_cast<void()>(&a) == nullptr); + T fn_ptr = std::any_cast<T>(a); + assert(fn_ptr == test_fn); +} + int main() { test_cast_is_noexcept(); test_cast_return_type(); @@ -155,4 +167,5 @@ int main() { test_cast<small>(); test_cast<large>(); test_cast_non_copyable_type(); + test_cast_function_pointer(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits