xref: /aosp_15_r20/external/abseil-cpp/absl/memory/memory_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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