Skip to content

Commit

Permalink
explicit dynarray copy constructor and clone function
Browse files Browse the repository at this point in the history
Also operator =(const dynarray &&) = delete
  • Loading branch information
OleErikPeistorpet committed Jun 6, 2024
1 parent 0bd4b90 commit 286c2d4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
9 changes: 7 additions & 2 deletions dynarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,21 @@ class dynarray

dynarray(dynarray && other) noexcept : _m(std::move(other._m)) {}
dynarray(dynarray && other, Alloc a);
dynarray(const dynarray & other) : dynarray(other,
explicit dynarray(const dynarray & other) : dynarray(other,
_alloTrait::select_on_container_copy_construction(other._m)) {}
dynarray(const dynarray & other, Alloc a) : _m(a) { append(other); }
explicit dynarray(const dynarray & other, Alloc a) : _m(a) { append(other); }

//! Workaround for GCC failing to choose explicit copy constructor in some cases
friend dynarray clone(const dynarray & d) { return dynarray(d); }
friend dynarray clone(const dynarray & d, Alloc a) { return dynarray(d, std::move(a)); }

~dynarray() noexcept;

dynarray & operator =(dynarray && other) &
noexcept(_alloTrait::propagate_on_container_move_assignment::value or _alloTrait::is_always_equal::value);
//! Requires that allocator_type is always equal or does not have propagate_on_container_copy_assignment
dynarray & operator =(const dynarray & other) &;
dynarray & operator =(const dynarray &&) = delete;

dynarray & operator =(std::initializer_list<T> il) & { assign(il); return *this; }

Expand Down
15 changes: 15 additions & 0 deletions unit_test/dynarray_construct_assignop_swap_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,21 @@ TEST_F(dynarrayConstructTest, copyConstructThrowing)
}
#endif

TEST_F(dynarrayConstructTest, clone)
{
using Al = StatefulAllocator<TrivialRelocat>;
auto x = dynarray< TrivialRelocat, Al >({TrivialRelocat{0.5}}, Al(-5));
EXPECT_EQ(1, g_allocCount.nAllocations);

auto y = clone(x);
EXPECT_EQ(-5, y.get_allocator().id);
EXPECT_EQ(2, g_allocCount.nAllocations);

auto z = clone(y, Al(7));
EXPECT_EQ(0.5, *z.front());
EXPECT_EQ(3, g_allocCount.nAllocations);
}

TEST_F(dynarrayConstructTest, swap)
{
dynarrayTrackingAlloc<int> a, b{1, 2};
Expand Down
6 changes: 5 additions & 1 deletion unit_test/dynarray_mutate_gtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,11 @@ TEST_F(dynarrayTest, erasePrecondCheck)
leakDetector->enabled = false;

dynarray<int> di{-2};
auto copy = di;
#if !defined __GNUC__ or __GNUC__ < 12
auto copy = dynarray(di);
#else
auto copy = clone(di);
#endif
ASSERT_DEATH( copy.erase(di.begin()), "" );
}

Expand Down

0 comments on commit 286c2d4

Please sign in to comment.