1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // FIXME(EricWF): Make this test pass in C++03 with Clang once the transition 10 // has gotten far enough that __invoke works. 11 // XFAIL: c++03 12 13 // <functional> 14 15 // INVOKE (f, t1, t2, ..., tN) 16 17 //------------------------------------------------------------------------------ 18 // TESTING INVOKE(f, t1, t2, ..., tN) 19 // - Bullet 4 -- t1.*f 20 // - Bullet 5 -- t1.get().*f // t1 is a reference wrapper. 21 // - Bullet 6 -- (*t1).*f 22 // 23 // Overview: 24 // Bullets 4, 5 and 6 handle the case where 'f' is a pointer to member object. 25 // Bullet 4 only handles the cases where t1 is an object of type T or a 26 // type derived from 'T'. Bullet 5 handles cases where 't1' is a reference_wrapper 27 // and bullet 6 handles all other cases. 28 // 29 // Concerns: 30 // 1) The return type is always an lvalue reference. 31 // 2) The return type is not less cv-qualified that the object that contains it. 32 // 3) The return type is not less cv-qualified than object type. 33 // 4) The call object is perfectly forwarded. 34 // 5) Classes that are publicly derived from 'T' are accepted as the call object 35 // 6) All types that dereference to T or a type derived from T can be used 36 // as the call object. 37 // 7) Pointers to T or a type derived from T can be used as the call object. 38 // 8) reference_wrapper's are properly unwrapped before invoking the function. 39 40 #include <functional> 41 #include <cassert> 42 #include <type_traits> 43 #include <utility> 44 45 #include "test_macros.h" 46 #include "invoke_helpers.h" 47 48 template <class Tp> 49 struct TestMemberObject { 50 TestMemberObject() : object() {} 51 Tp object; 52 private: 53 TestMemberObject(TestMemberObject const&); 54 TestMemberObject& operator=(TestMemberObject const&); 55 }; 56 57 template <class ObjectType> 58 struct TestCase { 59 public: 60 61 static void run() { TestCase().doTest(); } 62 63 private: 64 typedef TestMemberObject<ObjectType> TestType; 65 66 //========================================================================== 67 // TEST DISPATCH 68 void doTest() { 69 typedef DerivedFromType<TestType> Derived; 70 TestType obj; 71 TestType* obj_ptr = &obj; 72 Derived der; 73 Derived* der_ptr = &der; 74 DerefToType<TestType> dref; 75 DerefPropType<TestType> dref2; 76 std::reference_wrapper<TestType> rref(obj); 77 std::reference_wrapper<Derived> drref(der); 78 79 { 80 typedef ObjectType (TestType::*MemPtr); 81 typedef ObjectType E; 82 MemPtr M = &TestType::object; 83 runTestDispatch<E>(M, obj, &obj.object); 84 runTestDispatch<E>(M, der, &der.object); 85 runTestDispatch<E>(M, dref2, &dref2.object.object); 86 runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); 87 runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); 88 #if TEST_STD_VER >= 11 89 runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); 90 runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); 91 #endif 92 runTestNoPropDispatch<E>(M, dref, &dref.object.object); 93 } 94 { 95 typedef ObjectType const (TestType::*CMemPtr); 96 typedef ObjectType const E; 97 CMemPtr M = &TestType::object; 98 runTestDispatch<E>(M, obj, &obj.object); 99 runTestDispatch<E>(M, der, &der.object); 100 runTestDispatch<E>(M, dref2, &dref2.object.object); 101 runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); 102 runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); 103 #if TEST_STD_VER >= 11 104 runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); 105 runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); 106 #endif 107 runTestNoPropDispatch<E>(M, dref, &dref.object.object); 108 } 109 { 110 typedef ObjectType volatile (TestType::*VMemPtr); 111 typedef ObjectType volatile E; 112 VMemPtr M = &TestType::object; 113 runTestDispatch<E>(M, obj, &obj.object); 114 runTestDispatch<E>(M, der, &der.object); 115 runTestDispatch<E>(M, dref2, &dref2.object.object); 116 runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); 117 runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); 118 #if TEST_STD_VER >= 11 119 runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); 120 runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); 121 #endif 122 runTestNoPropDispatch<E>(M, dref, &dref.object.object); 123 } 124 { 125 typedef ObjectType const volatile (TestType::*CVMemPtr); 126 typedef ObjectType const volatile E; 127 CVMemPtr M = &TestType::object; 128 runTestDispatch<E>(M, obj, &obj.object); 129 runTestDispatch<E>(M, der, &der.object); 130 runTestDispatch<E>(M, dref2, &dref2.object.object); 131 runTestPropCVDispatch<E>(M, obj_ptr, &obj_ptr->object); 132 runTestPropCVDispatch<E>(M, der_ptr, &der_ptr->object); 133 #if TEST_STD_VER >= 11 134 runTestPropCVDispatch<E>(M, rref, &(rref.get().object)); 135 runTestPropCVDispatch<E>(M, drref, &(drref.get().object)); 136 #endif 137 runTestNoPropDispatch<E>(M, dref, &dref.object.object); 138 } 139 } 140 141 template <class Expect, class Fn, class T> 142 void runTestDispatch(Fn M, T& obj, ObjectType* expect) { 143 runTest<Expect &> (M, C_<T&>(obj), expect); 144 runTest<Expect const&> (M, C_<T const&>(obj), expect); 145 runTest<Expect volatile&> (M, C_<T volatile&>(obj), expect); 146 runTest<Expect const volatile&>(M, C_<T const volatile&>(obj), expect); 147 #if TEST_STD_VER >= 11 148 runTest<Expect&&> (M, C_<T&&>(obj), expect); 149 runTest<Expect const&&> (M, C_<T const&&>(obj), expect); 150 runTest<Expect volatile&&> (M, C_<T volatile&&>(obj), expect); 151 runTest<Expect const volatile&&>(M, C_<T const volatile&&>(obj), expect); 152 #endif 153 } 154 155 template <class Expect, class Fn, class T> 156 void runTestPropCVDispatch(Fn M, T& obj, ObjectType* expect) { 157 runTest<Expect &> (M, obj, expect); 158 runTest<Expect const&> (M, makeConst(obj), expect); 159 runTest<Expect volatile&> (M, makeVolatile(obj), expect); 160 runTest<Expect const volatile&>(M, makeCV(obj), expect); 161 } 162 163 template <class Expect, class Fn, class T> 164 void runTestNoPropDispatch(Fn M, T& obj, ObjectType* expect) { 165 runTest<Expect&>(M, C_<T &>(obj), expect); 166 runTest<Expect&>(M, C_<T const&>(obj), expect); 167 runTest<Expect&>(M, C_<T volatile&>(obj), expect); 168 runTest<Expect&>(M, C_<T const volatile&>(obj), expect); 169 #if TEST_STD_VER >= 11 170 runTest<Expect&>(M, C_<T&&>(obj), expect); 171 runTest<Expect&>(M, C_<T const&&>(obj), expect); 172 runTest<Expect&>(M, C_<T volatile&&>(obj), expect); 173 runTest<Expect&>(M, C_<T const volatile&&>(obj), expect); 174 #endif 175 } 176 177 template <class Expect, class Fn, class T> 178 void runTest(Fn M, const T& obj, ObjectType* expect) { 179 static_assert((std::is_same< 180 decltype(std::__invoke(M, obj)), Expect 181 >::value), ""); 182 Expect e = std::__invoke(M, obj); 183 assert(&e == expect); 184 } 185 186 template <class Expect, class Fn, class T> 187 #if TEST_STD_VER >= 11 188 void runTest(Fn M, T&& obj, ObjectType* expect) { 189 #else 190 void runTest(Fn M, T& obj, ObjectType* expect ) { 191 #endif 192 { 193 static_assert((std::is_same< 194 decltype(std::__invoke(M, std::forward<T>(obj))), Expect 195 >::value), ""); 196 Expect e = std::__invoke(M, std::forward<T>(obj)); 197 assert(&e == expect); 198 } 199 } 200 }; 201 202 int main(int, char**) { 203 TestCase<ArgType>::run(); 204 TestCase<ArgType const>::run(); 205 TestCase<ArgType volatile>::run(); 206 TestCase<ArgType const volatile>::run(); 207 TestCase<ArgType*>::run(); 208 209 return 0; 210 } 211