Fix and improve last PR
Former-commit-id: 16afead68e42411402dfb5a7bd957a4940b6f83a
This commit is contained in:
@@ -15,7 +15,6 @@
|
||||
#include <Nazara/Lua/Enums.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
struct lua_Debug;
|
||||
struct lua_State;
|
||||
@@ -48,6 +47,8 @@ namespace Nz
|
||||
void CheckAny(int index) const;
|
||||
bool CheckBoolean(int index) const;
|
||||
bool CheckBoolean(int index, bool defValue) const;
|
||||
template<typename T> T CheckBoundInteger(int index) const;
|
||||
template<typename T> T CheckBoundInteger(int index, T defValue) const;
|
||||
template<typename T> T CheckField(const char* fieldName, int tableIndex = -1) const;
|
||||
template<typename T> T CheckField(const String& fieldName, int tableIndex = -1) const;
|
||||
template<typename T> T CheckField(const char* fieldName, T defValue, int tableIndex = -1) const;
|
||||
@@ -176,6 +177,7 @@ namespace Nz
|
||||
static LuaInstance* GetInstance(lua_State* state);
|
||||
|
||||
private:
|
||||
template<typename T> T CheckBounds(int index, long long value) const;
|
||||
bool Run(int argCount, int resultCount);
|
||||
|
||||
static void* MemoryAllocator(void *ud, void *ptr, std::size_t osize, std::size_t nsize);
|
||||
@@ -190,14 +192,6 @@ namespace Nz
|
||||
lua_State* m_state;
|
||||
unsigned int m_level;
|
||||
};
|
||||
|
||||
// Performs a 'ranged cast' to type T, i.e. a cast guaranteed to end up within the numerical limits of the type (or the limits provided in argument),
|
||||
// without over- or under-flowing.
|
||||
// Values beyond that range will be truncated to the type minimum (resp. maximum) if they are greater (resp. lesser) than the initial value.
|
||||
template <class T> T ranged_cast(long long a, T high = std::numeric_limits<T>::max(), T low = std::numeric_limits<T>::min())
|
||||
{
|
||||
return static_cast<T>(std::min(static_cast<long long>(high), std::max(a, static_cast<long long>(low))));
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Lua/LuaInstance.inl>
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Algorithm.hpp>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include "LuaInstance.hpp"
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -70,33 +72,19 @@ namespace Nz
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_integral<T>::value && !std::is_unsigned<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
|
||||
std::enable_if_t<std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
|
||||
{
|
||||
*arg = static_cast<T>(instance.CheckInteger(index));
|
||||
*arg = instance.CheckBoundInteger<T>(index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_integral<T>::value && !std::is_unsigned<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
std::enable_if_t<std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
{
|
||||
*arg = static_cast<T>(instance.CheckInteger(index, defValue));
|
||||
*arg = instance.CheckBoundInteger<T>(index, defValue);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, TypeTag<T>)
|
||||
{
|
||||
using SignedT = std::make_signed_t<T>;
|
||||
return LuaImplQueryArg(instance, index, reinterpret_cast<SignedT*>(arg), TypeTag<SignedT>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, T defValue, TypeTag<T>)
|
||||
{
|
||||
using SignedT = std::make_signed_t<T>;
|
||||
return LuaImplQueryArg(instance, index, reinterpret_cast<SignedT*>(arg), static_cast<SignedT>(defValue), TypeTag<SignedT>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<!std::is_integral<T>::value, unsigned int> LuaImplQueryArg(const LuaInstance& instance, int index, T* arg, const T& defValue, TypeTag<T> tag)
|
||||
{
|
||||
@@ -148,26 +136,24 @@ namespace Nz
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_integral<T>::value && !std::is_unsigned<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T>)
|
||||
std::enable_if_t<std::is_integral<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T>)
|
||||
{
|
||||
instance.PushInteger(val);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::enable_if_t<std::is_unsigned<T>::value, int> LuaImplReplyVal(const LuaInstance& instance, T val, TypeTag<T>)
|
||||
{
|
||||
using SignedT = typename std::make_signed<T>::type;
|
||||
|
||||
return LuaImplReplyVal(instance, static_cast<SignedT>(val), TypeTag<SignedT>());
|
||||
}
|
||||
|
||||
inline int LuaImplReplyVal(const LuaInstance& instance, std::string val, TypeTag<std::string>)
|
||||
{
|
||||
instance.PushString(val.c_str(), val.size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int LuaImplReplyVal(const LuaInstance& instance, ByteArray val, TypeTag<ByteArray>)
|
||||
{
|
||||
instance.PushString(reinterpret_cast<const char*>(val.GetConstBuffer()), val.GetSize());
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int LuaImplReplyVal(const LuaInstance& instance, String val, TypeTag<String>)
|
||||
{
|
||||
instance.PushString(std::move(val));
|
||||
@@ -420,6 +406,18 @@ namespace Nz
|
||||
return object;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T LuaInstance::CheckBoundInteger(int index) const
|
||||
{
|
||||
return CheckBounds<T>(index, CheckInteger(index));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T LuaInstance::CheckBoundInteger(int index, T defValue) const
|
||||
{
|
||||
return CheckBounds<T>(index, CheckInteger(index, defValue));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T LuaInstance::CheckField(const char* fieldName, int tableIndex) const
|
||||
{
|
||||
@@ -550,4 +548,19 @@ namespace Nz
|
||||
{
|
||||
SetGlobal(name.GetConstBuffer(), std::forward<T>(arg));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T LuaInstance::CheckBounds(int index, long long value) const
|
||||
{
|
||||
long long minBounds = std::numeric_limits<T>::min();
|
||||
long long maxBounds = std::numeric_limits<T>::max();
|
||||
if (value < minBounds || value > maxBounds)
|
||||
{
|
||||
Nz::StringStream stream;
|
||||
stream << "Argument #" << index << " is outside value range [" << minBounds << ", " << maxBounds << "] (" << value << ')';
|
||||
Error(stream);
|
||||
}
|
||||
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user