1 // Copyright 2017 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 // Tests for pointer utilities.
16
17 #include "absl/memory/memory.h"
18
19 #include <sys/types.h>
20
21 #include <cstddef>
22 #include <memory>
23 #include <string>
24 #include <type_traits>
25 #include <utility>
26 #include <vector>
27
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30
31 namespace {
32
33 using ::testing::ElementsAre;
34 using ::testing::Return;
35
36 // This class creates observable behavior to verify that a destructor has
37 // been called, via the instance_count variable.
38 class DestructorVerifier {
39 public:
DestructorVerifier()40 DestructorVerifier() { ++instance_count_; }
41 DestructorVerifier(const DestructorVerifier&) = delete;
42 DestructorVerifier& operator=(const DestructorVerifier&) = delete;
~DestructorVerifier()43 ~DestructorVerifier() { --instance_count_; }
44
45 // The number of instances of this class currently active.
instance_count()46 static int instance_count() { return instance_count_; }
47
48 private:
49 // The number of instances of this class currently active.
50 static int instance_count_;
51 };
52
53 int DestructorVerifier::instance_count_ = 0;
54
TEST(WrapUniqueTest,WrapUnique)55 TEST(WrapUniqueTest, WrapUnique) {
56 // Test that the unique_ptr is constructed properly by verifying that the
57 // destructor for its payload gets called at the proper time.
58 {
59 auto dv = new DestructorVerifier;
60 EXPECT_EQ(1, DestructorVerifier::instance_count());
61 std::unique_ptr<DestructorVerifier> ptr = absl::WrapUnique(dv);
62 EXPECT_EQ(1, DestructorVerifier::instance_count());
63 }
64 EXPECT_EQ(0, DestructorVerifier::instance_count());
65 }
66
67 // InitializationVerifier fills in a pattern when allocated so we can
68 // distinguish between its default and value initialized states (without
69 // accessing truly uninitialized memory).
70 struct InitializationVerifier {
71 static constexpr int kDefaultScalar = 0x43;
72 static constexpr int kDefaultArray = 0x4B;
73
operator new__anonf7074e5b0111::InitializationVerifier74 static void* operator new(size_t n) {
75 void* ret = ::operator new(n);
76 memset(ret, kDefaultScalar, n);
77 return ret;
78 }
79
operator new[]__anonf7074e5b0111::InitializationVerifier80 static void* operator new[](size_t n) {
81 void* ret = ::operator new[](n);
82 memset(ret, kDefaultArray, n);
83 return ret;
84 }
85
86 int a;
87 int b;
88 };
89
90 struct ArrayWatch {
operator new[]__anonf7074e5b0111::ArrayWatch91 void* operator new[](size_t n) {
92 allocs().push_back(n);
93 return ::operator new[](n);
94 }
operator delete[]__anonf7074e5b0111::ArrayWatch95 void operator delete[](void* p) { return ::operator delete[](p); }
allocs__anonf7074e5b0111::ArrayWatch96 static std::vector<size_t>& allocs() {
97 static auto& v = *new std::vector<size_t>;
98 return v;
99 }
100 };
101
TEST(RawPtrTest,RawPointer)102 TEST(RawPtrTest, RawPointer) {
103 int i = 5;
104 EXPECT_EQ(&i, absl::RawPtr(&i));
105 }
106
TEST(RawPtrTest,SmartPointer)107 TEST(RawPtrTest, SmartPointer) {
108 int* o = new int(5);
109 std::unique_ptr<int> p(o);
110 EXPECT_EQ(o, absl::RawPtr(p));
111 }
112
113 class IntPointerNonConstDeref {
114 public:
IntPointerNonConstDeref(int * p)115 explicit IntPointerNonConstDeref(int* p) : p_(p) {}
operator !=(const IntPointerNonConstDeref & a,std::nullptr_t)116 friend bool operator!=(const IntPointerNonConstDeref& a, std::nullptr_t) {
117 return a.p_ != nullptr;
118 }
operator *()119 int& operator*() { return *p_; }
120
121 private:
122 std::unique_ptr<int> p_;
123 };
124
TEST(RawPtrTest,SmartPointerNonConstDereference)125 TEST(RawPtrTest, SmartPointerNonConstDereference) {
126 int* o = new int(5);
127 IntPointerNonConstDeref p(o);
128 EXPECT_EQ(o, absl::RawPtr(p));
129 }
130
TEST(RawPtrTest,NullValuedRawPointer)131 TEST(RawPtrTest, NullValuedRawPointer) {
132 int* p = nullptr;
133 EXPECT_EQ(nullptr, absl::RawPtr(p));
134 }
135
TEST(RawPtrTest,NullValuedSmartPointer)136 TEST(RawPtrTest, NullValuedSmartPointer) {
137 std::unique_ptr<int> p;
138 EXPECT_EQ(nullptr, absl::RawPtr(p));
139 }
140
TEST(RawPtrTest,Nullptr)141 TEST(RawPtrTest, Nullptr) {
142 auto p = absl::RawPtr(nullptr);
143 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
144 EXPECT_EQ(nullptr, p);
145 }
146
TEST(RawPtrTest,Null)147 TEST(RawPtrTest, Null) {
148 auto p = absl::RawPtr(nullptr);
149 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
150 EXPECT_EQ(nullptr, p);
151 }
152
TEST(RawPtrTest,Zero)153 TEST(RawPtrTest, Zero) {
154 auto p = absl::RawPtr(nullptr);
155 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
156 EXPECT_EQ(nullptr, p);
157 }
158
TEST(ShareUniquePtrTest,Share)159 TEST(ShareUniquePtrTest, Share) {
160 auto up = absl::make_unique<int>();
161 int* rp = up.get();
162 auto sp = absl::ShareUniquePtr(std::move(up));
163 EXPECT_EQ(sp.get(), rp);
164 }
165
TEST(ShareUniquePtrTest,ShareNull)166 TEST(ShareUniquePtrTest, ShareNull) {
167 struct NeverDie {
168 using pointer = void*;
169 void operator()(pointer) {
170 ASSERT_TRUE(false) << "Deleter should not have been called.";
171 }
172 };
173
174 std::unique_ptr<void, NeverDie> up;
175 auto sp = absl::ShareUniquePtr(std::move(up));
176 }
177
TEST(WeakenPtrTest,Weak)178 TEST(WeakenPtrTest, Weak) {
179 auto sp = std::make_shared<int>();
180 auto wp = absl::WeakenPtr(sp);
181 EXPECT_EQ(sp.get(), wp.lock().get());
182 sp.reset();
183 EXPECT_TRUE(wp.expired());
184 }
185
186 // Should not compile.
187 /*
188 TEST(RawPtrTest, NotAPointer) {
189 absl::RawPtr(1.5);
190 }
191 */
192
TEST(AllocatorNoThrowTest,DefaultAllocator)193 TEST(AllocatorNoThrowTest, DefaultAllocator) {
194 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
195 EXPECT_TRUE(absl::default_allocator_is_nothrow::value);
196 #else
197 EXPECT_FALSE(absl::default_allocator_is_nothrow::value);
198 #endif
199 }
200
TEST(AllocatorNoThrowTest,StdAllocator)201 TEST(AllocatorNoThrowTest, StdAllocator) {
202 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
203 EXPECT_TRUE(absl::allocator_is_nothrow<std::allocator<int>>::value);
204 #else
205 EXPECT_FALSE(absl::allocator_is_nothrow<std::allocator<int>>::value);
206 #endif
207 }
208
TEST(AllocatorNoThrowTest,CustomAllocator)209 TEST(AllocatorNoThrowTest, CustomAllocator) {
210 struct NoThrowAllocator {
211 using is_nothrow = std::true_type;
212 };
213 struct CanThrowAllocator {
214 using is_nothrow = std::false_type;
215 };
216 struct UnspecifiedAllocator {};
217 EXPECT_TRUE(absl::allocator_is_nothrow<NoThrowAllocator>::value);
218 EXPECT_FALSE(absl::allocator_is_nothrow<CanThrowAllocator>::value);
219 EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value);
220 }
221
222 } // namespace
223