/// <summary> /// Step through a Range of Strings. /// </summary> /// <remarks> /// This method requires step to be a Fixnum. /// It uses a hybrid string comparison to prevent infinite loops and calls String#succ to get each item in the range. /// </remarks> private static object StepString(EachStorage /*!*/ storage, BlockParam /*!*/ block, Range /*!*/ self, MutableString begin, MutableString end, int step) { Assert.NotNull(storage, block, self); CheckStep(step); object result; MutableString item = begin; int comp; while ((comp = Protocols.Compare(storage, item, end)) < 0) { if (block.Yield(item.Clone(), out result)) { return(result); } if (ReferenceEquals(item, begin)) { item = item.Clone(); } // TODO: this can be optimized for (int i = 0; i < step; i++) { MutableStringOps.SuccInPlace(item); } if (item.Length > end.Length) { return(self); } } if (comp == 0 && !self.ExcludeEnd) { if (block.Yield(item.Clone(), out result)) { return(result); } } return(self); }
/// <summary> /// Step through a Range of Strings. /// </summary> /// <remarks> /// This method requires step to be a Fixnum. /// It uses a hybrid string comparison to prevent infinite loops and calls String#succ to get each item in the range. /// </remarks> private static IEnumerable <MutableString> EachStepString(ComparisonStorage /*!*/ storage, Range /*!*/ self, int step) { Assert.NotNull(storage, self); CheckStep(step); var begin = (MutableString)self.Begin; var end = (MutableString)self.End; MutableString item = begin; int comp; while ((comp = Protocols.Compare(storage, item, end)) < 0) { yield return(item.Clone()); if (ReferenceEquals(item, begin)) { item = item.Clone(); } // TODO: this can be optimized for (int i = 0; i < step; i++) { MutableStringOps.SuccInPlace(item); } if (item.Length > end.Length) { yield break; } } if (comp == 0 && !self.ExcludeEnd) { yield return(item.Clone()); } }