From 7a366cedf395981e5a5155331eaaba2e7b08117c Mon Sep 17 00:00:00 2001 From: Ole Erik Peistorpet Date: Thu, 6 Jun 2024 16:46:52 +0200 Subject: [PATCH] Fixed incorrect dynarray constructor sometimes chosen --- dynarray.h | 4 +++- .../dynarray_construct_assignop_swap_gtest.cpp | 15 +++++++++++++++ util.h | 7 +++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/dynarray.h b/dynarray.h index f8ba76ff..fdaebdd0 100644 --- a/dynarray.h +++ b/dynarray.h @@ -94,7 +94,9 @@ class dynarray auto result = dynarray(boost::range::istream_range(someStream)); @endcode */ template< typename InputRange, - typename /*EnableIfRange*/ = iterator_t > + typename /*EnableIfRange*/ = iterator_t, + enable_if< !_detail::isSameSansCVRef > = 0 + > explicit dynarray(InputRange && r, Alloc a = Alloc{}) : _m(a) { append(r); } dynarray(std::initializer_list il, Alloc a = Alloc{}) : _m(a) { append(il); } diff --git a/unit_test/dynarray_construct_assignop_swap_gtest.cpp b/unit_test/dynarray_construct_assignop_swap_gtest.cpp index b84ff886..974a2256 100644 --- a/unit_test/dynarray_construct_assignop_swap_gtest.cpp +++ b/unit_test/dynarray_construct_assignop_swap_gtest.cpp @@ -315,6 +315,21 @@ 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)); + EXPECT_EQ(0.5, *z.front()); + EXPECT_EQ(3, g_allocCount.nAllocations); +} + template void testMoveConstruct(Alloc a0, Alloc a1) { diff --git a/util.h b/util.h index f6e1b0c2..bf70a688 100644 --- a/util.h +++ b/util.h @@ -170,6 +170,13 @@ namespace _detail OEL_ALWAYS_INLINE constexpr const Empty_type_MSVC_unique_name & second() const { return *this; } OEL_ALWAYS_INLINE constexpr Empty_type_MSVC_unique_name & second() { return *this; } }; + + + + template< typename T, typename U, + typename SansCVRef = std::remove_cv_t< std::remove_reference_t > + > + inline constexpr auto isSameSansCVRef = std::is_same_v; } } // namespace oel