Files
Plugin/Source/SenseGloveUtils/Public/SGUtils/SGArrayUtils.h
T

539 lines
17 KiB
C++

/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2022 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#pragma once
#include <vector>
#include "Containers/Array.h"
#include "Templates/UnrealTemplate.h"
class SENSEGLOVEUTILS_API FSGArrayUtils final
{
public:
template<typename T>
static FORCEINLINE TArray<T> FromStdVector(const std::vector<T>& Vector)
{
TArray<T> Array(&Vector[0], Vector.size());
return MoveTemp(Array);
}
/// NOTE
/// std::vector<bool> is a non conforming container. Since it packs bools to be stored in one bit,
/// it cannot provide a bool reference. Thus, FSGArrayUtils::FromStdVector<bool>() cannot be used.
/// Hence, the specialization.
static TArray<bool> FromStdVector(const std::vector<bool>& Vector)
{
TArray<bool> Array;
for (const bool bValue: Vector)
{
Array.Add(bValue);
}
return MoveTemp(Array);
}
template<typename T>
static FORCEINLINE TArray<TArray<T>> FromStdVector(const std::vector<std::vector<T>>& Vector)
{
TArray<TArray<T>> Array;
for (const std::vector<T>& InnerVector: Vector)
{
TArray<T> InnerArray{FromStdVector<T>(InnerVector)};
Array.Add(MoveTemp(InnerArray));
}
return MoveTemp(Array);
}
template<typename T1, typename T2>
static TArray<T2> FromStdVector(const std::vector<T1>& Vector)
{
TArray<T2> Array;
for (const T1& T1Element: Vector)
{
T2 T2Element(T1Element);
Array.Add(MoveTemp(T2Element));
}
return MoveTemp(Array);
}
template<typename T1, typename T2>
static TArray<TArray<T2>> FromStdVector(const std::vector<std::vector<T1>>& Vector)
{
TArray<TArray<T2>> Array;
for (const std::vector<T1>& InnerVector: Vector)
{
TArray<T2> InnerArray{FromStdVector<T1, T2>(InnerVector)};
Array.Add(MoveTemp(InnerArray));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, typename IntermediateImpl, T2(IntermediateImpl::*ToT2TypeMethod)() const>
static TArray<T2> FromStdVector(const std::vector<T1>& Vector)
{
TArray<T2> Array;
for (const T1& T1Element: Vector)
{
IntermediateImpl ImplElement(T1Element);
T2 T2Element((ImplElement.*ToT2TypeMethod)());
Array.Add(MoveTemp(T2Element));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, typename IntermediateImpl, T2(IntermediateImpl::*ToT2TypeMethod)() const>
static TArray<TArray<T2>> FromStdVector(const std::vector<std::vector<T1>>& Vector)
{
TArray<TArray<T2>> Array;
for (const std::vector<T1>& InnerVector: Vector)
{
TArray<T2> InnerArray{FromStdVector<T1, T2, IntermediateImpl, ToT2TypeMethod>(InnerVector)};
Array.Add(MoveTemp(InnerArray));
}
return MoveTemp(Array);
}
template<typename T>
static FORCEINLINE std::vector<T> ToStdVector(const TArray<T>& Array)
{
std::vector<T> Vector(&Array[0], &Array[0] + Array.Num());
return MoveTemp(Vector);
}
template<typename T>
static FORCEINLINE std::vector<std::vector<T>> ToStdVector(const TArray<TArray<T>>& Array)
{
std::vector<std::vector<T>> Vector;
for (const TArray<T>& InnerArray: Array)
{
std::vector<T> InnerVector{ToStdVector<T>(InnerArray)};
Vector.emplace_back(MoveTemp(InnerVector));
}
return MoveTemp(Vector);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
static std::vector<T2> ToStdVector(const TArray<T1>& Array)
{
std::vector<T2> Vector;
for (const T1& T1Element: Array)
{
T2 T2Element((T1Element.*ToUnderlyingTypeMethod)());
Vector.emplace_back(MoveTemp(T2Element));
}
return MoveTemp(Vector);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
static std::vector<std::vector<T2>> ToStdVector(const TArray<TArray<T1>>& Array)
{
std::vector<std::vector<T2>> Vector;
for (const TArray<T1>& InnerArray: Array)
{
std::vector<T2> InnerVector{ToStdVector<T1, T2, ToUnderlyingTypeMethod>(InnerArray)};
Vector.emplace_back(MoveTemp(InnerVector));
}
return MoveTemp(Vector);
}
template<typename T1, typename T2, typename IntermediateImpl,
const T2&(IntermediateImpl::*ToUnderlyingTypeMethod)() const>
static std::vector<T2> ToStdVector(const TArray<T1>& Array)
{
std::vector<T2> Vector;
for (const T1& T1Element: Array)
{
IntermediateImpl ImplElement(T1Element);
T2 T2Element((ImplElement.*ToUnderlyingTypeMethod)());
Vector.emplace_back(MoveTemp(T2Element));
}
return MoveTemp(Vector);
}
template<typename T1, typename T2, typename IntermediateImpl,
const T2&(IntermediateImpl::*ToUnderlyingTypeMethod)() const>
static std::vector<std::vector<T2>> ToStdVector(const TArray<TArray<T1>>& Array)
{
std::vector<std::vector<T2>> Vector;
for (const TArray<T1>& InnerArray: Array)
{
std::vector<T2> InnerVector{ToStdVector<T1, T2, IntermediateImpl, ToUnderlyingTypeMethod>(InnerArray)};
Vector.emplace_back(MoveTemp(InnerVector));
}
return MoveTemp(Vector);
}
template<typename T1, typename T2>
static TArray<T2> FromImplType(const TArray<T1>& ImplArray)
{
TArray<T2> Array;
for (const T1& T1Element: ImplArray)
{
T2 T2Element(T1Element);
Array.Add(MoveTemp(T2Element));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, T2*(*NewObjectMethod)(UObject*, const T1&)>
static TArray<T2*> FromImplType(UObject* Outer, const TArray<T1>& ImplArray)
{
TArray<T2*> Array;
for (const T1& T1Element: ImplArray)
{
T2* T2Element(NewObjectMethod(Outer, T1Element));
Array.Add(MoveTemp(T2Element));
}
return MoveTemp(Array);
}
template<typename T1, typename T2>
static TArray<TArray<T2>> FromImplType(const TArray<TArray<T1>>& ImplArray)
{
TArray<TArray<T2>> Array;
for (const TArray<T1>& InnerImplArray: ImplArray)
{
TArray<T2> InnerArray{FromImplType<T1, T2>(InnerImplArray)};
Array.Add(MoveTemp(InnerArray));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, T2*(*NewObjectMethod)(UObject*, const T1&)>
static TArray<TArray<T2*>> FromImplType(UObject* Outer, const TArray<TArray<T1>>& ImplArray)
{
TArray<TArray<T2*>> Array;
for (const TArray<T1>& InnerImplArray: ImplArray)
{
TArray<T2*> InnerArray{FromImplType<T1, T2, NewObjectMethod>(Outer, InnerImplArray)};
Array.Add(MoveTemp(InnerArray));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, typename S>
static TArray<S> FromImplType(const TArray<TArray<T1>>& ImplArray)
{
TArray<S> Array;
for (const TArray<T1>& InnerImplArray: ImplArray)
{
TArray<T2> InnerArray{FromImplType<T1, T2>(InnerImplArray)};
S InnerArrayContainer{MoveTemp(InnerArray)};
Array.Add(MoveTemp(InnerArrayContainer));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, typename S, T2*(*NewObjectMethod)(UObject*, const T1&)>
static TArray<S> FromImplType(UObject* Outer, const TArray<TArray<T1>>& ImplArray)
{
TArray<S> Array;
for (const TArray<T1>& InnerImplArray: ImplArray)
{
TArray<T2*> InnerArray{FromImplType<T1, T2, NewObjectMethod>(Outer, InnerImplArray)};
S InnerArrayContainer{MoveTemp(InnerArray)};
Array.Add(MoveTemp(InnerArrayContainer));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, typename S>
static TArray<S> FromImplType(const TArray<TArray<T1*>>& ImplArray)
{
TArray<S> Array;
for (const TArray<T1>& InnerImplArray: ImplArray)
{
TArray<T2> InnerArray{FromImplType<T1, T2>(InnerImplArray)};
S InnerArrayContainer{MoveTemp(InnerArray)};
Array.Add(MoveTemp(InnerArrayContainer));
}
return MoveTemp(Array);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
static TArray<T2> ToImplType(const TArray<T1>& Array)
{
TArray<T2> ImplArray;
for (const T1& T1Element: Array)
{
T2 T2Element((T1Element.*ToUnderlyingTypeMethod)());
ImplArray.Add(MoveTemp(T2Element));
}
return MoveTemp(ImplArray);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
static TArray<T2> ToImplType(const TArray<T1*>& Array)
{
TArray<T2> ImplArray;
for (const T1* T1Element: Array)
{
T2 T2Element((T1Element->*ToUnderlyingTypeMethod)());
ImplArray.Add(MoveTemp(T2Element));
}
return MoveTemp(ImplArray);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
static TArray<TArray<T2>> ToImplType(const TArray<TArray<T1>>& Array)
{
TArray<TArray<T2>> ImplArray;
for (const TArray<T1>& InnerArray: Array)
{
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArray)};
ImplArray.Add(MoveTemp(InnerImplArray));
}
return MoveTemp(ImplArray);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
static TArray<TArray<T2>> ToImplType(const TArray<TArray<T1*>>& Array)
{
TArray<TArray<T2>> ImplArray;
for (const TArray<T1*>& InnerArray: Array)
{
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArray)};
ImplArray.Add(MoveTemp(InnerImplArray));
}
return MoveTemp(ImplArray);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const, typename S, TArray<T1> S::*
InnerArray>
static TArray<TArray<T2>> ToImplType(const TArray<S>& Array)
{
TArray<TArray<T2>> ImplArray;
for (const S& InnerArrayContainer: Array)
{
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArrayContainer.*InnerArray)};
ImplArray.Add(MoveTemp(InnerImplArray));
}
return MoveTemp(ImplArray);
}
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const, typename S, TArray<T1*> S::*
InnerArray>
static TArray<TArray<T2>> ToImplType(const TArray<S>& Array)
{
TArray<TArray<T2>> ImplArray;
for (const S& InnerArrayContainer: Array)
{
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArrayContainer.*InnerArray)};
ImplArray.Add(MoveTemp(InnerImplArray));
}
return MoveTemp(ImplArray);
}
template<typename T, typename S, TArray<T> S::*InnerArray>
static TArray<TArray<T>> FromBPNestedArray(const TArray<S>& BPNestedArray)
{
TArray<TArray<T>> NestedArray;
for (const S& BPInnerArrayContainer: BPNestedArray)
{
NestedArray.Add(BPInnerArrayContainer.*InnerArray);
}
return MoveTemp(NestedArray);
}
template<typename T, typename S>
static TArray<S> ToBPNestedArray(const TArray<TArray<T>>& NestedArray)
{
TArray<S> BPNestedArray;
for (const TArray<T>& InnerArray: NestedArray)
{
S BPInnerArrayContainer{InnerArray};
BPNestedArray.Add(MoveTemp(BPInnerArrayContainer));
}
return MoveTemp(BPNestedArray);
}
template<typename T, typename S>
static TArray<S> ToBPNestedArray(const TArray<TArray<T*>>& NestedArray)
{
TArray<S> BPNestedArray;
for (const TArray<T*>& InnerArray: NestedArray)
{
S BPInnerArrayContainer{InnerArray};
BPNestedArray.Add(MoveTemp(BPInnerArrayContainer));
}
return MoveTemp(BPNestedArray);
}
static TArray<FRotator> QuatsToRotators(const TArray<FQuat>& QuatsArray);
static TArray<TArray<FRotator>> QuatsToRotators(const TArray<TArray<FQuat>>& QuatsNestedArray);
template<typename S, TArray<FQuat> S::*InnerArray>
static TArray<TArray<FRotator>> QuatsToRotators(const TArray<S>& QuatsNestedArray)
{
TArray<TArray<FRotator>> RotatorsNestedArray;
for (const S& BPQuatsInnerArrayContainer: QuatsNestedArray)
{
RotatorsNestedArray.Add(QuatsToRotators(BPQuatsInnerArrayContainer.*InnerArray));
}
return MoveTemp(RotatorsNestedArray);
}
template<typename S>
static TArray<S> QuatsToRotators(const TArray<TArray<FQuat>>& QuatsNestedArray)
{
TArray<S> BPRotatorsNestedArray;
for (const TArray<FQuat>& QuatsInnerArray: QuatsNestedArray)
{
S BPRotatorsInnerArrayContainer{QuatsToRotators(QuatsInnerArray)};
BPRotatorsNestedArray.Add(MoveTemp(BPRotatorsInnerArrayContainer));
}
return MoveTemp(BPRotatorsNestedArray);
}
template<typename Q, typename R, TArray<FQuat> Q::*InnerArray>
static TArray<R> QuatsToRotators(const TArray<Q>& QuatsNestedArray)
{
TArray<R> BPRotatorsNestedArray;
for (const Q& QuatsInnerArrayContainer: QuatsNestedArray)
{
R BPRotatorsInnerArrayContainer{QuatsToRotators(QuatsInnerArrayContainer.*InnerArray)};
BPRotatorsNestedArray.Add(MoveTemp(BPRotatorsInnerArrayContainer));
}
return MoveTemp(BPRotatorsNestedArray);
}
static TArray<FQuat> RotatorsToQuats(const TArray<FRotator>& RotatorsArray);
static TArray<TArray<FQuat>> RotatorsToQuats(const TArray<TArray<FRotator>>& RotatorsNestedArray);
template<typename S, TArray<FRotator> S::*InnerArray>
static TArray<TArray<FQuat>> RotatorsToQuats(const TArray<S>& RotatorsNestedArray)
{
TArray<TArray<FQuat>> QuatsNestedArray;
for (const S& BPRotatorsInnerArrayContainer: RotatorsNestedArray)
{
QuatsNestedArray.Add(RotatorsToQuats(BPRotatorsInnerArrayContainer.*InnerArray));
}
return MoveTemp(QuatsNestedArray);
}
template<typename S>
static TArray<S> RotatorsToQuats(const TArray<TArray<FRotator>>& RotatorsNestedArray)
{
TArray<S> BPQuatsNestedArray;
for (const TArray<FRotator>& RotatorsInnerArray: RotatorsNestedArray)
{
S BPQuatsInnerArrayContainer{RotatorsToQuats(RotatorsInnerArray)};
BPQuatsNestedArray.Add(MoveTemp(BPQuatsInnerArrayContainer));
}
return MoveTemp(BPQuatsNestedArray);
}
template<typename Q, typename R, TArray<FRotator> Q::*InnerArray>
static TArray<R> RotatorsToQuats(const TArray<Q>& RotatorsNestedArray)
{
TArray<R> BPQuatsNestedArray;
for (const Q& RotatorsInnerArrayContainer: RotatorsNestedArray)
{
R BPQuatsInnerArrayContainer{RotatorsToQuats(RotatorsInnerArrayContainer.*InnerArray)};
BPQuatsNestedArray.Add(MoveTemp(BPQuatsInnerArrayContainer));
}
return MoveTemp(BPQuatsNestedArray);
}
public:
FSGArrayUtils() = delete;
virtual ~FSGArrayUtils() = delete;
};