public override Digit Remove(int index, Lineage lineage) { var whereIsThisIndex = WhereIsThisIndex(index); #if ASSERTS Size.AssertUnequal(1); #endif TChild res; switch (whereIsThisIndex) { case IN_START: case IN_MIDDLE_OF_1: res = First.Remove(index, lineage); if (res != null && res.IsFragment) { TChild left, right; res.Fuse(Second, out left, out right, lineage); return(CreateCheckNull(lineage, left, right, Third, Fourth)); } return(CreateCheckNull(lineage, res, Second, Third, Fourth)); case IN_START_OF_2: case IN_MIDDLE_OF_2: res = Second.Remove(index - First.Measure, lineage); if (res != null && res.IsFragment) { TChild left, right; First.Fuse(res, out left, out right, lineage); return(CreateCheckNull(lineage, left, right, Third, Fourth)); } return(CreateCheckNull(lineage, First, res, Third, Fourth)); case IN_START_OF_3: case IN_MIDDLE_OF_3: res = Third.Remove(index - First.Measure - Second.Measure, lineage); if (res != null && res.IsFragment) { TChild left, right; Second.Fuse(res, out left, out right, lineage); return(CreateCheckNull(lineage, First, left, right, Fourth)); } return(CreateCheckNull(lineage, First, Second, res, Fourth)); case IN_START_OF_4: case IN_MIDDLE_OF_4: res = Fourth.Remove(index - First.Measure - Second.Measure - Third.Measure, lineage); if (res != null && res.IsFragment) { TChild left, right; Third.Fuse(res, out left, out right, lineage); return(CreateCheckNull(lineage, First, Second, left, right)); } return(CreateCheckNull(lineage, First, Second, Third, res)); case IN_END: case OUTSIDE: throw ImplErrors.Arg_out_of_range("index", index); default: throw ImplErrors.Invalid_execution_path("Checked all index locations."); } }
public override void Fuse(Digit other, out Digit first, out Digit last, Lineage lineage) { Digit skip; Fuse(other, out first, out last, out skip, lineage); }
public override void Insert(int index, Leaf <TValue> leaf, out Digit leftmost, out Digit rightmost, Lineage lineage) { #if ASSERTS leaf.AssertNotNull(); #endif var whereIsThisIndex = WhereIsThisIndex(index); TChild myLeftmost; TChild myRightmost; leftmost = null; rightmost = null; switch (whereIsThisIndex) { case IN_START: case IN_MIDDLE_OF_1: First.Insert(index, leaf, out myLeftmost, out myRightmost, lineage); if (Size == 4 && myRightmost != null) { leftmost = new Digit(myLeftmost, myRightmost, Second, lineage); rightmost = MutateOrCreate(Third, Fourth, lineage); return; } leftmost = myRightmost != null ? CreateCheckNull(lineage, myLeftmost, myRightmost, Second, Third) : CreateCheckNull(lineage, myLeftmost, Second, Third, Fourth); rightmost = null; return; case IN_START_OF_2: case IN_MIDDLE_OF_2: Second.Insert(index - First.Measure, leaf, out myLeftmost, out myRightmost, lineage); if (Size == 4 && myRightmost != null) { leftmost = new Digit(First, myLeftmost, myRightmost, lineage); rightmost = MutateOrCreate(Third, Fourth, lineage); return; } leftmost = myRightmost != null ? CreateCheckNull(lineage, First, myLeftmost, myRightmost, Third) : CreateCheckNull(lineage, First, myLeftmost, Third, Fourth); rightmost = null; return; case IN_START_OF_3: case IN_MIDDLE_OF_3: Third.Insert(index - First.Measure - Second.Measure, leaf, out myLeftmost, out myRightmost, lineage); if (Size == 4 && myRightmost != null) { leftmost = new Digit(First, Second, myLeftmost, lineage); rightmost = MutateOrCreate(myRightmost, Fourth, lineage); return; } leftmost = myRightmost != null ? CreateCheckNull(lineage, First, Second, myLeftmost, myRightmost) : CreateCheckNull(lineage, First, Second, myLeftmost, Fourth); rightmost = null; return; case IN_START_OF_4: case IN_MIDDLE_OF_4: Fourth.Insert(index - Measure + Fourth.Measure, leaf, out myLeftmost, out myRightmost, lineage); if (Size == 4 && myRightmost != null) { leftmost = new Digit(First, Second, Third, lineage); rightmost = MutateOrCreate(myLeftmost, myRightmost, lineage); return; } leftmost = MutateOrCreate(First, Second, Third, myLeftmost, lineage); rightmost = null; return; default: throw ImplErrors.Invalid_execution_path(""); } }
private Digit MutateOrCreate(TChild a, TChild b, TChild c, TChild d, Lineage lineage) { return(Lineage.AllowMutation(lineage) ? _mutate(a.Measure + b.Measure + c.Measure + d.Measure, 4, a, b, c, d) : new Digit(a, b, c, d, lineage)); }
private Digit MutateOrCreate(TChild a, TChild b, Lineage lineage) { return(Lineage.AllowMutation(lineage) ? _mutate(a.Measure + b.Measure, 2, a, b) : new Digit(a, b, lineage)); }
private Digit MutateOrCreate(TChild a, Lineage lineage) { return(Lineage.AllowMutation(lineage) ? _mutate(a.Measure, 1, a) : new Digit(a, lineage)); }
public void Fuse(Digit other, out Digit leftmost, out Digit middle, out Digit rightmost, Lineage lineage) { #if ASSERTS other.AssertNotNull(); #endif var match = (Size << 3) | other.Size; switch (match) { case 1 << 3 | 1: leftmost = MutateOrCreate(First, other.First, lineage); rightmost = null; middle = null; return; case 1 << 3 | 2: leftmost = MutateOrCreate(First, other.First, other.Second, lineage); rightmost = null; middle = null; return; case 1 << 3 | 3: leftmost = MutateOrCreate(First, other.First, other.Second, other.Third, lineage); rightmost = null; middle = null; return; case 1 << 3 | 4: leftmost = new Digit(First, other.First, lineage); middle = MutateOrCreate(other.Second, other.Third, other.Fourth, lineage); rightmost = null; return; case 2 << 3 | 1: leftmost = MutateOrCreate(First, Second, other.First, lineage); middle = null; rightmost = null; return; case 2 << 3 | 2: case 2 << 3 | 3: case 3 << 3 | 2: case 3 << 3 | 3: leftmost = this; middle = other; rightmost = null; return; case 2 << 3 | 4: leftmost = new Digit(First, Second, other.First, lineage); middle = MutateOrCreate(other.Second, other.Third, other.Fourth, lineage); rightmost = null; return; case 3 << 3 | 4: leftmost = this; middle = new Digit(other.First, other.Second, lineage); rightmost = other.MutateOrCreate(other.Third, other.Fourth, lineage); return; case 3 << 3 | 1: leftmost = new Digit(First, Second, lineage); middle = MutateOrCreate(Third, other.First, lineage); rightmost = null; return; case 4 << 3 | 1: leftmost = new Digit(First, Second, lineage); middle = MutateOrCreate(Third, Fourth, other.First, lineage); rightmost = null; return; case 4 << 3 | 2: case 4 << 3 | 3: leftmost = new Digit(First, Second, lineage); middle = MutateOrCreate(Third, Fourth, lineage); rightmost = other; return; case 4 << 3 | 4: leftmost = new Digit(First, Second, Third, lineage); middle = new Digit(Fourth, other.First, other.Second, lineage); rightmost = other.MutateOrCreate(other.Third, other.Fourth, lineage); return; default: throw ImplErrors.Invalid_execution_path("Checked all possible size permutations already."); } //we should've handled all the cases in the Switch statement. Otherwise, produce this error. }
//This method is used when we don't know the exact size of the digit we want to create. public Digit CreateCheckNull(Lineage lineage, TChild item1 = null, TChild item2 = null, TChild item3 = null, TChild item4 = null) { var itemsPresent = item1 != null ? 1 : 0; itemsPresent |= item2 != null ? 2 : 0; itemsPresent |= item3 != null ? 4 : 0; itemsPresent |= item4 != null ? 8 : 0; Digit res; switch (itemsPresent) { case 0 << 0 | 0 << 1 | 0 << 2 | 0 << 3: res = null; break; case 1 << 0 | 0 << 1 | 0 << 2 | 0 << 3: res = MutateOrCreate(item1, lineage); break; case 0 << 0 | 1 << 1 | 0 << 2 | 0 << 3: res = MutateOrCreate(item2, lineage); break; case 0 << 0 | 0 << 1 | 1 << 2 | 0 << 3: res = MutateOrCreate(item3, lineage); break; case 0 << 0 | 0 << 1 | 0 << 2 | 1 << 3: res = MutateOrCreate(item4, lineage); break; case 1 << 0 | 1 << 1 | 0 << 2 | 0 << 3: res = MutateOrCreate(item1, item2, lineage); break; case 1 << 0 | 1 << 1 | 1 << 2 | 0 << 3: res = MutateOrCreate(item1, item2, item3, lineage); break; case 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3: res = MutateOrCreate(item1, item2, item3, item4, lineage); break; case 0 << 0 | 1 << 1 | 1 << 2 | 0 << 3: res = MutateOrCreate(item2, item3, lineage); break; case 0 << 0 | 1 << 1 | 1 << 2 | 1 << 3: res = MutateOrCreate(item2, item3, item4, lineage); break; case 0 << 0 | 0 << 1 | 1 << 2 | 1 << 3: res = MutateOrCreate(item3, item4, lineage); break; case 1 << 0 | 0 << 1 | 1 << 2 | 0 << 3: res = MutateOrCreate(item1, item3, lineage); break; case 1 << 0 | 0 << 1 | 1 << 2 | 1 << 3: res = MutateOrCreate(item1, item3, item4, lineage); break; case 0 << 0 | 1 << 1 | 0 << 2 | 1 << 3: res = MutateOrCreate(item2, item4, lineage); break; case 1 << 0 | 0 << 1 | 0 << 2 | 1 << 3: res = MutateOrCreate(item1, item4, lineage); break; case 1 << 0 | 1 << 1 | 0 << 2 | 1 << 3: res = MutateOrCreate(item1, item2, item4, lineage); break; default: throw ImplErrors.Invalid_execution_path("Checked all digit permutations already."); } return(res); }