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.06k stars 492 forks source link

`std::vector` of custom types crashes #1531

Open uyha opened 9 months ago

uyha commented 9 months ago

I am trying to use the ADL customization points to turn a Lua table to a custom type using the get<CustomType>() syntax. For getting a single value, it works as expected. However, when I put that custom type into a std::vector the program crashes.

Here is the program that I'm working on:

#include <fmt/format.h>
#include <fmt/ranges.h>
#include <sol/sol.hpp>

struct A {};

template <typename Handler>
auto sol_lua_check(sol::types<A>, lua_State *L, int index, Handler &&handler, sol::stack::record &tracking) -> bool {
  if (not sol::stack::check_usertype<A>(L, index) and not sol::stack::check<sol::table>(L, index)) {
    handler(L, index, sol::type_of(L, index), sol::type::userdata, "expected a A or a table");
    return false;
  }

  tracking.use(1);
  return true;
}

auto sol_lua_get(sol::types<A>, lua_State *L, int index, sol::stack::record &tracking) -> A {
  if (sol::stack::check_usertype<A>(L, index)) {
    return sol::stack::get_usertype<A>(L, index, tracking);
  }

  auto result = A{};
  auto object = sol::stack::get<sol::table>(L, lua_absindex(L, index));
  tracking.use(1);

  return result;
}

int main() {
  auto lua = sol::state{};

  lua.open_libraries(sol::lib::base, sol::lib::package);
  lua.new_usertype<A>("A");

  [[maybe_unused]] auto a  = lua.script(R"lua(return {})lua").get<A>();                // Works
  [[maybe_unused]] auto as = lua.script(R"lua(return {{}})lua").get<std::vector<A>>(); // Crashes
}

What am I doing wrong here?

uyha commented 9 months ago

so adding the following overloads makes it work, but I wonder why this is not done automatically?

template <typename Handler>
auto sol_lua_check(sol::types<sol::nested<A>>,
                                lua_State *L,
                                int index, 
                                Handler &&handler,
                                sol::stack::record &tracking) -> bool {
  return sol_lua_check<Handler>(sol::types<A>{}, L, index, handler, tracking);
}

auto sol_lua_get(sol::types<sol::nested<A>>,
                            lua_State *L,
                            int index,
                            sol::stack::record &tracking) -> A {
  return sol_lua_get(sol::types<A>{}, L, index, tracking);
}