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

Reply via email to