/// <summary> /// Creates a rope from the specified input. /// This operation runs in O(N). /// </summary> /// <exception cref="ArgumentNullException">input is null.</exception> public Rope(IEnumerable <T> input) { if (input == null) { throw new ArgumentNullException("input"); } var inputRope = input as Rope <T>; if (inputRope != null) { // clone ropes instead of copying them inputRope.root.Publish(); root = inputRope.root; } else { var text = input as string; if (text != null) { // if a string is IEnumerable<T>, then T must be char ((Rope <char>)(object) this).root = CharRope.InitFromString(text); } else { var arr = ToArray(input); root = RopeNode <T> .CreateFromArray(arr, 0, arr.Length); } } root.CheckInvariants(); }
/// <summary> /// Creates a rope from a part of the array. /// This operation runs in O(N). /// </summary> /// <exception cref="ArgumentNullException">input is null.</exception> public Rope(T[] array, int arrayIndex, int count) { VerifyArrayWithRange(array, arrayIndex, count); root = RopeNode <T> .CreateFromArray(array, arrayIndex, count); root.CheckInvariants(); }
internal void CheckInvariants() { if (height == 0) { Debug.Assert(left == null && right == null); if (contents == null) { Debug.Assert(this is FunctionNode <T>); Debug.Assert(length > 0); Debug.Assert(isShared); } else { Debug.Assert(contents != null && contents.Length == NodeSize); Debug.Assert(length >= 0 && length <= NodeSize); } } else { Debug.Assert(left != null && right != null); Debug.Assert(contents == null); Debug.Assert(length == left.length + right.length); Debug.Assert(height == 1 + Math.Max(left.height, right.height)); Debug.Assert(Math.Abs(Balance) <= 1); // this is an additional invariant that forces the tree to combine small leafs to prevent excessive memory usage: Debug.Assert(length > NodeSize); // note that this invariant ensures that all nodes except for the empty rope's single node have at least length 1 if (isShared) { Debug.Assert(left.isShared && right.isShared); } left.CheckInvariants(); right.CheckInvariants(); } }
/// <summary> /// Creates a new rope representing the empty string. /// </summary> public Rope() { // we'll construct the empty rope as a clone of an imaginary static empty rope root = RopeNode <T> .emptyRopeNode; root.CheckInvariants(); }
internal Rope(RopeNode <T> root) { this.root = root; root.CheckInvariants(); }