| // 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. |