Ejemplo n.º 1
0
                public override void IterBack(Action <Leaf <TValue> > action)
                {
#if ASSERTS
                    action.AssertNotNull();
#endif
                    switch (Size)
                    {
                    case 1:
                        First.IterBack(action);
                        return;

                    case 2:
                        Second.IterBack(action);
                        First.IterBack(action);
                        return;

                    case 3:
                        Third.IterBack(action);
                        Second.IterBack(action);
                        First.IterBack(action);
                        return;

                    case 4:
                        Fourth.IterBack(action);
                        Third.IterBack(action);
                        Second.IterBack(action);
                        First.IterBack(action);
                        return;

                    default:
                        throw ImplErrors.Invalid_execution_path("Checked all sizes already");
                    }
                }
Ejemplo n.º 2
0
            /// <summary>
            ///     Adds the specified key-value pair to the tree. O(logn)
            /// </summary>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <param name="lineage"></param>
            /// <param name="overwrite"></param>
            /// <returns></returns>
            private Node AvlAdd(TKey key, TValue value, Lineage lineage, bool overwrite)
            {
                if (IsEmpty)
                {
                    throw ImplErrors.Invalid_invocation("EmptyNode");
                }
                var r = Comparer.Compare(key, Key);

                if (r < 0)
                {
                    var newLeft = Left.IsEmpty ? NewForKvp(key, value, lineage) : Left.AvlAdd(key, value, lineage, overwrite);
                    if (newLeft == null)
                    {
                        return(null);
                    }
                    return(AvlBalance(newLeft, Right, lineage));
                }
                if (r > 0)
                {
                    var newRight = Right.IsEmpty ? NewForKvp(key, value, lineage) : Right.AvlAdd(key, value, lineage, overwrite);
                    if (newRight == null)
                    {
                        return(null);
                    }
                    return(AvlBalance(Left, newRight, lineage));
                }
                return(overwrite ? WithValue(value, lineage) : null);
            }
Ejemplo n.º 3
0
                public override string Print()
                {
                    string[] rest;
                    switch (Size)
                    {
                    case 1:
                        rest = new[] { First.Print() };
                        break;

                    case 2:
                        rest = new[] { First.Print(), Second.Print() };
                        break;

                    case 3:
                        rest = new[] { First.Print(), Second.Print(), Third.Print() };
                        break;

                    case 4:
                        rest = new[] { First.Print(), Second.Print(), Third.Print(), Fourth.Print() };
                        break;

                    default:
                        throw ImplErrors.Bad_digit_size(Size);
                    }
                    var joined = String.Join(", ", rest);

                    return(Measure == Size?Measure.ToString() : string.Format("{2} {0}: ({1})", Size, Measure, joined));
                }
Ejemplo n.º 4
0
                Digit Update_MUTATES(int index, Leaf <TValue> leaf)
                {
                    var whereIsThisIndex = WhereIsThisIndex(index);

                    switch (whereIsThisIndex)
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_1:
                        First = First.Update(index, leaf, Lineage);
                        return(this);

                    case IN_START_OF_2:
                    case IN_MIDDLE_OF_2:
                        Second = Second.Update(index - First.Measure, leaf, Lineage);
                        return(this);

                    case IN_START_OF_3:
                    case IN_MIDDLE_OF_3:
                        Third = Third.Update(index - First.Measure - Second.Measure, leaf, Lineage);
                        return(this);

                    case IN_START_OF_4:
                    case IN_MIDDLE_OF_4:
                        Fourth = Fourth.Update(index - First.Measure - Second.Measure - Third.Measure, leaf, Lineage);
                        return(this);

                    case IN_END:
                    case OUTSIDE:
                        throw ImplErrors.Arg_out_of_range("index", index);

                    default:
                        throw ImplErrors.Invalid_execution_path("Checked all index locations already.");
                    }
                }
Ejemplo n.º 5
0
 public override FingerTreeElement GetChild(int index)
 {
     if (index != 0)
     {
         throw ImplErrors.Arg_out_of_range("index", index);
     }
     return(CenterDigit);
 }
