• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 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/container/internal/common_policy_traits.h"
16 
17 #include <functional>
18 #include <memory>
19 #include <type_traits>
20 #include <utility>
21 
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "absl/base/config.h"
25 
26 namespace absl {
27 ABSL_NAMESPACE_BEGIN
28 namespace container_internal {
29 namespace {
30 
31 using ::testing::MockFunction;
32 using ::testing::AnyNumber;
33 using ::testing::ReturnRef;
34 
35 using Slot = int;
36 
37 struct PolicyWithoutOptionalOps {
38   using slot_type = Slot;
39   using key_type = Slot;
40   using init_type = Slot;
41 
42   static std::function<void(void*, Slot*, Slot)> construct;
43   static std::function<void(void*, Slot*)> destroy;
44 
45   static std::function<Slot&(Slot*)> element;
46 };
47 
48 std::function<void(void*, Slot*, Slot)> PolicyWithoutOptionalOps::construct;
49 std::function<void(void*, Slot*)> PolicyWithoutOptionalOps::destroy;
50 
51 std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::element;
52 
53 struct PolicyWithOptionalOps : PolicyWithoutOptionalOps {
54   static std::function<void(void*, Slot*, Slot*)> transfer;
55 };
56 std::function<void(void*, Slot*, Slot*)> PolicyWithOptionalOps::transfer;
57 
58 struct PolicyWithMemcpyTransfer : PolicyWithoutOptionalOps {
59   static std::function<std::true_type(void*, Slot*, Slot*)> transfer;
60 };
61 std::function<std::true_type(void*, Slot*, Slot*)>
62     PolicyWithMemcpyTransfer::transfer;
63 
64 struct Test : ::testing::Test {
Testabsl::container_internal::__anon4e6f86040111::Test65   Test() {
66     PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) {
67       construct.Call(a1, a2, std::move(a3));
68     };
69     PolicyWithoutOptionalOps::destroy = [&](void* a1, Slot* a2) {
70       destroy.Call(a1, a2);
71     };
72 
73     PolicyWithoutOptionalOps::element = [&](Slot* a1) -> Slot& {
74       return element.Call(a1);
75     };
76 
77     PolicyWithOptionalOps::transfer = [&](void* a1, Slot* a2, Slot* a3) {
78       return transfer.Call(a1, a2, a3);
79     };
80   }
81 
82   std::allocator<Slot> alloc;
83   int a = 53;
84 
85   MockFunction<void(void*, Slot*, Slot)> construct;
86   MockFunction<void(void*, Slot*)> destroy;
87 
88   MockFunction<Slot&(Slot*)> element;
89 
90   MockFunction<void(void*, Slot*, Slot*)> transfer;
91 };
92 
TEST_F(Test,construct)93 TEST_F(Test, construct) {
94   EXPECT_CALL(construct, Call(&alloc, &a, 53));
95   common_policy_traits<PolicyWithoutOptionalOps>::construct(&alloc, &a, 53);
96 }
97 
TEST_F(Test,destroy)98 TEST_F(Test, destroy) {
99   EXPECT_CALL(destroy, Call(&alloc, &a));
100   common_policy_traits<PolicyWithoutOptionalOps>::destroy(&alloc, &a);
101 }
102 
TEST_F(Test,element)103 TEST_F(Test, element) {
104   int b = 0;
105   EXPECT_CALL(element, Call(&a)).WillOnce(ReturnRef(b));
106   EXPECT_EQ(&b, &common_policy_traits<PolicyWithoutOptionalOps>::element(&a));
107 }
108 
TEST_F(Test,without_transfer)109 TEST_F(Test, without_transfer) {
110   int b = 42;
111   EXPECT_CALL(element, Call(&a)).Times(AnyNumber()).WillOnce(ReturnRef(a));
112   EXPECT_CALL(element, Call(&b)).WillOnce(ReturnRef(b));
113   EXPECT_CALL(construct, Call(&alloc, &a, b)).Times(AnyNumber());
114   EXPECT_CALL(destroy, Call(&alloc, &b)).Times(AnyNumber());
115   common_policy_traits<PolicyWithoutOptionalOps>::transfer(&alloc, &a, &b);
116 }
117 
TEST_F(Test,with_transfer)118 TEST_F(Test, with_transfer) {
119   int b = 42;
120   EXPECT_CALL(transfer, Call(&alloc, &a, &b));
121   common_policy_traits<PolicyWithOptionalOps>::transfer(&alloc, &a, &b);
122 }
123 
TEST(TransferUsesMemcpy,Basic)124 TEST(TransferUsesMemcpy, Basic) {
125   EXPECT_FALSE(
126       common_policy_traits<PolicyWithOptionalOps>::transfer_uses_memcpy());
127   EXPECT_TRUE(
128       common_policy_traits<PolicyWithMemcpyTransfer>::transfer_uses_memcpy());
129 }
130 
131 }  // namespace
132 }  // namespace container_internal
133 ABSL_NAMESPACE_END
134 }  // namespace absl
135