From f43bb5b3c9f45df9ba56cfb7376b1902ee5088e6 Mon Sep 17 00:00:00 2001 From: Ole Erik Peistorpet Date: Thu, 6 Jun 2024 12:09:48 +0200 Subject: [PATCH] explicit dynarray copy constructors Also operator =(const dynarray &&) = delete --- dynarray.h | 28 +++++++++++++++---- ...dynarray_construct_assignop_swap_gtest.cpp | 12 +++++--- unit_test/dynarray_mutate_gtest.cpp | 2 +- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/dynarray.h b/dynarray.h index fdaebdd0..066fd4d3 100644 --- a/dynarray.h +++ b/dynarray.h @@ -94,18 +94,22 @@ class dynarray auto result = dynarray(boost::range::istream_range(someStream)); @endcode */ template< typename InputRange, - typename /*EnableIfRange*/ = iterator_t, - enable_if< !_detail::isSameSansCVRef > = 0 + typename /*EnableIfRange*/ = iterator_t > explicit dynarray(InputRange && r, Alloc a = Alloc{}) : _m(a) { append(r); } dynarray(std::initializer_list il, Alloc a = Alloc{}) : _m(a) { append(il); } - dynarray(dynarray && other) noexcept : _m(std::move(other._m)) {} + dynarray(dynarray && other) noexcept : _m(std::move(other._m)) {} dynarray(dynarray && other, Alloc a); - 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) : dynarray(other, + _alloTrait::select_on_container_copy_construction(other._m)) {} + explicit dynarray(dynarray & other) : dynarray(static_cast(other)) {} + explicit dynarray(const dynarray && other) : dynarray(other) {} + explicit dynarray(const dynarray & other, Alloc a) : _m(a) { append(other); } + explicit dynarray(dynarray & other, Alloc a) : dynarray(static_cast(other), std::move(a)) {} + explicit dynarray(const dynarray && other, Alloc a) : dynarray(other, std::move(a)) {} ~dynarray() noexcept; @@ -113,6 +117,7 @@ class dynarray 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 il) & { assign(il); return *this; } @@ -924,6 +929,17 @@ explicit dynarray(InputRange &&, Alloc = {}) Alloc >; +#if defined __GNUC__ and __GNUC__ < 12 + template< typename T, typename A > + explicit dynarray(const dynarray &) -> dynarray; + + template< typename T, typename A > + explicit dynarray(dynarray &) -> dynarray; + + template< typename T, typename A > + explicit dynarray(const dynarray &&) -> dynarray; +#endif + #if OEL_MEM_BOUND_DEBUG_LVL } // namespace debug #endif diff --git a/unit_test/dynarray_construct_assignop_swap_gtest.cpp b/unit_test/dynarray_construct_assignop_swap_gtest.cpp index 974a2256..a5cd49b8 100644 --- a/unit_test/dynarray_construct_assignop_swap_gtest.cpp +++ b/unit_test/dynarray_construct_assignop_swap_gtest.cpp @@ -314,20 +314,24 @@ TEST_F(dynarrayConstructTest, constructMoveOnlyIterator) } #endif - TEST_F(dynarrayConstructTest, copyConstruct) { using Al = StatefulAllocator; auto x = dynarray< TrivialRelocat, Al >({TrivialRelocat{0.5}}, Al(-5)); - EXPECT_EQ(1, g_allocCount.nAllocations); auto y = dynarray(x); EXPECT_EQ(-5, y.get_allocator().id); EXPECT_EQ(2, g_allocCount.nAllocations); - auto z = dynarray(y, Al(7)); + auto const z = dynarray(y, Al(7)); EXPECT_EQ(0.5, *z.front()); - EXPECT_EQ(3, g_allocCount.nAllocations); + + auto const d = dynarray(std::move(z)); + EXPECT_EQ(0.5, *d.front()); + + auto const e = dynarray(std::move(d), Al(9)); + EXPECT_EQ(9, e.get_allocator().id); + EXPECT_EQ(5, g_allocCount.nAllocations); } template diff --git a/unit_test/dynarray_mutate_gtest.cpp b/unit_test/dynarray_mutate_gtest.cpp index f75eb1bb..4b18bb0d 100644 --- a/unit_test/dynarray_mutate_gtest.cpp +++ b/unit_test/dynarray_mutate_gtest.cpp @@ -831,7 +831,7 @@ TEST_F(dynarrayTest, erasePrecondCheck) leakDetector->enabled = false; dynarray di{-2}; - auto copy = di; + auto copy = dynarray(di); ASSERT_DEATH( copy.erase(di.begin()), "" ); }