abseil-cpp/absl/functional/function_ref_test.cc
Go to the documentation of this file.
1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/functional/function_ref.h"
16 
17 #include <functional>
18 #include <memory>
19 
20 #include "gmock/gmock.h"
21 #include "gtest/gtest.h"
22 #include "absl/container/internal/test_instance_tracker.h"
23 #include "absl/memory/memory.h"
24 
25 namespace absl {
27 namespace {
28 
29 void RunFun(FunctionRef<void()> f) { f(); }
30 
31 TEST(FunctionRefTest, Lambda) {
32  bool ran = false;
33  RunFun([&] { ran = true; });
34  EXPECT_TRUE(ran);
35 }
36 
37 int Function() { return 1337; }
38 
39 TEST(FunctionRefTest, Function1) {
41  EXPECT_EQ(1337, ref());
42 }
43 
44 TEST(FunctionRefTest, Function2) {
46  EXPECT_EQ(1337, ref());
47 }
48 
49 int NoExceptFunction() noexcept { return 1337; }
50 
51 // TODO(jdennett): Add a test for noexcept member functions.
52 TEST(FunctionRefTest, NoExceptFunction) {
54  EXPECT_EQ(1337, ref());
55 }
56 
57 TEST(FunctionRefTest, ForwardsArgs) {
58  auto l = [](std::unique_ptr<int> i) { return *i; };
59  FunctionRef<int(std::unique_ptr<int>)> ref(l);
60  EXPECT_EQ(42, ref(absl::make_unique<int>(42)));
61 }
62 
63 TEST(FunctionRef, ReturnMoveOnly) {
64  auto l = [] { return absl::make_unique<int>(29); };
66  EXPECT_EQ(29, *ref());
67 }
68 
69 TEST(FunctionRef, ManyArgs) {
70  auto l = [](int a, int b, int c) { return a + b + c; };
71  FunctionRef<int(int, int, int)> ref(l);
72  EXPECT_EQ(6, ref(1, 2, 3));
73 }
74 
75 TEST(FunctionRef, VoidResultFromNonVoidFunctor) {
76  bool ran = false;
77  auto l = [&]() -> int {
78  ran = true;
79  return 2;
80  };
81  FunctionRef<void()> ref(l);
82  ref();
83  EXPECT_TRUE(ran);
84 }
85 
86 TEST(FunctionRef, CastFromDerived) {
87  struct Base {};
88  struct Derived : public Base {};
89 
90  Derived d;
91  auto l1 = [&](Base* b) { EXPECT_EQ(&d, b); };
92  FunctionRef<void(Derived*)> ref1(l1);
93  ref1(&d);
94 
95  auto l2 = [&]() -> Derived* { return &d; };
96  FunctionRef<Base*()> ref2(l2);
97  EXPECT_EQ(&d, ref2());
98 }
99 
100 TEST(FunctionRef, VoidResultFromNonVoidFuncton) {
101  FunctionRef<void()> ref(Function);
102  ref();
103 }
104 
105 TEST(FunctionRef, MemberPtr) {
106  struct S {
107  int i;
108  };
109 
110  S s{1100111};
111  auto mem_ptr = &S::i;
112  FunctionRef<int(const S& s)> ref(mem_ptr);
113  EXPECT_EQ(1100111, ref(s));
114 }
115 
116 TEST(FunctionRef, MemberFun) {
117  struct S {
118  int i;
119  int get_i() const { return i; }
120  };
121 
122  S s{22};
123  auto mem_fun_ptr = &S::get_i;
124  FunctionRef<int(const S& s)> ref(mem_fun_ptr);
125  EXPECT_EQ(22, ref(s));
126 }
127 
128 TEST(FunctionRef, MemberFunRefqualified) {
129  struct S {
130  int i;
131  int get_i() && { return i; }
132  };
133  auto mem_fun_ptr = &S::get_i;
134  S s{22};
135  FunctionRef<int(S && s)> ref(mem_fun_ptr);
136  EXPECT_EQ(22, ref(std::move(s)));
137 }
138 
139 #if !defined(_WIN32) && defined(GTEST_HAS_DEATH_TEST)
140 
141 TEST(FunctionRef, MemberFunRefqualifiedNull) {
142  struct S {
143  int i;
144  int get_i() && { return i; }
145  };
146  auto mem_fun_ptr = &S::get_i;
147  mem_fun_ptr = nullptr;
148  EXPECT_DEBUG_DEATH({ FunctionRef<int(S && s)> ref(mem_fun_ptr); }, "");
149 }
150 
151 TEST(FunctionRef, NullMemberPtrAssertFails) {
152  struct S {
153  int i;
154  };
155  using MemberPtr = int S::*;
156  MemberPtr mem_ptr = nullptr;
157  EXPECT_DEBUG_DEATH({ FunctionRef<int(const S& s)> ref(mem_ptr); }, "");
158 }
159 
160 #endif // GTEST_HAS_DEATH_TEST
161 
162 TEST(FunctionRef, CopiesAndMovesPerPassByValue) {
167  ref(instance);
168  EXPECT_EQ(tracker.copies(), 1);
169  EXPECT_EQ(tracker.moves(), 1);
170 }
171 
172 TEST(FunctionRef, CopiesAndMovesPerPassByRef) {
175  auto l = [](const absl::test_internal::CopyableMovableInstance&) {};
177  ref(instance);
178  EXPECT_EQ(tracker.copies(), 0);
179  EXPECT_EQ(tracker.moves(), 0);
180 }
181 
182 TEST(FunctionRef, CopiesAndMovesPerPassByValueCallByMove) {
188  EXPECT_EQ(tracker.copies(), 0);
189  EXPECT_EQ(tracker.moves(), 2);
190 }
191 
192 TEST(FunctionRef, CopiesAndMovesPerPassByValueToRef) {
195  auto l = [](const absl::test_internal::CopyableMovableInstance&) {};
198  EXPECT_EQ(tracker.copies(), 0);
199  EXPECT_EQ(tracker.moves(), 1);
200 }
201 
202 TEST(FunctionRef, PassByValueTypes) {
206  struct Trivial {
207  void* p[2];
208  };
209  struct LargeTrivial {
210  void* p[3];
211  };
212 
213  static_assert(std::is_same<Invoker<void, int>, void (*)(VoidPtr, int)>::value,
214  "Scalar types should be passed by value");
215  static_assert(
216  std::is_same<Invoker<void, Trivial>, void (*)(VoidPtr, Trivial)>::value,
217  "Small trivial types should be passed by value");
218  static_assert(std::is_same<Invoker<void, LargeTrivial>,
219  void (*)(VoidPtr, LargeTrivial &&)>::value,
220  "Large trivial types should be passed by rvalue reference");
221  static_assert(
222  std::is_same<Invoker<void, CopyableMovableInstance>,
223  void (*)(VoidPtr, CopyableMovableInstance &&)>::value,
224  "Types with copy/move ctor should be passed by rvalue reference");
225 
226  // References are passed as references.
227  static_assert(
228  std::is_same<Invoker<void, int&>, void (*)(VoidPtr, int&)>::value,
229  "Reference types should be preserved");
230  static_assert(
231  std::is_same<Invoker<void, CopyableMovableInstance&>,
232  void (*)(VoidPtr, CopyableMovableInstance&)>::value,
233  "Reference types should be preserved");
234  static_assert(
235  std::is_same<Invoker<void, CopyableMovableInstance&&>,
236  void (*)(VoidPtr, CopyableMovableInstance &&)>::value,
237  "Reference types should be preserved");
238 
239  // Make sure the address of an object received by reference is the same as the
240  // addess of the object passed by the caller.
241  {
242  LargeTrivial obj;
243  auto test = [&obj](LargeTrivial& input) { ASSERT_EQ(&input, &obj); };
244  absl::FunctionRef<void(LargeTrivial&)> ref(test);
245  ref(obj);
246  }
247 
248  {
249  Trivial obj;
250  auto test = [&obj](Trivial& input) { ASSERT_EQ(&input, &obj); };
251  absl::FunctionRef<void(Trivial&)> ref(test);
252  ref(obj);
253  }
254 }
255 
256 } // namespace
258 } // namespace absl
obj
OPENSSL_EXPORT const ASN1_OBJECT * obj
Definition: x509.h:1671
S
#define S(s)
test
Definition: spinlock_test.cc:36
instance
RefCountedPtr< grpc_tls_certificate_provider > instance
Definition: xds_server_config_fetcher.cc:224
absl::functional_internal::VoidPtr
Definition: abseil-cpp/absl/functional/internal/function_ref.h:35
absl::TEST
TEST(NotificationTest, SanityTest)
Definition: abseil-cpp/absl/synchronization/notification_test.cc:126
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
xds_interop_client.int
int
Definition: xds_interop_client.py:113
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
ref
unsigned ref
Definition: cxa_demangle.cpp:4909
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
value
const char * value
Definition: hpack_parser_table.cc:165
absl::ABSL_NAMESPACE_BEGIN::RunFun
void RunFun(FunctionRef< void()> f)
Definition: abseil-cpp/absl/functional/function_ref_test.cc:29
absl::functional_internal::Invoker
R(*)(VoidPtr, typename ForwardT< Args >::type...) Invoker
Definition: abseil-cpp/absl/functional/internal/function_ref.h:63
absl::FunctionRef
Definition: abseil-cpp/absl/functional/function_ref.h:65
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
absl::test_internal::CopyableMovableInstance
Definition: abseil-cpp/absl/container/internal/test_instance_tracker.h:240
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
absl::test_internal::InstanceTracker
Definition: abseil-cpp/absl/container/internal/test_instance_tracker.h:160
absl::ABSL_NAMESPACE_BEGIN::Function
int Function()
Definition: abseil-cpp/absl/functional/function_ref_test.cc:37
tracker
SessionTracker * tracker
Definition: ssl_session_cache_test.cc:38
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::ABSL_NAMESPACE_BEGIN::NoExceptFunction
int NoExceptFunction() noexcept
Definition: abseil-cpp/absl/functional/function_ref_test.cc:49
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:25