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 #include <cstddef>
21 #include <memory>
22 #include <string>
23 #include <type_traits>
24 #include <utility>
25 #include <vector>
26
27 #include "gmock/gmock.h"
28 #include "gtest/gtest.h"
29
30 namespace {
31
32 using ::testing::ElementsAre;
33 using ::testing::Return;
34
35 // This class creates observable behavior to verify that a destructor has
36 // been called, via the instance_count variable.
37 class DestructorVerifier {
38 public:
DestructorVerifier()39 DestructorVerifier() { ++instance_count_; }
40 DestructorVerifier(const DestructorVerifier&) = delete;
41 DestructorVerifier& operator=(const DestructorVerifier&) = delete;
~DestructorVerifier()42 ~DestructorVerifier() { --instance_count_; }
43
44 // The number of instances of this class currently active.
instance_count()45 static int instance_count() { return instance_count_; }
46
47 private:
48 // The number of instances of this class currently active.
49 static int instance_count_;
50 };
51
52 int DestructorVerifier::instance_count_ = 0;
53
TEST(WrapUniqueTest,WrapUnique)54 TEST(WrapUniqueTest, WrapUnique) {
55 // Test that the unique_ptr is constructed properly by verifying that the
56 // destructor for its payload gets called at the proper time.
57 {
58 auto dv = new DestructorVerifier;
59 EXPECT_EQ(1, DestructorVerifier::instance_count());
60 std::unique_ptr<DestructorVerifier> ptr = absl::WrapUnique(dv);
61 EXPECT_EQ(1, DestructorVerifier::instance_count());
62 }
63 EXPECT_EQ(0, DestructorVerifier::instance_count());
64 }
TEST(MakeUniqueTest,Basic)65 TEST(MakeUniqueTest, Basic) {
66 std::unique_ptr<std::string> p = absl::make_unique<std::string>();
67 EXPECT_EQ("", *p);
68 p = absl::make_unique<std::string>("hi");
69 EXPECT_EQ("hi", *p);
70 }
71
72 // InitializationVerifier fills in a pattern when allocated so we can
73 // distinguish between its default and value initialized states (without
74 // accessing truly uninitialized memory).
75 struct InitializationVerifier {
76 static constexpr int kDefaultScalar = 0x43;
77 static constexpr int kDefaultArray = 0x4B;
78
operator new__anon084a24120111::InitializationVerifier79 static void* operator new(size_t n) {
80 void* ret = ::operator new(n);
81 memset(ret, kDefaultScalar, n);
82 return ret;
83 }
84
operator new[]__anon084a24120111::InitializationVerifier85 static void* operator new[](size_t n) {
86 void* ret = ::operator new[](n);
87 memset(ret, kDefaultArray, n);
88 return ret;
89 }
90
91 int a;
92 int b;
93 };
94
TEST(Initialization,MakeUnique)95 TEST(Initialization, MakeUnique) {
96 auto p = absl::make_unique<InitializationVerifier>();
97
98 EXPECT_EQ(0, p->a);
99 EXPECT_EQ(0, p->b);
100 }
101
TEST(Initialization,MakeUniqueArray)102 TEST(Initialization, MakeUniqueArray) {
103 auto p = absl::make_unique<InitializationVerifier[]>(2);
104
105 EXPECT_EQ(0, p[0].a);
106 EXPECT_EQ(0, p[0].b);
107 EXPECT_EQ(0, p[1].a);
108 EXPECT_EQ(0, p[1].b);
109 }
110
111 struct MoveOnly {
112 MoveOnly() = default;
MoveOnly__anon084a24120111::MoveOnly113 explicit MoveOnly(int i1) : ip1{new int{i1}} {}
MoveOnly__anon084a24120111::MoveOnly114 MoveOnly(int i1, int i2) : ip1{new int{i1}}, ip2{new int{i2}} {}
115 std::unique_ptr<int> ip1;
116 std::unique_ptr<int> ip2;
117 };
118
119 struct AcceptMoveOnly {
AcceptMoveOnly__anon084a24120111::AcceptMoveOnly120 explicit AcceptMoveOnly(MoveOnly m) : m_(std::move(m)) {}
121 MoveOnly m_;
122 };
123
TEST(MakeUniqueTest,MoveOnlyTypeAndValue)124 TEST(MakeUniqueTest, MoveOnlyTypeAndValue) {
125 using ExpectedType = std::unique_ptr<MoveOnly>;
126 {
127 auto p = absl::make_unique<MoveOnly>();
128 static_assert(std::is_same<decltype(p), ExpectedType>::value,
129 "unexpected return type");
130 EXPECT_TRUE(!p->ip1);
131 EXPECT_TRUE(!p->ip2);
132 }
133 {
134 auto p = absl::make_unique<MoveOnly>(1);
135 static_assert(std::is_same<decltype(p), ExpectedType>::value,
136 "unexpected return type");
137 EXPECT_TRUE(p->ip1 && *p->ip1 == 1);
138 EXPECT_TRUE(!p->ip2);
139 }
140 {
141 auto p = absl::make_unique<MoveOnly>(1, 2);
142 static_assert(std::is_same<decltype(p), ExpectedType>::value,
143 "unexpected return type");
144 EXPECT_TRUE(p->ip1 && *p->ip1 == 1);
145 EXPECT_TRUE(p->ip2 && *p->ip2 == 2);
146 }
147 }
148
TEST(MakeUniqueTest,AcceptMoveOnly)149 TEST(MakeUniqueTest, AcceptMoveOnly) {
150 auto p = absl::make_unique<AcceptMoveOnly>(MoveOnly());
151 p = std::unique_ptr<AcceptMoveOnly>(new AcceptMoveOnly(MoveOnly()));
152 }
153
154 struct ArrayWatch {
operator new[]__anon084a24120111::ArrayWatch155 void* operator new[](size_t n) {
156 allocs().push_back(n);
157 return ::operator new[](n);
158 }
operator delete[]__anon084a24120111::ArrayWatch159 void operator delete[](void* p) {
160 return ::operator delete[](p);
161 }
allocs__anon084a24120111::ArrayWatch162 static std::vector<size_t>& allocs() {
163 static auto& v = *new std::vector<size_t>;
164 return v;
165 }
166 };
167
TEST(Make_UniqueTest,Array)168 TEST(Make_UniqueTest, Array) {
169 // Ensure state is clean before we start so that these tests
170 // are order-agnostic.
171 ArrayWatch::allocs().clear();
172
173 auto p = absl::make_unique<ArrayWatch[]>(5);
174 static_assert(std::is_same<decltype(p),
175 std::unique_ptr<ArrayWatch[]>>::value,
176 "unexpected return type");
177 EXPECT_THAT(ArrayWatch::allocs(), ElementsAre(5 * sizeof(ArrayWatch)));
178 }
179
TEST(Make_UniqueTest,NotAmbiguousWithStdMakeUnique)180 TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) {
181 // Ensure that absl::make_unique is not ambiguous with std::make_unique.
182 // In C++14 mode, the below call to make_unique has both types as candidates.
183 struct TakesStdType {
184 explicit TakesStdType(const std::vector<int> &vec) {}
185 };
186 using absl::make_unique;
187 (void)make_unique<TakesStdType>(std::vector<int>());
188 }
189
190 #if 0
191 // These tests shouldn't compile.
192 TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
193 auto m = MoveOnly();
194 auto p = absl::make_unique<AcceptMoveOnly>(m);
195 }
196 TEST(MakeUniqueTestNC, KnownBoundArray) {
197 auto p = absl::make_unique<ArrayWatch[5]>();
198 }
199 #endif
200
TEST(RawPtrTest,RawPointer)201 TEST(RawPtrTest, RawPointer) {
202 int i = 5;
203 EXPECT_EQ(&i, absl::RawPtr(&i));
204 }
205
TEST(RawPtrTest,SmartPointer)206 TEST(RawPtrTest, SmartPointer) {
207 int* o = new int(5);
208 std::unique_ptr<int> p(o);
209 EXPECT_EQ(o, absl::RawPtr(p));
210 }
211
212 class IntPointerNonConstDeref {
213 public:
IntPointerNonConstDeref(int * p)214 explicit IntPointerNonConstDeref(int* p) : p_(p) {}
operator !=(const IntPointerNonConstDeref & a,std::nullptr_t)215 friend bool operator!=(const IntPointerNonConstDeref& a, std::nullptr_t) {
216 return a.p_ != nullptr;
217 }
operator *()218 int& operator*() { return *p_; }
219
220 private:
221 std::unique_ptr<int> p_;
222 };
223
TEST(RawPtrTest,SmartPointerNonConstDereference)224 TEST(RawPtrTest, SmartPointerNonConstDereference) {
225 int* o = new int(5);
226 IntPointerNonConstDeref p(o);
227 EXPECT_EQ(o, absl::RawPtr(p));
228 }
229
TEST(RawPtrTest,NullValuedRawPointer)230 TEST(RawPtrTest, NullValuedRawPointer) {
231 int* p = nullptr;
232 EXPECT_EQ(nullptr, absl::RawPtr(p));
233 }
234
TEST(RawPtrTest,NullValuedSmartPointer)235 TEST(RawPtrTest, NullValuedSmartPointer) {
236 std::unique_ptr<int> p;
237 EXPECT_EQ(nullptr, absl::RawPtr(p));
238 }
239
TEST(RawPtrTest,Nullptr)240 TEST(RawPtrTest, Nullptr) {
241 auto p = absl::RawPtr(nullptr);
242 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
243 EXPECT_EQ(nullptr, p);
244 }
245
TEST(RawPtrTest,Null)246 TEST(RawPtrTest, Null) {
247 auto p = absl::RawPtr(nullptr);
248 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
249 EXPECT_EQ(nullptr, p);
250 }
251
TEST(RawPtrTest,Zero)252 TEST(RawPtrTest, Zero) {
253 auto p = absl::RawPtr(nullptr);
254 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
255 EXPECT_EQ(nullptr, p);
256 }
257
TEST(ShareUniquePtrTest,Share)258 TEST(ShareUniquePtrTest, Share) {
259 auto up = absl::make_unique<int>();
260 int* rp = up.get();
261 auto sp = absl::ShareUniquePtr(std::move(up));
262 EXPECT_EQ(sp.get(), rp);
263 }
264
TEST(ShareUniquePtrTest,ShareNull)265 TEST(ShareUniquePtrTest, ShareNull) {
266 struct NeverDie {
267 using pointer = void*;
268 void operator()(pointer) {
269 ASSERT_TRUE(false) << "Deleter should not have been called.";
270 }
271 };
272
273 std::unique_ptr<void, NeverDie> up;
274 auto sp = absl::ShareUniquePtr(std::move(up));
275 }
276
TEST(WeakenPtrTest,Weak)277 TEST(WeakenPtrTest, Weak) {
278 auto sp = std::make_shared<int>();
279 auto wp = absl::WeakenPtr(sp);
280 EXPECT_EQ(sp.get(), wp.lock().get());
281 sp.reset();
282 EXPECT_TRUE(wp.expired());
283 }
284
285 // Should not compile.
286 /*
287 TEST(RawPtrTest, NotAPointer) {
288 absl::RawPtr(1.5);
289 }
290 */
291
292 template <typename T>
293 struct SmartPointer {
294 using difference_type = char;
295 };
296
297 struct PointerWith {
298 using element_type = int32_t;
299 using difference_type = int16_t;
300 template <typename U>
301 using rebind = SmartPointer<U>;
302
pointer_to__anon084a24120111::PointerWith303 static PointerWith pointer_to(
304 element_type& r) { // NOLINT(runtime/references)
305 return PointerWith{&r};
306 }
307
308 element_type* ptr;
309 };
310
311 template <typename... Args>
312 struct PointerWithout {};
313
TEST(PointerTraits,Types)314 TEST(PointerTraits, Types) {
315 using TraitsWith = absl::pointer_traits<PointerWith>;
316 EXPECT_TRUE((std::is_same<TraitsWith::pointer, PointerWith>::value));
317 EXPECT_TRUE((std::is_same<TraitsWith::element_type, int32_t>::value));
318 EXPECT_TRUE((std::is_same<TraitsWith::difference_type, int16_t>::value));
319 EXPECT_TRUE((
320 std::is_same<TraitsWith::rebind<int64_t>, SmartPointer<int64_t>>::value));
321
322 using TraitsWithout = absl::pointer_traits<PointerWithout<double, int>>;
323 EXPECT_TRUE((std::is_same<TraitsWithout::pointer,
324 PointerWithout<double, int>>::value));
325 EXPECT_TRUE((std::is_same<TraitsWithout::element_type, double>::value));
326 EXPECT_TRUE(
327 (std::is_same<TraitsWithout ::difference_type, std::ptrdiff_t>::value));
328 EXPECT_TRUE((std::is_same<TraitsWithout::rebind<int64_t>,
329 PointerWithout<int64_t, int>>::value));
330
331 using TraitsRawPtr = absl::pointer_traits<char*>;
332 EXPECT_TRUE((std::is_same<TraitsRawPtr::pointer, char*>::value));
333 EXPECT_TRUE((std::is_same<TraitsRawPtr::element_type, char>::value));
334 EXPECT_TRUE(
335 (std::is_same<TraitsRawPtr::difference_type, std::ptrdiff_t>::value));
336 EXPECT_TRUE((std::is_same<TraitsRawPtr::rebind<int64_t>, int64_t*>::value));
337 }
338
TEST(PointerTraits,Functions)339 TEST(PointerTraits, Functions) {
340 int i;
341 EXPECT_EQ(&i, absl::pointer_traits<PointerWith>::pointer_to(i).ptr);
342 EXPECT_EQ(&i, absl::pointer_traits<int*>::pointer_to(i));
343 }
344
TEST(AllocatorTraits,Typedefs)345 TEST(AllocatorTraits, Typedefs) {
346 struct A {
347 struct value_type {};
348 };
349 EXPECT_TRUE((
350 std::is_same<A,
351 typename absl::allocator_traits<A>::allocator_type>::value));
352 EXPECT_TRUE(
353 (std::is_same<A::value_type,
354 typename absl::allocator_traits<A>::value_type>::value));
355
356 struct X {};
357 struct HasPointer {
358 using value_type = X;
359 using pointer = SmartPointer<X>;
360 };
361 EXPECT_TRUE((std::is_same<SmartPointer<X>, typename absl::allocator_traits<
362 HasPointer>::pointer>::value));
363 EXPECT_TRUE(
364 (std::is_same<A::value_type*,
365 typename absl::allocator_traits<A>::pointer>::value));
366
367 EXPECT_TRUE(
368 (std::is_same<
369 SmartPointer<const X>,
370 typename absl::allocator_traits<HasPointer>::const_pointer>::value));
371 EXPECT_TRUE(
372 (std::is_same<const A::value_type*,
373 typename absl::allocator_traits<A>::const_pointer>::value));
374
375 struct HasVoidPointer {
376 using value_type = X;
377 struct void_pointer {};
378 };
379
380 EXPECT_TRUE((std::is_same<HasVoidPointer::void_pointer,
381 typename absl::allocator_traits<
382 HasVoidPointer>::void_pointer>::value));
383 EXPECT_TRUE(
384 (std::is_same<SmartPointer<void>, typename absl::allocator_traits<
385 HasPointer>::void_pointer>::value));
386
387 struct HasConstVoidPointer {
388 using value_type = X;
389 struct const_void_pointer {};
390 };
391
392 EXPECT_TRUE(
393 (std::is_same<HasConstVoidPointer::const_void_pointer,
394 typename absl::allocator_traits<
395 HasConstVoidPointer>::const_void_pointer>::value));
396 EXPECT_TRUE((std::is_same<SmartPointer<const void>,
397 typename absl::allocator_traits<
398 HasPointer>::const_void_pointer>::value));
399
400 struct HasDifferenceType {
401 using value_type = X;
402 using difference_type = int;
403 };
404 EXPECT_TRUE(
405 (std::is_same<int, typename absl::allocator_traits<
406 HasDifferenceType>::difference_type>::value));
407 EXPECT_TRUE((std::is_same<char, typename absl::allocator_traits<
408 HasPointer>::difference_type>::value));
409
410 struct HasSizeType {
411 using value_type = X;
412 using size_type = unsigned int;
413 };
414 EXPECT_TRUE((std::is_same<unsigned int, typename absl::allocator_traits<
415 HasSizeType>::size_type>::value));
416 EXPECT_TRUE((std::is_same<unsigned char, typename absl::allocator_traits<
417 HasPointer>::size_type>::value));
418
419 struct HasPropagateOnCopy {
420 using value_type = X;
421 struct propagate_on_container_copy_assignment {};
422 };
423
424 EXPECT_TRUE(
425 (std::is_same<HasPropagateOnCopy::propagate_on_container_copy_assignment,
426 typename absl::allocator_traits<HasPropagateOnCopy>::
427 propagate_on_container_copy_assignment>::value));
428 EXPECT_TRUE(
429 (std::is_same<std::false_type,
430 typename absl::allocator_traits<
431 A>::propagate_on_container_copy_assignment>::value));
432
433 struct HasPropagateOnMove {
434 using value_type = X;
435 struct propagate_on_container_move_assignment {};
436 };
437
438 EXPECT_TRUE(
439 (std::is_same<HasPropagateOnMove::propagate_on_container_move_assignment,
440 typename absl::allocator_traits<HasPropagateOnMove>::
441 propagate_on_container_move_assignment>::value));
442 EXPECT_TRUE(
443 (std::is_same<std::false_type,
444 typename absl::allocator_traits<
445 A>::propagate_on_container_move_assignment>::value));
446
447 struct HasPropagateOnSwap {
448 using value_type = X;
449 struct propagate_on_container_swap {};
450 };
451
452 EXPECT_TRUE(
453 (std::is_same<HasPropagateOnSwap::propagate_on_container_swap,
454 typename absl::allocator_traits<HasPropagateOnSwap>::
455 propagate_on_container_swap>::value));
456 EXPECT_TRUE(
457 (std::is_same<std::false_type, typename absl::allocator_traits<A>::
458 propagate_on_container_swap>::value));
459
460 struct HasIsAlwaysEqual {
461 using value_type = X;
462 struct is_always_equal {};
463 };
464
465 EXPECT_TRUE((std::is_same<HasIsAlwaysEqual::is_always_equal,
466 typename absl::allocator_traits<
467 HasIsAlwaysEqual>::is_always_equal>::value));
468 EXPECT_TRUE((std::is_same<std::true_type, typename absl::allocator_traits<
469 A>::is_always_equal>::value));
470 struct NonEmpty {
471 using value_type = X;
472 int i;
473 };
474 EXPECT_TRUE(
475 (std::is_same<std::false_type,
476 absl::allocator_traits<NonEmpty>::is_always_equal>::value));
477 }
478
479 template <typename T>
480 struct AllocWithPrivateInheritance : private std::allocator<T> {
481 using value_type = T;
482 };
483
TEST(AllocatorTraits,RebindWithPrivateInheritance)484 TEST(AllocatorTraits, RebindWithPrivateInheritance) {
485 // Regression test for some versions of gcc that do not like the sfinae we
486 // used in combination with private inheritance.
487 EXPECT_TRUE(
488 (std::is_same<AllocWithPrivateInheritance<int>,
489 absl::allocator_traits<AllocWithPrivateInheritance<char>>::
490 rebind_alloc<int>>::value));
491 }
492
493 template <typename T>
494 struct Rebound {};
495
496 struct AllocWithRebind {
497 using value_type = int;
498 template <typename T>
499 struct rebind {
500 using other = Rebound<T>;
501 };
502 };
503
504 template <typename T, typename U>
505 struct AllocWithoutRebind {
506 using value_type = int;
507 };
508
TEST(AllocatorTraits,Rebind)509 TEST(AllocatorTraits, Rebind) {
510 EXPECT_TRUE(
511 (std::is_same<Rebound<int>,
512 typename absl::allocator_traits<
513 AllocWithRebind>::template rebind_alloc<int>>::value));
514 EXPECT_TRUE(
515 (std::is_same<absl::allocator_traits<Rebound<int>>,
516 typename absl::allocator_traits<
517 AllocWithRebind>::template rebind_traits<int>>::value));
518
519 EXPECT_TRUE(
520 (std::is_same<AllocWithoutRebind<double, char>,
521 typename absl::allocator_traits<AllocWithoutRebind<
522 int, char>>::template rebind_alloc<double>>::value));
523 EXPECT_TRUE(
524 (std::is_same<absl::allocator_traits<AllocWithoutRebind<double, char>>,
525 typename absl::allocator_traits<AllocWithoutRebind<
526 int, char>>::template rebind_traits<double>>::value));
527 }
528
529 struct TestValue {
TestValue__anon084a24120111::TestValue530 TestValue() {}
TestValue__anon084a24120111::TestValue531 explicit TestValue(int* trace) : trace(trace) { ++*trace; }
~TestValue__anon084a24120111::TestValue532 ~TestValue() {
533 if (trace) --*trace;
534 }
535 int* trace = nullptr;
536 };
537
538 struct MinimalMockAllocator {
MinimalMockAllocator__anon084a24120111::MinimalMockAllocator539 MinimalMockAllocator() : value(0) {}
MinimalMockAllocator__anon084a24120111::MinimalMockAllocator540 explicit MinimalMockAllocator(int value) : value(value) {}
MinimalMockAllocator__anon084a24120111::MinimalMockAllocator541 MinimalMockAllocator(const MinimalMockAllocator& other)
542 : value(other.value) {}
543 using value_type = TestValue;
544 MOCK_METHOD1(allocate, value_type*(size_t));
545 MOCK_METHOD2(deallocate, void(value_type*, size_t));
546
547 int value;
548 };
549
TEST(AllocatorTraits,FunctionsMinimal)550 TEST(AllocatorTraits, FunctionsMinimal) {
551 int trace = 0;
552 int hint;
553 TestValue x(&trace);
554 MinimalMockAllocator mock;
555 using Traits = absl::allocator_traits<MinimalMockAllocator>;
556 EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x));
557 EXPECT_CALL(mock, deallocate(&x, 7));
558
559 EXPECT_EQ(&x, Traits::allocate(mock, 7));
560 Traits::allocate(mock, 7, static_cast<const void*>(&hint));
561 EXPECT_EQ(&x, Traits::allocate(mock, 7, static_cast<const void*>(&hint)));
562 Traits::deallocate(mock, &x, 7);
563
564 EXPECT_EQ(1, trace);
565 Traits::construct(mock, &x, &trace);
566 EXPECT_EQ(2, trace);
567 Traits::destroy(mock, &x);
568 EXPECT_EQ(1, trace);
569
570 EXPECT_EQ(std::numeric_limits<size_t>::max() / sizeof(TestValue),
571 Traits::max_size(mock));
572
573 EXPECT_EQ(0, mock.value);
574 EXPECT_EQ(0, Traits::select_on_container_copy_construction(mock).value);
575 }
576
577 struct FullMockAllocator {
FullMockAllocator__anon084a24120111::FullMockAllocator578 FullMockAllocator() : value(0) {}
FullMockAllocator__anon084a24120111::FullMockAllocator579 explicit FullMockAllocator(int value) : value(value) {}
FullMockAllocator__anon084a24120111::FullMockAllocator580 FullMockAllocator(const FullMockAllocator& other) : value(other.value) {}
581 using value_type = TestValue;
582 MOCK_METHOD1(allocate, value_type*(size_t));
583 MOCK_METHOD2(allocate, value_type*(size_t, const void*));
584 MOCK_METHOD2(construct, void(value_type*, int*));
585 MOCK_METHOD1(destroy, void(value_type*));
586 MOCK_CONST_METHOD0(max_size, size_t());
587 MOCK_CONST_METHOD0(select_on_container_copy_construction,
588 FullMockAllocator());
589
590 int value;
591 };
592
TEST(AllocatorTraits,FunctionsFull)593 TEST(AllocatorTraits, FunctionsFull) {
594 int trace = 0;
595 int hint;
596 TestValue x(&trace), y;
597 FullMockAllocator mock;
598 using Traits = absl::allocator_traits<FullMockAllocator>;
599 EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x));
600 EXPECT_CALL(mock, allocate(13, &hint)).WillRepeatedly(Return(&y));
601 EXPECT_CALL(mock, construct(&x, &trace));
602 EXPECT_CALL(mock, destroy(&x));
603 EXPECT_CALL(mock, max_size()).WillRepeatedly(Return(17));
604 EXPECT_CALL(mock, select_on_container_copy_construction())
605 .WillRepeatedly(Return(FullMockAllocator(23)));
606
607 EXPECT_EQ(&x, Traits::allocate(mock, 7));
608 EXPECT_EQ(&y, Traits::allocate(mock, 13, static_cast<const void*>(&hint)));
609
610 EXPECT_EQ(1, trace);
611 Traits::construct(mock, &x, &trace);
612 EXPECT_EQ(1, trace);
613 Traits::destroy(mock, &x);
614 EXPECT_EQ(1, trace);
615
616 EXPECT_EQ(17, Traits::max_size(mock));
617
618 EXPECT_EQ(0, mock.value);
619 EXPECT_EQ(23, Traits::select_on_container_copy_construction(mock).value);
620 }
621
TEST(AllocatorNoThrowTest,DefaultAllocator)622 TEST(AllocatorNoThrowTest, DefaultAllocator) {
623 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
624 EXPECT_TRUE(absl::default_allocator_is_nothrow::value);
625 #else
626 EXPECT_FALSE(absl::default_allocator_is_nothrow::value);
627 #endif
628 }
629
TEST(AllocatorNoThrowTest,StdAllocator)630 TEST(AllocatorNoThrowTest, StdAllocator) {
631 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
632 EXPECT_TRUE(absl::allocator_is_nothrow<std::allocator<int>>::value);
633 #else
634 EXPECT_FALSE(absl::allocator_is_nothrow<std::allocator<int>>::value);
635 #endif
636 }
637
TEST(AllocatorNoThrowTest,CustomAllocator)638 TEST(AllocatorNoThrowTest, CustomAllocator) {
639 struct NoThrowAllocator {
640 using is_nothrow = std::true_type;
641 };
642 struct CanThrowAllocator {
643 using is_nothrow = std::false_type;
644 };
645 struct UnspecifiedAllocator {
646 };
647 EXPECT_TRUE(absl::allocator_is_nothrow<NoThrowAllocator>::value);
648 EXPECT_FALSE(absl::allocator_is_nothrow<CanThrowAllocator>::value);
649 EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value);
650 }
651
652 } // namespace
653