blob: c47820e54ab0736238a9a8b5b5fc97b355793582 [file] [log] [blame]
Austin Schuh36244a12019-09-21 17:52:38 -07001// 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
30namespace {
31
32using ::testing::ElementsAre;
33using ::testing::Return;
34
35// This class creates observable behavior to verify that a destructor has
36// been called, via the instance_count variable.
37class DestructorVerifier {
38 public:
39 DestructorVerifier() { ++instance_count_; }
40 DestructorVerifier(const DestructorVerifier&) = delete;
41 DestructorVerifier& operator=(const DestructorVerifier&) = delete;
42 ~DestructorVerifier() { --instance_count_; }
43
44 // The number of instances of this class currently active.
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
52int DestructorVerifier::instance_count_ = 0;
53
54TEST(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}
65TEST(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).
75struct InitializationVerifier {
76 static constexpr int kDefaultScalar = 0x43;
77 static constexpr int kDefaultArray = 0x4B;
78
79 static void* operator new(size_t n) {
80 void* ret = ::operator new(n);
81 memset(ret, kDefaultScalar, n);
82 return ret;
83 }
84
85 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
95TEST(Initialization, MakeUnique) {
96 auto p = absl::make_unique<InitializationVerifier>();
97
98 EXPECT_EQ(0, p->a);
99 EXPECT_EQ(0, p->b);
100}
101
102TEST(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
111struct MoveOnly {
112 MoveOnly() = default;
113 explicit MoveOnly(int i1) : ip1{new int{i1}} {}
114 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
119struct AcceptMoveOnly {
120 explicit AcceptMoveOnly(MoveOnly m) : m_(std::move(m)) {}
121 MoveOnly m_;
122};
123
124TEST(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
149TEST(MakeUniqueTest, AcceptMoveOnly) {
150 auto p = absl::make_unique<AcceptMoveOnly>(MoveOnly());
151 p = std::unique_ptr<AcceptMoveOnly>(new AcceptMoveOnly(MoveOnly()));
152}
153
154struct ArrayWatch {
155 void* operator new[](size_t n) {
156 allocs().push_back(n);
157 return ::operator new[](n);
158 }
159 void operator delete[](void* p) {
160 return ::operator delete[](p);
161 }
162 static std::vector<size_t>& allocs() {
163 static auto& v = *new std::vector<size_t>;
164 return v;
165 }
166};
167
168TEST(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
180TEST(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.
192TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
193 auto m = MoveOnly();
194 auto p = absl::make_unique<AcceptMoveOnly>(m);
195}
196TEST(MakeUniqueTestNC, KnownBoundArray) {
197 auto p = absl::make_unique<ArrayWatch[5]>();
198}
199#endif
200
201TEST(RawPtrTest, RawPointer) {
202 int i = 5;
203 EXPECT_EQ(&i, absl::RawPtr(&i));
204}
205
206TEST(RawPtrTest, SmartPointer) {
207 int* o = new int(5);
208 std::unique_ptr<int> p(o);
209 EXPECT_EQ(o, absl::RawPtr(p));
210}
211
212class IntPointerNonConstDeref {
213 public:
214 explicit IntPointerNonConstDeref(int* p) : p_(p) {}
215 friend bool operator!=(const IntPointerNonConstDeref& a, std::nullptr_t) {
216 return a.p_ != nullptr;
217 }
218 int& operator*() { return *p_; }
219
220 private:
221 std::unique_ptr<int> p_;
222};
223
224TEST(RawPtrTest, SmartPointerNonConstDereference) {
225 int* o = new int(5);
226 IntPointerNonConstDeref p(o);
227 EXPECT_EQ(o, absl::RawPtr(p));
228}
229
230TEST(RawPtrTest, NullValuedRawPointer) {
231 int* p = nullptr;
232 EXPECT_EQ(nullptr, absl::RawPtr(p));
233}
234
235TEST(RawPtrTest, NullValuedSmartPointer) {
236 std::unique_ptr<int> p;
237 EXPECT_EQ(nullptr, absl::RawPtr(p));
238}
239
240TEST(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
246TEST(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
252TEST(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
258TEST(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
265TEST(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
277TEST(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/*
287TEST(RawPtrTest, NotAPointer) {
288 absl::RawPtr(1.5);
289}
290*/
291
292template <typename T>
293struct SmartPointer {
294 using difference_type = char;
295};
296
297struct PointerWith {
298 using element_type = int32_t;
299 using difference_type = int16_t;
300 template <typename U>
301 using rebind = SmartPointer<U>;
302
303 static PointerWith pointer_to(
304 element_type& r) { // NOLINT(runtime/references)
305 return PointerWith{&r};
306 }
307
308 element_type* ptr;
309};
310
311template <typename... Args>
312struct PointerWithout {};
313
314TEST(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
339TEST(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
345TEST(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
479template <typename T>
480struct AllocWithPrivateInheritance : private std::allocator<T> {
481 using value_type = T;
482};
483
484TEST(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
493template <typename T>
494struct Rebound {};
495
496struct AllocWithRebind {
497 using value_type = int;
498 template <typename T>
499 struct rebind {
500 using other = Rebound<T>;
501 };
502};
503
504template <typename T, typename U>
505struct AllocWithoutRebind {
506 using value_type = int;
507};
508
509TEST(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
529struct TestValue {
530 TestValue() {}
531 explicit TestValue(int* trace) : trace(trace) { ++*trace; }
532 ~TestValue() {
533 if (trace) --*trace;
534 }
535 int* trace = nullptr;
536};
537
538struct MinimalMockAllocator {
539 MinimalMockAllocator() : value(0) {}
540 explicit MinimalMockAllocator(int value) : value(value) {}
541 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
550TEST(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
577struct FullMockAllocator {
578 FullMockAllocator() : value(0) {}
579 explicit FullMockAllocator(int value) : value(value) {}
580 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
593TEST(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
622TEST(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
630TEST(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
638TEST(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