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 <new>
20 
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 
24 namespace absl {
25 ABSL_NAMESPACE_BEGIN
26 namespace container_internal {
27 namespace {
28 
29 using ::testing::MockFunction;
30 using ::testing::AnyNumber;
31 using ::testing::ReturnRef;
32 
33 using Slot = int;
34 
35 struct PolicyWithoutOptionalOps {
36   using slot_type = Slot;
37   using key_type = Slot;
38   using init_type = Slot;
39 
40   static std::function<void(void*, Slot*, Slot)> construct;
41   static std::function<void(void*, Slot*)> destroy;
42 
43   static std::function<Slot&(Slot*)> element;
44 };
45 
46 std::function<void(void*, Slot*, Slot)> PolicyWithoutOptionalOps::construct;
47 std::function<void(void*, Slot*)> PolicyWithoutOptionalOps::destroy;
48 
49 std::function<Slot&(Slot*)> PolicyWithoutOptionalOps::element;
50 
51 struct PolicyWithOptionalOps : PolicyWithoutOptionalOps {
52   static std::function<void(void*, Slot*, Slot*)> transfer;
53 };
54 
55 std::function<void(void*, Slot*, Slot*)> PolicyWithOptionalOps::transfer;
56 
57 struct Test : ::testing::Test {
Testabsl::container_internal::__anonae439deb0111::Test58   Test() {
59     PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) {
60       construct.Call(a1, a2, std::move(a3));
61     };
62     PolicyWithoutOptionalOps::destroy = [&](void* a1, Slot* a2) {
63       destroy.Call(a1, a2);
64     };
65 
66     PolicyWithoutOptionalOps::element = [&](Slot* a1) -> Slot& {
67       return element.Call(a1);
68     };
69 
70     PolicyWithOptionalOps::transfer = [&](void* a1, Slot* a2, Slot* a3) {
71       return transfer.Call(a1, a2, a3);
72     };
73   }
74 
75   std::allocator<Slot> alloc;
76   int a = 53;
77 
78   MockFunction<void(void*, Slot*, Slot)> construct;
79   MockFunction<void(void*, Slot*)> destroy;
80 
81   MockFunction<Slot&(Slot*)> element;
82 
83   MockFunction<void(void*, Slot*, Slot*)> transfer;
84 };
85 
TEST_F(Test,construct)86 TEST_F(Test, construct) {
87   EXPECT_CALL(construct, Call(&alloc, &a, 53));
88   common_policy_traits<PolicyWithoutOptionalOps>::construct(&alloc, &a, 53);
89 }
90 
TEST_F(Test,destroy)91 TEST_F(Test, destroy) {
92   EXPECT_CALL(destroy, Call(&alloc, &a));
93   common_policy_traits<PolicyWithoutOptionalOps>::destroy(&alloc, &a);
94 }
95 
TEST_F(Test,element)96 TEST_F(Test, element) {
97   int b = 0;
98   EXPECT_CALL(element, Call(&a)).WillOnce(ReturnRef(b));
99   EXPECT_EQ(&b, &common_policy_traits<PolicyWithoutOptionalOps>::element(&a));
100 }
101 
TEST_F(Test,without_transfer)102 TEST_F(Test, without_transfer) {
103   int b = 42;
104   EXPECT_CALL(element, Call(&a)).Times(AnyNumber()).WillOnce(ReturnRef(a));
105   EXPECT_CALL(element, Call(&b)).WillOnce(ReturnRef(b));
106   EXPECT_CALL(construct, Call(&alloc, &a, b)).Times(AnyNumber());
107   EXPECT_CALL(destroy, Call(&alloc, &b)).Times(AnyNumber());
108   common_policy_traits<PolicyWithoutOptionalOps>::transfer(&alloc, &a, &b);
109 }
110 
TEST_F(Test,with_transfer)111 TEST_F(Test, with_transfer) {
112   int b = 42;
113   EXPECT_CALL(transfer, Call(&alloc, &a, &b));
114   common_policy_traits<PolicyWithOptionalOps>::transfer(&alloc, &a, &b);
115 }
116 
117 }  // namespace
118 }  // namespace container_internal
119 ABSL_NAMESPACE_END
120 }  // namespace absl
121