Replaced static assert about TCHAR being not wider that ImWchar with a runtime check validating whether TCHAR values are in accepted range. Runtime check only happens on platforms where TCHAR is wider than ImWchar.

This commit is contained in:
Sebastian 2018-02-02 22:50:55 +00:00
parent c260a3d824
commit b2f4f43d7e

View File

@ -5,8 +5,45 @@
#include "ImGuiInputState.h" #include "ImGuiInputState.h"
#include <algorithm> #include <algorithm>
#include <limits>
#include <type_traits>
// If TCHAR is wider than ImWchar, enable or disable validation of input character before conversions.
#define VALIDATE_INPUT_CHARACTERS 1
#if VALIDATE_INPUT_CHARACTERS
DEFINE_LOG_CATEGORY_STATIC(LogImGuiInputState, Warning, All);
#endif
namespace
{
template<typename T, std::enable_if_t<(sizeof(T) <= sizeof(ImWchar)), T>* = nullptr>
ImWchar CastInputChar(T Char)
{
return static_cast<ImWchar>(Char);
}
template<typename T, std::enable_if_t<!(sizeof(T) <= sizeof(ImWchar)), T>* = nullptr>
ImWchar CastInputChar(T Char)
{
#if VALIDATE_INPUT_CHARACTERS
// We only need a runtime validation if TCHAR is wider than ImWchar.
// Signed and unsigned integral types with the same size as ImWchar should be safely converted. As long as the
// char value is in that range we can safely use it, otherwise we should log an error to notify about possible
// truncations.
static constexpr auto MinLimit = (std::numeric_limits<std::make_signed_t<ImWchar>>::min)();
static constexpr auto MaxLimit = (std::numeric_limits<std::make_unsigned_t<ImWchar>>::max)();
UE_CLOG(!(Char >= MinLimit && Char <= MaxLimit), LogImGuiInputState, Error,
TEXT("TCHAR value '%c' (%#x) is out of range %d (%#x) to %u (%#x) that can be safely converted to ImWchar. ")
TEXT("If you wish to disable this validation, please set VALIDATE_INPUT_CHARACTERS in ImGuiInputState.cpp to 0."),
Char, Char, MinLimit, MinLimit, MaxLimit, MaxLimit);
#endif
return static_cast<ImWchar>(Char);
}
}
FImGuiInputState::FImGuiInputState() FImGuiInputState::FImGuiInputState()
{ {
ResetState(); ResetState();
@ -14,11 +51,9 @@ FImGuiInputState::FImGuiInputState()
void FImGuiInputState::AddCharacter(TCHAR Char) void FImGuiInputState::AddCharacter(TCHAR Char)
{ {
static_assert(sizeof(TCHAR) <= sizeof(InputCharacters[0]), "Size of elements in Input Characters buffer is smaller than size of 'TCHAR'. Possible truncation.");
if (InputCharactersNum < Utilities::GetArraySize(InputCharacters)) if (InputCharactersNum < Utilities::GetArraySize(InputCharacters))
{ {
InputCharacters[InputCharactersNum++] = static_cast<ImWchar>(Char); InputCharacters[InputCharactersNum++] = CastInputChar(Char);
InputCharacters[InputCharactersNum] = 0; InputCharacters[InputCharactersNum] = 0;
} }
} }