19 #include <sys/types.h> 23 #include <type_traits> 27 #include "gmock/gmock.h" 28 #include "gtest/gtest.h" 32 using ::testing::ElementsAre;
33 using ::testing::Return;
37 class DestructorVerifier {
39 DestructorVerifier() { ++instance_count_; }
40 DestructorVerifier(
const DestructorVerifier&) =
delete;
41 DestructorVerifier& operator=(
const DestructorVerifier&) =
delete;
42 ~DestructorVerifier() { --instance_count_; }
45 static int instance_count() {
return instance_count_; }
49 static int instance_count_;
52 int DestructorVerifier::instance_count_ = 0;
58 auto dv =
new DestructorVerifier;
59 EXPECT_EQ(1, DestructorVerifier::instance_count());
61 EXPECT_EQ(1, DestructorVerifier::instance_count());
63 EXPECT_EQ(0, DestructorVerifier::instance_count());
65 TEST(MakeUniqueTest, Basic) {
66 std::unique_ptr<std::string> p = absl::make_unique<std::string>();
68 p = absl::make_unique<std::string>(
"hi");
75 struct InitializationVerifier {
76 static constexpr
int kDefaultScalar = 0x43;
77 static constexpr
int kDefaultArray = 0x4B;
79 static void*
operator new(
size_t n) {
80 void* ret = ::operator
new(
n);
81 memset(ret, kDefaultScalar,
n);
85 static void*
operator new[](
size_t n) {
86 void* ret = ::operator
new[](
n);
87 memset(ret, kDefaultArray,
n);
95 TEST(Initialization, MakeUnique) {
96 auto p = absl::make_unique<InitializationVerifier>();
102 TEST(Initialization, MakeUniqueArray) {
103 auto p = absl::make_unique<InitializationVerifier[]>(2);
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);
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;
119 struct AcceptMoveOnly {
120 explicit AcceptMoveOnly(MoveOnly m) : m_(
std::
move(m)) {}
124 TEST(MakeUniqueTest, MoveOnlyTypeAndValue) {
125 using ExpectedType = std::unique_ptr<MoveOnly>;
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);
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);
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);
149 TEST(MakeUniqueTest, AcceptMoveOnly) {
150 auto p = absl::make_unique<AcceptMoveOnly>(MoveOnly());
151 p = std::unique_ptr<AcceptMoveOnly>(
new AcceptMoveOnly(MoveOnly()));
155 void*
operator new[](
size_t n) {
156 allocs().push_back(
n);
157 return ::operator
new[](
n);
159 void operator delete[](
void* p) {
160 return ::operator
delete[](p);
162 static std::vector<size_t>& allocs() {
163 static auto&
v = *
new std::vector<size_t>;
168 TEST(Make_UniqueTest, Array) {
171 ArrayWatch::allocs().clear();
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)));
180 TEST(Make_UniqueTest, NotAmbiguousWithStdMakeUnique) {
183 struct TakesStdType {
184 explicit TakesStdType(
const std::vector<int> &vec) {}
187 (void)make_unique<TakesStdType>(std::vector<int>());
192 TEST(MakeUniqueTestNC, AcceptMoveOnlyLvalue) {
194 auto p = absl::make_unique<AcceptMoveOnly>(m);
196 TEST(MakeUniqueTestNC, KnownBoundArray) {
197 auto p = absl::make_unique<ArrayWatch[5]>();
201 TEST(RawPtrTest, RawPointer) {
206 TEST(RawPtrTest, SmartPointer) {
208 std::unique_ptr<int> p(o);
212 class IntPointerNonConstDeref {
214 explicit IntPointerNonConstDeref(
int* p) :
p_(p) {}
215 friend bool operator!=(
const IntPointerNonConstDeref&
a, std::nullptr_t) {
216 return a.p_ !=
nullptr;
221 std::unique_ptr<int>
p_;
224 TEST(RawPtrTest, SmartPointerNonConstDereference) {
226 IntPointerNonConstDeref p(o);
230 TEST(RawPtrTest, NullValuedRawPointer) {
235 TEST(RawPtrTest, NullValuedSmartPointer) {
236 std::unique_ptr<int> p;
240 TEST(RawPtrTest, Nullptr) {
242 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::
value));
243 EXPECT_EQ(
nullptr, p);
246 TEST(RawPtrTest, Null) {
248 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::
value));
249 EXPECT_EQ(
nullptr, p);
252 TEST(RawPtrTest, Zero) {
254 EXPECT_TRUE((std::is_same<std::nullptr_t, decltype(p)>::
value));
255 EXPECT_EQ(
nullptr, p);
258 TEST(ShareUniquePtrTest, Share) {
259 auto up = absl::make_unique<int>();
262 EXPECT_EQ(sp.get(), rp);
265 TEST(ShareUniquePtrTest, ShareNull) {
268 void operator()(pointer) {
269 ASSERT_TRUE(
false) <<
"Deleter should not have been called.";
273 std::unique_ptr<void, NeverDie> up;
277 TEST(WeakenPtrTest, Weak) {
278 auto sp = std::make_shared<int>();
280 EXPECT_EQ(sp.get(), wp.lock().get());
282 EXPECT_TRUE(wp.expired());
292 template <
typename T>
293 struct SmartPointer {
294 using difference_type = char;
298 using element_type = int32_t;
299 using difference_type = int16_t;
300 template <
typename U>
301 using rebind = SmartPointer<U>;
303 static PointerWith pointer_to(
305 return PointerWith{&r};
311 template <
typename... Args>
312 struct PointerWithout {};
314 TEST(PointerTraits, Types) {
320 std::is_same<TraitsWith::rebind<int64_t>, SmartPointer<int64_t>>::
value));
323 EXPECT_TRUE((std::is_same<TraitsWithout::pointer,
324 PointerWithout<double, int>>::
value));
328 EXPECT_TRUE((std::is_same<TraitsWithout::rebind<int64_t>,
329 PointerWithout<int64_t, int>>::
value));
336 EXPECT_TRUE((std::is_same<TraitsRawPtr::rebind<int64_t>, int64_t*>::
value));
339 TEST(PointerTraits, Functions) {
345 TEST(AllocatorTraits, Typedefs) {
359 using pointer = SmartPointer<X>;
362 HasPointer>::pointer>::
value));
369 SmartPointer<const X>,
375 struct HasVoidPointer {
377 struct void_pointer {};
380 EXPECT_TRUE((std::is_same<HasVoidPointer::void_pointer,
382 HasVoidPointer>::void_pointer>::
value));
385 HasPointer>::void_pointer>::
value));
387 struct HasConstVoidPointer {
389 struct const_void_pointer {};
393 (std::is_same<HasConstVoidPointer::const_void_pointer,
395 HasConstVoidPointer>::const_void_pointer>::
value));
396 EXPECT_TRUE((std::is_same<SmartPointer<const void>,
398 HasPointer>::const_void_pointer>::
value));
400 struct HasDifferenceType {
402 using difference_type = int;
406 HasDifferenceType>::difference_type>::
value));
408 HasPointer>::difference_type>::
value));
412 using size_type =
unsigned int;
415 HasSizeType>::size_type>::
value));
417 HasPointer>::size_type>::
value));
419 struct HasPropagateOnCopy {
421 struct propagate_on_container_copy_assignment {};
425 (std::is_same<HasPropagateOnCopy::propagate_on_container_copy_assignment,
427 propagate_on_container_copy_assignment>::
value));
429 (std::is_same<std::false_type,
431 A>::propagate_on_container_copy_assignment>::
value));
433 struct HasPropagateOnMove {
435 struct propagate_on_container_move_assignment {};
439 (std::is_same<HasPropagateOnMove::propagate_on_container_move_assignment,
441 propagate_on_container_move_assignment>::
value));
443 (std::is_same<std::false_type,
445 A>::propagate_on_container_move_assignment>::
value));
447 struct HasPropagateOnSwap {
449 struct propagate_on_container_swap {};
453 (std::is_same<HasPropagateOnSwap::propagate_on_container_swap,
455 propagate_on_container_swap>::
value));
458 propagate_on_container_swap>::
value));
460 struct HasIsAlwaysEqual {
462 struct is_always_equal {};
465 EXPECT_TRUE((std::is_same<HasIsAlwaysEqual::is_always_equal,
467 HasIsAlwaysEqual>::is_always_equal>::
value));
469 A>::is_always_equal>::
value));
475 (std::is_same<std::false_type,
479 template <
typename T>
480 struct AllocWithPrivateInheritance :
private std::allocator<T> {
484 TEST(AllocatorTraits, RebindWithPrivateInheritance) {
488 (std::is_same<AllocWithPrivateInheritance<int>,
490 rebind_alloc<int>>::
value));
493 template <
typename T>
496 struct AllocWithRebind {
498 template <
typename T>
500 using other = Rebound<T>;
504 template <
typename T,
typename U>
505 struct AllocWithoutRebind {
509 TEST(AllocatorTraits, Rebind) {
511 (std::is_same<Rebound<int>,
513 AllocWithRebind>::
template rebind_alloc<int>>::
value));
517 AllocWithRebind>::
template rebind_traits<int>>::
value));
520 (std::is_same<AllocWithoutRebind<double, char>,
522 int,
char>>::
template rebind_alloc<double>>::
value));
526 int,
char>>::
template rebind_traits<double>>::
value));
531 explicit TestValue(
int* trace) : trace(trace) { ++*trace; }
535 int* trace =
nullptr;
538 struct MinimalMockAllocator {
539 MinimalMockAllocator() :
value(0) {}
540 explicit MinimalMockAllocator(
int value) : value(value) {}
541 MinimalMockAllocator(
const MinimalMockAllocator& other)
545 MOCK_METHOD2(deallocate,
void(
value_type*,
size_t));
550 TEST(AllocatorTraits, FunctionsMinimal) {
554 MinimalMockAllocator mock;
556 EXPECT_CALL(mock, allocate(7)).WillRepeatedly(Return(&x));
557 EXPECT_CALL(mock, deallocate(&x, 7));
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);
570 EXPECT_EQ(std::numeric_limits<size_t>::max() /
sizeof(TestValue),
571 Traits::max_size(mock));
573 EXPECT_EQ(0, mock.value);
574 EXPECT_EQ(0, Traits::select_on_container_copy_construction(mock).
value);
577 struct FullMockAllocator {
578 FullMockAllocator() :
value(0) {}
579 explicit FullMockAllocator(
int value) : value(value) {}
580 FullMockAllocator(
const FullMockAllocator& other) :
value(other.
value) {}
583 MOCK_METHOD2(allocate,
value_type*(
size_t,
const void*));
586 MOCK_CONST_METHOD0(max_size,
size_t());
587 MOCK_CONST_METHOD0(select_on_container_copy_construction,
588 FullMockAllocator());
593 TEST(AllocatorTraits, FunctionsFull) {
596 TestValue x(&trace), y;
597 FullMockAllocator mock;
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)));
607 EXPECT_EQ(&x, Traits::allocate(mock, 7));
608 EXPECT_EQ(&y, Traits::allocate(mock, 13, static_cast<const void*>(&hint)));
616 EXPECT_EQ(17, Traits::max_size(mock));
618 EXPECT_EQ(0, mock.value);
619 EXPECT_EQ(23, Traits::select_on_container_copy_construction(mock).
value);
622 TEST(AllocatorNoThrowTest, DefaultAllocator) {
623 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW 630 TEST(AllocatorNoThrowTest, StdAllocator) {
631 #if defined(ABSL_ALLOCATOR_NOTHROW) && ABSL_ALLOCATOR_NOTHROW 638 TEST(AllocatorNoThrowTest, CustomAllocator) {
639 struct NoThrowAllocator {
640 using is_nothrow = std::true_type;
642 struct CanThrowAllocator {
643 using is_nothrow = std::false_type;
645 struct UnspecifiedAllocator {
memory_internal::ExtractOrT< memory_internal::GetIsAlwaysEqual, Alloc, typename std::is_empty< Alloc >::type > is_always_equal
std::unique_ptr< T > WrapUnique(T *ptr)
std::shared_ptr< T > ShareUniquePtr(std::unique_ptr< T, D > &&ptr)
uint128 operator*(uint128 lhs, uint128 rhs)
static std::function< void(void *, Slot *)> destroy
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
memory_internal::ExtractOrT< memory_internal::GetPointer, Alloc, value_type * > pointer
auto RawPtr(T &&ptr) -> decltype(std::addressof(*ptr))
static std::function< void(void *, Slot *, Slot)> construct
typename Alloc::value_type value_type
memory_internal::ExtractOrT< memory_internal::GetConstPointer, Alloc, typename absl::pointer_traits< pointer >::template rebind< const value_type >> const_pointer
std::weak_ptr< T > WeakenPtr(const std::shared_ptr< T > &ptr)
TEST(Symbolize, Unimplemented)
memory_internal::MakeUniqueResult< T >::scalar make_unique(Args &&...args)
std::unique_ptr< unsigned char[]> p_
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept