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:
ThePhD 2016-03-30 01:40:40 -04:00
parent 9804d7dd63
commit 92c388e30a
4 changed files with 69 additions and 34 deletions

View File

@ -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>

View File

@ -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)...);

View File

@ -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>

View File

@ -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") {