mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
add new tas for override_value and update_if_empty, improve the enable_if for a bunch of field_setter stuff
perform the last breaking change with .source() prepare for the coming release...
This commit is contained in:
parent
95ffd10283
commit
b6f40935c8
|
@ -56,14 +56,14 @@ members
|
|||
|
||||
environment(lua_State* L, sol::new_table nt);
|
||||
environment(lua_State* L, sol::new_table nt, const sol::reference& fallback);
|
||||
environment(sol::env_t, const sol::reference& object_that_has_environment);
|
||||
environment(sol::env_t, const sol::stack_reference& object_that_has_environment);
|
||||
environment(sol::env_key_t, const sol::reference& object_that_has_environment);
|
||||
environment(sol::env_key_t, const sol::stack_reference& object_that_has_environment);
|
||||
|
||||
The ones from table are used here (of particular note is the ability to use ``sol::environment(my_lua_state, sol::create);`` to make a fresh, unnamed environment), plus the three unique constructors shown above.
|
||||
|
||||
The first constructor is generally used as ``sol::environment my_env(my_lua_state, sol::create, my_fallback_table);``. The fallback table serves as the backup to lookup attempts on the environment table being created. It is achieved by simply creating a metatable for the ``sol::environment`` being created, and then doing ``env_metatable["__index"] = fallback;``. You can achieve fancier effects by changing the metatable of the environment to your liking, by creating it in some fashion and then setting the metatable explicitly and populating it with data, particularly with :doc:`sol::metatable_key<metatable_key>`.
|
||||
|
||||
The second and third unique constructors take a special empty type that serves as a key to trigger this constructor and serves no other purpose, ``sol::env_t``. The shortcut value so you don't have to create one is called ``sol::env_key``. It is used like ``sol::environment my_env(sol::env_key, some_object);``. It will extract the environment out of whatever the second argument is that may or may not have an environment. If it does not have an environment, the constructor will complete but the object will have ``env.valid() == false``, since it will reference Lua's ``nil``.
|
||||
The second and third unique constructors take a special empty type that serves as a key to trigger this constructor and serves no other purpose, ``sol::env_key_t``. The shortcut value so you don't have to create one is called ``sol::env_key``. It is used like ``sol::environment my_env(sol::env_key, some_object);``. It will extract the environment out of whatever the second argument is that may or may not have an environment. If it does not have an environment, the constructor will complete but the object will have ``env.valid() == false``, since it will reference Lua's ``nil``.
|
||||
|
||||
|
||||
.. code-block:: cpp
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// where someone wants to handle a nested table
|
||||
void demo(sol::nested<std::map<std::string, std::vector<std::string>>> src) {
|
||||
std::cout << "demo, sol::nested<...>" << std::endl;
|
||||
const auto& listmap = src.source;
|
||||
const auto& listmap = src.value();
|
||||
c_assert(listmap.size() == 2);
|
||||
for (const auto& kvp : listmap) {
|
||||
const std::vector<std::string>& strings = kvp.second;
|
||||
|
@ -38,11 +38,11 @@ void demo(sol::nested<std::map<std::string, std::vector<std::string>>> src) {
|
|||
void demo_explicit (sol::as_table_t<std::map<std::string, sol::as_table_t<std::vector<std::string>>>> src) {
|
||||
std::cout << "demo, explicit sol::as_table_t<...>" << std::endl;
|
||||
// Have to access the "source" member variable for as_table_t
|
||||
const auto& listmap = src.source;
|
||||
const auto& listmap = src.value();
|
||||
c_assert(listmap.size() == 2);
|
||||
for (const auto& kvp : listmap) {
|
||||
// Have to access the internal "source" for the inner as_table_t, as well
|
||||
const std::vector<std::string>& strings = kvp.second.source;
|
||||
const std::vector<std::string>& strings = kvp.second.value();
|
||||
c_assert(strings.size() == 3);
|
||||
std::cout << "\t" << kvp.first << " = ";
|
||||
for (const auto& s : strings) {
|
||||
|
|
|
@ -42,9 +42,11 @@ namespace sol { namespace detail {
|
|||
ebco(T&& v) : value_(std::move(v)){};
|
||||
ebco& operator=(const T& v) {
|
||||
value = v;
|
||||
return *this;
|
||||
}
|
||||
ebco& operator=(T&& v) {
|
||||
value_ = std::move(v);
|
||||
return *this;
|
||||
};
|
||||
template <typename Arg, typename... Args,
|
||||
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
|
||||
|
@ -68,17 +70,20 @@ namespace sol { namespace detail {
|
|||
ebco(const T& v) : T(v){};
|
||||
ebco(T&& v) : T(std::move(v)){};
|
||||
template <typename Arg, typename... Args,
|
||||
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
|
||||
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
|
||||
ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...){}
|
||||
typename = std::enable_if_t<!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
|
||||
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T>>>
|
||||
ebco(Arg&& arg, Args&&... args) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco& operator=(const T& v) {
|
||||
static_cast<T&>(*this) = v;
|
||||
return *this;
|
||||
}
|
||||
ebco& operator=(T&& v) {
|
||||
static_cast<T&>(*this) = std::move(v);
|
||||
return *this;
|
||||
};
|
||||
|
||||
T& value() {
|
||||
|
@ -90,6 +95,48 @@ namespace sol { namespace detail {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t tag>
|
||||
struct ebco<T&, tag> {
|
||||
T& ref;
|
||||
|
||||
ebco() = default;
|
||||
ebco(const ebco&) = default;
|
||||
ebco(ebco&&) = default;
|
||||
ebco(T& v) : ref(v){};
|
||||
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco& operator=(T& v) {
|
||||
ref = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& value() const {
|
||||
return const_cast<ebco<T&, tag>&>(*this).ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t tag>
|
||||
struct ebco<T&&, tag> {
|
||||
T&& ref;
|
||||
|
||||
ebco() = default;
|
||||
ebco(const ebco&) = default;
|
||||
ebco(ebco&&) = default;
|
||||
ebco(T&& v) : ref(v){};
|
||||
|
||||
ebco& operator=(const ebco&) = default;
|
||||
ebco& operator=(ebco&&) = default;
|
||||
ebco& operator=(T&& v) {
|
||||
ref = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(ref);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace sol::detail
|
||||
|
||||
#endif // SOL_EBCO_HPP
|
||||
|
|
|
@ -60,20 +60,20 @@ namespace sol {
|
|||
mt.pop();
|
||||
}
|
||||
|
||||
basic_environment(env_t, const stack_reference& extraction_target)
|
||||
basic_environment(env_key_t, const stack_reference& extraction_target)
|
||||
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<env_t>(this->lua_state(), -1, handler);
|
||||
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
template <bool b>
|
||||
basic_environment(env_t, const basic_reference<b>& extraction_target)
|
||||
basic_environment(env_key_t, const basic_reference<b>& extraction_target)
|
||||
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
|
||||
#if defined(SOL_SAFE_REFERENCES) && SOL_SAFE_REFERENCES
|
||||
constructor_handler handler{};
|
||||
stack::check<env_t>(this->lua_state(), -1, handler);
|
||||
stack::check<env_key_t>(this->lua_state(), -1, handler);
|
||||
#endif // Safety
|
||||
lua_pop(this->lua_state(), 2);
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ namespace sol {
|
|||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct unqualified_getter<env_t> {
|
||||
struct unqualified_getter<env_key_t> {
|
||||
static environment get(lua_State* L, int index, record& tracking) {
|
||||
tracking.use(1);
|
||||
return get_environment(stack_reference(L, raw_index(index)));
|
||||
|
|
|
@ -534,7 +534,7 @@ namespace sol {
|
|||
|
||||
template <typename F, typename... Filters>
|
||||
struct unqualified_pusher<filter_wrapper<F, Filters...>> {
|
||||
typedef filter_wrapper<F, Filters...> P;
|
||||
using P = filter_wrapper<F, Filters...>;
|
||||
|
||||
static int push(lua_State* L, const P& p) {
|
||||
lua_CFunction cf = call_detail::call_user<void, false, false, P, 2>;
|
||||
|
@ -552,6 +552,27 @@ namespace sol {
|
|||
return stack::push(L, c_closure(cf, upvalues));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unqualified_pusher<push_invoke_t<T>> {
|
||||
static int push(lua_State* L, push_invoke_t<T>&& pi) {
|
||||
if constexpr (std::is_invocable_v<std::add_rvalue_reference_t<T>, lua_State*>) {
|
||||
return stack::push(L, std::move(pi.value())(L));
|
||||
}
|
||||
else {
|
||||
return stack::push(L, std::move(pi.value())());
|
||||
}
|
||||
}
|
||||
|
||||
static int push(lua_State* L, const push_invoke_t<T>& pi) {
|
||||
if constexpr (std::is_invocable_v<const T, lua_State*>) {
|
||||
return stack::push(L, pi.value()(L));
|
||||
}
|
||||
else {
|
||||
return stack::push(L, pi.value()());
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace stack
|
||||
} // namespace sol
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ namespace sol { namespace stack {
|
|||
};
|
||||
|
||||
template <type expected, typename C>
|
||||
struct unqualified_checker<metatable_t, expected, C> {
|
||||
struct unqualified_checker<metatable_key_t, expected, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
|
@ -414,7 +414,7 @@ namespace sol { namespace stack {
|
|||
};
|
||||
|
||||
template <typename C>
|
||||
struct unqualified_checker<env_t, type::poly, C> {
|
||||
struct unqualified_checker<env_key_t, type::poly, C> {
|
||||
template <typename Handler>
|
||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||
tracking.use(1);
|
||||
|
|
|
@ -31,87 +31,68 @@
|
|||
|
||||
namespace sol {
|
||||
namespace stack {
|
||||
template <typename T, bool, bool, typename>
|
||||
template <typename T, bool global, bool raw, typename>
|
||||
struct field_getter {
|
||||
static constexpr int default_table_index = std::conditional_t<meta::is_c_str_v<T> || (std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
|| (std::is_integral_v<T> && !std::is_same_v<T, bool>) || (raw && std::is_void_v<std::remove_pointer_t<T>>),
|
||||
std::integral_constant<int, -1>, std::integral_constant<int, -2>> ::value;
|
||||
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = -2) {
|
||||
push(L, std::forward<Key>(key));
|
||||
lua_gettable(L, tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool global, typename C>
|
||||
struct field_getter<T, global, true, C> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = -2) {
|
||||
push(L, std::forward<Key>(key));
|
||||
lua_rawget(L, tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool b, bool raw, typename C>
|
||||
struct field_getter<metatable_t, b, raw, C> {
|
||||
void get(lua_State* L, metatable_t, int tableindex = -1) {
|
||||
if (lua_getmetatable(L, tableindex) == 0)
|
||||
push(L, lua_nil);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool b, bool raw, typename C>
|
||||
struct field_getter<env_t, b, raw, C> {
|
||||
void get(lua_State* L, env_t, int tableindex = -1) {
|
||||
#if SOL_LUA_VERSION < 502
|
||||
// Use lua_setfenv
|
||||
lua_getfenv(L, tableindex);
|
||||
#else
|
||||
// Use upvalues as explained in Lua 5.2 and beyond's manual
|
||||
if (lua_getupvalue(L, tableindex, 1) == nullptr) {
|
||||
push(L, lua_nil);
|
||||
void get(lua_State* L, Key&& key, int tableindex = default_table_index) {
|
||||
if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t>) {
|
||||
(void)L;
|
||||
(void)key;
|
||||
(void)tableindex;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, env_key_t>) {
|
||||
#if SOL_LUA_VERSION < 502
|
||||
// Use lua_setfenv
|
||||
lua_getfenv(L, tableindex);
|
||||
#else
|
||||
// Use upvalues as explained in Lua 5.2 and beyond's manual
|
||||
if (lua_getupvalue(L, tableindex, 1) == nullptr) {
|
||||
push(L, lua_nil);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool raw>
|
||||
struct field_getter<T, true, raw, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int = -1) {
|
||||
lua_getglobal(L, &key[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct field_getter<T, false, false, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = -1) {
|
||||
lua_getfield(L, tableindex, &key[0]);
|
||||
}
|
||||
};
|
||||
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
template <typename T>
|
||||
struct field_getter<T, false, false, std::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = -1) {
|
||||
lua_geti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
};
|
||||
#endif // Lua 5.3.x
|
||||
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, metatable_key_t>) {
|
||||
if (lua_getmetatable(L, tableindex) == 0)
|
||||
push(L, lua_nil);
|
||||
}
|
||||
else if constexpr(raw) {
|
||||
if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 502
|
||||
template <typename C>
|
||||
struct field_getter<void*, false, true, C> {
|
||||
void get(lua_State* L, void* key, int tableindex = -1) {
|
||||
lua_rawgetp(L, tableindex, key);
|
||||
}
|
||||
};
|
||||
else if constexpr (std::is_void_v<std::remove_pointer_t<T>>) {
|
||||
lua_rawgetp(L, tableindex, key);
|
||||
}
|
||||
#endif // Lua 5.3.x
|
||||
|
||||
template <typename T>
|
||||
struct field_getter<T, false, true, std::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>> {
|
||||
template <typename Key>
|
||||
void get(lua_State* L, Key&& key, int tableindex = -1) {
|
||||
lua_rawgeti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
lua_rawget(L, tableindex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (meta::is_c_str_v<T>) {
|
||||
if constexpr (global) {
|
||||
(void)tableindex;
|
||||
lua_getglobal(L, &key[0]);
|
||||
}
|
||||
else {
|
||||
lua_getfield(L, tableindex, &key[0]);
|
||||
}
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
else if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
lua_geti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#endif // Lua 5.3.x
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
lua_gettable(L, tableindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -158,83 +139,67 @@ namespace stack {
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T, bool, bool, typename>
|
||||
template <typename T, bool global, bool raw, typename>
|
||||
struct field_setter {
|
||||
static constexpr int default_table_index = std::conditional_t < meta::is_c_str_v<T> || (std::is_integral_v<T> && !std::is_same_v<T, bool>)
|
||||
|| (std::is_integral_v<T> && !std::is_same_v<T, bool>) || (raw && std::is_void_v<std::remove_pointer_t<T>>),
|
||||
std::integral_constant<int, -2>, std::integral_constant<int, -3>> ::value;
|
||||
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) {
|
||||
push(L, std::forward<Key>(key));
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_settable(L, tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool b>
|
||||
struct field_setter<T, b, true, std::enable_if_t<!std::is_same<metatable_t, meta::unqualified_t<T>>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) {
|
||||
push(L, std::forward<Key>(key));
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawset(L, tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool b, bool raw, typename C>
|
||||
struct field_setter<metatable_t, b, raw, C> {
|
||||
template <typename Value>
|
||||
void set(lua_State* L, metatable_t, Value&& value, int tableindex = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setmetatable(L, tableindex);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, bool raw>
|
||||
struct field_setter<T, true, raw, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setglobal(L, &key[0]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct field_setter<T, false, false, std::enable_if_t<meta::is_c_str<T>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setfield(L, tableindex, &key[0]);
|
||||
}
|
||||
};
|
||||
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
template <typename T>
|
||||
struct field_setter<T, false, false, std::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_seti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
};
|
||||
#endif // Lua 5.3.x
|
||||
|
||||
template <typename T>
|
||||
struct field_setter<T, false, true, std::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
};
|
||||
|
||||
void set(lua_State* L, Key&& key, Value&& value, int tableindex = default_table_index) {
|
||||
if constexpr (std::is_same_v<T, update_if_empty_t> || std::is_same_v<T, override_value_t>) {
|
||||
(void)L;
|
||||
(void)key;
|
||||
(void)value;
|
||||
(void)tableindex;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, metatable_key_t>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setmetatable(L, tableindex);
|
||||
}
|
||||
else if constexpr (raw) {
|
||||
if constexpr (std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawseti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 502
|
||||
template <typename C>
|
||||
struct field_setter<void*, false, true, C> {
|
||||
template <typename Key, typename Value>
|
||||
void set(lua_State* L, void* key, Value&& value, int tableindex = -2) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawsetp(L, tableindex, key);
|
||||
else if constexpr (std::is_void_v<std::remove_pointer_t<T>>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawsetp(L, tableindex, key);
|
||||
}
|
||||
#endif // Lua 5.2.x
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_rawset(L, tableindex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (meta::is_c_str_v<T>) {
|
||||
if constexpr (global) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setglobal(L, &key[0]);
|
||||
(void)tableindex;
|
||||
}
|
||||
else {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_setfield(L, tableindex, &key[0]);
|
||||
}
|
||||
}
|
||||
#if SOL_LUA_VERSION >= 503
|
||||
else if constexpr(std::is_integral_v<T> && !std::is_same_v<bool, T>) {
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_seti(L, tableindex, static_cast<lua_Integer>(key));
|
||||
}
|
||||
#endif // Lua 5.3.x
|
||||
else {
|
||||
push(L, std::forward<Key>(key));
|
||||
push(L, std::forward<Value>(value));
|
||||
lua_settable(L, tableindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // Lua 5.2.x
|
||||
|
||||
template <typename... Args, bool b, bool raw, typename C>
|
||||
struct field_setter<std::tuple<Args...>, b, raw, C> {
|
||||
|
@ -268,7 +233,7 @@ namespace stack {
|
|||
template <typename Keys, typename Value>
|
||||
void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) {
|
||||
get_field<b, raw>(L, std::get<0>(std::forward<Keys>(keys)), tableindex);
|
||||
set_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)), std::forward<Value>(value));
|
||||
set_field<false, raw>(L, std::get<1>(std::forward<Keys>(keys)), std::forward<Value>(value), lua_gettop(L));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -452,8 +452,8 @@ namespace sol {
|
|||
};
|
||||
|
||||
template <>
|
||||
struct unqualified_pusher<metatable_t> {
|
||||
static int push(lua_State* L, metatable_t) {
|
||||
struct unqualified_pusher<metatable_key_t> {
|
||||
static int push(lua_State* L, metatable_key_t) {
|
||||
#if defined(SOL_SAFE_STACK_CHECK) && SOL_SAFE_STACK_CHECK
|
||||
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
|
||||
#endif // make sure stack doesn't overflow
|
||||
|
@ -604,7 +604,7 @@ namespace sol {
|
|||
return 1;
|
||||
}
|
||||
|
||||
template <typename Arg, typename... Args, meta::disable<meta::any_same<meta::unqualified_t<Arg>, no_metatable_t, metatable_t>> = meta::enabler>
|
||||
template <typename Arg, typename... Args, meta::disable<meta::any_same<meta::unqualified_t<Arg>, no_metatable_t, metatable_key_t>> = meta::enabler>
|
||||
static int push(lua_State* L, Arg&& arg, Args&&... args) {
|
||||
const auto name = &usertype_traits<meta::unqualified_t<T>>::user_gc_metatable()[0];
|
||||
return push_with(L, name, std::forward<Arg>(arg), std::forward<Args>(args)...);
|
||||
|
@ -617,7 +617,7 @@ namespace sol {
|
|||
}
|
||||
|
||||
template <typename Key, typename... Args>
|
||||
static int push(lua_State* L, metatable_t, Key&& key, Args&&... args) {
|
||||
static int push(lua_State* L, metatable_key_t, Key&& key, Args&&... args) {
|
||||
const auto name = &key[0];
|
||||
return push_with<true>(L, name, std::forward<Args>(args)...);
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace sol {
|
|||
|
||||
namespace stack {
|
||||
template <>
|
||||
struct unqualified_getter<metatable_t> {
|
||||
struct unqualified_getter<metatable_key_t> {
|
||||
static table get(lua_State* L, int index = -1) {
|
||||
if (lua_getmetatable(L, index) == 0) {
|
||||
return table(L, ref_index(LUA_REFNIL));
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace sol {
|
|||
lua_pop(L, static_cast<int>(n));
|
||||
}
|
||||
};
|
||||
|
||||
struct ref_clean {
|
||||
lua_State* L;
|
||||
int& n;
|
||||
|
@ -53,6 +54,7 @@ namespace sol {
|
|||
lua_pop(L, static_cast<int>(n));
|
||||
}
|
||||
};
|
||||
|
||||
inline int fail_on_newindex(lua_State* L) {
|
||||
return luaL_error(L, "sol: cannot modify the elements of an enumeration table");
|
||||
}
|
||||
|
@ -62,6 +64,7 @@ namespace sol {
|
|||
|
||||
template <bool top_level, typename... Args>
|
||||
constexpr inline bool is_global_v = is_global<top_level, Args...>::value;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <bool top_level, typename ref_t>
|
||||
|
@ -154,20 +157,33 @@ namespace sol {
|
|||
}
|
||||
}
|
||||
|
||||
template <bool global, bool raw, bool forced, typename Key, typename... Keys>
|
||||
template <bool global, bool raw, detail::insert_mode mode, typename Key, typename... Keys>
|
||||
void traverse_set_deep(int table_index, Key&& key, Keys&&... keys) const {
|
||||
using KeyU = meta::unqualified_t<Key>;
|
||||
lua_State* L = base_t::lua_state();
|
||||
if constexpr(std::is_same_v<KeyU, force_t>) {
|
||||
if constexpr (std::is_same_v<KeyU, update_if_empty_t>) {
|
||||
(void)key;
|
||||
traverse_set_deep<false, raw, true>(table_index, std::forward<Keys>(keys)...);
|
||||
traverse_set_deep<false, raw, detail::insert_mode::update_if_empty>(table_index, std::forward<Keys>(keys)...);
|
||||
}
|
||||
else if constexpr (std::is_same_v<KeyU, override_value_t>) {
|
||||
(void)key;
|
||||
traverse_set_deep<false, raw, detail::insert_mode::override_value>(table_index, std::forward<Keys>(keys)...);
|
||||
}
|
||||
else {
|
||||
lua_State* L = base_t::lua_state();
|
||||
if constexpr (sizeof...(Keys) == 1) {
|
||||
stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
|
||||
if constexpr ((mode & detail::insert_mode::update_if_empty) == detail::insert_mode::update_if_empty) {
|
||||
stack::get_field<global, raw>(L, key, table_index);
|
||||
type vt = type_of(L, -1);
|
||||
if (vt == type::lua_nil || vt == type::none) {
|
||||
stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack::set_field<global, raw>(L, std::forward<Key>(key), std::forward<Keys>(keys)..., table_index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if constexpr (forced) {
|
||||
if constexpr ((mode & detail::insert_mode::override_value) == detail::insert_mode::override_value) {
|
||||
stack::probe p = stack::probe_get_field<global, raw>(L, key, table_index);
|
||||
if (!p.success) {
|
||||
constexpr bool is_seq = std::is_integral_v<KeyU>;
|
||||
|
@ -175,10 +191,20 @@ namespace sol {
|
|||
stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
|
||||
}
|
||||
}
|
||||
else if constexpr((mode & detail::insert_mode::update_if_empty) == detail::insert_mode::update_if_empty) {
|
||||
stack::get_field<global, raw>(L, key, table_index);
|
||||
type vt = type_of(L, -1);
|
||||
if (vt == type::lua_nil || vt == type::none) {
|
||||
constexpr bool is_seq = std::is_integral_v<KeyU>;
|
||||
lua_pop(L, 1);
|
||||
stack::set_field<global, raw>(L, key, new_table(static_cast<int>(is_seq), !static_cast<int>(is_seq)), table_index);
|
||||
stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
stack::get_field<global, raw>(L, std::forward<Key>(key), table_index);
|
||||
}
|
||||
traverse_set_deep<false, raw, forced>(lua_gettop(L), std::forward<Keys>(keys)...);
|
||||
traverse_set_deep<false, raw, mode>(lua_gettop(L), std::forward<Keys>(keys)...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +277,7 @@ namespace sol {
|
|||
if (!is_table<meta::unqualified_t<T>>::value) {
|
||||
auto pp = stack::push_pop(*this);
|
||||
constructor_handler handler{};
|
||||
stack::check<basic_table_core>(L, -1, handler);
|
||||
stack::check<basic_table_core>(lua_state(), -1, handler);
|
||||
}
|
||||
#endif // Safety
|
||||
}
|
||||
|
@ -317,7 +343,7 @@ namespace sol {
|
|||
int table_index = pp.index_of(*this);
|
||||
lua_State* L = base_t::lua_state();
|
||||
auto pn = stack::pop_n(L, static_cast<int>(sizeof...(Keys) - 2));
|
||||
traverse_set_deep<top_level, false, false>(table_index, std::forward<Keys>(keys)...);
|
||||
traverse_set_deep<top_level, false, detail::insert_mode::none>(table_index, std::forward<Keys>(keys)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -625,6 +625,9 @@ namespace sol {
|
|||
using is_c_str = any<std::is_same<std::decay_t<unqualified_t<T>>, const char*>, std::is_same<std::decay_t<unqualified_t<T>>, char*>,
|
||||
std::is_same<unqualified_t<T>, std::string>>;
|
||||
|
||||
template <typename T>
|
||||
constexpr inline bool is_c_str_v = is_c_str<T>::value;
|
||||
|
||||
template <typename T>
|
||||
struct is_move_only
|
||||
: all<neg<std::is_reference<T>>, neg<std::is_copy_constructible<unqualified_t<T>>>, std::is_move_constructible<unqualified_t<T>>> {};
|
||||
|
|
|
@ -80,11 +80,9 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct implicit_wrapper {
|
||||
T& item;
|
||||
implicit_wrapper(T* item)
|
||||
: item(*item) {
|
||||
implicit_wrapper(T* item) : item(*item) {
|
||||
}
|
||||
implicit_wrapper(T& item)
|
||||
: item(item) {
|
||||
implicit_wrapper(T& item) : item(item) {
|
||||
}
|
||||
operator T&() {
|
||||
return item;
|
||||
|
@ -115,11 +113,11 @@ namespace sol {
|
|||
struct non_lua_nil_t {};
|
||||
} // namespace detail
|
||||
|
||||
struct metatable_t {};
|
||||
const metatable_t metatable_key = {};
|
||||
struct metatable_key_t {};
|
||||
const metatable_key_t metatable_key = {};
|
||||
|
||||
struct env_t {};
|
||||
const env_t env_key = {};
|
||||
struct env_key_t {};
|
||||
const env_key_t env_key = {};
|
||||
|
||||
struct no_metatable_t {};
|
||||
const no_metatable_t no_metatable = {};
|
||||
|
@ -133,13 +131,13 @@ namespace sol {
|
|||
yielding_t(yielding_t&&) = default;
|
||||
yielding_t& operator=(const yielding_t&) = default;
|
||||
yielding_t& operator=(yielding_t&&) = default;
|
||||
template <typename Arg, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, yielding_t>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
yielding_t(Arg&& arg)
|
||||
: func(std::forward<Arg>(arg)) {
|
||||
template <typename Arg,
|
||||
meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, yielding_t>>,
|
||||
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
yielding_t(Arg&& arg) : func(std::forward<Arg>(arg)) {
|
||||
}
|
||||
template <typename Arg0, typename Arg1, typename... Args>
|
||||
yielding_t(Arg0&& arg0, Arg1&& arg1, Args&&... args)
|
||||
: func(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
yielding_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : func(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -217,8 +215,7 @@ namespace sol {
|
|||
|
||||
struct upvalue_index {
|
||||
int index;
|
||||
upvalue_index(int idx)
|
||||
: index(lua_upvalueindex(idx)) {
|
||||
upvalue_index(int idx) : index(lua_upvalueindex(idx)) {
|
||||
}
|
||||
|
||||
operator int() const {
|
||||
|
@ -228,8 +225,7 @@ namespace sol {
|
|||
|
||||
struct raw_index {
|
||||
int index;
|
||||
raw_index(int i)
|
||||
: index(i) {
|
||||
raw_index(int i) : index(i) {
|
||||
}
|
||||
|
||||
operator int() const {
|
||||
|
@ -239,8 +235,7 @@ namespace sol {
|
|||
|
||||
struct absolute_index {
|
||||
int index;
|
||||
absolute_index(lua_State* L, int idx)
|
||||
: index(lua_absindex(L, idx)) {
|
||||
absolute_index(lua_State* L, int idx) : index(lua_absindex(L, idx)) {
|
||||
}
|
||||
|
||||
operator int() const {
|
||||
|
@ -250,8 +245,7 @@ namespace sol {
|
|||
|
||||
struct ref_index {
|
||||
int index;
|
||||
ref_index(int idx)
|
||||
: index(idx) {
|
||||
ref_index(int idx) : index(idx) {
|
||||
}
|
||||
|
||||
operator int() const {
|
||||
|
@ -262,15 +256,13 @@ namespace sol {
|
|||
struct stack_count {
|
||||
int count;
|
||||
|
||||
stack_count(int cnt)
|
||||
: count(cnt) {
|
||||
stack_count(int cnt) : count(cnt) {
|
||||
}
|
||||
};
|
||||
|
||||
struct lightuserdata_value {
|
||||
void* value;
|
||||
lightuserdata_value(void* data)
|
||||
: value(data) {
|
||||
lightuserdata_value(void* data) : value(data) {
|
||||
}
|
||||
operator void*() const {
|
||||
return value;
|
||||
|
@ -279,8 +271,7 @@ namespace sol {
|
|||
|
||||
struct userdata_value {
|
||||
void* value;
|
||||
userdata_value(void* data)
|
||||
: value(data) {
|
||||
userdata_value(void* data) : value(data) {
|
||||
}
|
||||
operator void*() const {
|
||||
return value;
|
||||
|
@ -291,14 +282,11 @@ namespace sol {
|
|||
struct light {
|
||||
L* value;
|
||||
|
||||
light(L& x)
|
||||
: value(std::addressof(x)) {
|
||||
light(L& x) : value(std::addressof(x)) {
|
||||
}
|
||||
light(L* x)
|
||||
: value(x) {
|
||||
light(L* x) : value(x) {
|
||||
}
|
||||
light(void* x)
|
||||
: value(static_cast<L*>(x)) {
|
||||
light(void* x) : value(static_cast<L*>(x)) {
|
||||
}
|
||||
operator L*() const {
|
||||
return value;
|
||||
|
@ -318,8 +306,7 @@ namespace sol {
|
|||
struct user {
|
||||
U value;
|
||||
|
||||
user(U&& x)
|
||||
: value(std::forward<U>(x)) {
|
||||
user(U&& x) : value(std::forward<U>(x)) {
|
||||
}
|
||||
operator std::add_pointer_t<std::remove_reference_t<U>>() {
|
||||
return std::addressof(value);
|
||||
|
@ -342,8 +329,7 @@ namespace sol {
|
|||
struct metatable_registry_key {
|
||||
T key;
|
||||
|
||||
metatable_registry_key(T key)
|
||||
: key(std::forward<T>(key)) {
|
||||
metatable_registry_key(T key) : key(std::forward<T>(key)) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -357,8 +343,7 @@ namespace sol {
|
|||
struct closure {
|
||||
lua_CFunction c_function;
|
||||
std::tuple<Upvalues...> upvalues;
|
||||
closure(lua_CFunction f, Upvalues... targetupvalues)
|
||||
: c_function(f), upvalues(std::forward<Upvalues>(targetupvalues)...) {
|
||||
closure(lua_CFunction f, Upvalues... targetupvalues) : c_function(f), upvalues(std::forward<Upvalues>(targetupvalues)...) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -366,8 +351,7 @@ namespace sol {
|
|||
struct closure<> {
|
||||
lua_CFunction c_function;
|
||||
int upvalues;
|
||||
closure(lua_CFunction f, int upvalue_count = 0)
|
||||
: c_function(f), upvalues(upvalue_count) {
|
||||
closure(lua_CFunction f, int upvalue_count = 0) : c_function(f), upvalues(upvalue_count) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -382,8 +366,7 @@ namespace sol {
|
|||
struct function_arguments {
|
||||
std::tuple<Ps...> arguments;
|
||||
template <typename Arg, typename... Args, meta::disable<std::is_same<meta::unqualified_t<Arg>, function_arguments>> = meta::enabler>
|
||||
function_arguments(Arg&& arg, Args&&... args)
|
||||
: arguments(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
function_arguments(Arg&& arg, Args&&... args) : arguments(std::forward<Arg>(arg), std::forward<Args>(args)...) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -399,47 +382,75 @@ namespace sol {
|
|||
|
||||
template <typename T>
|
||||
struct as_table_t {
|
||||
T source;
|
||||
private:
|
||||
T value_;
|
||||
|
||||
public:
|
||||
as_table_t() = default;
|
||||
as_table_t(const as_table_t&) = default;
|
||||
as_table_t(as_table_t&&) = default;
|
||||
as_table_t& operator=(const as_table_t&) = default;
|
||||
as_table_t& operator=(as_table_t&&) = default;
|
||||
template <typename Arg, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, as_table_t>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
as_table_t(Arg&& arg)
|
||||
: source(std::forward<Arg>(arg)) {
|
||||
template <typename Arg,
|
||||
meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, as_table_t>>,
|
||||
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
as_table_t(Arg&& arg) : value_(std::forward<Arg>(arg)) {
|
||||
}
|
||||
template <typename Arg0, typename Arg1, typename... Args>
|
||||
as_table_t(Arg0&& arg0, Arg1&& arg1, Args&&... args)
|
||||
: source(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
as_table_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
T& value() & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(value_);
|
||||
}
|
||||
|
||||
const T& value() const& {
|
||||
return value_;
|
||||
}
|
||||
|
||||
operator std::add_lvalue_reference_t<T>() {
|
||||
return source;
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct nested {
|
||||
T source;
|
||||
private:
|
||||
T value_;
|
||||
|
||||
public:
|
||||
nested() = default;
|
||||
nested(const nested&) = default;
|
||||
nested(nested&&) = default;
|
||||
nested& operator=(const nested&) = default;
|
||||
nested& operator=(nested&&) = default;
|
||||
template <typename Arg, meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, nested>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
nested(Arg&& arg)
|
||||
: source(std::forward<Arg>(arg)) {
|
||||
template <typename Arg,
|
||||
meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, nested>>,
|
||||
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
nested(Arg&& arg) : value_(std::forward<Arg>(arg)) {
|
||||
}
|
||||
template <typename Arg0, typename Arg1, typename... Args>
|
||||
nested(Arg0&& arg0, Arg1&& arg1, Args&&... args)
|
||||
: source(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
nested(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
T& value() & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(value_);
|
||||
}
|
||||
|
||||
const T& value() const& {
|
||||
return value_;
|
||||
}
|
||||
|
||||
operator std::add_lvalue_reference_t<T>() {
|
||||
return source;
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -465,29 +476,52 @@ namespace sol {
|
|||
|
||||
template <typename T>
|
||||
struct as_container_t {
|
||||
T source;
|
||||
|
||||
as_container_t(T value) : source(std::move(value)) {
|
||||
private:
|
||||
T value_;
|
||||
|
||||
public:
|
||||
as_container_t() = default;
|
||||
as_container_t(const as_container_t&) = default;
|
||||
as_container_t(as_container_t&&) = default;
|
||||
as_container_t& operator=(const as_container_t&) = default;
|
||||
as_container_t& operator=(as_container_t&&) = default;
|
||||
template <typename Arg,
|
||||
meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, as_container_t>>,
|
||||
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
as_container_t(Arg&& arg) : value_(std::forward<Arg>(arg)) {
|
||||
}
|
||||
template <typename Arg0, typename Arg1, typename... Args>
|
||||
as_container_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
operator std::add_rvalue_reference_t<T>() {
|
||||
return std::move(source);
|
||||
T& value() & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
operator std::add_lvalue_reference_t<std::add_const_t<T>>() const {
|
||||
return source;
|
||||
T&& value() && {
|
||||
return std::move(value_);
|
||||
}
|
||||
|
||||
const T& value() const& {
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct as_container_t<T&> {
|
||||
std::reference_wrapper<T> source;
|
||||
private:
|
||||
std::reference_wrapper<T> value_;
|
||||
|
||||
as_container_t(T& value) : source(value) {
|
||||
public:
|
||||
as_container_t(T& value) : value_(value) {
|
||||
}
|
||||
|
||||
T& value() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
operator T&() {
|
||||
return source;
|
||||
return value();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -496,14 +530,69 @@ namespace sol {
|
|||
return as_container_t<T>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
struct force_t {};
|
||||
constexpr inline force_t force = force_t();
|
||||
template <typename T>
|
||||
struct push_invoke_t {
|
||||
private:
|
||||
T value_;
|
||||
|
||||
public:
|
||||
push_invoke_t() = default;
|
||||
push_invoke_t(const push_invoke_t&) = default;
|
||||
push_invoke_t(push_invoke_t&&) = default;
|
||||
push_invoke_t& operator=(const push_invoke_t&) = default;
|
||||
push_invoke_t& operator=(push_invoke_t&&) = default;
|
||||
template <typename Arg,
|
||||
meta::enable<meta::neg<std::is_same<meta::unqualified_t<Arg>, push_invoke_t>>,
|
||||
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<Arg>>>> = meta::enabler>
|
||||
push_invoke_t(Arg&& arg) : value_(std::forward<Arg>(arg)) {
|
||||
}
|
||||
template <typename Arg0, typename Arg1, typename... Args>
|
||||
push_invoke_t(Arg0&& arg0, Arg1&& arg1, Args&&... args) : value_(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Args>(args)...) {
|
||||
}
|
||||
|
||||
T& value() & {
|
||||
return value_;
|
||||
}
|
||||
|
||||
T&& value() && {
|
||||
return std::move(value_);
|
||||
}
|
||||
|
||||
const T& value() const & {
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct push_invoke_t<T&> {
|
||||
std::reference_wrapper<T> value_;
|
||||
|
||||
push_invoke_t(T& value) : value_(value) {
|
||||
}
|
||||
|
||||
T& value() {
|
||||
return value_;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Fx>
|
||||
auto push_invoke(Fx&& fx) {
|
||||
return push_invoke_t<Fx>(std::forward<Fx>(fx));
|
||||
}
|
||||
|
||||
struct override_value_t {};
|
||||
constexpr inline override_value_t override_value = override_value_t();
|
||||
struct update_if_empty_t {};
|
||||
constexpr inline update_if_empty_t update_if_empty = update_if_empty_t();
|
||||
|
||||
namespace detail {
|
||||
enum insert_mode { none = 0x0, update_if_empty = 0x01, override_value = 0x02 };
|
||||
}
|
||||
|
||||
struct this_state {
|
||||
lua_State* L;
|
||||
|
||||
this_state(lua_State* Ls)
|
||||
: L(Ls) {
|
||||
this_state(lua_State* Ls) : L(Ls) {
|
||||
}
|
||||
|
||||
operator lua_State*() const noexcept {
|
||||
|
@ -522,8 +611,7 @@ namespace sol {
|
|||
struct this_main_state {
|
||||
lua_State* L;
|
||||
|
||||
this_main_state(lua_State* Ls)
|
||||
: L(Ls) {
|
||||
this_main_state(lua_State* Ls) : L(Ls) {
|
||||
}
|
||||
|
||||
operator lua_State*() const noexcept {
|
||||
|
@ -549,8 +637,7 @@ namespace sol {
|
|||
new_table& operator=(const new_table&) = default;
|
||||
new_table& operator=(new_table&&) = default;
|
||||
|
||||
new_table(int sequence_hint, int map_hint = 0)
|
||||
: sequence_hint(sequence_hint), map_hint(map_hint) {
|
||||
new_table(int sequence_hint, int map_hint = 0) : sequence_hint(sequence_hint), map_hint(map_hint) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -587,10 +674,7 @@ namespace sol {
|
|||
count
|
||||
};
|
||||
|
||||
enum class call_syntax {
|
||||
dot = 0,
|
||||
colon = 1
|
||||
};
|
||||
enum class call_syntax { dot = 0, colon = 1 };
|
||||
|
||||
enum class load_mode {
|
||||
any = 0,
|
||||
|
@ -696,13 +780,9 @@ namespace sol {
|
|||
}
|
||||
|
||||
inline const std::string& to_string(load_status c) {
|
||||
static const std::array<std::string, 7> names{ { "ok",
|
||||
"memory",
|
||||
"gc",
|
||||
"syntax",
|
||||
"file",
|
||||
"CRITICAL_EXCEPTION_FAILURE",
|
||||
"CRITICAL_INDETERMINATE_STATE_FAILURE" } };
|
||||
static const std::array<std::string, 7> names{
|
||||
{ "ok", "memory", "gc", "syntax", "file", "CRITICAL_EXCEPTION_FAILURE", "CRITICAL_INDETERMINATE_STATE_FAILURE" }
|
||||
};
|
||||
switch (c) {
|
||||
case load_status::ok:
|
||||
return names[0];
|
||||
|
@ -829,16 +909,15 @@ namespace sol {
|
|||
|
||||
template <typename T>
|
||||
struct is_lua_reference : std::integral_constant<bool,
|
||||
std::is_base_of<reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<main_reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value> {};
|
||||
std::is_base_of<reference, meta::unqualified_t<T>>::value || std::is_base_of<main_reference, meta::unqualified_t<T>>::value
|
||||
|| std::is_base_of<stack_reference, meta::unqualified_t<T>>::value> {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_lua_reference_v = is_lua_reference<T>::value;
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_reference_or_proxy
|
||||
: std::integral_constant<bool, is_lua_reference<meta::unqualified_t<T>>::value || meta::is_specialization_of<meta::unqualified_t<T>, proxy>::value> {};
|
||||
: std::integral_constant<bool, is_lua_reference<meta::unqualified_t<T>>::value || meta::is_specialization_of<meta::unqualified_t<T>, proxy>::value> {};
|
||||
|
||||
template <typename T>
|
||||
inline constexpr bool is_lua_reference_or_proxy_v = is_lua_reference_or_proxy<T>::value;
|
||||
|
@ -873,17 +952,23 @@ namespace sol {
|
|||
struct is_container<T, std::enable_if_t<meta::is_string_like<meta::unqualified_t<T>>::value>> : std::false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<T, std::enable_if_t<meta::all<std::is_array<meta::unqualified_t<T>>, meta::neg<meta::any_same<std::remove_all_extents_t<meta::unqualified_t<T>>, char, wchar_t, char16_t, char32_t>>>::value>> : std::true_type {};
|
||||
struct is_container<T,
|
||||
std::enable_if_t<meta::all<std::is_array<meta::unqualified_t<T>>,
|
||||
meta::neg<meta::any_same<std::remove_all_extents_t<meta::unqualified_t<T>>, char, wchar_t, char16_t, char32_t>>>::value>> : std::true_type {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_container<T, std::enable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<is_initializer_list<meta::unqualified_t<T>>>, meta::neg<meta::is_string_like<meta::unqualified_t<T>>>>::value>> : std::true_type {};
|
||||
struct is_container<T,
|
||||
std::enable_if_t<meta::all<meta::has_begin_end<meta::unqualified_t<T>>, meta::neg<is_initializer_list<meta::unqualified_t<T>>>,
|
||||
meta::neg<meta::is_string_like<meta::unqualified_t<T>>>>::value>> : std::true_type {};
|
||||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct is_container : detail::is_container<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_to_stringable : meta::any<meta::supports_to_string_member<meta::unqualified_t<T>>, meta::supports_adl_to_string<meta::unqualified_t<T>>, meta::supports_ostream_op<meta::unqualified_t<T>>> {};
|
||||
struct is_to_stringable : meta::any<meta::supports_to_string_member<meta::unqualified_t<T>>, meta::supports_adl_to_string<meta::unqualified_t<T>>,
|
||||
meta::supports_ostream_op<meta::unqualified_t<T>>> {};
|
||||
|
||||
namespace detail {
|
||||
template <typename T, typename = void>
|
||||
|
@ -956,13 +1041,13 @@ namespace sol {
|
|||
struct lua_type_of<basic_usertype<T, Base>> : std::integral_constant<type, type::table> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<metatable_t> : std::integral_constant<type, type::table> {};
|
||||
struct lua_type_of<metatable_key_t> : std::integral_constant<type, type::table> {};
|
||||
|
||||
template <typename B>
|
||||
struct lua_type_of<basic_environment<B>> : std::integral_constant<type, type::poly> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<env_t> : std::integral_constant<type, type::poly> {};
|
||||
struct lua_type_of<env_key_t> : std::integral_constant<type, type::poly> {};
|
||||
|
||||
template <>
|
||||
struct lua_type_of<new_table> : std::integral_constant<type, type::table> {};
|
||||
|
@ -1130,7 +1215,9 @@ namespace sol {
|
|||
|
||||
namespace detail {
|
||||
template <typename...>
|
||||
struct void_ { typedef void type; };
|
||||
struct void_ {
|
||||
typedef void type;
|
||||
};
|
||||
template <typename T, typename = void>
|
||||
struct has_internal_marker_impl : std::false_type {};
|
||||
template <typename T>
|
||||
|
@ -1141,14 +1228,13 @@ namespace sol {
|
|||
} // namespace detail
|
||||
|
||||
template <typename T>
|
||||
struct is_lua_primitive : std::integral_constant<bool,
|
||||
type::userdata != lua_type_of<meta::unqualified_t<T>>::value
|
||||
|| ((type::userdata == lua_type_of<meta::unqualified_t<T>>::value)
|
||||
&& detail::has_internal_marker<lua_type_of<meta::unqualified_t<T>>>::value
|
||||
&& !detail::has_internal_marker<lua_size<meta::unqualified_t<T>>>::value)
|
||||
|| is_lua_reference<meta::unqualified_t<T>>::value
|
||||
|| meta::is_specialization_of<meta::unqualified_t<T>, std::tuple>::value
|
||||
|| meta::is_specialization_of<meta::unqualified_t<T>, std::pair>::value> {};
|
||||
struct is_lua_primitive
|
||||
: std::integral_constant<bool,
|
||||
type::userdata != lua_type_of<meta::unqualified_t<T>>::value
|
||||
|| ((type::userdata == lua_type_of<meta::unqualified_t<T>>::value) && detail::has_internal_marker<lua_type_of<meta::unqualified_t<T>>>::value
|
||||
&& !detail::has_internal_marker<lua_size<meta::unqualified_t<T>>>::value)
|
||||
|| is_lua_reference<meta::unqualified_t<T>>::value || meta::is_specialization_of<meta::unqualified_t<T>, std::tuple>::value
|
||||
|| meta::is_specialization_of<meta::unqualified_t<T>, std::pair>::value> {};
|
||||
|
||||
template <typename T>
|
||||
struct is_main_threaded : std::is_base_of<main_reference, T> {};
|
||||
|
@ -1217,9 +1303,11 @@ namespace sol {
|
|||
public:
|
||||
typedef std::integral_constant<bool, meta::count_for<is_variadic_arguments, typename base_t::args_list>::value != 0> runtime_variadics_t;
|
||||
static const std::size_t true_arity = base_t::arity;
|
||||
static const std::size_t arity = detail::accumulate_list<std::size_t, 0, lua_size, typename base_t::args_list>::value - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
|
||||
static const std::size_t arity = detail::accumulate_list<std::size_t, 0, lua_size, typename base_t::args_list>::value
|
||||
- meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
|
||||
static const std::size_t true_free_arity = base_t::free_arity;
|
||||
static const std::size_t free_arity = detail::accumulate_list<std::size_t, 0, lua_size, typename base_t::free_args_list>::value - meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
|
||||
static const std::size_t free_arity = detail::accumulate_list<std::size_t, 0, lua_size, typename base_t::free_args_list>::value
|
||||
- meta::count_for<is_transparent_argument, typename base_t::args_list>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -387,11 +387,11 @@ namespace sol {
|
|||
}
|
||||
|
||||
static int push(lua_State* L, const as_container_t<T>& as_cont) {
|
||||
return push_lvalue(std::is_lvalue_reference<T>(), L, as_cont.source);
|
||||
return push_lvalue(std::is_lvalue_reference<T>(), L, as_cont.value());
|
||||
}
|
||||
|
||||
static int push(lua_State* L, as_container_t<T>&& as_cont) {
|
||||
return push_rvalue(meta::all<std::is_rvalue_reference<T>, meta::neg<std::is_lvalue_reference<T>>>(), L, std::forward<T>(as_cont.source));
|
||||
return push_rvalue(meta::all<std::is_rvalue_reference<T>, meta::neg<std::is_lvalue_reference<T>>>(), L, std::forward<T>(as_cont.value()));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// This file was generated with a script.
|
||||
// Generated 2019-02-14 09:52:13.841439 UTC
|
||||
// This header was generated with sol v2.20.6 (revision b938e42)
|
||||
// Generated 2019-02-16 22:26:16.417718 UTC
|
||||
// This header was generated with sol v3.0.0 (revision 95ffd10)
|
||||
// https://github.com/ThePhD/sol2
|
||||
|
||||
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP
|
||||
|
@ -376,8 +376,6 @@ namespace sol {
|
|||
template <typename T>
|
||||
struct as_container_t;
|
||||
template <typename T>
|
||||
struct force_t;
|
||||
template <typename T>
|
||||
struct nested;
|
||||
template <typename T>
|
||||
struct light;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,7 +47,7 @@ TEST_CASE("containers/vector table roundtrip", "make sure vectors can be round-t
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::vector<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ TEST_CASE("containers/deque table roundtrip", "make sure deques can be round-tri
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::deque<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ TEST_CASE("containers/array table roundtrip", "make sure arrays can be round-tri
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::array<int, 3>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ TEST_CASE("containers/list table roundtrip", "make sure lists can be round-tripp
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::list<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ TEST_CASE("containers/forward_list table roundtrip", "make sure forward_lists ca
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::forward_list<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ TEST_CASE("containers/map table roundtrip", "make sure maps can be round-tripped
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::map<std::string, int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ TEST_CASE("containers/unordered_map table roundtrip", "make sure unordered_maps
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::unordered_map<std::string, int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ TEST_CASE("containers/unordered_set table roundtrip", "make sure unordered_sets
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::unordered_set<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ TEST_CASE("containers/set table roundtrip", "make sure sets can be round-tripped
|
|||
auto result1 = lua.safe_script("x = f()", sol::script_pass_on_error);
|
||||
REQUIRE(result1.valid());
|
||||
sol::as_table_t<std::set<int>> x = lua["x"];
|
||||
bool areequal = x.source == v;
|
||||
bool areequal = x.value() == v;
|
||||
REQUIRE(areequal);
|
||||
}
|
||||
|
||||
|
@ -248,8 +248,8 @@ TEST_CASE("containers/table conversion", "test table conversions with as_table a
|
|||
sol::nested<std::vector<std::string>> nested_strings = lua["v2"];
|
||||
|
||||
std::vector<std::string> expected_values{ "bark", "woof" };
|
||||
REQUIRE(as_table_strings.source == expected_values);
|
||||
REQUIRE(nested_strings.source == expected_values);
|
||||
REQUIRE(as_table_strings.value() == expected_values);
|
||||
REQUIRE(nested_strings.value() == expected_values);
|
||||
}
|
||||
|
||||
TEST_CASE("containers/from table argument conversions", "test table conversions without as_table and nested for function args") {
|
||||
|
|
|
@ -201,11 +201,11 @@ end
|
|||
sol::as_table_t<std::forward_list<int>> t1flist = lua["c"];
|
||||
sol::as_table_t<std::set<int>> t1set = lua["c"];
|
||||
const int src[5] = { 1, 2, 3, 4, 5 };
|
||||
check_ordered_values(src, t1vector.source);
|
||||
check_ordered_values(src, t1deque.source);
|
||||
check_ordered_values(src, t1list.source);
|
||||
check_ordered_values(src, t1flist.source);
|
||||
check_ordered_values(src, t1set.source);
|
||||
check_ordered_values(src, t1vector.value());
|
||||
check_ordered_values(src, t1deque.value());
|
||||
check_ordered_values(src, t1list.value());
|
||||
check_ordered_values(src, t1flist.value());
|
||||
check_ordered_values(src, t1set.value());
|
||||
}
|
||||
SECTION("map-like") {
|
||||
sol::state lua;
|
||||
|
@ -216,7 +216,7 @@ end
|
|||
|
||||
sol::as_table_t<std::unordered_map<std::string, int>> t1umap = lua["c"];
|
||||
sol::as_table_t<std::unordered_multimap<std::string, int>> t1ummap = lua["c"];
|
||||
table_check_unordered_values(src, t1umap.source);
|
||||
table_check_unordered_values(src, t1ummap.source);
|
||||
table_check_unordered_values(src, t1umap.value());
|
||||
table_check_unordered_values(src, t1ummap.value());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2018 Rapptz, ThePhD 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.
|
||||
|
||||
#include "sol_test.hpp"
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
TEST_CASE("tables/force", "allow force by way of key") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::io);
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua["a"].force()["b"].force()["c"] = 357;
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
}
|
||||
|
||||
TEST_CASE("tables/proxy force", "allow proxies to force creation of tables with explicit function") {
|
||||
SECTION("explicit") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua["a"].force()["b"].force()["c"] = 357;
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
}
|
||||
SECTION("key type") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua[sol::force]["a"]["b"]["c"] = 357;
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
}
|
||||
}
|
132
tests/runtime_tests/source/tables.insertion.cpp
Normal file
132
tests/runtime_tests/source/tables.insertion.cpp
Normal file
|
@ -0,0 +1,132 @@
|
|||
// sol3
|
||||
|
||||
// The MIT License (MIT)
|
||||
|
||||
// Copyright (c) 2013-2018 Rapptz, ThePhD 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.
|
||||
|
||||
#include "sol_test.hpp"
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
TEST_CASE("tables/proxy override_value", "allow override_value by way of key") {
|
||||
sol::state lua;
|
||||
lua.open_libraries(sol::lib::base, sol::lib::io);
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua["a"].force()["b"].force()["c"] = 357;
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
}
|
||||
|
||||
TEST_CASE("tables/insertion override", "allow override all non-table values plus final value") {
|
||||
SECTION("traverse") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua.traverse_set(sol::override_value, "a", "b", "c", 357);
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
|
||||
lua.traverse_set(sol::override_value, "a", "b", 500);
|
||||
sol::optional<int> b_totally_there = lua["a"]["b"];
|
||||
sol::optional<int> totally_not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(b_totally_there));
|
||||
REQUIRE(*b_totally_there == 500);
|
||||
REQUIRE_FALSE(static_cast<bool>(totally_not_there));
|
||||
}
|
||||
SECTION("proxy") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua[sol::override_value]["a"]["b"]["c"] = 357;
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
|
||||
lua[sol::override_value]["a"]["b"] = 500;
|
||||
sol::optional<int> b_totally_there = lua["a"]["b"];
|
||||
sol::optional<int> totally_not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(b_totally_there));
|
||||
REQUIRE(*b_totally_there == 500);
|
||||
REQUIRE_FALSE(static_cast<bool>(totally_not_there));
|
||||
}
|
||||
SECTION("complex proxy") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
int definitely_there = (lua[sol::override_value]["a"]["b"]["c"] = 357);
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == definitely_there);
|
||||
REQUIRE(*totally_there == 357);
|
||||
REQUIRE(definitely_there == 357);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("tables/insertion update_if_empty", "allow updating a value only if it's missing") {
|
||||
SECTION("traverse") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua.traverse_set(sol::update_if_empty, "a", "b", "c", 357);
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
}
|
||||
SECTION("proxy") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua[sol::update_if_empty]["a"]["b"]["c"] = 357;
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
|
||||
lua[sol::update_if_empty]["a"]["b"]["c"] = 500;
|
||||
sol::optional<int> totally_there_still = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there_still));
|
||||
REQUIRE(*totally_there_still == 357);
|
||||
}
|
||||
SECTION("proxy invoker") {
|
||||
sol::state lua;
|
||||
|
||||
sol::optional<int> not_there = lua["a"]["b"]["c"];
|
||||
REQUIRE_FALSE(static_cast<bool>(not_there));
|
||||
lua[sol::update_if_empty]["a"]["b"]["c"] = sol::push_invoke([]() { return 357; });
|
||||
sol::optional<int> totally_there = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there));
|
||||
REQUIRE(*totally_there == 357);
|
||||
|
||||
lua[sol::update_if_empty]["a"]["b"]["c"] = sol::push_invoke([]() { return 1000; });
|
||||
sol::optional<int> totally_there_still = lua["a"]["b"]["c"];
|
||||
REQUIRE(static_cast<bool>(totally_there_still));
|
||||
REQUIRE(*totally_there_still == 357);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user