mirror of
https://github.com/taglib/taglib.git
synced 2025-07-18 21:14:23 -04:00
Detach list when setAutoDelete() is called
When calling setAutoDelete() on the implicitly shared copy of a list, also auto-deletion of the original container was modified because it was not detached. On the other hand, detach() was called by some methods getting an Iterator parameter, which can lead to modification of other implicitly shared copies but not the object is was called on. This happens when the method is called on a not-already-detached container, which is normally not the case because the container is detached when the iterator is taken (e.g. calling begin()). In such methods detach() cannot be called, and the client must make sure that the iterator is taken after making an implicit copy. This will NOT work: List<int> l1 = { 1 }; auto it = l1.begin(); List<int> l2 = l1; l1.erase(it); This will modify both l1 and l2. The second and the third lines must be swapped so that l1.begin() will detach l1 from l2.
This commit is contained in:
@ -60,17 +60,36 @@ public:
|
||||
|
||||
void testDetach()
|
||||
{
|
||||
List<int> l1;
|
||||
l1.append(1);
|
||||
l1.append(2);
|
||||
l1.append(3);
|
||||
l1.append(4);
|
||||
{
|
||||
List<int> l1;
|
||||
l1.append(1);
|
||||
l1.append(2);
|
||||
l1.append(3);
|
||||
l1.append(4);
|
||||
|
||||
List<int> l2 = l1;
|
||||
auto it = l2.find(3);
|
||||
*it = 33;
|
||||
CPPUNIT_ASSERT_EQUAL(3, l1[2]);
|
||||
CPPUNIT_ASSERT_EQUAL(33, l2[2]);
|
||||
List<int> l2 = l1;
|
||||
auto it = l2.find(3);
|
||||
*it = 33;
|
||||
CPPUNIT_ASSERT_EQUAL(3, l1[2]);
|
||||
CPPUNIT_ASSERT_EQUAL(33, l2[2]);
|
||||
}
|
||||
{
|
||||
List<int *> l1;
|
||||
List<int *> l2 = l1;
|
||||
CPPUNIT_ASSERT(!l1.autoDelete());
|
||||
CPPUNIT_ASSERT(!l2.autoDelete());
|
||||
l2.setAutoDelete(true);
|
||||
CPPUNIT_ASSERT(!l1.autoDelete());
|
||||
CPPUNIT_ASSERT(l2.autoDelete());
|
||||
}
|
||||
{
|
||||
List<int> l1;
|
||||
List<int> l2 = l1;
|
||||
l1.insert(l1.begin(), 1);
|
||||
CPPUNIT_ASSERT(!l1.isEmpty());
|
||||
CPPUNIT_ASSERT_EQUAL(1, l1.front());
|
||||
CPPUNIT_ASSERT(l2.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
void bracedInit()
|
||||
|
Reference in New Issue
Block a user