Mercurial > code
changeset 228:927c4f3b8a88
Add Luae::optional to templatize luaL_opt*
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 09 Jun 2014 13:05:33 +0200 |
parents | 4c9b2a3f2396 |
children | 96ff112d05cf 5e1001649d07 |
files | C++/Luae.h C++/Tests/Luae/TestLuae.cpp C++/Tests/Luae/TestLuae.h |
diffstat | 3 files changed, 248 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/Luae.h Thu May 29 10:58:32 2014 +0200 +++ b/C++/Luae.h Mon Jun 09 13:05:33 2014 +0200 @@ -132,6 +132,11 @@ * * return get(L, index); * } + * + * static Point optional(lua_State *L, int index, const Point &def) + * { + * // Do your check or return def + * } * }; * * int l_push(lua_State *L) @@ -166,6 +171,7 @@ static const bool canGet = true; static const bool canPush = true; static const bool canCheck = true; + static const bool canOptional = true; static const bool isCustom = true; static const bool isUserdata = false; }; @@ -191,9 +197,7 @@ }; template <typename T> - struct IsSharedUserdata : std::false_type - { - }; + struct IsSharedUserdata : std::false_type { }; template <typename T> struct IsSharedUserdata<std::shared_ptr<T>> { @@ -1060,6 +1064,45 @@ } /** + * Get an optional custom type. Returns the value or the + * def argument. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + template <typename T> + static EnableIf<IsCustom<T>::value, T> + optional(lua_State *L, int index, const T &def) + { + static_assert(TypeInfo<T>::canOptional, "type not supported"); + + return TypeInfo<T>::optional(L, index, def); + } + + /** + * Get an optional userdata, returns the userdata pointer + * or a new created one. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + template <typename T> + static EnableIf<IsUserdata<T>::value, T *> + optional(lua_State *L, int index, const T &def) + { + auto ptr = luaL_testudata(L, index, TypeInfo<T>::name); + + if (!ptr) + return new (L, TypeInfo<T>::name) T(def); + + return ptr; + } + + /** * Get a custom type with check. * * @param L the Lua state @@ -1190,6 +1233,22 @@ { return lua_toboolean(L, index); } + + /** + * Get an optional boolean. + * + * @param L the Lua state + * @param index the index + * @param def the default value if not boolean + * @return the value or def + */ + static bool optional(lua_State *L, int index, const bool &def) + { + if (lua_type(L, index) == LUA_TBOOLEAN) + return lua_toboolean(L, index); + + return def; + } }; /** @@ -1230,6 +1289,19 @@ { return luaL_checkinteger(L, index); } + + /** + * Get an optional integer. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + static int optional(lua_State *L, int index, const int &def) + { + return luaL_optint(L, index, def); + } }; /** @@ -1270,6 +1342,19 @@ { return luaL_checkinteger(L, index); } + + /** + * Get an optional long. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + static long optional(lua_State *L, int index, const long &def) + { + return luaL_optlong(L, index, def); + } }; /** @@ -1310,6 +1395,19 @@ { return luaL_checknumber(L, index); } + + /** + * Get an optional double. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + static double optional(lua_State *L, int index, const double &def) + { + return luaL_optnumber(L, index, def); + } }; /** @@ -1333,11 +1431,17 @@ * * @param L the Lua state * @param index the index - * @return a boolean + * @return the string or "" */ static std::string get(lua_State *L, int index) { - return lua_tostring(L, index); + size_t length; + const char *str = lua_tolstring(L, index, &length); + + if (!str) + return ""; + + return std::string(str, length); } /** @@ -1345,10 +1449,30 @@ * * @param L the Lua state * @param index the index + * @return the string */ static std::string check(lua_State *L, int index) { - return luaL_checkstring(L, index); + size_t length; + const char *str = luaL_tolstring(L, index, &length); + + return std::string(str, length); + } + + /** + * Get an optional string. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + static std::string optional(lua_State *L, int index, const std::string &def) + { + size_t length; + const char *str = luaL_optlstring(L, index, def.c_str(), &length); + + return std::string(str, length); } }; @@ -1416,6 +1540,23 @@ return get(L, index); } + + /** + * Get an optional std::u32string. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + static std::u32string optional(lua_State *L, int index, const std::u32string &def) + { + if (lua_type(L, index) != LUA_TNUMBER && + lua_type(L, index) != LUA_TTABLE) + return def; + + return get(L, index); + } }; /** @@ -1456,6 +1597,19 @@ { return luaL_checkstring(L, index); } + + /** + * Get an optional C string. + * + * @param L the Lua state + * @param index the index + * @param def the default value + * @return the value or def + */ + static const char *optional(lua_State *L, int index, const char *& def) + { + return luaL_optstring(L, index, def); + } }; /**
--- a/C++/Tests/Luae/TestLuae.cpp Thu May 29 10:58:32 2014 +0200 +++ b/C++/Tests/Luae/TestLuae.cpp Mon Jun 09 13:05:33 2014 +0200 @@ -408,6 +408,80 @@ } } +void TestLuae::optionalbool() +{ + LuaeState L; + Luae::openlibs(L); + + Luae::push(L, nullptr); + CPPUNIT_ASSERT_MESSAGE("false expected", Luae::optional<bool>(L, -1, false) == false); + + Luae::push(L, true); + CPPUNIT_ASSERT_MESSAGE("true expected", Luae::optional<bool>(L, -1, false) == true); +} + +void TestLuae::optionalint() +{ + LuaeState L; + Luae::openlibs(L); + + Luae::push(L, nullptr); + CPPUNIT_ASSERT_MESSAGE("123 expected", Luae::optional<int>(L, -1, 123) == 123); + + Luae::push(L, 456); + CPPUNIT_ASSERT_MESSAGE("456 expected", Luae::optional<int>(L, -1, 999) == 456); +} + +void TestLuae::optionallong() +{ + LuaeState L; + Luae::openlibs(L); + + Luae::push(L, nullptr); + CPPUNIT_ASSERT_MESSAGE("123456789 expected", Luae::optional<long>(L, -1, 123456789) == 123456789); + + Luae::push(L, 789); + CPPUNIT_ASSERT_MESSAGE("789 expected", Luae::optional<long>(L, -1, 888) == 789); +} + +void TestLuae::optionaldouble() +{ + LuaeState L; + Luae::openlibs(L); + + Luae::push(L, nullptr); + CPPUNIT_ASSERT_MESSAGE("123.321 expected", Luae::optional<double>(L, -1, 123.321) == 123.321); + + Luae::push(L, 99.44); + CPPUNIT_ASSERT_MESSAGE("99.44 expected", Luae::optional<double>(L, -1, 321.321) == 99.44); +} + +void TestLuae::optionalstring() +{ + LuaeState L; + Luae::openlibs(L); + + Luae::push(L, nullptr); + CPPUNIT_ASSERT_MESSAGE("abc expected", Luae::optional<std::string>(L, -1, "abc") == std::string("abc")); + + Luae::push(L, "xyz"); + CPPUNIT_ASSERT_MESSAGE("xyz expected", Luae::optional<std::string>(L, -1, "qwerty") == std::string("xyz")); +} + +void TestLuae::optionalustring() +{ + LuaeState L; + Luae::openlibs(L); + + std::u32string expected { 'a', 'b', 'c' }; + Luae::push(L, nullptr); + CPPUNIT_ASSERT_MESSAGE("abc expected", Luae::optional<std::u32string>(L, -1, expected) == expected); + + std::u32string notthatone { 'x', 'y' }; + Luae::push(L, expected); + CPPUNIT_ASSERT_MESSAGE("abc expected", Luae::optional<std::u32string>(L, -1, notthatone) == expected); +} + int main() { CppUnit::TextTestRunner runnerText; @@ -415,4 +489,4 @@ runnerText.addTest(TestLuae::suite()); return runnerText.run("", false) == 1 ? 0 : 1; -} \ No newline at end of file +}
--- a/C++/Tests/Luae/TestLuae.h Thu May 29 10:58:32 2014 +0200 +++ b/C++/Tests/Luae/TestLuae.h Mon Jun 09 13:05:33 2014 +0200 @@ -38,6 +38,12 @@ CPPUNIT_TEST(testdouble); CPPUNIT_TEST(teststring); CPPUNIT_TEST(testustring); + CPPUNIT_TEST(optionalbool); + CPPUNIT_TEST(optionalint); + CPPUNIT_TEST(optionallong); + CPPUNIT_TEST(optionaldouble); + CPPUNIT_TEST(optionalstring); + CPPUNIT_TEST(optionalustring); CPPUNIT_TEST_SUITE_END(); public: @@ -54,6 +60,12 @@ void testdouble(); void teststring(); void testustring(); + void optionalbool(); + void optionalint(); + void optionallong(); + void optionaldouble(); + void optionalstring(); + void optionalustring(); }; -#endif // !_TEST_LUAE_H_ \ No newline at end of file +#endif // !_TEST_LUAE_H_