// 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); } }