function_view_unittest.cc (4618B)
1 /* 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "api/function_view.h" 12 13 #include <memory> 14 #include <utility> 15 16 #include "test/gtest.h" 17 18 namespace webrtc { 19 20 namespace { 21 22 int CallWith33(FunctionView<int(int)> fv) { 23 return fv ? fv(33) : -1; 24 } 25 26 int Add33(int x) { 27 return x + 33; 28 } 29 30 } // namespace 31 32 // Test the main use case of FunctionView: implicitly converting a callable 33 // argument. 34 TEST(FunctionViewTest, ImplicitConversion) { 35 EXPECT_EQ(38, CallWith33([](int x) { return x + 5; })); 36 EXPECT_EQ(66, CallWith33(Add33)); 37 EXPECT_EQ(-1, CallWith33(nullptr)); 38 } 39 40 TEST(FunctionViewTest, IntIntLambdaWithoutState) { 41 auto f = [](int x) { return x + 1; }; 42 EXPECT_EQ(18, f(17)); 43 FunctionView<int(int)> fv(f); 44 EXPECT_TRUE(fv); 45 EXPECT_EQ(18, fv(17)); 46 } 47 48 TEST(FunctionViewTest, IntVoidLambdaWithState) { 49 int x = 13; 50 auto f = [x]() mutable { return ++x; }; 51 FunctionView<int()> fv(f); 52 EXPECT_TRUE(fv); 53 EXPECT_EQ(14, f()); 54 EXPECT_EQ(15, fv()); 55 EXPECT_EQ(16, f()); 56 EXPECT_EQ(17, fv()); 57 } 58 59 TEST(FunctionViewTest, IntIntFunction) { 60 FunctionView<int(int)> fv(Add33); 61 EXPECT_TRUE(fv); 62 EXPECT_EQ(50, fv(17)); 63 } 64 65 TEST(FunctionViewTest, IntIntFunctionPointer) { 66 FunctionView<int(int)> fv(&Add33); 67 EXPECT_TRUE(fv); 68 EXPECT_EQ(50, fv(17)); 69 } 70 71 TEST(FunctionViewTest, Null) { 72 // These two call constructors that statically construct null FunctionViews. 73 EXPECT_FALSE(FunctionView<int()>()); 74 EXPECT_FALSE(FunctionView<int()>(nullptr)); 75 76 // This calls the constructor for function pointers. 77 EXPECT_FALSE(FunctionView<int()>(reinterpret_cast<int (*)()>(0))); 78 } 79 80 // Ensure that FunctionView handles move-only arguments and return values. 81 TEST(FunctionViewTest, UniquePtrPassthrough) { 82 auto f = [](std::unique_ptr<int> x) { return x; }; 83 FunctionView<std::unique_ptr<int>(std::unique_ptr<int>)> fv(f); 84 std::unique_ptr<int> x(new int); 85 int* x_addr = x.get(); 86 auto y = fv(std::move(x)); 87 EXPECT_EQ(x_addr, y.get()); 88 } 89 90 TEST(FunctionViewTest, CopyConstructor) { 91 auto f17 = [] { return 17; }; 92 FunctionView<int()> fv1(f17); 93 FunctionView<int()> fv2(fv1); 94 EXPECT_EQ(17, fv1()); 95 EXPECT_EQ(17, fv2()); 96 } 97 98 TEST(FunctionViewTest, MoveConstructorIsCopy) { 99 auto f17 = [] { return 17; }; 100 FunctionView<int()> fv1(f17); 101 FunctionView<int()> fv2(std::move(fv1)); // NOLINT 102 EXPECT_EQ(17, fv1()); 103 EXPECT_EQ(17, fv2()); 104 } 105 106 TEST(FunctionViewTest, CopyAssignment) { 107 auto f17 = [] { return 17; }; 108 FunctionView<int()> fv1(f17); 109 auto f23 = [] { return 23; }; 110 FunctionView<int()> fv2(f23); 111 EXPECT_EQ(17, fv1()); 112 EXPECT_EQ(23, fv2()); 113 fv2 = fv1; 114 EXPECT_EQ(17, fv1()); 115 EXPECT_EQ(17, fv2()); 116 } 117 118 TEST(FunctionViewTest, MoveAssignmentIsCopy) { 119 auto f17 = [] { return 17; }; 120 FunctionView<int()> fv1(f17); 121 auto f23 = [] { return 23; }; 122 FunctionView<int()> fv2(f23); 123 EXPECT_EQ(17, fv1()); 124 EXPECT_EQ(23, fv2()); 125 fv2 = std::move(fv1); // NOLINT 126 EXPECT_EQ(17, fv1()); 127 EXPECT_EQ(17, fv2()); 128 } 129 130 TEST(FunctionViewTest, Swap) { 131 auto f17 = [] { return 17; }; 132 FunctionView<int()> fv1(f17); 133 auto f23 = [] { return 23; }; 134 FunctionView<int()> fv2(f23); 135 EXPECT_EQ(17, fv1()); 136 EXPECT_EQ(23, fv2()); 137 using std::swap; 138 swap(fv1, fv2); 139 EXPECT_EQ(23, fv1()); 140 EXPECT_EQ(17, fv2()); 141 } 142 143 // Ensure that when you copy-construct a FunctionView, the new object points to 144 // the same function as the old one (as opposed to the new object pointing to 145 // the old one). 146 TEST(FunctionViewTest, CopyConstructorChaining) { 147 auto f17 = [] { return 17; }; 148 FunctionView<int()> fv1(f17); 149 FunctionView<int()> fv2(fv1); 150 EXPECT_EQ(17, fv1()); 151 EXPECT_EQ(17, fv2()); 152 auto f23 = [] { return 23; }; 153 fv1 = f23; 154 EXPECT_EQ(23, fv1()); 155 EXPECT_EQ(17, fv2()); 156 } 157 158 // Ensure that when you assign one FunctionView to another, we actually make a 159 // copy (as opposed to making the second FunctionView point to the first one). 160 TEST(FunctionViewTest, CopyAssignmentChaining) { 161 auto f17 = [] { return 17; }; 162 FunctionView<int()> fv1(f17); 163 FunctionView<int()> fv2; 164 EXPECT_TRUE(fv1); 165 EXPECT_EQ(17, fv1()); 166 EXPECT_FALSE(fv2); 167 fv2 = fv1; 168 EXPECT_EQ(17, fv1()); 169 EXPECT_EQ(17, fv2()); 170 auto f23 = [] { return 23; }; 171 fv1 = f23; 172 EXPECT_EQ(23, fv1()); 173 EXPECT_EQ(17, fv2()); 174 } 175 176 } // namespace webrtc