You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.0 KiB
121 lines
3.0 KiB
5 years ago
|
// Needed for NET40
|
||
|
#if !NET_4_6
|
||
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace LinqInternal.Threading.Needles
|
||
|
{
|
||
|
[Serializable]
|
||
|
[System.Diagnostics.DebuggerNonUserCode]
|
||
|
internal struct StructNeedle<T> : IEquatable<StructNeedle<T>>, IRecyclableNeedle<T>
|
||
|
{
|
||
|
private T _value;
|
||
|
|
||
|
public StructNeedle(T target)
|
||
|
{
|
||
|
_value = target;
|
||
|
}
|
||
|
|
||
|
public bool IsAlive
|
||
|
{
|
||
|
get { return !ReferenceEquals(Value, null); }
|
||
|
}
|
||
|
|
||
|
public T Value
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
// Keep backing field
|
||
|
return _value;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
// Keep backing field
|
||
|
_value = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static explicit operator T(StructNeedle<T> needle)
|
||
|
{
|
||
|
return needle.Value;
|
||
|
}
|
||
|
|
||
|
public static implicit operator StructNeedle<T>(T field)
|
||
|
{
|
||
|
return new StructNeedle<T>(field);
|
||
|
}
|
||
|
|
||
|
public static bool operator !=(StructNeedle<T> left, StructNeedle<T> right)
|
||
|
{
|
||
|
return NotEqualsExtracted(left, right);
|
||
|
}
|
||
|
|
||
|
public static bool operator ==(StructNeedle<T> left, StructNeedle<T> right)
|
||
|
{
|
||
|
return EqualsExtracted(left, right);
|
||
|
}
|
||
|
|
||
|
public override bool Equals(object obj)
|
||
|
{
|
||
|
if (obj is StructNeedle<T>)
|
||
|
{
|
||
|
return EqualsExtracted(this, (StructNeedle<T>)obj);
|
||
|
}
|
||
|
// Keep the "is" operator
|
||
|
if (obj is T)
|
||
|
{
|
||
|
var target = Value;
|
||
|
return IsAlive && EqualityComparer<T>.Default.Equals(target, (T)obj);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public bool Equals(StructNeedle<T> other)
|
||
|
{
|
||
|
return EqualsExtracted(this, other);
|
||
|
}
|
||
|
|
||
|
public override int GetHashCode()
|
||
|
{
|
||
|
return base.GetHashCode();
|
||
|
}
|
||
|
|
||
|
void IRecyclableNeedle<T>.Free()
|
||
|
{
|
||
|
Value = default(T);
|
||
|
}
|
||
|
|
||
|
public override string ToString()
|
||
|
{
|
||
|
var target = Value;
|
||
|
if (IsAlive)
|
||
|
{
|
||
|
return target.ToString();
|
||
|
}
|
||
|
return "<Dead Needle>";
|
||
|
}
|
||
|
|
||
|
private static bool EqualsExtracted(StructNeedle<T> left, StructNeedle<T> right)
|
||
|
{
|
||
|
var leftValue = left.Value;
|
||
|
if (left.IsAlive)
|
||
|
{
|
||
|
var rightValue = right.Value;
|
||
|
return right.IsAlive && EqualityComparer<T>.Default.Equals(leftValue, rightValue);
|
||
|
}
|
||
|
return !right.IsAlive;
|
||
|
}
|
||
|
|
||
|
private static bool NotEqualsExtracted(StructNeedle<T> left, StructNeedle<T> right)
|
||
|
{
|
||
|
var leftValue = left.Value;
|
||
|
if (left.IsAlive)
|
||
|
{
|
||
|
var rightValue = right.Value;
|
||
|
return !right.IsAlive || !EqualityComparer<T>.Default.Equals(leftValue, rightValue);
|
||
|
}
|
||
|
return right.IsAlive;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|