00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "absl/memory/memory.h"
00018
00019 #include <sys/types.h>
00020 #include <cstddef>
00021 #include <memory>
00022 #include <string>
00023 #include <type_traits>
00024 #include <utility>
00025 #include <vector>
00026
00027 #include "gmock/gmock.h"
00028 #include "gtest/gtest.h"
00029
00030 namespace {
00031
00032 using ::testing::ElementsAre;
00033 using ::testing::Return;
00034
00035
00036
00037 class DestructorVerifier {
00038 public:
00039 DestructorVerifier() { ++instance_count_; }
00040 DestructorVerifier(const DestructorVerifier&) = delete;
00041 DestructorVerifier& operator=(const DestructorVerifier&) = delete;
00042 ~DestructorVerifier() { --instance_count_; }
00043
00044
00045 static int instance_count() { return instance_count_; }
00046
00047 private:
00048
00049 static int instance_count_;
00050 };
00051
00052 int DestructorVerifier::instance_count_ = 0;
00053
00054 TEST(WrapUniqueTest, WrapUnique) {
00055
00056
00057 {
00058 auto dv = new DestructorVerifier;
00059 EXPECT_EQ(1, DestructorVerifier::instance_count());
00060 std::unique_ptr<DestructorVerifier> ptr = absl::WrapUnique(dv);
00061 EXPECT_EQ(1, DestructorVerifier::instance_count());
00062 }
00063 EXPECT_EQ(0, DestructorVerifier::instance_count());
00064 }
00065 TEST(MakeUniqueTest, Basic) {
00066 std::unique_ptr<std::string> p = absl::make_unique<std::string>();
00067 EXPECT_EQ("", *p);
00068 p = absl::make_unique<std::string>("hi");
00069 EXPECT_EQ("hi", *p);
00070 }
00071
00072
00073
00074
00075 struct InitializationVerifier {
00076 static constexpr int kDefaultScalar = 0x43;
00077 static constexpr int kDefaultArray = 0x4B;
00078
00079 static void* operator new(size_t n) {
00080 void* ret = ::operator new(n);
00081 memset(ret, kDefaultScalar, n);
00082 return ret;
00083 }
00084
00085 static void* operator new[](size_t n) {
00086 void* ret = ::operator new[](n);
00087 memset(ret, kDefaultArray, n);
00088 return ret;
00089 }
00090
00091 int a;
00092 int b;
00093 };
00094
00095 TEST(Initialization, MakeUnique) {
00096 auto p = absl::make_unique<InitializationVerifier>();
00097
00098 EXPECT_EQ(0, p->a);
00099 EXPECT_EQ(0, p->b);
00100 }
00101
00102 TEST(Initialization, MakeUniqueArray) {
00103 auto p = absl::make_unique<InitializationVerifier[]>(2);
00104
00105 EXPECT_EQ(0, p[0].a);
00106 EXPECT_EQ(0, p[0].b);
00107 EXPECT_EQ(0, p[1].a);
00108 EXPECT_EQ(0, p[1].b);
00109 }
00110
00111 struct MoveOnly {
00112 MoveOnly() = default;
00113 explicit MoveOnly(int i1) : ip1{new int{i1}} {}
00114 MoveOnly(int i1, int i2) : ip1{new int{i1}}, ip2{new int{i2}} {}
00115 std::unique_ptr<int> ip1;
00116 std::unique_ptr<int> ip2;
00117 };
00118
00119 struct AcceptMoveOnly {
00120 explicit AcceptMoveOnly(MoveOnly m) : m_(std::move(m)) {}
00121 MoveOnly m_;
00122 };
00123
00124 TEST(MakeUniqueTest, MoveOnlyTypeAndValue) {
00125 using ExpectedType = std::unique_ptr<MoveOnly>;
00126 {
00127 auto p = absl::make_unique<MoveOnly>();
00128 static_assert(std::is_same<decltype(p), ExpectedType>::value,
00129 "unexpected return type");
00130 EXPECT_TRUE(!p->ip1);
00131 EXPECT_TRUE(!p->ip2);
00132 }
00133 {
00134 auto p = absl::make_unique<MoveOnly>(1);
00135 static_assert(std::is_same<decltype(p), ExpectedType>::value,
00136 "unexpected return type");
00137 EXPECT_TRUE(p->ip1 && *p->ip1 == 1);
00138 EXPECT_TRUE(!p->ip2);
00139 }
00140 {
00141 auto p = absl::make_unique<MoveOnly>(1, 2);
00142 static_assert(std::is_same<decltype(p), ExpectedType>::value,
00143 "unexpected return type");
00144 EXPECT_TRUE(p->ip1 && *p->ip1 == 1);
00145 EXPECT_TRUE(p->ip2 && *p->ip2 == 2);
00146 }
00147 }
00148
00149 TEST(MakeUniqueTest, AcceptMoveOnly) {
00150 auto p = absl::make_unique<AcceptMoveOnly>(MoveOnly());
00151 p = std::unique_ptr<AcceptMoveOnly>(new AcceptMoveOnly(MoveOnly()));
00152 }
00153
00154 struct ArrayWatch {
00155 void* operator new[](size_t n) {
00156 allocs().push_back(n);
00157 return ::operator new[](n);
00158 }
00159 void operator delete[](void* p) {
00160 return ::operator delete[](p);
00161 }
00162 static std::vector<size_t>& allocs() {
00163 static auto& v = *new std::vector<size_t>;
00164 return v;
00165 }
00166 };
00167
00168 TEST(Make_UniqueTest, Array) {
00169
00170
00171 ArrayWatch::allocs().clear();
00172
00173 auto p = absl::make_unique<ArrayWatch[]>(5);
00174 static_assert(std::is_same<decltype(p),
00175 std::unique_ptr<ArrayWatch[]>>::value,
00176 "unexpected return type");
00177 EXPECT_THAT(ArrayWatch::allocs(), ElementsAre(5 * sizeof(ArrayWatch)));
00178 }
00179
00180 TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) {
00181
00182
00183 struct TakesStdType {
00184 explicit TakesStdType(const std::vector<int> &vec) {}
00185 };
00186 using absl::make_unique;
00187 (void)make_unique<TakesStdType>(std::vector<int>());
00188 }
00189
00190 #if 0
00191
00192 TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
00193 auto m = MoveOnly();
00194 auto p = absl::make_unique<AcceptMoveOnly>(m);
00195 }
00196 TEST(MakeUniqueTestNC, KnownBoundArray) {
00197 auto p = absl::make_unique<ArrayWatch[5]>();
00198 }
00199 #endif
00200
00201 TEST(RawPtrTest, RawPointer) {
00202 int i = 5;
00203 EXPECT_EQ(&i, absl::RawPtr(&i));
00204 }
00205
00206 TEST(RawPtrTest, SmartPointer) {
00207 int* o = new int(5);
00208 std::unique_ptr<int> p(o);
00209 EXPECT_EQ(o, absl::RawPtr(p));
00210 }
00211
00212 class IntPointerNonConstDeref {
00213 public:
00214 explicit IntPointerNonConstDeref(int* p) : p_(p) {}
00215 friend bool operator!=(const IntPointerNonConstDeref& a, std::nullptr_t) {
00216 return a.p_ != nullptr;
00217 }
00218 int& operator*() { return *p_; }
00219
00220 private:
00221 std::unique_ptr<int> p_;
00222 };
00223
00224 TEST(RawPtrTest, SmartPointerNonConstDereference) {
00225 int* o = new int(5);
00226 IntPointerNonConstDeref p(o);
00227 EXPECT_EQ(o, absl::RawPtr(p));
00228 }
00229
00230 TEST(RawPtrTest, NullValuedRawPointer) {
00231 int* p = nullptr;
00232 EXPECT_EQ(nullptr, absl::RawPtr(p));
00233 }
00234
00235 TEST(RawPtrTest, NullValuedSmartPointer) {
00236 std::unique_ptr<int> p;
00237 EXPECT_EQ(nullptr, absl::RawPtr(p));
00238 }
00239
00240 TEST(RawPtrTest, Nullptr) {
00241 auto p = absl::RawPtr(nullptr);
00242 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
00243 EXPECT_EQ(nullptr, p);
00244 }
00245
00246 TEST(RawPtrTest, Null) {
00247 auto p = absl::RawPtr(nullptr);
00248 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
00249 EXPECT_EQ(nullptr, p);
00250 }
00251
00252 TEST(RawPtrTest, Zero) {
00253 auto p = absl::RawPtr(nullptr);
00254 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::value));
00255 EXPECT_EQ(nullptr, p);
00256 }
00257
00258 TEST(ShareUniquePtrTest, Share) {
00259 auto up = absl::make_unique<int>();
00260 int* rp = up.get();
00261 auto sp = absl::ShareUniquePtr(std::move(up));
00262 EXPECT_EQ(sp.get(), rp);
00263 }
00264
00265 TEST(ShareUniquePtrTest, ShareNull) {
00266 struct NeverDie {
00267 using pointer = void*;
00268 void operator()(pointer) {
00269 ASSERT_TRUE(false) << "Deleter should not have been called.";
00270 }
00271 };
00272
00273 std::unique_ptr<void, NeverDie> up;
00274 auto sp = absl::ShareUniquePtr(std::move(up));
00275 }
00276
00277 TEST(WeakenPtrTest, Weak) {
00278 auto sp = std::make_shared<int>();
00279 auto wp = absl::WeakenPtr(sp);
00280 EXPECT_EQ(sp.get(), wp.lock().get());
00281 sp.reset();
00282 EXPECT_TRUE(wp.expired());
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292 template <typename T>
00293 struct SmartPointer {
00294 using difference_type = char;
00295 };
00296
00297 struct PointerWith {
00298 using element_type = int32_t;
00299 using difference_type = int16_t;
00300 template <typename U>
00301 using rebind = SmartPointer<U>;
00302
00303 static PointerWith pointer_to(
00304 element_type& r) {
00305 return PointerWith{&r};
00306 }
00307
00308 element_type* ptr;
00309 };
00310
00311 template <typename... Args>
00312 struct PointerWithout {};
00313
00314 TEST(PointerTraits, Types) {
00315 using TraitsWith = absl::pointer_traits<PointerWith>;
00316 EXPECT_TRUE((std::is_same<TraitsWith::pointer, PointerWith>::value));
00317 EXPECT_TRUE((std::is_same<TraitsWith::element_type, int32_t>::value));
00318 EXPECT_TRUE((std::is_same<TraitsWith::difference_type, int16_t>::value));
00319 EXPECT_TRUE((
00320 std::is_same<TraitsWith::rebind<int64_t>, SmartPointer<int64_t>>::value));
00321
00322 using TraitsWithout = absl::pointer_traits<PointerWithout<double, int>>;
00323 EXPECT_TRUE((std::is_same<TraitsWithout::pointer,
00324 PointerWithout<double, int>>::value));
00325 EXPECT_TRUE((std::is_same<TraitsWithout::element_type, double>::value));
00326 EXPECT_TRUE(
00327 (std::is_same<TraitsWithout ::difference_type, std::ptrdiff_t>::value));
00328 EXPECT_TRUE((std::is_same<TraitsWithout::rebind<int64_t>,
00329 PointerWithout<int64_t, int>>::value));
00330
00331 using TraitsRawPtr = absl::pointer_traits<char*>;
00332 EXPECT_TRUE((std::is_same<TraitsRawPtr::pointer, char*>::value));
00333 EXPECT_TRUE((std::is_same<TraitsRawPtr::element_type, char>::value));
00334 EXPECT_TRUE(
00335 (std::is_same<TraitsRawPtr::difference_type, std::ptrdiff_t>::value));
00336 EXPECT_TRUE((std::is_same<TraitsRawPtr::rebind<int64_t>, int64_t*>::value));
00337 }
00338
00339 TEST(PointerTraits, Functions) {
00340 int i;
00341 EXPECT_EQ(&i, absl::pointer_traits<PointerWith>::pointer_to(i).ptr);
00342 EXPECT_EQ(&i, absl::pointer_traits<int*>::pointer_to(i));
00343 }
00344
00345 TEST(AllocatorTraits, Typedefs) {
00346 struct A {
00347 struct value_type {};
00348 };
00349 EXPECT_TRUE((
00350 std::is_same<A,
00351 typename absl::allocator_traits<A>::allocator_type>::value));
00352 EXPECT_TRUE(
00353 (std::is_same<A::value_type,
00354 typename absl::allocator_traits<A>::value_type>::value));
00355
00356 struct X {};
00357 struct HasPointer {
00358 using value_type = X;
00359 using pointer = SmartPointer<X>;
00360 };
00361 EXPECT_TRUE((std::is_same<SmartPointer<X>, typename absl::allocator_traits<
00362 HasPointer>::pointer>::value));
00363 EXPECT_TRUE(
00364 (std::is_same<A::value_type*,
00365 typename absl::allocator_traits<A>::pointer>::value));
00366
00367 EXPECT_TRUE(
00368 (std::is_same<
00369 SmartPointer<const X>,
00370 typename absl::allocator_traits<HasPointer>::const_pointer>::value));
00371 EXPECT_TRUE(
00372 (std::is_same<const A::value_type*,
00373 typename absl::allocator_traits<A>::const_pointer>::value));
00374
00375 struct HasVoidPointer {
00376 using value_type = X;
00377 struct void_pointer {};
00378 };
00379
00380 EXPECT_TRUE((std::is_same<HasVoidPointer::void_pointer,
00381 typename absl::allocator_traits<
00382 HasVoidPointer>::void_pointer>::value));
00383 EXPECT_TRUE(
00384 (std::is_same<SmartPointer<void>, typename absl::allocator_traits<
00385 HasPointer>::void_pointer>::value));
00386
00387 struct HasConstVoidPointer {
00388 using value_type = X;
00389 struct const_void_pointer {};
00390 };
00391
00392 EXPECT_TRUE(
00393 (std::is_same<HasConstVoidPointer::const_void_pointer,
00394 typename absl::allocator_traits<
00395 HasConstVoidPointer>::const_void_pointer>::value));
00396 EXPECT_TRUE((std::is_same<SmartPointer<const void>,
00397 typename absl::allocator_traits<
00398 HasPointer>::const_void_pointer>::value));
00399
00400 struct HasDifferenceType {
00401 using value_type = X;
00402 using difference_type = int;
00403 };
00404 EXPECT_TRUE(
00405 (std::is_same<int, typename absl::allocator_traits<
00406 HasDifferenceType>::difference_type>::value));
00407 EXPECT_TRUE((std::is_same<char, typename absl::allocator_traits<
00408 HasPointer>::difference_type>::value));
00409
00410 struct HasSizeType {
00411 using value_type = X;
00412 using size_type = unsigned int;
00413 };
00414 EXPECT_TRUE((std::is_same<unsigned int, typename absl::allocator_traits<
00415 HasSizeType>::size_type>::value));
00416 EXPECT_TRUE((std::is_same<unsigned char, typename absl::allocator_traits<
00417 HasPointer>::size_type>::value));
00418
00419 struct HasPropagateOnCopy {
00420 using value_type = X;
00421 struct propagate_on_container_copy_assignment {};
00422 };
00423
00424 EXPECT_TRUE(
00425 (std::is_same<HasPropagateOnCopy::propagate_on_container_copy_assignment,
00426 typename absl::allocator_traits<HasPropagateOnCopy>::
00427 propagate_on_container_copy_assignment>::value));
00428 EXPECT_TRUE(
00429 (std::is_same<std::false_type,
00430 typename absl::allocator_traits<
00431 A>::propagate_on_container_copy_assignment>::value));
00432
00433 struct HasPropagateOnMove {
00434 using value_type = X;
00435 struct propagate_on_container_move_assignment {};
00436 };
00437
00438 EXPECT_TRUE(
00439 (std::is_same<HasPropagateOnMove::propagate_on_container_move_assignment,
00440 typename absl::allocator_traits<HasPropagateOnMove>::
00441 propagate_on_container_move_assignment>::value));
00442 EXPECT_TRUE(
00443 (std::is_same<std::false_type,
00444 typename absl::allocator_traits<
00445 A>::propagate_on_container_move_assignment>::value));
00446
00447 struct HasPropagateOnSwap {
00448 using value_type = X;
00449 struct propagate_on_container_swap {};
00450 };
00451
00452 EXPECT_TRUE(
00453 (std::is_same<HasPropagateOnSwap::propagate_on_container_swap,
00454 typename absl::allocator_traits<HasPropagateOnSwap>::
00455 propagate_on_container_swap>::value));
00456 EXPECT_TRUE(
00457 (std::is_same<std::false_type, typename absl::allocator_traits<A>::
00458 propagate_on_container_swap>::value));
00459
00460 struct HasIsAlwaysEqual {
00461 using value_type = X;
00462 struct is_always_equal {};
00463 };
00464
00465 EXPECT_TRUE((std::is_same<HasIsAlwaysEqual::is_always_equal,
00466 typename absl::allocator_traits<
00467 HasIsAlwaysEqual>::is_always_equal>::value));
00468 EXPECT_TRUE((std::is_same<std::true_type, typename absl::allocator_traits<
00469 A>::is_always_equal>::value));
00470 struct NonEmpty {
00471 using value_type = X;
00472 int i;
00473 };
00474 EXPECT_TRUE(
00475 (std::is_same<std::false_type,
00476 absl::allocator_traits<NonEmpty>::is_always_equal>::value));
00477 }
00478
00479 template <typename T>
00480 struct AllocWithPrivateInheritance : private std::allocator<T> {
00481 using value_type = T;
00482 };
00483
00484 TEST(AllocatorTraits, RebindWithPrivateInheritance) {
00485
00486
00487 EXPECT_TRUE(
00488 (std::is_same<AllocWithPrivateInheritance<int>,
00489 absl::allocator_traits<AllocWithPrivateInheritance<char>>::
00490 rebind_alloc<int>>::value));
00491 }
00492
00493 template <typename T>
00494 struct Rebound {};
00495
00496 struct AllocWithRebind {
00497 using value_type = int;
00498 template <typename T>
00499 struct rebind {
00500 using other = Rebound<T>;
00501 };
00502 };
00503
00504 template <typename T, typename U>
00505 struct AllocWithoutRebind {
00506 using value_type = int;
00507 };
00508
00509 TEST(AllocatorTraits, Rebind) {
00510 EXPECT_TRUE(
00511 (std::is_same<Rebound<int>,
00512 typename absl::allocator_traits<
00513 AllocWithRebind>::template rebind_alloc<int>>::value));
00514 EXPECT_TRUE(
00515 (std::is_same<absl::allocator_traits<Rebound<int>>,
00516 typename absl::allocator_traits<
00517 AllocWithRebind>::template rebind_traits<int>>::value));
00518
00519 EXPECT_TRUE(
00520 (std::is_same<AllocWithoutRebind<double, char>,
00521 typename absl::allocator_traits<AllocWithoutRebind<
00522 int, char>>::template rebind_alloc<double>>::value));
00523 EXPECT_TRUE(
00524 (std::is_same<absl::allocator_traits<AllocWithoutRebind<double, char>>,
00525 typename absl::allocator_traits<AllocWithoutRebind<
00526 int, char>>::template rebind_traits<double>>::value));
00527 }
00528
00529 struct TestValue {
00530 TestValue() {}
00531 explicit TestValue(int* trace) : trace(trace) { ++*trace; }
00532 ~TestValue() {
00533 if (trace) --*trace;
00534 }
00535 int* trace = nullptr;
00536 };
00537
00538 struct MinimalMockAllocator {
00539 MinimalMockAllocator() : value(0) {}
00540 explicit MinimalMockAllocator(int value) : value(value) {}
00541 MinimalMockAllocator(const MinimalMockAllocator& other)
00542 : value(other.value) {}
00543 using value_type = TestValue;
00544 MOCK_METHOD1(allocate, value_type*(size_t));
00545 MOCK_METHOD2(deallocate, void(value_type*, size_t));
00546
00547 int value;
00548 };
00549
00550 TEST(AllocatorTraits, FunctionsMinimal) {
00551 int trace = 0;
00552 int hint;
00553 TestValue x(&trace);
00554 MinimalMockAllocator mock;
00555 using Traits = absl::allocator_traits<MinimalMockAllocator>;
00556 EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x));
00557 EXPECT_CALL(mock, deallocate(&x, 7));
00558
00559 EXPECT_EQ(&x, Traits::allocate(mock, 7));
00560 Traits::allocate(mock, 7, static_cast<const void*>(&hint));
00561 EXPECT_EQ(&x, Traits::allocate(mock, 7, static_cast<const void*>(&hint)));
00562 Traits::deallocate(mock, &x, 7);
00563
00564 EXPECT_EQ(1, trace);
00565 Traits::construct(mock, &x, &trace);
00566 EXPECT_EQ(2, trace);
00567 Traits::destroy(mock, &x);
00568 EXPECT_EQ(1, trace);
00569
00570 EXPECT_EQ(std::numeric_limits<size_t>::max() / sizeof(TestValue),
00571 Traits::max_size(mock));
00572
00573 EXPECT_EQ(0, mock.value);
00574 EXPECT_EQ(0, Traits::select_on_container_copy_construction(mock).value);
00575 }
00576
00577 struct FullMockAllocator {
00578 FullMockAllocator() : value(0) {}
00579 explicit FullMockAllocator(int value) : value(value) {}
00580 FullMockAllocator(const FullMockAllocator& other) : value(other.value) {}
00581 using value_type = TestValue;
00582 MOCK_METHOD1(allocate, value_type*(size_t));
00583 MOCK_METHOD2(allocate, value_type*(size_t, const void*));
00584 MOCK_METHOD2(construct, void(value_type*, int*));
00585 MOCK_METHOD1(destroy, void(value_type*));
00586 MOCK_CONST_METHOD0(max_size, size_t());
00587 MOCK_CONST_METHOD0(select_on_container_copy_construction,
00588 FullMockAllocator());
00589
00590 int value;
00591 };
00592
00593 TEST(AllocatorTraits, FunctionsFull) {
00594 int trace = 0;
00595 int hint;
00596 TestValue x(&trace), y;
00597 FullMockAllocator mock;
00598 using Traits = absl::allocator_traits<FullMockAllocator>;
00599 EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x));
00600 EXPECT_CALL(mock, allocate(13, &hint)).WillRepeatedly(Return(&y));
00601 EXPECT_CALL(mock, construct(&x, &trace));
00602 EXPECT_CALL(mock, destroy(&x));
00603 EXPECT_CALL(mock, max_size()).WillRepeatedly(Return(17));
00604 EXPECT_CALL(mock, select_on_container_copy_construction())
00605 .WillRepeatedly(Return(FullMockAllocator(23)));
00606
00607 EXPECT_EQ(&x, Traits::allocate(mock, 7));
00608 EXPECT_EQ(&y, Traits::allocate(mock, 13, static_cast<const void*>(&hint)));
00609
00610 EXPECT_EQ(1, trace);
00611 Traits::construct(mock, &x, &trace);
00612 EXPECT_EQ(1, trace);
00613 Traits::destroy(mock, &x);
00614 EXPECT_EQ(1, trace);
00615
00616 EXPECT_EQ(17, Traits::max_size(mock));
00617
00618 EXPECT_EQ(0, mock.value);
00619 EXPECT_EQ(23, Traits::select_on_container_copy_construction(mock).value);
00620 }
00621
00622 TEST(AllocatorNoThrowTest, DefaultAllocator) {
00623 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
00624 EXPECT_TRUE(absl::default_allocator_is_nothrow::value);
00625 #else
00626 EXPECT_FALSE(absl::default_allocator_is_nothrow::value);
00627 #endif
00628 }
00629
00630 TEST(AllocatorNoThrowTest, StdAllocator) {
00631 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW
00632 EXPECT_TRUE(absl::allocator_is_nothrow<std::allocator<int>>::value);
00633 #else
00634 EXPECT_FALSE(absl::allocator_is_nothrow<std::allocator<int>>::value);
00635 #endif
00636 }
00637
00638 TEST(AllocatorNoThrowTest, CustomAllocator) {
00639 struct NoThrowAllocator {
00640 using is_nothrow = std::true_type;
00641 };
00642 struct CanThrowAllocator {
00643 using is_nothrow = std::false_type;
00644 };
00645 struct UnspecifiedAllocator {
00646 };
00647 EXPECT_TRUE(absl::allocator_is_nothrow<NoThrowAllocator>::value);
00648 EXPECT_FALSE(absl::allocator_is_nothrow<CanThrowAllocator>::value);
00649 EXPECT_FALSE(absl::allocator_is_nothrow<UnspecifiedAllocator>::value);
00650 }
00651
00652 }