You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am currently porting over a project of mine from a custom Lua C++ wrapper to sol2. This custom wrapper used std::any to allow passing arbitrary values to and from Lua without knowing their explicit types. This was convenient, because my event dispatching system also uses std::any, so I could directly send the std::any I got form an event straight to Lua, and the wrapper would take care of dispatching the content of the std::any to the most appropriate Lua type. The implicit contract was that, in this case, the std::any was expected to only ever contain basic numeric types, booleans, and strings [*].
I think the closest equivalent in sol2 is sol::object, which fulfils about the same need, however there are some important differences. As far as I can tell, the biggest one is that the ownership model is different: sol::object has reference semantic, and shared ownership of the underlying value (since the value is actually stored in the Lua memory space, and the object just keeps a reference to it). In contrast, std::any has value semantic and single ownership. This means I cannot use sol::object where I would normally use std::any (i.e., in my event dispatcher system).
There's also no built-in way to convert one to another, that I can see. I would need to add a function like this:
sol::object to_sol_object(sol::state& lua, const std::any& a) {
if (!a.has_value()) returnsol::make_object(lua.lua_state(), sol::lua_nil);
constauto& type = a.type();
#defineTRY_TYPE(T) if (type == typeid(T)) return sol::make_object(lua.lua_state(), std::any_cast<T>(a))
TRY_TYPE(bool);
TRY_TYPE(char);
TRY_TYPE(unsignedchar);
TRY_TYPE(short);
TRY_TYPE(unsignedshort);
TRY_TYPE(int);
TRY_TYPE(unsignedint);
TRY_TYPE(long);
TRY_TYPE(unsignedlong);
TRY_TYPE(longlong);
TRY_TYPE(unsignedlonglong);
TRY_TYPE(float);
TRY_TYPE(double);
TRY_TYPE(std::string);
// etc, possibly adding support for more basic types and other sol types
#undef TRY_TYPE
throwstd::runtime_error("unsupported type"); // or your favorite error-reporting mechanism
}
And then the other way:
std::any from_sol_object(const sol::object& o) {
if (o == sol::lua_nil) returnstd::any();
#defineTRY_TYPE(T) if (o.is<T>()) return o.as<T>()
TRY_TYPE(bool);
TRY_TYPE(char);
TRY_TYPE(unsignedchar);
TRY_TYPE(short);
TRY_TYPE(unsignedshort);
TRY_TYPE(int);
TRY_TYPE(unsignedint);
TRY_TYPE(long);
TRY_TYPE(unsignedlong);
TRY_TYPE(longlong);
TRY_TYPE(unsignedlonglong);
TRY_TYPE(float);
TRY_TYPE(double);
TRY_TYPE(std::string);
// etc, possibly adding support for more basic types and other sol types
#undef TRY_TYPE
throwstd::runtime_error("unsupported type"); // or your favorite error-reporting mechanism
}
I understand the scope of std::any and sol::object isn't the same, so I'm not suggesting replacing one with the other. But I was wondering if there was a plan, or interest, in adding first-class support for std::any in sol2? Maybe you know of a more clever way to do this than the naive functions above.
[*] : This type of contract could also be fulfiled by std::variant, which perhaps makes the task easier. I see that sol2 already supports std::variant, so perhaps it's just that std::any is too unconstrained a type to be supported generically by sol2...
The text was updated successfully, but these errors were encountered:
so perhaps it's just that std::any is too unconstrained a type to be supported generically by sol2...
This is, in fact, exactly why I can't support it. I'd just throw a bunch of types at the std::any, hoping one sticks. This is only something your code can do: the best I can do is -- as is already happening -- transport the value (std::any) exactly as-is.
For your purposes, it might make sense to unravel to the type and just push the actual value from C++ into Lua. Then, you can retrieve it using a std::variant<Types, You, Care, About>, which is -- as you noted -- already supported in sol2!
Thank you! I will drop std::any and use std::variant, since that makes the contract more explicit. Really glad to see it supported out of the box :) sol2 is a really nice library, thanks for your efforts!
I am currently porting over a project of mine from a custom Lua C++ wrapper to sol2. This custom wrapper used
std::any
to allow passing arbitrary values to and from Lua without knowing their explicit types. This was convenient, because my event dispatching system also usesstd::any
, so I could directly send thestd::any
I got form an event straight to Lua, and the wrapper would take care of dispatching the content of thestd::any
to the most appropriate Lua type. The implicit contract was that, in this case, thestd::any
was expected to only ever contain basic numeric types, booleans, and strings [*].I think the closest equivalent in sol2 is
sol::object
, which fulfils about the same need, however there are some important differences. As far as I can tell, the biggest one is that the ownership model is different:sol::object
has reference semantic, and shared ownership of the underlying value (since the value is actually stored in the Lua memory space, and the object just keeps a reference to it). In contrast,std::any
has value semantic and single ownership. This means I cannot usesol::object
where I would normally usestd::any
(i.e., in my event dispatcher system).There's also no built-in way to convert one to another, that I can see. I would need to add a function like this:
And then the other way:
I understand the scope of
std::any
andsol::object
isn't the same, so I'm not suggesting replacing one with the other. But I was wondering if there was a plan, or interest, in adding first-class support forstd::any
in sol2? Maybe you know of a more clever way to do this than the naive functions above.[*] : This type of contract could also be fulfiled by
std::variant
, which perhaps makes the task easier. I see that sol2 already supportsstd::variant
, so perhaps it's just thatstd::any
is too unconstrained a type to be supported generically by sol2...The text was updated successfully, but these errors were encountered: