# HG changeset patch # User moel.mich # Date 1370711160 0 # Node ID 4b43228a989469b5c006b0e9d98b67105405dbbd # Parent 5be8f27732373b285e7a9452b6bb5f08e44f65df Some modifications to the OxyPlot library to back-port to .NET 2.0. Added the LINQBridge library for the LINQ based code in OxyPlot (the original .NET LINQ is not available in .NET 2.0). diff -r 5be8f2773237 -r 4b43228a9894 External/OxyPlot/OxyPlot.WindowsForms/HashSet.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/External/OxyPlot/OxyPlot.WindowsForms/HashSet.cs Sat Jun 08 17:06:00 2013 +0000 @@ -0,0 +1,27 @@ + +namespace OxyPlot.WindowsForms { + using System; + using System.Collections.Generic; + using System.Text; + + public class HashSet { + + private readonly Dictionary set = new Dictionary(); + + public bool Add(T value) { + if (set.ContainsKey(value)) + return true; + + set.Add(value, null); + return false; + } + + public bool Contains(T value) { + return set.ContainsKey(value); + } + + public void Clear() { + set.Clear(); + } + } +} diff -r 5be8f2773237 -r 4b43228a9894 External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj --- a/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Sat Jun 08 16:53:22 2013 +0000 +++ b/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Sat Jun 08 17:06:00 2013 +0000 @@ -9,39 +9,41 @@ Properties OxyPlot.WindowsForms OxyPlot.WindowsForms - v4.0 - Client + v2.0 + + 512 true full false - bin\Debug\NET40\ + Bin\Debug\ obj\Debug\NET40\ - DEBUG;TRACE + TRACE;DEBUG prompt 4 pdbonly true - ..\..\Output\NET40\ + Bin\Release\ obj\Release\NET40\ TRACE prompt 4 - ..\..\Output\NET40\OxyPlot.WindowsForms.XML + + true - OxyPlot.WindowsForms.snk + + - @@ -49,6 +51,7 @@ Properties\GlobalAssemblyInfo.cs + @@ -60,9 +63,6 @@ - - - {7a0b35c0-dd17-4964-8e9a-44d6cecdc692} OxyPlot diff -r 5be8f2773237 -r 4b43228a9894 External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk Binary file External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.snk has changed diff -r 5be8f2773237 -r 4b43228a9894 External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs --- a/External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs Sat Jun 08 16:53:22 2013 +0000 +++ b/External/OxyPlot/OxyPlot/Axes/DateTimeAxis.cs Sat Jun 08 17:06:00 2013 +0000 @@ -185,17 +185,6 @@ public DateTimeIntervalType MinorIntervalType { get; set; } /// - /// Gets or sets the time zone (used when formatting date/time values). - /// - /// - /// No date/time conversion will be performed if this property is null. - /// - /// - /// The time zone info. - /// - public TimeZoneInfo TimeZone { get; set; } - - /// /// Creates a data point. /// /// @@ -294,12 +283,6 @@ // convert the double value to a DateTime var time = ToDateTime(x); - // If a time zone is specified, convert the time - if (this.TimeZone != null) - { - time = TimeZoneInfo.ConvertTime(time, this.TimeZone); - } - string fmt = this.ActualStringFormat; if (fmt == null) { @@ -348,11 +331,6 @@ { var time = ToDateTime(x); - if (this.TimeZone != null) - { - time = TimeZoneInfo.ConvertTime(time, this.TimeZone); - } - return time; } diff -r 5be8f2773237 -r 4b43228a9894 External/OxyPlot/OxyPlot/LinqBridge.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/External/OxyPlot/OxyPlot/LinqBridge.cs Sat Jun 08 17:06:00 2013 +0000 @@ -0,0 +1,3115 @@ +#region License, Terms and Author(s) +// +// LINQBridge +// Copyright (c) 2007 Atif Aziz, Joseph Albahari. All rights reserved. +// +// Author(s): +// +// Atif Aziz, http://www.raboof.com +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the New BSD License, a copy of which should have +// been delivered along with this distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +#endregion + +#if LINQBRIDGE_LIB + +namespace System.Linq { + public partial class Enumerable { } + public partial interface IGrouping { } + public partial interface ILookup { } + public partial interface IOrderedEnumerable { } +} + +namespace System.Runtime.CompilerServices { + public partial class ExtensionAttribute { } +} + +#endif + +// $Id: Enumerable.cs c08984d432b1 2012/04/17 16:05:19 azizatif $ + +namespace System.Linq +{ + #region Imports + + using System; + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics; + using LinqBridge; + + #endregion + + /// + /// Provides a set of static (Shared in Visual Basic) methods for + /// querying objects that implement . + /// + + static partial class Enumerable + { + /// + /// Returns the input typed as . + /// + + public static IEnumerable AsEnumerable(this IEnumerable source) + { + return source; + } + + /// + /// Returns an empty that has the + /// specified type argument. + /// + + public static IEnumerable Empty() + { + return Sequence.Empty; + } + + /// + /// Converts the elements of an to the + /// specified type. + /// + + public static IEnumerable Cast( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return CastYield(source); + } + + private static IEnumerable CastYield( + IEnumerable source) + { + foreach (var item in source) + yield return (TResult) item; + } + + /// + /// Filters the elements of an based on a specified type. + /// + + public static IEnumerable OfType( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return OfTypeYield(source); + } + + private static IEnumerable OfTypeYield( + IEnumerable source) + { + foreach (var item in source) + if (item is TResult) + yield return (TResult) item; + } + + /// + /// Generates a sequence of integral numbers within a specified range. + /// + /// The value of the first integer in the sequence. + /// The number of sequential integers to generate. + + public static IEnumerable Range(int start, int count) + { + if (count < 0) + throw new ArgumentOutOfRangeException("count", count, null); + + var end = (long) start + count; + if (end - 1 >= int.MaxValue) + throw new ArgumentOutOfRangeException("count", count, null); + + return RangeYield(start, end); + } + + private static IEnumerable RangeYield(int start, long end) + { + for (var i = start; i < end; i++) + yield return i; + } + + /// + /// Generates a sequence that contains one repeated value. + /// + + public static IEnumerable Repeat(TResult element, int count) + { + if (count < 0) throw new ArgumentOutOfRangeException("count", count, null); + + return RepeatYield(element, count); + } + + private static IEnumerable RepeatYield(TResult element, int count) + { + for (var i = 0; i < count; i++) + yield return element; + } + + /// + /// Filters a sequence of values based on a predicate. + /// + + public static IEnumerable Where( + this IEnumerable source, + Func predicate) + { + if (predicate == null) throw new ArgumentNullException("predicate"); + + return source.Where((item, i) => predicate(item)); + } + + /// + /// Filters a sequence of values based on a predicate. + /// Each element's index is used in the logic of the predicate function. + /// + + public static IEnumerable Where( + this IEnumerable source, + Func predicate) + { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + + return WhereYield(source, predicate); + } + + private static IEnumerable WhereYield( + IEnumerable source, + Func predicate) + { + var i = 0; + foreach (var item in source) + if (predicate(item, i++)) + yield return item; + } + + /// + /// Projects each element of a sequence into a new form. + /// + + public static IEnumerable Select( + this IEnumerable source, + Func selector) + { + if (selector == null) throw new ArgumentNullException("selector"); + + return source.Select((item, i) => selector(item)); + } + + /// + /// Projects each element of a sequence into a new form by + /// incorporating the element's index. + /// + + public static IEnumerable Select( + this IEnumerable source, + Func selector) + { + if (source == null) throw new ArgumentNullException("source"); + if (selector == null) throw new ArgumentNullException("selector"); + + return SelectYield(source, selector); + } + + private static IEnumerable SelectYield( + IEnumerable source, + Func selector) + { + var i = 0; + foreach (var item in source) + yield return selector(item, i++); + } + + /// + /// Projects each element of a sequence to an + /// and flattens the resulting sequences into one sequence. + /// + + public static IEnumerable SelectMany( + this IEnumerable source, + Func> selector) + { + if (selector == null) throw new ArgumentNullException("selector"); + + return source.SelectMany((item, i) => selector(item)); + } + + /// + /// Projects each element of a sequence to an , + /// and flattens the resulting sequences into one sequence. The + /// index of each source element is used in the projected form of + /// that element. + /// + + public static IEnumerable SelectMany( + this IEnumerable source, + Func> selector) + { + if (selector == null) throw new ArgumentNullException("selector"); + + return source.SelectMany(selector, (item, subitem) => subitem); + } + + /// + /// Projects each element of a sequence to an , + /// flattens the resulting sequences into one sequence, and invokes + /// a result selector function on each element therein. + /// + + public static IEnumerable SelectMany( + this IEnumerable source, + Func> collectionSelector, + Func resultSelector) + { + if (collectionSelector == null) throw new ArgumentNullException("collectionSelector"); + + return source.SelectMany((item, i) => collectionSelector(item), resultSelector); + } + + /// + /// Projects each element of a sequence to an , + /// flattens the resulting sequences into one sequence, and invokes + /// a result selector function on each element therein. The index of + /// each source element is used in the intermediate projected form + /// of that element. + /// + + public static IEnumerable SelectMany( + this IEnumerable source, + Func> collectionSelector, + Func resultSelector) + { + if (source == null) throw new ArgumentNullException("source"); + if (collectionSelector == null) throw new ArgumentNullException("collectionSelector"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + return SelectManyYield(source, collectionSelector, resultSelector); + } + + private static IEnumerable SelectManyYield( + this IEnumerable source, + Func> collectionSelector, + Func resultSelector) + { + var i = 0; + foreach (var item in source) + foreach (var subitem in collectionSelector(item, i++)) + yield return resultSelector(item, subitem); + } + + /// + /// Returns elements from a sequence as long as a specified condition is true. + /// + + public static IEnumerable TakeWhile( + this IEnumerable source, + Func predicate) + { + if (predicate == null) throw new ArgumentNullException("predicate"); + + return source.TakeWhile((item, i) => predicate(item)); + } + + /// + /// Returns elements from a sequence as long as a specified condition is true. + /// The element's index is used in the logic of the predicate function. + /// + + public static IEnumerable TakeWhile( + this IEnumerable source, + Func predicate) + { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + + return TakeWhileYield(source, predicate); + } + + private static IEnumerable TakeWhileYield( + this IEnumerable source, + Func predicate) + { + var i = 0; + foreach (var item in source) + if (predicate(item, i++)) + yield return item; + else + break; + } + + /// + /// Returns a specified number of contiguous elements from the start + /// of a sequence. + /// + + public static IEnumerable Take( + this IEnumerable source, + int count) + { + return source.TakeWhile((item, i) => i < count); + } + + private static class Futures + { + public static readonly Func Default = () => default(T); + public static readonly Func Undefined = () => { throw new InvalidOperationException(); }; + } + + /// + /// Base implementation of First operator. + /// + + private static TSource FirstImpl( + this IEnumerable source, + Func empty) + { + if (source == null) throw new ArgumentNullException("source"); + Debug.Assert(empty != null); + + var list = source as IList; // optimized case for lists + if (list != null) + return list.Count > 0 ? list[0] : empty(); + + using (var e = source.GetEnumerator()) // fallback for enumeration + return e.MoveNext() ? e.Current : empty(); + } + + /// + /// Returns the first element of a sequence. + /// + + public static TSource First( + this IEnumerable source) + { + return source.FirstImpl(Futures.Undefined); + } + + /// + /// Returns the first element in a sequence that satisfies a specified condition. + /// + + public static TSource First( + this IEnumerable source, + Func predicate) + { + return First(source.Where(predicate)); + } + + /// + /// Returns the first element of a sequence, or a default value if + /// the sequence contains no elements. + /// + + public static TSource FirstOrDefault( + this IEnumerable source) + { + return source.FirstImpl(Futures.Default); + } + + /// + /// Returns the first element of the sequence that satisfies a + /// condition or a default value if no such element is found. + /// + + public static TSource FirstOrDefault( + this IEnumerable source, + Func predicate) + { + return FirstOrDefault(source.Where(predicate)); + } + + /// + /// Base implementation of Last operator. + /// + + private static TSource LastImpl( + this IEnumerable source, + Func empty) + { + if (source == null) throw new ArgumentNullException("source"); + + var list = source as IList; // optimized case for lists + if (list != null) + return list.Count > 0 ? list[list.Count - 1] : empty(); + + using (var e = source.GetEnumerator()) + { + if (!e.MoveNext()) + return empty(); + + var last = e.Current; + while (e.MoveNext()) + last = e.Current; + + return last; + } + } + + /// + /// Returns the last element of a sequence. + /// + public static TSource Last( + this IEnumerable source) + { + return source.LastImpl(Futures.Undefined); + } + + /// + /// Returns the last element of a sequence that satisfies a + /// specified condition. + /// + + public static TSource Last( + this IEnumerable source, + Func predicate) + { + return Last(source.Where(predicate)); + } + + /// + /// Returns the last element of a sequence, or a default value if + /// the sequence contains no elements. + /// + + public static TSource LastOrDefault( + this IEnumerable source) + { + return source.LastImpl(Futures.Default); + } + + /// + /// Returns the last element of a sequence that satisfies a + /// condition or a default value if no such element is found. + /// + + public static TSource LastOrDefault( + this IEnumerable source, + Func predicate) + { + return LastOrDefault(source.Where(predicate)); + } + + /// + /// Base implementation of Single operator. + /// + + private static TSource SingleImpl( + this IEnumerable source, + Func empty) + { + if (source == null) throw new ArgumentNullException("source"); + + using (var e = source.GetEnumerator()) + { + if (e.MoveNext()) + { + var single = e.Current; + if (!e.MoveNext()) + return single; + + throw new InvalidOperationException(); + } + + return empty(); + } + } + + /// + /// Returns the only element of a sequence, and throws an exception + /// if there is not exactly one element in the sequence. + /// + + public static TSource Single( + this IEnumerable source) + { + return source.SingleImpl(Futures.Undefined); + } + + /// + /// Returns the only element of a sequence that satisfies a + /// specified condition, and throws an exception if more than one + /// such element exists. + /// + + public static TSource Single( + this IEnumerable source, + Func predicate) + { + return Single(source.Where(predicate)); + } + + /// + /// Returns the only element of a sequence, or a default value if + /// the sequence is empty; this method throws an exception if there + /// is more than one element in the sequence. + /// + + public static TSource SingleOrDefault( + this IEnumerable source) + { + return source.SingleImpl(Futures.Default); + } + + /// + /// Returns the only element of a sequence that satisfies a + /// specified condition or a default value if no such element + /// exists; this method throws an exception if more than one element + /// satisfies the condition. + /// + + public static TSource SingleOrDefault( + this IEnumerable source, + Func predicate) + { + return SingleOrDefault(source.Where(predicate)); + } + + /// + /// Returns the element at a specified index in a sequence. + /// + + public static TSource ElementAt( + this IEnumerable source, + int index) + { + if (source == null) throw new ArgumentNullException("source"); + + if (index < 0) + throw new ArgumentOutOfRangeException("index", index, null); + + var list = source as IList; + if (list != null) + return list[index]; + + try + { + return source.SkipWhile((item, i) => i < index).First(); + } + catch (InvalidOperationException) // if thrown by First + { + throw new ArgumentOutOfRangeException("index", index, null); + } + } + + /// + /// Returns the element at a specified index in a sequence or a + /// default value if the index is out of range. + /// + + public static TSource ElementAtOrDefault( + this IEnumerable source, + int index) + { + if (source == null) throw new ArgumentNullException("source"); + + if (index < 0) + return default(TSource); + + var list = source as IList; + if (list != null) + return index < list.Count ? list[index] : default(TSource); + + return source.SkipWhile((item, i) => i < index).FirstOrDefault(); + } + + /// + /// Inverts the order of the elements in a sequence. + /// + + public static IEnumerable Reverse( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return ReverseYield(source); + } + + private static IEnumerable ReverseYield(IEnumerable source) + { + var stack = new Stack(); + foreach (var item in source) + stack.Push(item); + + foreach (var item in stack) + yield return item; + } + + /// + /// Bypasses elements in a sequence as long as a specified condition + /// is true and then returns the remaining elements. + /// + + public static IEnumerable SkipWhile( + this IEnumerable source, + Func predicate) + { + if (predicate == null) throw new ArgumentNullException("predicate"); + + return source.SkipWhile((item, i) => predicate(item)); + } + + /// + /// Bypasses elements in a sequence as long as a specified condition + /// is true and then returns the remaining elements. The element's + /// index is used in the logic of the predicate function. + /// + + public static IEnumerable SkipWhile( + this IEnumerable source, + Func predicate) + { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + + return SkipWhileYield(source, predicate); + } + + private static IEnumerable SkipWhileYield( + IEnumerable source, + Func predicate) + { + using (var e = source.GetEnumerator()) + { + for (var i = 0; ; i++) + { + if (!e.MoveNext()) + yield break; + + if (!predicate(e.Current, i)) + break; + } + + do { yield return e.Current; } while (e.MoveNext()); + } + } + + /// + /// Bypasses a specified number of elements in a sequence and then + /// returns the remaining elements. + /// + + public static IEnumerable Skip( + this IEnumerable source, + int count) + { + return source.SkipWhile((item, i) => i < count); + } + + /// + /// Returns the number of elements in a sequence. + /// + + public static int Count( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var collection = source as ICollection; + return collection != null + ? collection.Count + : source.Aggregate(0, (count, item) => checked(count + 1)); + } + + /// + /// Returns a number that represents how many elements in the + /// specified sequence satisfy a condition. + /// + + public static int Count( + this IEnumerable source, + Func predicate) + { + return Count(source.Where(predicate)); + } + + /// + /// Returns an that represents the total number + /// of elements in a sequence. + /// + + public static long LongCount( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + var array = source as Array; + return array != null + ? array.LongLength + : source.Aggregate(0L, (count, item) => count + 1); + } + + /// + /// Returns an that represents how many elements + /// in a sequence satisfy a condition. + /// + + public static long LongCount( + this IEnumerable source, + Func predicate) + { + return LongCount(source.Where(predicate)); + } + + /// + /// Concatenates two sequences. + /// + + public static IEnumerable Concat( + this IEnumerable first, + IEnumerable second) + { + if (first == null) throw new ArgumentNullException("first"); + if (second == null) throw new ArgumentNullException("second"); + + return ConcatYield(first, second); + } + + private static IEnumerable ConcatYield( + IEnumerable first, + IEnumerable second) + { + foreach (var item in first) + yield return item; + + foreach (var item in second) + yield return item; + } + + /// + /// Creates a from an . + /// + + public static List ToList( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return new List(source); + } + + /// + /// Creates an array from an . + /// + + public static TSource[] ToArray( + this IEnumerable source) + { + return source.ToList().ToArray(); + } + + /// + /// Returns distinct elements from a sequence by using the default + /// equality comparer to compare values. + /// + + public static IEnumerable Distinct( + this IEnumerable source) + { + return Distinct(source, /* comparer */ null); + } + + /// + /// Returns distinct elements from a sequence by using a specified + /// to compare values. + /// + + public static IEnumerable Distinct( + this IEnumerable source, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + + return DistinctYield(source, comparer); + } + + private static IEnumerable DistinctYield( + IEnumerable source, + IEqualityComparer comparer) + { + var set = new Dictionary(comparer); + var gotNull = false; + + foreach (var item in source) + { + if (item == null) + { + if (gotNull) + continue; + gotNull = true; + } + else + { + if (set.ContainsKey(item)) + continue; + set.Add(item, null); + } + + yield return item; + } + } + + /// + /// Creates a from an + /// according to a specified key + /// selector function. + /// + + public static ILookup ToLookup( + this IEnumerable source, + Func keySelector) + { + return ToLookup(source, keySelector, e => e, /* comparer */ null); + } + + /// + /// Creates a from an + /// according to a specified key + /// selector function and a key comparer. + /// + + public static ILookup ToLookup( + this IEnumerable source, + Func keySelector, + IEqualityComparer comparer) + { + return ToLookup(source, keySelector, e => e, comparer); + } + + /// + /// Creates a from an + /// according to specified key + /// and element selector functions. + /// + + public static ILookup ToLookup( + this IEnumerable source, + Func keySelector, + Func elementSelector) + { + return ToLookup(source, keySelector, elementSelector, /* comparer */ null); + } + + /// + /// Creates a from an + /// according to a specified key + /// selector function, a comparer and an element selector function. + /// + + public static ILookup ToLookup( + this IEnumerable source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (elementSelector == null) throw new ArgumentNullException("elementSelector"); + + var lookup = new Lookup(comparer); + + foreach (var item in source) + { + var key = keySelector(item); + + var grouping = (Grouping) lookup.Find(key); + if (grouping == null) + { + grouping = new Grouping(key); + lookup.Add(grouping); + } + + grouping.Add(elementSelector(item)); + } + + return lookup; + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function. + /// + + public static IEnumerable> GroupBy( + this IEnumerable source, + Func keySelector) + { + return GroupBy(source, keySelector, /* comparer */ null); + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function and compares the keys by using a specified + /// comparer. + /// + + public static IEnumerable> GroupBy( + this IEnumerable source, + Func keySelector, + IEqualityComparer comparer) + { + return GroupBy(source, keySelector, e => e, comparer); + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function and projects the elements for each group by + /// using a specified function. + /// + + public static IEnumerable> GroupBy( + this IEnumerable source, + Func keySelector, + Func elementSelector) + { + return GroupBy(source, keySelector, elementSelector, /* comparer */ null); + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function and creates a result value from each group and + /// its key. + /// + + public static IEnumerable> GroupBy( + this IEnumerable source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (elementSelector == null) throw new ArgumentNullException("elementSelector"); + + return ToLookup(source, keySelector, elementSelector, comparer); + } + + /// + /// Groups the elements of a sequence according to a key selector + /// function. The keys are compared by using a comparer and each + /// group's elements are projected by using a specified function. + /// + + public static IEnumerable GroupBy( + this IEnumerable source, + Func keySelector, + Func, TResult> resultSelector) + { + return GroupBy(source, keySelector, resultSelector, /* comparer */ null); + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function and creates a result value from each group and + /// its key. The elements of each group are projected by using a + /// specified function. + /// + + public static IEnumerable GroupBy( + this IEnumerable source, + Func keySelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g)); + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function and creates a result value from each group and + /// its key. The keys are compared by using a specified comparer. + /// + + public static IEnumerable GroupBy( + this IEnumerable source, + Func keySelector, + Func elementSelector, + Func, TResult> resultSelector) + { + return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null); + } + + /// + /// Groups the elements of a sequence according to a specified key + /// selector function and creates a result value from each group and + /// its key. Key values are compared by using a specified comparer, + /// and the elements of each group are projected by using a + /// specified function. + /// + + public static IEnumerable GroupBy( + this IEnumerable source, + Func keySelector, + Func elementSelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (elementSelector == null) throw new ArgumentNullException("elementSelector"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + return ToLookup(source, keySelector, elementSelector, comparer) + .Select(g => resultSelector(g.Key, g)); + } + + /// + /// Applies an accumulator function over a sequence. + /// + + public static TSource Aggregate( + this IEnumerable source, + Func func) + { + if (source == null) throw new ArgumentNullException("source"); + if (func == null) throw new ArgumentNullException("func"); + + using (var e = source.GetEnumerator()) + { + if (!e.MoveNext()) + throw new InvalidOperationException(); + + return e.Renumerable().Skip(1).Aggregate(e.Current, func); + } + } + + /// + /// Applies an accumulator function over a sequence. The specified + /// seed value is used as the initial accumulator value. + /// + + public static TAccumulate Aggregate( + this IEnumerable source, + TAccumulate seed, + Func func) + { + return Aggregate(source, seed, func, r => r); + } + + /// + /// Applies an accumulator function over a sequence. The specified + /// seed value is used as the initial accumulator value, and the + /// specified function is used to select the result value. + /// + + public static TResult Aggregate( + this IEnumerable source, + TAccumulate seed, + Func func, + Func resultSelector) + { + if (source == null) throw new ArgumentNullException("source"); + if (func == null) throw new ArgumentNullException("func"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + var result = seed; + + foreach (var item in source) + result = func(result, item); + + return resultSelector(result); + } + + /// + /// Produces the set union of two sequences by using the default + /// equality comparer. + /// + + public static IEnumerable Union( + this IEnumerable first, + IEnumerable second) + { + return Union(first, second, /* comparer */ null); + } + + /// + /// Produces the set union of two sequences by using a specified + /// . + /// + + public static IEnumerable Union( + this IEnumerable first, + IEnumerable second, + IEqualityComparer comparer) + { + return first.Concat(second).Distinct(comparer); + } + + /// + /// Returns the elements of the specified sequence or the type + /// parameter's default value in a singleton collection if the + /// sequence is empty. + /// + + public static IEnumerable DefaultIfEmpty( + this IEnumerable source) + { + return source.DefaultIfEmpty(default(TSource)); + } + + /// + /// Returns the elements of the specified sequence or the specified + /// value in a singleton collection if the sequence is empty. + /// + + public static IEnumerable DefaultIfEmpty( + this IEnumerable source, + TSource defaultValue) + { + if (source == null) throw new ArgumentNullException("source"); + + return DefaultIfEmptyYield(source, defaultValue); + } + + private static IEnumerable DefaultIfEmptyYield( + IEnumerable source, + TSource defaultValue) + { + using (var e = source.GetEnumerator()) + { + if (!e.MoveNext()) + yield return defaultValue; + else + do { yield return e.Current; } while (e.MoveNext()); + } + } + + /// + /// Determines whether all elements of a sequence satisfy a condition. + /// + + public static bool All( + this IEnumerable source, + Func predicate) + { + if (source == null) throw new ArgumentNullException("source"); + if (predicate == null) throw new ArgumentNullException("predicate"); + + foreach (var item in source) + if (!predicate(item)) + return false; + + return true; + } + + /// + /// Determines whether a sequence contains any elements. + /// + + public static bool Any( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + using (var e = source.GetEnumerator()) + return e.MoveNext(); + } + + /// + /// Determines whether any element of a sequence satisfies a + /// condition. + /// + + public static bool Any( + this IEnumerable source, + Func predicate) + { + return source.Where(predicate).Any(); + } + + /// + /// Determines whether a sequence contains a specified element by + /// using the default equality comparer. + /// + + public static bool Contains( + this IEnumerable source, + TSource value) + { + return source.Contains(value, /* comparer */ null); + } + + /// + /// Determines whether a sequence contains a specified element by + /// using a specified . + /// + + public static bool Contains( + this IEnumerable source, + TSource value, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + + if (comparer == null) + { + var collection = source as ICollection; + if (collection != null) + return collection.Contains(value); + } + + comparer = comparer ?? EqualityComparer.Default; + return source.Any(item => comparer.Equals(item, value)); + } + + /// + /// Determines whether two sequences are equal by comparing the + /// elements by using the default equality comparer for their type. + /// + + public static bool SequenceEqual( + this IEnumerable first, + IEnumerable second) + { + return first.SequenceEqual(second, /* comparer */ null); + } + + /// + /// Determines whether two sequences are equal by comparing their + /// elements by using a specified . + /// + + public static bool SequenceEqual( + this IEnumerable first, + IEnumerable second, + IEqualityComparer comparer) + { + if (first == null) throw new ArgumentNullException("frist"); + if (second == null) throw new ArgumentNullException("second"); + + comparer = comparer ?? EqualityComparer.Default; + + using (IEnumerator lhs = first.GetEnumerator(), + rhs = second.GetEnumerator()) + { + do + { + if (!lhs.MoveNext()) + return !rhs.MoveNext(); + + if (!rhs.MoveNext()) + return false; + } + while (comparer.Equals(lhs.Current, rhs.Current)); + } + + return false; + } + + /// + /// Base implementation for Min/Max operator. + /// + + private static TSource MinMaxImpl( + this IEnumerable source, + Func lesser) + { + if (source == null) throw new ArgumentNullException("source"); + Debug.Assert(lesser != null); + + if (typeof(TSource).IsClass) // ReSharper disable CompareNonConstrainedGenericWithNull + source = source.Where(e => e != null).DefaultIfEmpty(); // ReSharper restore CompareNonConstrainedGenericWithNull + + return source.Aggregate((a, item) => lesser(a, item) ? a : item); + } + + /// + /// Base implementation for Min/Max operator for nullable types. + /// + + private static TSource? MinMaxImpl( + this IEnumerable source, + TSource? seed, Func lesser) where TSource : struct + { + if (source == null) throw new ArgumentNullException("source"); + Debug.Assert(lesser != null); + + return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item); + // == MinMaxImpl(Repeat(null, 1).Concat(source), lesser); + } + + /// + /// Returns the minimum value in a generic sequence. + /// + + public static TSource Min( + this IEnumerable source) + { + var comparer = Comparer.Default; + return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0); + } + + /// + /// Invokes a transform function on each element of a generic + /// sequence and returns the minimum resulting value. + /// + + public static TResult Min( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Min(); + } + + /// + /// Returns the maximum value in a generic sequence. + /// + + public static TSource Max( + this IEnumerable source) + { + var comparer = Comparer.Default; + return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0); + } + + /// + /// Invokes a transform function on each element of a generic + /// sequence and returns the maximum resulting value. + /// + + public static TResult Max( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Max(); + } + + /// + /// Makes an enumerator seen as enumerable once more. + /// + /// + /// The supplied enumerator must have been started. The first element + /// returned is the element the enumerator was on when passed in. + /// DO NOT use this method if the caller must be a generator. It is + /// mostly safe among aggregate operations. + /// + + private static IEnumerable Renumerable(this IEnumerator e) + { + Debug.Assert(e != null); + + do { yield return e.Current; } while (e.MoveNext()); + } + + /// + /// Sorts the elements of a sequence in ascending order according to a key. + /// + + public static IOrderedEnumerable OrderBy( + this IEnumerable source, + Func keySelector) + { + return source.OrderBy(keySelector, /* comparer */ null); + } + + /// + /// Sorts the elements of a sequence in ascending order by using a + /// specified comparer. + /// + + public static IOrderedEnumerable OrderBy( + this IEnumerable source, + Func keySelector, + IComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + + return new OrderedEnumerable(source, keySelector, comparer, /* descending */ false); + } + + /// + /// Sorts the elements of a sequence in descending order according to a key. + /// + + public static IOrderedEnumerable OrderByDescending( + this IEnumerable source, + Func keySelector) + { + return source.OrderByDescending(keySelector, /* comparer */ null); + } + + /// + /// Sorts the elements of a sequence in descending order by using a + /// specified comparer. + /// + + public static IOrderedEnumerable OrderByDescending( + this IEnumerable source, + Func keySelector, + IComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (source == null) throw new ArgumentNullException("keySelector"); + + return new OrderedEnumerable(source, keySelector, comparer, /* descending */ true); + } + + /// + /// Performs a subsequent ordering of the elements in a sequence in + /// ascending order according to a key. + /// + + public static IOrderedEnumerable ThenBy( + this IOrderedEnumerable source, + Func keySelector) + { + return source.ThenBy(keySelector, /* comparer */ null); + } + + /// + /// Performs a subsequent ordering of the elements in a sequence in + /// ascending order by using a specified comparer. + /// + + public static IOrderedEnumerable ThenBy( + this IOrderedEnumerable source, + Func keySelector, + IComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + + return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false); + } + + /// + /// Performs a subsequent ordering of the elements in a sequence in + /// descending order, according to a key. + /// + + public static IOrderedEnumerable ThenByDescending( + this IOrderedEnumerable source, + Func keySelector) + { + return source.ThenByDescending(keySelector, /* comparer */ null); + } + + /// + /// Performs a subsequent ordering of the elements in a sequence in + /// descending order by using a specified comparer. + /// + + public static IOrderedEnumerable ThenByDescending( + this IOrderedEnumerable source, + Func keySelector, + IComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + + return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true); + } + + /// + /// Base implementation for Intersect and Except operators. + /// + + private static IEnumerable IntersectExceptImpl( + this IEnumerable first, + IEnumerable second, + IEqualityComparer comparer, + bool flag) + { + if (first == null) throw new ArgumentNullException("first"); + if (second == null) throw new ArgumentNullException("second"); + + var keys = new List>(); + var flags = new Dictionary, bool>(new KeyComparer(comparer)); + + foreach (var item in from item in first + select new Key(item) into item + where !flags.ContainsKey(item) + select item) + { + flags.Add(item, !flag); + keys.Add(item); + } + + foreach (var item in from item in second + select new Key(item) into item + where flags.ContainsKey(item) + select item) + { + flags[item] = flag; + } + + // + // As per docs, "the marked elements are yielded in the order in + // which they were collected. + // + + return from item in keys where flags[item] select item.Value; + } + + /// + /// Produces the set intersection of two sequences by using the + /// default equality comparer to compare values. + /// + + public static IEnumerable Intersect( + this IEnumerable first, + IEnumerable second) + { + return first.Intersect(second, /* comparer */ null); + } + + /// + /// Produces the set intersection of two sequences by using the + /// specified to compare values. + /// + + public static IEnumerable Intersect( + this IEnumerable first, + IEnumerable second, + IEqualityComparer comparer) + { + return IntersectExceptImpl(first, second, comparer, /* flag */ true); + } + + /// + /// Produces the set difference of two sequences by using the + /// default equality comparer to compare values. + /// + + public static IEnumerable Except( + this IEnumerable first, + IEnumerable second) + { + return first.Except(second, /* comparer */ null); + } + + /// + /// Produces the set difference of two sequences by using the + /// specified to compare values. + /// + + public static IEnumerable Except( + this IEnumerable first, + IEnumerable second, + IEqualityComparer comparer) + { + return IntersectExceptImpl(first, second, comparer, /* flag */ false); + } + + /// + /// Creates a from an + /// according to a specified key + /// selector function. + /// + + public static Dictionary ToDictionary( + this IEnumerable source, + Func keySelector) + { + return source.ToDictionary(keySelector, /* comparer */ null); + } + + /// + /// Creates a from an + /// according to a specified key + /// selector function and key comparer. + /// + + public static Dictionary ToDictionary( + this IEnumerable source, + Func keySelector, + IEqualityComparer comparer) + { + return source.ToDictionary(keySelector, e => e, comparer); + } + + /// + /// Creates a from an + /// according to specified key + /// selector and element selector functions. + /// + + public static Dictionary ToDictionary( + this IEnumerable source, + Func keySelector, + Func elementSelector) + { + return source.ToDictionary(keySelector, elementSelector, /* comparer */ null); + } + + /// + /// Creates a from an + /// according to a specified key + /// selector function, a comparer, and an element selector function. + /// + + public static Dictionary ToDictionary( + this IEnumerable source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + if (elementSelector == null) throw new ArgumentNullException("elementSelector"); + + var dict = new Dictionary(comparer); + + foreach (var item in source) + { + // + // ToDictionary is meant to throw ArgumentNullException if + // keySelector produces a key that is null and + // Argument exception if keySelector produces duplicate keys + // for two elements. Incidentally, the doucmentation for + // IDictionary.Add says that the Add method + // throws the same exceptions under the same circumstances + // so we don't need to do any additional checking or work + // here and let the Add implementation do all the heavy + // lifting. + // + + dict.Add(keySelector(item), elementSelector(item)); + } + + return dict; + } + + /// + /// Correlates the elements of two sequences based on matching keys. + /// The default equality comparer is used to compare keys. + /// + + public static IEnumerable Join( + this IEnumerable outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector) + { + return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null); + } + + /// + /// Correlates the elements of two sequences based on matching keys. + /// The default equality comparer is used to compare keys. A + /// specified is used to compare keys. + /// + + public static IEnumerable Join( + this IEnumerable outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector, + IEqualityComparer comparer) + { + if (outer == null) throw new ArgumentNullException("outer"); + if (inner == null) throw new ArgumentNullException("inner"); + if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector"); + if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + var lookup = inner.ToLookup(innerKeySelector, comparer); + + return + from o in outer + from i in lookup[outerKeySelector(o)] + select resultSelector(o, i); + } + + /// + /// Correlates the elements of two sequences based on equality of + /// keys and groups the results. The default equality comparer is + /// used to compare keys. + /// + + public static IEnumerable GroupJoin( + this IEnumerable outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func, TResult> resultSelector) + { + return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null); + } + + /// + /// Correlates the elements of two sequences based on equality of + /// keys and groups the results. The default equality comparer is + /// used to compare keys. A specified + /// is used to compare keys. + /// + + public static IEnumerable GroupJoin( + this IEnumerable outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + if (outer == null) throw new ArgumentNullException("outer"); + if (inner == null) throw new ArgumentNullException("inner"); + if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector"); + if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector"); + if (resultSelector == null) throw new ArgumentNullException("resultSelector"); + + var lookup = inner.ToLookup(innerKeySelector, comparer); + return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)])); + } + + private static class Sequence + { + public static readonly IEnumerable Empty = new T[0]; + } + + private sealed class Grouping : List, IGrouping + { + internal Grouping(K key) + { + Key = key; + } + + public K Key { get; private set; } + } + } +} + +// $Id: Enumerable.g.tt 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace System.Linq +{ + #region Imports + + using System; + using System.Collections.Generic; + + #endregion + + // This partial implementation was template-generated: + // Mon, 16 Apr 2012 20:05:53 GMT + + partial class Enumerable + { + /// + /// Computes the sum of a sequence of nullable values. + /// + + public static int Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + int sum = 0; + foreach (var num in source) + sum = checked(sum + num); + + return sum; + } + + /// + /// Computes the sum of a sequence of nullable + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static int Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of nullable values. + /// + + public static double Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + long sum = 0; + long count = 0; + + foreach (var num in source) + checked + { + sum += (int) num; + count++; + } + + if (count == 0) + throw new InvalidOperationException(); + + return (double) sum / count; + } + + /// + /// Computes the average of a sequence of nullable values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static double Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + + /// + /// Computes the sum of a sequence of values. + /// + + public static int? Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + int sum = 0; + foreach (var num in source) + sum = checked(sum + (num ?? 0)); + + return sum; + } + + /// + /// Computes the sum of a sequence of + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static int? Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of values. + /// + + public static double? Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + long sum = 0; + long count = 0; + + foreach (var num in source.Where(n => n != null)) + checked + { + sum += (int) num; + count++; + } + + if (count == 0) + return null; + + return (double?) sum / count; + } + + /// + /// Computes the average of a sequence of values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static double? Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + /// + /// Returns the minimum value in a sequence of nullable + /// values. + /// + + public static int? Min( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the minimum nullable value. + /// + + public static int? Min( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Min(); + } + + /// + /// Returns the maximum value in a sequence of nullable + /// values. + /// + + public static int? Max( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), + null, (max, x) => x == null || (max != null && x.Value < max.Value)); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the maximum nullable value. + /// + + public static int? Max( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Max(); + } + + /// + /// Computes the sum of a sequence of nullable values. + /// + + public static long Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + long sum = 0; + foreach (var num in source) + sum = checked(sum + num); + + return sum; + } + + /// + /// Computes the sum of a sequence of nullable + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static long Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of nullable values. + /// + + public static double Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + long sum = 0; + long count = 0; + + foreach (var num in source) + checked + { + sum += (long) num; + count++; + } + + if (count == 0) + throw new InvalidOperationException(); + + return (double) sum / count; + } + + /// + /// Computes the average of a sequence of nullable values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static double Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + + /// + /// Computes the sum of a sequence of values. + /// + + public static long? Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + long sum = 0; + foreach (var num in source) + sum = checked(sum + (num ?? 0)); + + return sum; + } + + /// + /// Computes the sum of a sequence of + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static long? Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of values. + /// + + public static double? Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + long sum = 0; + long count = 0; + + foreach (var num in source.Where(n => n != null)) + checked + { + sum += (long) num; + count++; + } + + if (count == 0) + return null; + + return (double?) sum / count; + } + + /// + /// Computes the average of a sequence of values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static double? Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + /// + /// Returns the minimum value in a sequence of nullable + /// values. + /// + + public static long? Min( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the minimum nullable value. + /// + + public static long? Min( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Min(); + } + + /// + /// Returns the maximum value in a sequence of nullable + /// values. + /// + + public static long? Max( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), + null, (max, x) => x == null || (max != null && x.Value < max.Value)); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the maximum nullable value. + /// + + public static long? Max( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Max(); + } + + /// + /// Computes the sum of a sequence of nullable values. + /// + + public static float Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + float sum = 0; + foreach (var num in source) + sum = checked(sum + num); + + return sum; + } + + /// + /// Computes the sum of a sequence of nullable + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static float Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of nullable values. + /// + + public static float Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + float sum = 0; + long count = 0; + + foreach (var num in source) + checked + { + sum += (float) num; + count++; + } + + if (count == 0) + throw new InvalidOperationException(); + + return (float) sum / count; + } + + /// + /// Computes the average of a sequence of nullable values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static float Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + + /// + /// Computes the sum of a sequence of values. + /// + + public static float? Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + float sum = 0; + foreach (var num in source) + sum = checked(sum + (num ?? 0)); + + return sum; + } + + /// + /// Computes the sum of a sequence of + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static float? Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of values. + /// + + public static float? Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + float sum = 0; + long count = 0; + + foreach (var num in source.Where(n => n != null)) + checked + { + sum += (float) num; + count++; + } + + if (count == 0) + return null; + + return (float?) sum / count; + } + + /// + /// Computes the average of a sequence of values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static float? Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + /// + /// Returns the minimum value in a sequence of nullable + /// values. + /// + + public static float? Min( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the minimum nullable value. + /// + + public static float? Min( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Min(); + } + + /// + /// Returns the maximum value in a sequence of nullable + /// values. + /// + + public static float? Max( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), + null, (max, x) => x == null || (max != null && x.Value < max.Value)); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the maximum nullable value. + /// + + public static float? Max( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Max(); + } + + /// + /// Computes the sum of a sequence of nullable values. + /// + + public static double Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + double sum = 0; + foreach (var num in source) + sum = checked(sum + num); + + return sum; + } + + /// + /// Computes the sum of a sequence of nullable + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static double Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of nullable values. + /// + + public static double Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + double sum = 0; + long count = 0; + + foreach (var num in source) + checked + { + sum += (double) num; + count++; + } + + if (count == 0) + throw new InvalidOperationException(); + + return (double) sum / count; + } + + /// + /// Computes the average of a sequence of nullable values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static double Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + + /// + /// Computes the sum of a sequence of values. + /// + + public static double? Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + double sum = 0; + foreach (var num in source) + sum = checked(sum + (num ?? 0)); + + return sum; + } + + /// + /// Computes the sum of a sequence of + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static double? Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of values. + /// + + public static double? Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + double sum = 0; + long count = 0; + + foreach (var num in source.Where(n => n != null)) + checked + { + sum += (double) num; + count++; + } + + if (count == 0) + return null; + + return (double?) sum / count; + } + + /// + /// Computes the average of a sequence of values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static double? Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + /// + /// Returns the minimum value in a sequence of nullable + /// values. + /// + + public static double? Min( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the minimum nullable value. + /// + + public static double? Min( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Min(); + } + + /// + /// Returns the maximum value in a sequence of nullable + /// values. + /// + + public static double? Max( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), + null, (max, x) => x == null || (max != null && x.Value < max.Value)); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the maximum nullable value. + /// + + public static double? Max( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Max(); + } + + /// + /// Computes the sum of a sequence of nullable values. + /// + + public static decimal Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + decimal sum = 0; + foreach (var num in source) + sum = checked(sum + num); + + return sum; + } + + /// + /// Computes the sum of a sequence of nullable + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static decimal Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of nullable values. + /// + + public static decimal Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + decimal sum = 0; + long count = 0; + + foreach (var num in source) + checked + { + sum += (decimal) num; + count++; + } + + if (count == 0) + throw new InvalidOperationException(); + + return (decimal) sum / count; + } + + /// + /// Computes the average of a sequence of nullable values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static decimal Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + + /// + /// Computes the sum of a sequence of values. + /// + + public static decimal? Sum( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + decimal sum = 0; + foreach (var num in source) + sum = checked(sum + (num ?? 0)); + + return sum; + } + + /// + /// Computes the sum of a sequence of + /// values that are obtained by invoking a transform function on + /// each element of the input sequence. + /// + + public static decimal? Sum( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Sum(); + } + + /// + /// Computes the average of a sequence of values. + /// + + public static decimal? Average( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + decimal sum = 0; + long count = 0; + + foreach (var num in source.Where(n => n != null)) + checked + { + sum += (decimal) num; + count++; + } + + if (count == 0) + return null; + + return (decimal?) sum / count; + } + + /// + /// Computes the average of a sequence of values + /// that are obtained by invoking a transform function on each + /// element of the input sequence. + /// + + public static decimal? Average( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Average(); + } + + /// + /// Returns the minimum value in a sequence of nullable + /// values. + /// + + public static decimal? Min( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the minimum nullable value. + /// + + public static decimal? Min( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Min(); + } + + /// + /// Returns the maximum value in a sequence of nullable + /// values. + /// + + public static decimal? Max( + this IEnumerable source) + { + if (source == null) throw new ArgumentNullException("source"); + + return MinMaxImpl(source.Where(x => x != null), + null, (max, x) => x == null || (max != null && x.Value < max.Value)); + } + + /// + /// Invokes a transform function on each element of a sequence and + /// returns the maximum nullable value. + /// + + public static decimal? Max( + this IEnumerable source, + Func selector) + { + return source.Select(selector).Max(); + } + } +} + +// $Id: ExtensionAttribute.cs 898b3d493ed6 2012/04/17 20:09:57 azizatif $ + +namespace System.Runtime.CompilerServices +{ + /// + /// This attribute allows us to define extension methods without + /// requiring .NET Framework 3.5. For more information, see the section, + /// Extension Methods in .NET Framework 2.0 Apps, + /// of Basic Instincts: Extension Methods + /// column in MSDN Magazine, + /// issue Nov 2007. + /// + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] + sealed partial class ExtensionAttribute : Attribute { } +} + +// $Id: Func.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace System +{ +#if LINQBRIDGE_LIB + public delegate TResult Func(); + public delegate TResult Func(T a); + public delegate TResult Func(T1 arg1, T2 arg2); + public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3); + public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4); +#else + delegate TResult Func(); + delegate TResult Func(T a); + delegate TResult Func(T1 arg1, T2 arg2); + delegate TResult Func(T1 arg1, T2 arg2, T3 arg3); + delegate TResult Func(T1 arg1, T2 arg2, T3 arg3, T4 arg4); +#endif +} + +// $Id: IGrouping.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace System.Linq +{ + #region Imports + + using System.Collections.Generic; + + #endregion + + /// + /// Represents a collection of objects that have a common key. + /// + + partial interface IGrouping : IEnumerable + { + /// + /// Gets the key of the . + /// + + TKey Key { get; } + } +} + +// $Id: ILookup.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace System.Linq +{ + using System.Collections.Generic; + + /// + /// Defines an indexer, size property, and Boolean search method for + /// data structures that map keys to + /// sequences of values. + /// + + partial interface ILookup : IEnumerable> + { + bool Contains(TKey key); + int Count { get; } + IEnumerable this[TKey key] { get; } + } +} + +// $Id: Internal.cs 1567e00f1a20 2012/04/17 16:09:51 azizatif $ + +namespace LinqBridge +{ + #region Imports + + using System; + using System.Collections.Generic; + + #endregion + + /// + /// This type is not intended to be used directly from user code. + /// It may be removed or changed in a future version without notice. + /// + + sealed class DelegatingComparer : IComparer + { + private readonly Func _comparer; + + public DelegatingComparer(Func comparer) + { + if (comparer == null) throw new ArgumentNullException("comparer"); + _comparer = comparer; + } + + public int Compare(T x, T y) { return _comparer(x, y); } + } + + /// + /// This type is not intended to be used directly from user code. + /// It may be removed or changed in a future version without notice. + /// + + struct Key + { + public Key(T value) : this() { Value = value; } + public T Value { get; private set; } + } + + /// + /// This type is not intended to be used directly from user code. + /// It may be removed or changed in a future version without notice. + /// + + sealed class KeyComparer : IEqualityComparer> + { + private readonly IEqualityComparer _innerComparer; + + public KeyComparer(IEqualityComparer innerComparer) + { + _innerComparer = innerComparer ?? EqualityComparer.Default; + } + + public bool Equals(Key x, Key y) + { + return _innerComparer.Equals(x.Value, y.Value); + } + + public int GetHashCode(Key obj) + { + return obj.Value == null ? 0 : _innerComparer.GetHashCode(obj.Value); + } + } +} + +// $Id: IOrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace System.Linq +{ + using System.Collections.Generic; + + /// + /// Represents a sorted sequence. + /// + + partial interface IOrderedEnumerable : IEnumerable + { + /// + /// Performs a subsequent ordering on the elements of an + /// according to a key. + /// + + IOrderedEnumerable CreateOrderedEnumerable( + Func keySelector, IComparer comparer, bool descending); + } +} + +// $Id: Lookup.cs c08984d432b1 2012/04/17 16:05:19 azizatif $ + +namespace System.Linq +{ + #region Imports + + using System; + using System.Collections; + using System.Collections.Generic; + using IEnumerable=System.Collections.IEnumerable; + using LinqBridge; + + #endregion + + /// + /// Represents a collection of keys each mapped to one or more values. + /// + + internal sealed class Lookup : ILookup + { + private readonly Dictionary, IGrouping> _map; + private readonly List> _orderedKeys; // remember order of insertion + + internal Lookup(IEqualityComparer comparer) + { + _map = new Dictionary, IGrouping>(new KeyComparer(comparer)); + _orderedKeys = new List>(); + } + + internal void Add(IGrouping item) + { + var key = new Key(item.Key); + _map.Add(key, item); + _orderedKeys.Add(key); + } + + internal IEnumerable Find(TKey key) + { + IGrouping grouping; + return _map.TryGetValue(new Key(key), out grouping) ? grouping : null; + } + + /// + /// Gets the number of key/value collection pairs in the . + /// + + public int Count + { + get { return _map.Count; } + } + + /// + /// Gets the collection of values indexed by the specified key. + /// + + public IEnumerable this[TKey key] + { + get + { + IGrouping result; + return _map.TryGetValue(new Key(key), out result) ? result : Enumerable.Empty(); + } + } + + /// + /// Determines whether a specified key is in the . + /// + + public bool Contains(TKey key) + { + return _map.ContainsKey(new Key(key)); + } + + /// + /// Applies a transform function to each key and its associated + /// values and returns the results. + /// + + public IEnumerable ApplyResultSelector( + Func, TResult> resultSelector) + { + if (resultSelector == null) + throw new ArgumentNullException("resultSelector"); + + foreach (var pair in _map) + yield return resultSelector(pair.Key.Value, pair.Value); + } + + /// + /// Returns a generic enumerator that iterates through the . + /// + + public IEnumerator> GetEnumerator() + { + foreach (var key in _orderedKeys) + yield return _map[key]; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} + +// $Id: OrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace LinqBridge +{ + #region Imports + + using System; + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics; + using System.Linq; + + #endregion + + internal sealed class OrderedEnumerable : IOrderedEnumerable + { + private readonly IEnumerable _source; + private readonly Func, IComparer> _comparerComposer; + + public OrderedEnumerable(IEnumerable source, + Func keySelector, IComparer comparer, bool descending) : + this(source, (_, next) => next, keySelector, comparer, descending) {} + + private OrderedEnumerable(IEnumerable source, + Func, IComparer> parent, + Func keySelector, IComparer comparer, bool descending) + { + if (source == null) throw new ArgumentNullException("source"); + if (keySelector == null) throw new ArgumentNullException("keySelector"); + Debug.Assert(parent != null); + + _source = source; + + comparer = comparer ?? Comparer.Default; + var direction = descending ? -1 : 1; + + _comparerComposer = (items, next) => + { + Debug.Assert(items != null); + Debug.Assert(next != null); + + var keys = new K[items.Length]; + for (var i = 0; i < items.Length; i++) + keys[i] = keySelector(items[i]); + + return parent(items, new DelegatingComparer((i, j) => + { + var result = direction * comparer.Compare(keys[i], keys[j]); + return result != 0 ? result : next.Compare(i, j); + })); + }; + } + + public IOrderedEnumerable CreateOrderedEnumerable( + Func keySelector, IComparer comparer, bool descending) + { + return new OrderedEnumerable(_source, _comparerComposer, keySelector, comparer, descending); + } + + public IEnumerator GetEnumerator() + { + // + // Sort using Array.Sort but docs say that it performs an + // unstable sort. LINQ, on the other hand, says OrderBy performs + // a stable sort. Use the item position then as a tie + // breaker when all keys compare equal, thus making the sort + // stable. + // + + var items = _source.ToArray(); + var positionComparer = new DelegatingComparer((i, j) => i.CompareTo(j)); + var comparer = _comparerComposer(items, positionComparer); + var keys = new int[items.Length]; + for (var i = 0; i < keys.Length; i++) + keys[i] = i; + Array.Sort(keys, items, comparer); + return ((IEnumerable) items).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} + +// $Id: Action.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $ + +namespace System +{ +#if LINQBRIDGE_LIB + public delegate void Action(); + public delegate void Action(T1 arg1, T2 arg2); + public delegate void Action(T1 arg1, T2 arg2, T3 arg3); + public delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4); +#else + delegate void Action(); + delegate void Action(T1 arg1, T2 arg2); + delegate void Action(T1 arg1, T2 arg2, T3 arg3); + delegate void Action(T1 arg1, T2 arg2, T3 arg3, T4 arg4); +#endif +} + diff -r 5be8f2773237 -r 4b43228a9894 External/OxyPlot/OxyPlot/OxyPlot.csproj --- a/External/OxyPlot/OxyPlot/OxyPlot.csproj Sat Jun 08 16:53:22 2013 +0000 +++ b/External/OxyPlot/OxyPlot/OxyPlot.csproj Sat Jun 08 17:06:00 2013 +0000 @@ -9,41 +9,39 @@ Properties OxyPlot OxyPlot - v4.0 + v2.0 512 - Client + + true full false - bin\Debug\ - DEBUG;TRACE + Bin\Debug\ + TRACE;DEBUG;LINQBRIDGE_LIB prompt 4 pdbonly true - ..\..\Output\NET40x\ - TRACE + Bin\Release\ + TRACE;LINQBRIDGE_LIB prompt 4 - ..\..\Output\NET40x\OxyPlot.XML + + true - OxyPlot.snk + + - - - - - @@ -95,6 +93,7 @@ + @@ -224,7 +223,6 @@ -