| // Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #include "vm/intrusive_dlist.h" | |
| #include "vm/unit_test.h" | |
| namespace dart { | |
| class Base { | |
| public: | |
| explicit Base(int arg) : base(arg) {} | |
| int base; | |
| }; | |
| class Item : public Base, | |
| public IntrusiveDListEntry<Item>, | |
| public IntrusiveDListEntry<Item, 2> { | |
| public: | |
| explicit Item(int arg0, int arg1) : Base(arg0), item(arg1) {} | |
| int item; | |
| }; | |
| UNIT_TEST_CASE(IntrusiveDListMultiEntryTest) { | |
| Item a1(1, 11), a2(2, 12), a3(3, 13); | |
| IntrusiveDList<Item> all; | |
| IntrusiveDList<Item, 2> ready; | |
| EXPECT(all.IsEmpty()); | |
| EXPECT(ready.IsEmpty()); | |
| all.Append(&a2); | |
| all.Append(&a3); | |
| all.Prepend(&a1); | |
| EXPECT_EQ(all.First()->item, 11); | |
| EXPECT_EQ(all.Last()->item, 13); | |
| ready.Append(&a1); | |
| ready.Append(&a2); | |
| EXPECT_EQ(ready.First()->item, 11); | |
| EXPECT_EQ(ready.Last()->item, 12); | |
| int i = 0; | |
| for (auto it = all.Begin(); it != all.End(); ++it) { | |
| i++; | |
| EXPECT_EQ(it->base, i); | |
| EXPECT_EQ((*it)->base, i); | |
| EXPECT_EQ(it->item, 10 + i); | |
| EXPECT_EQ((*it)->item, 10 + i); | |
| } | |
| EXPECT_EQ(i, 3); | |
| i = 0; | |
| for (auto it = ready.Begin(); it != ready.End(); ++it) { | |
| i++; | |
| EXPECT_EQ(it->base, i); | |
| EXPECT_EQ((*it)->base, i); | |
| EXPECT_EQ(it->item, 10 + i); | |
| EXPECT_EQ((*it)->item, 10 + i); | |
| } | |
| EXPECT_EQ(i, 2); | |
| ready.Remove(&a1); | |
| ready.Remove(&a2); | |
| all.Remove(&a1); | |
| all.Remove(&a2); | |
| all.Remove(&a3); | |
| EXPECT(all.IsEmpty()); | |
| EXPECT(ready.IsEmpty()); | |
| } | |
| UNIT_TEST_CASE(IntrusiveDListRemoveFirstTest) { | |
| Item a1(1, 11), a2(2, 12), a3(3, 13); | |
| IntrusiveDList<Item> all; | |
| all.Append(&a2); | |
| all.Append(&a3); | |
| all.Prepend(&a1); | |
| EXPECT_EQ(&a1, all.RemoveFirst()); | |
| EXPECT_EQ(&a2, all.RemoveFirst()); | |
| EXPECT_EQ(&a3, all.RemoveFirst()); | |
| EXPECT(all.IsEmpty()); | |
| } | |
| UNIT_TEST_CASE(IntrusiveDListRemoveLastTest) { | |
| Item a1(1, 11), a2(2, 12), a3(3, 13); | |
| IntrusiveDList<Item> all; | |
| all.Append(&a2); | |
| all.Append(&a3); | |
| all.Prepend(&a1); | |
| EXPECT_EQ(&a3, all.RemoveLast()); | |
| EXPECT_EQ(&a2, all.RemoveLast()); | |
| EXPECT_EQ(&a1, all.RemoveLast()); | |
| EXPECT(all.IsEmpty()); | |
| } | |
| UNIT_TEST_CASE(IntrusiveDListIsInList) { | |
| Item a1(1, 11), a2(2, 12), a3(3, 13); | |
| IntrusiveDList<Item> all; | |
| all.Append(&a2); | |
| all.Append(&a3); | |
| all.Prepend(&a1); | |
| ASSERT(all.IsInList(&a1)); | |
| ASSERT(all.IsInList(&a2)); | |
| ASSERT(all.IsInList(&a3)); | |
| EXPECT_EQ(&a1, all.RemoveFirst()); | |
| EXPECT(!all.IsInList(&a1)); | |
| EXPECT_EQ(&a3, all.RemoveLast()); | |
| EXPECT(!all.IsInList(&a3)); | |
| EXPECT_EQ(&a2, all.RemoveFirst()); | |
| EXPECT(!all.IsInList(&a2)); | |
| EXPECT(all.IsEmpty()); | |
| } | |
| UNIT_TEST_CASE(IntrusiveDListEraseIterator) { | |
| Item a1(1, 11), a2(2, 12), a3(3, 13); | |
| IntrusiveDList<Item> all; | |
| all.Append(&a2); | |
| all.Append(&a3); | |
| all.Prepend(&a1); | |
| auto it = all.Begin(); | |
| it = all.Erase(++it); | |
| EXPECT_EQ(*it, &a3); | |
| EXPECT_EQ(*it, all.Last()); | |
| it = all.Erase(all.Begin()); | |
| EXPECT_EQ(*it, &a3); | |
| EXPECT_EQ(*it, all.First()); | |
| EXPECT_EQ(*it, all.Last()); | |
| it = all.Erase(all.Begin()); | |
| EXPECT(it == all.End()); | |
| EXPECT(all.IsEmpty()); | |
| } | |
| UNIT_TEST_CASE(IntrusiveDListAppendListTest) { | |
| // Append to empty list. | |
| { | |
| IntrusiveDList<Item> all; | |
| IntrusiveDList<Item> other; | |
| Item a1(1, 11), a2(2, 12); | |
| all.Append(&a1); | |
| all.Append(&a2); | |
| other.AppendList(&all); | |
| EXPECT(all.IsEmpty()); | |
| EXPECT(!other.IsEmpty()); | |
| EXPECT_EQ(&a1, other.First()); | |
| EXPECT_EQ(&a2, other.Last()); | |
| auto it = other.Begin(); | |
| EXPECT_EQ(&a1, *it); | |
| it = other.Erase(it); | |
| EXPECT_EQ(&a2, *it); | |
| it = other.Erase(it); | |
| EXPECT(it == other.end()); | |
| } | |
| // Append to non-empty list. | |
| { | |
| IntrusiveDList<Item> all; | |
| IntrusiveDList<Item> other; | |
| Item a1(1, 11), a2(2, 12); | |
| all.Append(&a1); | |
| all.Append(&a2); | |
| Item o1(1, 11); | |
| other.Append(&o1); | |
| other.AppendList(&all); | |
| EXPECT(all.IsEmpty()); | |
| EXPECT(!other.IsEmpty()); | |
| EXPECT_EQ(&o1, other.First()); | |
| EXPECT_EQ(&a2, other.Last()); | |
| auto it = other.Begin(); | |
| EXPECT_EQ(&o1, *it); | |
| it = other.Erase(it); | |
| EXPECT_EQ(&a1, *it); | |
| it = other.Erase(it); | |
| EXPECT_EQ(&a2, *it); | |
| it = other.Erase(it); | |
| EXPECT(it == other.end()); | |
| } | |
| } | |
| } // namespace dart. |