Ejemplo n.º 6
0
                public override void Split(int index, out FTree <TChild> left, out TChild child, out FTree <TChild> right, Lineage lineage)
                {
#if ASSERTS
                    var oldMeasure = Measure;
                    var oldValue   = this[index];
#endif
                    switch (WhereIsThisIndex(index))
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_LEFT:
                        Digit lLeft, lRight;
                        LeftDigit.Split(index, out lLeft, out child, out lRight, lineage);
                        index -= lLeft == null ? 0 : lLeft.Measure;
                        left   = CreateCheckNull(Lineage.Immutable, lLeft);
                        right  = CreateCheckNull(lineage, lRight, DeepTree, RightDigit);
                        break;

                    case IN_START_OF_DEEP:
                    case IN_MIDDLE_OF_DEEP:
                        index -= LeftDigit.Measure;
                        FTree <Digit> mLeft, mRight;
                        Digit         mCenter;
                        DeepTree.Split(index, out mLeft, out mCenter, out mRight, lineage);
                        Digit mcLeft, mcRight;
                        index -= mLeft.Measure;
                        mCenter.Split(index, out mcLeft, out child, out mcRight, lineage);
                        index -= mcLeft == null ? 0 : mcLeft.Measure;
                        left   = CreateCheckNull(Lineage.Immutable, LeftDigit, mLeft, mcLeft);
                        right  = CreateCheckNull(lineage, mcRight, mRight, RightDigit);
                        break;

                    case IN_MIDDLE_OF_RIGHT:
                    case IN_START_OF_RIGHT:
                        Digit rLeft, rRight;
                        index -= LeftDigit.Measure + DeepTree.Measure;
                        RightDigit.Split(index, out rLeft, out child, out rRight, lineage);
                        index -= rLeft == null ? 0 : rLeft.Measure;
                        right  = CreateCheckNull(Lineage.Immutable, rRight);
                        left   = CreateCheckNull(lineage, LeftDigit, DeepTree, rLeft);
                        break;

                    case IN_END:
                    case OUTSIDE:
                        throw ImplErrors.Arg_out_of_range("index", index);

                    default:
                        throw ImplErrors.Invalid_execution_path("Index didn't match any of the cases.");
                    }
#if ASSERTS
                    oldMeasure.AssertEqual(left.Measure + child.Measure + right.Measure);
                    oldValue.AssertEqual(child[index]);
#endif
                }
Ejemplo n.º 7
0
 /// <summary>
 ///     Removes the minimum element and returns it. O(logn)
 /// </summary>
 /// <param name="min"></param>
 /// <param name="lineage"></param>
 /// <returns></returns>
 public Node ExtractMin(out Node min, Lineage lineage)
 {
     if (IsEmpty)
     {
         throw ImplErrors.Invalid_invocation("EmptyNode");
     }
     if (!Left.IsEmpty)
     {
         return(AvlBalance(Left.ExtractMin(out min, lineage), Right, lineage));
     }
     min = this;
     return(Right);
 }
Ejemplo n.º 8
0
 public Node ExtractMax(out Node max, Lineage lineage)
 {
     if (IsEmpty)
     {
         throw ImplErrors.Invalid_invocation("EmptyNode");
     }
     if (!Right.IsEmpty)
     {
         return(AvlBalance(Left, Right.ExtractMax(out max, lineage), lineage));
     }
     max = this;
     return(Left);
 }
Ejemplo n.º 9
0
                /// <summary>
                ///     Returns a code telling where is the index located
                /// </summary>
                /// <param name="index"> </param>
                /// <returns> </returns>
                int WhereIsThisIndex(int index)
                {
#if ASSERTS
                    index.AssertEqual(i => i < Measure);
#endif
                    var measure1 = First.Measure;
                    if (index == 0)
                    {
                        return(IN_START);
                    }
                    if (index < measure1)
                    {
                        return(IN_MIDDLE_OF_1);
                    }
                    if (index == measure1)
                    {
                        return(IN_START_OF_2);
                    }
                    var measure2 = measure1 + Second.Measure;
                    if (index < measure2)
                    {
                        return(IN_MIDDLE_OF_2);
                    }
                    if (index == measure2)
                    {
                        return(IN_START_OF_3);
                    }
                    var measure3 = measure2 + Third.Measure;
                    if (index < measure3)
                    {
                        return(IN_MIDDLE_OF_3);
                    }
                    if (index == measure3)
                    {
                        return(IN_START_OF_4);
                    }
                    var measure4 = measure3 + Fourth.Measure;
                    if (index < measure4)
                    {
                        return(IN_MIDDLE_OF_4);
                    }
                    if (index == measure4)
                    {
                        return(IN_END);
                    }
                    if (index > measure4)
                    {
                        return(OUTSIDE);
                    }
                    throw ImplErrors.Invalid_execution_path("Checked all possible index locations");
                }
