feat(miscellaneous): add support for c-style variadic functions and the corresponding testing
This commit is contained in:
parent
00838c2e35
commit
790b7fd5e6
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Miscellaneous/AssertionMacros.h"
|
#include "Miscellaneous/AssertionMacros.h"
|
||||||
#include "Miscellaneous/Compare.h"
|
#include "Miscellaneous/Compare.h"
|
||||||
|
#include "Miscellaneous/VarArgs.h"
|
||||||
|
|
||||||
NAMESPACE_REDCRAFT_BEGIN
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
NAMESPACE_MODULE_BEGIN(Redcraft)
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
@ -13,6 +14,7 @@ void TestMiscellaneous()
|
|||||||
{
|
{
|
||||||
TestAssertionMacros();
|
TestAssertionMacros();
|
||||||
TestCompare();
|
TestCompare();
|
||||||
|
TestVarArgs();
|
||||||
}
|
}
|
||||||
|
|
||||||
NAMESPACE_UNNAMED_BEGIN
|
NAMESPACE_UNNAMED_BEGIN
|
||||||
@ -220,6 +222,69 @@ void TestCompare()
|
|||||||
always_check(SynthThreeWayCompare(FTestSynth( 0), FTestSynth(-1)) == weak_ordering::greater);
|
always_check(SynthThreeWayCompare(FTestSynth( 0), FTestSynth(-1)) == weak_ordering::greater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NAMESPACE_UNNAMED_BEGIN
|
||||||
|
|
||||||
|
enum class ETestVarArgs
|
||||||
|
{
|
||||||
|
A = 0xA,
|
||||||
|
B = 0xB,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FTestVarArgs
|
||||||
|
{
|
||||||
|
int16 A;
|
||||||
|
float32 B;
|
||||||
|
|
||||||
|
friend bool operator==(const FTestVarArgs& LHS, const FTestVarArgs& RHS) { return LHS.A == RHS.A && LHS.B == RHS.B; }
|
||||||
|
};
|
||||||
|
|
||||||
|
void VARARGS TestVarArgs(int32 Count, ...)
|
||||||
|
{
|
||||||
|
VARARGS_ACCESS_BEGIN(Context, Count);
|
||||||
|
|
||||||
|
// always_check(VARARGS_ACCESS(Context, bool) == true);
|
||||||
|
// always_check(VARARGS_ACCESS(Context, char) == 2);
|
||||||
|
// always_check(VARARGS_ACCESS(Context, short) == 3);
|
||||||
|
always_check(VARARGS_ACCESS(Context, int) == 4);
|
||||||
|
always_check(VARARGS_ACCESS(Context, long long) == 5);
|
||||||
|
|
||||||
|
// always_check(VARARGS_ACCESS(Context, float) == 6.0f);
|
||||||
|
always_check(VARARGS_ACCESS(Context, double) == 7.0 );
|
||||||
|
always_check(VARARGS_ACCESS(Context, long double) == 8.0l);
|
||||||
|
|
||||||
|
// always_check(VARARGS_ACCESS(Context, nullptr_t) == nullptr);
|
||||||
|
always_check(VARARGS_ACCESS(Context, void*) == nullptr);
|
||||||
|
always_check(VARARGS_ACCESS(Context, int32 FTestVarArgs::*) == nullptr);
|
||||||
|
|
||||||
|
always_check(VARARGS_ACCESS(Context, ETestVarArgs) == ETestVarArgs::B);
|
||||||
|
always_check(VARARGS_ACCESS(Context, FTestVarArgs) == FTestVarArgs({ 404, 5.0f }));
|
||||||
|
|
||||||
|
VARARGS_ACCESS_END(Context);
|
||||||
|
};
|
||||||
|
|
||||||
|
NAMESPACE_UNNAMED_END
|
||||||
|
|
||||||
|
void TestVarArgs()
|
||||||
|
{
|
||||||
|
TestVarArgs
|
||||||
|
(
|
||||||
|
7 - 5,
|
||||||
|
// true,
|
||||||
|
// static_cast< char>(2),
|
||||||
|
// static_cast< short>(3),
|
||||||
|
static_cast< int>(4),
|
||||||
|
static_cast<long long>(5),
|
||||||
|
// 6.0f,
|
||||||
|
7.0,
|
||||||
|
8.0l,
|
||||||
|
// nullptr,
|
||||||
|
static_cast<void*>(nullptr),
|
||||||
|
static_cast<int32 FTestVarArgs::*>(nullptr),
|
||||||
|
ETestVarArgs::B,
|
||||||
|
FTestVarArgs({ 404, 5.0f })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
NAMESPACE_END(Testing)
|
NAMESPACE_END(Testing)
|
||||||
|
|
||||||
NAMESPACE_MODULE_END(Utility)
|
NAMESPACE_MODULE_END(Utility)
|
||||||
|
46
Redcraft.Utility/Source/Public/Miscellaneous/VarArgs.h
Normal file
46
Redcraft.Utility/Source/Public/Miscellaneous/VarArgs.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreTypes.h"
|
||||||
|
#include "TypeTraits/TypeTraits.h"
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
NAMESPACE_REDCRAFT_BEGIN
|
||||||
|
NAMESPACE_MODULE_BEGIN(Redcraft)
|
||||||
|
NAMESPACE_MODULE_BEGIN(Utility)
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_BEGIN
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct TVarArgsAssert
|
||||||
|
{
|
||||||
|
static_assert(CArithmetic<T> || CEnum<T> || CPointer<T> || CMemberPointer<T> || CClass<T>, "The type must be arithmetic, enum, pointer, member pointer, or class");
|
||||||
|
static_assert(!CNullPointer<T>, "The 'nullptr_t' is promoted to 'void*' when passed through '...'");
|
||||||
|
static_assert(!CSameAs<T, float>, "The 'float' is promoted to 'double' when passed through '...'");
|
||||||
|
static_assert(!CSameAs<T, bool>, "The 'bool' is promoted to 'int' when passed through '...'");
|
||||||
|
static_assert(!CSameAs<T, char>, "The 'char' is promoted to 'int' when passed through '...'");
|
||||||
|
static_assert(!CSameAs<T, short>, "The 'short' is promoted to 'int' when passed through '...'");
|
||||||
|
static_assert(CSameAs<T, TRemoveCV<T>>, "The 'const' and 'volatile' qualifiers are removed when passed through '...'");
|
||||||
|
static_assert(!CEnum<T> || CScopedEnum<T>, "The unscoped enum is promoted to 'int' when passed through '...'");
|
||||||
|
static_assert(!CClass<T> || CTriviallyCopyable<T>, "The non-trivially copyable class is not supported");
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> inline constexpr TVarArgsAssert<T> VarArgsAssert{ };
|
||||||
|
|
||||||
|
NAMESPACE_PRIVATE_END
|
||||||
|
|
||||||
|
/** Enables access to variadic function arguments. */
|
||||||
|
#define VARARGS_ACCESS_BEGIN(ContextName, NamedParam) NAMESPACE_STD::va_list ContextName; va_start(ContextName, NamedParam)
|
||||||
|
|
||||||
|
/** Makes a copy of the variadic function arguments. */
|
||||||
|
#define VARARGS_ACCESS_COPY(ContextName, ContextSource) NAMESPACE_STD::va_list ContextName; va_copy(ContextName, ContextSource)
|
||||||
|
|
||||||
|
/** Accesses the next variadic function argument. */
|
||||||
|
#define VARARGS_ACCESS(ContextName, Type) (NAMESPACE_PRIVATE::VarArgsAssert<Type>, va_arg(ContextName, Type))
|
||||||
|
|
||||||
|
/** Ends traversal of the variadic function arguments. */
|
||||||
|
#define VARARGS_ACCESS_END(ContextName) va_end(ContextName)
|
||||||
|
|
||||||
|
NAMESPACE_MODULE_END(Utility)
|
||||||
|
NAMESPACE_MODULE_END(Redcraft)
|
||||||
|
NAMESPACE_REDCRAFT_END
|
@ -11,6 +11,7 @@ NAMESPACE_BEGIN(Testing)
|
|||||||
REDCRAFTUTILITY_API void TestMiscellaneous();
|
REDCRAFTUTILITY_API void TestMiscellaneous();
|
||||||
REDCRAFTUTILITY_API void TestAssertionMacros();
|
REDCRAFTUTILITY_API void TestAssertionMacros();
|
||||||
REDCRAFTUTILITY_API void TestCompare();
|
REDCRAFTUTILITY_API void TestCompare();
|
||||||
|
REDCRAFTUTILITY_API void TestVarArgs();
|
||||||
|
|
||||||
NAMESPACE_END(Testing)
|
NAMESPACE_END(Testing)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user