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
// 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 |