Ejemplo n.º 10
0
            private Node AvlAdd(int hash, TKey key, TValue value, Lineage lineage, bool overwrite)
            {
#if ASSERTS
                var initialCount = Count;
#endif
                if (IsEmpty)
                {
                    throw ImplErrors.Invalid_invocation("Empty Node");
                }
                Node ret;
                if (hash < Hash)
                {
                    var newLeft = Left.IsEmpty
                                                ? NewForKvp(hash, key, value, lineage)
                                                : Left.AvlAdd(hash, key, value, lineage, overwrite);
                    if (newLeft == null)
                    {
                        return(null);
                    }
                    ret = AvlBalance(newLeft, Right, lineage);
                }
                else if (hash > Hash)
                {
                    var newRight = Right.IsEmpty
                                                ? NewForKvp(hash, key, value, lineage)
                                                : Right.AvlAdd(hash, key, value, lineage, overwrite);
                    if (newRight == null)
                    {
                        return(null);
                    }
                    ret = AvlBalance(Left, newRight, lineage);
                }
                else
                {
                    var newBucket = Bucket.Add(key, value, lineage, overwrite);
                    if (newBucket == null)
                    {
                        return(null);
                    }
                    ret = WithBucket(newBucket, lineage);
                }


#if ASSERTS
                ret.Count.AssertEqual(x => x <= initialCount + 1 && x >= initialCount);
                ret.IsBalanced.AssertTrue();
                ret.Root_Contains(key).AssertTrue();
                //ret.AllBuckets.Count(b => b.Find(key).IsSome).Is(1);
#endif
                return(ret);
            }
Ejemplo n.º 11
0
                FTree <TChild> CreateCheckNull(Lineage lineage, Digit left = null, FTree <Digit> deep = null, Digit right = null)
                {
                    var memberPermutation = left != null ? 1 << 0 : 0;

                    memberPermutation |= (deep != null && deep.Measure != 0) ? 1 << 1 : 0;
                    memberPermutation |= right != null ? 1 << 2 : 0;

                    switch (memberPermutation)
                    {
                    case 0 << 0 | 0 << 1 | 0 << 2:
                            return(Empty);

                    case 1 << 0 | 0 << 1 | 0 << 2:
                            return(new Single(left, lineage));

                    case 1 << 0 | 1 << 1 | 0 << 2:
                            var r2    = deep.Right;
                        var     deep1 = deep.RemoveLast(lineage);

                        return(MutateOrCreate(left, deep1, r2, lineage));

                    case 1 << 0 | 1 << 1 | 1 << 2:
                            return(MutateOrCreate(left, deep, right, lineage));

                    case 0 << 0 | 1 << 1 | 1 << 2:
                            return(MutateOrCreate(deep.Left, deep.RemoveFirst(lineage), right, lineage));

                    case 1 << 0 | 0 << 1 | 1 << 2:
                            return(MutateOrCreate(left, deep, right, lineage));

                    case 0 << 0 | 1 << 1 | 0 << 2:
                            left = deep.Left;
                        deep     = deep.RemoveFirst(lineage);
                        if (deep.Measure != 0)
                        {
                            right = deep.Right;
                            deep  = deep.RemoveLast(lineage);
                            return(MutateOrCreate(left, deep, right, lineage));
                        }
                        return(new Single(left, lineage));

                    case 0 << 0 | 0 << 1 | 1 << 2:
                            return(new Single(right, lineage));

                    default:
                        throw ImplErrors.Invalid_execution_path("Explicitly checked all possible tree permutations.");
                    }
                }
Ejemplo n.º 12
0
 public Bucket ByArbitraryOrder(int index)
 {
     if (IsEmpty)
     {
         throw ImplErrors.Arg_out_of_range("index", index);
     }
     if (index < Left.Count)
     {
         return(Left.ByArbitraryOrder(index));
     }
     if (index < Left.Count + Bucket.Count)
     {
         return(Bucket.ByIndex(index - Left.Count));
     }
     return(Right.ByArbitraryOrder(index - Left.Count - Bucket.Count));
 }
Ejemplo n.º 13
0
                public override FingerTreeElement GetChild(int index)
                {
                    switch (index)
                    {
                    case 0:
                        return(LeftDigit);

                    case 1:
                        return(DeepTree);

                    case 2:
                        return(RightDigit);

                    default:
                        throw ImplErrors.Arg_out_of_range("index", index);
                    }
                }
