mirror of
https://github.com/ETLCPP/etl.git
synced 2026-07-30 08:16:19 +08:00
Fix etl::unique_ptr::swap() for deleters (#1482)
* Fix etl::unique_ptr::swap() for deleters Fixes https://github.com/ETLCPP/etl/issues/1481 * Fix etl::deque iterator swap() Swap all members, not just the index.
This commit is contained in:
parent
e6a7642121
commit
0663fc7078
@ -457,6 +457,8 @@ namespace etl
|
||||
using ETL_OR_STD::swap; // Allow ADL
|
||||
|
||||
swap(index, other.index);
|
||||
swap(p_deque, other.p_deque);
|
||||
swap(p_buffer, other.p_buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -703,6 +705,8 @@ namespace etl
|
||||
void swap(const_iterator& other)
|
||||
{
|
||||
ETL_OR_STD::swap(index, other.index);
|
||||
ETL_OR_STD::swap(p_deque, other.p_deque);
|
||||
ETL_OR_STD::swap(p_buffer, other.p_buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -2085,6 +2085,7 @@ namespace etl
|
||||
using ETL_OR_STD::swap;
|
||||
|
||||
swap(p, value.p);
|
||||
swap(deleter, value.deleter);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
@ -2292,6 +2293,7 @@ namespace etl
|
||||
using ETL_OR_STD::swap;
|
||||
|
||||
swap(p, v.p);
|
||||
swap(deleter, v.deleter);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
|
||||
@ -632,6 +632,42 @@ namespace
|
||||
CHECK(third >= first);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
// The member swap() must exchange the complete iterator state (index,
|
||||
// owning deque and buffer).
|
||||
TEST(test_iterator_swap_different_deques)
|
||||
{
|
||||
DataInt data1 = {1, 2, 3, 4, 5};
|
||||
DataInt data2 = {10, 20, 30, 40, 50};
|
||||
|
||||
DataInt::iterator itr1 = data1.begin() + 1; // -> 2
|
||||
DataInt::iterator itr2 = data2.begin() + 3; // -> 40
|
||||
|
||||
itr1.swap(itr2);
|
||||
|
||||
CHECK_EQUAL(40, *itr1);
|
||||
CHECK_EQUAL(2, *itr2);
|
||||
CHECK(&itr1.container() == &data2);
|
||||
CHECK(&itr2.container() == &data1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_const_iterator_swap_different_deques)
|
||||
{
|
||||
DataInt data1 = {1, 2, 3, 4, 5};
|
||||
DataInt data2 = {10, 20, 30, 40, 50};
|
||||
|
||||
DataInt::const_iterator itr1 = data1.begin() + 1; // -> 2
|
||||
DataInt::const_iterator itr2 = data2.begin() + 3; // -> 40
|
||||
|
||||
itr1.swap(itr2);
|
||||
|
||||
CHECK_EQUAL(40, *itr1);
|
||||
CHECK_EQUAL(2, *itr2);
|
||||
CHECK(&itr1.container() == &data2);
|
||||
CHECK(&itr2.container() == &data1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_iterator_comparison_rollover_left)
|
||||
{
|
||||
|
||||
@ -923,6 +923,56 @@ namespace
|
||||
CHECK_EQUAL(1, *up2);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unique_ptr_swap_deleters)
|
||||
{
|
||||
struct Deleter
|
||||
{
|
||||
char id;
|
||||
|
||||
explicit Deleter(const char id_)
|
||||
: id(id_)
|
||||
{
|
||||
}
|
||||
|
||||
Deleter(const Deleter&) = delete;
|
||||
Deleter& operator=(const Deleter&) = delete;
|
||||
|
||||
Deleter(Deleter&& other) noexcept
|
||||
: id(other.id)
|
||||
{
|
||||
other.id = ' ';
|
||||
}
|
||||
|
||||
Deleter& operator=(Deleter&& other) noexcept
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
id = other.id;
|
||||
other.id = ' ';
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Deleter() = default;
|
||||
|
||||
void operator()(int*) const {}
|
||||
};
|
||||
|
||||
int a_obj = 1;
|
||||
int b_obj = 2;
|
||||
etl::unique_ptr<int, Deleter> up1(&a_obj, Deleter('A'));
|
||||
etl::unique_ptr<int, Deleter> up2(&b_obj, Deleter('B'));
|
||||
|
||||
up1.swap(up2);
|
||||
|
||||
CHECK_EQUAL(2, *up1);
|
||||
CHECK_EQUAL('B', up1.get_deleter().id);
|
||||
CHECK_EQUAL(1, *up2);
|
||||
CHECK_EQUAL('A', up2.get_deleter().id);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unique_ptr_from_nullptr_assignment)
|
||||
{
|
||||
@ -1067,6 +1117,56 @@ namespace
|
||||
CHECK_EQUAL(3, up2[3]);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unique_ptr_array_swap_deleters)
|
||||
{
|
||||
struct Deleter
|
||||
{
|
||||
char id;
|
||||
|
||||
explicit Deleter(const char id_)
|
||||
: id(id_)
|
||||
{
|
||||
}
|
||||
|
||||
Deleter(const Deleter&) = delete;
|
||||
Deleter& operator=(const Deleter&) = delete;
|
||||
|
||||
Deleter(Deleter&& other) noexcept
|
||||
: id(other.id)
|
||||
{
|
||||
other.id = ' ';
|
||||
}
|
||||
|
||||
Deleter& operator=(Deleter&& other) noexcept
|
||||
{
|
||||
if (&other != this)
|
||||
{
|
||||
id = other.id;
|
||||
other.id = ' ';
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Deleter() = default;
|
||||
|
||||
void operator()(int*) const {}
|
||||
};
|
||||
|
||||
int a_obj = 1;
|
||||
int b_obj = 2;
|
||||
etl::unique_ptr<int[], Deleter> up1(&a_obj, Deleter('A'));
|
||||
etl::unique_ptr<int[], Deleter> up2(&b_obj, Deleter('B'));
|
||||
|
||||
up1.swap(up2);
|
||||
|
||||
CHECK_EQUAL(2, up1[0]);
|
||||
CHECK_EQUAL('B', up1.get_deleter().id);
|
||||
CHECK_EQUAL(1, up2[0]);
|
||||
CHECK_EQUAL('A', up2.get_deleter().id);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_unique_ptr_array_from_nullptr_assignment)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user