mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
And nooow we're set for optional. Totally. With the get_or
implementation as well. Hopefully this will be all we need.
This commit is contained in:
parent
9804d7dd63
commit
92c388e30a
@ -43,14 +43,19 @@ struct field_getter<std::tuple<Args...>, b, C> {
|
||||
template <std::size_t... I, typename Keys>
|
||||
void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) {
|
||||
get_field<b>(L, detail::forward_get<0>(keys), tableindex);
|
||||
void(detail::swallow{ (get_field<false>(L, detail::forward_get<I>(keys), -1), 0)... });
|
||||
void(detail::swallow{ (get_field<false>(L, detail::forward_get<I>(keys)), 0)... });
|
||||
reference saved(L, -1);
|
||||
lua_pop(L, static_cast<int>(sizeof...(I)));
|
||||
saved.push();
|
||||
}
|
||||
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys, int tableindex = -2) {
|
||||
void get(lua_State* L, Keys&& keys) {
|
||||
apply(std::index_sequence_for<Args...>(), L, std::forward<Keys>(keys), lua_absindex(L, -1));
|
||||
}
|
||||
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys, int tableindex) {
|
||||
apply(std::index_sequence_for<Args...>(), L, std::forward<Keys>(keys), tableindex);
|
||||
}
|
||||
};
|
||||
@ -58,10 +63,18 @@ struct field_getter<std::tuple<Args...>, b, C> {
|
||||
template <typename A, typename B, bool b, typename C>
|
||||
struct field_getter<std::pair<A, B>, b, C> {
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys, int tableindex = -2) {
|
||||
tableindex = lua_absindex(L, tableindex);
|
||||
void get(lua_State* L, Keys&& keys, int tableindex) {
|
||||
get_field<b>(L, detail::forward_get<0>(keys), tableindex);
|
||||
get_field<false>(L, detail::forward_get<1>(keys), tableindex + 1);
|
||||
get_field<false>(L, detail::forward_get<1>(keys));
|
||||
reference saved(L, -1);
|
||||
lua_pop(L, static_cast<int>(2));
|
||||
saved.push();
|
||||
}
|
||||
|
||||
template <typename Keys>
|
||||
void get(lua_State* L, Keys&& keys) {
|
||||
get_field<b>(L, detail::forward_get<0>(keys));
|
||||
get_field<false>(L, detail::forward_get<1>(keys));
|
||||
reference saved(L, -1);
|
||||
lua_pop(L, static_cast<int>(2));
|
||||
saved.push();
|
||||
@ -137,7 +150,9 @@ template <typename... Args, bool b, typename C>
|
||||
struct field_setter<std::tuple<Args...>, b, C> {
|
||||
template <bool g, std::size_t I, typename Key, typename Value>
|
||||
void apply(std::index_sequence<I>, lua_State* L, Key&& keys, Value&& value, int tableindex) {
|
||||
set_field<g>(L, detail::forward_get<I>(keys), std::forward<Value>(value), I > 0 ? -1 : tableindex);
|
||||
I > 0 ?
|
||||
set_field<g>(L, detail::forward_get<I>(keys), std::forward<Value>(value)) :
|
||||
set_field<g>(L, detail::forward_get<I>(keys), std::forward<Value>(value), tableindex);
|
||||
}
|
||||
|
||||
template <bool g, std::size_t I0, std::size_t I1, std::size_t... I, typename Keys, typename Value>
|
||||
|
@ -182,6 +182,16 @@ public:
|
||||
return global.get<Args...>(std::forward<Keys>(keys)...);
|
||||
}
|
||||
|
||||
template<typename T, typename Key>
|
||||
decltype(auto) get_or(Key&& key, T&& otherwise) const {
|
||||
return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
|
||||
}
|
||||
|
||||
template<typename T, typename Key, typename D>
|
||||
decltype(auto) get_or(Key&& key, D&& otherwise) const {
|
||||
return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
state_view& set(Args&&... args) {
|
||||
global.set(std::forward<Args>(args)...);
|
||||
|
@ -178,16 +178,23 @@ public:
|
||||
return tuple_get( types<Ret...>( ), std::index_sequence_for<Ret...>( ), std::forward_as_tuple(std::forward<Keys>(keys)...));
|
||||
}
|
||||
|
||||
template<typename Ret, typename Key>
|
||||
Ret get_with_default(Key key, Ret _default) const {
|
||||
template<typename T, typename Key>
|
||||
decltype(auto) get_or(Key&& key, T&& otherwise) const {
|
||||
typedef decltype(get<T>("")) U;
|
||||
sol::optional<U> option = get<sol::optional<U>>(std::forward<Key>(key));
|
||||
if (option) {
|
||||
return static_cast<U>(option.value());
|
||||
}
|
||||
return static_cast<U>(std::forward<T>(otherwise));
|
||||
}
|
||||
|
||||
sol::optional<Ret> option = operator[](key);
|
||||
if( option ){
|
||||
return option.value();
|
||||
}
|
||||
else {
|
||||
return _default;
|
||||
}
|
||||
template<typename T, typename Key, typename D>
|
||||
decltype(auto) get_or(Key&& key, D&& otherwise) const {
|
||||
sol::optional<T> option = get<sol::optional<T>>(std::forward<Key>(key));
|
||||
if (option) {
|
||||
return static_cast<T>(option.value());
|
||||
}
|
||||
return static_cast<T>(std::forward<D>(otherwise));
|
||||
}
|
||||
|
||||
template <typename T, typename... Keys>
|
||||
|
41
tests.cpp
41
tests.cpp
@ -325,6 +325,25 @@ TEST_CASE("simple/set-get-global-integer", "Tests if the get function works prop
|
||||
REQUIRE(b == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("simple/get_or", "check if table.get_or works correctly") {
|
||||
sol::state lua;
|
||||
|
||||
auto bob_table = lua.create_table("bob");
|
||||
int is_set=0;
|
||||
int is_not_set=0;
|
||||
bob_table.set("is_set",42);
|
||||
|
||||
is_set = bob_table.get_or("is_set", 3);
|
||||
is_not_set = bob_table.get_or("is_not_set", 22);
|
||||
|
||||
REQUIRE(is_set == 42);
|
||||
REQUIRE(is_not_set == 22);
|
||||
|
||||
lua["joe"] = 55.6;
|
||||
double bark = lua.get_or<double>("joe", 60);
|
||||
REQUIRE(bark == 55.6);
|
||||
}
|
||||
|
||||
TEST_CASE("simple/addition", "check if addition works and can be gotten through lua.get and lua.set") {
|
||||
sol::state lua;
|
||||
|
||||
@ -505,23 +524,6 @@ TEST_CASE("tables/variables", "Check if tables and variables work as intended")
|
||||
REQUIRE_NOTHROW(lua.script("assert(os.name == \"windows\")"));
|
||||
}
|
||||
|
||||
TEST_CASE("simple/get_default", "Test that table::get_default work corretly") {
|
||||
sol::state lua;
|
||||
|
||||
auto bob_table = lua.create_table("bob");
|
||||
int is_set=0;
|
||||
int is_not_set=0;
|
||||
bob_table.set("is_set",42);
|
||||
|
||||
is_set = bob_table.get_with_default("is_set",3);
|
||||
is_not_set = bob_table.get_with_default("is_not_set",22);
|
||||
|
||||
REQUIRE(is_set == 42);
|
||||
REQUIRE(is_not_set == 22);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("tables/create", "Check if creating a table is kosher") {
|
||||
sol::state lua;
|
||||
lua["testtable"] = sol::table::create(lua.lua_state(), 0, 0, "Woof", "Bark", 1, 2, 3, 4);
|
||||
@ -719,6 +721,7 @@ TEST_CASE("tables/operator[]-optional", "Test if proxies on tables can lazily ev
|
||||
REQUIRE(non_nope.value() == 1);
|
||||
REQUIRE(non_nope2.value() == 1);
|
||||
|
||||
std::cout << "Keys: nope, kek, hah" << std::endl;
|
||||
lua.set(std::make_tuple("nope", "kek", "hah"), 35);
|
||||
sol::optional<int> non_nope3 = lua["nope"]["kek"]["hah"].get<sol::optional<int>>();
|
||||
sol::optional<int> non_nope4 = lua.get<sol::optional<int>>(std::make_tuple("nope", "kek", "hah"));
|
||||
@ -726,8 +729,8 @@ TEST_CASE("tables/operator[]-optional", "Test if proxies on tables can lazily ev
|
||||
REQUIRE(present);
|
||||
present = (bool)non_nope4;
|
||||
REQUIRE(present);
|
||||
REQUIRE(non_nope3.value() == 1);
|
||||
REQUIRE(non_nope4.value() == 1);
|
||||
REQUIRE(non_nope3.value() == 35);
|
||||
REQUIRE(non_nope4.value() == 35);
|
||||
}
|
||||
|
||||
TEST_CASE("tables/usertype", "Show that we can create classes from usertype and use them") {
|
||||
|
Loading…
x
Reference in New Issue
Block a user