TestFunctionRef.cpp (3963B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/Assertions.h" 8 #include "mozilla/FunctionRef.h" 9 #include "mozilla/UniquePtr.h" 10 11 using mozilla::FunctionRef; 12 13 #define CHECK(c) \ 14 do { \ 15 bool cond = !!(c); \ 16 MOZ_RELEASE_ASSERT(cond, "Failed assertion: " #c); \ 17 } while (false) 18 19 int addConstRefs(const int& arg1, const int& arg2) { return arg1 + arg2; } 20 21 void incrementPointer(int* arg) { (*arg)++; } 22 23 int increment(int arg) { return arg + 1; } 24 25 int incrementUnique(mozilla::UniquePtr<int> ptr) { return *ptr + 1; } 26 27 static bool helloWorldCalled = false; 28 29 void helloWorld() { helloWorldCalled = true; } 30 31 struct S { 32 static int increment(int arg) { return arg + 1; } 33 }; 34 35 struct Incrementor { 36 int operator()(int arg) { return arg + 1; } 37 }; 38 39 template <typename Fn> 40 struct Caller; 41 42 template <typename Fn, typename... Params> 43 std::invoke_result_t<Fn, Params...> CallFunctionRef(FunctionRef<Fn> aRef, 44 Params... aParams) { 45 return aRef(std::forward<Params>(aParams)...); 46 } 47 48 static void TestNonmemberFunction() { 49 CHECK(CallFunctionRef<int(int)>(increment, 42) == 43); 50 } 51 52 static void TestStaticMemberFunction() { 53 CHECK(CallFunctionRef<int(int)>(&S::increment, 42) == 43); 54 } 55 56 static void TestFunctionObject() { 57 auto incrementor = Incrementor(); 58 CHECK(CallFunctionRef<int(int)>(incrementor, 42) == 43); 59 } 60 61 static void TestFunctionObjectTemporary() { 62 CHECK(CallFunctionRef<int(int)>(Incrementor(), 42) == 43); 63 } 64 65 static void TestLambda() { 66 // Test non-capturing lambda 67 auto lambda1 = [](int arg) { return arg + 1; }; 68 CHECK(CallFunctionRef<int(int)>(lambda1, 42) == 43); 69 70 // Test capturing lambda 71 int one = 1; 72 auto lambda2 = [one](int arg) { return arg + one; }; 73 CHECK(CallFunctionRef<int(int)>(lambda2, 42) == 43); 74 75 CHECK(CallFunctionRef<int(int)>([](int arg) { return arg + 1; }, 42) == 43); 76 } 77 78 static void TestOperatorBool() { 79 auto ToBool = [](FunctionRef<int(int)> aRef) { 80 return static_cast<bool>(aRef); 81 }; 82 CHECK(!ToBool({})); 83 CHECK(ToBool(increment)); 84 CHECK(!ToBool(nullptr)); 85 } 86 87 static void TestReferenceParameters() { 88 int x = 1; 89 int y = 2; 90 CHECK(CallFunctionRef<int(const int&, const int&)>(addConstRefs, x, y) == 3); 91 } 92 93 static void TestVoidNoParameters() { 94 CHECK(!helloWorldCalled); 95 CallFunctionRef<void()>(helloWorld); 96 CHECK(helloWorldCalled); 97 } 98 99 static void TestPointerParameters() { 100 int x = 1; 101 CallFunctionRef<void(int*)>(incrementPointer, &x); 102 CHECK(x == 2); 103 } 104 105 static void TestImplicitFunctorTypeConversion() { 106 auto incrementor = Incrementor(); 107 short x = 1; 108 CHECK(CallFunctionRef<long(short)>(incrementor, x) == 2); 109 } 110 111 static void TestImplicitLambdaTypeConversion() { 112 short x = 1; 113 CHECK(CallFunctionRef<long(short)>([](short arg) { return arg + 1; }, x) == 114 2); 115 } 116 117 static void TestImplicitFunctionPointerTypeConversion() { 118 short x = 1; 119 CHECK(CallFunctionRef<long(short)>(&increment, x) == 2); 120 } 121 122 static void TestMoveOnlyArguments() { 123 CHECK(CallFunctionRef<int(mozilla::UniquePtr<int>)>( 124 &incrementUnique, mozilla::MakeUnique<int>(5)) == 6); 125 } 126 127 int main() { 128 TestNonmemberFunction(); 129 TestStaticMemberFunction(); 130 TestFunctionObject(); 131 TestFunctionObjectTemporary(); 132 TestLambda(); 133 TestOperatorBool(); 134 TestReferenceParameters(); 135 TestPointerParameters(); 136 TestVoidNoParameters(); 137 TestImplicitFunctorTypeConversion(); 138 TestImplicitLambdaTypeConversion(); 139 TestImplicitFunctionPointerTypeConversion(); 140 TestMoveOnlyArguments(); 141 142 printf("TestFunctionRef OK!\n"); 143 return 0; 144 }