Index: include/__functional_03 =================================================================== --- include/__functional_03 +++ include/__functional_03 @@ -662,6 +662,9 @@ static bool __not_null(_R2 (*__p)()) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (*__p)(...)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(const function<_R2()>& __p) {return __p;} public: typedef _Rp result_type; @@ -944,18 +947,33 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (*__p)(_B0)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (*__p)(_B0, ...)) {return __p;} template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)()) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(...)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(...) const) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;} template _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(...) volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(...) const volatile) {return __p;} template _LIBCPP_INLINE_VISIBILITY static bool __not_null(const function<_R2(_B0)>& __p) {return __p;} @@ -1240,6 +1258,9 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (*__p)(_B0, _B1, ...)) {return __p;} template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;} @@ -1252,6 +1273,18 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, ...)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, ...) const) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, ...) volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, ...) const volatile) {return __p;} template _LIBCPP_INLINE_VISIBILITY static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;} @@ -1535,6 +1568,9 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (*__p)(_B0, _B1, _B2, ...)) {return __p;} template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;} @@ -1547,6 +1583,18 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2, ...)) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2, ...) const) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2, ...) volatile) {return __p;} + template + _LIBCPP_INLINE_VISIBILITY + static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2, ...) const volatile) {return __p;} template _LIBCPP_INLINE_VISIBILITY static bool __not_null(const function<_R2(_B0, _B1, _B2)>& __p) {return __p;} Index: include/__functional_base_03 =================================================================== --- include/__functional_base_03 +++ include/__functional_base_03 @@ -425,6 +425,19 @@ return (__t1.*__f)(); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(...), _T1& __t1) +{ + return (__t1.*__f)(); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -437,6 +450,19 @@ return (__t1.*__f)(__a0); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, ...), _T1& __t1, _A0& __a0) +{ + return (__t1.*__f)(__a0); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -449,6 +475,19 @@ return (__t1.*__f)(__a0, __a1); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, ...), _T1& __t1, _A0& __a0, _A1& __a1) +{ + return (__t1.*__f)(__a0, __a1); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -461,6 +500,20 @@ return (__t1.*__f)(__a0, __a1, __a2); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2, ...), _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) +{ + return (__t1.*__f)(__a0, __a1, __a2); +} + + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -473,6 +526,19 @@ return (__t1.*__f)(); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(...) const, _T1& __t1) +{ + return (__t1.*__f)(); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -485,6 +551,19 @@ return (__t1.*__f)(__a0); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, ...) const, _T1& __t1, _A0& __a0) +{ + return (__t1.*__f)(__a0); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -497,6 +576,19 @@ return (__t1.*__f)(__a0, __a1); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, ...) const, _T1& __t1, _A0& __a0, _A1& __a1) +{ + return (__t1.*__f)(__a0, __a1); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -509,6 +601,19 @@ return (__t1.*__f)(__a0, __a1, __a2); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2, ...) const, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) +{ + return (__t1.*__f)(__a0, __a1, __a2); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -521,6 +626,19 @@ return (__t1.*__f)(); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(...) volatile, _T1& __t1) +{ + return (__t1.*__f)(); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -533,6 +651,19 @@ return (__t1.*__f)(__a0); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, ...) volatile, _T1& __t1, _A0& __a0) +{ + return (__t1.*__f)(__a0); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -545,6 +676,19 @@ return (__t1.*__f)(__a0, __a1); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, ...) volatile, _T1& __t1, _A0& __a0, _A1& __a1) +{ + return (__t1.*__f)(__a0, __a1); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -557,6 +701,19 @@ return (__t1.*__f)(__a0, __a1, __a2); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2, ...) volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) +{ + return (__t1.*__f)(__a0, __a1, __a2); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -569,6 +726,19 @@ return (__t1.*__f)(); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(...) const volatile, _T1& __t1) +{ + return (__t1.*__f)(); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -581,6 +751,19 @@ return (__t1.*__f)(__a0); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, ...) const volatile, _T1& __t1, _A0& __a0) +{ + return (__t1.*__f)(__a0); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -593,6 +776,19 @@ return (__t1.*__f)(__a0, __a1); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, ...) const volatile, _T1& __t1, _A0& __a0, _A1& __a1) +{ + return (__t1.*__f)(__a0, __a1); +} + template inline _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -605,6 +801,20 @@ return (__t1.*__f)(__a0, __a1, __a2); } + +template +inline _LIBCPP_INLINE_VISIBILITY +typename enable_if +< + is_base_of<_Tp, typename remove_reference<_T1>::type>::value, + _Rp +>::type +__invoke(_Rp (_Tp::*__f)(_A0, _A1, _A2, ...) const volatile, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) +{ + return (__t1.*__f)(__a0, __a1, __a2); +} + + // second bullet template Index: include/functional =================================================================== --- include/functional +++ include/functional @@ -1473,8 +1473,8 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const volatile) {return __p;} -#if __has_feature(cxx_reference_qualified_functions) +#if __has_feature(cxx_reference_qualified_functions) template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap...) &) {return __p;} @@ -1499,8 +1499,8 @@ template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const volatile &) {return __p;} - - template + + template _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap...) &&) {return __p;} template @@ -1525,6 +1525,7 @@ _LIBCPP_INLINE_VISIBILITY static bool __not_null(_R2 (_Cp::*__p)(_Ap..., ...) const volatile &&) {return __p;} #endif // __has_feature(cxx_reference_qualified_functions) + template _LIBCPP_INLINE_VISIBILITY static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;} Index: test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp =================================================================== --- test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp +++ test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp @@ -23,16 +23,41 @@ #define NULL_CV_TYPE +#if __cplusplus >= 201103L +#define TEST_CV_MEM_TYPE_RET(Ret, CV) \ + test_mf(); \ + test_mf(); \ + test_mf(); \ + test_mf(); \ + test_mf(); \ + test_mf() +#else +#define TEST_CV_MEM_TYPE_RET(Ret, CV) \ + test_mf(); \ + test_mf() +#endif + +#define TEST_CV_MEM_TYPE(CV) \ + TEST_CV_MEM_TYPE_RET(void, CV); \ + TEST_CV_MEM_TYPE_RET(int, CV) + #define TEST_CV_TYPE(CV) \ - test(); \ - test(); \ - test(); \ - test(); \ - test(); \ - test() + test1(); \ + test1();\ + test2(); \ + test2();\ + test3(); \ + test3();\ + test1(); \ + test1();\ + test2(); \ + test2();\ + test3(); \ + test3() + template -void test() { +void test_mf() { MemFn mf = nullptr; std::function f = mf; A a; @@ -40,6 +65,36 @@ catch (std::bad_function_call&) {} } + +template +void test1() { + RawFn fn = nullptr; + std::function f = fn; + int x = 42; + try { f(x); assert(false); } + catch (std::bad_function_call&) {} +} + + +template +void test2() { + RawFn fn = nullptr; + std::function f = fn; + int x = 42; + try { f(x, x); assert(false); } + catch (std::bad_function_call&) {} +} + + +template +void test3() { + RawFn fn = nullptr; + std::function f = fn; + int x = 42; + try { f(x, x, x); assert(false); } + catch (std::bad_function_call&) {} +} + int main() { { void (*p)() = nullptr; @@ -54,9 +109,28 @@ catch ( std::bad_function_call & ) {} } { - TEST_CV_TYPE( NULL_CV_TYPE ); - TEST_CV_TYPE( const ); - TEST_CV_TYPE( volatile ); - TEST_CV_TYPE( const volatile ); + int (*p)(int&, ...) = nullptr; + std::function< int(int&) > f = p; + int x = 42; + try { f(x); } + catch ( std::bad_function_call & ) {} + } + { + TEST_CV_MEM_TYPE( NULL_CV_TYPE ); + TEST_CV_MEM_TYPE( const ); + TEST_CV_MEM_TYPE( volatile ); + TEST_CV_MEM_TYPE( const volatile ); + } + { + TEST_CV_TYPE( NULL_CV_TYPE ); + TEST_CV_TYPE( const ); + TEST_CV_TYPE( volatile ); + TEST_CV_TYPE( const volatile ); + + TEST_CV_TYPE( & ); + TEST_CV_TYPE( const & ); + TEST_CV_TYPE( volatile & ); + TEST_CV_TYPE( const volatile & ); + } } \ No newline at end of file