public void TestMutabilification() { // Make a single block mutable RVList <int> v = new RVList <int>(1, 0); RWList <int> w = v.ToRWList(); ExpectList(w, 1, 0); w[1] = 2; ExpectList(w, 1, 2); ExpectList(v, 1, 0); // Make another block, make the front block mutable, then the block-of-2 v.Push(-1); w = v.ToRWList(); w[2] = 3; ExpectList(w, 1, 0, 3); Assert.That(w.WithoutLast(1) == v.WithoutLast(1)); w[1] = 2; ExpectList(w, 1, 2, 3); Assert.That(w.WithoutLast(1) != v.WithoutLast(1)); // Now for a more complicated case: create a long immutable chain by // using a nasty access pattern, add a mutable block in front, then // make some of the immutable blocks mutable. This will cause several // immutable blocks to be consolidated into one mutable block, // shortening the chain. v = new RVList <int>(6); v = v.Add(-1).Tail.Add(5).Add(-1).Tail.Add(4).Add(-1).Tail.Add(3); v = v.Add(-1).Tail.Add(2).Add(-1).Tail.Add(1).Add(-1).Tail.Add(0); ExpectList(v, 6, 5, 4, 3, 2, 1, 0); // At this point, every block in the chain has only one item (it's // a linked list!) and the capacity of each block is 2. Assert.AreEqual(7, v.BlockChainLength); w = v.ToRWList(); w.AddRange(new int[] { 1, 2, 3, 4, 5 }); Assert.AreEqual(w.Count, 12); ExpectList(w, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5); // Indices: 0 1 2 3 4 5 6 7 8 9 10 11 // Blocks: H| G| F| E| D| C| B | block A (front of chain) Assert.AreEqual(8, w.BlockChainLength); Assert.AreEqual(4, w.LocalCount); w[3] = -3; ExpectList(w, 6, 5, 4, -3, 2, 1, 0, 1, 2, 3, 4, 5); // Indices: 0 1 2 3 4 5 6 7 8 9 10 11 // Blocks: H| G| F| block I | block A (front of chain) Assert.AreEqual(5, w.BlockChainLength); }
public void TestInsertRemove() { RWList <int> list = new RWList <int>(); for (int i = 0; i <= 12; i++) { list.Insert(0, i); } ExpectList(list, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); for (int i = 1; i <= 6; i++) { list.RemoveAt(i); } ExpectList(list, 12, 10, 8, 6, 4, 2, 0); Assert.AreEqual(0, list.Pop()); list.Insert(1, -2); ExpectList(list, 12, -2, 10, 8, 6, 4, 2); list.Insert(2, -1); ExpectList(list, 12, -2, -1, 10, 8, 6, 4, 2); Assert.That(list.Remove(-1)); Assert.That(list.Remove(12)); list[0] = 12; ExpectList(list, 12, 10, 8, 6, 4, 2); // Make sure RWList.Clear doesn't disturb FVList RVList <int> v = list.WithoutLast(4); list.Clear(); ExpectList(list); ExpectList(v, 12, 10); // Some simple InsertRange calls where some immutable items must be // converted to mutable RVList <int> oneTwo = new RVList <int>(1, 2); RVList <int> threeFour = new RVList <int>(3, 4); list = oneTwo.ToRWList(); list.InsertRange(1, threeFour); ExpectList(list, 1, 3, 4, 2); list = threeFour.ToRWList(); list.InsertRange(0, oneTwo); ExpectList(list, 1, 2, 3, 4); // More tests... list.RemoveRange(2, 2); ExpectList(list, 1, 2); list.InsertRange(2, new int[] { 3, 3, 4, 4, 4, 5, 6, 7, 8, 9 }); ExpectList(list, 1, 2, 3, 3, 4, 4, 4, 5, 6, 7, 8, 9); list.RemoveRange(3, 3); ExpectList(list, 1, 2, 3, 4, 5, 6, 7, 8, 9); v = list.ToRVList(); list.RemoveRange(5, 4); ExpectList(list, 1, 2, 3, 4, 5); ExpectList(v, 1, 2, 3, 4, 5, 6, 7, 8, 9); }