mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
more luajit compatibility fixes - works with Lua 5.1, 5.2, 5.3
additional tests to make sure pass-by-value and copy semantics work as intended new proxy_base class to reduce code duplication update function / protected_function usage (to solve starwing's issue while keeping code as clean as possible)
This commit is contained in:
parent
27f09fbb35
commit
1d93f560f2
3
.gitignore
vendored
3
.gitignore
vendored
@ -40,3 +40,6 @@ luajit-2.0.4/
|
||||
*.creator.user.*
|
||||
lua-5.3.1/
|
||||
main2.cpp
|
||||
lua-5.3.2/
|
||||
lua-5.2.4/
|
||||
bench/
|
||||
|
@ -13,11 +13,11 @@ static sol::state prepare_cpp_function_state( ) {
|
||||
return lua;
|
||||
}
|
||||
|
||||
struct sol_fast_function_result_cpp_bench {
|
||||
struct sol_protected_function_result_cpp_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_cpp_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
sol::fast_function r = lua[ "r" ];
|
||||
sol::protected_function r = lua[ "r" ];
|
||||
int value = r( );
|
||||
return value;
|
||||
};
|
||||
@ -25,11 +25,11 @@ struct sol_fast_function_result_cpp_bench {
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_fast_direct_cpp_bench {
|
||||
struct sol_protected_call_cpp_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_cpp_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
sol::fast_function r = lua[ "r" ];
|
||||
sol::protected_function r = lua[ "r" ];
|
||||
int value = r.call<int>( );
|
||||
return value;
|
||||
};
|
||||
@ -49,7 +49,7 @@ struct sol_function_result_cpp_bench {
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_direct_cpp_bench {
|
||||
struct sol_call_cpp_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_cpp_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
@ -61,7 +61,7 @@ struct sol_direct_cpp_bench {
|
||||
}
|
||||
};
|
||||
|
||||
struct c_direct_cpp_bench {
|
||||
struct c_call_cpp_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_cpp_function_state( );
|
||||
lua_State* L = lua.lua_state( );
|
||||
@ -82,11 +82,11 @@ void bench_cpp_function( const std::string& dir, std::string& configurationname,
|
||||
cfg.title = "sol::function (C++ source) (" + configurationname + " " + platformname + ")";
|
||||
cfg.samples = 100;
|
||||
nonius::benchmark benchmarks [] = {
|
||||
nonius::benchmark( "fast_function - function_result", sol_fast_function_result_cpp_bench( ) ),
|
||||
nonius::benchmark( "fast_function - call<>", sol_fast_direct_cpp_bench( ) ),
|
||||
nonius::benchmark( "protected_function - function_result", sol_protected_function_result_cpp_bench( ) ),
|
||||
nonius::benchmark( "protected_function - call<>", sol_protected_call_cpp_bench( ) ),
|
||||
nonius::benchmark( "function - function_result", sol_function_result_cpp_bench( ) ),
|
||||
nonius::benchmark( "function - call<>", sol_direct_cpp_bench( ) ),
|
||||
nonius::benchmark( "plain C", c_direct_cpp_bench( ) ),
|
||||
nonius::benchmark( "function - call<>", sol_call_cpp_bench( ) ),
|
||||
nonius::benchmark( "plain C", c_call_cpp_bench( ) ),
|
||||
};
|
||||
nonius::go( cfg, std::begin( benchmarks ), std::end( benchmarks ), nonius::html_reporter( ) );
|
||||
}
|
||||
|
@ -13,30 +13,6 @@ end
|
||||
return lua;
|
||||
}
|
||||
|
||||
struct sol_fast_function_result_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
sol::fast_function r = lua[ "r" ];
|
||||
int value = r( );
|
||||
return value;
|
||||
};
|
||||
meter.measure( measurement );
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_fast_direct_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
sol::fast_function r = lua[ "r" ];
|
||||
int value = r.call<int>( );
|
||||
return value;
|
||||
};
|
||||
meter.measure( measurement );
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_function_result_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
@ -49,7 +25,7 @@ struct sol_function_result_lua_bench {
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_direct_lua_bench {
|
||||
struct sol_call_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
@ -61,6 +37,30 @@ struct sol_direct_lua_bench {
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_protected_function_result_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
sol::protected_function r = lua[ "r" ];
|
||||
int value = r( );
|
||||
return value;
|
||||
};
|
||||
meter.measure( measurement );
|
||||
}
|
||||
};
|
||||
|
||||
struct sol_protected_call_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
auto measurement = [ & ] ( int run_index ) {
|
||||
sol::protected_function r = lua[ "r" ];
|
||||
int value = r.call<int>( );
|
||||
return value;
|
||||
};
|
||||
meter.measure( measurement );
|
||||
}
|
||||
};
|
||||
|
||||
struct c_direct_lua_bench {
|
||||
void operator () ( nonius::chronometer meter ) const {
|
||||
sol::state lua = prepare_lua_function_state( );
|
||||
@ -81,11 +81,11 @@ void bench_lua_function( const std::string& dir, std::string& configurationname
|
||||
cfg.output_file = dir + "sol.functions (lua source) - " + configurationname + " " + platformname + ".html";
|
||||
cfg.title = "sol::function (lua source) (" + configurationname + " " + platformname + ")";
|
||||
cfg.samples = 100;
|
||||
nonius::benchmark benchmarks [] = {
|
||||
nonius::benchmark( "fast_function - function_result", sol_fast_function_result_lua_bench( ) ),
|
||||
nonius::benchmark( "fast_function - call<>", sol_fast_direct_lua_bench( ) ),
|
||||
nonius::benchmark( "function - function_result", sol_function_result_lua_bench( ) ),
|
||||
nonius::benchmark( "function - call<>", sol_direct_lua_bench( ) ),
|
||||
nonius::benchmark benchmarks[] = {
|
||||
nonius::benchmark("function - function_result", sol_function_result_lua_bench()),
|
||||
nonius::benchmark("function - call<>", sol_call_lua_bench()),
|
||||
nonius::benchmark("protected_function - function_result", sol_protected_function_result_lua_bench()),
|
||||
nonius::benchmark("protected_function - call<>", sol_protected_call_lua_bench()),
|
||||
nonius::benchmark( "plain C", c_direct_lua_bench( ) ),
|
||||
};
|
||||
nonius::go( cfg, std::begin( benchmarks ), std::end( benchmarks ), nonius::html_reporter( ) );
|
||||
|
2
sol.hpp
2
sol.hpp
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Danny Y., Rapptz
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
140
sol/function.hpp
140
sol/function.hpp
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -28,88 +28,13 @@
|
||||
#include "function_types.hpp"
|
||||
#include "usertype_traits.hpp"
|
||||
#include "resolve.hpp"
|
||||
#include "function_result.hpp"
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace sol {
|
||||
class function_result {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
int returncount;
|
||||
int popcount;
|
||||
call_error error;
|
||||
|
||||
template <typename T, std::size_t I>
|
||||
stack::get_return<T> get(types<T>, indices<I>) const {
|
||||
return stack::get<T>(L, index);
|
||||
}
|
||||
|
||||
template <typename... Ret, std::size_t... I>
|
||||
stack::get_return<Ret...> get(types<Ret...>, indices<I...>) const {
|
||||
auto r = std::make_tuple(stack::get<Ret>(L, index + I)...);
|
||||
return r;
|
||||
}
|
||||
|
||||
public:
|
||||
function_result() = default;
|
||||
function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_error error = call_error::ok): L(L), index(index), returncount(returncount), popcount(popcount), error(error) {
|
||||
|
||||
}
|
||||
function_result(const function_result&) = default;
|
||||
function_result& operator=(const function_result&) = default;
|
||||
function_result(function_result&& o) : L(o.L), index(o.index), returncount(o.returncount), error(o.error) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but will be thorough
|
||||
o.L = nullptr;
|
||||
o.index = 0;
|
||||
o.returncount = 0;
|
||||
o.popcount = 0;
|
||||
o.error = call_error::runtime;
|
||||
}
|
||||
function_result& operator=(function_result&& o) {
|
||||
L = o.L;
|
||||
index = o.index;
|
||||
returncount = o.returncount;
|
||||
error = o.error;
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but will be thorough
|
||||
o.L = nullptr;
|
||||
o.index = 0;
|
||||
o.returncount = 0;
|
||||
o.popcount = 0;
|
||||
o.error = call_error::runtime;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool valid() const {
|
||||
return error == call_error::ok;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T get() const {
|
||||
tuple_types<Unqualified<T>> tr;
|
||||
return get(tr, tr);
|
||||
}
|
||||
|
||||
operator std::string() const {
|
||||
return get<std::string>();
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<std::is_same<Unqualified<T>, const char*>>, Not<std::is_same<Unqualified<T>, char>>, Not<std::is_same<Unqualified<T>, std::string>>, Not<std::is_same<Unqualified<T>, std::initializer_list<char>>>> = 0>
|
||||
operator T () const {
|
||||
return get<T>();
|
||||
}
|
||||
|
||||
~function_result() {
|
||||
stack::remove(L, index, popcount);
|
||||
}
|
||||
};
|
||||
|
||||
class fast_function : public reference {
|
||||
class function : public reference {
|
||||
private:
|
||||
void luacall( std::ptrdiff_t argcount, std::ptrdiff_t resultcount ) const {
|
||||
lua_callk( lua_state( ), static_cast<int>( argcount ), static_cast<int>( resultcount ), 0, nullptr );
|
||||
@ -117,7 +42,7 @@ private:
|
||||
|
||||
template<std::size_t... I, typename... Ret>
|
||||
std::tuple<Ret...> invoke( indices<I...>, types<Ret...>, std::ptrdiff_t n ) const {
|
||||
luacall( n, sizeof...( Ret ), h );
|
||||
luacall( n, sizeof...( Ret ) );
|
||||
int nreturns = static_cast<int>( sizeof...( Ret ) );
|
||||
int stacksize = lua_gettop( lua_state( ) );
|
||||
int firstreturn = std::max( 0, stacksize - nreturns ) + 1;
|
||||
@ -139,35 +64,22 @@ private:
|
||||
|
||||
function_result invoke( indices<>, types<>, std::ptrdiff_t n ) const {
|
||||
int stacksize = lua_gettop( lua_state( ) );
|
||||
int firstreturn = std::max( 0, stacksize - static_cast<int>( n ) - 1 );
|
||||
int poststacksize = 0;
|
||||
int returncount = 0;
|
||||
try {
|
||||
luacall( n, LUA_MULTRET );
|
||||
poststacksize = lua_gettop( lua_state( ) );
|
||||
returncount = poststacksize - firstreturn;
|
||||
}
|
||||
// Handle C++ errors thrown from C++ functions bound inside of lua
|
||||
catch ( const std::exception& error ) {
|
||||
stack::push( lua_state( ), error.what( ) );
|
||||
return function_result( lua_state( ), firstreturn, 0, 1, call_error::runtime );
|
||||
}
|
||||
catch ( ... ) {
|
||||
throw;
|
||||
}
|
||||
|
||||
int firstreturn = std::max( 1, stacksize - static_cast<int>( n ) );
|
||||
luacall( n, LUA_MULTRET );
|
||||
int poststacksize = lua_gettop( lua_state( ) );
|
||||
int returncount = poststacksize - firstreturn;
|
||||
return function_result( lua_state( ), firstreturn, returncount, returncount, call_error::ok );
|
||||
}
|
||||
|
||||
public:
|
||||
fast_function( ) = default;
|
||||
fast_function( lua_State* L, int index = -1 ) : reference( L, index ) {
|
||||
function( ) = default;
|
||||
function( lua_State* L, int index = -1 ) : reference( L, index ) {
|
||||
type_assert( L, index, type::function );
|
||||
}
|
||||
fast_function( const fast_function& ) = default;
|
||||
fast_function& operator=( const fast_function& ) = default;
|
||||
fast_function( fast_function&& ) = default;
|
||||
fast_function& operator=( fast_function&& ) = default;
|
||||
function( const function& ) = default;
|
||||
function& operator=( const function& ) = default;
|
||||
function( function&& ) = default;
|
||||
function& operator=( function&& ) = default;
|
||||
|
||||
template<typename... Args>
|
||||
function_result operator()( Args&&... args ) const {
|
||||
@ -176,7 +88,7 @@ public:
|
||||
|
||||
template<typename... Ret, typename... Args>
|
||||
auto operator()( types<Ret...>, Args&&... args ) const
|
||||
-> decltype( invoke( types<Ret...>( ), types<Ret...>( ), 0, std::declval<handler&>( ) ) ) {
|
||||
-> decltype( invoke( types<Ret...>( ), types<Ret...>( ), 0 ) ) {
|
||||
return call<Ret...>( std::forward<Args>( args )... );
|
||||
}
|
||||
|
||||
@ -190,7 +102,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class safe_function : public reference {
|
||||
class protected_function : public reference {
|
||||
private:
|
||||
static reference& handler_storage() {
|
||||
static sol::reference h;
|
||||
@ -252,21 +164,21 @@ private:
|
||||
function_result invoke(indices<>, types<>, std::ptrdiff_t n, handler& h) const {
|
||||
bool handlerpushed = error_handler.valid();
|
||||
int stacksize = lua_gettop(lua_state());
|
||||
int firstreturn = std::max(0, stacksize - static_cast<int>(n) - 1);
|
||||
int firstreturn = std::max(1, stacksize - static_cast<int>(n) - 1);
|
||||
int returncount = 0;
|
||||
call_error code = call_error::ok;
|
||||
|
||||
try {
|
||||
code = static_cast<call_error>(luacall(n, LUA_MULTRET, h));
|
||||
int poststacksize = lua_gettop( lua_state( ) );
|
||||
int poststacksize = lua_gettop(lua_state());
|
||||
returncount = poststacksize - firstreturn;
|
||||
}
|
||||
// Handle C++ errors thrown from C++ functions bound inside of lua
|
||||
catch (const std::exception& error) {
|
||||
code = call_error::runtime;
|
||||
h.stackindex = 0;
|
||||
stack::push(lua_state(), error.what());
|
||||
return function_result( lua_state( ), firstreturn, 0, 1, call_error::runtime );
|
||||
firstreturn = lua_gettop(lua_state());
|
||||
return function_result(lua_state(), firstreturn, 0, 1, call_error::runtime);
|
||||
}
|
||||
catch (...) {
|
||||
throw;
|
||||
@ -277,14 +189,14 @@ private:
|
||||
public:
|
||||
sol::reference error_handler;
|
||||
|
||||
safe_function() = default;
|
||||
safe_function(lua_State* L, int index = -1): reference(L, index), error_handler(get_default_handler()) {
|
||||
protected_function() = default;
|
||||
protected_function(lua_State* L, int index = -1): reference(L, index), error_handler(get_default_handler()) {
|
||||
type_assert(L, index, type::function);
|
||||
}
|
||||
safe_function(const safe_function&) = default;
|
||||
safe_function& operator=(const safe_function&) = default;
|
||||
safe_function( safe_function&& ) = default;
|
||||
safe_function& operator=( safe_function&& ) = default;
|
||||
protected_function(const protected_function&) = default;
|
||||
protected_function& operator=(const protected_function&) = default;
|
||||
protected_function( protected_function&& ) = default;
|
||||
protected_function& operator=( protected_function&& ) = default;
|
||||
|
||||
template<typename... Args>
|
||||
function_result operator()(Args&&... args) const {
|
||||
|
103
sol/function_result.hpp
Normal file
103
sol/function_result.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_FUNCTION_RESULT_HPP
|
||||
#define SOL_FUNCTION_RESULT_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
|
||||
namespace sol {
|
||||
struct function_result : public proxy_base<function_result> {
|
||||
private:
|
||||
lua_State* L;
|
||||
int index;
|
||||
int returncount;
|
||||
int popcount;
|
||||
call_error error;
|
||||
|
||||
template <typename T, std::size_t I>
|
||||
stack::get_return<T> get(types<T>, indices<I>) const {
|
||||
return stack::get<T>(L, index);
|
||||
}
|
||||
|
||||
template <typename... Ret, std::size_t... I>
|
||||
stack::get_return<Ret...> get(types<Ret...>, indices<I...>) const {
|
||||
return stack::get_return<Ret...>(stack::get<Ret>(L, index + I)...);
|
||||
}
|
||||
|
||||
public:
|
||||
function_result() = default;
|
||||
function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_error error = call_error::ok): L(L), index(index), returncount(returncount), popcount(popcount), error(error) {
|
||||
|
||||
}
|
||||
function_result(const function_result&) = default;
|
||||
function_result& operator=(const function_result&) = default;
|
||||
function_result(function_result&& o) : L(o.L), index(o.index), returncount(o.returncount), error(o.error) {
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but will be thorough
|
||||
o.L = nullptr;
|
||||
o.index = 0;
|
||||
o.returncount = 0;
|
||||
o.popcount = 0;
|
||||
o.error = call_error::runtime;
|
||||
}
|
||||
function_result& operator=(function_result&& o) {
|
||||
L = o.L;
|
||||
index = o.index;
|
||||
returncount = o.returncount;
|
||||
error = o.error;
|
||||
// Must be manual, otherwise destructor will screw us
|
||||
// return count being 0 is enough to keep things clean
|
||||
// but will be thorough
|
||||
o.L = nullptr;
|
||||
o.index = 0;
|
||||
o.returncount = 0;
|
||||
o.popcount = 0;
|
||||
o.error = call_error::runtime;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool valid() const {
|
||||
return error == call_error::ok;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T get() const {
|
||||
tuple_types<Unqualified<T>> tr;
|
||||
return get(tr, tr);
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
decltype(auto) operator[](K&& key) const {
|
||||
return get<table>()[std::forward<K>(key)];
|
||||
}
|
||||
|
||||
~function_result() {
|
||||
stack::remove(L, index, popcount);
|
||||
}
|
||||
};
|
||||
} // sol
|
||||
|
||||
#endif // SOL_FUNCTION_RESULT_HPP
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -25,10 +25,11 @@
|
||||
#include "traits.hpp"
|
||||
#include "object.hpp"
|
||||
#include "function.hpp"
|
||||
#include "proxy_base.hpp"
|
||||
|
||||
namespace sol {
|
||||
template<typename Table, typename Key>
|
||||
struct proxy {
|
||||
struct proxy : public proxy_base<proxy<Table, Key>> {
|
||||
private:
|
||||
Table tbl;
|
||||
If<std::is_array<Unqualified<Key>>, Key&, Unqualified<Key>> key;
|
||||
@ -67,20 +68,6 @@ public:
|
||||
return tbl.template get<T>( key );
|
||||
}
|
||||
|
||||
operator std::string() const {
|
||||
return get<std::string>();
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<is_string_constructible<T>>, is_lua_primitive<T>> = 0>
|
||||
operator T ( ) const {
|
||||
return get<T>( );
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<is_string_constructible<T>>, Not<is_lua_primitive<T>>> = 0>
|
||||
operator T& ( ) const {
|
||||
return get<T&>( );
|
||||
}
|
||||
|
||||
template <typename K>
|
||||
decltype(auto) operator[](K&& key) const {
|
||||
return get<table>()[std::forward<K>(key)];
|
||||
|
51
sol/proxy_base.hpp
Normal file
51
sol/proxy_base.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifndef SOL_PROXY_BASE_HPP
|
||||
#define SOL_PROXY_BASE_HPP
|
||||
|
||||
#include "reference.hpp"
|
||||
#include "tuple.hpp"
|
||||
#include "stack.hpp"
|
||||
|
||||
namespace sol {
|
||||
template <typename Super>
|
||||
struct proxy_base {
|
||||
operator std::string() const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<std::string>();
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<is_string_constructible<T>>, is_proxy_primitive<Unqualified<T>>> = 0>
|
||||
operator T ( ) const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<T>( );
|
||||
}
|
||||
|
||||
template<typename T, EnableIf<Not<is_string_constructible<T>>, Not<is_proxy_primitive<Unqualified<T>>>> = 0>
|
||||
operator T& ( ) const {
|
||||
const Super& super = *static_cast<const Super*>(static_cast<const void*>(this));
|
||||
return super.template get<T&>( );
|
||||
}
|
||||
};
|
||||
} // sol
|
||||
|
||||
#endif // SOL_PROXY_BASE_HPP
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -25,14 +25,18 @@
|
||||
#include "types.hpp"
|
||||
|
||||
namespace sol {
|
||||
namespace detail {
|
||||
namespace stack {
|
||||
template <typename T>
|
||||
struct push_pop {
|
||||
T t;
|
||||
push_pop (T x) : t(x) { t.push(); }
|
||||
~push_pop() { t.pop(); }
|
||||
};
|
||||
} // detail
|
||||
template <typename T>
|
||||
push_pop<T> push_popper(T&& x) {
|
||||
return push_pop<T>(std::forward<T>(x));
|
||||
};
|
||||
} // stack
|
||||
|
||||
class reference {
|
||||
private:
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -150,7 +150,7 @@ inline void lua_setglobali(lua_State* L, lua_Integer n) {
|
||||
#else
|
||||
lua_pushglobaltable(L);
|
||||
lua_pushinteger(L, n);
|
||||
lua_pushvalue(L, -3)
|
||||
lua_pushvalue(L, -3);
|
||||
lua_settable(L, -3);
|
||||
lua_pop(L, 2); // remove table, and the copy of the value
|
||||
#endif
|
||||
|
@ -150,19 +150,19 @@ public:
|
||||
return globals.get<Args...>(std::forward<Keys>(keys)...);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
state_view& set(T&& key, U&& value) {
|
||||
globals.set(std::forward<T>(key), std::forward<U>(value));
|
||||
template<typename... Tn>
|
||||
state_view& set(Tn&&... argn) {
|
||||
globals.set(std::forward<Tn>(argn)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SOL_DEPRECATED table& set_userdata(usertype<T>& user) {
|
||||
SOL_DEPRECATED state_view& set_userdata(usertype<T>& user) {
|
||||
return set_usertype(user);
|
||||
}
|
||||
|
||||
template<typename Key, typename T>
|
||||
SOL_DEPRECATED table& set_userdata(Key&& key, usertype<T>& user) {
|
||||
SOL_DEPRECATED state_view& set_userdata(Key&& key, usertype<T>& user) {
|
||||
return set_usertype(std::forward<Key>(key), user);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -49,8 +49,9 @@ class table_core : public reference {
|
||||
return stack::pop<T>(lua_state());
|
||||
}
|
||||
|
||||
template<typename T, typename Key, DisableIf<Not<std::is_void<Key>>, Bool<top_level>> = 0>
|
||||
template<typename T, typename Key, DisableIf<Bool<top_level>, Not<std::is_void<Key>>> = 0>
|
||||
decltype(auto) single_get( Key&& key ) const {
|
||||
auto pp = stack::push_popper(*this);
|
||||
stack::push( lua_state( ), std::forward<Key>( key ) );
|
||||
lua_gettable( lua_state( ), -2 );
|
||||
return stack::pop<T>( lua_state( ) );
|
||||
@ -78,8 +79,9 @@ class table_core : public reference {
|
||||
lua_setglobal( lua_state( ), &key[0] );
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, DisableIf<Not<std::is_void<Key>>, Bool<top_level>> = 0>
|
||||
template<typename Key, typename Value, DisableIf<Bool<top_level>, Not<std::is_void<Key>>> = 0>
|
||||
void single_set(Key&& key, Value&& value) {
|
||||
auto pp = stack::push_popper(*this);
|
||||
stack::push(lua_state(), std::forward<Key>(key));
|
||||
stack::push(lua_state(), std::forward<Value>(value));
|
||||
lua_settable(lua_state(), -3);
|
||||
@ -87,8 +89,8 @@ class table_core : public reference {
|
||||
|
||||
template<typename Pairs, std::size_t... I>
|
||||
void tuple_set( indices<I...>, Pairs&& pairs ) {
|
||||
using swallow = int[];
|
||||
swallow{ 0, ( single_set(std::get<I * 2>(pairs), std::get<I * 2 + 1>(pairs)) , 0)..., 0 };
|
||||
using swallow = int[];
|
||||
swallow{ 0, ( single_set(std::get<I * 2>(pairs), std::get<I * 2 + 1>(pairs)) , 0)..., 0 };
|
||||
}
|
||||
|
||||
#if SOL_LUA_VERSION < 502
|
||||
@ -105,14 +107,12 @@ public:
|
||||
|
||||
template<typename... Ret, typename... Keys>
|
||||
decltype(auto) get( Keys&&... keys ) const {
|
||||
auto pp = detail::push_pop<const table_core&>(*this);
|
||||
return tuple_get( types<Ret...>( ), build_indices<sizeof...( Ret )>( ), std::forward_as_tuple(std::forward<Keys>(keys)...));
|
||||
}
|
||||
|
||||
template<typename... Tn>
|
||||
table_core& set( Tn&&... argn ) {
|
||||
auto pp = detail::push_pop<const table_core&>(*this);
|
||||
tuple_set(build_indices<sizeof...(Tn) / 2>(), std::forward_as_tuple(std::forward<Tn>(argn)...));
|
||||
tuple_set(build_indices<sizeof...(Tn) / 2>(), std::forward_as_tuple(std::forward<Tn>(argn)...));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -136,21 +136,19 @@ public:
|
||||
if ( top_level ) {
|
||||
stack::push( lua_state( ), user );
|
||||
lua_setglobal( lua_state( ), &key[ 0 ] );
|
||||
pop( );
|
||||
}
|
||||
else {
|
||||
push( );
|
||||
auto pp = stack::push_popper( *this );
|
||||
stack::push( lua_state( ), std::forward<Key>( key ) );
|
||||
stack::push( lua_state( ), user );
|
||||
lua_settable( lua_state( ), -3 );
|
||||
pop( );
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Fx>
|
||||
void for_each( Fx&& fx ) const {
|
||||
push( );
|
||||
auto pp = stack::push_popper( *this );
|
||||
stack::push( lua_state( ), nil );
|
||||
while ( lua_next( this->lua_state( ), -2 ) ) {
|
||||
sol::object key( lua_state( ), -2 );
|
||||
@ -158,14 +156,11 @@ public:
|
||||
fx( key, value );
|
||||
lua_pop( lua_state( ), 1 );
|
||||
}
|
||||
pop( );
|
||||
}
|
||||
|
||||
size_t size( ) const {
|
||||
push( );
|
||||
size_t result = lua_rawlen( lua_state( ), -1 );
|
||||
pop( );
|
||||
return result;
|
||||
auto pp = stack::push_popper( *this );
|
||||
return lua_rawlen(lua_state(), -1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -238,11 +233,10 @@ private:
|
||||
|
||||
template<typename... Sig, typename... Args, typename Key, DisableIf<Not<std::is_arithmetic<Unqualified<Key>>>, Bool<top_level>> = 0>
|
||||
void set_resolved_function( Key&& key, Args&&... args ) {
|
||||
push( );
|
||||
auto pp = stack::push_popper( *this );
|
||||
int tabletarget = lua_gettop( lua_state( ) );
|
||||
stack::push<function_sig_t<Sig...>>( lua_state( ), std::forward<Args>( args )... );
|
||||
lua_setfield( lua_state( ), tabletarget, &key[ 0 ] );
|
||||
pop( );
|
||||
}
|
||||
};
|
||||
} // sol
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -44,7 +44,7 @@ struct unwrap {
|
||||
|
||||
template<typename T>
|
||||
struct unwrap<std::reference_wrapper<T>> {
|
||||
typedef typename std::add_lvalue_reference<T>::type type;
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -321,7 +321,7 @@ auto unwrapper(T&& item) -> decltype(std::forward<T>(item)) {
|
||||
}
|
||||
|
||||
template<typename Arg>
|
||||
Unwrap<Arg> unwrapper(std::reference_wrapper<Arg> arg) {
|
||||
Arg& unwrapper(std::reference_wrapper<Arg> arg) {
|
||||
return arg.get();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -93,9 +93,6 @@ struct constructors {};
|
||||
|
||||
const auto default_constructor = constructors<types<>>{};
|
||||
|
||||
template <typename T>
|
||||
using ref = std::reference_wrapper<T>;
|
||||
|
||||
} // sol
|
||||
|
||||
#endif // SOL_TUPLE_HPP
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
@ -126,9 +126,8 @@ template <bool>
|
||||
class table_core;
|
||||
typedef table_core<false> table;
|
||||
typedef table_core<true> global_table;
|
||||
class fast_function;
|
||||
class safe_function;
|
||||
typedef safe_function function;
|
||||
class function;
|
||||
class protected_function;
|
||||
class object;
|
||||
|
||||
template <typename T, typename = void>
|
||||
@ -165,7 +164,7 @@ template <>
|
||||
struct lua_type_of<function> : std::integral_constant<type, type::function> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<fast_function> : std::integral_constant<type, type::function> {};
|
||||
struct lua_type_of<protected_function> : std::integral_constant<type, type::function> {};
|
||||
|
||||
template <typename Signature>
|
||||
struct lua_type_of<std::function<Signature>> : std::integral_constant<type, type::function>{};
|
||||
@ -195,6 +194,14 @@ struct lua_type_of<T, typename std::enable_if<std::is_enum<T>::value>::type> : s
|
||||
template <typename T>
|
||||
struct is_lua_primitive : std::integral_constant<bool, type::userdata != lua_type_of<Unqualified<T>>::value> { };
|
||||
|
||||
template <typename T>
|
||||
struct is_proxy_primitive : is_lua_primitive<T> { };
|
||||
|
||||
template <typename T>
|
||||
struct is_proxy_primitive<std::reference_wrapper<T>> : std::true_type { };
|
||||
|
||||
template <typename... Tn>
|
||||
struct is_proxy_primitive<std::tuple<Tn...>> : std::true_type { };
|
||||
} // sol
|
||||
|
||||
#endif // SOL_TYPES_HPP
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -1,6 +1,6 @@
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2015 Rapptz and contributors
|
||||
// Copyright (c) 2013-2016 Rapptz and contributors
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
|
176
tests.cpp
176
tests.cpp
@ -198,7 +198,7 @@ struct giver {
|
||||
|
||||
};
|
||||
|
||||
TEST_CASE("simple/set_global", "Check if the set_global works properly.") {
|
||||
TEST_CASE("simple/set", "Check if the set works properly.") {
|
||||
sol::state lua;
|
||||
|
||||
lua.set("a", 9);
|
||||
@ -207,10 +207,8 @@ TEST_CASE("simple/set_global", "Check if the set_global works properly.") {
|
||||
lua.set("d", "hello");
|
||||
REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
||||
|
||||
lua.set("e", std::string("hello"));
|
||||
lua.set("e", std::string("hello"), "f", true);
|
||||
REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
||||
|
||||
lua.set("f", true);
|
||||
REQUIRE_NOTHROW(lua.script("if f ~= true then error('wrong value') end"));
|
||||
}
|
||||
|
||||
@ -225,11 +223,11 @@ TEST_CASE("simple/get", "Tests if the get function works properly.") {
|
||||
REQUIRE_NOTHROW(lua.get<sol::nil_t>("b"));
|
||||
|
||||
lua.script("d = 'hello'");
|
||||
auto d = lua.get<std::string>("d");
|
||||
REQUIRE(d == "hello");
|
||||
|
||||
lua.script("e = true");
|
||||
auto e = lua.get<bool>("e");
|
||||
std::string d;
|
||||
bool e;
|
||||
std::tie( d, e ) = lua.get<std::string, bool>("d", "e");
|
||||
REQUIRE(d == "hello");
|
||||
REQUIRE(e == true);
|
||||
}
|
||||
|
||||
@ -265,7 +263,7 @@ TEST_CASE("simple/call_with_parameters", "Lua function is called with a few para
|
||||
REQUIRE_NOTHROW(fvoid(1, 2, 3));
|
||||
REQUIRE_NOTHROW(a = f.call<int>(1, 2, 3));
|
||||
REQUIRE(a == 6);
|
||||
REQUIRE_THROWS(a = f.call<int>(1, 2, "arf"));
|
||||
REQUIRE_THROWS(a = f(1, 2, "arf"));
|
||||
}
|
||||
|
||||
TEST_CASE("simple/call_c++_function", "C++ function is called from lua") {
|
||||
@ -627,7 +625,7 @@ TEST_CASE("tables/usertype", "Show that we can create classes from usertype and
|
||||
REQUIRE(cresult == 3);
|
||||
}
|
||||
|
||||
TEST_CASE("tables/usertype constructors", "Show that we can create classes from usertype and use them with multiple destructors") {
|
||||
TEST_CASE("tables/usertype constructors", "Show that we can create classes from usertype and use them with multiple constructors") {
|
||||
|
||||
sol::state lua;
|
||||
|
||||
@ -704,19 +702,25 @@ TEST_CASE("tables/usertype utility derived", "usertype classes must play nice wh
|
||||
lua.set_usertype(baseusertype);
|
||||
|
||||
lua.script("base = Base.new(5)");
|
||||
lua.script("print(base:get_num())");
|
||||
REQUIRE_NOTHROW(lua.script("print(base:get_num())"));
|
||||
|
||||
sol::constructors<sol::types<int>> derivedctor;
|
||||
sol::usertype<Derived> derivedusertype(derivedctor, "get_num", &Derived::get_num, "get_num_10", &Derived::get_num_10);
|
||||
/*sol::constructors<sol::types<int>> derivedctor;
|
||||
sol::usertype<Derived> derivedusertype(derivedctor,
|
||||
"get_num_10", &Derived::get_num_10,
|
||||
"get_num", &Derived::get_num
|
||||
);
|
||||
|
||||
lua.set_usertype(derivedusertype);
|
||||
|
||||
lua.script("derived = Derived.new(7)");
|
||||
lua.script("dgn10 = derived:get_num_10()\nprint(dgn10)");
|
||||
lua.script("dgn = derived:get_num()\nprint(dgn)");
|
||||
Derived& derived = lua["derived"];
|
||||
lua.script("dgn = derived:get_num()\n"
|
||||
"print(dgn)");
|
||||
lua.script("dgn10 = derived:get_num_10()\n"
|
||||
"print(dgn10)");
|
||||
|
||||
REQUIRE((lua.get<int>("dgn10") == 70));
|
||||
REQUIRE((lua.get<int>("dgn") == 7));
|
||||
REQUIRE((lua.get<int>("dgn") == 7));*/
|
||||
}
|
||||
|
||||
TEST_CASE("tables/self-referential usertype", "usertype classes must play nice when C++ object types are requested for C++ code") {
|
||||
@ -856,24 +860,11 @@ TEST_CASE("tables/issue-number-twenty-five", "Using pointers and references from
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/issue-number-thirty-five", "using value types created from lua-called C++ code, fixing user-defined types with constructors") {
|
||||
struct Line {
|
||||
Vec p1, p2;
|
||||
Line() : p1{0, 0, 0}, p2{0, 0, 0} {}
|
||||
Line(float x) : p1{x, x, x}, p2{x, x, x} {}
|
||||
Line(const Vec& p1) : p1{p1}, p2{p1} {}
|
||||
Line(Vec p1, Vec p2) : p1{p1}, p2{p2} {}
|
||||
};
|
||||
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base);
|
||||
|
||||
sol::constructors<sol::types<>, sol::types<Vec>, sol::types<Vec, Vec>> lctor;
|
||||
sol::usertype<Line> ludata(lctor);
|
||||
lua.set_usertype("Line", ludata);
|
||||
|
||||
sol::constructors<sol::types<float, float, float>> ctor;
|
||||
sol::usertype<Vec> udata(ctor, "normalized", &Vec::normalized, "length", &Vec::length);
|
||||
|
||||
lua.set_usertype(udata);
|
||||
|
||||
REQUIRE_NOTHROW(lua.script("v = Vec.new(1, 2, 3)\n"
|
||||
@ -971,20 +962,26 @@ TEST_CASE("references/get-set", "properly get and set with std::ref semantics. N
|
||||
|
||||
lua.new_usertype<vars>("vars",
|
||||
"boop", &vars::boop);
|
||||
|
||||
vars var{};
|
||||
vars rvar{};
|
||||
lua.set("beep", var);
|
||||
lua.set("rbeep", std::ref(rvar));
|
||||
auto& my_var = lua.get<vars>("beep");
|
||||
auto& ref_var = lua.get<sol::ref<vars>>("rbeep");
|
||||
|
||||
auto& ref_var = lua.get<std::reference_wrapper<vars>>("rbeep");
|
||||
vars& proxy_my_var = lua["beep"];
|
||||
std::reference_wrapper<vars> proxy_ref_var = lua["rbeep"];
|
||||
var.boop = 2;
|
||||
rvar.boop = 5;
|
||||
|
||||
// Was return as a value: var must be diferent from "beep"
|
||||
REQUIRE_FALSE(std::addressof(var) == std::addressof(my_var));
|
||||
REQUIRE_FALSE(std::addressof(proxy_my_var) == std::addressof(var));
|
||||
REQUIRE((my_var.boop == 0));
|
||||
REQUIRE(var.boop != my_var.boop);
|
||||
// Reference should point back to the same type.
|
||||
|
||||
REQUIRE(std::addressof(ref_var) == std::addressof(rvar));
|
||||
//REQUIRE(std::addressof(proxy_ref_var.get()) == std::addressof(rvar));
|
||||
REQUIRE(rvar.boop == 5);
|
||||
REQUIRE(rvar.boop == ref_var.boop);
|
||||
}
|
||||
|
||||
@ -1003,7 +1000,7 @@ TEST_CASE("interop/null-to-nil-and-back", "nil should be the given type when a p
|
||||
"assert(x == nil)"));
|
||||
}
|
||||
|
||||
TEST_CASE( "functions/sol::function_result", "Function result should be the beefy return type for sol::function that allows for error checking and error handlers" ) {
|
||||
TEST_CASE( "functions/function_result-protected_function", "Function result should be the beefy return type for sol::function that allows for error checking and error handlers" ) {
|
||||
sol::state lua;
|
||||
lua.open_libraries( sol::lib::base, sol::lib::debug );
|
||||
|
||||
@ -1032,8 +1029,8 @@ TEST_CASE( "functions/sol::function_result", "Function result should be the beef
|
||||
+ "end"
|
||||
);
|
||||
|
||||
sol::function func = lua[ "doom" ];
|
||||
sol::function luafunc = lua[ "luadoom" ];
|
||||
sol::protected_function func = lua[ "doom" ];
|
||||
sol::protected_function luafunc = lua[ "luadoom" ];
|
||||
sol::function luahandler = lua[ "handler" ];
|
||||
sol::function cpphandler = lua[ "cpphandler" ];
|
||||
func.error_handler = luahandler;
|
||||
@ -1049,5 +1046,110 @@ TEST_CASE( "functions/sol::function_result", "Function result should be the beef
|
||||
REQUIRE(!result2.valid());
|
||||
errorstring = result2;
|
||||
REQUIRE(errorstring == errormessage2);
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("functions/destructor-tests", "Show that proper copies / destruction happens") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
static void* last_call = nullptr;
|
||||
static void* static_call = reinterpret_cast<void*>(0x01);
|
||||
typedef void(* fptr)();
|
||||
struct x {
|
||||
x() {++created;}
|
||||
x(const x&) {++created;}
|
||||
x(x&&) {++created;}
|
||||
x& operator=(const x&) {++created; return *this;}
|
||||
x& operator=(x&&) {++created; 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;}
|
||||
};
|
||||
|
||||
// stateful functors/member functions should always copy unless specified
|
||||
{
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
last_call = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
x x1;
|
||||
lua.set_function("x1copy", &x::func, x1);
|
||||
lua.script("x1copy()");
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(last_call == &x1);
|
||||
|
||||
lua.set_function("x1ref", &x::func, std::ref(x1));
|
||||
lua.script("x1ref()");
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == &x1);
|
||||
}
|
||||
REQUIRE(created == 2);
|
||||
REQUIRE(destroyed == 2);
|
||||
REQUIRE(created == destroyed);
|
||||
}
|
||||
|
||||
// things convertible to a static function should _never_ be forced to make copies
|
||||
// therefore, pass through untouched
|
||||
{
|
||||
created = 0;
|
||||
destroyed = 0;
|
||||
last_call = nullptr;
|
||||
{
|
||||
sol::state lua;
|
||||
y y1;
|
||||
lua.set_function("y1copy", y1);
|
||||
lua.script("y1copy()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == static_call);
|
||||
|
||||
last_call = nullptr;
|
||||
lua.set_function("y1ref", std::ref(y1));
|
||||
lua.script("y1ref()");
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE(last_call == static_call);
|
||||
}
|
||||
REQUIRE(created == 1);
|
||||
REQUIRE(destroyed == 1);
|
||||
REQUIRE(created == destroyed);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("usertype/destructor-tests", "Show that proper copies / destruction happens") {
|
||||
static int created = 0;
|
||||
static int destroyed = 0;
|
||||
static void* last_call = nullptr;
|
||||
struct x {
|
||||
x() {++created;}
|
||||
~x () {++destroyed;}
|
||||
};
|
||||
{
|
||||
sol::state lua;
|
||||
x x1;
|
||||
x x2;
|
||||
lua.set("x1copy", x1, "x2copy", x2, "x1ref", std::ref(x1));
|
||||
x& x1copyref = lua["x1copy"];
|
||||
x& x2copyref = lua["x2copy"];
|
||||
x& x1ref = lua["x1ref"];
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 0);
|
||||
REQUIRE_FALSE(last_call == &x1);
|
||||
REQUIRE(std::addressof(x1) == std::addressof(x1ref));
|
||||
}
|
||||
REQUIRE(created == 4);
|
||||
REQUIRE(destroyed == 4);
|
||||
REQUIRE(created == destroyed);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user