예제 #1
0
                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.");
                    }
                }
예제 #2
0
                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);
                }
예제 #3
0
                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("");
                    }
                }
예제 #4
0
 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));
 }
예제 #5
0
 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));
 }
예제 #6
0
 private Digit MutateOrCreate(TChild a, Lineage lineage)
 {
     return(Lineage.AllowMutation(lineage) ? _mutate(a.Measure, 1, a) : new Digit(a, lineage));
 }
예제 #7
0
                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.
                }
예제 #8
0
                //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);
                }