public static Expression ForEach(ParameterExpression item, Expression source, Expression body) { if (!typeof(IEnumerable).IsAssignableFrom(source.Type)) { throw new InvalidOperationException($"{source.Type} does not implement IEnumerable and cannot be iterated using foreach"); } ParameterExpression enumerator = Expression.Parameter(typeof(IEnumerator), "enumerator"); LabelTarget forEachEnd = Expression.Label(); return(Expression.Block( new[] { item, enumerator }, Expression.Assign( enumerator, Expression.Call(source, EnumerableMembers.GetEnumerator()) ), Expression.Loop( Expression.IfThenElse( Expression.Call(enumerator, EnumerableMembers.MoveNext()), Expression.Block( Expression.Assign(item, Expression.Convert(Expression.Property(enumerator, EnumerableMembers.Current()), item.Type)), body ), Expression.Break(forEachEnd) ), forEachEnd ) )); }
public static bool IsWhiteSpace(string a) { return(ToOption(a) .Map(EnumerableMembers.Cast <char>) .Map(EnumerableMembers.All <char>(char.IsWhiteSpace)) .GetOrElse(false)); }
private Expression MoveEnumerator(ParameterExpression enumerator, ParameterExpression someLeft) { return(Expression.Assign( someLeft, Expression.Call( enumerator, EnumerableMembers.MoveNext(typeof(IDiffItem)) ) )); }
private Expression <Func <IDiff <TType>, IDiff <TType>, IConflictContainer, List <IDiffItem> > > Compile() { ParameterExpression left = Expression.Parameter(typeof(IDiff <TType>), "left"); ParameterExpression right = Expression.Parameter(typeof(IDiff <TType>), "right"); ParameterExpression conflicts = Expression.Parameter(typeof(IConflictContainer), "ret"); ParameterExpression ret = Expression.Parameter(typeof(List <IDiffItem>), "ret"); ParameterExpression leftEnumerator = Expression.Parameter(typeof(IEnumerator <IDiffItem>), "leftEnumerator"); ParameterExpression leftSomeLeft = Expression.Parameter(typeof(bool), "leftSomeLeft"); ParameterExpression rightEnumerator = Expression.Parameter(typeof(IEnumerator <IDiffItem>), "rightEnumerator"); ParameterExpression rightSomeLeft = Expression.Parameter(typeof(bool), "rightSomeLeft"); return(Expression.Lambda <Func <IDiff <TType>, IDiff <TType>, IConflictContainer, List <IDiffItem> > >( Expression.Block( new[] { ret, leftEnumerator, leftSomeLeft, rightEnumerator, rightSomeLeft }, Expression.Assign( ret, Expression.New( ListMembers.NewWithCount(typeof(IDiffItem)), Expression.Add( Expression.Property(left, DiffMembers.Count()), Expression.Property(right, DiffMembers.Count()) ) ) ), Expression.Assign( leftEnumerator, Expression.Call(left, EnumerableMembers.GetEnumerator(typeof(IDiffItem))) ), Expression.Assign( rightEnumerator, Expression.Call(right, EnumerableMembers.GetEnumerator(typeof(IDiffItem))) ), this.MoveEnumerator(leftEnumerator, leftSomeLeft), this.MoveEnumerator(rightEnumerator, rightSomeLeft), Expression.Block(Class <TType> .Properties.Select(x => this.EvaluateProperty(leftEnumerator, leftSomeLeft, rightEnumerator, rightSomeLeft, conflicts, ret, x))), ret ), left, right, conflicts )); }
private Expression EvaluateProperty(ParameterExpression leftEnumerator, ParameterExpression leftSomeLeft, ParameterExpression rightEnumerator, ParameterExpression rightSomeLeft, Expression conflicts, Expression ret, Property property) { Expression leftCurrent = Expression.Property(leftEnumerator, EnumerableMembers.Current(typeof(IDiffItem))); Expression rightCurrent = Expression.Property(rightEnumerator, EnumerableMembers.Current(typeof(IDiffItem))); /* PSEUDO CODE FOR THIS: * if (leftSomeLeft && leftCurrent.UniqueID == ID) * { * if (rightSomeLeft && rightCurrent.UniqueID == ID) * { * CheckConflicts(leftCurrent, rightCurrent) * rightSomeLeft = next(rightCurrent) * } * else * add(leftCurrent) * leftSomeLeft = next(leftCurrent) * } * else if (rightSomeLeft && rightCurrent.UniqueID == ID) * { * add(rightCurrent) * rightSomeLeft = next(rightCurrent) * } */ Expression leftShouldBeProcessed = Expression.AndAlso( leftSomeLeft, Expression.Equal( Expression.Property( Expression.Property( Expression.Convert( leftCurrent, typeof(IDiffClassItem) ), DiffItemsMembers.ClassProperty() ), FastPropertyMembers.UniqueID() ), Expression.Constant(property.UniqueID) ) ); Expression rightShouldBeProcessed = Expression.AndAlso( rightSomeLeft, Expression.Equal( Expression.Property( Expression.Property( Expression.Convert( rightCurrent, typeof(IDiffClassItem) ), DiffItemsMembers.ClassProperty() ), FastPropertyMembers.UniqueID() ), Expression.Constant(property.UniqueID) ) ); return(Expression.IfThenElse( leftShouldBeProcessed, Expression.Block( Expression.IfThenElse( rightShouldBeProcessed, Expression.Block( this.CompileCheckConflicts(property, leftCurrent, rightCurrent, conflicts, ret), this.MoveEnumerator(rightEnumerator, rightSomeLeft) ), Expression.Call( ret, ListMembers.Add(typeof(IDiffItem)), leftCurrent ) ), this.MoveEnumerator(leftEnumerator, leftSomeLeft) ), Expression.IfThen( rightShouldBeProcessed, Expression.Block( Expression.Call( ret, ListMembers.Add(typeof(IDiffItem)), rightCurrent ), this.MoveEnumerator(rightEnumerator, rightSomeLeft) ) ) )); }
public static IEnumerable <TA> Flatten <TA>(this IEnumerable <Option <TA> > @as) { return(EnumerableMembers.Flatten(@as)); }
public static IEnumerable <TA> PrependRange <TA>(this IEnumerable <TA> @as, IEnumerable <TA> range) { return(EnumerableMembers.PrependRange(range)(@as)); }
public static IEnumerable <TA> Prepend <TA>(this IEnumerable <TA> @as, Option <TA> a) { return(EnumerableMembers.Prepend(a)(@as)); }
public static IEnumerable <TB> FlatMap <TA, TB>(this IEnumerable <TA> @as, Func <TA, IEnumerable <TB> > f) { return(EnumerableMembers.FlatMap(f)(@as)); }
public static Func <TValue, IEnumerable <KeyValuePair <TKey, TValue> > > Append <TKey, TValue>(this IEnumerable <KeyValuePair <TKey, TValue> > kvps, TKey key) { return(Functions.RotateRight2(EnumerableMembers.Append <TKey, TValue>(key))(kvps)); }
public static IEnumerable <KeyValuePair <TKey, TValue> > Prepend <TKey, TValue>(this IEnumerable <KeyValuePair <TKey, TValue> > kvps, TKey key, TValue value) { return(EnumerableMembers.Prepend(key, value)(kvps)); }