Ejemplo n.º 14
0
            public Bucket Add(TKey key, TValue v, Lineage lin, bool overwrite)
            {
                if (IsEmpty)
                {
                    throw ImplErrors.Invalid_invocation("Empty Bucket");
                }
                if (Eq.Equals(key, Key))
                {
                    return(overwrite ? WithKeyValue(key, v, lin) : null);
                }
                var newNext = Next.IsEmpty ? new Bucket(key, v, Empty, Eq, lin) : Next.Add(key, v, lin, overwrite);

                if (newNext == null)
                {
                    return(null);
                }
                return(WithNext(newNext, lin));
            }
Ejemplo n.º 15
0
                public Digit AddLast(TChild item, Lineage lineage)
                {
                    switch (Size)
                    {
                    case 1:
                        return(MutateOrCreate(First, item, lineage));

                    case 2:
                        return(MutateOrCreate(First, Second, item, lineage));

                    case 3:
                        return(MutateOrCreate(First, Second, Third, item, lineage));

                    case 4:
                        throw ImplErrors.Bad_digit_size(Size);
                    }
                    throw ImplErrors.Bad_digit_size(Size);
                }
Ejemplo n.º 16
0
                public Digit RemoveFirst(Lineage lineage)
                {
                    switch (Size)
                    {
                    case 1:
                        throw ImplErrors.Digit_too_small(Size);

                    case 2:
                        return(MutateOrCreate(Second, lineage));

                    case 3:
                        return(MutateOrCreate(Second, Third, lineage));

                    case 4:
                        return(MutateOrCreate(Second, Third, Fourth, lineage));
                    }
                    throw ImplErrors.Bad_digit_size(Size);
                }
Ejemplo n.º 17
0
                public Digit RemoveLast(Lineage lineage)
                {
                    switch (Size)
                    {
                    case 1:
                        throw ImplErrors.Bad_digit_size(Size);

                    case 2:
                        return(MutateOrCreate(First, lineage));

                    case 3:
                        return(MutateOrCreate(First, Second, lineage));

                    case 4:
                        return(MutateOrCreate(First, Second, Third, lineage));
                    }
                    throw ImplErrors.Bad_digit_size(Size);
                }
Ejemplo n.º 18
0
                public override FingerTreeElement GetChild(int index)
                {
                    switch (index)
                    {
                    case 0:
                        return(First);

                    case 1:
                        return(Second);

                    case 2:
                        return(Third);

                    case 3:
                        return(Fourth);

                    default:
                        throw ImplErrors.Arg_out_of_range("index", index);
                    }
                }
Ejemplo n.º 19
0
                public override FTree <TChild> Update(int index, Leaf <TValue> leaf, Lineage lineage)
                {
                    var            whereIsThisIndex = WhereIsThisIndex(index);
                    FTree <TChild> ret;

#if ASSERTS
                    var oldSize = Measure;
#endif
                    switch (whereIsThisIndex)
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_LEFT:
                        var newLeft = LeftDigit.Update(index, leaf, lineage);
                        ret = MutateOrCreate(newLeft, DeepTree, RightDigit, lineage);
                        break;

                    case IN_START_OF_DEEP:
                    case IN_MIDDLE_OF_DEEP:
                        if (DeepTree.Measure == 0)
                        {
                            goto case IN_START_OF_RIGHT;
                        }
                        var newDeep = DeepTree.Update(index - LeftDigit.Measure, leaf, lineage);
                        ret = MutateOrCreate(LeftDigit, newDeep, RightDigit, lineage);
                        break;

                    case IN_START_OF_RIGHT:
                    case IN_MIDDLE_OF_RIGHT:
                        var newRight = RightDigit.Update(index - LeftDigit.Measure - DeepTree.Measure, leaf, lineage);
                        ret = MutateOrCreate(LeftDigit, DeepTree, newRight, lineage);
                        break;

                    default:
                        throw ImplErrors.Arg_out_of_range("index", index);
                    }
#if ASSERTS
                    ret.Measure.AssertEqual(oldSize);
                    ret[index].AssertEqual(leaf);
#endif
                    return(ret);
                }
