2021-03-06 23:14:48 +08:00
// sol2
2017-12-20 17:58:32 +08:00
// The MIT License (MIT)
2022-06-25 16:00:53 +08:00
// Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
2017-12-20 17:58:32 +08:00
// 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.
2018-12-20 12:17:15 +08:00
# include "sol_test.hpp"
2018-12-20 14:18:07 +08:00
# include "common_classes.hpp"
2016-08-24 09:42:27 +08:00
2022-06-23 04:32:13 +08:00
# include <catch2/catch_all.hpp>
2016-08-24 09:42:27 +08:00
# include <iterator>
# include <vector>
# include <list>
2017-08-06 07:20:28 +08:00
# include <forward_list>
2016-08-24 09:42:27 +08:00
# include <map>
2017-08-06 07:20:28 +08:00
# include <deque>
# include <array>
2016-08-24 09:42:27 +08:00
# include <unordered_map>
2016-08-27 20:45:37 +08:00
# include <set>
# include <unordered_set>
2016-08-24 09:42:27 +08:00
2019-09-15 12:43:44 +08:00
inline namespace sol2_test_containers {
struct returns_callable {
std : : vector < int > * ptr ;
returns_callable ( std : : vector < int > & ref_ ) : ptr ( & ref_ ) {
}
std : : vector < int > & operator ( ) ( ) const {
REQUIRE ( ptr - > size ( ) = = 3 ) ;
return * ptr ;
}
} ;
} // namespace sol2_test_containers
2016-08-24 09:42:27 +08:00
TEST_CASE ( " containers/returns " , " make sure that even references to vectors are being serialized as tables " ) {
sol : : state lua ;
2020-11-20 04:12:56 +08:00
std : : vector < int > v { 1 , 2 , 3 } ;
2019-09-15 12:43:44 +08:00
returns_callable f ( v ) ;
2019-08-15 13:26:52 +08:00
lua . set_function ( " f " , f ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " x = f() " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-08-24 09:42:27 +08:00
sol : : object x = lua [ " x " ] ;
sol : : type xt = x . get_type ( ) ;
REQUIRE ( xt = = sol : : type : : userdata ) ;
sol : : table t = x ;
bool matching ;
matching = t [ 1 ] = = 1 ;
REQUIRE ( matching ) ;
matching = t [ 2 ] = = 2 ;
REQUIRE ( matching ) ;
matching = t [ 3 ] = = 3 ;
REQUIRE ( matching ) ;
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " containers/custom usertype " , " make sure container usertype metatables can be overridden " ) {
2016-08-24 09:42:27 +08:00
typedef std : : unordered_map < int , int > bark ;
2017-09-17 02:18:45 +08:00
2016-08-24 09:42:27 +08:00
sol : : state lua ;
lua . open_libraries ( ) ;
2020-11-20 04:12:56 +08:00
lua . new_usertype < bark > (
" bark " ,
2019-08-15 13:26:52 +08:00
" something " ,
[ ] ( const bark & b ) { INFO ( " It works: " < < b . at ( 24 ) ) ; } ,
" size " ,
& bark : : size ,
" at " ,
sol : : resolve < const int & > ( & bark : : at ) ,
" clear " ,
& bark : : clear ) ;
2020-11-20 04:12:56 +08:00
bark obj { { 24 , 50 } } ;
2016-08-24 09:42:27 +08:00
lua . set ( " a " , & obj ) ;
2017-12-07 21:24:50 +08:00
{
auto result0 = lua . safe_script ( " assert(a:at(24) == 50) " , sol : : script_pass_on_error ) ;
REQUIRE ( result0 . valid ( ) ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " a:something() " , sol : : script_pass_on_error ) ;
2017-12-07 21:24:50 +08:00
REQUIRE ( result1 . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
lua . set ( " a " , obj ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " assert(a:at(24) == 50) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " a:something() " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " containers/const serialization kvp " , " make sure const keys / values are respected " ) {
2016-08-24 09:42:27 +08:00
typedef std : : map < int , const int > bark ;
sol : : state lua ;
lua . open_libraries ( ) ;
2017-12-07 21:24:50 +08:00
{
2020-11-20 04:12:56 +08:00
bark obj { { 24 , 50 } } ;
2017-12-07 21:24:50 +08:00
lua . set ( " a " , std : : ref ( obj ) ) ;
auto result0 = lua . safe_script ( " assert(a[24] == 50) " , sol : : script_pass_on_error ) ;
REQUIRE ( result0 . valid ( ) ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " a[24] = 51 " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result1 . valid ( ) ) ;
2017-12-07 21:24:50 +08:00
auto result2 = lua . safe_script ( " assert(a[24] == 50) " , sol : : script_pass_on_error ) ;
REQUIRE ( result2 . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " containers/basic serialization " , " make sure containers are turned into proper userdata and have basic hooks established " ) {
2016-08-24 09:42:27 +08:00
typedef std : : vector < int > woof ;
sol : : state lua ;
lua . open_libraries ( ) ;
2020-11-20 04:12:56 +08:00
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 } ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " for k = 1, #b do assert(k == b[k]) end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2020-11-20 04:12:56 +08:00
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 } ;
2016-08-24 09:42:27 +08:00
lua . set ( " b " , w ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " for k = 1, #b do assert(k == b[k]) end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
lua . set ( " b " , & w ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " for k = 1, #b do assert(k == b[k]) end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
lua . set ( " b " , std : : ref ( w ) ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " for k = 1, #b do assert(k == b[k]) end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
}
2017-08-06 07:20:28 +08:00
#if 0 // LUL const int holders
TEST_CASE ( " containers/const serialization " , " make sure containers are turned into proper userdata and the basic hooks respect const-ness " ) {
2016-08-24 09:42:27 +08:00
typedef std : : vector < const int > woof ;
sol : : state lua ;
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 } ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " for k, v in pairs(b) do assert(k == v) end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " b[1] = 20 " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
}
2016-08-24 09:42:27 +08:00
}
2017-08-06 07:20:28 +08:00
# endif
2016-08-24 09:42:27 +08:00
2017-07-10 00:00:57 +08:00
TEST_CASE ( " containers/const correctness " , " usertype metatable names should reasonably ignore const attributes " ) {
2016-08-24 09:42:27 +08:00
struct Vec {
int x , y , z ;
} ;
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
lua . new_usertype < Vec > ( " Vec " , " x " , & Vec : : x , " y " , & Vec : : y , " z " , & Vec : : z ) ;
Vec vec ;
vec . x = 1 ;
vec . y = 2 ;
vec . z = - 3 ;
std : : vector < Vec > foo ;
foo . push_back ( vec ) ;
2017-09-17 02:18:45 +08:00
std : : vector < Vec const * > bar ;
2016-08-24 09:42:27 +08:00
bar . push_back ( & vec ) ;
2018-01-29 11:21:13 +08:00
auto result0 = lua . safe_script ( R " (
2016-08-24 09:42:27 +08:00
func = function ( vecs )
2016-08-24 20:31:18 +08:00
for i = 1 , # vecs do
vec = vecs [ i ]
2016-08-24 09:42:27 +08:00
print ( i , " : " , vec . x , vec . y , vec . z )
end
end
2019-08-15 13:26:52 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result0 . valid ( ) ) ;
sol : : protected_function f ( lua [ " func " ] ) ;
auto pfr1 = f ( foo ) ;
REQUIRE ( pfr1 . valid ( ) ) ;
auto pfr2 = f ( bar ) ;
REQUIRE ( pfr2 . valid ( ) ) ;
2016-08-24 09:42:27 +08:00
}
2019-08-15 13:26:52 +08:00
TEST_CASE (
" containers/usertype transparency " , " Make sure containers pass their arguments through transparently and push the results as references, not new values " ) {
2016-09-29 07:05:26 +08:00
class A {
public :
int a ;
2020-11-20 04:12:56 +08:00
A ( int b = 2 ) : a ( b ) { } ;
2016-09-29 07:05:26 +08:00
2017-09-17 02:18:45 +08:00
void func ( ) {
}
2016-09-29 07:05:26 +08:00
} ;
struct B {
B ( ) {
for ( std : : size_t i = 0 ; i < 20 ; + + i ) {
a_list . emplace_back ( static_cast < int > ( i ) ) ;
}
}
std : : vector < A > a_list ;
} ;
sol : : state lua ;
2019-08-15 13:26:52 +08:00
lua . new_usertype < B > ( " B " , " a_list " , & B : : a_list ) ;
2016-09-29 07:05:26 +08:00
2018-01-29 11:21:13 +08:00
auto result = lua . safe_script ( R " (
2016-09-29 07:05:26 +08:00
b = B . new ( )
a_ref = b . a_list [ 2 ]
2019-08-15 13:26:52 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result . valid ( ) ) ;
2016-09-29 07:05:26 +08:00
B & b = lua [ " b " ] ;
A & a_ref = lua [ " a_ref " ] ;
REQUIRE ( & b . a_list [ 1 ] = = & a_ref ) ;
REQUIRE ( b . a_list [ 1 ] . a = = a_ref . a ) ;
}
2016-11-08 02:52:20 +08:00
struct options {
static int livingcount ;
static options * last ;
options ( ) {
+ + livingcount ;
last = this ;
INFO ( " constructor: " < < this ) ;
}
std : : string output_help ( ) {
last = this ;
INFO ( " func: " < < this ) ;
return " " ;
}
2017-09-17 02:18:45 +08:00
void begin ( ) {
}
void end ( ) {
}
2016-11-08 02:52:20 +08:00
~ options ( ) {
last = this ;
- - livingcount ;
}
} ;
options * options : : last = nullptr ;
int options : : livingcount = 0 ;
struct machine {
options opt ;
} ;
namespace sol {
template < >
2020-11-20 04:12:56 +08:00
struct is_container < options > : std : : false_type { } ;
2017-09-17 02:18:45 +08:00
} // namespace sol
2016-11-08 02:52:20 +08:00
2017-07-10 00:00:57 +08:00
TEST_CASE ( " containers/is container " , " make sure the is_container trait behaves properly " ) {
2016-11-08 02:52:20 +08:00
sol : : state lua ;
lua . open_libraries ( ) ;
2019-08-15 13:26:52 +08:00
lua . new_usertype < options > ( " options_type " , " output_help " , & options : : output_help ) ;
2016-11-08 02:52:20 +08:00
2019-08-15 13:26:52 +08:00
lua . new_usertype < machine > (
" machine_type " , " new " , sol : : no_constructor , " opt " , [ ] ( machine & m ) { return & m . opt ; } , " copy_opt " , [ ] ( machine & m ) { return m . opt ; } ) ;
2016-11-08 02:52:20 +08:00
2017-09-17 02:18:45 +08:00
{
2016-11-08 02:52:20 +08:00
machine m ;
lua [ " machine " ] = & m ;
2018-01-29 11:21:13 +08:00
auto result0 = lua . safe_script ( R " (
machine : opt ( ) : output_help ( )
2019-08-15 13:26:52 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result0 . valid ( ) ) ;
2016-11-08 02:52:20 +08:00
REQUIRE ( options : : last = = & m . opt ) ;
REQUIRE ( options : : livingcount = = 1 ) ;
}
REQUIRE ( options : : livingcount = = 0 ) ;
}
2016-11-15 02:42:55 +08:00
TEST_CASE ( " containers/readonly " , " make sure readonly members are stored appropriately " ) {
sol : : state lua ;
lua . open_libraries ( ) ;
struct bar {
int x = 24 ;
} ;
struct foo {
std : : list < bar > seq ;
} ;
2019-08-15 13:26:52 +08:00
lua . new_usertype < foo > ( " foo " ,
" seq " ,
& foo : : seq , // this one works
" readonly_seq " ,
2020-11-20 04:12:56 +08:00
sol : : readonly ( & foo : : seq ) ) ;
lua [ " value " ] = std : : list < bar > { { } , { } , { } } ;
2017-09-17 02:18:45 +08:00
2018-01-29 11:21:13 +08:00
auto result0 = lua . safe_script ( R " (
2016-11-15 02:42:55 +08:00
a = foo . new ( )
x = a . seq
a . seq = value
y = a . readonly_seq
2019-08-15 13:26:52 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result0 . valid ( ) ) ;
2016-11-15 02:42:55 +08:00
std : : list < bar > & seqrefx = lua [ " x " ] ;
std : : list < bar > & seqrefy = lua [ " y " ] ;
REQUIRE ( & seqrefx = = & seqrefy ) ;
REQUIRE ( seqrefx . size ( ) = = 3 ) ;
2017-12-11 04:56:49 +08:00
auto result = lua . safe_script ( " a.readonly_seq = value " , sol : : script_pass_on_error ) ;
2016-11-15 02:42:55 +08:00
REQUIRE_FALSE ( result . valid ( ) ) ;
}
2016-11-27 02:58:06 +08:00
TEST_CASE ( " containers/to_args " , " Test that the to_args abstractions works " ) {
sol : : state lua ;
lua . open_libraries ( ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " function f (a, b, c, d) print(a, b, c, d) return a, b, c, d end " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-11-27 02:58:06 +08:00
sol : : function f = lua [ " f " ] ;
int a , b , c , d ;
2020-11-20 04:12:56 +08:00
std : : vector < int > v2 { 3 , 4 } ;
2016-11-27 02:58:06 +08:00
sol : : tie ( a , b , c , d ) = f ( 1 , 2 , sol : : as_args ( v2 ) ) ;
REQUIRE ( a = = 1 ) ;
REQUIRE ( b = = 2 ) ;
REQUIRE ( c = = 3 ) ;
REQUIRE ( d = = 4 ) ;
2020-11-20 04:12:56 +08:00
std : : set < int > v4 { 7 , 6 , 8 , 5 } ;
2016-11-27 02:58:06 +08:00
sol : : tie ( a , b , c , d ) = f ( sol : : as_args ( v4 ) ) ;
REQUIRE ( a = = 5 ) ;
REQUIRE ( b = = 6 ) ;
REQUIRE ( c = = 7 ) ;
REQUIRE ( d = = 8 ) ;
int v3 [ ] = { 10 , 11 , 12 } ;
sol : : tie ( a , b , c , d ) = f ( 9 , sol : : as_args ( v3 ) ) ;
REQUIRE ( a = = 9 ) ;
REQUIRE ( b = = 10 ) ;
REQUIRE ( c = = 11 ) ;
REQUIRE ( d = = 12 ) ;
}
2017-03-16 22:12:17 +08:00
2017-07-10 00:00:57 +08:00
TEST_CASE ( " containers/append idiom " , " ensure the append-idiom works as intended " ) {
2017-04-08 20:25:49 +08:00
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
2019-08-15 13:26:52 +08:00
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script (
2019-08-15 13:26:52 +08:00
R " (
2017-04-08 20:25:49 +08:00
function f_fill ( vec )
print ( " #vec in lua: " . . # vec )
for k = 1 , # vec do
vec [ k ] = k
end
print ( " #vec in lua: " . . # vec )
end
function f_append ( vec )
print ( " #vec in lua: " . . # vec )
2022-06-23 04:32:13 +08:00
vec [ Issue - vec ] = - 10456407
vec [ Issue - vec + 1 ] = - 54
2017-04-08 20:25:49 +08:00
print ( " #vec in lua: " . . # vec )
end
2019-08-15 13:26:52 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result1 . valid ( ) ) ;
2020-11-20 04:12:56 +08:00
std : : vector < int > fill_cmp { 1 , 2 , 3 } ;
std : : vector < int > append_cmp { - 1 , - 1 , - 10456407 , - 54 } ;
2017-04-08 20:25:49 +08:00
2020-11-20 04:12:56 +08:00
std : : vector < int > vec1 { - 1 , - 1 , - 1 } ;
std : : vector < int > vec2 { - 1 , - 1 , - 1 } ;
2017-04-08 20:25:49 +08:00
REQUIRE ( vec1 . size ( ) = = 3 ) ;
lua [ " f_fill " ] ( vec1 ) ;
REQUIRE ( vec1 . size ( ) = = 3 ) ;
REQUIRE ( vec1 = = fill_cmp ) ;
REQUIRE ( vec2 . size ( ) = = 3 ) ;
lua [ " f_append " ] ( vec2 ) ;
REQUIRE ( vec2 . size ( ) = = 4 ) ;
REQUIRE ( vec2 = = append_cmp ) ;
}
2017-05-21 08:01:04 +08:00
TEST_CASE ( " containers/non_copyable " , " make sure non-copyable types in containers behave properly when stored as a member variable in a bound usertype " ) {
struct test {
std : : vector < non_copyable > b ;
2019-08-15 13:26:52 +08:00
test ( ) : b ( ) {
2017-09-17 02:18:45 +08:00
}
2017-05-21 08:01:04 +08:00
test ( test & & ) = default ;
test & operator = ( test & & ) = default ;
test ( const test & ) = delete ;
test & operator = ( const test & ) = delete ;
} ;
SECTION ( " normal " ) {
sol : : state lua ;
2019-08-15 13:26:52 +08:00
lua . new_usertype < test > ( " test " , " b " , sol : : readonly ( & test : : b ) ) ;
2017-05-21 08:01:04 +08:00
2020-11-20 04:12:56 +08:00
lua [ " v " ] = std : : vector < non_copyable > { } ;
2017-05-21 08:01:04 +08:00
2017-12-11 04:56:49 +08:00
auto pfr = lua . safe_script ( " t = test.new() t.b = v " , sol : : script_pass_on_error ) ;
2017-08-11 15:24:17 +08:00
REQUIRE_FALSE ( pfr . valid ( ) ) ;
2017-05-21 08:01:04 +08:00
}
}
2017-05-29 22:32:37 +08:00
2017-06-24 06:07:24 +08:00
TEST_CASE ( " containers/pairs " , " test how well pairs work with the underlying system " ) {
2019-02-14 15:40:57 +08:00
using pair_arr_t = std : : pair < std : : string , int > [ 5 ] ;
using arr_t = int [ 5 ] ;
2017-08-11 15:24:17 +08:00
2017-06-24 06:07:24 +08:00
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
2020-11-20 04:12:56 +08:00
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 } } ;
2017-08-11 15:24:17 +08:00
arr_t d = { 1 , 2 , 3 , 4 , 5 } ;
2017-06-24 06:07:24 +08:00
lua [ " a " ] = std : : ref ( a ) ;
lua [ " b " ] = & b ;
2017-08-11 15:24:17 +08:00
lua [ " c " ] = std : : ref ( c ) ;
lua [ " d " ] = & d ;
2017-06-24 06:07:24 +08:00
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " av1, av2 = a:get(1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
auto result2 = lua . safe_script ( " bv1, bv2 = b:get(1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result2 . valid ( ) ) ;
auto result3 = lua . safe_script ( " cv1, cv2 = c:get(1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result3 . valid ( ) ) ;
auto result4 = lua . safe_script ( " dv1, dv2 = d:get(1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result4 . valid ( ) ) ;
2017-06-24 06:07:24 +08:00
std : : vector < std : : pair < std : : string , int > > & la = lua [ " a " ] ;
std : : array < std : : pair < std : : string , int > , 5 > & lb = lua [ " b " ] ;
2017-08-11 15:24:17 +08:00
pair_arr_t * plc = lua [ " c " ] ;
pair_arr_t & lc = * plc ;
arr_t * pld = lua [ " d " ] ;
arr_t & ld = * pld ;
2017-06-24 06:07:24 +08:00
std : : pair < std : : string , int > & va = la [ 0 ] ;
std : : pair < std : : string , int > & vb = lb [ 0 ] ;
2017-08-11 15:24:17 +08:00
std : : pair < std : : string , int > & vc = lc [ 0 ] ;
int & vd = ld [ 0 ] ;
2017-06-24 06:07:24 +08:00
std : : string av1 = lua [ " av1 " ] ;
int av2 = lua [ " av2 " ] ;
std : : string bv1 = lua [ " bv1 " ] ;
int bv2 = lua [ " bv2 " ] ;
2017-08-11 15:24:17 +08:00
std : : string cv1 = lua [ " cv1 " ] ;
int cv2 = lua [ " cv2 " ] ;
int dv1 = lua [ " dv1 " ] ;
sol : : lua_nil_t dv2 = lua [ " dv2 " ] ;
2017-06-24 06:07:24 +08:00
REQUIRE ( va . first = = " one " ) ;
REQUIRE ( va . second = = 1 ) ;
REQUIRE ( vb . first = = " one " ) ;
REQUIRE ( vb . second = = 1 ) ;
2017-08-11 15:24:17 +08:00
REQUIRE ( vc . first = = " one " ) ;
REQUIRE ( vc . second = = 1 ) ;
REQUIRE ( vd = = 1 ) ;
2017-06-24 06:07:24 +08:00
REQUIRE ( av1 = = " one " ) ;
REQUIRE ( av2 = = 1 ) ;
REQUIRE ( bv1 = = " one " ) ;
REQUIRE ( bv2 = = 1 ) ;
2017-08-11 15:24:17 +08:00
REQUIRE ( cv1 = = " one " ) ;
REQUIRE ( cv2 = = 1 ) ;
REQUIRE ( dv1 = = 1 ) ;
REQUIRE ( dv2 = = sol : : lua_nil ) ;
}
TEST_CASE ( " containers/pointer types " , " check that containers with unique usertypes and pointers or something " ) {
struct base_t {
virtual int get ( ) const = 0 ;
2019-08-15 13:26:52 +08:00
virtual ~ base_t ( ) {
}
2017-08-11 15:24:17 +08:00
} ;
struct derived_1_t : base_t {
virtual int get ( ) const override {
return 250 ;
}
} ;
struct derived_2_t : base_t {
virtual int get ( ) const override {
return 500 ;
}
} ;
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
derived_1_t d1 ;
derived_2_t d2 ;
std : : vector < std : : unique_ptr < base_t > > v1 ;
v1 . push_back ( std : : make_unique < derived_1_t > ( ) ) ;
v1 . push_back ( std : : make_unique < derived_2_t > ( ) ) ;
std : : vector < base_t * > v2 ;
v2 . push_back ( & d1 ) ;
v2 . push_back ( & d2 ) ;
2018-01-29 11:21:13 +08:00
lua [ " c1 " ] = std : : move ( v1 ) ;
lua [ " c2 " ] = & v2 ;
2019-08-15 13:26:52 +08:00
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " b1 = c1[1] " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
base_t * b1 = lua [ " b1 " ] ;
int val1 = b1 - > get ( ) ;
REQUIRE ( val1 = = 250 ) ;
auto result2 = lua . safe_script ( " b2 = c2[2] " , sol : : script_pass_on_error ) ;
REQUIRE ( result2 . valid ( ) ) ;
base_t * b2 = lua [ " b2 " ] ;
int val2 = b2 - > get ( ) ;
REQUIRE ( val2 = = 500 ) ;
2017-06-24 06:07:24 +08:00
}
2021-10-24 06:13:25 +08:00
TEST_CASE ( " containers/keep alive " , " containers are kept alive even if they are returned as a temporary " ) {
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base , sol : : lib : : table ) ;
# define PATTERN() 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
lua [ " get_collection " ] = [ ] ( ) {
return std : : vector < int > ( { PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) ,
PATTERN ( ) } ) ;
} ;
# undef PATTERN
sol : : optional < sol : : error > maybe_error = lua . safe_script ( R " lua(
print ( " LET'S GET IT BAYBEEE! " )
for i , v in pairs ( get_collection ( ) ) do
collectgarbage ( )
collectgarbage ( )
local index = i - 1
print ( i , index , ( index % 10 ) , v )
assert ( ( index % 10 ) = = v )
end
collectgarbage ( )
collectgarbage ( )
print ( " YEEEAH! " )
) lua " );
REQUIRE_FALSE ( maybe_error . has_value ( ) ) ;
}