abseil-cpp/absl/functional/bind_front_test.cc
Go to the documentation of this file.
1 // Copyright 2018 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/bind_front.h"
16 
17 #include <stddef.h>
18 
19 #include <functional>
20 #include <memory>
21 #include <string>
22 
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 #include "absl/memory/memory.h"
26 
27 namespace {
28 
29 char CharAt(const char* s, size_t index) { return s[index]; }
30 
31 TEST(BindTest, Basics) {
32  EXPECT_EQ('C', absl::bind_front(CharAt)("ABC", 2));
33  EXPECT_EQ('C', absl::bind_front(CharAt, "ABC")(2));
34  EXPECT_EQ('C', absl::bind_front(CharAt, "ABC", 2)());
35 }
36 
37 TEST(BindTest, Lambda) {
38  auto lambda = [](int x, int y, int z) { return x + y + z; };
39  EXPECT_EQ(6, absl::bind_front(lambda)(1, 2, 3));
40  EXPECT_EQ(6, absl::bind_front(lambda, 1)(2, 3));
41  EXPECT_EQ(6, absl::bind_front(lambda, 1, 2)(3));
42  EXPECT_EQ(6, absl::bind_front(lambda, 1, 2, 3)());
43 }
44 
45 struct Functor {
46  std::string operator()() & { return "&"; }
47  std::string operator()() const& { return "const&"; }
48  std::string operator()() && { return "&&"; }
49  std::string operator()() const&& { return "const&&"; }
50 };
51 
52 TEST(BindTest, PerfectForwardingOfBoundArgs) {
53  auto f = absl::bind_front(Functor());
54  const auto& cf = f;
55  EXPECT_EQ("&", f());
56  EXPECT_EQ("const&", cf());
57  EXPECT_EQ("&&", std::move(f)());
58  EXPECT_EQ("const&&", std::move(cf)());
59 }
60 
61 struct ArgDescribe {
62  std::string operator()(int&) const { return "&"; } // NOLINT
63  std::string operator()(const int&) const { return "const&"; } // NOLINT
64  std::string operator()(int&&) const { return "&&"; }
65  std::string operator()(const int&&) const { return "const&&"; }
66 };
67 
68 TEST(BindTest, PerfectForwardingOfFreeArgs) {
69  ArgDescribe f;
70  int i;
71  EXPECT_EQ("&", absl::bind_front(f)(static_cast<int&>(i)));
72  EXPECT_EQ("const&", absl::bind_front(f)(static_cast<const int&>(i)));
73  EXPECT_EQ("&&", absl::bind_front(f)(static_cast<int&&>(i)));
74  EXPECT_EQ("const&&", absl::bind_front(f)(static_cast<const int&&>(i)));
75 }
76 
77 struct NonCopyableFunctor {
78  NonCopyableFunctor() = default;
79  NonCopyableFunctor(const NonCopyableFunctor&) = delete;
80  NonCopyableFunctor& operator=(const NonCopyableFunctor&) = delete;
81  const NonCopyableFunctor* operator()() const { return this; }
82 };
83 
84 TEST(BindTest, RefToFunctor) {
85  // It won't copy/move the functor and use the original object.
86  NonCopyableFunctor ncf;
87  auto bound_ncf = absl::bind_front(std::ref(ncf));
88  auto bound_ncf_copy = bound_ncf;
89  EXPECT_EQ(&ncf, bound_ncf_copy());
90 }
91 
92 struct Struct {
94 };
95 
96 TEST(BindTest, StoreByCopy) {
97  Struct s = {"hello"};
98  auto f = absl::bind_front(&Struct::value, s);
99  auto g = f;
100  EXPECT_EQ("hello", f());
101  EXPECT_EQ("hello", g());
102  EXPECT_NE(&s.value, &f());
103  EXPECT_NE(&s.value, &g());
104  EXPECT_NE(&g(), &f());
105 }
106 
107 struct NonCopyable {
108  explicit NonCopyable(const std::string& s) : value(s) {}
109  NonCopyable(const NonCopyable&) = delete;
110  NonCopyable& operator=(const NonCopyable&) = delete;
111 
113 };
114 
115 const std::string& GetNonCopyableValue(const NonCopyable& n) { return n.value; }
116 
117 TEST(BindTest, StoreByRef) {
118  NonCopyable s("hello");
119  auto f = absl::bind_front(&GetNonCopyableValue, std::ref(s));
120  EXPECT_EQ("hello", f());
121  EXPECT_EQ(&s.value, &f());
122  auto g = std::move(f); // NOLINT
123  EXPECT_EQ("hello", g());
124  EXPECT_EQ(&s.value, &g());
125  s.value = "goodbye";
126  EXPECT_EQ("goodbye", g());
127 }
128 
129 TEST(BindTest, StoreByCRef) {
130  NonCopyable s("hello");
131  auto f = absl::bind_front(&GetNonCopyableValue, std::cref(s));
132  EXPECT_EQ("hello", f());
133  EXPECT_EQ(&s.value, &f());
134  auto g = std::move(f); // NOLINT
135  EXPECT_EQ("hello", g());
136  EXPECT_EQ(&s.value, &g());
137  s.value = "goodbye";
138  EXPECT_EQ("goodbye", g());
139 }
140 
141 const std::string& GetNonCopyableValueByWrapper(
142  std::reference_wrapper<NonCopyable> n) {
143  return n.get().value;
144 }
145 
146 TEST(BindTest, StoreByRefInvokeByWrapper) {
147  NonCopyable s("hello");
148  auto f = absl::bind_front(GetNonCopyableValueByWrapper, std::ref(s));
149  EXPECT_EQ("hello", f());
150  EXPECT_EQ(&s.value, &f());
151  auto g = std::move(f);
152  EXPECT_EQ("hello", g());
153  EXPECT_EQ(&s.value, &g());
154  s.value = "goodbye";
155  EXPECT_EQ("goodbye", g());
156 }
157 
158 TEST(BindTest, StoreByPointer) {
159  NonCopyable s("hello");
161  EXPECT_EQ("hello", f());
162  EXPECT_EQ(&s.value, &f());
163  auto g = std::move(f);
164  EXPECT_EQ("hello", g());
165  EXPECT_EQ(&s.value, &g());
166 }
167 
168 int Sink(std::unique_ptr<int> p) {
169  return *p;
170 }
171 
172 std::unique_ptr<int> Factory(int n) { return absl::make_unique<int>(n); }
173 
174 TEST(BindTest, NonCopyableArg) {
175  EXPECT_EQ(42, absl::bind_front(Sink)(absl::make_unique<int>(42)));
176  EXPECT_EQ(42, absl::bind_front(Sink, absl::make_unique<int>(42))());
177 }
178 
179 TEST(BindTest, NonCopyableResult) {
180  EXPECT_THAT(absl::bind_front(Factory)(42), ::testing::Pointee(42));
181  EXPECT_THAT(absl::bind_front(Factory, 42)(), ::testing::Pointee(42));
182 }
183 
184 // is_copy_constructible<FalseCopyable<unique_ptr<T>> is true but an attempt to
185 // instantiate the copy constructor leads to a compile error. This is similar
186 // to how standard containers behave.
187 template <class T>
188 struct FalseCopyable {
189  FalseCopyable() {}
190  FalseCopyable(const FalseCopyable& other) : m(other.m) {}
191  FalseCopyable(FalseCopyable&& other) : m(std::move(other.m)) {}
192  T m;
193 };
194 
195 int GetMember(FalseCopyable<std::unique_ptr<int>> x) { return *x.m; }
196 
197 TEST(BindTest, WrappedMoveOnly) {
198  FalseCopyable<std::unique_ptr<int>> x;
199  x.m = absl::make_unique<int>(42);
200  auto f = absl::bind_front(&GetMember, std::move(x));
201  EXPECT_EQ(42, std::move(f)());
202 }
203 
204 int Plus(int a, int b) { return a + b; }
205 
206 TEST(BindTest, ConstExpr) {
207  constexpr auto f = absl::bind_front(CharAt);
208  EXPECT_EQ(f("ABC", 1), 'B');
209  static constexpr int five = 5;
210  constexpr auto plus5 = absl::bind_front(Plus, five);
211  EXPECT_EQ(plus5(1), 6);
212 
213  // There seems to be a bug in MSVC dealing constexpr construction of
214  // char[]. Notice 'plus5' above; 'int' works just fine.
215 #if !(defined(_MSC_VER) && _MSC_VER < 1910)
216  static constexpr char data[] = "DEF";
217  constexpr auto g = absl::bind_front(CharAt, data);
218  EXPECT_EQ(g(1), 'E');
219 #endif
220 }
221 
222 struct ManglingCall {
223  int operator()(int, double, std::string) const { return 0; }
224 };
225 
226 TEST(BindTest, Mangling) {
227  // We just want to generate a particular instantiation to see its mangling.
228  absl::bind_front(ManglingCall{}, 1, 3.3)("A");
229 }
230 
231 } // namespace
testing::Pointee
internal::PointeeMatcher< InnerMatcher > Pointee(const InnerMatcher &inner_matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8691
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
absl::bind_front
constexpr ABSL_NAMESPACE_BEGIN functional_internal::bind_front_t< F, BoundArgs... > bind_front(F &&func, BoundArgs &&... args)
Definition: abseil-cpp/absl/functional/bind_front.h:182
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
y
const double y
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3611
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
xds_manager.p
p
Definition: xds_manager.py:60
z
Uncopyable z
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3612
T
#define T(upbtypeconst, upbtype, ctype, default_value)
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
TEST
#define TEST(name, init_size,...)
Definition: arena_test.cc:75
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2028
ref
unsigned ref
Definition: cxa_demangle.cpp:4909
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
g
struct @717 g
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
value
const char * value
Definition: hpack_parser_table.cc:165
Struct
struct Struct Struct
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:670
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
regress.m
m
Definition: regress/regress.py:25
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:48