Ejemplo n.º 20
0
                public override Digit Update(int index, Leaf <TValue> leaf, Lineage lineage)
                {
                    if (Lineage.AllowMutation(lineage))
                    {
                        return(Update_MUTATES(index, leaf));
                    }
#if ASSERTS
                    leaf.AssertNotNull();
#endif
                    var    whereIsThisIndex = WhereIsThisIndex(index);
                    TChild res;
                    switch (whereIsThisIndex)
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_1:
                        res = First.Update(index, leaf, lineage);
                        return(CreateCheckNull(lineage, res, Second, Third, Fourth));

                    case IN_START_OF_2:
                    case IN_MIDDLE_OF_2:
                        res = Second.Update(index - First.Measure, leaf, lineage);
                        return(CreateCheckNull(lineage, First, res, Third, Fourth));

                    case IN_START_OF_3:
                    case IN_MIDDLE_OF_3:
                        res = Third.Update(index - First.Measure - Second.Measure, leaf, lineage);
                        return(CreateCheckNull(lineage, First, Second, res, Fourth));

                    case IN_START_OF_4:
                    case IN_MIDDLE_OF_4:
                        res = Fourth.Update(index - First.Measure - Second.Measure - Third.Measure, leaf, lineage);
                        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.");
                    }
                }
Ejemplo n.º 21
0
                public override Digit Reverse(Lineage lineage)
                {
                    switch (Size)
                    {
                    case 1:
                        return(MutateOrCreate(First.Reverse(lineage), lineage));

                    case 2:
                        return(MutateOrCreate(Second.Reverse(lineage), First.Reverse(lineage), lineage));

                    case 3:
                        return(MutateOrCreate(Third.Reverse(lineage), Second.Reverse(lineage), First.Reverse(lineage), lineage));

                    case 4:
                        return(MutateOrCreate(Fourth.Reverse(lineage), Third.Reverse(lineage), Second.Reverse(lineage),
                                              First.Reverse(lineage), lineage));

                    default:
                        throw ImplErrors.Invalid_execution_path("Checked all sizes");
                    }
                }
Ejemplo n.º 22
0
 public Node ByOrder(int index)
 {
     for (Node cur = this; !cur.IsEmpty;)
     {
         var left = cur.Left.Count;
         if (index < left)
         {
             cur = cur.Left;
         }
         else if (index == left)
         {
             return(cur);
         }
         else
         {
             cur    = cur.Right;
             index -= left + 1;
         }
     }
     throw ImplErrors.Arg_out_of_range("index", index);
 }
Ejemplo n.º 23
0
                public void Split(int index, out Digit left, out TChild center, out Digit right, Lineage lineage)
                {
                    switch (WhereIsThisIndex(index))
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_1:
                        left   = null;
                        center = First;
                        right  = CreateCheckNull(lineage, Second, Third, Fourth);
                        break;

                    case IN_START_OF_2:
                    case IN_MIDDLE_OF_2:
                        left   = new Digit(First, lineage);
                        center = Second;
                        right  = CreateCheckNull(lineage, Third, Fourth);
                        break;

                    case IN_START_OF_3:
                    case IN_MIDDLE_OF_3:
                        left   = new Digit(First, Second, lineage);
                        center = Third;
                        right  = CreateCheckNull(lineage, Fourth);
                        break;

                    case IN_MIDDLE_OF_4:
                    case IN_START_OF_4:
                        left   = new Digit(First, Second, Third, lineage);
                        center = Fourth;
                        right  = null;
                        break;

                    case IN_END:
                    case OUTSIDE:
                        throw ImplErrors.Arg_out_of_range("index", index);

                    default:
                        throw ImplErrors.Invalid_execution_path("Checked all index locations.");
                    }
                }
Ejemplo n.º 24
0
            private Node ExtractMin(out Node min, Lineage lineage)
            {
                if (IsEmpty)
                {
                    throw ImplErrors.Invalid_invocation("EmptyNode");
                }
                Node ret;

                if (!Left.IsEmpty)
                {
                    ret = AvlBalance(Left.ExtractMin(out min, lineage), Right, lineage);
                }
                else
                {
                    min = this;
                    ret = Right;
                }
#if ASSERTS
                ret.IsBalanced.AssertTrue();
#endif
                return(ret);
            }
Ejemplo n.º 25
0
                public override Leaf <TValue> this[int index] {
                    get {
                        index.AssertEqual(i => i < Measure);

                        var m1 = LeftDigit.Measure;
                        var m2 = DeepTree.Measure + m1;

                        if (index < m1)
                        {
                            return(LeftDigit[index]);
                        }
                        if (index < m2)
                        {
                            return(DeepTree[index - m1]);
                        }
                        if (index < Measure)
                        {
                            return(RightDigit[index - m2]);
                        }

                        throw ImplErrors.Arg_out_of_range("index", index);
                    }
                }
