memory_test.cc (5925B)
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: 40 DestructorVerifier() { ++instance_count_; } 41 DestructorVerifier(const DestructorVerifier&) = delete; 42 DestructorVerifier& operator=(const DestructorVerifier&) = delete; 43 ~DestructorVerifier() { --instance_count_; } 44 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 53 int DestructorVerifier::instance_count_ = 0; 54 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 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 90 struct ArrayWatch { 91 void* operator new[](size_t n) { 92 allocs().push_back(n); 93 return ::operator new[](n); 94 } 95 void operator delete[](void* p) { return ::operator delete[](p); } 96 static std::vector<size_t>& allocs() { 97 static auto& v = *new std::vector<size_t>; 98 return v; 99 } 100 }; 101 102 TEST(RawPtrTest, RawPointer) { 103 int i = 5; 104 EXPECT_EQ(&i, absl::RawPtr(&i)); 105 } 106 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: 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 125 TEST(RawPtrTest, SmartPointerNonConstDereference) { 126 int* o = new int(5); 127 IntPointerNonConstDeref p(o); 128 EXPECT_EQ(o, absl::RawPtr(p)); 129 } 130 131 TEST(RawPtrTest, NullValuedRawPointer) { 132 int* p = nullptr; 133 EXPECT_EQ(nullptr, absl::RawPtr(p)); 134 } 135 136 TEST(RawPtrTest, NullValuedSmartPointer) { 137 std::unique_ptr<int> p; 138 EXPECT_EQ(nullptr, absl::RawPtr(p)); 139 } 140 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 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 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 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 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 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 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 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 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