// Copyright Matthew King 2012-2013.
// Distributed under the Boost Software License, Version 1.0.
// (See http://www.boost.org/LICENSE_1_0.txt)
using System.Collections.Generic;
///
/// Provides functionality assist with the generation of hash codes.
///
internal sealed class HashCodeBuilder
{
///
/// Multiplier for the argument hashes.
///
private readonly int multiplier;
///
/// Current hash value.
///
private int hashCode;
///
/// Initializes a new instance of the HashCodeBuilder class.
///
/// Initial value for the hash.
/// Multiplier for the argument hashes.
private HashCodeBuilder(int seed, int multiplier)
{
this.multiplier = multiplier;
this.hashCode = seed;
}
///
/// Includes the specified value in the hash code.
///
/// Type of the value to include in the hash code.
/// Value to include in the hash code.
/// This HashCodeBuilder instance.
public HashCodeBuilder AddValue(T value)
{
return this.AddValue(value, null);
}
///
/// Includes the specified value in the hash code.
///
/// Type of the value to include in the hash code.
/// Value to include in the hash code.
/// IEqualityComparer<T> to calculate the hash code.
/// This HashCodeBuilder instance.
public HashCodeBuilder AddValue(T value, IEqualityComparer comparer)
{
if (comparer == null)
{
comparer = EqualityComparer.Default;
}
unchecked
{
int hc = value != null ? comparer.GetHashCode(value) : 0;
this.hashCode = (this.hashCode * this.multiplier) + hc;
}
return this;
}
///
/// Includes the specified values in the hash code.
///
/// Type of the values to include in the hash code.
///
/// An enumerator that iterates through the sequence of values to include in the hash code.
///
/// This HashCodeBuilder instance.
public HashCodeBuilder AddValues(IEnumerable values)
{
return this.AddValues(values, null);
}
///
/// Includes the specified values in the hash code.
///
/// Type of the values to include in the hash code.
///
/// An enumerator that iterates through the sequence of values to include in the hash code.
///
///
/// IEqualityComparer<T> to calculate the hash code.
///
/// This HashCodeBuilder instance.
public HashCodeBuilder AddValues(IEnumerable values, IEqualityComparer comparer)
{
if (comparer == null)
{
comparer = EqualityComparer.Default;
}
if (values != null)
{
foreach (T value in values)
{
unchecked
{
int hc = value != null ? value.GetHashCode() : 0;
this.hashCode = (this.hashCode * this.multiplier) + hc;
}
}
}
return this;
}
///
/// Returns the current hash code of this HashCodeBuilder instance.
///
/// The current hash code.
public int ToHashCode()
{
return this.hashCode;
}
///
/// Implicit conversion from HashCodeBuilder to int.
///
/// The HashCodeBuilder instance to convert.
/// The current hash code of the HashCodeBuilder instance.
public static implicit operator int(HashCodeBuilder builder)
{
return builder.ToHashCode();
}
///
/// Creates a new HashCodeBuilder instance.
///
/// A new HashCodeBuilder instance.
public static HashCodeBuilder Create()
{
return new HashCodeBuilder(17, 29);
}
}