test new compat mode (we only test text, but I don't really generate binary files, and it seems to play ball both ways, so...)

This commit is contained in:
ThePhD 2017-09-16 14:18:45 -04:00
parent 2aecb11e97
commit 76d7195e64
26 changed files with 1133 additions and 841 deletions

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script.
// Generated 2017-09-14 12:49:46.096117 UTC
// This header was generated with sol v2.18.3 (revision 1fc0027)
// Generated 2017-09-16 18:18:13.277753 UTC
// This header was generated with sol v2.18.3 (revision 2aecb11)
// https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP
@ -1604,6 +1604,7 @@ extern "C" {
}
#endif
#undef COMPAT53_INCLUDE_SOURCE
#if defined(COMPAT53_PREFIX)
/* - change the symbol names of functions to avoid linker conflicts
* - compat-5.3.c needs to be compiled (and linked) separately
@ -1611,7 +1612,6 @@ extern "C" {
# if !defined(COMPAT53_API)
# define COMPAT53_API extern
# endif
# undef COMPAT53_INCLUDE_SOURCE
#else /* COMPAT53_PREFIX */
/* - make all functions static and include the source.
* - compat-5.3.c doesn't need to be compiled (and linked) separately
@ -1674,12 +1674,12 @@ extern "C" {
# define LUA_OPLE 2
#endif
/* LuaJIT/Lua 5.1 does not have the updated
/* LuaJIT/Lua 5.1 does not have the updated
* error codes for thread status/function returns (but some patched versions do)
* define it only if it's not found
*/
#if !defined(LUA_ERRGCMM)
/* Use + 2 because in some versions of Lua (Lua 5.1)
/* Use + 2 because in some versions of Lua (Lua 5.1)
* LUA_ERRFILE is defined as (LUA_ERRERR+1)
* so we need to avoid it (LuaJIT might have something at this
* integer value too)
@ -1698,6 +1698,14 @@ typedef struct luaL_Buffer_53 {
} luaL_Buffer_53;
#define luaL_Buffer luaL_Buffer_53
/* In PUC-Rio 5.1, userdata is a simple FILE*
* In LuaJIT, it's a struct where the first member is a FILE*
* We can't support the `closef` member
*/
typedef struct luaL_Stream {
FILE *f;
} luaL_Stream;
#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
COMPAT53_API int lua_absindex (lua_State *L, int i);
@ -1753,6 +1761,9 @@ COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum);
#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
COMPAT53_API void luaL_checkversion (lua_State *L);
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode);
@ -2003,12 +2014,15 @@ COMPAT53_API void luaL_requiref (lua_State *L, const char *modname,
#if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
#include <share.h>
#endif // VC++ _fsopen for share-allowed file read
#endif /* VC++ _fsopen for share-allowed file read */
#ifndef COMPAT53_HAVE_STRERROR_R
# if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || (!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
# if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || \
(!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
# define COMPAT53_HAVE_STRERROR_R 1
# if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_XOPEN_SOURCE) || _XOPEN_SOURCE >= 600)) && (!defined(_GNU_SOURCE) || !_GNU_SOURCE)
# if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
(defined(_XOPEN_SOURCE) || _XOPEN_SOURCE >= 600)) && \
(!defined(_GNU_SOURCE) || !_GNU_SOURCE)
# ifndef COMPAT53_HAVE_STRERROR_R_XSI
# define COMPAT53_HAVE_STRERROR_R_XSI 1
# endif /* XSI-Compliant strerror_r */
@ -2035,7 +2049,8 @@ COMPAT53_API void luaL_requiref (lua_State *L, const char *modname,
#endif /* strerror_r */
#ifndef COMPAT53_HAVE_STRERROR_S
# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || (defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
# define COMPAT53_HAVE_STRERROR_S 1
# else /* not VC++ or C11 */
# define COMPAT53_HAVE_STRERROR_S 0
@ -2046,7 +2061,7 @@ COMPAT53_API void luaL_requiref (lua_State *L, const char *modname,
#define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
#endif /* Lua File Buffer Size */
static char* compat53_strerror(int en, char* buff, size_t sz) {
static char* compat53_strerror (int en, char* buff, size_t sz) {
#if COMPAT53_HAVE_STRERROR_R
/* use strerror_r here, because it's available on these specific platforms */
#if COMPAT53_HAVE_STRERROR_R_XSI
@ -2401,13 +2416,48 @@ COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
static int compat53_checkmode (lua_State *L, const char *mode, const char *modename, int err) {
if (mode && strchr(mode, modename[0]) == NULL) {
lua_pushfstring(L, "attempt to load a %s chunk when 'mode' is '%s'", modename, mode);
lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
return err;
}
return LUA_OK;
}
typedef struct compat53_LoadF {
typedef struct {
lua_Reader reader;
void *ud;
int has_peeked_data;
const char *peeked_data;
size_t peeked_data_size;
} compat53_reader_data;
static const char *compat53_reader (lua_State *L, void *ud, size_t *size) {
compat53_reader_data *data = (compat53_reader_data *)ud;
if (data->has_peeked_data) {
data->has_peeked_data = 0;
*size = data->peeked_data_size;
return data->peeked_data;
} else
return data->reader(L, data->ud, size);
}
COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *source, const char *mode) {
int status = LUA_OK;
compat53_reader_data compat53_data = { reader, data, 1, 0, 0 };
compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
if (compat53_data.peeked_data && compat53_data.peeked_data_size &&
compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */
status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
else
status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
if (status != LUA_OK)
return status;
/* we need to call the original 5.1 version of lua_load! */
#undef lua_load
return lua_load(L, compat53_reader, &compat53_data, source);
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
}
typedef struct {
int n; /* number of pre-read characters */
FILE *f; /* file being read */
char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */
@ -2472,7 +2522,6 @@ static int compat53_skipcomment (compat53_LoadF *lf, int *cp) {
}
COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode) {
static const char lua_signature[] = "\x1bLua";
compat53_LoadF lf;
int status, readstatus;
int c;
@ -2484,24 +2533,25 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char
else {
lua_pushfstring(L, "@%s", filename);
#if defined(_MSC_VER)
/* a quick check shows that fopen_s this goes back to VS 2005,
* and _fsopen goes back to VS 2003 .NET, possibly even before that
* so we don't need to do any version number checks,
* since this has been there since forever
/* This code is here to stop a deprecation error that stops builds
* if a certain macro is defined. While normally not caring would
* be best, some header-only libraries and builds can't afford to
* dictate this to the user. A quick check shows that fopen_s this
* goes back to VS 2005, and _fsopen goes back to VS 2003 .NET,
* possibly even before that so we don't need to do any version
* number checks, since this has been there since forever.
*/
/* TO USER: if you want the behavior of typical fopen_s/fopen,
* which does lock the file on VC++, define the macro used below
*/
/* TO USER: if you want the behavior of typical fopen_s/fopen,
* which does lock the file on VC++, define the macro used below to 0
*/
#if COMPAT53_FOPEN_NO_LOCK
lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */
if (lf.f == NULL) {
if (lf.f == NULL)
return compat53_errfile(L, "open", fnameindex);
}
#else /* use default locking version */
if (fopen_s(&lf.f, filename, "r") != 0) {
if (fopen_s(&lf.f, filename, "r") != 0)
return compat53_errfile(L, "open", fnameindex);
}
#endif /* Locking vs. No-locking fopen variants */
#else
lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */
@ -2510,30 +2560,19 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char
}
if (compat53_skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == lua_signature[0]) { /* binary file? */
status = compat53_checkmode(L, mode, "binary", LUA_ERRFILE);
if (status != LUA_OK) {
fclose(lf.f);
return compat53_errfile(L, "improper mode", fnameindex);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
#if defined(_MSC_VER)
if (freopen_s(&lf.f, filename, "r", lf.f) != 0) return compat53_errfile(L, "open", fnameindex);
if (freopen_s(&lf.f, filename, "rb", lf.f) != 0)
return compat53_errfile(L, "reopen", fnameindex);
#else
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return compat53_errfile(L, "reopen", fnameindex);
#endif
compat53_skipcomment(&lf, &c); /* re-read initial portion */
}
else { /* text file */
status = compat53_checkmode(L, mode, "text", LUA_ERRFILE);
if (status != LUA_OK) {
fclose(lf.f);
return compat53_errfile(L, "improper mode", fnameindex);
}
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1));
status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode);
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
@ -2546,7 +2585,7 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char
COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) {
int status = LUA_OK;
if (sz > 0 && buff[0] == '\x1b') {
if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) {
status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
}
else {
@ -18486,12 +18525,7 @@ namespace sol {
load_result load(lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
#if SOL_LUA_VERSION > 501
load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
#else
(void)mode;
load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget));
#endif
return load_result(L, absolute_index(L, -1), 1, 1, x);
}

View File

@ -25,12 +25,15 @@
#if defined(_MSC_VER) && COMPAT53_FOPEN_NO_LOCK
#include <share.h>
#endif // VC++ _fsopen for share-allowed file read
#endif /* VC++ _fsopen for share-allowed file read */
#ifndef COMPAT53_HAVE_STRERROR_R
# if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || (!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
# if defined(__GLIBC__) || defined(_POSIX_VERSION) || defined(__APPLE__) || \
(!defined (__MINGW32__) && defined(__GNUC__) && (__GNUC__ < 6))
# define COMPAT53_HAVE_STRERROR_R 1
# if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_XOPEN_SOURCE) || _XOPEN_SOURCE >= 600)) && (!defined(_GNU_SOURCE) || !_GNU_SOURCE)
# if ((defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
(defined(_XOPEN_SOURCE) || _XOPEN_SOURCE >= 600)) && \
(!defined(_GNU_SOURCE) || !_GNU_SOURCE)
# ifndef COMPAT53_HAVE_STRERROR_R_XSI
# define COMPAT53_HAVE_STRERROR_R_XSI 1
# endif /* XSI-Compliant strerror_r */
@ -57,7 +60,8 @@
#endif /* strerror_r */
#ifndef COMPAT53_HAVE_STRERROR_S
# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || (defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
# if defined(_MSC_VER) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
(defined(__STDC_LIB_EXT1__) && __STDC_LIB_EXT1__)
# define COMPAT53_HAVE_STRERROR_S 1
# else /* not VC++ or C11 */
# define COMPAT53_HAVE_STRERROR_S 0
@ -68,7 +72,8 @@
#define COMPAT53_LUA_FILE_BUFFER_SIZE 4096
#endif /* Lua File Buffer Size */
static char* compat53_strerror(int en, char* buff, size_t sz) {
static char* compat53_strerror (int en, char* buff, size_t sz) {
#if COMPAT53_HAVE_STRERROR_R
/* use strerror_r here, because it's available on these specific platforms */
#if COMPAT53_HAVE_STRERROR_R_XSI
@ -98,6 +103,7 @@ static char* compat53_strerror(int en, char* buff, size_t sz) {
#endif
}
COMPAT53_API int lua_absindex (lua_State *L, int i) {
if (i < 0 && i > LUA_REGISTRYINDEX)
i += lua_gettop(L) + 1;
@ -441,14 +447,52 @@ COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
static int compat53_checkmode (lua_State *L, const char *mode, const char *modename, int err) {
if (mode && strchr(mode, modename[0]) == NULL) {
lua_pushfstring(L, "attempt to load a %s chunk when 'mode' is '%s'", modename, mode);
lua_pushfstring(L, "attempt to load a %s chunk (mode is '%s')", modename, mode);
return err;
}
return LUA_OK;
}
typedef struct compat53_LoadF {
typedef struct {
lua_Reader reader;
void *ud;
int has_peeked_data;
const char *peeked_data;
size_t peeked_data_size;
} compat53_reader_data;
static const char *compat53_reader (lua_State *L, void *ud, size_t *size) {
compat53_reader_data *data = (compat53_reader_data *)ud;
if (data->has_peeked_data) {
data->has_peeked_data = 0;
*size = data->peeked_data_size;
return data->peeked_data;
} else
return data->reader(L, data->ud, size);
}
COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char *source, const char *mode) {
int status = LUA_OK;
compat53_reader_data compat53_data = { reader, data, 1, 0, 0 };
compat53_data.peeked_data = reader(L, data, &(compat53_data.peeked_data_size));
if (compat53_data.peeked_data && compat53_data.peeked_data_size &&
compat53_data.peeked_data[0] == LUA_SIGNATURE[0]) /* binary file? */
status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
else
status = compat53_checkmode(L, mode, "text", LUA_ERRSYNTAX);
if (status != LUA_OK)
return status;
/* we need to call the original 5.1 version of lua_load! */
#undef lua_load
return lua_load(L, compat53_reader, &compat53_data, source);
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
}
typedef struct {
int n; /* number of pre-read characters */
FILE *f; /* file being read */
char buff[COMPAT53_LUA_FILE_BUFFER_SIZE]; /* area for reading file */
@ -518,7 +562,6 @@ static int compat53_skipcomment (compat53_LoadF *lf, int *cp) {
COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode) {
static const char lua_signature[] = "\x1bLua";
compat53_LoadF lf;
int status, readstatus;
int c;
@ -530,24 +573,25 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char
else {
lua_pushfstring(L, "@%s", filename);
#if defined(_MSC_VER)
/* a quick check shows that fopen_s this goes back to VS 2005,
* and _fsopen goes back to VS 2003 .NET, possibly even before that
* so we don't need to do any version number checks,
* since this has been there since forever
/* This code is here to stop a deprecation error that stops builds
* if a certain macro is defined. While normally not caring would
* be best, some header-only libraries and builds can't afford to
* dictate this to the user. A quick check shows that fopen_s this
* goes back to VS 2005, and _fsopen goes back to VS 2003 .NET,
* possibly even before that so we don't need to do any version
* number checks, since this has been there since forever.
*/
/* TO USER: if you want the behavior of typical fopen_s/fopen,
* which does lock the file on VC++, define the macro used below
*/
/* TO USER: if you want the behavior of typical fopen_s/fopen,
* which does lock the file on VC++, define the macro used below to 0
*/
#if COMPAT53_FOPEN_NO_LOCK
lf.f = _fsopen(filename, "r", _SH_DENYNO); /* do not lock the file in any way */
if (lf.f == NULL) {
if (lf.f == NULL)
return compat53_errfile(L, "open", fnameindex);
}
#else /* use default locking version */
if (fopen_s(&lf.f, filename, "r") != 0) {
if (fopen_s(&lf.f, filename, "r") != 0)
return compat53_errfile(L, "open", fnameindex);
}
#endif /* Locking vs. No-locking fopen variants */
#else
lf.f = fopen(filename, "r"); /* default stdlib doesn't forcefully lock files here */
@ -556,30 +600,19 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char
}
if (compat53_skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == lua_signature[0]) { /* binary file? */
status = compat53_checkmode(L, mode, "binary", LUA_ERRFILE);
if (status != LUA_OK) {
fclose(lf.f);
return compat53_errfile(L, "improper mode", fnameindex);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
#if defined(_MSC_VER)
if (freopen_s(&lf.f, filename, "r", lf.f) != 0) return compat53_errfile(L, "open", fnameindex);
if (freopen_s(&lf.f, filename, "rb", lf.f) != 0)
return compat53_errfile(L, "reopen", fnameindex);
#else
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return compat53_errfile(L, "reopen", fnameindex);
#endif
compat53_skipcomment(&lf, &c); /* re-read initial portion */
}
else { /* text file */
status = compat53_checkmode(L, mode, "text", LUA_ERRFILE);
if (status != LUA_OK) {
fclose(lf.f);
return compat53_errfile(L, "improper mode", fnameindex);
}
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1));
status = lua_load(L, &compat53_getF, &lf, lua_tostring(L, -1), mode);
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
@ -593,7 +626,7 @@ COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char
COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode) {
int status = LUA_OK;
if (sz > 0 && buff[0] == '\x1b') {
if (sz > 0 && buff[0] == LUA_SIGNATURE[0]) {
status = compat53_checkmode(L, mode, "binary", LUA_ERRSYNTAX);
}
else {
@ -604,6 +637,7 @@ COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, co
return luaL_loadbuffer(L, buff, sz, name);
}
#if !defined(l_inspectstat) && \
(defined(unix) || defined(__unix) || defined(__unix__) || \
defined(__TOS_AIX__) || defined(_SYSTYPE_BSD) || \

View File

@ -9,11 +9,13 @@ extern "C" {
#endif
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif
#undef COMPAT53_INCLUDE_SOURCE
#if defined(COMPAT53_PREFIX)
/* - change the symbol names of functions to avoid linker conflicts
* - compat-5.3.c needs to be compiled (and linked) separately
@ -21,7 +23,6 @@ extern "C" {
# if !defined(COMPAT53_API)
# define COMPAT53_API extern
# endif
# undef COMPAT53_INCLUDE_SOURCE
#else /* COMPAT53_PREFIX */
/* - make all functions static and include the source.
* - compat-5.3.c doesn't need to be compiled (and linked) separately
@ -86,12 +87,12 @@ extern "C" {
# define LUA_OPLE 2
#endif
/* LuaJIT/Lua 5.1 does not have the updated
/* LuaJIT/Lua 5.1 does not have the updated
* error codes for thread status/function returns (but some patched versions do)
* define it only if it's not found
*/
#if !defined(LUA_ERRGCMM)
/* Use + 2 because in some versions of Lua (Lua 5.1)
/* Use + 2 because in some versions of Lua (Lua 5.1)
* LUA_ERRFILE is defined as (LUA_ERRERR+1)
* so we need to avoid it (LuaJIT might have something at this
* integer value too)
@ -110,6 +111,14 @@ typedef struct luaL_Buffer_53 {
} luaL_Buffer_53;
#define luaL_Buffer luaL_Buffer_53
/* In PUC-Rio 5.1, userdata is a simple FILE*
* In LuaJIT, it's a struct where the first member is a FILE*
* We can't support the `closef` member
*/
typedef struct luaL_Stream {
FILE *f;
} luaL_Stream;
#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
COMPAT53_API int lua_absindex (lua_State *L, int i);
@ -165,6 +174,9 @@ COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum);
#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
COMPAT53_API void luaL_checkversion (lua_State *L);
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode);

View File

@ -488,12 +488,7 @@ namespace sol {
load_result load(lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
#if SOL_LUA_VERSION > 501
load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()));
#else
(void)mode;
load_status x = static_cast<load_status>(lua_load(L, reader, data, chunknametarget));
#endif
return load_result(L, absolute_index(L, -1), 1, 1, x);
}

View File

@ -22,12 +22,13 @@ private:
public:
static const void* last_printed;
my_object(int sz) : mdata() {
my_object(int sz)
: mdata() {
mdata.resize(sz);
std::iota(mdata.begin(), mdata.end(), 1);
}
void operator() (std::size_t count, int value) {
void operator()(std::size_t count, int value) {
for (; count > 0; --count) {
mdata.push_back(value);
}
@ -42,19 +43,45 @@ public: // Container requirements, as per the C++ standard
using difference_type = decltype(mdata)::difference_type;
using size_type = decltype(mdata)::size_type;
iterator begin() { return iterator(mdata.begin()); }
iterator end() { return iterator(mdata.end()); }
const_iterator begin() const { return const_iterator(mdata.begin()); }
const_iterator end() const { return const_iterator(mdata.end()); }
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
size_type size() const noexcept { return mdata.size(); }
size_type max_size() const noexcept { return mdata.max_size(); }
void push_back(const value_type& v) { mdata.push_back(v); }
void insert(const_iterator where, const value_type& v) { mdata.insert(where, v); }
bool empty() const noexcept { return mdata.empty(); }
bool operator== (const my_object& right) const { return mdata == right.mdata; }
bool operator!=(const my_object& right) const noexcept { return mdata != right.mdata; }
iterator begin() {
return iterator(mdata.begin());
}
iterator end() {
return iterator(mdata.end());
}
const_iterator begin() const {
return const_iterator(mdata.begin());
}
const_iterator end() const {
return const_iterator(mdata.end());
}
const_iterator cbegin() const {
return begin();
}
const_iterator cend() const {
return end();
}
size_type size() const noexcept {
return mdata.size();
}
size_type max_size() const noexcept {
return mdata.max_size();
}
void push_back(const value_type& v) {
mdata.push_back(v);
}
void insert(const_iterator where, const value_type& v) {
mdata.insert(where, v);
}
bool empty() const noexcept {
return mdata.empty();
}
bool operator==(const my_object& right) const {
return mdata == right.mdata;
}
bool operator!=(const my_object& right) const noexcept {
return mdata != right.mdata;
}
std::vector<int>& data() {
return mdata;
@ -63,12 +90,11 @@ public: // Container requirements, as per the C++ standard
const std::vector<int>& data() const {
return mdata;
}
};
const void* my_object::last_printed = nullptr;
std::ostream& operator<< (std::ostream& ostr, const my_object& mo) {
std::ostream& operator<<(std::ostream& ostr, const my_object& mo) {
my_object::last_printed = static_cast<const void*>(&mo);
ostr << "{ ";
const auto& v = mo.data();
@ -89,7 +115,7 @@ std::ostream& operator<< (std::ostream& ostr, const my_object& mo) {
namespace sol {
template <>
struct is_container<my_object> : std::false_type {};
}
} // namespace sol
template <typename T>
void sequence_container_check(sol::state& lua, T& items) {
@ -99,7 +125,8 @@ for i=1,#c do
v = c[i]
assert(v == (i + 10))
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(r1.valid());
}
{
@ -208,7 +235,8 @@ for i=1,#c do
v = c[(i + 10)]
assert(v == (i + 10))
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(r1.valid());
}
{
@ -403,7 +431,8 @@ for i=1,#c do
v = c[(i + 10)]
assert(v == (i + 20))
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(r1.valid());
}
{
@ -617,7 +646,8 @@ for i=1,#c do
v = c[i]
assert(v == (i + 10))
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE(r1.valid());
}
{
@ -730,7 +760,7 @@ TEST_CASE("containers/sequence containers", "check all of the functinos for ever
SECTION("list") {
sol::state lua;
lua.open_libraries(sol::lib::base);
std::list<int> items{ 11, 12, 13, 14, 15 };
lua["c"] = &items;
sequence_container_check(lua, items);
@ -911,18 +941,18 @@ end
)");
// Have the function we
// Have the function we
// just defined in Lua
sol::function g = lua["g"];
sol::function h = lua["h"];
sol::function i = lua["i"];
sol::function sf = lua["sf"];
// Set a global variable called
// Set a global variable called
// "arr" to be a vector of 5 lements
lua["c_arr"] = std::array<int, 5>{ { 2, 4, 6, 8, 10 } };
lua["arr"] = std::vector<int>{ 2, 4, 6, 8, 10 };
lua["map"] = std::map<int, int>{ { 1 , 2 },{ 2, 4 },{ 3, 6 },{ 4, 8 },{ 5, 10 } };
lua["map"] = std::map<int, int>{ { 1, 2 }, { 2, 4 }, { 3, 6 }, { 4, 8 }, { 5, 10 } };
lua["set"] = std::set<int>{ 2, 4, 6, 8, 10 };
std::array<int, 5>& c_arr = lua["c_arr"];
std::vector<int>& arr = lua["arr"];
@ -1002,8 +1032,7 @@ TEST_CASE("containers/as_container reference", "test that we can force a contain
"size", &my_object::size,
"iterable", [](my_object& mo) {
return sol::as_container(mo);
}
);
});
#if SOL_LUA_VERSION > 501
REQUIRE_NOTHROW([&]() {

View File

@ -19,15 +19,15 @@ auto test_table_return_one() {
}
auto test_table_return_two() {
return sol::as_table(std::vector<std::pair<std::string, int>>{ { "one", 1 },{ "two", 2 },{ "three", 3 } });
return sol::as_table(std::vector<std::pair<std::string, int>>{ { "one", 1 }, { "two", 2 }, { "three", 3 } });
}
auto test_table_return_three() {
return sol::as_table(std::map<std::string, std::string>{ { "name", "Rapptz" },{ "friend", "ThePhD" },{ "project", "sol" } });
return sol::as_table(std::map<std::string, std::string>{ { "name", "Rapptz" }, { "friend", "ThePhD" }, { "project", "sol" } });
}
auto test_table_return_four() {
return sol::as_table(std::array<std::pair<std::string, int>, 4>{ { { "one", 1 },{ "two", 2 },{ "three", 3 },{ "four", 4 } } });
return sol::as_table(std::array<std::pair<std::string, int>, 4>{ { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 } } });
}
TEST_CASE("containers/returns", "make sure that even references to vectors are being serialized as tables") {
@ -55,11 +55,11 @@ TEST_CASE("containers/table conversion", "test table conversions with as_table a
lua.open_libraries(sol::lib::base);
lua.set_function("bark", []() {
return sol::as_nested(std::vector<std::string>{"bark", "woof"});
return sol::as_nested(std::vector<std::string>{ "bark", "woof" });
});
lua.set_function("woof", []() {
return sol::as_nested(std::vector<std::string>{"bark", "woof"});
return sol::as_nested(std::vector<std::string>{ "bark", "woof" });
});
lua.safe_script("v1 = bark()");
@ -68,7 +68,7 @@ TEST_CASE("containers/table conversion", "test table conversions with as_table a
sol::as_table_t<std::vector<std::string>> as_table_strings = lua["v1"];
sol::nested<std::vector<std::string>> nested_strings = lua["v2"];
std::vector<std::string> expected_values{"bark", "woof"};
std::vector<std::string> expected_values{ "bark", "woof" };
REQUIRE(as_table_strings.source == expected_values);
REQUIRE(nested_strings.source == expected_values);
}
@ -116,7 +116,7 @@ TEST_CASE("containers/list roundtrip", "make sure lists can be round-tripped") {
return v;
});
lua.safe_script("x = f()");
std::list <int> x = lua["x"];
std::list<int> x = lua["x"];
bool areequal = x == v;
REQUIRE(areequal);
}
@ -128,14 +128,14 @@ TEST_CASE("containers/forward_list roundtrip", "make sure forward_lists can be r
return v;
});
lua.safe_script("x = f()");
std::forward_list <int> x = lua["x"];
std::forward_list<int> x = lua["x"];
bool areequal = x == v;
REQUIRE(areequal);
}
TEST_CASE("containers/map roundtrip", "make sure maps can be round-tripped") {
sol::state lua;
std::map<std::string, int> v{ { "a", 1 },{ "b", 2 },{ "c", 3 } };
std::map<std::string, int> v{ { "a", 1 }, { "b", 2 }, { "c", 3 } };
lua.set_function("f", [&]() -> std::map<std::string, int>& {
return v;
});
@ -147,7 +147,7 @@ TEST_CASE("containers/map roundtrip", "make sure maps can be round-tripped") {
TEST_CASE("containers/unordered_map roundtrip", "make sure unordered_maps can be round-tripped") {
sol::state lua;
std::unordered_map<std::string, int> v{ { "a", 1 },{ "b", 2 },{ "c", 3 } };
std::unordered_map<std::string, int> v{ { "a", 1 }, { "b", 2 }, { "c", 3 } };
lua.set_function("f", [&]() -> std::unordered_map<std::string, int>& {
return v;
});
@ -224,7 +224,7 @@ TEST_CASE("containers/list table roundtrip", "make sure lists can be round-tripp
return sol::as_table(v);
});
lua.safe_script("x = f()");
sol::as_table_t<std::list <int>> x = lua["x"];
sol::as_table_t<std::list<int>> x = lua["x"];
bool areequal = x.source == v;
REQUIRE(areequal);
}
@ -243,7 +243,7 @@ TEST_CASE("containers/forward_list table roundtrip", "make sure forward_lists ca
TEST_CASE("containers/map table roundtrip", "make sure maps can be round-tripped") {
sol::state lua;
std::map<std::string, int> v{ { "a", 1 },{ "b", 2 },{ "c", 3 } };
std::map<std::string, int> v{ { "a", 1 }, { "b", 2 }, { "c", 3 } };
lua.set_function("f", [&]() {
return sol::as_table(v);
});
@ -255,7 +255,7 @@ TEST_CASE("containers/map table roundtrip", "make sure maps can be round-tripped
TEST_CASE("containers/unordered_map table roundtrip", "make sure unordered_maps can be round-tripped") {
sol::state lua;
std::unordered_map<std::string, int> v{ { "a", 1 },{ "b", 2 },{ "c", 3 } };
std::unordered_map<std::string, int> v{ { "a", 1 }, { "b", 2 }, { "c", 3 } };
lua.set_function("f", [&]() {
return sol::as_table(v);
});
@ -291,17 +291,14 @@ TEST_CASE("containers/set table roundtrip", "make sure sets can be round-tripped
TEST_CASE("containers/custom usertype", "make sure container usertype metatables can be overridden") {
typedef std::unordered_map<int, int> bark;
sol::state lua;
lua.open_libraries();
lua.new_usertype<bark>("bark",
"something", [](const bark& b) {
INFO("It works: " << b.at(24));
},
"size", &bark::size,
"at", sol::resolve<const int&>(&bark::at),
"clear", &bark::clear
);
"size", &bark::size, "at", sol::resolve<const int&>(&bark::at), "clear", &bark::clear);
bark obj{ { 24, 50 } };
lua.set("a", &obj);
REQUIRE_NOTHROW(lua.safe_script("assert(a:at(24) == 50)"));
@ -330,21 +327,17 @@ TEST_CASE("containers/basic serialization", "make sure containers are turned int
lua.open_libraries();
lua.set("b", woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 });
REQUIRE_NOTHROW(
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
);
lua.safe_script("for k = 1, #b do assert(k == b[k]) end"));
woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
lua.set("b", w);
REQUIRE_NOTHROW(
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
);
lua.safe_script("for k = 1, #b do assert(k == b[k]) end"));
lua.set("b", &w);
REQUIRE_NOTHROW(
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
);
lua.safe_script("for k = 1, #b do assert(k == b[k]) end"));
lua.set("b", std::ref(w));
REQUIRE_NOTHROW(
lua.safe_script("for k = 1, #b do assert(k == b[k]) end")
);
lua.safe_script("for k = 1, #b do assert(k == b[k]) end"));
}
#if 0 // LUL const int holders
@ -367,21 +360,17 @@ TEST_CASE("containers/table serialization", "ensure types can be serialized as t
lua.open_libraries();
lua.set("b", sol::as_table(woof{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }));
REQUIRE_NOTHROW(
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
);
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end"));
woof w{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
lua.set("b", sol::as_table(w));
REQUIRE_NOTHROW(
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
);
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end"));
lua.set("b", sol::as_table(&w));
REQUIRE_NOTHROW(
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
);
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end"));
lua.set("b", sol::as_table(std::ref(w)));
REQUIRE_NOTHROW(
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end")
);
lua.safe_script("for k, v in ipairs(b) do assert(k == v) end"));
}
TEST_CASE("containers/const correctness", "usertype metatable names should reasonably ignore const attributes") {
@ -401,7 +390,7 @@ TEST_CASE("containers/const correctness", "usertype metatable names should reaso
std::vector<Vec> foo;
foo.push_back(vec);
std::vector<Vec const *> bar;
std::vector<Vec const*> bar;
bar.push_back(&vec);
lua.safe_script(R"(
@ -413,7 +402,7 @@ func = function(vecs)
end
)");
REQUIRE_NOTHROW([&]{
REQUIRE_NOTHROW([&] {
lua["func"](foo);
lua["func"](bar);
}());
@ -462,9 +451,11 @@ TEST_CASE("containers/usertype transparency", "Make sure containers pass their a
class A {
public:
int a;
A(int b = 2) : a(b) {};
A(int b = 2)
: a(b){};
void func() { }
void func() {
}
};
struct B {
@ -480,8 +471,7 @@ TEST_CASE("containers/usertype transparency", "Make sure containers pass their a
sol::state lua;
lua.new_usertype<B>("B",
"a_list", &B::a_list
);
"a_list", &B::a_list);
lua.safe_script(R"(
b = B.new()
@ -509,8 +499,10 @@ struct options {
return "";
}
void begin() {}
void end() {}
void begin() {
}
void end() {
}
~options() {
last = this;
@ -528,23 +520,21 @@ struct machine {
namespace sol {
template <>
struct is_container<options> : std::false_type {};
}
} // namespace sol
TEST_CASE("containers/is container", "make sure the is_container trait behaves properly") {
sol::state lua;
lua.open_libraries();
lua.new_usertype<options>("options_type",
"output_help", &options::output_help
);
"output_help", &options::output_help);
lua.new_usertype<machine>("machine_type",
"new", sol::no_constructor,
"opt", [](machine& m) { return &m.opt; },
"copy_opt", [](machine& m) { return m.opt; }
);
"copy_opt", [](machine& m) { return m.opt; });
{
{
machine m;
lua["machine"] = &m;
@ -572,11 +562,11 @@ TEST_CASE("containers/readonly", "make sure readonly members are stored appropri
lua.new_usertype<foo>(
"foo",
"seq", &foo::seq, // this one works
"readonly_seq", sol::readonly(&foo::seq) // this one does not work
);
lua["value"] = std::list<bar>{ {},{},{} };
"seq", &foo::seq, // this one works
"readonly_seq", sol::readonly(&foo::seq) // this one does not work
);
lua["value"] = std::list<bar>{ {}, {}, {} };
lua.safe_script(R"(
a = foo.new()
x = a.seq
@ -622,7 +612,6 @@ TEST_CASE("containers/to_args", "Test that the to_args abstractions works") {
REQUIRE(b == 10);
REQUIRE(c == 11);
REQUIRE(d == 12);
}
TEST_CASE("containers/ipairs test", "ensure that abstractions roundtrip properly") {
@ -661,7 +650,7 @@ TEST_CASE("containers/append idiom", "ensure the append-idiom works as intended"
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.safe_script(
R"(
R"(
function f_fill(vec)
print("#vec in lua: " .. #vec)
for k = 1, #vec do
@ -703,7 +692,9 @@ TEST_CASE("containers/non_copyable", "make sure non-copyable types in containers
struct test {
std::vector<non_copyable> b;
test() : b() {}
test()
: b() {
}
test(test&&) = default;
test& operator=(test&&) = default;
test(const test&) = delete;
@ -713,8 +704,7 @@ TEST_CASE("containers/non_copyable", "make sure non-copyable types in containers
SECTION("normal") {
sol::state lua;
lua.new_usertype<test>("test",
"b", sol::readonly(&test::b)
);
"b", sol::readonly(&test::b));
lua["v"] = std::vector<non_copyable>{};
@ -724,9 +714,8 @@ TEST_CASE("containers/non_copyable", "make sure non-copyable types in containers
SECTION("simple") {
sol::state lua;
lua.new_simple_usertype<test>("test",
"b", sol::readonly(&test::b)
);
"b", sol::readonly(&test::b));
lua["v"] = std::vector<non_copyable>{};
auto pfr = lua.safe_script("t = test.new()\nt.b = v", sol::script_pass_on_error);
@ -734,15 +723,18 @@ TEST_CASE("containers/non_copyable", "make sure non-copyable types in containers
}
}
TEST_CASE("containers/input iterators", "test shitty input iterators that are all kinds of B L E H") {
class int_shim {
public:
int_shim() = default;
int_shim(int x) : x_(x) {}
int_shim(int x)
: x_(x) {
}
int val() const { return x_; }
int val() const {
return x_;
}
private:
int x_ = -1;
@ -752,7 +744,8 @@ TEST_CASE("containers/input iterators", "test shitty input iterators that are al
public:
input_it() = default;
input_it(int n, int m) : n_(n), m_(m), value_(n_) {
input_it(int n, int m)
: n_(n), m_(m), value_(n_) {
assert(n_ >= 0);
assert(m_ >= 0);
assert(n_ <= m_);
@ -764,11 +757,15 @@ TEST_CASE("containers/input iterators", "test shitty input iterators that are al
}
}
const int_shim &operator*() const { return value_; }
const int_shim& operator*() const {
return value_;
}
const int_shim *operator->() const { return &value_; }
const int_shim* operator->() const {
return &value_;
}
input_it &operator++() {
input_it& operator++() {
assert(n_ >= 0);
assert(m_ >= 0);
if (n_ == m_ - 1) {
@ -781,9 +778,13 @@ TEST_CASE("containers/input iterators", "test shitty input iterators that are al
return *this;
}
bool operator==(const input_it &i) const { return n_ == i.n_ && m_ == i.m_; }
bool operator==(const input_it& i) const {
return n_ == i.n_ && m_ == i.m_;
}
bool operator!=(const input_it &i) const { return !(*this == i); }
bool operator!=(const input_it& i) const {
return !(*this == i);
}
private:
int n_ = -1;
@ -797,21 +798,27 @@ TEST_CASE("containers/input iterators", "test shitty input iterators that are al
using iterator = input_it;
using const_iterator = input_it;
const_iterator begin() const { return iterator(0, 100); }
const_iterator begin() const {
return iterator(0, 100);
}
const_iterator end() const { return iterator(); }
const_iterator end() const {
return iterator();
}
value_type gcc_warning_block() {
return int_shim();
}
std::size_t size() const { return 100; }
std::size_t size() const {
return 100;
}
};
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::package);
lua.new_usertype<int_shim>("int_shim",
"new", sol::no_constructor,
lua.new_usertype<int_shim>("int_shim",
"new", sol::no_constructor,
"val", &int_shim::val);
not_really_a_container c;
@ -839,9 +846,9 @@ TEST_CASE("containers/pairs", "test how well pairs work with the underlying syst
lua.open_libraries(sol::lib::base);
std::vector<std::pair<std::string, int>> a{ { "one", 1 },{ "two", 2 },{ "three", 3 },{ "four", 4 },{ "five", 5 } };
std::array<std::pair<std::string, int>, 5> b{ { { "one", 1 },{ "two", 2 },{ "three", 3 },{ "four", 4 },{ "five", 5 } } };
pair_arr_t c{ { "one", 1 },{ "two", 2 },{ "three", 3 },{ "four", 4 },{ "five", 5 } };
std::vector<std::pair<std::string, int>> a{ { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } };
std::array<std::pair<std::string, int>, 5> b{ { { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } } };
pair_arr_t c{ { "one", 1 }, { "two", 2 }, { "three", 3 }, { "four", 4 }, { "five", 5 } };
arr_t d = { 1, 2, 3, 4, 5 };
lua["a"] = std::ref(a);

View File

@ -144,8 +144,8 @@ co = nil
std::string identifier;
sol::reference obj;
co_test(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
co_test(sol::this_state L, std::string id)
: identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
@ -163,7 +163,6 @@ co = nil
}
~co_test() {
}
};
@ -174,9 +173,7 @@ co = nil
sol::constructors<co_test(sol::this_state, std::string)>(),
"store", &co_test::store,
"copy_store", &co_test::copy_store,
"get", &co_test::get
);
"get", &co_test::get);
auto r = lua.safe_script(code);
REQUIRE(r.valid());
@ -231,8 +228,8 @@ co = nil
std::string identifier;
sol::reference obj;
co_test_implicit(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
co_test_implicit(sol::this_state L, std::string id)
: identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
@ -250,7 +247,6 @@ co = nil
}
~co_test_implicit() {
}
};
@ -261,9 +257,7 @@ co = nil
sol::constructors<co_test_implicit(sol::this_state, std::string)>(),
"store", &co_test_implicit::store,
"copy_store", &co_test_implicit::copy_store,
"get", &co_test_implicit::get
);
"get", &co_test_implicit::get);
auto r = lua.safe_script(code);
REQUIRE(r.valid());
@ -317,8 +311,8 @@ collectgarbage()
std::string identifier;
sol::main_reference obj;
co_test_implicit(sol::this_state L, std::string id) : identifier(id), obj(L, sol::lua_nil) {
co_test_implicit(sol::this_state L, std::string id)
: identifier(id), obj(L, sol::lua_nil) {
}
void store(sol::table ref) {
@ -340,7 +334,6 @@ collectgarbage()
}
~co_test_implicit() {
}
};
@ -351,9 +344,7 @@ collectgarbage()
sol::constructors<co_test_implicit(sol::this_state, std::string)>(),
"store", &co_test_implicit::store,
"copy_store", &co_test_implicit::copy_store,
"get", &co_test_implicit::get
);
"get", &co_test_implicit::get);
auto r = lua.safe_script(code);
REQUIRE(r.valid());

View File

@ -42,7 +42,7 @@ namespace sol {
static two_things get(lua_State* L, int index, record& tracking) {
// Get the first element
int a = stack::get<int>(L, index);
// Get the second element,
// Get the second element,
// in the +1 position from the first
bool b = stack::get<bool>(L, index + 1);
// we use 2 slots, each of the previous takes 1
@ -61,8 +61,8 @@ namespace sol {
}
};
}
}
} // namespace stack
} // namespace sol
TEST_CASE("customization/split struct", "using the newly documented customization points to handle different kinds of classes") {
sol::state lua;
@ -80,7 +80,7 @@ TEST_CASE("customization/split struct", "using the newly documented customizatio
two_things thingsf = f(two_things{ 24, true }, 1);
two_things thingsg;
double d;
sol::tie( thingsg, d ) = g(two_things{ 25, false }, 2, 34.0);
sol::tie(thingsg, d) = g(two_things{ 25, false }, 2, 34.0);
REQUIRE(thingsf.a == 25);
REQUIRE(thingsf.b);

View File

@ -6,7 +6,6 @@
#include <iostream>
#include "test_stack_guard.hpp"
TEST_CASE("environments/get", "Envronments can be taken out of things like Lua functions properly") {
sol::state lua;
sol::stack_guard luasg(lua);
@ -28,11 +27,10 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
env_g.set_on(g);
g();
int test = env_g["test"];
REQUIRE(test == 5);
sol::object global_test = lua["test"];
REQUIRE(!global_test.valid());
@ -40,32 +38,29 @@ TEST_CASE("environments/get", "Envronments can be taken out of things like Lua f
lua.set_function("check_f_env",
[&lua, &env_f](sol::object target) {
sol::stack_guard sg(lua);
sol::environment target_env(sol::env_key, target);
int test_env_f = env_f["test"];
int test_target_env = target_env["test"];
REQUIRE(test_env_f == test_target_env);
REQUIRE(test_env_f == 31);
REQUIRE(env_f == target_env);
}
);
sol::stack_guard sg(lua);
sol::environment target_env(sol::env_key, target);
int test_env_f = env_f["test"];
int test_target_env = target_env["test"];
REQUIRE(test_env_f == test_target_env);
REQUIRE(test_env_f == 31);
REQUIRE(env_f == target_env);
});
lua.set_function("check_g_env",
[&lua, &env_g](sol::function target) {
sol::stack_guard sg(lua);
sol::environment target_env = sol::get_environment(target);
int test_env_g = env_g["test"];
int test_target_env = target_env["test"];
REQUIRE(test_env_g == test_target_env);
REQUIRE(test_env_g == 5);
REQUIRE(env_g == target_env);
}
);
sol::stack_guard sg(lua);
sol::environment target_env = sol::get_environment(target);
int test_env_g = env_g["test"];
int test_target_env = target_env["test"];
REQUIRE(test_env_g == test_target_env);
REQUIRE(test_env_g == 5);
REQUIRE(env_g == target_env);
});
lua.set_function("check_h_env",
[&lua](sol::function target) {
sol::stack_guard sg(lua);
sol::environment target_env = sol::get_environment(target);
}
);
sol::stack_guard sg(lua);
sol::environment target_env = sol::get_environment(target);
});
REQUIRE_NOTHROW([&lua]() {
lua.safe_script("check_f_env(f)");
@ -86,7 +81,7 @@ TEST_CASE("environments/shadowing", "Environments can properly shadow and fallba
sol::optional<int> maybe_global_a = lua["a"];
sol::optional<int> maybe_env_b = plain_env["b"];
sol::optional<int> maybe_global_b = lua["b"];
REQUIRE(maybe_env_a != sol::nullopt);
REQUIRE(maybe_env_a.value() == 24);
REQUIRE(maybe_env_b == sol::nullopt);
@ -205,7 +200,7 @@ TEST_CASE("environments/functions", "see if environments on functions are workin
TEST_CASE("environments/this_environment", "test various situations of pulling out an environment") {
static std::string code = "return (f(10))";
sol::state lua;
lua["f"] = [](sol::this_environment te, int x, sol::this_state ts) {
@ -216,7 +211,7 @@ TEST_CASE("environments/this_environment", "test various situations of pulling o
sol::state_view lua = ts;
return x + static_cast<int>(lua["x"]);
};
sol::environment e(lua, sol::create, lua.globals());
lua["x"] = 5;
e["x"] = 20;

View File

@ -33,8 +33,7 @@ TEST_CASE("filters/self", "ensure we return a direct reference to the lua userda
lua.new_usertype<vec2>("vec2",
"x", &vec2::x,
"y", &vec2::y,
"normalize", sol::filters(&vec2::normalize, sol::returns_self())
);
"normalize", sol::filters(&vec2::normalize, sol::returns_self()));
REQUIRE_NOTHROW([&]() {
lua.safe_script(R"(
v1 = vec2.new()
@ -47,7 +46,7 @@ assert(rawequal(v1, v2))
v1 = nil
collectgarbage()
print(v2) -- v2 points to same, is not destroyed
)");
)");
}());
}
@ -60,7 +59,8 @@ TEST_CASE("filters/self_dependency", "ensure we can keep a userdata instance ali
struct dep {
int value = 20;
~dep() {
std::cout << "\t" << "[C++] ~dep" << std::endl;
std::cout << "\t"
<< "[C++] ~dep" << std::endl;
value = std::numeric_limits<int>::max();
deps_destroyed.push_back(this);
}
@ -71,7 +71,8 @@ TEST_CASE("filters/self_dependency", "ensure we can keep a userdata instance ali
dep d;
~gc_test() {
std::cout << "\t" << "[C++] ~gc_test" << std::endl;
std::cout << "\t"
<< "[C++] ~gc_test" << std::endl;
gc_tests_destroyed.push_back(this);
}
};
@ -82,15 +83,13 @@ TEST_CASE("filters/self_dependency", "ensure we can keep a userdata instance ali
lua.new_usertype<dep>("dep",
"value", &dep::value,
sol::meta_function::to_string, [](dep& d) {
return "{ " + std::to_string(d.value) + " }";
}
);
return "{ " + std::to_string(d.value) + " }";
});
lua.new_usertype<gc_test>("gc_test",
"d", sol::filters(&gc_test::d, sol::self_dependency()),
sol::meta_function::to_string, [](gc_test& g) {
return "{ d: { " + std::to_string(g.d.value) + " } }";
}
);
return "{ d: { " + std::to_string(g.d.value) + " } }";
});
lua.safe_script(R"(
g = gc_test.new()
@ -157,7 +156,9 @@ TEST_CASE("filters/stack_dependencies", "ensure we can take dependencies even to
std::reference_wrapper<holder> href;
composition_related comp;
depends_on_reference(holder& h) : href(h) {}
depends_on_reference(holder& h)
: href(h) {
}
~depends_on_reference() {
std::cout << "[C++] ~depends_on_reference" << std::endl;
@ -169,12 +170,10 @@ TEST_CASE("filters/stack_dependencies", "ensure we can take dependencies even to
lua.open_libraries(sol::lib::base);
lua.new_usertype<holder>("holder",
"value", &holder::value
);
"value", &holder::value);
lua.new_usertype<depends_on_reference>("depends_on_reference",
"new", sol::filters(sol::constructors<depends_on_reference(holder&)>(), sol::stack_dependencies(-1, 1)),
"comp", &depends_on_reference::comp
);
"comp", &depends_on_reference::comp);
lua.safe_script(R"(
h = holder.new()

View File

@ -33,7 +33,10 @@ void takefn(std::function<int()> purr) {
}
struct A {
int a = 0xA; int bark() { return 1; }
int a = 0xA;
int bark() {
return 1;
}
};
std::tuple<int, int> bark(int num_value, A* a) {
@ -75,7 +78,7 @@ namespace sep {
INFO(x << " " << y << " " << z);
return 11;
}
}
} // namespace sep
int func_1(int) {
return 1;
@ -90,11 +93,14 @@ int func_2(int, int) {
}
void func_3(int, int, int) {
}
int f1(int) { return 32; }
int f2(int, int) { return 1; }
int f1(int) {
return 32;
}
int f2(int, int) {
return 1;
}
struct fer {
double f3(int, int) {
return 2.5;
@ -262,16 +268,14 @@ TEST_CASE("functions/sol::function to std::function", "check if conversion to st
lua.set_function("testFunc", test_free_func);
lua.set_function("testFunc2", test_free_func2);
lua.safe_script(
"testFunc(function() print(\"hello std::function\") end)"
);
"testFunc(function() print(\"hello std::function\") end)");
REQUIRE_NOTHROW(lua.safe_script(
"function m(a)\n"
" print(\"hello std::function with arg \", a)\n"
" return a\n"
"end\n"
"\n"
"testFunc2(m, 1)"
));
"testFunc2(m, 1)"));
}
TEST_CASE("functions/returning functions from C++", "check to see if returning a functor and getting a functor from lua is possible") {
@ -280,7 +284,8 @@ TEST_CASE("functions/returning functions from C++", "check to see if returning a
lua.set_function("makefn", makefn);
lua.set_function("takefn", takefn);
lua.safe_script("afx = makefn()\n"
lua.safe_script(
"afx = makefn()\n"
"print(afx())\n"
"takefn(afx)\n");
}
@ -314,8 +319,7 @@ TEST_CASE("functions/function_result and protected_function_result", "Function r
std::string("function luahandler ( message )")
+ " print('lua handler called with: ' .. message)"
+ " return '" + handlederrormessage + "'"
+ "end"
);
+ "end");
auto nontrampolinefx = [](lua_State*) -> int { throw "x"; };
lua_CFunction c_nontrampolinefx = nontrampolinefx;
lua.set("nontrampoline", c_nontrampolinefx);
@ -433,11 +437,9 @@ TEST_CASE("functions/all kinds", "Register all kinds of functions, make sure the
auto d = []() { return 503; };
lua.new_usertype<test_1>("test_1",
"bark", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>
);
"bark", sol::c_call<decltype(&test_1::bark_mem), &test_1::bark_mem>);
lua.new_usertype<test_2>("test_2",
"bark", sol::c_call<decltype(&test_2::bark), &test_2::bark>
);
"bark", sol::c_call<decltype(&test_2::bark), &test_2::bark>);
test_2 t2;
lua.set_function("a", a);
@ -473,7 +475,6 @@ I = i(o1)
I = i(o1)
)");
lua.safe_script(R"(
J0 = j()
j(24)
@ -492,7 +493,6 @@ l(o1, 678)
L1 = l(o1)
)");
lua.safe_script(R"(
M0 = m()
m(256)
@ -505,8 +505,7 @@ N = n(1, 2, 3)
int ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N;
std::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N)
= lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
);
"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N");
REQUIRE(ob == 0xA);
@ -537,8 +536,7 @@ N = n(1, 2, 3)
sol::tie(ob, A, B, C, D, F, G0, G1, H, I, J0, J1, K0, K1, L0, L1, M0, M1, N)
= lua.get<int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int>(
"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N"
);
"ob", "A", "B", "C", "D", "F", "G0", "G1", "H", "I", "J0", "J1", "K0", "K1", "L0", "L1", "M0", "M1", "N");
REQUIRE(ob == 0xA);
@ -593,10 +591,9 @@ N = n(1, 2, 3)
{
auto result = lua.safe_script("v(nested, inner)", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
}
}
TEST_CASE("simple/call with parameters", "Lua function is called with a few parameters from C++") {
sol::state lua;
@ -773,8 +770,7 @@ TEST_CASE("functions/overloading", "Check if overloading works properly for regu
"a = func(1)\n"
"b = func('bark')\n"
"c = func(1,2)\n"
"func(1,2,3)\n"
));
"func(1,2,3)\n"));
REQUIRE((lua["a"] == 1));
REQUIRE((lua["b"] == string_bark));
@ -842,13 +838,11 @@ TEST_CASE("functions/stack atomic", "make sure functions don't impede on the sta
sol::stack_guard opsg(lua);
sol::optional<std::string> opt_result = Stringtest("optional test");
REQUIRE(opsg.check_stack());
if (opt_result)
{
if (opt_result) {
std::string s = opt_result.value();
INFO("Back in C++, opt_result is : " << s);
}
else
{
else {
INFO("opt_result failed");
}
}
@ -1017,7 +1011,7 @@ TEST_CASE("functions/set_function already wrapped", "setting a function returned
sol::function fn = lua.safe_script("return function() return 5 end");
sol::protected_function pfn = fn;
std::function<int()> sfn = fn;
lua.set_function("test", fn);
lua.set_function("test2", pfn);
lua.set_function("test3", sfn);
@ -1054,7 +1048,6 @@ TEST_CASE("functions/set_function already wrapped", "setting a function returned
REQUIRE_NOTHROW(lua.safe_script("assert(type(test) == 'function')"));
REQUIRE_NOTHROW(lua.safe_script("assert(test() ~= nil)"));
REQUIRE_NOTHROW(lua.safe_script("assert(test() == 5)"));
}
SECTION("does the function actually get executed?") {
@ -1094,7 +1087,7 @@ TEST_CASE("functions/pointer nullptr + nil", "ensure specific semantics for hand
REQUIRE(p == nullptr);
}
};
std::shared_ptr<nil_test> sptr;
std::unique_ptr<nil_test> uptr;
std::unique_ptr<nil_test> ruptr;
@ -1256,10 +1249,14 @@ TEST_CASE("functions/pointer nullptr + nil", "ensure specific semantics for hand
}
TEST_CASE("functions/unique_usertype overloading", "make sure overloading can work with ptr vs. specifically asking for a unique_usertype") {
struct test {
struct test {
int special_value = 17;
test() : special_value(17) {}
test(int special_value) : special_value(special_value) {}
test()
: special_value(17) {
}
test(int special_value)
: special_value(special_value) {
}
};
auto print_up_test = [](std::unique_ptr<test>& x) {
REQUIRE(x->special_value == 21);
@ -1281,17 +1278,13 @@ TEST_CASE("functions/unique_usertype overloading", "make sure overloading can wo
};
using f_t = void(test&);
f_t* fptr = print_ref_test;
std::unique_ptr<test> ut = std::make_unique<test>(17);
SECTION("working") {
sol::state lua;
lua.set_function("f", print_up_test);
lua.set_function("g", sol::overload(
std::move(print_sp_test),
print_up_test,
std::ref(print_ptr_test)
));
lua.set_function("g", sol::overload(std::move(print_sp_test), print_up_test, std::ref(print_ptr_test)));
lua.set_function("h", std::ref(fptr));
lua.set_function("i", std::move(print_up_2_test));
@ -1350,15 +1343,15 @@ TEST_CASE("functions/noexcept", "allow noexcept functions to be serialized prope
return 0x61;
}
int noexcept_method() noexcept {
return 0x62;
int noexcept_method() noexcept {
return 0x62;
}
} t;
lua_CFunction ccall = sol::c_call<decltype(&raw_noexcept_function), &raw_noexcept_function>;
sol::state lua;
lua.set_function("f", &T::noexcept_function);
lua.set_function("g", &T::noexcept_method);
lua.set_function("h", &T::noexcept_method, T());

View File

@ -70,12 +70,18 @@ TEST_CASE("gc/virtual destructors", "ensure types with virtual destructions beha
class A {
public:
virtual ~A() { as.push_back(this); std::cout << "~A" << std::endl; }
virtual ~A() {
as.push_back(this);
std::cout << "~A" << std::endl;
}
};
class B : public A {
public:
virtual ~B() { bs.push_back(this); std::cout << "~B" << std::endl; }
virtual ~B() {
bs.push_back(this);
std::cout << "~B" << std::endl;
}
};
{
@ -99,7 +105,9 @@ TEST_CASE("gc/function argument storage", "ensure functions take references on t
class gc_entity {
public:
~gc_entity() { entities.push_back(this); }
~gc_entity() {
entities.push_back(this);
}
};
SECTION("plain") {
entities.clear();
@ -115,18 +123,17 @@ end
gc_entity e;
target = &e;
{
f(e); // same with std::ref(e)!
f(e); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
{
f(&e); // same with std::ref(e)!
f(&e); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
{
f(std::ref(e)); // same with std::ref(e)!
f(std::ref(e)); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
}
REQUIRE(entities.size() == 1);
REQUIRE(entities.back() == target);
@ -146,18 +153,17 @@ end
gc_entity e;
target = &e;
{
f(e); // same with std::ref(e)!
f(e); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
{
f(&e); // same with std::ref(e)!
f(&e); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
{
f(std::ref(e)); // same with std::ref(e)!
f(std::ref(e)); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
}
REQUIRE(entities.size() == 1);
REQUIRE(entities.back() == target);
@ -177,50 +183,80 @@ end
gc_entity e;
target = &e;
{
f(e); // same with std::ref(e)!
f(e); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
{
f(&e); // same with std::ref(e)!
f(&e); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
{
f(std::ref(e)); // same with std::ref(e)!
f(std::ref(e)); // same with std::ref(e)!
lua.collect_garbage(); // destroys e for some reason
}
}
REQUIRE(entities.size() == 1);
REQUIRE(entities.back() == target);
}
}
TEST_CASE("gc/function storage", "show that proper copies / destruction happens for function storage (or not)") {
static int created = 0;
static int destroyed = 0;
static void* last_call = nullptr;
static void* static_call = reinterpret_cast<void*>(0x01);
typedef void(*fptr)();
typedef void (*fptr)();
struct x {
x() { ++created; }
x(const x&) { ++created; }
x(x&&) { ++created; }
x& operator=(const x&) { return *this; }
x& operator=(x&&) { return *this; }
void func() { last_call = static_cast<void*>(this); };
~x() { ++destroyed; }
x() {
++created;
}
x(const x&) {
++created;
}
x(x&&) {
++created;
}
x& operator=(const x&) {
return *this;
}
x& operator=(x&&) {
return *this;
}
void func() {
last_call = static_cast<void*>(this);
};
~x() {
++destroyed;
}
};
struct y {
y() { ++created; }
y(const x&) { ++created; }
y(x&&) { ++created; }
y& operator=(const x&) { return *this; }
y& operator=(x&&) { return *this; }
static void func() { last_call = static_call; };
void operator()() { func(); }
operator fptr () { return func; }
~y() { ++destroyed; }
y() {
++created;
}
y(const x&) {
++created;
}
y(x&&) {
++created;
}
y& operator=(const x&) {
return *this;
}
y& operator=(x&&) {
return *this;
}
static void func() {
last_call = static_call;
};
void operator()() {
func();
}
operator fptr() {
return func;
}
~y() {
++destroyed;
}
};
// stateful functors/member functions should always copy unless specified
@ -274,7 +310,6 @@ TEST_CASE("gc/function storage", "show that proper copies / destruction happens
}
}
TEST_CASE("gc/same type closures", "make sure destructions are per-object, not per-type, by destroying one type multiple times") {
static std::set<void*> last_my_closures;
static bool checking_closures = false;
@ -283,7 +318,9 @@ TEST_CASE("gc/same type closures", "make sure destructions are per-object, not p
struct my_closure {
int& n;
my_closure(int& n) : n(n) {}
my_closure(int& n)
: n(n) {
}
~my_closure() noexcept(false) {
if (!checking_closures)
return;
@ -295,8 +332,9 @@ TEST_CASE("gc/same type closures", "make sure destructions are per-object, not p
last_my_closures.insert(f, addr);
}
int operator() () {
++n; return n;
int operator()() {
++n;
return n;
}
};
@ -318,12 +356,24 @@ TEST_CASE("gc/usertypes", "show that proper copies / destruction happens for use
static int created = 0;
static int destroyed = 0;
struct x {
x() { ++created; }
x(const x&) { ++created; }
x(x&&) { ++created; }
x& operator=(const x&) { return *this; }
x& operator=(x&&) { return *this; }
~x() { ++destroyed; }
x() {
++created;
}
x(const x&) {
++created;
}
x(x&&) {
++created;
}
x& operator=(const x&) {
return *this;
}
x& operator=(x&&) {
return *this;
}
~x() {
++destroyed;
}
};
SECTION("plain") {
created = 0;
@ -392,8 +442,12 @@ TEST_CASE("gc/usertypes", "show that proper copies / destruction happens for use
TEST_CASE("gc/double-deletion tests", "make sure usertypes are properly destructed and don't double-delete memory or segfault") {
class crash_class {
public:
crash_class() {}
~crash_class() { a = 10; }
crash_class() {
}
~crash_class() {
a = 10;
}
private:
int a;
};
@ -402,8 +456,7 @@ TEST_CASE("gc/double-deletion tests", "make sure usertypes are properly destruct
SECTION("regular") {
lua.new_usertype<crash_class>("CrashClass",
sol::call_constructor, sol::constructors<sol::types<>>()
);
sol::call_constructor, sol::constructors<sol::types<>>());
lua.safe_script(R"(
function testCrash()
@ -417,8 +470,7 @@ TEST_CASE("gc/double-deletion tests", "make sure usertypes are properly destruct
}
SECTION("simple") {
lua.new_simple_usertype<crash_class>("CrashClass",
sol::call_constructor, sol::constructors<sol::types<>>()
);
sol::call_constructor, sol::constructors<sol::types<>>());
lua.safe_script(R"(
function testCrash()
@ -455,10 +507,9 @@ TEST_CASE("gc/shared_ptr regression", "metatables should not screw over unique u
lua.new_usertype<test>("test",
"create", [&]() -> std::shared_ptr<test> {
tests.push_back(std::make_shared<test>());
return tests.back();
}
);
tests.push_back(std::make_shared<test>());
return tests.back();
});
REQUIRE(created == 0);
REQUIRE(destroyed == 0);
lua.safe_script("x = test.create()");
@ -483,10 +534,9 @@ TEST_CASE("gc/shared_ptr regression", "metatables should not screw over unique u
lua.new_simple_usertype<test>("test",
"create", [&]() -> std::shared_ptr<test> {
tests.push_back(std::make_shared<test>());
return tests.back();
}
);
tests.push_back(std::make_shared<test>());
return tests.back();
});
REQUIRE(created == 0);
REQUIRE(destroyed == 0);
lua.safe_script("x = test.create()");
@ -505,8 +555,12 @@ TEST_CASE("gc/shared_ptr regression", "metatables should not screw over unique u
TEST_CASE("gc/double deleter guards", "usertype metatables internally must not rely on C++ state") {
SECTION("regular") {
struct c_a { int xv; };
struct c_b { int yv; };
struct c_a {
int xv;
};
struct c_b {
int yv;
};
auto routine = []() {
sol::state lua;
lua.new_usertype<c_a>("c_a", "x", &c_a::xv);
@ -519,8 +573,12 @@ TEST_CASE("gc/double deleter guards", "usertype metatables internally must not r
REQUIRE_NOTHROW(routine());
}
SECTION("simple") {
struct sc_a { int xv; };
struct sc_b { int yv; };
struct sc_a {
int xv;
};
struct sc_b {
int yv;
};
auto routine = []() {
sol::state lua;
lua.new_simple_usertype<sc_a>("c_a", "x", &sc_a::xv);

View File

@ -28,19 +28,15 @@ TEST_CASE("inheritance/basic", "test that metatables are properly inherited") {
sol::state lua;
lua.new_usertype<A>("A",
"a", &A::a
);
"a", &A::a);
lua.new_usertype<B>("B",
"b", &B::b
);
"b", &B::b);
lua.new_usertype<C>("C",
"c", &C::c,
sol::base_classes, sol::bases<B, A>()
);
sol::base_classes, sol::bases<B, A>());
lua.new_usertype<D>("D",
"d", &D::d,
sol::base_classes, sol::bases<C, B, A>()
);
sol::base_classes, sol::bases<C, B, A>());
lua.safe_script("obj = D.new()");
lua.safe_script("d = obj:d()");
@ -61,32 +57,52 @@ TEST_CASE("inheritance/basic", "test that metatables are properly inherited") {
TEST_CASE("inheritance/multi base", "test that multiple bases all work and overloading for constructors works with them") {
class TestClass00 {
public:
int Thing() const { return 123; }
int Thing() const {
return 123;
}
};
class TestClass01 : public TestClass00 {
public:
TestClass01() : a(1) {}
TestClass01(const TestClass00& other) : a(other.Thing()) {}
TestClass01()
: a(1) {
}
TestClass01(const TestClass00& other)
: a(other.Thing()) {
}
int a;
};
class TestClass02 : public TestClass01 {
public:
TestClass02() : b(2) {}
TestClass02(const TestClass01& other) : b(other.a) {}
TestClass02(const TestClass00& other) : b(other.Thing()) {}
TestClass02()
: b(2) {
}
TestClass02(const TestClass01& other)
: b(other.a) {
}
TestClass02(const TestClass00& other)
: b(other.Thing()) {
}
int b;
};
class TestClass03 : public TestClass02 {
public:
TestClass03() : c(2) {}
TestClass03(const TestClass02& other) : c(other.b) {}
TestClass03(const TestClass01& other) : c(other.a) {}
TestClass03(const TestClass00& other) : c(other.Thing()) {}
TestClass03()
: c(2) {
}
TestClass03(const TestClass02& other)
: c(other.b) {
}
TestClass03(const TestClass01& other)
: c(other.a) {
}
TestClass03(const TestClass00& other)
: c(other.Thing()) {
}
int c;
};
@ -95,32 +111,28 @@ TEST_CASE("inheritance/multi base", "test that multiple bases all work and overl
sol::usertype<TestClass00> s_TestUsertype00(
sol::call_constructor, sol::constructors<sol::types<>>(),
"Thing", &TestClass00::Thing
);
"Thing", &TestClass00::Thing);
lua.set_usertype("TestClass00", s_TestUsertype00);
sol::usertype<TestClass01> s_TestUsertype01(
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass00&>>(),
sol::base_classes, sol::bases<TestClass00>(),
"a", &TestClass01::a
);
"a", &TestClass01::a);
lua.set_usertype("TestClass01", s_TestUsertype01);
sol::usertype<TestClass02> s_TestUsertype02(
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
sol::base_classes, sol::bases<TestClass01, TestClass00>(),
"b", &TestClass02::b
);
"b", &TestClass02::b);
lua.set_usertype("TestClass02", s_TestUsertype02);
sol::usertype<TestClass03> s_TestUsertype03(
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass02&>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
sol::base_classes, sol::bases<TestClass02, TestClass01, TestClass00>(),
"c", &TestClass03::c
);
"c", &TestClass03::c);
lua.set_usertype("TestClass03", s_TestUsertype03);
@ -156,66 +168,82 @@ tc3 = TestClass03(tc1)
TEST_CASE("inheritance/simple multi base", "test that multiple bases all work and overloading for constructors works with them") {
class TestClass00 {
public:
int Thing() const { return 123; }
int Thing() const {
return 123;
}
};
class TestClass01 : public TestClass00 {
public:
TestClass01() : a(1) {}
TestClass01(const TestClass00& other) : a(other.Thing()) {}
TestClass01()
: a(1) {
}
TestClass01(const TestClass00& other)
: a(other.Thing()) {
}
int a;
};
class TestClass02 : public TestClass01 {
public:
TestClass02() : b(2) {}
TestClass02(const TestClass01& other) : b(other.a) {}
TestClass02(const TestClass00& other) : b(other.Thing()) {}
TestClass02()
: b(2) {
}
TestClass02(const TestClass01& other)
: b(other.a) {
}
TestClass02(const TestClass00& other)
: b(other.Thing()) {
}
int b;
};
class TestClass03 : public TestClass02 {
public:
TestClass03() : c(2) {}
TestClass03(const TestClass02& other) : c(other.b) {}
TestClass03(const TestClass01& other) : c(other.a) {}
TestClass03(const TestClass00& other) : c(other.Thing()) {}
TestClass03()
: c(2) {
}
TestClass03(const TestClass02& other)
: c(other.b) {
}
TestClass03(const TestClass01& other)
: c(other.a) {
}
TestClass03(const TestClass00& other)
: c(other.Thing()) {
}
int c;
};
sol::state lua;
sol::simple_usertype<TestClass00> s_TestUsertype00( lua,
sol::simple_usertype<TestClass00> s_TestUsertype00(lua,
sol::call_constructor, sol::constructors<sol::types<>>(),
"Thing", &TestClass00::Thing
);
"Thing", &TestClass00::Thing);
lua.set_usertype("TestClass00", s_TestUsertype00);
sol::simple_usertype<TestClass01> s_TestUsertype01( lua,
sol::simple_usertype<TestClass01> s_TestUsertype01(lua,
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass00&>>(),
sol::base_classes, sol::bases<TestClass00>(),
"a", &TestClass01::a
);
"a", &TestClass01::a);
lua.set_usertype("TestClass01", s_TestUsertype01);
sol::simple_usertype<TestClass02> s_TestUsertype02( lua,
sol::simple_usertype<TestClass02> s_TestUsertype02(lua,
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
sol::base_classes, sol::bases<TestClass01, TestClass00>(),
"b", &TestClass02::b
);
"b", &TestClass02::b);
lua.set_usertype("TestClass02", s_TestUsertype02);
sol::simple_usertype<TestClass03> s_TestUsertype03( lua,
sol::simple_usertype<TestClass03> s_TestUsertype03(lua,
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const TestClass02&>, sol::types<const TestClass01&>, sol::types<const TestClass00&>>(),
sol::base_classes, sol::bases<TestClass02, TestClass01, TestClass00>(),
"c", &TestClass03::c
);
"c", &TestClass03::c);
lua.set_usertype("TestClass03", s_TestUsertype03);

View File

@ -60,7 +60,7 @@ TEST_CASE("large_integer/unsigned64", "pass too large unsigned 64bit value to lu
lua.set_function("f", [&](T num) -> T {
return num;
});
REQUIRE_THROWS([&lua](){
REQUIRE_THROWS([&lua]() {
sol::protected_function pf = lua["f"];
auto result = pf(0xFFFFFFFFFFFFFFFFull);
}());
@ -72,7 +72,7 @@ TEST_CASE("large_integer/double", "pass negative and large positive values as si
lua.set_function("s32", [&](std::int32_t num) {
return num;
});
lua.set_function("s64", [&](std::int64_t num) {
lua.set_function("s64", [&](std::int64_t num) {
return num;
});
lua.set_function("u32", [&](std::uint32_t num) {

View File

@ -12,14 +12,18 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
struct T {};
struct U {
int a;
U(int x = 20) : a(x) {}
U(int x = 20)
: a(x) {
}
bool operator==(const U& r) {
return a == r.a;
}
};
struct V {
int a;
V(int x = 20) : a(x) {}
V(int x = 20)
: a(x) {
}
bool operator==(const V& r) const {
return a == r.a;
}
@ -170,7 +174,7 @@ TEST_CASE("operators/default", "test that generic equality operators and all sor
TEST_CASE("operators/call", "test call operator generation") {
struct callable {
int operator ()(int a, std::string b) {
int operator()(int a, std::string b) {
return a + static_cast<int>(b.length());
}
};
@ -211,7 +215,7 @@ struct stringable {
};
const void* stringable::last_print_ptr = nullptr;
std::ostream& operator<< (std::ostream& ostr, const stringable& o) {
std::ostream& operator<<(std::ostream& ostr, const stringable& o) {
stringable::last_print_ptr = static_cast<const void*>(&o);
return ostr << "{ stringable, std::ostream! }";
}
@ -236,7 +240,7 @@ namespace inside {
adl_stringable2::last_print_ptr = static_cast<const void*>(&o);
return "{ inside::adl_stringable2, inside::to_string! }";
}
}
} // namespace inside
struct member_stringable {
static const void* last_print_ptr;
@ -451,8 +455,8 @@ TEST_CASE("operators/length", "test that size is automatically bound to the leng
}
SECTION("regular") {
lua.new_usertype<sizable>("sizable");
{
lua.safe_script("obj = sizable.new()");
{
lua.safe_script("obj = sizable.new()");
lua.safe_script("s = #obj");
std::size_t s = lua["s"];
REQUIRE(s == 6);

View File

@ -3,7 +3,6 @@
#include <catch.hpp>
#include <sol.hpp>
TEST_CASE("issues/stack overflow", "make sure various operations repeated don't trigger stack overflow") {
sol::state lua;
lua.safe_script("t = {};t[0]=20");
@ -11,15 +10,16 @@ TEST_CASE("issues/stack overflow", "make sure various operations repeated don't
sol::function f = lua["lua_function"];
std::string teststring = "testtext";
REQUIRE_NOTHROW([&]{
REQUIRE_NOTHROW([&] {
for (int i = 0; i < 1000000; ++i) {
std::string result = f(teststring);
if (result != teststring) throw std::logic_error("RIP");
if (result != teststring)
throw std::logic_error("RIP");
}
}());
sol::table t = lua["t"];
int expected = 20;
REQUIRE_NOTHROW([&]{
REQUIRE_NOTHROW([&] {
for (int i = 0; i < 1000000; ++i) {
int result = t[0];
t.size();
@ -29,7 +29,6 @@ TEST_CASE("issues/stack overflow", "make sure various operations repeated don't
}());
}
TEST_CASE("issues/stack overflow 2", "make sure basic iterators clean up properly when they're not iterated through (e.g., with empty())") {
sol::state lua;
sol::table t = lua.create_table_with(1, "wut");

View File

@ -36,9 +36,9 @@ TEST_CASE("plain/indestructible", "test that we error for types that are innatel
i->~indestructible();
}
};
private:
~indestructible() {
}
};
@ -61,10 +61,9 @@ TEST_CASE("plain/indestructible", "test that we error for types that are innatel
lua.new_usertype<indestructible>("indestructible",
sol::default_constructor,
sol::meta_function::garbage_collect, sol::destructor([](indestructible& i) {
indestructible::insider del;
del(&i);
})
);
indestructible::insider del;
del(&i);
}));
lua.safe_script("i = nil");
auto result = lua.safe_script("collectgarbage()", sol::script_pass_on_error);
REQUIRE(result.valid());

View File

@ -42,12 +42,11 @@ TEST_CASE("simple_usertype/usertypes", "Ensure that simple usertypes properly wo
lua.new_simple_usertype<bark>("bark",
"fun", &bark::fun,
"get", &bark::get,
"var", sol::as_function( &bark::var ),
"var", sol::as_function(&bark::var),
"the_marker", sol::as_function(&bark::the_marker),
"x", sol::overload(&bark::get),
"y", sol::overload(&bark::set),
"z", sol::overload(&bark::get, &bark::set)
);
"z", sol::overload(&bark::get, &bark::set));
lua.safe_script("b = bark.new()");
bark& b = lua["b"];
@ -95,8 +94,11 @@ TEST_CASE("simple_usertype/usertype constructors", "Ensure that calls with speci
int var = 50;
marker mark;
bark() {}
bark(int v) : var(v) {}
bark() {
}
bark(int v)
: var(v) {
}
void fun() {
var = 51;
@ -123,14 +125,13 @@ TEST_CASE("simple_usertype/usertype constructors", "Ensure that calls with speci
sol::state lua;
lua.new_simple_usertype<bark>("bark",
sol::constructors<sol::types<>, sol::types<int>>(),
"fun", sol::protect( &bark::fun ),
"fun", sol::protect(&bark::fun),
"get", &bark::get,
"var", sol::as_function( &bark::var ),
"var", sol::as_function(&bark::var),
"the_marker", &bark::the_marker,
"x", sol::overload(&bark::get),
"y", sol::overload(&bark::set),
"z", sol::overload(&bark::get, &bark::set)
);
"z", sol::overload(&bark::get, &bark::set));
lua.safe_script("bx = bark.new(760)");
bark& bx = lua["bx"];
@ -185,9 +186,8 @@ TEST_CASE("simple_usertype/vars", "simple usertype vars can bind various values
"straight", sol::var(2),
"global", sol::var(muh_variable),
"global2", sol::var(through_variable),
"global3", sol::var(std::ref(through_variable))
);
"global3", sol::var(std::ref(through_variable)));
through_variable = 20;
lua.safe_script(R"(
@ -214,22 +214,28 @@ g3 = test.global3
TEST_CASE("simple_usertype/variable-control", "test to see if usertypes respond to inheritance and variable controls") {
class A {
public:
virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
virtual void a() {
throw std::runtime_error("entered base pure virtual implementation");
};
};
class B : public A {
public:
virtual void a() override { }
virtual void a() override {
}
};
class sA {
public:
virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
virtual void a() {
throw std::runtime_error("entered base pure virtual implementation");
};
};
class sB : public sA {
public:
virtual void a() override { }
virtual void a() override {
}
};
struct sV {
@ -287,14 +293,18 @@ TEST_CASE("simple_usertype/variable-control", "test to see if usertypes respond
TEST_CASE("simple_usertype/factory constructor overloads", "simple usertypes should invoke the proper factories") {
class A {
public:
virtual void a() { throw std::runtime_error("entered base pure virtual implementation"); };
virtual void a() {
throw std::runtime_error("entered base pure virtual implementation");
};
};
class B : public A {
public:
int bvar = 24;
virtual void a() override { }
void f() {}
virtual void a() override {
}
void f() {
}
};
sol::state lua;
@ -302,20 +312,13 @@ TEST_CASE("simple_usertype/factory constructor overloads", "simple usertypes sho
sol::constructors<sol::types<>, sol::types<const B&>> c;
lua.new_simple_usertype<B>("B",
sol::call_constructor, c,
"new", sol::factories([]() {
return B();
"new", sol::factories([]() {
return B();
}),
"new2", sol::initializers(
[](B& mem) {
new(&mem)B();
},
[](B& mem, int v) {
new(&mem)B(); mem.bvar = v;
}
),
"new2", sol::initializers([](B& mem) { new (&mem) B(); }, [](B& mem, int v) {
new(&mem)B(); mem.bvar = v; }),
"f", sol::as_function(&B::bvar),
"g", sol::overload([](B&) { return 2; }, [](B&, int v) { return v; })
);
"g", sol::overload([](B&) { return 2; }, [](B&, int v) { return v; }));
lua.safe_script("b = B()");
lua.safe_script("b2 = B.new()");
@ -369,7 +372,7 @@ TEST_CASE("simple_usertype/runtime append", "allow extra functions to be appende
int y = lua["y"];
REQUIRE(x == 200);
REQUIRE(y == 200);
lua.safe_script("z = b.method2(b)");
lua.safe_script("w = b:method2()");
int z = lua["z"];
@ -395,7 +398,7 @@ TEST_CASE("simple_usertype/table append", "Ensure that appending to the meta tab
lua.set("a", &a);
lua.set("pa", &a);
lua.set("ua", std::make_unique<A>());
REQUIRE_NOTHROW([&]{
REQUIRE_NOTHROW([&] {
lua.safe_script("assert(a:func() == 5000)");
lua.safe_script("assert(pa:func() == 5000)");
lua.safe_script("assert(ua:func() == 5000)");
@ -406,7 +409,9 @@ TEST_CASE("simple_usertype/class call propogation", "make sure methods and varia
class A {
public:
int var = 200;
int thing() const { return 123; }
int thing() const {
return 123;
}
};
class B : public A {
@ -418,8 +423,7 @@ TEST_CASE("simple_usertype/class call propogation", "make sure methods and varia
lua.new_simple_usertype<B>("B",
sol::default_constructor,
"thing", &B::thing,
"var", &B::var
);
"var", &B::var);
lua.safe_script(R"(
b = B.new()
@ -431,40 +435,45 @@ TEST_CASE("simple_usertype/class call propogation", "make sure methods and varia
TEST_CASE("simple_usertype/call constructor", "ensure that all kinds of call-based constructors can be serialized") {
struct thing {};
struct v_test {
};
struct f_test {
int i; f_test(int i) : i(i) {}
int i;
f_test(int i)
: i(i) {
}
};
struct i_test {
int i; i_test(int i) : i(i) {}
int i;
i_test(int i)
: i(i) {
}
};
struct r_test {
int i; r_test(int i) : i(i) {}
int i;
r_test(int i)
: i(i) {
}
};
sol::state lua;
lua.open_libraries(sol::lib::base);
auto f = sol::factories([]() {return f_test(30); });
auto f = sol::factories([]() { return f_test(30); });
lua.new_simple_usertype<f_test>("f_test",
sol::call_constructor, sol::factories([]() {
return f_test(20);
}),
"new", f
);
"new", f);
lua.new_simple_usertype<i_test>("i_test",
sol::call_constructor, sol::initializers([](i_test& obj) {
new(&obj)i_test(21);
})
);
new (&obj) i_test(21);
}));
lua.new_simple_usertype<r_test>("r_test",
sol::call_constructor, [](sol::table) {
return r_test(22);
}
);
return r_test(22);
});
lua.safe_script("a = f_test()");
lua.safe_script("b = i_test()");
@ -486,13 +495,11 @@ TEST_CASE("simple_usertype/call constructor", "ensure that all kinds of call-bas
REQUIRE(v.second.is<thing>());
}
return v_test();
}
);
});
lua.new_simple_usertype<v_test>("v_test",
sol::meta_function::construct, vfactories,
sol::call_constructor, vfactories
);
sol::call_constructor, vfactories);
lua.new_simple_usertype<thing>("thing");
lua.safe_script("things = {thing.new(), thing.new()}");
@ -513,8 +520,7 @@ TEST_CASE("simple_usertype/no_constructor", "make sure simple usertype errors wh
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<thing>("thing",
sol::meta_function::construct, sol::no_constructor
);
sol::meta_function::construct, sol::no_constructor);
auto result = lua.safe_script("a = thing.new()", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -524,11 +530,10 @@ TEST_CASE("simple_usertype/no_constructor", "make sure simple usertype errors wh
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<thing>("thing",
sol::call_constructor, sol::no_constructor
);
sol::call_constructor, sol::no_constructor);
auto result = lua.safe_script("a = thing()", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
}
}
TEST_CASE("simple_usertype/missing key", "make sure a missing key returns nil") {
@ -544,7 +549,9 @@ TEST_CASE("simple_usertype/missing key", "make sure a missing key returns nil")
TEST_CASE("simple_usertype/runtime extensibility", "Check if usertypes are runtime extensible") {
struct thing {
int v = 20;
int func(int a) { return a; }
int func(int a) {
return a;
}
};
int val = 0;
@ -553,8 +560,7 @@ TEST_CASE("simple_usertype/runtime extensibility", "Check if usertypes are runti
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<thing>("thing",
"func", &thing::func
);
"func", &thing::func);
lua.safe_script(R"(
t = thing.new()
@ -565,7 +571,8 @@ t = thing.new()
t.runtime_func = function (a)
return a + 50
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -574,7 +581,8 @@ end
function t:runtime_func(a)
return a + 52
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -600,8 +608,7 @@ end
lua.new_simple_usertype<thing>("thing",
"func", &thing::func,
"v", &thing::v
);
"v", &thing::v);
lua.safe_script(R"(
t = thing.new()
@ -612,7 +619,8 @@ t = thing.new()
t.runtime_func = function (a)
return a + 50
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -621,7 +629,8 @@ end
function t:runtime_func(a)
return a + 52
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}());
@ -646,7 +655,8 @@ end
TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") {
struct heart_base_t {};
struct heart_t : heart_base_t {
void func() {}
void func() {
}
};
SECTION("plain") {
@ -675,8 +685,7 @@ TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be p
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<heart_t>("a",
sol::base_classes, sol::bases<heart_base_t>()
);
sol::base_classes, sol::bases<heart_base_t>());
REQUIRE_NOTHROW([&lua]() {
lua.safe_script("obj = a.new()");
@ -700,8 +709,7 @@ TEST_CASE("simple_usertype/runtime replacement", "ensure that functions can be p
lua.new_simple_usertype<heart_t>("a",
"func", &heart_t::func,
sol::base_classes, sol::bases<heart_base_t>()
);
sol::base_classes, sol::bases<heart_base_t>());
REQUIRE_NOTHROW([&lua]() {
lua.safe_script("obj = a.new()");
@ -740,7 +748,6 @@ TEST_CASE("simple_usertype/meta key retrievals", "allow for special meta keys (_
s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo;
lua["var"] = s;
lua.safe_script("var = sample.new()");
lua.safe_script("var.key = 2");
lua.safe_script("var.__newindex = 4");
@ -770,7 +777,7 @@ TEST_CASE("simple_usertype/meta key retrievals", "allow for special meta keys (_
sol::state lua;
lua.new_simple_usertype<sample>("sample", sol::meta_function::new_index, &sample::foo);
lua.safe_script("var = sample.new()");
lua.safe_script("var.key = 2");
lua.safe_script("var.__newindex = 4");
@ -808,8 +815,7 @@ TEST_CASE("simple_usertype/static properties", "allow for static functions to ge
lua.new_simple_usertype<test_t>("test",
"f", std::function<std::size_t()>(std::bind(std::mem_fn(&test_t::func), &manager)),
"g", sol::property(&test_t::s_func, &test_t::g_func)
);
"g", sol::property(&test_t::s_func, &test_t::g_func));
lua.safe_script("v1 = test.f()");
lua.safe_script("v2 = test.g");
@ -825,10 +831,12 @@ TEST_CASE("simple_usertype/static properties", "allow for static functions to ge
TEST_CASE("simple_usertype/indexing", "make sure simple usertypes can be indexed/new_indexed properly without breaking") {
static int val = 0;
class indexing_test {
public:
indexing_test() { val = 0; }
indexing_test() {
val = 0;
}
sol::object getter(const std::string& name, sol::this_state _s) {
REQUIRE(name == "a");
@ -851,8 +859,7 @@ TEST_CASE("simple_usertype/indexing", "make sure simple usertypes can be indexed
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<indexing_test>("test",
sol::meta_function::index, &indexing_test::getter,
sol::meta_function::new_index, &indexing_test::setter
);
sol::meta_function::new_index, &indexing_test::setter);
lua.safe_script(R"(
local t = test.new()
@ -869,8 +876,7 @@ TEST_CASE("simple_usertype/indexing", "make sure simple usertypes can be indexed
lua.open_libraries(sol::lib::base);
lua.new_simple_usertype<indexing_test>("test",
sol::meta_function::index, &indexing_test::getter,
sol::meta_function::new_index, &indexing_test::setter
);
sol::meta_function::new_index, &indexing_test::setter);
lua["test"]["hi"] = [](indexing_test& _self) -> int { return _self.hi(); };

View File

@ -4,8 +4,11 @@ struct test_stack_guard {
lua_State* L;
int& begintop;
int& endtop;
test_stack_guard(lua_State* L, int& begintop, int& endtop) : L(L), begintop(begintop), endtop(endtop) {
test_stack_guard(lua_State* L, int& begintop, int& endtop)
: L(L), begintop(begintop), endtop(endtop) {
begintop = lua_gettop(L);
}
~test_stack_guard() { endtop = lua_gettop(L); }
~test_stack_guard() {
endtop = lua_gettop(L);
}
};

View File

@ -39,6 +39,26 @@ struct write_file_attempt_object {
}
};
struct string_reader_load {
const std::string& str;
std::size_t reads;
string_reader_load(const std::string& s)
: str(s), reads(0) {
}
};
const char* string_reader(lua_State* L, void* vpstr, size_t* sz) {
(void)L;
string_reader_load& srl = *static_cast<string_reader_load*>(vpstr);
if (srl.reads++ > 0) {
*sz = 0;
return NULL;
}
*sz = static_cast<size_t>(srl.str.size());
return srl.str.c_str();
}
TEST_CASE("state/require_file", "opening files as 'requires'") {
static const char file_require_file[] = "./tmp_thingy.lua";
static const char file_require_file_user[] = "./tmp_thingy_user.lua";
@ -57,9 +77,11 @@ TEST_CASE("state/require_file", "opening files as 'requires'") {
std::remove(file_require_file_user);
};
SECTION("with usertypes") {
SECTION("with usertypes") {
struct foo {
foo(int bar) : bar(bar) {}
foo(int bar)
: bar(bar) {
}
const int bar;
};
@ -69,8 +91,7 @@ TEST_CASE("state/require_file", "opening files as 'requires'") {
lua.new_usertype<foo>("foo",
sol::constructors<sol::types<int>>{},
"bar", &foo::bar
);
"bar", &foo::bar);
const sol::table thingy1 = lua.require_file("thingy", file_require_file_user);
@ -140,7 +161,7 @@ TEST_CASE("state/require", "require using a function") {
REQUIRE(val2 == 221);
// THIS IS ONLY REQUIRED IN LUA 5.3, FOR SOME REASON
// must have loaded the same table
// REQUIRE(thingy1 == thingy2);
// REQUIRE(thingy1 == thingy2);
}
TEST_CASE("state/multi require", "make sure that requires transfers across hand-rolled script implementation and standard requiref") {
@ -347,7 +368,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
std::call_once(flag_file_g, write_file_attempt_object(), file_good, good);
auto clean_files = []() {
if (finished.fetch_add(1) < 10) {
if (finished.fetch_add(1) < 14) {
return;
}
std::remove(file_bad_syntax);
@ -412,7 +433,7 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
sol::stack_guard sg(lua);
auto errbsload = lua.load(bad_syntax);
REQUIRE(!errbsload.valid());
sol::load_result errbrload = lua.load(bad_runtime);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
@ -430,6 +451,87 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
REQUIRE(ar == 21);
clean_files();
}
SECTION("load") {
sol::state lua;
sol::stack_guard sg(lua);
string_reader_load bssrl(bad_syntax);
void* vpbssrl = static_cast<void*>(&bssrl);
auto errbsload = lua.load(&string_reader, vpbssrl, bad_syntax);
REQUIRE(!errbsload.valid());
string_reader_load brsrl(bad_runtime);
void* vpbrsrl = static_cast<void*>(&brsrl);
sol::load_result errbrload = lua.load(&string_reader, vpbrsrl, bad_runtime);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
string_reader_load gsrl(good);
void* vpgsrl = static_cast<void*>(&gsrl);
sol::load_result resultload = lua.load(&string_reader, vpgsrl, good);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
auto result = resultpf();
int a = lua["a"];
int ar = result;
REQUIRE(result.valid());
REQUIRE(a == 21);
REQUIRE(ar == 21);
clean_files();
}
SECTION("load_string (text)") {
sol::state lua;
sol::stack_guard sg(lua);
auto errbsload = lua.load(bad_syntax, bad_syntax, sol::load_mode::text);
REQUIRE(!errbsload.valid());
sol::load_result errbrload = lua.load(bad_runtime, bad_runtime, sol::load_mode::text);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
sol::load_result resultload = lua.load(good, good, sol::load_mode::text);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
auto result = resultpf();
int a = lua["a"];
int ar = result;
REQUIRE(result.valid());
REQUIRE(a == 21);
REQUIRE(ar == 21);
clean_files();
}
SECTION("load (text)") {
sol::state lua;
sol::stack_guard sg(lua);
string_reader_load bssrl(bad_syntax);
void* vpbssrl = static_cast<void*>(&bssrl);
auto errbsload = lua.load(&string_reader, vpbssrl, bad_syntax, sol::load_mode::text);
REQUIRE(!errbsload.valid());
string_reader_load brsrl(bad_runtime);
void* vpbrsrl = static_cast<void*>(&brsrl);
sol::load_result errbrload = lua.load(&string_reader, vpbrsrl, bad_runtime, sol::load_mode::text);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
string_reader_load gsrl(good);
void* vpgsrl = static_cast<void*>(&gsrl);
sol::load_result resultload = lua.load(&string_reader, vpgsrl, good, sol::load_mode::text);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
auto result = resultpf();
int a = lua["a"];
int ar = result;
REQUIRE(result.valid());
REQUIRE(a == 21);
REQUIRE(ar == 21);
clean_files();
}
SECTION("script_file") {
sol::state lua;
sol::stack_guard sg(lua);
@ -522,6 +624,29 @@ TEST_CASE("state/script, do, and load", "test success and failure cases for load
REQUIRE(ar == 21);
clean_files();
}
SECTION("load_file (text)") {
sol::state lua;
sol::stack_guard sg(lua);
auto errbsload = lua.load_file(file_bad_syntax, sol::load_mode::text);
REQUIRE(!errbsload.valid());
sol::load_result errbrload = lua.load_file(file_bad_runtime, sol::load_mode::text);
REQUIRE(errbrload.valid());
sol::protected_function errbrpf = errbrload;
auto errbr = errbrpf();
REQUIRE(!errbr.valid());
sol::load_result resultload = lua.load_file(file_good, sol::load_mode::text);
REQUIRE(resultload.valid());
sol::protected_function resultpf = resultload;
auto result = resultpf();
int a = lua["a"];
int ar = result;
REQUIRE(result.valid());
REQUIRE(a == 21);
REQUIRE(ar == 21);
clean_files();
}
}
TEST_CASE("state/script return converts", "make sure that script return values are convertable from one to another") {

View File

@ -14,8 +14,8 @@ namespace muh_namespace {
namespace {
struct ns_anon_test {};
}
}
} // namespace
} // namespace muh_namespace
// There isn't a single library roundtripping which codecvt works on. We'll do the nitty-gritty of it later...
TEST_CASE("stack/strings", "test that strings can be roundtripped") {
@ -57,7 +57,7 @@ TEST_CASE("stack/strings", "test that strings can be roundtripped") {
REQUIRE(utf16_to_utf8 == utf8str_s);
REQUIRE(utf32_to_utf8 == utf8str_s);
REQUIRE(wide_to_utf8 == utf8str_s);
std::wstring utf8_to_wide = lua["utf8"];
std::wstring utf16_to_wide = lua["utf16"];
std::wstring utf32_to_wide = lua["utf32"];

View File

@ -16,7 +16,7 @@ std::string free_function() {
}
struct object {
std::string operator() () {
std::string operator()() {
INFO("member_test()");
return "test";
}
@ -34,7 +34,7 @@ TEST_CASE("tables/as enums", "Making sure enums can be put in and gotten out as
left,
right
};
sol::state lua;
lua.open_libraries(sol::lib::base);
@ -42,8 +42,7 @@ TEST_CASE("tables/as enums", "Making sure enums can be put in and gotten out as
"up", direction::up,
"down", direction::down,
"left", direction::left,
"right", direction::right
);
"right", direction::right);
sol::object obj = lua["direction"]["up"];
bool isdir = obj.is<direction>();
@ -67,8 +66,7 @@ TEST_CASE("tables/as enum classes", "Making sure enums can be put in and gotten
"up", direction::up,
"down", direction::down,
"left", direction::left,
"right", direction::right
);
"right", direction::right);
sol::object obj = lua["direction"]["up"];
bool isdir = obj.is<direction>();
@ -129,8 +127,7 @@ TEST_CASE("tables/new_enum", "Making sure enums can be put in and gotten out as
"up", direction::up,
"down", direction::down,
"left", direction::left,
"right", direction::right
);
"right", direction::right);
direction d = lua["direction"]["left"];
REQUIRE(d == direction::left);
@ -143,12 +140,7 @@ TEST_CASE("tables/new_enum", "Making sure enums can be put in and gotten out as
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_enum<direction>("direction", {
{ "up", direction::up },
{ "down", direction::down },
{ "left", direction::left },
{ "right", direction::right }
} );
lua.new_enum<direction>("direction", { { "up", direction::up }, { "down", direction::down }, { "left", direction::left }, { "right", direction::right } });
direction d = lua["direction"]["left"];
REQUIRE(d == direction::left);
@ -163,7 +155,8 @@ TEST_CASE("tables/for_each", "Testing the use of for_each to get values from a l
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.safe_script("arr = {\n"
lua.safe_script(
"arr = {\n"
"[0] = \"Hi\",\n"
"[1] = 123.45,\n"
"[2] = \"String value\",\n"
@ -277,7 +270,8 @@ TEST_CASE("tables/iterators", "Testing the use of iteratrs to get values from a
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.safe_script("arr = {\n"
lua.safe_script(
"arr = {\n"
"[0] = \"Hi\",\n"
"[1] = 123.45,\n"
"[2] = \"String value\",\n"
@ -328,7 +322,8 @@ TEST_CASE("tables/iterators", "Testing the use of iteratrs to get values from a
}
}(kvp.first, kvp.second);
}
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
REQUIRE(iterations == tablesize);
}
@ -393,10 +388,9 @@ TEST_CASE("tables/function variables", "Check if tables and function calls work
lua.get<sol::table>("os").set_function("fun",
[]() {
INFO("stateless lambda()");
return "test";
}
);
INFO("stateless lambda()");
return "test";
});
REQUIRE_NOTHROW(run_script(lua));
lua.get<sol::table>("os").set_function("fun", &free_function);
@ -414,15 +408,13 @@ TEST_CASE("tables/function variables", "Check if tables and function calls work
lua.get<sol::table>("os").set_function("fun", &object::operator(), std::ref(reflval));
REQUIRE_NOTHROW(run_script(lua));
// stateful lambda: non-convertible, cannot be optimised
int breakit = 50;
lua.get<sol::table>("os").set_function("fun",
[&breakit]() {
INFO("stateful lambda()");
return "test";
}
);
INFO("stateful lambda()");
return "test";
});
REQUIRE_NOTHROW(run_script(lua));
// r-value, cannot optimise
@ -573,8 +565,7 @@ TEST_CASE("tables/raw set and raw get", "ensure raw setting and getting works th
sol::table t = lua.create_table();
t[sol::metatable_key] = lua.create_table_with(
sol::meta_function::new_index, [](lua_State* L) { return luaL_error(L, "nay"); },
sol::meta_function::index, [](lua_State* L) { return luaL_error(L, "nay"); }
);
sol::meta_function::index, [](lua_State* L) { return luaL_error(L, "nay"); });
t.raw_set("a", 2.5);
double la = t.raw_get<double>("a");
REQUIRE(la == 2.5);

View File

@ -7,7 +7,6 @@
#include <list>
#include <memory>
struct non_copyable {
non_copyable() = default;
non_copyable(const non_copyable&) = delete;
@ -18,21 +17,23 @@ struct non_copyable {
struct vars {
vars() {
}
int boop = 0;
~vars() {
}
};
struct fuser {
int x;
fuser() : x(0) {}
fuser()
: x(0) {
}
fuser(int x) : x(x) {}
fuser(int x)
: x(x) {
}
int add(int y) {
return x + y;
@ -46,9 +47,15 @@ struct fuser {
namespace crapola {
struct fuser {
int x;
fuser() : x(0) {}
fuser(int x) : x(x) {}
fuser(int x, int x2) : x(x * x2) {}
fuser()
: x(0) {
}
fuser(int x)
: x(x) {
}
fuser(int x, int x2)
: x(x * x2) {
}
int add(int y) {
return x + y;
@ -57,11 +64,13 @@ namespace crapola {
return x + y + 2;
}
};
} // crapola
} // namespace crapola
class Base {
public:
Base(int a_num) : m_num(a_num) { }
Base(int a_num)
: m_num(a_num) {
}
int get_num() {
return m_num;
@ -73,7 +82,9 @@ protected:
class Derived : public Base {
public:
Derived(int a_num) : Base(a_num) { }
Derived(int a_num)
: Base(a_num) {
}
int get_num_10() {
return 10 * m_num;
@ -94,13 +105,15 @@ public:
struct Vec {
float x, y, z;
Vec(float x, float y, float z) : x{ x }, y{ y }, z{ z } {}
Vec(float x, float y, float z)
: x{ x }, y{ y }, z{ z } {
}
float length() {
return sqrtf(x*x + y*y + z*z);
return sqrtf(x * x + y * y + z * z);
}
Vec normalized() {
float invS = 1 / length();
return{ x * invS, y * invS, z * invS };
return { x * invS, y * invS, z * invS };
}
};
@ -108,7 +121,6 @@ struct giver {
int a = 0;
giver() {
}
void gief() {
@ -116,7 +128,6 @@ struct giver {
}
static void stuff() {
}
static void gief_stuff(giver& t, int a) {
@ -124,15 +135,18 @@ struct giver {
}
~giver() {
}
};
struct factory_test {
private:
factory_test() { a = true_a; }
~factory_test() { a = 0; }
factory_test() {
a = true_a;
}
~factory_test() {
a = 0;
}
public:
static int num_saved;
static int num_killed;
@ -151,7 +165,7 @@ public:
}
static void save(factory_test& f) {
new(&f)factory_test();
new (&f) factory_test();
++num_saved;
}
@ -172,15 +186,18 @@ bool something() {
struct thing {
int v = 100;
thing() {}
thing(int x) : v(x) {}
thing() {
}
thing(int x)
: v(x) {
}
};
struct self_test {
int bark;
self_test() : bark(100) {
self_test()
: bark(100) {
}
void g(const std::string& str) {
@ -203,13 +220,14 @@ struct ext_getset {
const int meow = 56;
ext_getset() = default;
ext_getset(int v) : bark(v) {}
ext_getset(int v)
: bark(v) {
}
ext_getset(ext_getset&&) = default;
ext_getset(const ext_getset&) = delete;
ext_getset& operator=(ext_getset&&) = default;
ext_getset& operator=(const ext_getset&) = delete;
~ext_getset() {
}
std::string x() {
@ -229,13 +247,11 @@ struct ext_getset {
}
static void s_set(int) {
}
static int s_get(int x) {
return x + 20;
}
};
template <typename T>
@ -271,7 +287,8 @@ TEST_CASE("usertype/usertype", "Show that we can create classes from usertype an
sol::usertype<fuser> lc{ "add", &fuser::add, "add2", &fuser::add2 };
lua.set_usertype(lc);
lua.safe_script("a = fuser:new()\n"
lua.safe_script(
"a = fuser:new()\n"
"b = a:add(1)\n"
"c = a:add2(1)\n");
@ -339,7 +356,8 @@ TEST_CASE("usertype/usertype-utility", "Show internal management of classes regi
lua.new_usertype<fuser>("fuser", "add", &fuser::add, "add2", &fuser::add2);
lua.safe_script("a = fuser.new()\n"
lua.safe_script(
"a = fuser.new()\n"
"b = a:add(1)\n"
"c = a:add2(1)\n");
@ -373,15 +391,16 @@ TEST_CASE("usertype/usertype-utility-derived", "usertype classes must play nice
sol::constructors<sol::types<int>> derivedctor;
sol::usertype<Derived> derivedusertype(derivedctor,
"get_num_10", &Derived::get_num_10,
"get_num", &Derived::get_num
);
"get_num", &Derived::get_num);
lua.set_usertype(derivedusertype);
lua.safe_script("derived = Derived.new(7)");
lua.safe_script("dgn = derived:get_num()\n"
lua.safe_script(
"dgn = derived:get_num()\n"
"print(dgn)");
lua.safe_script("dgn10 = derived:get_num_10()\n"
lua.safe_script(
"dgn10 = derived:get_num_10()\n"
"print(dgn10)");
REQUIRE((lua.get<int>("dgn10") == 70));
@ -397,8 +416,7 @@ TEST_CASE("usertype/self-referential usertype", "usertype classes must play nice
lua.safe_script(
"local a = test.new()\n"
"a:g(\"woof\")\n"
"a:f(a)\n"
);
"a:f(a)\n");
}
TEST_CASE("usertype/issue-number-twenty-five", "Using pointers and references from C++ classes in Lua") {
@ -449,9 +467,11 @@ TEST_CASE("usertype/issue-number-thirty-five", "using value types created from l
sol::usertype<Vec> udata(ctor, "normalized", &Vec::normalized, "length", &Vec::length);
lua.set_usertype(udata);
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
REQUIRE_NOTHROW(lua.safe_script(
"v = Vec.new(1, 2, 3)\n"
"print(v:length())"));
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
REQUIRE_NOTHROW(lua.safe_script(
"v = Vec.new(1, 2, 3)\n"
"print(v:normalized():length())"));
}
@ -469,11 +489,13 @@ TEST_CASE("usertype/lua-stored-usertype", "ensure usertype values can be stored
// usertype dies, but still usable in lua!
}
REQUIRE_NOTHROW(lua.safe_script("collectgarbage()\n"
REQUIRE_NOTHROW(lua.safe_script(
"collectgarbage()\n"
"v = Vec.new(1, 2, 3)\n"
"print(v:length())"));
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
REQUIRE_NOTHROW(lua.safe_script(
"v = Vec.new(1, 2, 3)\n"
"print(v:normalized():length())"));
}
@ -489,23 +511,23 @@ TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as
"length", &Vec::length);
lua.set_usertype(udata);
REQUIRE_NOTHROW(lua.safe_script("v = Vec.new(1, 2, 3)\n"
REQUIRE_NOTHROW(lua.safe_script(
"v = Vec.new(1, 2, 3)\n"
"v2 = Vec.new(0, 1, 0)\n"
"print(v:length())\n"
));
REQUIRE_NOTHROW(lua.safe_script("v.x = 2\n"
"print(v:length())\n"));
REQUIRE_NOTHROW(lua.safe_script(
"v.x = 2\n"
"v2.y = 2\n"
"print(v.x, v.y, v.z)\n"
"print(v2.x, v2.y, v2.z)\n"
));
REQUIRE_NOTHROW(lua.safe_script("assert(v.x == 2)\n"
"print(v2.x, v2.y, v2.z)\n"));
REQUIRE_NOTHROW(lua.safe_script(
"assert(v.x == 2)\n"
"assert(v2.x == 0)\n"
"assert(v2.y == 2)\n"
));
REQUIRE_NOTHROW(lua.safe_script("v.x = 3\n"
"assert(v2.y == 2)\n"));
REQUIRE_NOTHROW(lua.safe_script(
"v.x = 3\n"
"local x = v.x\n"
"assert(x == 3)\n"
));
"assert(x == 3)\n"));
struct breaks {
sol::function f;
@ -514,8 +536,7 @@ TEST_CASE("usertype/member-variables", "allow table-like accessors to behave as
lua.open_libraries(sol::lib::base);
lua.set("b", breaks());
lua.new_usertype<breaks>("breaks",
"f", &breaks::f
);
"f", &breaks::f);
breaks& b = lua["b"];
REQUIRE_NOTHROW(lua.safe_script("b.f = function () print('BARK!') end"));
@ -528,15 +549,17 @@ TEST_CASE("usertype/nonmember-functions", "let users set non-member functions th
lua.open_libraries(sol::lib::base);
lua.new_usertype<giver>("giver",
"gief_stuff", giver::gief_stuff,
"gief", &giver::gief,
"__tostring", [](const giver& t) {
return std::to_string(t.a) + ": giving value";
}
).get<sol::table>("giver").set_function("stuff", giver::stuff);
"gief_stuff", giver::gief_stuff,
"gief", &giver::gief,
"__tostring", [](const giver& t) {
return std::to_string(t.a) + ": giving value";
})
.get<sol::table>("giver")
.set_function("stuff", giver::stuff);
REQUIRE_NOTHROW(lua.safe_script("giver.stuff()"));
REQUIRE_NOTHROW(lua.safe_script("t = giver.new()\n"
REQUIRE_NOTHROW(lua.safe_script(
"t = giver.new()\n"
"print(tostring(t))\n"
"t:gief()\n"
"t:gief_stuff(20)\n"));
@ -549,24 +572,25 @@ TEST_CASE("usertype/unique-shared-ptr", "manage the conversion and use of unique
auto uniqueint = std::make_unique<int64_t>(unique_value);
auto sharedint = std::make_shared<int64_t>(unique_value);
long preusecount = sharedint.use_count();
{ sol::state lua;
lua.open_libraries(sol::lib::base);
lua.set("uniqueint", std::move(uniqueint));
lua.set("sharedint", sharedint);
std::unique_ptr<int64_t>& uniqueintref = lua["uniqueint"];
std::shared_ptr<int64_t>& sharedintref = lua["sharedint"];
int64_t* rawuniqueintref = lua["uniqueint"];
int64_t* rawsharedintref = lua["sharedint"];
int siusecount = sharedintref.use_count();
REQUIRE((uniqueintref.get() == rawuniqueintref && sharedintref.get() == rawsharedintref));
REQUIRE((uniqueintref != nullptr && sharedintref != nullptr && rawuniqueintref != nullptr && rawsharedintref != nullptr));
REQUIRE((unique_value == *uniqueintref.get() && unique_value == *sharedintref.get()));
REQUIRE((unique_value == *rawuniqueintref && unique_value == *rawsharedintref));
REQUIRE(siusecount == sharedint.use_count());
std::shared_ptr<int64_t> moreref = sharedint;
REQUIRE(unique_value == *moreref.get());
REQUIRE(moreref.use_count() == sharedint.use_count());
REQUIRE(moreref.use_count() == sharedintref.use_count());
{
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.set("uniqueint", std::move(uniqueint));
lua.set("sharedint", sharedint);
std::unique_ptr<int64_t>& uniqueintref = lua["uniqueint"];
std::shared_ptr<int64_t>& sharedintref = lua["sharedint"];
int64_t* rawuniqueintref = lua["uniqueint"];
int64_t* rawsharedintref = lua["sharedint"];
int siusecount = sharedintref.use_count();
REQUIRE((uniqueintref.get() == rawuniqueintref && sharedintref.get() == rawsharedintref));
REQUIRE((uniqueintref != nullptr && sharedintref != nullptr && rawuniqueintref != nullptr && rawsharedintref != nullptr));
REQUIRE((unique_value == *uniqueintref.get() && unique_value == *sharedintref.get()));
REQUIRE((unique_value == *rawuniqueintref && unique_value == *rawsharedintref));
REQUIRE(siusecount == sharedint.use_count());
std::shared_ptr<int64_t> moreref = sharedint;
REQUIRE(unique_value == *moreref.get());
REQUIRE(moreref.use_count() == sharedint.use_count());
REQUIRE(moreref.use_count() == sharedintref.use_count());
}
REQUIRE(preusecount == sharedint.use_count());
}
@ -575,7 +599,8 @@ TEST_CASE("regressions/one", "issue number 48") {
sol::state lua;
lua.new_usertype<vars>("vars",
"boop", &vars::boop);
REQUIRE_NOTHROW(lua.safe_script("beep = vars.new()\n"
REQUIRE_NOTHROW(lua.safe_script(
"beep = vars.new()\n"
"beep.boop = 1"));
// test for segfault
auto my_var = lua.get<vars>("beep");
@ -622,8 +647,7 @@ TEST_CASE("usertype/private-constructible", "Check to make sure special snowflak
lua.new_usertype<factory_test>("factory_test",
"new", sol::initializers(factory_test::save),
"__gc", sol::destructor(factory_test::kill),
"a", &factory_test::a
);
"a", &factory_test::a);
std::unique_ptr<factory_test, factory_test::deleter> f = factory_test::make();
lua.set("true_a", factory_test::true_a, "f", f.get());
@ -640,15 +664,18 @@ TEST_CASE("usertype/private-constructible", "Check to make sure special snowflak
}
TEST_CASE("usertype/const-pointer", "Make sure const pointers can be taken") {
struct A_x { int x = 201; };
struct A_x {
int x = 201;
};
struct B_foo {
int foo(const A_x* a) { return a->x; };
int foo(const A_x* a) {
return a->x;
};
};
sol::state lua;
lua.new_usertype<B_foo>("B",
"foo", &B_foo::foo
);
lua.new_usertype<B_foo>("B",
"foo", &B_foo::foo);
lua.set("a", A_x());
lua.set("b", B_foo());
lua.safe_script("x = b:foo(a)");
@ -677,8 +704,7 @@ TEST_CASE("usertype/overloading", "Check if overloading works properly for usert
lua.new_usertype<woof>("woof",
"var", &woof::var,
"func", sol::overload(&woof::func, &woof::func2, &woof::func2s)
);
"func", sol::overload(&woof::func, &woof::func2, &woof::func2s));
const std::string bark_58 = "bark 58";
@ -686,8 +712,7 @@ TEST_CASE("usertype/overloading", "Check if overloading works properly for usert
"r = woof:new()\n"
"a = r:func(1)\n"
"b = r:func(1, 2)\n"
"c = r:func(58, 'bark')\n"
));
"c = r:func(58, 'bark')\n"));
REQUIRE((lua["a"] == 1));
REQUIRE((lua["b"] == 3.5));
REQUIRE((lua["c"] == bark_58));
@ -697,15 +722,20 @@ TEST_CASE("usertype/overloading", "Check if overloading works properly for usert
TEST_CASE("usertype/overloading_values", "ensure overloads handle properly") {
struct overloading_test {
int print(int i) { INFO("Integer print: " << i); return 500 + i; }
int print() { INFO("No param print."); return 500; }
int print(int i) {
INFO("Integer print: " << i);
return 500 + i;
}
int print() {
INFO("No param print.");
return 500;
}
};
sol::state lua;
lua.new_usertype<overloading_test>("overloading_test", sol::constructors<>(),
"print", sol::overload(static_cast<int (overloading_test::*)(int)>(&overloading_test::print), static_cast<int (overloading_test::*)()>(&overloading_test::print)),
"print2", sol::overload(static_cast<int (overloading_test::*)()>(&overloading_test::print), static_cast<int (overloading_test::*)(int)>(&overloading_test::print))
);
"print2", sol::overload(static_cast<int (overloading_test::*)()>(&overloading_test::print), static_cast<int (overloading_test::*)(int)>(&overloading_test::print)));
lua.set("test", overloading_test());
sol::function f0_0 = lua.load("return test:print()");
@ -783,9 +813,11 @@ TEST_CASE("usertype/readonly-and-static-functions", "Check if static functions c
struct bark {
int var = 50;
void func() {}
void func() {
}
static void oh_boy() {}
static void oh_boy() {
}
static int oh_boy(std::string name) {
return static_cast<int>(name.length());
@ -805,8 +837,7 @@ TEST_CASE("usertype/readonly-and-static-functions", "Check if static functions c
"something2", [](int x, int y) { return x + y; },
"func", &bark::func,
"oh_boy", sol::overload(sol::resolve<void()>(&bark::oh_boy), sol::resolve<int(std::string)>(&bark::oh_boy)),
sol::meta_function::call_function, &bark::operator()
);
sol::meta_function::call_function, &bark::operator());
REQUIRE_NOTHROW(lua.safe_script("assert(bark.oh_boy('woo') == 3)"));
REQUIRE_NOTHROW(lua.safe_script("bark.oh_boy()"));
@ -889,8 +920,7 @@ TEST_CASE("usertype/properties", "Check if member properties/variables work") {
"a", sol::property(&bark::get_var2, &bark::set_var2),
"b", sol::property(&bark::get_var2),
"c", sol::property(&bark::get_var3),
"d", sol::property(&bark::set_var2)
);
"d", sol::property(&bark::set_var2));
bark b;
lua.set("b", &b);
@ -933,7 +963,9 @@ TEST_CASE("usertype/properties", "Check if member properties/variables work") {
TEST_CASE("usertype/safety", "crash with an exception -- not a segfault -- on bad userdata calls") {
class Test {
public:
void sayHello() { std::cout << "Hey\n"; }
void sayHello() {
std::cout << "Hey\n";
}
};
sol::state lua;
@ -952,9 +984,7 @@ TEST_CASE("usertype/call_constructor", "make sure lua types can be constructed w
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
"v", &thing::v
, sol::call_constructor, sol::constructors<sol::types<>, sol::types<int>>()
);
"v", &thing::v, sol::call_constructor, sol::constructors<sol::types<>, sol::types<int>>());
lua.safe_script(R"(
t = thing(256)
@ -970,14 +1000,12 @@ TEST_CASE("usertype/call_constructor-factories", "make sure tables can be passed
lua.open_libraries();
lua.new_usertype<matrix_xf>("mat",
sol::call_constructor, sol::factories(&matrix_xf::from_lua_table)
);
sol::call_constructor, sol::factories(&matrix_xf::from_lua_table));
lua.safe_script("m = mat{ {1.1, 2.2} }");
lua.new_usertype<matrix_xi>("mati",
sol::call_constructor, sol::factories(&matrix_xi::from_lua_table)
);
sol::call_constructor, sol::factories(&matrix_xi::from_lua_table));
lua.safe_script("mi = mati{ {1, 2} }");
@ -993,25 +1021,27 @@ TEST_CASE("usertype/call_constructor_2", "prevent metatable regression") {
class class01 {
public:
int x = 57;
class01() {}
class01() {
}
};
class class02 {
public:
int x = 50;
class02() {}
class02(const class01& other) : x(other.x) {}
class02() {
}
class02(const class01& other)
: x(other.x) {
}
};
sol::state lua;
lua.new_usertype<class01>("class01",
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class01&>>()
);
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class01&>>());
lua.new_usertype<class02>("class02",
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class02&>, sol::types<const class01&>>()
);
sol::call_constructor, sol::constructors<sol::types<>, sol::types<const class02&>, sol::types<const class01&>>());
REQUIRE_NOTHROW(lua.safe_script(R"(
x = class01()
@ -1026,24 +1056,20 @@ TEST_CASE("usertype/blank_constructor", "make sure lua types cannot be construct
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
"v", &thing::v
, sol::call_constructor, sol::constructors<>()
);
"v", &thing::v, sol::call_constructor, sol::constructors<>());
auto result = lua.safe_script("t = thing(256)", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
TEST_CASE("usertype/no_constructor", "make sure lua types cannot be constructed if a blank / empty constructor is provided") {
SECTION("order1") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
"v", &thing::v,
sol::call_constructor, sol::no_constructor
);
"v", &thing::v,
sol::call_constructor, sol::no_constructor);
auto result = lua.safe_script("t = thing()", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -1051,22 +1077,20 @@ TEST_CASE("usertype/no_constructor", "make sure lua types cannot be constructed
SECTION("order2") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
sol::call_constructor, sol::no_constructor,
"v", &thing::v
);
sol::call_constructor, sol::no_constructor,
"v", &thing::v);
auto result = lua.safe_script("t = thing.new()", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
SECTION("new no_constructor") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
sol::meta_function::construct, sol::no_constructor
);
sol::meta_function::construct, sol::no_constructor);
auto result = lua.safe_script("t = thing.new()", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -1076,8 +1100,7 @@ TEST_CASE("usertype/no_constructor", "make sure lua types cannot be constructed
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
sol::call_constructor, sol::no_constructor
);
sol::call_constructor, sol::no_constructor);
auto result = lua.safe_script("t = thing()", sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
}
@ -1090,20 +1113,10 @@ TEST_CASE("usertype/coverage", "try all the things") {
lua.new_usertype<ext_getset>("ext_getset",
sol::call_constructor, sol::constructors<sol::types<>, sol::types<int>>(),
sol::meta_function::garbage_collect, sol::destructor(des<ext_getset>),
"x", sol::overload(&ext_getset::x, &ext_getset::x2, [](ext_getset& m, std::string x, int y) {
return m.meow + 50 + y + x.length();
"x", sol::overload(&ext_getset::x, &ext_getset::x2, [](ext_getset& m, std::string x, int y) {
return m.meow + 50 + y + x.length();
}),
"bark", &ext_getset::bark,
"meow", &ext_getset::meow,
"readonlybark", sol::readonly(&ext_getset::bark),
"set", &ext_getset::set,
"get", &ext_getset::get,
"sset", &ext_getset::s_set,
"sget", &ext_getset::s_get,
"propbark", sol::property(&ext_getset::set, &ext_getset::get),
"readonlypropbark", sol::property(&ext_getset::get),
"writeonlypropbark", sol::property(&ext_getset::set)
);
"bark", &ext_getset::bark, "meow", &ext_getset::meow, "readonlybark", sol::readonly(&ext_getset::bark), "set", &ext_getset::set, "get", &ext_getset::get, "sset", &ext_getset::s_set, "sget", &ext_getset::s_get, "propbark", sol::property(&ext_getset::set, &ext_getset::get), "readonlypropbark", sol::property(&ext_getset::get), "writeonlypropbark", sol::property(&ext_getset::set));
INFO("usertype created");
@ -1129,7 +1142,7 @@ y = e.sget(20)
int y = lua["y"];
REQUIRE(x == 500);
REQUIRE(y == 40);
INFO("REQUIRE(x, y) successful");
lua.safe_script(R"(
@ -1197,8 +1210,12 @@ print(e.bark)
TEST_CASE("usertype/copyability", "make sure user can write to a class variable even if the class itself isn't copy-safe") {
struct NoCopy {
int get() const { return _you_can_copy_me; }
void set(int val) { _you_can_copy_me = val; }
int get() const {
return _you_can_copy_me;
}
void set(int val) {
_you_can_copy_me = val;
}
int _you_can_copy_me;
non_copyable _haha_you_cant_copy_me;
@ -1211,8 +1228,7 @@ TEST_CASE("usertype/copyability", "make sure user can write to a class variable
lua.safe_script(R"__(
nocopy = NoCopy.new()
nocopy.val = 5
)__")
);
)__"));
}
TEST_CASE("usertype/protect", "users should be allowed to manually protect a function") {
@ -1224,16 +1240,14 @@ TEST_CASE("usertype/protect", "users should be allowed to manually protect a fun
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<protect_me>("protect_me",
"gen", sol::protect( &protect_me::gen )
);
lua.new_usertype<protect_me>("protect_me",
"gen", sol::protect(&protect_me::gen));
REQUIRE_NOTHROW(
lua.safe_script(R"__(
pm = protect_me.new()
value = pcall(pm.gen,pm)
)__")
);
)__"));
bool value = lua["value"];
REQUIRE_FALSE(value);
}
@ -1250,8 +1264,7 @@ TEST_CASE("usertype/vars", "usertype vars can bind various class items") {
"global", sol::var(muh_variable),
"ref_global", sol::var(std::ref(muh_variable)),
"global2", sol::var(through_variable),
"ref_global2", sol::var(std::ref(through_variable))
);
"ref_global2", sol::var(std::ref(through_variable)));
int prets = lua["test"]["straight"];
int pretg = lua["test"]["global"];
@ -1283,7 +1296,6 @@ print(t.global)
REQUIRE(mv == 50);
REQUIRE(muh_variable == 25);
lua.safe_script(R"(
print(t.ref_global)
t.ref_global = 50
@ -1334,8 +1346,7 @@ TEST_CASE("usertype/static-properties", "allow for static functions to get and s
lua.new_usertype<test_t>("test",
"f", std::function<std::size_t()>(std::bind(std::mem_fn(&test_t::func), &manager)),
"g", sol::property(&test_t::s_func, &test_t::g_func)
);
"g", sol::property(&test_t::s_func, &test_t::g_func));
lua.safe_script("v1 = test.f()");
lua.safe_script("v2 = test.g");
@ -1360,16 +1371,8 @@ TEST_CASE("usertype/var-and-property", "make sure const vars are readonly and pr
lua.open_libraries();
lua.new_usertype<test>("test",
"prop", sol::property(
[](test& t) {
return t.value;
},
[](test& t, int x) {
t.value = x;
}
),
"global", sol::var(std::ref(arf))
);
"prop", sol::property([](test& t) { return t.value; }, [](test& t, int x) { t.value = x; }),
"global", sol::var(std::ref(arf)));
lua.safe_script(R"(
t = test.new()
@ -1405,8 +1408,7 @@ TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't ge
lua.new_usertype<Entity>("Entity",
"new", sol::no_constructor,
"get_name", &Entity::GetName
);
"get_name", &Entity::GetName);
lua.safe_script(R"(
function my_func(entity)
@ -1416,7 +1418,7 @@ TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't ge
)");
sol::function my_func = lua["my_func"];
REQUIRE_NOTHROW([&]{
REQUIRE_NOTHROW([&] {
auto ent = std::make_shared<Entity>();
my_func(ent);
Entity ent2;
@ -1425,7 +1427,7 @@ TEST_CASE("usertype/unique_usertype-check", "make sure unique usertypes don't ge
}());
}
TEST_CASE("usertype/abstract-base-class", "Ensure that abstract base classes and such can be registered") {
TEST_CASE("usertype/abstract-base-class", "Ensure that abstract base classes and such can be registered") {
sol::state lua;
lua.new_usertype<abstract_A>("A", "a", &abstract_A::a);
lua.new_usertype<abstract_B>("B", sol::base_classes, sol::bases<abstract_A>());
@ -1470,8 +1472,7 @@ TEST_CASE("usertype/call-initializers", "Ensure call constructors with initializ
lua.open_libraries();
lua.new_usertype<A>("A",
sol::call_constructor, sol::initializers(&A::init)
);
sol::call_constructor, sol::initializers(&A::init));
lua.safe_script(R"(
a = A(24.3)
@ -1496,7 +1497,9 @@ TEST_CASE("usertype/missing-key", "make sure a missing key returns nil") {
TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime extensible") {
struct thing {
int v = 20;
int func(int a) { return a; }
int func(int a) {
return a;
}
};
int val = 0;
@ -1505,8 +1508,7 @@ TEST_CASE("usertype/runtime-extensibility", "Check if usertypes are runtime exte
lua.open_libraries(sol::lib::base);
lua.new_usertype<thing>("thing",
"func", &thing::func
);
"func", &thing::func);
lua.safe_script(R"(
t = thing.new()
@ -1517,7 +1519,8 @@ t = thing.new()
t.runtime_func = function (a)
return a + 50
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
};
@ -1526,7 +1529,8 @@ end
function t:runtime_func(a)
return a + 52
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
};
@ -1552,8 +1556,7 @@ end
lua.new_usertype<thing>("thing",
"func", &thing::func,
"v", &thing::v
);
"v", &thing::v);
lua.safe_script(R"(
t = thing.new()
@ -1564,7 +1567,8 @@ t = thing.new()
t.runtime_func = function (a)
return a + 50
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
};
@ -1573,7 +1577,8 @@ end
function t:runtime_func(a)
return a + 52
end
)", sol::script_pass_on_error);
)",
sol::script_pass_on_error);
REQUIRE_FALSE(result.valid());
};
@ -1598,7 +1603,8 @@ end
TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly replaced at runtime for non-indexed things") {
struct heart_base_t {};
struct heart_t : heart_base_t {
void func() {}
void func() {
}
};
SECTION("plain") {
@ -1627,8 +1633,7 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly
lua.open_libraries(sol::lib::base);
lua.new_usertype<heart_t>("a",
sol::base_classes, sol::bases<heart_base_t>()
);
sol::base_classes, sol::bases<heart_base_t>());
REQUIRE_NOTHROW([&lua]() {
lua.safe_script("obj = a.new()");
@ -1652,8 +1657,7 @@ TEST_CASE("usertype/runtime-replacement", "ensure that functions can be properly
lua.new_usertype<heart_t>("a",
"func", &heart_t::func,
sol::base_classes, sol::bases<heart_base_t>()
);
sol::base_classes, sol::bases<heart_base_t>());
REQUIRE_NOTHROW([&lua]() {
lua.safe_script("obj = a.new()");
@ -1692,7 +1696,6 @@ TEST_CASE("usertype/meta-key-retrievals", "allow for special meta keys (__index,
s[sol::metatable_key][sol::meta_function::new_index] = &d_sample::foo;
lua["var"] = s;
lua.safe_script("var = sample.new()");
lua.safe_script("var.key = 2");
lua.safe_script("var.__newindex = 4");
@ -1751,10 +1754,9 @@ TEST_CASE("usertype/noexcept-methods", "make sure noexcept functinos and methods
};
sol::state lua;
lua.new_usertype<T>("T",
"nf", &T::noexcept_function,
"nm", &T::noexcept_method
);
lua.new_usertype<T>("T",
"nf", &T::noexcept_function,
"nm", &T::noexcept_method);
lua.safe_script("t = T.new()");
lua.safe_script("v1 = t.nf()");

View File

@ -14,7 +14,7 @@
std::mutex basic_init_require_mutex;
void basic_initialization_and_lib_open() {
sol::state lua;
try {
lua.open_libraries();
@ -36,7 +36,6 @@ void basic_initialization_and_lib_open() {
}
}
TEST_CASE("utility/variant", "test that variant can be round-tripped") {
#ifdef SOL_CXX17_FEATURES
SECTION("okay") {
@ -134,8 +133,7 @@ TEST_CASE("utility/this_state", "Ensure this_state argument can be gotten anywhe
INFO("created lua state");
lua.open_libraries(sol::lib::base);
lua.new_usertype<bark>("bark",
"with_state", &bark::with_state
);
"with_state", &bark::with_state);
INFO("setting b and with_state_2");
bark b;

View File

@ -22,7 +22,7 @@ TEST_CASE("variadics/variadic_args", "Check to see we can receive multiple argum
int value = v;
r += value;
}
return{ r, r > 200 };
return { r, r > 200 };
});
lua.safe_script("x = v(25, 25)");
@ -44,8 +44,7 @@ TEST_CASE("variadics/required with variadic_args", "Check if a certain number of
sol::state lua;
lua.set_function("v",
[](sol::this_state, sol::variadic_args, int, int) {
}
);
});
REQUIRE_NOTHROW(lua.safe_script("v(20, 25, 30)"));
REQUIRE_NOTHROW(lua.safe_script("v(20, 25)"));
auto result = lua.safe_script("v(20)", sol::script_pass_on_error);
@ -181,16 +180,14 @@ TEST_CASE("variadics/variadic_results", "returning a variable amount of argument
}
TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves properly in the presence of variadic fallbacks") {
struct vec2 { float x = 0, y = 0; };
struct vec2 {
float x = 0, y = 0;
};
sol::state lua;
lua.new_simple_usertype<vec2>("vec2",
sol::call_constructor, sol::factories([]() {
return vec2{};
}, [](vec2 const& v) -> vec2 {
return v;
}, [](sol::variadic_args va) {
sol::call_constructor, sol::factories([]() { return vec2{}; }, [](vec2 const& v) -> vec2 { return v; }, [](sol::variadic_args va) {
vec2 res{};
if (va.size() == 1) {
res.x = va[0].get<float>();
@ -203,9 +200,7 @@ TEST_CASE("variadics/fallback_constructor", "ensure constructor matching behaves
else {
throw sol::error("invalid args");
}
return res;
})
);
return res; }));
REQUIRE_NOTHROW([&]() {
lua.safe_script("v0 = vec2();");

View File

@ -13,12 +13,10 @@
#include "test_stack_guard.hpp"
bool func_opt_ret_bool(sol::optional<int> i) {
if (i)
{
if (i) {
INFO(i.value());
}
else
{
else {
INFO("optional isn't set");
}
return true;
@ -35,39 +33,45 @@ TEST_CASE("table/traversal", "ensure that we can chain requests and tunnel down
test_stack_guard g(lua.lua_state(), begintop, endtop);
int traversex24 = lua.traverse_get<int>("t1", "t2", "t3");
REQUIRE(traversex24 == 24);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
int x24 = lua["t1"]["t2"]["t3"];
REQUIRE(x24 == 24);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
lua["t1"]["t2"]["t3"] = 64;
int traversex64 = lua.traverse_get<int>("t1", "t2", "t3");
REQUIRE(traversex64 == 64);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
int x64 = lua["t1"]["t2"]["t3"];
REQUIRE(x64 == 64);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
lua.traverse_set("t1", "t2", "t3", 13);
int traversex13 = lua.traverse_get<int>("t1", "t2", "t3");
REQUIRE(traversex13 == 13);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
int x13 = lua["t1"]["t2"]["t3"];
REQUIRE(x13 == 13);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
}
TEST_CASE("simple/set", "Check if the set works properly.") {
@ -76,18 +80,21 @@ TEST_CASE("simple/set", "Check if the set works properly.") {
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
lua.set("a", 9);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
REQUIRE_NOTHROW(lua.safe_script("if a ~= 9 then error('wrong value') end"));
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
lua.set("d", "hello");
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
REQUIRE_NOTHROW(lua.safe_script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
lua.set("e", std::string("hello"), "f", true);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
REQUIRE_NOTHROW(lua.safe_script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
REQUIRE_NOTHROW(lua.safe_script("if f ~= true then error('wrong value') end"));
}
@ -101,13 +108,15 @@ TEST_CASE("simple/get", "Tests if the get function works properly.") {
test_stack_guard g(lua.lua_state(), begintop, endtop);
auto a = lua.get<int>("a");
REQUIRE(a == 9.0);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
lua.safe_script("b = nil");
{
test_stack_guard g(lua.lua_state(), begintop, endtop);
REQUIRE_NOTHROW(lua.get<sol::nil_t>("b"));
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
lua.safe_script("d = 'hello'");
lua.safe_script("e = true");
@ -118,7 +127,8 @@ TEST_CASE("simple/get", "Tests if the get function works properly.") {
std::tie(d, e) = lua.get<std::string, bool>("d", "e");
REQUIRE(d == "hello");
REQUIRE(e == true);
} REQUIRE(begintop == endtop);
}
REQUIRE(begintop == endtop);
}
TEST_CASE("simple/set and get global integer", "Tests if the get function works properly with global integers") {
@ -223,7 +233,8 @@ TEST_CASE("interop/null-to-nil-and-back", "nil should be the given type when a p
lua.set_function("rofl", [](int* x) {
INFO(x);
});
REQUIRE_NOTHROW(lua.safe_script("x = lol()\n"
REQUIRE_NOTHROW(lua.safe_script(
"x = lol()\n"
"rofl(x)\n"
"assert(x == nil)"));
}
@ -338,14 +349,12 @@ TEST_CASE("object/main_* conversions", "make sure all basic reference types can
TEST_CASE("feature/indexing overrides", "make sure index functions can be overridden on types") {
struct PropertySet {
sol::object get_property_lua(const char* name, sol::this_state s)
{
sol::object get_property_lua(const char* name, sol::this_state s) {
auto& var = props[name];
return sol::make_object(s, var);
}
void set_property_lua(const char* name, sol::stack_object object)
{
void set_property_lua(const char* name, sol::stack_object object) {
props[name] = object.as<std::string>();
}
@ -363,13 +372,8 @@ TEST_CASE("feature/indexing overrides", "make sure index functions can be overri
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<PropertySet>("PropertySet"
, sol::meta_function::new_index, &PropertySet::set_property_lua
, sol::meta_function::index, &PropertySet::get_property_lua
);
lua.new_usertype<DynamicObject>("DynamicObject"
, "props", sol::property(&DynamicObject::get_dynamic_props)
);
lua.new_usertype<PropertySet>("PropertySet", sol::meta_function::new_index, &PropertySet::set_property_lua, sol::meta_function::index, &PropertySet::get_property_lua);
lua.new_usertype<DynamicObject>("DynamicObject", "props", sol::property(&DynamicObject::get_dynamic_props));
lua.safe_script(R"__(
obj = DynamicObject:new()
@ -386,21 +390,19 @@ TEST_CASE("features/indexing numbers", "make sure indexing functions can be over
public:
double data[3];
vector() : data{ 0,0,0 } {}
vector()
: data{ 0, 0, 0 } {
}
double& operator[](int i)
{
double& operator[](int i) {
return data[i];
}
static double my_index(vector& v, int i)
{
static double my_index(vector& v, int i) {
return v[i];
}
static void my_new_index(vector& v, int i, double x)
{
static void my_new_index(vector& v, int i, double x) {
v[i] = x;
}
};
@ -410,11 +412,11 @@ TEST_CASE("features/indexing numbers", "make sure indexing functions can be over
lua.new_usertype<vector>("vector", sol::constructors<sol::types<>>(),
sol::meta_function::index, &vector::my_index,
sol::meta_function::new_index, &vector::my_new_index);
lua.safe_script("v = vector.new()\n"
lua.safe_script(
"v = vector.new()\n"
"print(v[1])\n"
"v[2] = 3\n"
"print(v[2])\n"
);
"print(v[2])\n");
vector& v = lua["v"];
REQUIRE(v[0] == 0.0);
@ -432,36 +434,29 @@ TEST_CASE("features/multiple inheritance", "Ensure that multiple inheritance wor
};
struct simple : base1 {
};
struct complex : base1, base2 {
};
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<base1>("base1",
"a1", &base1::a1
);
"a1", &base1::a1);
lua.new_usertype<base2>("base2",
"a2", &base2::a2
);
"a2", &base2::a2);
lua.new_usertype<simple>("simple",
"a1", &simple::a1,
sol::base_classes, sol::bases<base1>()
);
sol::base_classes, sol::bases<base1>());
lua.new_usertype<complex>("complex",
"a1", &complex::a1,
"a2", &complex::a2,
sol::base_classes, sol::bases<base1, base2>()
);
lua.safe_script("c = complex.new()\n"
sol::base_classes, sol::bases<base1, base2>());
lua.safe_script(
"c = complex.new()\n"
"s = simple.new()\n"
"b1 = base1.new()\n"
"b2 = base1.new()\n"
);
"b2 = base1.new()\n");
base1* sb1 = lua["s"];
REQUIRE(sb1 != nullptr);
@ -476,7 +471,6 @@ TEST_CASE("features/multiple inheritance", "Ensure that multiple inheritance wor
REQUIRE(cb2->a2 == 500);
}
TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't considered as a function by using unwrap_unqualified_t trait") {
struct base1 {
int a1 = 250;
@ -494,7 +488,7 @@ TEST_CASE("regressions/std::ref", "Ensure that std::reference_wrapper<> isn't co
REQUIRE(vp->a1 == 250);
REQUIRE(vr.a1 == 250);
v.a1 = 568;
REQUIRE(vp->a1 == 568);
@ -508,8 +502,8 @@ TEST_CASE("optional/left out args", "Make sure arguments can be left out of opti
// sol::optional needs an argument no matter what?
lua.set_function("func_opt_ret_bool", func_opt_ret_bool);
REQUIRE_NOTHROW([&]{
lua.safe_script(R"(
REQUIRE_NOTHROW([&] {
lua.safe_script(R"(
func_opt_ret_bool(42)
func_opt_ret_bool()
print('ok')
@ -519,18 +513,21 @@ TEST_CASE("optional/left out args", "Make sure arguments can be left out of opti
TEST_CASE("pusher/constness", "Make sure more types can handle being const and junk") {
struct Foo {
Foo(const sol::function& f) : _f(f) {}
Foo(const sol::function& f)
: _f(f) {
}
const sol::function& _f;
const sol::function& f() const { return _f; }
const sol::function& f() const {
return _f;
}
};
sol::state lua;
lua.new_usertype<Foo>("Foo",
sol::call_constructor, sol::no_constructor,
"f", &Foo::f
);
"f", &Foo::f);
lua["func"] = []() { return 20; };
sol::function f = lua["func"];
@ -561,13 +558,13 @@ TEST_CASE("proxy/equality", "check to make sure equality tests work") {
REQUIRE_FALSE((lua["a"] == nullptr));
REQUIRE_FALSE((lua["a"] == 0));
REQUIRE_FALSE((lua["a"] == 2));
lua["a"] = 2;
REQUIRE_FALSE((lua["a"] == sol::nil)); //0
REQUIRE_FALSE((lua["a"] == nullptr)); //0
REQUIRE_FALSE((lua["a"] == 0)); //0
REQUIRE((lua["a"] == 2)); //1
REQUIRE_FALSE((lua["a"] == nullptr)); //0
REQUIRE_FALSE((lua["a"] == 0)); //0
REQUIRE((lua["a"] == 2)); //1
}
TEST_CASE("compilation/const regression", "make sure constness in tables is respected all the way down") {
@ -588,7 +585,7 @@ TEST_CASE("compilation/const regression", "make sure constness in tables is resp
TEST_CASE("numbers/integers", "make sure integers are detectable on most platforms") {
sol::state lua;
lua["a"] = 50; // int
lua["a"] = 50; // int
lua["b"] = 50.5; // double
sol::object a = lua["a"];
@ -611,17 +608,15 @@ TEST_CASE("numbers/integers", "make sure integers are detectable on most platfor
TEST_CASE("object/is", "test whether or not the is abstraction works properly for a user-defined type") {
struct thing {};
SECTION("stack_object")
{
SECTION("stack_object") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.set_function("is_thing", [](sol::stack_object obj) { return obj.is<thing>(); } );
lua.set_function("is_thing", [](sol::stack_object obj) { return obj.is<thing>(); });
lua["a"] = thing{};
REQUIRE_NOTHROW(lua.safe_script("assert(is_thing(a))"));
}
SECTION("object")
{
SECTION("object") {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.set_function("is_thing", [](sol::object obj) { return obj.is<thing>(); });