Files
2026-01-19 09:50:54 +09:00

407 lines
11 KiB
C#

using System;
namespace Nanomesh
{
public unsafe interface IMetaAttribute
{
IMetaAttribute Set<K>(int index, K value) where K : unmanaged;
K Get<K>(int index) where K : unmanaged;
}
public unsafe struct MetaAttribute<T0> : IMetaAttribute
where T0 : unmanaged
{
public T0 attr0;
public MetaAttribute(T0 attr0)
{
this.attr0 = attr0;
}
public unsafe K Get<K>(int index) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
return kk[0];
}
default:
throw new ArgumentOutOfRangeException();
}
}
public IMetaAttribute Set<K>(int index, K value) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
default:
throw new ArgumentOutOfRangeException();
}
}
public override int GetHashCode()
{
return attr0.GetHashCode();
}
public override bool Equals(object obj)
{
return ((MetaAttribute<T0>)obj).attr0.Equals(attr0);
}
}
public unsafe struct MetaAttribute<T0, T1> : IMetaAttribute
where T0 : unmanaged
where T1 : unmanaged
{
public T0 attr0;
public T1 attr1;
public MetaAttribute(T0 attr0, T1 attr1)
{
this.attr0 = attr0;
this.attr1 = attr1;
}
public unsafe K Get<K>(int index) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
return kk[0];
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
return kk[0];
}
default:
throw new ArgumentOutOfRangeException();
}
}
public IMetaAttribute Set<K>(int index, K value) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
default:
throw new ArgumentOutOfRangeException();
}
}
}
public unsafe struct MetaAttribute<T0, T1, T2> : IMetaAttribute
where T0 : unmanaged
where T1 : unmanaged
where T2 : unmanaged
{
public T0 attr0;
public T1 attr1;
public T2 attr2;
public MetaAttribute(T0 attr0, T1 attr1, T2 attr2)
{
this.attr0 = attr0;
this.attr1 = attr1;
this.attr2 = attr2;
}
public unsafe K Get<K>(int index) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
return kk[0];
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
return kk[0];
}
case 2:
fixed (T2* k = &attr2)
{
K* kk = (K*)k;
return kk[0];
}
default:
throw new ArgumentOutOfRangeException();
}
}
public IMetaAttribute Set<K>(int index, K value) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 2:
fixed (T2* k = &attr2)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
default:
throw new ArgumentOutOfRangeException();
}
}
}
public unsafe struct MetaAttribute<T0, T1, T2, T3> : IMetaAttribute
where T0 : unmanaged
where T1 : unmanaged
where T2 : unmanaged
where T3 : unmanaged
{
public T0 attr0;
public T1 attr1;
public T2 attr2;
public T3 attr3;
public MetaAttribute(T0 attr0, T1 attr1, T2 attr2, T3 attr3)
{
this.attr0 = attr0;
this.attr1 = attr1;
this.attr2 = attr2;
this.attr3 = attr3;
}
public unsafe K Get<K>(int index) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
return kk[0];
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
return kk[0];
}
case 2:
fixed (T2* k = &attr2)
{
K* kk = (K*)k;
return kk[0];
}
case 3:
fixed (T3* k = &attr3)
{
K* kk = (K*)k;
return kk[0];
}
default:
throw new ArgumentOutOfRangeException();
}
// Shorter idea but only C# 8.0:
//fixed (void* v = &this)
//{
// byte* b = (byte*)v;
// b += Positions[index];
// return ((K*)b)[0];
//};
}
public IMetaAttribute Set<K>(int index, K value) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 2:
fixed (T2* k = &attr2)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 3:
fixed (T3* k = &attr3)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
default:
throw new ArgumentOutOfRangeException();
}
}
}
public unsafe struct MetaAttribute<T0, T1, T2, T3, T4> : IMetaAttribute
where T0 : unmanaged
where T1 : unmanaged
where T2 : unmanaged
where T3 : unmanaged
where T4 : unmanaged
{
public T0 attr0;
public T1 attr1;
public T2 attr2;
public T3 attr3;
public T4 attr4;
public MetaAttribute(T0 attr0, T1 attr1, T2 attr2, T3 attr3, T4 attr4)
{
this.attr0 = attr0;
this.attr1 = attr1;
this.attr2 = attr2;
this.attr3 = attr3;
this.attr4 = attr4;
}
public unsafe K Get<K>(int index) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
return kk[0];
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
return kk[0];
}
case 2:
fixed (T2* k = &attr2)
{
K* kk = (K*)k;
return kk[0];
}
case 3:
fixed (T3* k = &attr3)
{
K* kk = (K*)k;
return kk[0];
}
case 4:
fixed (T4* k = &attr4)
{
K* kk = (K*)k;
return kk[0];
}
default:
throw new ArgumentOutOfRangeException();
}
// Shorter idea but only C# 8.0:
//fixed (void* v = &this)
//{
// byte* b = (byte*)v;
// b += Positions[index];
// return ((K*)b)[0];
//};
}
public IMetaAttribute Set<K>(int index, K value) where K : unmanaged
{
switch (index)
{
case 0:
fixed (T0* k = &attr0)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 1:
fixed (T1* k = &attr1)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 2:
fixed (T2* k = &attr2)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 3:
fixed (T3* k = &attr3)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
case 4:
fixed (T4* k = &attr4)
{
K* kk = (K*)k;
kk[0] = value;
return this;
}
default:
throw new ArgumentOutOfRangeException();
}
}
}
}