ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.18k stars 515 forks source link

is<std::vector<T>> and as<sol::optional<std::vector<T>>> are always true for lua table #1518

Open smbape opened 1 year ago

smbape commented 1 year ago
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

#include <vector>

int main(int, char**) {
    std::cout << "=== containers retrieved from lua tables ==="
              << std::endl;

    sol::state lua;
    lua.open_libraries();

    lua.set_function("is_vector_int", [](sol::object obj) {
        return obj.is<std::vector<int>>();
    });

    lua.set_function("is_vector_string", [](sol::object obj) {
        return obj.is<std::vector<std::string>>();
    });

    lua.set_function("maybe_optional_vector_int", [](sol::object obj) {
        return static_cast<bool>(obj.as<sol::optional<std::vector<int>>>());
    });

    lua.set_function("maybe_optional_vector_string", [](sol::object obj) {
        return static_cast<bool>(obj.as<sol::optional<std::vector<std::string>>>());
    });

    lua.set_function("vector_int", [](sol::object obj) {
        return obj.as<std::vector<int>>();
    });

    lua.set_function("vector_string", [](sol::object obj) {
        return obj.as<std::vector<std::string>>();
    });

    lua.script(R"(
print('{ "0", 1 } is vector of string? ' .. tostring(is_vector_string({ "0", 1 })))
print('{ "0", 1 } is vector of int? ' .. tostring(is_vector_int({ "0", 1 })))
print('{ "0" } may be vector of string? ' .. tostring(maybe_optional_vector_string({ "0" })))

print('{ "0", 1 } is vector of string? ' .. tostring(is_vector_string({ "0", 1 })))
print('{ "0", 1 } is vector of int? ' .. tostring(is_vector_int({ "0", 1 })))
print('{ 1 } may be vector of int? ' .. tostring(maybe_optional_vector_int({ 1 })))

print('{ "0", 1 } may be vector of int? ' .. tostring(maybe_optional_vector_int({ "0", 1 }))) -- crashes
print('{ "0", 1 } may be vector of string? ' .. tostring(maybe_optional_vector_string({ "0", 1 }))) -- crashes
print('{ "0", 1 } vector of int? ' .. tostring(vector_int({ "0", 1 }))) -- crashes
print('{ "0", 1 } vector of string? ' .. tostring(vector_string({ "0", 1 }))) -- crashes
    )");

    std::cout << std::endl;

    return 0;
}
=== containers retrieved from lua tables ===
{ "0", 1 } is vector of string? true
{ "0", 1 } is vector of int? true
{ "0" } may be vector of string? true
{ "0", 1 } is vector of string? true
{ "0", 1 } is vector of int? true
{ 1 } may be vector of int? true
[sol2] An error occurred and has been passed to an error handler: sol: runtime error: stack index -1, expected number, received string: not a numeric type
stack traceback:
        [C]: in function 'maybe_optional_vector_int'
        [string "..."]:10: in main chunk

In the documentation, it is written If it detects that a proper optional exists, it will attempt to use it., however, it seems that, when passed a table, it is not the case.

Version : 3.3.0 OS : Windows 10

If I manually do a loop on the table values, there is a huge performance lost. Is there a work around?