Use Davids suggestion to reduce code duplication. I didn't know that would work
:-)
http://reviews.llvm.org/D9873
Files:
include/__functional_03
include/__functional_base_03
include/functional
test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/__functional_03
===================================================================
--- include/__functional_03
+++ include/__functional_03
@@ -662,6 +662,9 @@
static bool __not_null(_R2 (*__p)()) {return __p;}
template <class _R2>
_LIBCPP_INLINE_VISIBILITY
+ static bool __not_null(_R2 (*__p)(...)) {return __p;}
+ template <class _R2>
+ _LIBCPP_INLINE_VISIBILITY
static bool __not_null(const function<_R2()>& __p) {return __p;}
public:
typedef _Rp result_type;
@@ -944,18 +947,12 @@
template <class _R2, class _B0>
_LIBCPP_INLINE_VISIBILITY
static bool __not_null(_R2 (*__p)(_B0)) {return __p;}
- template <class _R2, class _Cp>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)()) {return __p;}
- template <class _R2, class _Cp>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)() const) {return __p;}
- template <class _R2, class _Cp>
+ template <class _R2, class _B0>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)() volatile) {return __p;}
- template <class _R2, class _Cp>
+ static bool __not_null(_R2 (*__p)(_B0, ...)) {return __p;}
+ template <class _Ret, class _Class>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)() const volatile) {return __p;}
+ static bool __not_null(_Ret _Class::*__p) { return __p; }
template <class _R2, class _B0>
_LIBCPP_INLINE_VISIBILITY
static bool __not_null(const function<_R2(_B0)>& __p) {return __p;}
@@ -1240,18 +1237,12 @@
template <class _R2, class _B0, class _B1>
_LIBCPP_INLINE_VISIBILITY
static bool __not_null(_R2 (*__p)(_B0, _B1)) {return __p;}
- template <class _R2, class _Cp, class _B1>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1)) {return __p;}
- template <class _R2, class _Cp, class _B1>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1) const) {return __p;}
- template <class _R2, class _Cp, class _B1>
+ template <class _R2, class _B0, class _B1>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1) volatile) {return __p;}
- template <class _R2, class _Cp, class _B1>
+ static bool __not_null(_R2 (*__p)(_B0, _B1, ...)) {return __p;}
+ template <class _Ret, class _Class>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1) const volatile) {return __p;}
+ static bool __not_null(_Ret _Class::*__p) { return __p; }
template <class _R2, class _B0, class _B1>
_LIBCPP_INLINE_VISIBILITY
static bool __not_null(const function<_R2(_B0, _B1)>& __p) {return __p;}
@@ -1535,18 +1526,12 @@
template <class _R2, class _B0, class _B1, class _B2>
_LIBCPP_INLINE_VISIBILITY
static bool __not_null(_R2 (*__p)(_B0, _B1, _B2)) {return __p;}
- template <class _R2, class _Cp, class _B1, class _B2>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2)) {return __p;}
- template <class _R2, class _Cp, class _B1, class _B2>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const) {return __p;}
- template <class _R2, class _Cp, class _B1, class _B2>
+ template <class _R2, class _B0, class _B1, class _B2>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) volatile) {return __p;}
- template <class _R2, class _Cp, class _B1, class _B2>
+ static bool __not_null(_R2 (*__p)(_B0, _B1, _B2, ...)) {return __p;}
+ template <class _Ret, class _Class>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_B1, _B2) const volatile) {return __p;}
+ static bool __not_null(_Ret _Class::*__p) { return __p; }
template <class _R2, class _B0, class _B1, class _B2>
_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 <class _Rp, class _Tp, class _T1>
+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 <class _Rp, class _Tp, class _T1, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -437,6 +450,19 @@
return (__t1.*__f)(__a0);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -449,6 +475,19 @@
return (__t1.*__f)(__a0, __a1);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -461,6 +500,20 @@
return (__t1.*__f)(__a0, __a1, __a2);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+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 <class _Rp, class _Tp, class _T1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -473,6 +526,19 @@
return (__t1.*__f)();
}
+
+template <class _Rp, class _Tp, class _T1>
+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 <class _Rp, class _Tp, class _T1, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -485,6 +551,19 @@
return (__t1.*__f)(__a0);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -497,6 +576,19 @@
return (__t1.*__f)(__a0, __a1);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -509,6 +601,19 @@
return (__t1.*__f)(__a0, __a1, __a2);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+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 <class _Rp, class _Tp, class _T1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -521,6 +626,19 @@
return (__t1.*__f)();
}
+
+template <class _Rp, class _Tp, class _T1>
+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 <class _Rp, class _Tp, class _T1, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -533,6 +651,19 @@
return (__t1.*__f)(__a0);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -545,6 +676,19 @@
return (__t1.*__f)(__a0, __a1);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -557,6 +701,19 @@
return (__t1.*__f)(__a0, __a1, __a2);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+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 <class _Rp, class _Tp, class _T1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -569,6 +726,19 @@
return (__t1.*__f)();
}
+
+template <class _Rp, class _Tp, class _T1>
+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 <class _Rp, class _Tp, class _T1, class _A0>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -581,6 +751,19 @@
return (__t1.*__f)(__a0);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -593,6 +776,19 @@
return (__t1.*__f)(__a0, __a1);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1>
+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 <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -605,6 +801,20 @@
return (__t1.*__f)(__a0, __a1, __a2);
}
+
+template <class _Rp, class _Tp, class _T1, class _A0, class _A1, class _A2>
+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 <class _Rp, class _Tp, class _T1>
Index: include/functional
===================================================================
--- include/functional
+++ include/functional
@@ -1446,18 +1446,12 @@
template <class _R2, class ..._Ap>
_LIBCPP_INLINE_VISIBILITY
static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;}
- template <class _R2, class _Cp, class ..._Ap>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;}
- template <class _R2, class _Cp, class ..._Ap>
- _LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;}
- template <class _R2, class _Cp, class ..._Ap>
+ template <class _R2, class ..._Ap>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;}
- template <class _R2, class _Cp, class ..._Ap>
+ static bool __not_null(_R2 (*__p)(_Ap..., ...)) { return __p; }
+ template <class _Ret, class _Class>
_LIBCPP_INLINE_VISIBILITY
- static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;}
+ static bool __not_null(_Ret _Class::*__p) { return __p; }
template <class _R2, class ..._Ap>
_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.pass.cpp
===================================================================
--- test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
+++ test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
@@ -11,7 +11,7 @@
// class function<R(ArgTypes...)>
-// function(nullptr_t);
+// function(Fp);
#include <functional>
#include <cassert>
Index: test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp
===================================================================
--- /dev/null
+++ test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_nullptr.pass.cpp
@@ -0,0 +1,125 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// class function<R(ArgTypes...)>
+
+// function(Fp);
+
+// Ensure that __not_null works for all function types.
+// See https://llvm.org/bugs/show_bug.cgi?id=23589
+
+#include <functional>
+#include <cassert>
+
+struct A {};
+
+#define NULL_CV_TYPE
+
+#if __cplusplus >= 201103L
+#define TEST_CV_MEM_TYPE_RET(Ret, CV) \
+ test_mf<Ret(A::*)() CV, Ret(A CV &), A CV &>(); \
+ test_mf<Ret(A::*)(...) CV, Ret(A CV &), A CV &>(); \
+ test_mf<Ret(A::*)() CV &, Ret(A CV &), A CV &>(); \
+ test_mf<Ret(A::*)(...) CV &, Ret(A CV &), A CV &>(); \
+ test_mf<Ret(A::*)() CV &&, Ret(A CV &&), A CV &&>(); \
+ test_mf<Ret(A::*)(...) CV &&, Ret(A CV &&), A CV &&>()
+#else
+#define TEST_CV_MEM_TYPE_RET(Ret, CV) \
+ test_mf<Ret(A::*)() CV, Ret(A CV &), A CV &>(); \
+ test_mf<Ret(A::*)(...) CV, Ret(A CV &), A CV &>()
+#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) \
+ test0<void(*)(), void()>(); \
+ test0<void(*)(...), void()>(); \
+ test1<void(*)(int CV), void(int CV)>(); \
+ test1<void(*)(int CV, ...), void(int CV)>();\
+ test2<void(*)(int CV, int CV), void(int CV, int CV)>(); \
+ test2<void(*)(int CV, int CV, ...), void(int CV, int CV)>();\
+ test3<void(*)(int CV, int CV, int CV), void(int CV, int CV, int CV)>(); \
+ test3<void(*)(int CV, int CV, int CV...), void(int CV, int CV, int CV)>();\
+ test0<int(*)(), int()>(); \
+ test0<int(*)(...), int()>(); \
+ test1<int(*)(int CV), int(int CV)>(); \
+ test1<int(*)(int CV, ...), int(int CV)>();\
+ test2<int(*)(int CV, int CV), int(int CV, int CV)>(); \
+ test2<int(*)(int CV, int CV, ...), int(int CV, int CV)>();\
+ test3<int(*)(int CV, int CV, int CV), int(int CV, int CV, int CV)>(); \
+ test3<int(*)(int CV, int CV, int CV...), int(int CV, int CV, int CV)>()
+
+
+template <class MemFn, class Fn, class CVA>
+void test_mf() {
+ MemFn mf = nullptr;
+ std::function<Fn> f = mf;
+ A a;
+ try { f(static_cast<CVA>(a)); assert(false); }
+ catch (std::bad_function_call&) {}
+}
+
+template <class RawFn, class Fn>
+void test0() {
+ RawFn fn = nullptr;
+ std::function<Fn> f = fn;
+ try { f(); assert(false); }
+ catch (std::bad_function_call&) {}
+}
+
+template <class RawFn, class Fn>
+void test1() {
+ RawFn fn = nullptr;
+ std::function<Fn> f = fn;
+ int x = 42;
+ try { f(x); assert(false); }
+ catch (std::bad_function_call&) {}
+}
+
+template <class RawFn, class Fn>
+void test2() {
+ RawFn fn = nullptr;
+ std::function<Fn> f = fn;
+ int x = 42;
+ try { f(x, x); assert(false); }
+ catch (std::bad_function_call&) {}
+}
+
+template <class RawFn, class Fn>
+void test3() {
+ RawFn fn = nullptr;
+ std::function<Fn> f = fn;
+ int x = 42;
+ try { f(x, x, x); assert(false); }
+ catch (std::bad_function_call&) {}
+}
+
+int main() {
+ {
+ 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
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits