diff --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base --- a/libcxx/include/__functional_base +++ b/libcxx/include/__functional_base @@ -298,7 +298,7 @@ template struct __invoke_return { - typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type; + typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type; }; #else // defined(_LIBCPP_CXX03_LANG) @@ -314,27 +314,27 @@ #ifndef _LIBCPP_CXX03_LANG template static _Ret __call(_Args&&... __args) { - return __invoke(_VSTD::forward<_Args>(__args)...); + return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...); } #else template static _Ret __call(_Fn __f) { - return __invoke(__f); + return _VSTD::__invoke(__f); } template static _Ret __call(_Fn __f, _A0& __a0) { - return __invoke(__f, __a0); + return _VSTD::__invoke(__f, __a0); } template static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) { - return __invoke(__f, __a0, __a1); + return _VSTD::__invoke(__f, __a0, __a1); } template static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){ - return __invoke(__f, __a0, __a1, __a2); + return _VSTD::__invoke(__f, __a0, __a1, __a2); } #endif }; @@ -345,27 +345,27 @@ #ifndef _LIBCPP_CXX03_LANG template static void __call(_Args&&... __args) { - __invoke(_VSTD::forward<_Args>(__args)...); + _VSTD::__invoke(_VSTD::forward<_Args>(__args)...); } #else template static void __call(_Fn __f) { - __invoke(__f); + _VSTD::__invoke(__f); } template static void __call(_Fn __f, _A0& __a0) { - __invoke(__f, __a0); + _VSTD::__invoke(__f, __a0); } template static void __call(_Fn __f, _A0& __a0, _A1& __a1) { - __invoke(__f, __a0, __a1); + _VSTD::__invoke(__f, __a0, __a1); } template static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) { - __invoke(__f, __a0, __a1, __a2); + _VSTD::__invoke(__f, __a0, __a1, __a2); } #endif }; @@ -398,112 +398,112 @@ _LIBCPP_INLINE_VISIBILITY typename __invoke_of::type operator() (_ArgTypes&&... __args) const { - return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); + return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...); } #else _LIBCPP_INLINE_VISIBILITY typename __invoke_return::type operator() () const { - return __invoke(get()); + return _VSTD::__invoke(get()); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return0::type operator() (_A0& __a0) const { - return __invoke(get(), __a0); + return _VSTD::__invoke(get(), __a0); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return0::type operator() (_A0 const& __a0) const { - return __invoke(get(), __a0); + return _VSTD::__invoke(get(), __a0); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0& __a0, _A1& __a1) const { - return __invoke(get(), __a0, __a1); + return _VSTD::__invoke(get(), __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0 const& __a0, _A1& __a1) const { - return __invoke(get(), __a0, __a1); + return _VSTD::__invoke(get(), __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0& __a0, _A1 const& __a1) const { - return __invoke(get(), __a0, __a1); + return _VSTD::__invoke(get(), __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0 const& __a0, _A1 const& __a1) const { - return __invoke(get(), __a0, __a1); + return _VSTD::__invoke(get(), __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { - return __invoke(get(), __a0, __a1, __a2); + return _VSTD::__invoke(get(), __a0, __a1, __a2); } #endif // _LIBCPP_CXX03_LANG }; diff --git a/libcxx/include/__functional_base_03 b/libcxx/include/__functional_base_03 --- a/libcxx/include/__functional_base_03 +++ b/libcxx/include/__functional_base_03 @@ -40,7 +40,7 @@ template struct __enable_invoke_imp<_Ret, _T1, false, false> { typedef typename add_lvalue_reference< - typename __apply_cv()), _Ret>::type + typename __apply_cv()), _Ret>::type >::type _Bullet4; typedef _Bullet4 type; }; @@ -142,7 +142,7 @@ template inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()()) +decltype(declval<_Fp&>()()) __invoke(_Fp& __f) { return __f(); @@ -150,7 +150,7 @@ template inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) +decltype(declval<_Fp&>()(declval<_A0&>())) __invoke(_Fp& __f, _A0& __a0) { return __f(__a0); @@ -158,7 +158,7 @@ template inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) +decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>())) __invoke(_Fp& __f, _A0& __a0, _A1& __a1) { return __f(__a0, __a1); @@ -166,7 +166,7 @@ template inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) +decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>())) __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) { return __f(__a0, __a1, __a2); @@ -181,13 +181,13 @@ template struct __invoke_return<_Fp, false> { - typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; + typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type; }; template struct __invoke_return0 { - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; + typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type; }; template @@ -199,8 +199,8 @@ template struct __invoke_return1 { - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), - _VSTD::declval<_A1&>())) type; + typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), + declval<_A1&>())) type; }; template @@ -211,9 +211,9 @@ template struct __invoke_return2 { - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), - _VSTD::declval<_A1&>(), - _VSTD::declval<_A2&>())) type; + typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), + declval<_A1&>(), + declval<_A2&>())) type; }; template diff --git a/libcxx/include/functional b/libcxx/include/functional --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1295,7 +1295,7 @@ _LIBCPP_INLINE_VISIBILITY typename __invoke_return::type operator() (_ArgTypes&&... __args) const { - return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...); + return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...); } #else @@ -1303,98 +1303,98 @@ _LIBCPP_INLINE_VISIBILITY typename __invoke_return0::type operator() (_A0& __a0) const { - return __invoke(__f_, __a0); + return _VSTD::__invoke(__f_, __a0); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return0::type operator() (_A0 const& __a0) const { - return __invoke(__f_, __a0); + return _VSTD::__invoke(__f_, __a0); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0& __a0, _A1& __a1) const { - return __invoke(__f_, __a0, __a1); + return _VSTD::__invoke(__f_, __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0 const& __a0, _A1& __a1) const { - return __invoke(__f_, __a0, __a1); + return _VSTD::__invoke(__f_, __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0& __a0, _A1 const& __a1) const { - return __invoke(__f_, __a0, __a1); + return _VSTD::__invoke(__f_, __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return1::type operator() (_A0 const& __a0, _A1 const& __a1) const { - return __invoke(__f_, __a0, __a1); + return _VSTD::__invoke(__f_, __a0, __a1); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1& __a1, _A2& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } template _LIBCPP_INLINE_VISIBILITY typename __invoke_return2::type operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const { - return __invoke(__f_, __a0, __a1, __a2); + return _VSTD::__invoke(__f_, __a0, __a1, __a2); } #endif }; @@ -2302,7 +2302,7 @@ } virtual _Rp operator()(_ArgTypes&& ... __arg) { - return __invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); + return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...); } #ifndef _LIBCPP_NO_RTTI diff --git a/libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +#include + +#include "test_macros.h" + +struct Incomplete; +template struct Holder { T t; }; +typedef Holder *Ptr; + +struct A { + Ptr no_args() const { return nullptr; } + Ptr one_arg(Ptr p) const { return p; } + void one_arg_void(Ptr) const { } +}; + +int main(int, char**) +{ + A a; + A *pa = &a; + const A *cpa = &a; + Ptr x = nullptr; + const Ptr cx = nullptr; + std::mem_fn(&A::no_args)(a); + std::mem_fn(&A::no_args)(pa); + std::mem_fn(&A::no_args)(*cpa); + std::mem_fn(&A::no_args)(cpa); + std::mem_fn(&A::one_arg)(a, x); + std::mem_fn(&A::one_arg)(pa, x); + std::mem_fn(&A::one_arg)(a, cx); + std::mem_fn(&A::one_arg)(pa, cx); + std::mem_fn(&A::one_arg)(*cpa, x); + std::mem_fn(&A::one_arg)(cpa, x); + std::mem_fn(&A::one_arg)(*cpa, cx); + std::mem_fn(&A::one_arg)(cpa, cx); + std::mem_fn(&A::one_arg_void)(a, x); + std::mem_fn(&A::one_arg_void)(pa, x); + std::mem_fn(&A::one_arg_void)(a, cx); + std::mem_fn(&A::one_arg_void)(pa, cx); + std::mem_fn(&A::one_arg_void)(*cpa, x); + std::mem_fn(&A::one_arg_void)(cpa, x); + std::mem_fn(&A::one_arg_void)(*cpa, cx); + std::mem_fn(&A::one_arg_void)(cpa, cx); + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03 + +// + +#include + +#include "test_macros.h" + +struct Incomplete; +template struct Holder { T t; }; +typedef Holder *Ptr; + +Ptr no_args() { return nullptr; } +Ptr one_arg(Ptr p) { return p; } +Ptr two_args(Ptr p, Ptr) { return p; } +Ptr three_args(Ptr p, Ptr, Ptr) { return p; } +Ptr four_args(Ptr p, Ptr, Ptr, Ptr) { return p; } + +void one_arg_void(Ptr) { } + +int main(int, char**) +{ + Ptr x = nullptr; + std::function f(no_args); f(); + std::function g(one_arg); g(x); + std::function h(one_arg_void); h(x); + return 0; +} diff --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// + +#include + +#include "test_macros.h" + +struct Incomplete; +template struct Holder { T t; }; +typedef Holder *Ptr; + +Ptr no_args() { return nullptr; } +Ptr one_arg(Ptr p) { return p; } +Ptr two_args(Ptr p, Ptr) { return p; } +Ptr three_args(Ptr p, Ptr, Ptr) { return p; } + +void one_arg_void(Ptr) { } + +int main(int, char**) +{ + Ptr x = nullptr; + const Ptr cx = nullptr; + std::ref(no_args)(); + std::ref(one_arg)(x); + std::ref(one_arg)(cx); + std::ref(two_args)(x, x); + std::ref(two_args)(x, cx); + std::ref(two_args)(cx, x); + std::ref(two_args)(cx, cx); + std::ref(three_args)(x, x, x); + std::ref(three_args)(x, x, cx); + std::ref(three_args)(x, cx, x); + std::ref(three_args)(cx, x, x); + std::ref(three_args)(x, cx, cx); + std::ref(three_args)(cx, x, cx); + std::ref(three_args)(cx, cx, x); + std::ref(three_args)(cx, cx, cx); + std::ref(one_arg_void)(x); + std::ref(one_arg_void)(cx); + + return 0; +}