|
using System; |
|
using System.Collections.Generic; |
|
|
|
namespace Unity.MLAgents |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public struct InplaceArray<T> : IEquatable<InplaceArray<T>> where T : struct |
|
{ |
|
private const int k_MaxLength = 4; |
|
private readonly int m_Length; |
|
|
|
private T m_Elem0; |
|
private T m_Elem1; |
|
private T m_Elem2; |
|
private T m_Elem3; |
|
|
|
|
|
|
|
|
|
|
|
public InplaceArray(T elem0) |
|
{ |
|
m_Length = 1; |
|
m_Elem0 = elem0; |
|
m_Elem1 = new T(); |
|
m_Elem2 = new T(); |
|
m_Elem3 = new T(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
public InplaceArray(T elem0, T elem1) |
|
{ |
|
m_Length = 2; |
|
m_Elem0 = elem0; |
|
m_Elem1 = elem1; |
|
m_Elem2 = new T(); |
|
m_Elem3 = new T(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public InplaceArray(T elem0, T elem1, T elem2) |
|
{ |
|
m_Length = 3; |
|
m_Elem0 = elem0; |
|
m_Elem1 = elem1; |
|
m_Elem2 = elem2; |
|
m_Elem3 = new T(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public InplaceArray(T elem0, T elem1, T elem2, T elem3) |
|
{ |
|
m_Length = 4; |
|
m_Elem0 = elem0; |
|
m_Elem1 = elem1; |
|
m_Elem2 = elem2; |
|
m_Elem3 = elem3; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static InplaceArray<T> FromList(IList<T> elems) |
|
{ |
|
switch (elems.Count) |
|
{ |
|
case 1: |
|
return new InplaceArray<T>(elems[0]); |
|
case 2: |
|
return new InplaceArray<T>(elems[0], elems[1]); |
|
case 3: |
|
return new InplaceArray<T>(elems[0], elems[1], elems[2]); |
|
case 4: |
|
return new InplaceArray<T>(elems[0], elems[1], elems[2], elems[3]); |
|
default: |
|
throw new ArgumentOutOfRangeException(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
public T this[int index] |
|
{ |
|
get |
|
{ |
|
if (index >= Length) |
|
{ |
|
throw new IndexOutOfRangeException(); |
|
} |
|
|
|
switch (index) |
|
{ |
|
case 0: |
|
return m_Elem0; |
|
case 1: |
|
return m_Elem1; |
|
case 2: |
|
return m_Elem2; |
|
case 3: |
|
return m_Elem3; |
|
default: |
|
throw new IndexOutOfRangeException(); |
|
} |
|
} |
|
|
|
set |
|
{ |
|
if (index >= Length) |
|
{ |
|
throw new IndexOutOfRangeException(); |
|
} |
|
|
|
switch (index) |
|
{ |
|
case 0: |
|
m_Elem0 = value; |
|
break; |
|
case 1: |
|
m_Elem1 = value; |
|
break; |
|
case 2: |
|
m_Elem2 = value; |
|
break; |
|
case 3: |
|
m_Elem3 = value; |
|
break; |
|
default: |
|
throw new IndexOutOfRangeException(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
public int Length |
|
{ |
|
get => m_Length; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
public override string ToString() |
|
{ |
|
switch (m_Length) |
|
{ |
|
case 1: |
|
return $"[{m_Elem0}]"; |
|
case 2: |
|
return $"[{m_Elem0}, {m_Elem1}]"; |
|
case 3: |
|
return $"[{m_Elem0}, {m_Elem1}, {m_Elem2}]"; |
|
case 4: |
|
return $"[{m_Elem0}, {m_Elem1}, {m_Elem2}, {m_Elem3}]"; |
|
default: |
|
throw new IndexOutOfRangeException(); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static bool operator ==(InplaceArray<T> lhs, InplaceArray<T> rhs) |
|
{ |
|
return lhs.Equals(rhs); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static bool operator !=(InplaceArray<T> lhs, InplaceArray<T> rhs) => !lhs.Equals(rhs); |
|
|
|
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object other) => other is InplaceArray<T> other1 && this.Equals(other1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
public bool Equals(InplaceArray<T> other) |
|
{ |
|
|
|
var thisTuple = (m_Elem0, m_Elem1, m_Elem2, m_Elem3, Length); |
|
var otherTuple = (other.m_Elem0, other.m_Elem1, other.m_Elem2, other.m_Elem3, other.Length); |
|
return thisTuple.Equals(otherTuple); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode() |
|
{ |
|
return (m_Elem0, m_Elem1, m_Elem2, m_Elem3, Length).GetHashCode(); |
|
} |
|
} |
|
} |
|
|