<commit_before>﻿namespace TomsToolbox.Essentials
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    /// <inheritdoc />
    /// <summary>
    /// <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> implementation using a delegate function to compare the values.
    /// </summary>
    /// <typeparam name="T">The type of objects to compare.</typeparam>
    public class DelegateEqualityComparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T?, T?, bool> _comparer;
        private readonly Func<T?, int> _hashCodeGenerator;

        /// <inheritdoc />
        /// <summary>
        /// Initializes a new instance of the <see cref="T:TomsToolbox.Essentials.DelegateEqualityComparer`1" /> class,
        /// using <see cref="M:System.Object.Equals(System.Object,System.Object)" /> and <see cref="M:System.Object.GetHashCode" />
        /// </summary>
        public DelegateEqualityComparer()
            : this((a, b) => object.Equals(a, b), x => ReferenceEquals(x, null) ? 0 : x.GetHashCode())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateEqualityComparer{T}"/> class.
        /// </summary>
        /// <param name="selector">The selector that selects the object to compare, if e.g. two objects can be compared by a single property.</param>
        public DelegateEqualityComparer(Func<T?, object> selector)
        {
            _comparer = (a, b) => Equals(selector(a), selector(b));
            _hashCodeGenerator = obj => selector(obj)?.GetHashCode() ?? 0;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateEqualityComparer{T}" /> class.
        /// </summary>
        /// <param name="comparer">The compare function.</param>
        /// <param name="hashCodeGenerator">The hash code generator.</param>
        public DelegateEqualityComparer(Func<T?, T?, bool> comparer, Func<T?, int> hashCodeGenerator)
        {
            _comparer = comparer;
            _hashCodeGenerator = hashCodeGenerator;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateEqualityComparer{T}" /> class.
        /// </summary>
        /// <param name="selector">The selector that selects the object to compare, if e.g. two objects can be compared by a single property.</param>
        /// <param name="comparer">The compare function.</param>
        /// <param name="hashCodeGenerator">The hash code generator.</param>
        public DelegateEqualityComparer(Func<T?, object> selector, Func<object?, object?, bool> comparer, Func<object?, int> hashCodeGenerator)
        {
            _comparer = (a, b) => comparer(selector(a), selector(b));
            _hashCodeGenerator = obj => hashCodeGenerator(selector(obj));
        }

        /// <inheritdoc />
        public bool Equals(T? x, T? y)
        {
            if (!typeof(T).GetTypeInfo().IsValueType)
            {
                if (ReferenceEquals(x, null))
                    return ReferenceEquals(y, null);

                if (ReferenceEquals(y, null))
                    return false;
            }

            return _comparer(x, y);
        }

        /// <inheritdoc />
        public int GetHashCode(T? obj)
        {
            if (!typeof(T).GetTypeInfo().IsValueType)
            {
                if (ReferenceEquals(obj, null))
                    return 0;
            }<commit_msg>Fix nullable signature of DelegateEqualityComparer<commit_after>﻿namespace TomsToolbox.Essentials
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;

    /// <inheritdoc />
    /// <summary>
    /// <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> implementation using a delegate function to compare the values.
    /// </summary>
    /// <typeparam name="T">The type of objects to compare.</typeparam>
    public class DelegateEqualityComparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T?, T?, bool> _comparer;
        private readonly Func<T?, int> _hashCodeGenerator;

        /// <inheritdoc />
        /// <summary>
        /// Initializes a new instance of the <see cref="T:TomsToolbox.Essentials.DelegateEqualityComparer`1" /> class,
        /// using <see cref="M:System.Object.Equals(System.Object,System.Object)" /> and <see cref="M:System.Object.GetHashCode" />
        /// </summary>
        public DelegateEqualityComparer()
            : this((a, b) => object.Equals(a, b), x => ReferenceEquals(x, null) ? 0 : x.GetHashCode())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateEqualityComparer{T}"/> class.
        /// </summary>
        /// <param name="selector">The selector that selects the object to compare, if e.g. two objects can be compared by a single property.</param>
        public DelegateEqualityComparer(Func<T?, object?> selector)
        {
            _comparer = (a, b) => Equals(selector(a), selector(b));
            _hashCodeGenerator = obj => selector(obj)?.GetHashCode() ?? 0;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateEqualityComparer{T}" /> class.
        /// </summary>
        /// <param name="comparer">The compare function.</param>
        /// <param name="hashCodeGenerator">The hash code generator.</param>
        public DelegateEqualityComparer(Func<T?, T?, bool> comparer, Func<T?, int> hashCodeGenerator)
        {
            _comparer = comparer;
            _hashCodeGenerator = hashCodeGenerator;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DelegateEqualityComparer{T}" /> class.
        /// </summary>
        /// <param name="selector">The selector that selects the object to compare, if e.g. two objects can be compared by a single property.</param>
        /// <param name="comparer">The compare function.</param>
        /// <param name="hashCodeGenerator">The hash code generator.</param>
        public DelegateEqualityComparer(Func<T?, object?> selector, Func<object?, object?, bool> comparer, Func<object?, int> hashCodeGenerator)
        {
            _comparer = (a, b) => comparer(selector(a), selector(b));
            _hashCodeGenerator = obj => hashCodeGenerator(selector(obj));
        }

        /// <inheritdoc />
        public bool Equals(T? x, T? y)
        {
            if (!typeof(T).GetTypeInfo().IsValueType)
            {
                if (ReferenceEquals(x, null))
                    return ReferenceEquals(y, null);

                if (ReferenceEquals(y, null))
                    return false;
            }

            return _comparer(x, y);
        }

        /// <inheritdoc />
        public int GetHashCode(T? obj)
        {
            if (!typeof(T).GetTypeInfo().IsValueType)
            {
                if (ReferenceEquals(obj, null))
                    return 0;
            }
{'fraction_non_alphanumeric': 0.13489904052699414, 'fraction_numerical': 0.0014320492624946299, 'mean_word_length': 2.1473636773321316, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6075988', 'n_tokens_mistral': 1938, 'n_tokens_neox': 1885, 'n_words': 490}