//******************************
// Written by Peter Golde
// Copyright (c) 2004-2005, Wintellect
//
// Use and restribution of this code is subject to the license agreement
// contained in the file "License.txt" accompanying this file.
//******************************
using System;
using System.Collections.Generic;
namespace Wintellect.PowerCollections
{
///
/// A collection of methods to create IComparer and IEqualityComparer instances in various ways.
///
internal static class Comparers
{
///
/// Class to change an IEqualityComparer<TKey> to an IEqualityComparer<KeyValuePair<TKey, TValue>>
/// Only the keys are compared.
///
[Serializable]
class KeyValueEqualityComparer : IEqualityComparer>
{
private IEqualityComparer keyEqualityComparer;
public KeyValueEqualityComparer(IEqualityComparer keyEqualityComparer)
{ this.keyEqualityComparer = keyEqualityComparer; }
public bool Equals(KeyValuePair x, KeyValuePair y)
{ return keyEqualityComparer.Equals(x.Key, y.Key); }
public int GetHashCode(KeyValuePair obj)
{
return Util.GetHashCode(obj.Key, keyEqualityComparer);
}
public override bool Equals(object obj)
{
if (obj is KeyValueEqualityComparer)
return object.Equals(keyEqualityComparer, ((KeyValueEqualityComparer)obj).keyEqualityComparer);
else
return false;
}
public override int GetHashCode()
{
return keyEqualityComparer.GetHashCode();
}
}
///
/// Class to change an IComparer<TKey> to an IComparer<KeyValuePair<TKey, TValue>>
/// Only the keys are compared.
///
[Serializable]
class KeyValueComparer : IComparer>
{
private IComparer keyComparer;
public KeyValueComparer(IComparer keyComparer)
{ this.keyComparer = keyComparer; }
public int Compare(KeyValuePair x, KeyValuePair y)
{ return keyComparer.Compare(x.Key, y.Key); }
public override bool Equals(object obj)
{
if (obj is KeyValueComparer)
return object.Equals(keyComparer, ((KeyValueComparer)obj).keyComparer);
else
return false;
}
public override int GetHashCode()
{
return keyComparer.GetHashCode();
}
}
///
/// Class to change an IComparer<TKey> and IComparer<TValue> to an IComparer<KeyValuePair<TKey, TValue>>
/// Keys are compared, followed by values.
///
[Serializable]
class PairComparer : IComparer>
{
private IComparer keyComparer;
private IComparer valueComparer;
public PairComparer(IComparer keyComparer, IComparer valueComparer)
{
this.keyComparer = keyComparer;
this.valueComparer = valueComparer;
}
public int Compare(KeyValuePair x, KeyValuePair y)
{
int keyCompare = keyComparer.Compare(x.Key, y.Key);
if (keyCompare == 0)
return valueComparer.Compare(x.Value, y.Value);
else
return keyCompare;
}
public override bool Equals(object obj)
{
if (obj is PairComparer)
return object.Equals(keyComparer, ((PairComparer)obj).keyComparer) &&
object.Equals(valueComparer, ((PairComparer)obj).valueComparer);
else
return false;
}
public override int GetHashCode()
{
return keyComparer.GetHashCode() ^ valueComparer.GetHashCode();
}
}
///
/// Class to change an Comparison<T> to an IComparer<T>.
///
[Serializable]
class ComparisonComparer : IComparer
{
private Comparison comparison;
public ComparisonComparer(Comparison comparison)
{ this.comparison = comparison; }
public int Compare(T x, T y)
{ return comparison(x, y); }
public override bool Equals(object obj)
{
if (obj is ComparisonComparer)
return comparison.Equals(((ComparisonComparer)obj).comparison);
else
return false;
}
public override int GetHashCode()
{
return comparison.GetHashCode();
}
}
///
/// Class to change an Comparison<TKey> to an IComparer<KeyValuePair<TKey, TValue>>.
/// GetHashCode cannot be used on this class.
///
[Serializable]
class ComparisonKeyValueComparer : IComparer>
{
private Comparison comparison;
public ComparisonKeyValueComparer(Comparison comparison)
{ this.comparison = comparison; }
public int Compare(KeyValuePair x, KeyValuePair y)
{ return comparison(x.Key, y.Key); }
public override bool Equals(object obj)
{
if (obj is ComparisonKeyValueComparer)
return comparison.Equals(((ComparisonKeyValueComparer)obj).comparison);
else
return false;
}
public override int GetHashCode()
{
return comparison.GetHashCode();
}
}
///
/// Given an Comparison on a type, returns an IComparer on that type.
///
/// T to compare.
/// Comparison delegate on T
/// IComparer that uses the comparison.
public static IComparer ComparerFromComparison(Comparison comparison)
{
if (comparison == null)
throw new ArgumentNullException("comparison");
return new ComparisonComparer(comparison);
}
///
/// Given an IComparer on TKey, returns an IComparer on
/// key-value Pairs.
///
/// TKey of the pairs
/// TValue of the apris
/// IComparer on TKey
/// IComparer for comparing key-value pairs.
public static IComparer> ComparerKeyValueFromComparerKey(IComparer keyComparer)
{
if (keyComparer == null)
throw new ArgumentNullException("keyComparer");
return new KeyValueComparer(keyComparer);
}
///
/// Given an IEqualityComparer on TKey, returns an IEqualityComparer on
/// key-value Pairs.
///
/// TKey of the pairs
/// TValue of the apris
/// IComparer on TKey
/// IEqualityComparer for comparing key-value pairs.
public static IEqualityComparer> EqualityComparerKeyValueFromComparerKey(IEqualityComparer keyEqualityComparer)
{
if (keyEqualityComparer == null)
throw new ArgumentNullException("keyEqualityComparer");
return new KeyValueEqualityComparer(keyEqualityComparer);
}
///
/// Given an IComparer on TKey and TValue, returns an IComparer on
/// key-value Pairs of TKey and TValue, comparing first keys, then values.
///
/// TKey of the pairs
/// TValue of the apris
/// IComparer on TKey
/// IComparer on TValue
/// IComparer for comparing key-value pairs.
public static IComparer> ComparerPairFromKeyValueComparers(IComparer keyComparer, IComparer valueComparer)
{
if (keyComparer == null)
throw new ArgumentNullException("keyComparer");
if (valueComparer == null)
throw new ArgumentNullException("valueComparer");
return new PairComparer(keyComparer, valueComparer);
}
///
/// Given an Comparison on TKey, returns an IComparer on
/// key-value Pairs.
///
/// TKey of the pairs
/// TValue of the apris
/// Comparison delegate on TKey
/// IComparer for comparing key-value pairs.
public static IComparer> ComparerKeyValueFromComparisonKey(Comparison keyComparison)
{
if (keyComparison == null)
throw new ArgumentNullException("keyComparison");
return new ComparisonKeyValueComparer(keyComparison);
}
///
/// Given an element type, check that it implements IComparable<T> or IComparable, then returns
/// a IComparer that can be used to compare elements of that type.
///
/// The IComparer<T> instance.
/// T does not implement IComparable<T>.
public static IComparer DefaultComparer()
{
if (typeof(IComparable).IsAssignableFrom(typeof(T)) ||
typeof(System.IComparable).IsAssignableFrom(typeof(T)))
{
return Comparer.Default;
}
else {
throw new InvalidOperationException(string.Format(Strings.UncomparableType, typeof(T).FullName));
}
}
///
/// Given an key and value type, check that TKey implements IComparable<T> or IComparable, then returns
/// a IComparer that can be used to compare KeyValuePairs of those types.
///
/// The IComparer<KeyValuePair<TKey, TValue>> instance.
/// TKey does not implement IComparable<T>.
public static IComparer> DefaultKeyValueComparer()
{
IComparer keyComparer = DefaultComparer();
return ComparerKeyValueFromComparerKey(keyComparer);
}
}
}