#include <string>
#include <vector>
#include <iostream>
#include <cstdint>
namespace Math
{
template <typename Type>
struct P2
{
union
{
struct
{
Type X, Y;
};
Type Data[2];
};
};
template <typename Type>
struct P3
{
union
{
struct
{
Type X, Y, Z;
};
Type Data[3];
};
};
template <typename Type>
struct P4
{
union
{
struct
{
Type X, Y, Z, W;
};
Type Data[4];
};
};
// Generic case, no named variables
template <typename T, int Count>
struct CountToVectorData
{
typedef struct
{
T Data[Count];
} type;
};
// Specializations...
template <typename T>
struct CountToVectorData <T, 2>
{
typedef P2<T> type;
};
template <typename T>
struct CountToVectorData <T, 3>
{
typedef P3<T> type;
};
template <typename T>
struct CountToVectorData <T, 4>
{
typedef P4<T> type;
};
template <typename Type, size_t TemplateElementCount>
class TVector :public CountToVectorData <Type, TemplateElementCount>::type
{
public:
TVector(void)
{
for(unsigned cont = 0; cont < TemplateElementCount; ++cont)
this->Data[cont] = 0;
}
TVector(Type V1, Type V2 = 0, Type V3 = 0, Type V4 = 0)
{
this->Data[0] = V1;
if(TemplateElementCount >=2)
{
this->Data[1] = V2;
if(TemplateElementCount >=3)
{
this->Data[2] = V3;
if(TemplateElementCount == 4)
this->Data[3] = V4;
}
}
}
TVector(TVector <Type, TemplateElementCount-1> &OtherVector, Type LastValue = 0)
{
for(unsigned cont = 0; cont < TemplateElementCount-1; ++cont)
{
this->Data[cont] = OtherVector.Data[cont];
}
this->Data[TemplateElementCount-1] = LastValue;
}
void SetValues(Type V1, Type V2 = 0, Type V3 = 0, Type V4 = 0)
{
this->Data[0] = V1;
if(TemplateElementCount >=2)
{
this->Data[1] = V2;
if(TemplateElementCount >=3)
{
this->Data[2] = V3;
if(TemplateElementCount == 4)
this->Data[3] = V4;
}
}
}
// TVector ( Type First, ... )
// {
// this->Data[0] = First;
// va_list arguments;
// va_start ( arguments, First );
// for ( unsigned cont = 1; cont < TemplateElementCount; ++cont )
// this->Data[cont] = va_arg ( arguments, Type );
// va_end ( arguments );
// }
double Length(void)
{
Type Accum = 0;
for(unsigned cont = 0; cont < TemplateElementCount; ++cont)
Accum += (this->Data[cont]*this->Data[cont]);
return sqrt(Accum);
}
void SetAllElementsTo(Type In_Value)
{
for(unsigned cont = 0; cont < TemplateElementCount; ++cont)
this->Data[cont] = In_Value;
}
void Normalize(void)
{
double VecLength = Length();
if(VecLength == 0) return;
for(unsigned cont = 0; cont < TemplateElementCount; ++cont) \
this->Data[cont] /= VecLength ;
}
Type operator [](const int Index) const
{
return this->Data[Index];
}
Type &operator [](const int Index)
{
return this->Data[Index];
}
/*
TVector <Type,TemplateElementCount> operator - ( const TVector <Type,TemplateElementCount> &Second )
{
TVector <Type,TemplateElementCount> Result;
for ( unsigned cont = 0; cont < 3; ++cont )
Result.Data[cont] = this->Data[cont] - Second.Data[cont];
return Result;
}*/
};
}
template <typename Type, unsigned TemplateElementCount>
Math::TVector <Type,TemplateElementCount> operator - (Math::TVector <Type,TemplateElementCount> &First, Math::TVector <Type,TemplateElementCount> &Second)
{
Math::TVector <Type,TemplateElementCount> Result;
for(unsigned cont = 0; cont < TemplateElementCount; ++cont)
Result.Data[cont] = First.Data[cont] - Second.Data[cont];
return Result;
}
int main(int argc, char **argv)
{
Math::TVector <int32_t, 3> Vector1, Vector2;
Vector1.X = 1;
Vector1.Y = 2;
Vector1.Z = 3;
Vector2.SetValues(0,0,1);
for(unsigned cont = 0; cont < 3; ++cont)
{
std::cout << " -> " << Vector1.Data[cont] << std::endl;
}
Vector1 = Vector1 - Vector2;
for(unsigned cont = 0; cont < 3; ++cont)
{
std::cout << " -> " << Vector1.Data[cont] << std::endl;
}
return 0;
}