From 92c388e30a94ab2dee63eee07087402181a2f3dc Mon Sep 17 00:00:00 2001 From: ThePhD Date: Wed, 30 Mar 2016 01:40:40 -0400 Subject: [PATCH] And nooow we're set for optional. Totally. With the `get_or` implementation as well. Hopefully this will be all we need. --- sol/stack_field.hpp | 27 +++++++++++++++++++++------ sol/state_view.hpp | 10 ++++++++++ sol/table_core.hpp | 25 ++++++++++++++++--------- tests.cpp | 41 ++++++++++++++++++++++------------------- 4 files changed, 69 insertions(+), 34 deletions(-) diff --git a/sol/stack_field.hpp b/sol/stack_field.hpp index 1c283fd2..add7df2b 100644 --- a/sol/stack_field.hpp +++ b/sol/stack_field.hpp @@ -43,14 +43,19 @@ struct field_getter, b, C> { template void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) { get_field(L, detail::forward_get<0>(keys), tableindex); - void(detail::swallow{ (get_field(L, detail::forward_get(keys), -1), 0)... }); + void(detail::swallow{ (get_field(L, detail::forward_get(keys)), 0)... }); reference saved(L, -1); lua_pop(L, static_cast(sizeof...(I))); saved.push(); } template - void get(lua_State* L, Keys&& keys, int tableindex = -2) { + void get(lua_State* L, Keys&& keys) { + apply(std::index_sequence_for(), L, std::forward(keys), lua_absindex(L, -1)); + } + + template + void get(lua_State* L, Keys&& keys, int tableindex) { apply(std::index_sequence_for(), L, std::forward(keys), tableindex); } }; @@ -58,10 +63,18 @@ struct field_getter, b, C> { template struct field_getter, b, C> { template - 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(L, detail::forward_get<0>(keys), tableindex); - get_field(L, detail::forward_get<1>(keys), tableindex + 1); + get_field(L, detail::forward_get<1>(keys)); + reference saved(L, -1); + lua_pop(L, static_cast(2)); + saved.push(); + } + + template + void get(lua_State* L, Keys&& keys) { + get_field(L, detail::forward_get<0>(keys)); + get_field(L, detail::forward_get<1>(keys)); reference saved(L, -1); lua_pop(L, static_cast(2)); saved.push(); @@ -137,7 +150,9 @@ template struct field_setter, b, C> { template void apply(std::index_sequence, lua_State* L, Key&& keys, Value&& value, int tableindex) { - set_field(L, detail::forward_get(keys), std::forward(value), I > 0 ? -1 : tableindex); + I > 0 ? + set_field(L, detail::forward_get(keys), std::forward(value)) : + set_field(L, detail::forward_get(keys), std::forward(value), tableindex); } template diff --git a/sol/state_view.hpp b/sol/state_view.hpp index 56e5905c..ab289211 100644 --- a/sol/state_view.hpp +++ b/sol/state_view.hpp @@ -182,6 +182,16 @@ public: return global.get(std::forward(keys)...); } + template + decltype(auto) get_or(Key&& key, T&& otherwise) const { + return global.get_or(std::forward(key), std::forward(otherwise)); + } + + template + decltype(auto) get_or(Key&& key, D&& otherwise) const { + return global.get_or(std::forward(key), std::forward(otherwise)); + } + template state_view& set(Args&&... args) { global.set(std::forward(args)...); diff --git a/sol/table_core.hpp b/sol/table_core.hpp index f530ec4c..c56c562a 100644 --- a/sol/table_core.hpp +++ b/sol/table_core.hpp @@ -178,16 +178,23 @@ public: return tuple_get( types( ), std::index_sequence_for( ), std::forward_as_tuple(std::forward(keys)...)); } - template - Ret get_with_default(Key key, Ret _default) const { + template + decltype(auto) get_or(Key&& key, T&& otherwise) const { + typedef decltype(get("")) U; + sol::optional option = get>(std::forward(key)); + if (option) { + return static_cast(option.value()); + } + return static_cast(std::forward(otherwise)); + } - sol::optional option = operator[](key); - if( option ){ - return option.value(); - } - else { - return _default; - } + template + decltype(auto) get_or(Key&& key, D&& otherwise) const { + sol::optional option = get>(std::forward(key)); + if (option) { + return static_cast(option.value()); + } + return static_cast(std::forward(otherwise)); } template diff --git a/tests.cpp b/tests.cpp index 9b7f4ae6..b7f4d9da 100644 --- a/tests.cpp +++ b/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("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 non_nope3 = lua["nope"]["kek"]["hah"].get>(); sol::optional non_nope4 = lua.get>(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") {