Ejemplo n.º 26
0
                public Digit ConstructMult(TValue[] arr, ref int index, int mult, Lineage lin)
                {
                    var c = ExampleChild;

                    switch (mult)
                    {
                    case 1:
                        return(new Digit(c.Construct3(arr, ref index, lin), lin));

                    case 2:
                        return(new Digit(c.Construct3(arr, ref index, lin), c.Construct3(arr, ref index, lin), lin));

                    case 3:
                        return(new Digit(c.Construct3(arr, ref index, lin), c.Construct3(arr, ref index, lin),
                                         c.Construct3(arr, ref index, lin), lin));

                    case 4:
                        return(new Digit(c.Construct3(arr, ref index, lin), c.Construct3(arr, ref index, lin),
                                         c.Construct3(arr, ref index, lin), c.Construct3(arr, ref index, lin), lin));

                    default:
                        throw ImplErrors.Bad_digit_size(mult);
                    }
                }
Ejemplo n.º 27
0
 public override FTree <TChild> RemoveAt(int index, Lineage lineage)
 {
     throw ImplErrors.Invalid_invocation("Empty FingerTree");
 }
Ejemplo n.º 28
0
 public override FTree <TChild> Update(int index, Leaf <TValue> leaf, Lineage lineage)
 {
     throw ImplErrors.Invalid_invocation("Empty FingerTree");
 }
Ejemplo n.º 29
0
 public override FingerTreeElement GetChild(int index)
 {
     throw ImplErrors.Invalid_invocation("Empty FingerTree");
 }
Ejemplo n.º 30
0
                public override FTree <TChild> RemoveAt(int index, Lineage lineage)
                {
                    var            whereIsThisIndex = WhereIsThisIndex(index);
                    Digit          newLeft;
                    FTree <TChild> ret = this;

#if ASSERTS
                    var newMeasure          = Measure - 1;
                    var expectedAtIndex     = index != Measure - 1 ? this[index + 1] : null;
                    var expectedBeforeIndex = index != 0 ? this[index - 1] : null;
#endif
                    switch (whereIsThisIndex)
                    {
                    case IN_START:
                    case IN_MIDDLE_OF_LEFT:
                        if (LeftDigit.IsFragment)
                        {
                            var fixedTree = FixLeftDigit(lineage);
                            ret = fixedTree.RemoveAt(index, lineage);
                        }
                        else
                        {
                            newLeft = LeftDigit.Remove(index, lineage);
                            ret     = CreateCheckNull(lineage, newLeft, DeepTree, RightDigit);
                        }
                        break;

                    case IN_START_OF_DEEP:
                    case IN_MIDDLE_OF_DEEP:
                        if (DeepTree.Measure == 0)
                        {
                            goto case IN_START_OF_RIGHT;
                        }
                        var           deep = DeepTree;
                        FTree <Digit> newDeep;
                        if (deep.IsFragment)
                        {
                            newDeep = deep.AddFirst(LeftDigit, lineage);
                            newDeep = newDeep.RemoveAt(index, lineage);
                            newLeft = newDeep.Left;
                            newDeep = newDeep.RemoveFirst(lineage);
                            ret     = MutateOrCreate(newLeft, newDeep, RightDigit, lineage);
                        }
                        else
                        {
                            newDeep = DeepTree.RemoveAt(index - LeftDigit.Measure, lineage);
                            ret     = CreateCheckNull(lineage, LeftDigit, newDeep, RightDigit);
                        }
                        break;

                    case IN_START_OF_RIGHT:
                    case IN_MIDDLE_OF_RIGHT:
                        if (RightDigit.IsFragment)
                        {
                            var fixedTree = FixRightDigit(lineage);
                            ret = fixedTree.RemoveAt(index, lineage);
                        }
                        else
                        {
                            var newRight = RightDigit.Remove(index - LeftDigit.Measure - DeepTree.Measure, lineage);
                            ret = CreateCheckNull(lineage, LeftDigit, DeepTree, newRight);
                        }
                        break;

                    case IN_END:
                    case OUTSIDE:
                        throw ImplErrors.Arg_out_of_range("index", index);

                    default:
                        throw ImplErrors.Invalid_execution_path("Checked all possible index locations already.");
                    }
#if ASSERTS
                    ret.Measure.AssertEqual(newMeasure);
                    if (expectedAtIndex != null)
                    {
                        ret[index].Value.AssertEqual(expectedAtIndex.Value);
                    }
                    if (expectedBeforeIndex != null)
                    {
                        ret[index - 1].Value.AssertEqual(expectedBeforeIndex.Value);
                    }
#endif
                    return(ret);
                }