public VList(VList <T> list) { this = list; }
public Enumerator(VList <T> list, VList <T> subList) : this(new FVList <T>(list._block, list._localCount), new FVList <T>(subList._block, subList._localCount)) { }
public void SimpleTests() { // In this simple test, I only add and remove items from the back // of a VList, but forking is also tested. VList <int> list = new VList <int>(); Assert.That(list.IsEmpty); // Adding to VListBlockOfTwo list = new VList <int>(10, 20); ExpectList(list, 10, 20); list = new VList <int>(); list.Add(1); Assert.That(!list.IsEmpty); list.Add(2); ExpectList(list, 1, 2); // A fork in VListBlockOfTwo. Note that list2 will use two VListBlocks // here but list will only use one. VList <int> list2 = list.WithoutLast(1); list2.Add(3); ExpectList(list, 1, 2); ExpectList(list2, 1, 3); // Try doubling list2 list2.AddRange(list2); ExpectList(list2, 1, 3, 1, 3); // list now uses two arrays list.Add(4); ExpectList(list, 1, 2, 4); // Try doubling list using a different overload of AddRange() list.AddRange((IList <int>)list); ExpectList(list, 1, 2, 4, 1, 2, 4); list = list.WithoutLast(3); ExpectList(list, 1, 2, 4); // Remove(), Pop() Assert.AreEqual(3, list2.Pop()); ExpectList(list2, 1, 3, 1); Assert.That(!list2.Remove(0)); Assert.AreEqual(1, list2.Pop()); Assert.That(list2.Remove(3)); ExpectList(list2, 1); Assert.That(list2.Remove(1)); ExpectList(list2); AssertThrows <Exception>(delegate() { list2.Pop(); }); // Add many, SubList(). This will fill 3 arrays (sizes 8, 4, 2) and use // 1 element of a size-16 array. Oh, and test the enumerator. for (int i = 5; i <= 16; i++) { list.Add(i); } ExpectList(list, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); list2 = list.WithoutLast(6); ExpectListByEnumerator(list2, 1, 2, 4, 5, 6, 7, 8, 9, 10); AssertThrows <IndexOutOfRangeException>(delegate() { int i = list[-1]; }); AssertThrows <IndexOutOfRangeException>(delegate() { int i = list[15]; }); // IndexOf, contains Assert.That(list.Contains(11)); Assert.That(!list2.Contains(11)); Assert.That(list[list.IndexOf(2)] == 2); Assert.That(list[list.IndexOf(1)] == 1); Assert.That(list[list.IndexOf(15)] == 15); Assert.That(list.IndexOf(3) == -1); // PreviousIn(), Back VList <int> list3 = list2; Assert.AreEqual(11, (list3 = list3.NextIn(list)).Last); Assert.AreEqual(12, (list3 = list3.NextIn(list)).Last); Assert.AreEqual(13, (list3 = list3.NextIn(list)).Last); Assert.AreEqual(14, (list3 = list3.NextIn(list)).Last); Assert.AreEqual(15, (list3 = list3.NextIn(list)).Last); Assert.AreEqual(16, (list3 = list3.NextIn(list)).Last); AssertThrows <Exception>(delegate() { list3.NextIn(list); }); // Next Assert.AreEqual(10, (list3 = list3.WithoutLast(6)).Last); Assert.AreEqual(9, (list3 = list3.Tail).Last); Assert.AreEqual(8, (list3 = list3.Tail).Last); Assert.AreEqual(7, (list3 = list3.Tail).Last); Assert.AreEqual(6, (list3 = list3.Tail).Last); Assert.AreEqual(5, (list3 = list3.Tail).Last); Assert.AreEqual(4, (list3 = list3.Tail).Last); Assert.AreEqual(2, (list3 = list3.Tail).Last); Assert.AreEqual(1, (list3 = list3.Tail).Last); Assert.That((list3 = list3.Tail).IsEmpty); // list2 is still the same ExpectList(list2, 1, 2, 4, 5, 6, 7, 8, 9, 10); // ==, !=, Equals(), AddRange(a, b) Assert.That(!list2.Equals("hello")); list3 = list2; Assert.That(list3.Equals(list2)); Assert.That(list3 == list2); // This AddRange forks the list. List2 ends up with block sizes 8 (3 // used), 8 (3 used), 4, 2. list2.AddRange(list2, list2.WithoutLast(3)); ExpectList(list2, 1, 2, 4, 5, 6, 7, 8, 9, 10, 8, 9, 10); Assert.That(list3 != list2); // List3 is a sublist of list, but list2 no longer is Assert.That(list3.NextIn(list).Last == 11); AssertThrows <InvalidOperationException>(delegate() { list2.NextIn(list); }); list2 = list2.WithoutLast(3); Assert.That(list3 == list2); }
public VList <T> AddRange(VList <T> list) { return(AddRange(list, new VList <T>())); }
public VList <T> AddRange(VList <T> list, VList <T> excludeSubList) { this = VListBlock <T> .AddRange(_block, _localCount, list.ToFVList(), excludeSubList.ToFVList()).ToVList(); return(this); }
public VList <T> NextIn(VList <T> largerList) { return(VListBlock <T> .BackUpOnce(this, largerList)); }
public void TestExampleTransforms() { // These examples are listed in the documentation of FVList.Transform(). // There are more Transform() tests in VListTests() and RWListTests(). VList <int> list = new VList <int>(new int[] { -1, 2, -2, 13, 5, 8, 9 }); VList <int> output; output = list.Transform((int i, ref int n) => { // Keep every second item return((i % 2) == 1 ? XfAction.Keep : XfAction.Drop); }); ExpectList(output, 2, 13, 8); output = list.Transform((int i, ref int n) => { // Keep odd numbers return((n % 2) != 0 ? XfAction.Keep : XfAction.Drop); }); ExpectList(output, -1, 13, 5, 9); output = list.Transform((int i, ref int n) => { // Keep and square all odd numbers if ((n % 2) != 0) { n *= n; return(XfAction.Change); } else { return(XfAction.Drop); } }); ExpectList(output, 1, 169, 25, 81); output = list.Transform((int i, ref int n) => { // Increase each item by its index n += i; return(i == 0 ? XfAction.Keep : XfAction.Change); }); ExpectList(output, -1, 3, 0, 16, 9, 13, 15); list = new VList <int>(new int[] { 1, 2, 3 }); output = list.Transform(delegate(int i, ref int n) { return(i >= 0 ? XfAction.Repeat : XfAction.Keep); }); ExpectList(output, 1, 1, 2, 2, 3, 3); output = list.Transform(delegate(int i, ref int n) { if (i >= 0) { return(XfAction.Repeat); } n *= 10; return(XfAction.Change); }); ExpectList(output, 1, 10, 2, 20, 3, 30); output = list.Transform(delegate(int i, ref int n) { if (i >= 0) { n *= 10; return(XfAction.Repeat); } return(XfAction.Keep); }); ExpectList(output, 10, 1, 20, 2, 30, 3); output = list.Transform(delegate(int i, ref int n) { n *= 10; if (n > 1000) { return(XfAction.Drop); } return(XfAction.Repeat); }); ExpectList(output, 10, 100, 1000, 20, 200, 30, 300); }
public Enumerator(VList <T> list) { _tail = (FVList <T>)list; _current = default(T); }
public void SimpleTests() { // Tests simple adds and removes from the front of the list. It // makes part of its tail immutable, but doesn't make it mutable // again. Also, we test operations that don't modify the list. WList <int> list = new WList <int>(); Assert.That(list.IsEmpty); // create VListBlockOfTwo list = new WList <int>(10, 20); ExpectList(list, 10, 20); // Add() list.Clear(); list.Add(1); Assert.That(!list.IsEmpty); list.Add(2); Assert.AreEqual(1, list.BlockChainLength); list.Add(3); Assert.AreEqual(2, list.BlockChainLength); ExpectList(list, 1, 2, 3); VList <int> snap = list.ToVList(); ExpectList(snap, 1, 2, 3); // AddRange(), Push(), Pop() list.Push(4); list.AddRange(new int[] { 5, 6 }); ExpectList(list, 1, 2, 3, 4, 5, 6); Assert.AreEqual(list.Pop(), 6); ExpectList(list, 1, 2, 3, 4, 5); list.RemoveRange(3, 2); ExpectList(list, 1, 2, 3); // Double the list list.AddRange(list); ExpectList(list, 1, 2, 3, 1, 2, 3); list.RemoveRange(3, 3); // Fill a third block list.AddRange(new int[] { 4, 5, 6, 7, 8, 9 }); list.AddRange(new int[] { 10, 11, 12, 13, 14 }); ExpectList(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); // Remove(), enumerator list.Remove(14); list.Remove(13); list.Remove(12); list.Remove(11); ExpectListByEnumerator(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // IndexOutOfRangeException AssertThrows <IndexOutOfRangeException>(delegate() { int i = list[-1]; }); AssertThrows <IndexOutOfRangeException>(delegate() { int i = list[10]; }); AssertThrows <IndexOutOfRangeException>(delegate() { list.Insert(-1, -1); }); AssertThrows <IndexOutOfRangeException>(delegate() { list.Insert(list.Count + 1, -1); }); AssertThrows <IndexOutOfRangeException>(delegate() { list.RemoveAt(-1); }); AssertThrows <IndexOutOfRangeException>(delegate() { list.RemoveAt(list.Count); }); // Front, Contains, IndexOf Assert.That(list.Last == 10); Assert.That(list.Contains(9)); Assert.That(list[list.IndexOf(2)] == 2); Assert.That(list[list.IndexOf(9)] == 9); Assert.That(list[list.IndexOf(7)] == 7); Assert.That(list.IndexOf(-1) == -1); // snap is still the same ExpectList(snap, 1, 2, 3); }
public void SelectManyTests() { // Plan: make a series of lists of different lengths and transform them // semi-randomly, but do the same transformation on a regular list. Then // ensure that the VList came out the same as the plain List. // // Note: this test isn't included in FVListTests because the FVList.Smart // methods act in "reverse order" compared to the LINQ methods Select/Where/etc. // so the results wouldn't be the same between List<int> and FVList<int>. int initialLength = 0, trial = -1; string subtest = ""; int same = 0, pattern = 0; try { for (initialLength = 0; initialLength < 100; initialLength++) { trial = -1; VList <int> vlist = VList <int> .Empty; List <int> list = new List <int>(); for (int i = 0; i < initialLength; i++) { vlist.Add(i); list.Add(i); } // First, ensure that if the list is not changed, the same list comes out subtest = "unchanged"; Assert.AreEqual(vlist, vlist.SmartSelect(i => i)); Assert.IsTrue(vlist == vlist.SmartSelect(i => i)); Assert.AreEqual(vlist, vlist.SmartWhere(i => true)); Assert.IsTrue(vlist == vlist.SmartWhere(i => true)); Assert.AreEqual(vlist, vlist.SmartSelectMany(i => new[] { i })); Assert.IsTrue(vlist == vlist.SmartSelectMany(i => new[] { i })); for (trial = 0; trial < (initialLength.IsInRange(1, 10) ? 4 : 1); trial++) { // Number of items to keep the same at the beginning of the transform same = initialLength == 0 ? 0 : _r.Next(8) % initialLength; pattern = _r.Next(); int index = 0; Func <int, int> select = n => ++ index <= same ? n : n + 1000; Func <int, bool> where = n => ++ index <= same * 2 || ((pattern >> (index & 31)) & 1) == 0; Func <int, IList <int> > selectMany = n => { var @out = new List <int>(); if (index < same) { @out.Add(n); } else { for (int i = 0; i < ((pattern >> (index & 15)) & 3); i++) { @out.Add(index * 1000 + i); } } index++; return(@out); }; Func <int, IEnumerable <int> > selectManyE = n => selectMany(n); subtest = "SmartSelect"; var expectS = list.Select(select); index = 0; var resultS = vlist.SmartSelect(select); index = 0; ExpectList(resultS, expectS); subtest = "SmartWhere"; var expectW = list.Where(where); index = 0; var resultW = vlist.SmartWhere(where); index = 0; ExpectList(resultW, expectW); subtest = "SmartSelectMany"; var expectM = list.SelectMany(selectManyE); index = 0; var resultM = vlist.SmartSelectMany(selectMany); index = 0; ExpectList(resultM, expectM); } } } catch (Exception e) { e.Data["subtest"] = subtest; e.Data["initialLength"] = initialLength; e.Data["trial"] = trial; e.Data["same"] = same; e.Data["pattern"] = pattern; throw; } }