blob: fafd3a4199d2ce627fb4950a3a5e98515b4d3d83 [file] [log] [blame]
mistergc2e75482017-09-19 16:54:40 -04001// 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//
nik727338b70432019-03-08 10:27:53 -05007// https://www.apache.org/licenses/LICENSE-2.0
mistergc2e75482017-09-19 16:54:40 -04008//
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>
Abseil Team41a62632020-07-21 10:23:33 -070020
mistergc2e75482017-09-19 16:54:40 -040021#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
31namespace {
32
33using ::testing::ElementsAre;
34using ::testing::Return;
35
36// This class creates observable behavior to verify that a destructor has
37// been called, via the instance_count variable.
38class DestructorVerifier {
39 public:
Abseil Team41a62632020-07-21 10:23:33 -070040 DestructorVerifier() { ++instance_count_; }
mistergc2e75482017-09-19 16:54:40 -040041 DestructorVerifier(const DestructorVerifier&) = delete;
42 DestructorVerifier& operator=(const DestructorVerifier&) = delete;
Abseil Team41a62632020-07-21 10:23:33 -070043 ~DestructorVerifier() { --instance_count_; }
mistergc2e75482017-09-19 16:54:40 -040044
45 // The number of instances of this class currently active.
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
53int DestructorVerifier::instance_count_ = 0;
54
55TEST(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}
Derek Maurof02e8c02022-11-16 07:01:18 -080066
Abseil Team44b0faf2018-12-04 11:01:12 -080067// 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).
70struct InitializationVerifier {
71 static constexpr int kDefaultScalar = 0x43;
72 static constexpr int kDefaultArray = 0x4B;
73
74 static void* operator new(size_t n) {
75 void* ret = ::operator new(n);
76 memset(ret, kDefaultScalar, n);
77 return ret;
78 }
79
80 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
mistergc2e75482017-09-19 16:54:40 -040090struct ArrayWatch {
91 void* operator new[](size_t n) {
92 allocs().push_back(n);
93 return ::operator new[](n);
94 }
Abseil Team41a62632020-07-21 10:23:33 -070095 void operator delete[](void* p) { return ::operator delete[](p); }
mistergc2e75482017-09-19 16:54:40 -040096 static std::vector<size_t>& allocs() {
97 static auto& v = *new std::vector<size_t>;
98 return v;
99 }
100};
101
mistergc2e75482017-09-19 16:54:40 -0400102TEST(RawPtrTest, RawPointer) {
103 int i = 5;
104 EXPECT_EQ(&i, absl::RawPtr(&i));
105}
106
107TEST(RawPtrTest, SmartPointer) {
108 int* o = new int(5);
109 std::unique_ptr<int> p(o);
110 EXPECT_EQ(o, absl::RawPtr(p));
111}
112
113class IntPointerNonConstDeref {
114 public:
115 explicit IntPointerNonConstDeref(int* p) : p_(p) {}
116 friend bool operator!=(const IntPointerNonConstDeref& a, std::nullptr_t) {
117 return a.p_ != nullptr;
118 }
119 int& operator*() { return *p_; }
120
121 private:
122 std::unique_ptr<int> p_;
123};
124
125TEST(RawPtrTest, SmartPointerNonConstDereference) {
126 int* o = new int(5);
127 IntPointerNonConstDeref p(o);
128 EXPECT_EQ(o, absl::RawPtr(p));
129}
130
131TEST(RawPtrTest, NullValuedRawPointer) {
132 int* p = nullptr;
133 EXPECT_EQ(nullptr, absl::RawPtr(p));
134}
135
136TEST(RawPtrTest, NullValuedSmartPointer) {
137 std::unique_ptr<int> p;
138 EXPECT_EQ(nullptr, absl::RawPtr(p));
139}
140
141TEST(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
147TEST(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
153TEST(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
159TEST(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
166TEST(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
178TEST(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/*
188TEST(RawPtrTest, NotAPointer) {
189 absl::RawPtr(1.5);
190}
191*/
192
mistergc2e75482017-09-19 16:54:40 -0400193TEST(AllocatorNoThrowTest, DefaultAllocator) {
Abseil Teamca3f8752019-04-23 12:04:13 -0700194#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
mistergc2e75482017-09-19 16:54:40 -0400195 EXPECT_TRUE(absl::default_allocator_is_nothrow::value);
196#else
197 EXPECT_FALSE(absl::default_allocator_is_nothrow::value);
198#endif
199}
200
201TEST(AllocatorNoThrowTest, StdAllocator) {
Abseil Teamca3f8752019-04-23 12:04:13 -0700202#if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
mistergc2e75482017-09-19 16:54:40 -0400203 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
209TEST(AllocatorNoThrowTest, CustomAllocator) {
210 struct NoThrowAllocator {
211 using is_nothrow = std::true_type;
212 };
213 struct CanThrowAllocator {
214 using is_nothrow = std::false_type;
215 };
Abseil Team41a62632020-07-21 10:23:33 -0700216 struct UnspecifiedAllocator {};
mistergc2e75482017-09-19 16:54:40 -0400217 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
mistergc2e75482017-09-19 16:54:40 -0400222} // namespace