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