blob: 041791b95c8e73148497872bf489585cba2f3316 [file] [log] [blame]
// 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.