/// <summary> /// Step through a Range of objects that are not Numeric or String. /// </summary> private static object StepObject(EachStorage /*!*/ storage, BlockParam /*!*/ block, Range /*!*/ self, object begin, object end, int step) { Assert.NotNull(storage, block, self); CheckStep(storage, step); CheckBegin(storage, self.Begin); object item = begin, result; int comp; var succSite = storage.SuccSite; while ((comp = Protocols.Compare(storage, item, end)) < 0) { if (block.Yield(item, out result)) { return(result); } for (int i = 0; i < step; ++i) { item = succSite.Target(succSite, item); } } if (comp == 0 && !self.ExcludeEnd) { if (block.Yield(item, out result)) { return(result); } } return(self); }
/// <summary> /// Step through a Range of objects that are not Numeric or String. /// </summary> private static IEnumerable <object> EachStepObject(EachStorage /*!*/ storage, Range /*!*/ self, int step) { Assert.NotNull(storage, self); CheckStep(storage, step); int comp; object begin = self.Begin; CheckBegin(storage, begin); object end = self.End; object item = begin; var succSite = storage.SuccSite; while ((comp = Protocols.Compare(storage, item, end)) < 0) { yield return(item); for (int i = 0; i < step; ++i) { item = succSite.Target(succSite, item); } } if (comp == 0 && !self.ExcludeEnd) { yield return(item); } }
public static IEnumerable <object> EachInRange(EachStorage /*!*/ storage, Range /*!*/ self, object step) { if (self.Begin is int && self.End is int) { // self.begin is Fixnum; directly call item = item + 1 instead of succ return(EachStepFixnum(self, ConvertStepToInt(storage, step))); } else if (self.Begin is MutableString) { // self.begin is String; use item.succ and item <=> self.end but make sure you check the length of the strings #if SILVERLIGHT return(EachStepString(storage, self, ConvertStepToInt(storage, step)).Cast <object>()); #else return(CollectionUtils.ToCovariant <MutableString, object>(EachStepString(storage, self, ConvertStepToInt(storage, step)))); #endif } else if (storage.Context.IsInstanceOf(self.Begin, storage.Context.GetClass(typeof(Numeric)))) { // self.begin is Numeric; invoke item = item + 1 instead of succ and invoke < or <= for compare return(EachStepNumeric(storage, self, step)); } else { // self.begin is not Numeric or String; just invoke item.succ and item <=> self.end return(EachStepObject(storage, self, ConvertStepToInt(storage, step))); } }
/// <summary> /// Check that the object responds to "succ". /// </summary> private static void CheckBegin(EachStorage /*!*/ storage, object begin) { if (!Protocols.RespondTo(storage.RespondToSite, storage.Context, begin, "succ")) { throw RubyExceptions.CreateTypeError("can't iterate from {0}", storage.Context.GetClassDisplayName(begin)); } }
public static object GetMinimum(EachStorage /*!*/ comparisonStorage, Range /*!*/ self) { if (IsBeginGreatherThanEnd(comparisonStorage, self)) { return(null); } return(self.Begin); }
private static int ConvertStepToInt(EachStorage storage, object step) { if (step is int) { return((int)step); } var site = storage.FixnumCastSite; return(site.Target(site, step)); }
public static object GetMaximum(EachStorage /*!*/ comparisonStorage, Range /*!*/ self) { if (IsBeginGreatherThanEnd(comparisonStorage, self)) { return(null); } if (!self.ExcludeEnd) { return(self.End); } return(EachInRange(comparisonStorage, self, 1).Last()); }
public static object Each(EachStorage /*!*/ storage, [NotNull] BlockParam /*!*/ block, Range /*!*/ self) { if (self.Begin is int && self.End is int) { return(StepFixnum(block, self, (int)self.Begin, (int)self.End, 1)); } else if (self.Begin is MutableString) { return(StepString(storage, block, self, (MutableString)self.Begin, (MutableString)self.End, 1)); } else { return(StepObject(storage, block, self, self.Begin, self.End, 1)); } }
/// <summary> /// Check that the object, when converted to an integer, is not less than or equal to zero. /// </summary> private static void CheckStep(EachStorage /*!*/ storage, object step) { var equals = storage.EqualsSite; if (Protocols.IsTrue(equals.Target(equals, step, 0))) { throw RubyExceptions.CreateArgumentError("step can't be 0"); } var lessThan = storage.LessThanSite; if (RubyOps.IsTrue(lessThan.Target(lessThan, step, 0))) { throw RubyExceptions.CreateArgumentError("step can't be negative"); } }
public static object Each(EachStorage /*!*/ storage, [NotNull] BlockParam /*!*/ block, Range /*!*/ self) { Assert.NotNull(block); CheckBegin(storage, self.Begin); var each = EachInRange(storage, self, 1); foreach (var item in each) { object result; if (block.Yield(item, 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 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); }
public static object GetMinimumBy(EachStorage /*!*/ comparisonStorage, BlockParam /*!*/ block, Range /*!*/ self) { if (IsBeginGreatherThanEnd(comparisonStorage, self)) { return(null); } var each = EachInRange(comparisonStorage, self, 1); return(each.Aggregate((x, y) => { object blockResult; if (block.Yield(y, x, out blockResult)) { return blockResult; } int r = Protocols.ConvertCompareResult(comparisonStorage, blockResult); return r < 0 ? y : x; })); }
public static object Step(EachStorage /*!*/ storage, [NotNull] BlockParam /*!*/ block, Range /*!*/ self, [Optional] object step) { if (step == Missing.Value) { step = ClrInteger.One; } Assert.NotNull(block); var each = EachInRange(storage, self, step); foreach (var item in each) { object result; if (block.Yield(item, out result)) { return(result); } } return(self); }
/// <summary> /// Step through a Range of Numerics. /// </summary> private static IEnumerable <object> EachStepNumeric(EachStorage /*!*/ storage, Range /*!*/ self, object step) { Assert.NotNull(storage, self); CheckStep(storage, step); object item = self.Begin; object end = self.End; int comp; while ((comp = Protocols.Compare(storage, item, end)) < 0) { yield return(item); var add = storage.AddSite; item = add.Target(add, item, step); } if (comp == 0 && !self.ExcludeEnd) { yield return(item); } }
public static object GetMinimumBy(EachStorage/*!*/ comparisonStorage, BlockParam/*!*/ block, Range/*!*/ self) { if (IsBeginGreatherThanEnd(comparisonStorage, self)) { return null; } var each = EachInRange(comparisonStorage, self, 1); return each.Aggregate((x, y) => { object blockResult; if (block.Yield(y, x, out blockResult)) { return blockResult; } int r = Protocols.ConvertCompareResult(comparisonStorage, blockResult); return r < 0 ? y : x; }); }
public static object GetMinimum(EachStorage/*!*/ comparisonStorage, Range/*!*/ self) { if (IsBeginGreatherThanEnd(comparisonStorage, self)) { return null; } return self.Begin; }
public static object GetMaximum(EachStorage/*!*/ comparisonStorage, Range/*!*/ self) { if (IsBeginGreatherThanEnd(comparisonStorage, self)) { return null; } if (!self.ExcludeEnd) { return self.End; } return EachInRange(comparisonStorage, self, 1).Last(); }
/// <summary> /// Step through a Range of objects that are not Numeric or String. /// </summary> private static IEnumerable<object> EachStepObject(EachStorage/*!*/ storage, Range/*!*/ self, int step) { Assert.NotNull(storage, self); CheckStep(storage, step); int comp; object begin = self.Begin; CheckBegin(storage, begin); object end = self.End; object item = begin; var succSite = storage.SuccSite; while ((comp = Protocols.Compare(storage, item, end)) < 0) { yield return item; for (int i = 0; i < step; ++i) { item = succSite.Target(succSite, item); } } if (comp == 0 && !self.ExcludeEnd) { yield return item; } }
/// <summary> /// Step through a Range of Numerics. /// </summary> private static IEnumerable<object> EachStepNumeric(EachStorage/*!*/ storage, Range/*!*/ self, object step) { Assert.NotNull(storage, self); CheckStep(storage, step); object item = self.Begin; object end = self.End; int comp; while ((comp = Protocols.Compare(storage, item, end)) < 0) { yield return item; var add = storage.AddSite; item = add.Target(add, item, step); } if (comp == 0 && !self.ExcludeEnd) { yield return item; } }
/// <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; var succSite = storage.SuccSite; 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; }
private static int ConvertStepToInt(EachStorage storage, object step) { if (step is int) { return (int)step; } var site = storage.FixnumCastSite; return site.Target(site, step); }
public static IEnumerable<object> EachInRange(EachStorage/*!*/ storage, Range/*!*/ self, object step) { if (self.Begin is int && self.End is int) { // self.begin is Fixnum; directly call item = item + 1 instead of succ return EachStepFixnum(self, ConvertStepToInt(storage, step)); } else if (self.Begin is MutableString) { // self.begin is String; use item.succ and item <=> self.end but make sure you check the length of the strings #if SILVERLIGHT return EachStepString(storage, self, ConvertStepToInt(storage, step)).Cast<object>(); #else return EachStepString(storage, self, ConvertStepToInt(storage, step)); #endif } else if (storage.Context.IsInstanceOf(self.Begin, storage.Context.GetClass(typeof(Numeric)))) { // self.begin is Numeric; invoke item = item + 1 instead of succ and invoke < or <= for compare return EachStepNumeric(storage, self, step); } else { // self.begin is not Numeric or String; just invoke item.succ and item <=> self.end return EachStepObject(storage, self, ConvertStepToInt(storage, step)); } }
public static Enumerator /*!*/ GetStepEnumerator(EachStorage /*!*/ storage, Range /*!*/ self, [Optional] object step) { return(new Enumerator((_, block) => Step(storage, block, self, step))); }
/// <summary> /// Check that the object, when converted to an integer, is not less than or equal to zero. /// </summary> private static void CheckStep(EachStorage/*!*/ storage, object step) { var equals = storage.EqualsSite; if (Protocols.IsTrue(equals.Target(equals, step, 0))) { throw RubyExceptions.CreateArgumentError("step can't be 0"); } var lessThan = storage.LessThanSite; if (RubyOps.IsTrue(lessThan.Target(lessThan, step, 0))) { throw RubyExceptions.CreateArgumentError("step can't be negative"); } }
public static Enumerator/*!*/ GetEachEnumerator(EachStorage/*!*/ storage, Range/*!*/ self) { return new Enumerator((_, block) => Each(storage, block, self)); }
public static Enumerator/*!*/ GetStepEnumerator(EachStorage/*!*/ storage, Range/*!*/ self, [Optional]object step) { return new Enumerator((_, block) => Step(storage, block, self, step)); }
public static object Each(EachStorage/*!*/ storage, [NotNull]BlockParam/*!*/ block, Range/*!*/ self) { if (self.Begin is int && self.End is int) { return StepFixnum(block, self, (int)self.Begin, (int)self.End, 1); } else if (self.Begin is MutableString) { return StepString(storage, block, self, (MutableString)self.Begin, (MutableString)self.End, 1); } else { return StepObject(storage, block, self, self.Begin, self.End, 1); } }
public static object Step(EachStorage/*!*/ storage, [NotNull]BlockParam/*!*/ block, Range/*!*/ self, [Optional]object step) { if (step == Missing.Value) { step = ClrInteger.One; } Assert.NotNull(block); var each = EachInRange(storage, self, step); foreach (var item in each) { object result; if (block.Yield(item, out result)) { return result; } } return self; }
/// <summary> /// Step through a Range of objects that are not Numeric or String. /// </summary> private static object StepObject(EachStorage/*!*/ storage, BlockParam/*!*/ block, Range/*!*/ self, object begin, object end, int step) { Assert.NotNull(storage, block, self); CheckStep(storage, step); CheckBegin(storage, self.Begin); object item = begin, result; int comp; var succSite = storage.SuccSite; while ((comp = Protocols.Compare(storage, item, end)) < 0) { if (block.Yield(item, out result)) { return result; } for (int i = 0; i < step; ++i) { item = succSite.Target(succSite, item); } } if (comp == 0 && !self.ExcludeEnd) { if (block.Yield(item, out result)) { return result; } } return self; }
public static Enumerator /*!*/ GetEachEnumerator(EachStorage /*!*/ storage, Range /*!*/ self) { return(new Enumerator((_, block) => Each(storage, block, self))); }
/// <summary> /// Check that the object responds to "succ". /// </summary> private static void CheckBegin(EachStorage/*!*/ storage, object begin) { if (!Protocols.RespondTo(storage.RespondToSite, storage.Context, begin, "succ")) { throw RubyExceptions.CreateTypeError("can't iterate from {0}", storage.Context.GetClassDisplayName(begin)); } }
public static object Each(EachStorage/*!*/ storage, [NotNull]BlockParam/*!*/ block, Range/*!*/ self) { Assert.NotNull(block); CheckBegin(storage, self.Begin); var each = EachInRange(storage, self, 1); foreach (var item in each) { object result; if (block.Yield(item, out result)) { return result; } } return self; }