From ca6165bae527fec84e7d4f2d1dd7e5ae6f7cd03d Mon Sep 17 00:00:00 2001 From: satoren Date: Fri, 14 Apr 2017 23:43:13 +0900 Subject: [PATCH] code format by clang-format --- .clang-format | 4 + include/kaguya/another_binding_api.hpp | 470 ++-- include/kaguya/compatibility.hpp | 227 +- include/kaguya/config.hpp | 55 +- include/kaguya/detail/lua_function_def.hpp | 545 ++-- include/kaguya/detail/lua_ref_impl.hpp | 597 ++-- include/kaguya/detail/lua_table_def.hpp | 967 +++---- include/kaguya/detail/lua_variant_def.hpp | 202 +- include/kaguya/error_handler.hpp | 349 ++- include/kaguya/exception.hpp | 142 +- include/kaguya/function_tuple_def.hpp | 165 +- include/kaguya/kaguya.hpp | 4 - include/kaguya/lua_ref.hpp | 1178 ++++---- include/kaguya/lua_ref_function.hpp | 762 +++-- include/kaguya/lua_ref_table.hpp | 1143 ++++---- include/kaguya/metatable.hpp | 1295 +++++---- include/kaguya/native_function.hpp | 1892 ++++++------- include/kaguya/native_function_cxx03.hpp | 327 +-- include/kaguya/native_function_cxx11.hpp | 395 ++- include/kaguya/object.hpp | 1611 +++++------ include/kaguya/optional.hpp | 461 +-- include/kaguya/preprocess.hpp | 58 +- include/kaguya/preprocess_repeate.hpp | 2783 ++++++++++++------- include/kaguya/push_any.hpp | 145 +- include/kaguya/push_tuple.hpp | 77 +- include/kaguya/ref_tuple.hpp | 61 +- include/kaguya/state.hpp | 1043 ++++--- include/kaguya/traits.hpp | 275 +- include/kaguya/type.hpp | 1931 ++++++------- include/kaguya/utility.hpp | 412 ++- include/kaguya/utility_cxx03.hpp | 282 +- include/kaguya/utility_cxx11.hpp | 211 +- test/test_01_primitive.cpp | 516 ++-- test/test_02_classreg.cpp | 2935 +++++++++----------- test/test_03_function.cpp | 769 +++-- test/test_04_lua_function.cpp | 1001 ++++--- test/test_05_lua_ref.cpp | 1186 ++++---- test/test_06_state.cpp | 951 +++---- test/test_07_vector_map_to_luatable.cpp | 237 +- test/test_08_optional.cpp | 471 ++-- test/test_09_utility.cpp | 390 ++- test/test_10_loadfile.cpp | 57 +- test/test_11_cxx11_feature.cpp | 539 ++-- test/test_12_push_any.cpp | 62 +- test/test_13_another_binding_api.cpp | 71 +- test/test_14_error_message.cpp | 63 +- test/test_20_max_arg_20.cpp | 104 +- test/test_main.cpp | 42 +- test/test_util.hpp | 548 ++-- 49 files changed, 14603 insertions(+), 15408 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..7084b12 --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +--- +BasedOnStyle: LLVM +SortIncludes: false +Standard: Cpp03 \ No newline at end of file diff --git a/include/kaguya/another_binding_api.hpp b/include/kaguya/another_binding_api.hpp index 197bd39..0000aa3 100644 --- a/include/kaguya/another_binding_api.hpp +++ b/include/kaguya/another_binding_api.hpp @@ -6,13 +6,11 @@ #include "kaguya/kaguya.hpp" - /// @addtogroup another_binding_api /// @brief Boost.python like binding API.(experimental) /// this api is not multi-thread-safe. /// @{ - #if defined(KAGUYA_DYNAMIC_LIB) #if defined(_WIN32) || defined(_WIN64) #define KAGUYA_EXPORT extern "C" __declspec(dllexport) @@ -23,247 +21,257 @@ #define KAGUYA_EXPORT #endif -/// @brief start define binding -#define KAGUYA_BINDINGS(MODULE_NAME)\ -void KAGUYA_PP_CAT(kaguya_bind_internal_,MODULE_NAME)();\ -KAGUYA_EXPORT int KAGUYA_PP_CAT(luaopen_, MODULE_NAME)(lua_State* L) { return kaguya::detail::bind_internal(L,&KAGUYA_PP_CAT(kaguya_bind_internal_, MODULE_NAME)); }\ +/// @brief start define binding +#define KAGUYA_BINDINGS(MODULE_NAME) \ + \ +void KAGUYA_PP_CAT(kaguya_bind_internal_, MODULE_NAME)(); \ + \ +KAGUYA_EXPORT int \ + KAGUYA_PP_CAT(luaopen_, MODULE_NAME)(lua_State * L) { \ + return kaguya::detail::bind_internal( \ + L, &KAGUYA_PP_CAT(kaguya_bind_internal_, MODULE_NAME)); \ + } \ + \ void KAGUYA_PP_CAT(kaguya_bind_internal_, MODULE_NAME)() -namespace kaguya -{ - namespace detail - { - struct scope_stack - { - LuaTable current_scope() - { - return !stack.empty() ? stack.back() : LuaTable(); - } - static scope_stack& instance() - { - static scope_stack instance_; - return instance_; - } - void push(const LuaTable& table) - { - stack.push_back(table); - } - void pop() - { - stack.pop_back(); - } - private: - scope_stack() {} - scope_stack(const scope_stack&); - scope_stack& operator=(const scope_stack&); - - std::vector stack; - }; - } - - - /// @ingroup another_binding_api - /// @brief binding scope - struct scope - { - scope(const std::string& name) :pushed_(true) - { - detail::scope_stack& stack = detail::scope_stack::instance(); - LuaTable current = stack.current_scope(); - if (!current[name]) - { - current[name] = NewTable(); - } - scope_table_ = current[name]; - stack.push(scope_table_); - } - scope(const LuaTable& t) :pushed_(true) - { - scope_table_ = t; - detail::scope_stack::instance().push(scope_table_); - } - scope():pushed_(false) - { - detail::scope_stack& stack = detail::scope_stack::instance(); - scope_table_ = stack.current_scope(); - } - - TableKeyReferenceProxy attr(const std::string& name) { - return scope_table_.operator[](name); - } - LuaTable table() { - return scope_table_; - } - - ~scope() - { - if (pushed_) - { - detail::scope_stack::instance().pop(); - } - } - - private: - LuaTable scope_table_; - bool pushed_; - }; - - - namespace detail - { - inline int bind_internal(lua_State* L, void(*bindfn)()) { - int count = lua_gettop(L); - kaguya::State state(L); - LuaTable l = state.newTable(); - l.push(); - scope scope(l); - bindfn(); - return lua_gettop(L) - count; - } - } - - /// @ingroup another_binding_api - /// @brief define class binding - template - struct class_ : private UserdataMetatable - { - class_(const std::string& name) :name_(name) { - } - ~class_() { - LuaTable scope = detail::scope_stack::instance().current_scope(); - if (scope) - { - scope[name_].setClass(*this); - } - } - -#if KAGUYA_USE_CPP11 - template - class_& constructor() { this->template setConstructors(); return *this; } +namespace kaguya { +namespace detail { +struct scope_stack { + LuaTable current_scope() { + return !stack.empty() ? stack.back() : LuaTable(); + } + static scope_stack &instance() { + static scope_stack instance_; + return instance_; + } + void push(const LuaTable &table) { stack.push_back(table); } + void pop() { stack.pop_back(); } + +private: + scope_stack() {} + scope_stack(const scope_stack &); + scope_stack &operator=(const scope_stack &); + + std::vector stack; +}; +} - template - class_& constructors() { this->template setConstructors(); return *this; } -#else - class_& constructor() { this->template setConstructors(); return *this; } +/// @ingroup another_binding_api +/// @brief binding scope +struct scope { + scope(const std::string &name) : pushed_(true) { + detail::scope_stack &stack = detail::scope_stack::instance(); + LuaTable current = stack.current_scope(); + if (!current[name]) { + current[name] = NewTable(); + } + scope_table_ = current[name]; + stack.push(scope_table_); + } + scope(const LuaTable &t) : pushed_(true) { + scope_table_ = t; + detail::scope_stack::instance().push(scope_table_); + } + scope() : pushed_(false) { + detail::scope_stack &stack = detail::scope_stack::instance(); + scope_table_ = stack.current_scope(); + } + + TableKeyReferenceProxy attr(const std::string &name) { + return scope_table_.operator[](name); + } + LuaTable table() { return scope_table_; } + + ~scope() { + if (pushed_) { + detail::scope_stack::instance().pop(); + } + } + +private: + LuaTable scope_table_; + bool pushed_; +}; + +namespace detail { +inline int bind_internal(lua_State *L, void (*bindfn)()) { + int count = lua_gettop(L); + kaguya::State state(L); + LuaTable l = state.newTable(); + l.push(); + scope scope(l); + bindfn(); + return lua_gettop(L) - count; +} +} -#define KAGUYA_ADD_CON_FN_DEF(N) \ - template\ - class_& constructor() { this->template setConstructors(); return *this; } +/// @ingroup another_binding_api +/// @brief define class binding +template +struct class_ : private UserdataMetatable { + class_(const std::string &name) : name_(name) {} + ~class_() { + LuaTable scope = detail::scope_stack::instance().current_scope(); + if (scope) { + scope[name_].setClass(*this); + } + } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_ADD_CON_FN_DEF) +#if KAGUYA_USE_CPP11 + template class_ &constructor() { + this->template setConstructors(); + return *this; + } + + template class_ &constructors() { + this->template setConstructors(); + return *this; + } +#else + class_ &constructor() { + this->template setConstructors(); + return *this; + } + +#define KAGUYA_ADD_CON_FN_DEF(N) \ + template class_ &constructor() { \ + this->template setConstructors(); \ + return *this; \ + } + + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_ADD_CON_FN_DEF) #undef KAGUYA_ADD_CON_FN_DEF - class_& constructors() { this->template setConstructors(); return *this; } + class_ &constructors() { + this->template setConstructors(); + return *this; + } -#define KAGUYA_ADD_CONS_FN_DEF(N) \ - template\ - class_& constructors() { this->template setConstructors(); return *this; } +#define KAGUYA_ADD_CONS_FN_DEF(N) \ + template class_ &constructors() { \ + this->template setConstructors(); \ + return *this; \ + } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_ADD_CONS_FN_DEF) + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_ADD_CONS_FN_DEF) #undef KAGUYA_ADD_CONS_FN_DEF #endif - /// @ingroup another_binding_api - /// @brief function binding - template - class_& function(const char* name, F f) { this-> addFunction(name, f); return *this; } - - template - class_& function(const char* name, FunctionInvokerType f) { this-> addStaticField(name, f); return *this; } - - /// @ingroup another_binding_api - /// @brief property binding - template - class_& property(const char* name, F f) { this->addProperty(name, f); return *this; } - - /// @ingroup another_binding_api - /// @brief property binding with getter and sette function - template - class_& property(const char* name, Getter getter, Setter setter) { this->addProperty(name, getter, setter); return *this; } - - /// @brief class function binding - template - class_& class_function(const char* name, F f) { this->addStaticFunction(name, f); return *this; } - - template - class_& class_function(const char* name, FunctionInvokerType f) { this-> addStaticField(name, f); return *this; } - - - /// @ingroup another_binding_api - /// @brief function binding - template - class_& def(const char* name, F f) { this->addFunction(name, f); return *this; } - - /// @ingroup another_binding_api - /// @brief property binding with getter and sette function - template - class_& add_property(const char* name, Getter getter, Setter setter) { property(name, getter, setter); return *this; } - - /// @ingroup another_binding_api - /// @brief property binding - template - class_& add_property(const char* name, F f) { property(name, f); return *this; } - - - /// @ingroup another_binding_api - /// @brief static property binding - template - class_& add_static_property(const char* name, Data data) { this->addStaticField(name, data); return *this; } - - private: - std::string name_; - }; - - - template - struct enum_ - { - enum_(const std::string& name) :enum_scope_table_(scope(name).table()) { - } - enum_& value(const char* name, EnumType data) { - enum_scope_table_[name] = data; - return *this; - } - private: - LuaTable enum_scope_table_; - }; - - /// @ingroup another_binding_api - /// @brief function binding - template - void function(const char* name, F f) { - LuaTable scope = detail::scope_stack::instance().current_scope(); - if (scope) - { - scope[name] = kaguya::function(f); - } - } - template - void function(const char* name, FunctionInvokerType f) { - LuaTable scope = detail::scope_stack::instance().current_scope(); - if (scope) - { - scope[name] = f; - } - } - - /// @ingroup another_binding_api - /// @brief function binding - template - void def(const char* name, F f) { kaguya::function(name, f); } - - /// @ingroup another_binding_api - /// @brief function binding - template - void constant(const char* name, T v) - { - LuaTable scope = detail::scope_stack::instance().current_scope(); - if (scope) - { - scope[name] = v; - } - } + /// @ingroup another_binding_api + /// @brief function binding + template class_ &function(const char *name, F f) { + this->addFunction(name, f); + return *this; + } + + template + class_ &function(const char *name, FunctionInvokerType f) { + this->addStaticField(name, f); + return *this; + } + + /// @ingroup another_binding_api + /// @brief property binding + template class_ &property(const char *name, F f) { + this->addProperty(name, f); + return *this; + } + + /// @ingroup another_binding_api + /// @brief property binding with getter and sette function + template + class_ &property(const char *name, Getter getter, Setter setter) { + this->addProperty(name, getter, setter); + return *this; + } + + /// @brief class function binding + template class_ &class_function(const char *name, F f) { + this->addStaticFunction(name, f); + return *this; + } + + template + class_ &class_function(const char *name, FunctionInvokerType f) { + this->addStaticField(name, f); + return *this; + } + + /// @ingroup another_binding_api + /// @brief function binding + template class_ &def(const char *name, F f) { + this->addFunction(name, f); + return *this; + } + + /// @ingroup another_binding_api + /// @brief property binding with getter and sette function + template + class_ &add_property(const char *name, Getter getter, Setter setter) { + property(name, getter, setter); + return *this; + } + + /// @ingroup another_binding_api + /// @brief property binding + template class_ &add_property(const char *name, F f) { + property(name, f); + return *this; + } + + /// @ingroup another_binding_api + /// @brief static property binding + template + class_ &add_static_property(const char *name, Data data) { + this->addStaticField(name, data); + return *this; + } + +private: + std::string name_; +}; + +template struct enum_ { + enum_(const std::string &name) : enum_scope_table_(scope(name).table()) {} + enum_ &value(const char *name, EnumType data) { + enum_scope_table_[name] = data; + return *this; + } + +private: + LuaTable enum_scope_table_; +}; + +/// @ingroup another_binding_api +/// @brief function binding +template void function(const char *name, F f) { + LuaTable scope = detail::scope_stack::instance().current_scope(); + if (scope) { + scope[name] = kaguya::function(f); + } +} +template +void function(const char *name, FunctionInvokerType f) { + LuaTable scope = detail::scope_stack::instance().current_scope(); + if (scope) { + scope[name] = f; + } +} + +/// @ingroup another_binding_api +/// @brief function binding +template void def(const char *name, F f) { + kaguya::function(name, f); +} +/// @ingroup another_binding_api +/// @brief function binding +template void constant(const char *name, T v) { + LuaTable scope = detail::scope_stack::instance().current_scope(); + if (scope) { + scope[name] = v; + } +} } /// @} - diff --git a/include/kaguya/compatibility.hpp b/include/kaguya/compatibility.hpp index 3423d95..2a29e25 100644 --- a/include/kaguya/compatibility.hpp +++ b/include/kaguya/compatibility.hpp @@ -6,143 +6,118 @@ #include "kaguya/config.hpp" -namespace kaguya -{ - //for lua version compatibility - namespace compat - { +namespace kaguya { +// for lua version compatibility +namespace compat { #if LUA_VERSION_NUM >= 503 - inline int lua_rawgetp_rtype(lua_State *L, int idx, const void* ptr) - { - return lua_rawgetp(L, idx, ptr); - } - inline int lua_getfield_rtype(lua_State *L, int idx, const char* k) - { - return lua_getfield(L, idx, k); - } - inline int lua_gettable_rtype(lua_State *L, int idx) - { - return lua_gettable(L, idx); - } +inline int lua_rawgetp_rtype(lua_State *L, int idx, const void *ptr) { + return lua_rawgetp(L, idx, ptr); +} +inline int lua_getfield_rtype(lua_State *L, int idx, const char *k) { + return lua_getfield(L, idx, k); +} +inline int lua_gettable_rtype(lua_State *L, int idx) { + return lua_gettable(L, idx); +} #elif LUA_VERSION_NUM == 502 - inline int lua_rawgetp_rtype(lua_State *L, int idx, const void* ptr) - { - lua_rawgetp(L, idx, ptr); - return lua_type(L, -1); - } +inline int lua_rawgetp_rtype(lua_State *L, int idx, const void *ptr) { + lua_rawgetp(L, idx, ptr); + return lua_type(L, -1); +} #elif LUA_VERSION_NUM < 502 - enum LUA_OPEQ - { - LUA_OPEQ, - LUA_OPLT, - LUA_OPLE - }; - inline int lua_compare(lua_State *L, int index1, int index2, int op) - { - switch (op) - { - case LUA_OPEQ: - return lua_equal(L, index1, index2); - case LUA_OPLT: - return lua_lessthan(L, index1, index2); - case LUA_OPLE: - return lua_equal(L, index1, index2) || lua_lessthan(L, index1, index2); - default: - return 0; - } - } +enum LUA_OPEQ { LUA_OPEQ, LUA_OPLT, LUA_OPLE }; +inline int lua_compare(lua_State *L, int index1, int index2, int op) { + switch (op) { + case LUA_OPEQ: + return lua_equal(L, index1, index2); + case LUA_OPLT: + return lua_lessthan(L, index1, index2); + case LUA_OPLE: + return lua_equal(L, index1, index2) || lua_lessthan(L, index1, index2); + default: + return 0; + } +} - inline void lua_pushglobaltable(lua_State *L) - { - lua_pushvalue(L, LUA_GLOBALSINDEX); - } - inline size_t lua_rawlen(lua_State *L, int index) - { - int type = lua_type(L, index); - if (type != LUA_TSTRING && type != LUA_TTABLE && type != LUA_TUSERDATA && type != LUA_TLIGHTUSERDATA) - { - return 0; - } - return lua_objlen(L, index); - } +inline void lua_pushglobaltable(lua_State *L) { + lua_pushvalue(L, LUA_GLOBALSINDEX); +} +inline size_t lua_rawlen(lua_State *L, int index) { + int type = lua_type(L, index); + if (type != LUA_TSTRING && type != LUA_TTABLE && type != LUA_TUSERDATA && + type != LUA_TLIGHTUSERDATA) { + return 0; + } + return lua_objlen(L, index); +} - inline int lua_resume(lua_State *L, lua_State* from, int nargs) - { - KAGUYA_UNUSED(from); - return ::lua_resume(L, nargs); - } - inline int lua_absindex(lua_State *L, int idx) - { - return (idx > 0 || (idx <= LUA_REGISTRYINDEX)) ? idx : lua_gettop(L) + 1 + idx; - } - inline int lua_rawgetp_rtype(lua_State *L, int idx, const void* ptr) - { - int absidx = lua_absindex(L, idx); - lua_pushlightuserdata(L, (void*)ptr); - lua_rawget(L, absidx); - return lua_type(L, -1); - } - inline void lua_rawsetp(lua_State *L, int idx, const void* ptr) - { - int absidx = lua_absindex(L, idx); - lua_pushvalue(L, -1); - lua_pushlightuserdata(L, (void*)ptr); - lua_replace(L, -3); - lua_rawset(L, absidx); - } - inline void luaL_requiref(lua_State *L, const char *modname, - lua_CFunction openf, int glb) { +inline int lua_resume(lua_State *L, lua_State *from, int nargs) { + KAGUYA_UNUSED(from); + return ::lua_resume(L, nargs); +} +inline int lua_absindex(lua_State *L, int idx) { + return (idx > 0 || (idx <= LUA_REGISTRYINDEX)) ? idx + : lua_gettop(L) + 1 + idx; +} +inline int lua_rawgetp_rtype(lua_State *L, int idx, const void *ptr) { + int absidx = lua_absindex(L, idx); + lua_pushlightuserdata(L, (void *)ptr); + lua_rawget(L, absidx); + return lua_type(L, -1); +} +inline void lua_rawsetp(lua_State *L, int idx, const void *ptr) { + int absidx = lua_absindex(L, idx); + lua_pushvalue(L, -1); + lua_pushlightuserdata(L, (void *)ptr); + lua_replace(L, -3); + lua_rawset(L, absidx); +} +inline void luaL_requiref(lua_State *L, const char *modname, + lua_CFunction openf, int glb) { - lua_pushcfunction(L, openf); - lua_pushstring(L, modname); - lua_call(L, 1, 1); + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); + lua_call(L, 1, 1); - if (glb) { - lua_pushvalue(L, -1); - lua_setglobal(L, modname); - } - } - inline lua_Number lua_tonumberx(lua_State *L, int index, int *isnum) - { - if (isnum) { *isnum = lua_isnumber(L, index); } - return lua_tonumber(L, index); - } + if (glb) { + lua_pushvalue(L, -1); + lua_setglobal(L, modname); + } +} +inline lua_Number lua_tonumberx(lua_State *L, int index, int *isnum) { + if (isnum) { + *isnum = lua_isnumber(L, index); + } + return lua_tonumber(L, index); +} #endif #if LUA_VERSION_NUM < 503 - inline void lua_seti(lua_State *L, int index, lua_Integer n) - { - int absidx = lua_absindex(L, index); - lua_pushvalue(L, -1); - lua_pushinteger(L, n); - lua_replace(L, -3); - lua_rawset(L, absidx); - } - inline int lua_geti(lua_State *L, int index, lua_Integer i) - { - int absidx = lua_absindex(L, index); - lua_pushinteger(L, i); - lua_rawget(L, absidx); - return lua_type(L, -1); - } - inline int lua_getfield_rtype(lua_State *L, int idx, const char* k) - { - lua_getfield(L, idx, k); - return lua_type(L, -1); - } - inline int lua_gettable_rtype(lua_State *L, int idx) - { - lua_gettable(L, idx); - return lua_type(L, -1); - } +inline void lua_seti(lua_State *L, int index, lua_Integer n) { + int absidx = lua_absindex(L, index); + lua_pushvalue(L, -1); + lua_pushinteger(L, n); + lua_replace(L, -3); + lua_rawset(L, absidx); +} +inline int lua_geti(lua_State *L, int index, lua_Integer i) { + int absidx = lua_absindex(L, index); + lua_pushinteger(L, i); + lua_rawget(L, absidx); + return lua_type(L, -1); +} +inline int lua_getfield_rtype(lua_State *L, int idx, const char *k) { + lua_getfield(L, idx, k); + return lua_type(L, -1); +} +inline int lua_gettable_rtype(lua_State *L, int idx) { + lua_gettable(L, idx); + return lua_type(L, -1); +} #endif #if LUA_VERSION_NUM < 501 - void lua_createtable(lua_State *L, int narr, int nrec) - { - lua_newtable(L); - } +void lua_createtable(lua_State *L, int narr, int nrec) { lua_newtable(L); } #endif - } - - using namespace compat; } +using namespace compat; +} diff --git a/include/kaguya/config.hpp b/include/kaguya/config.hpp index 7b36b7d..fafcd02 100644 --- a/include/kaguya/config.hpp +++ b/include/kaguya/config.hpp @@ -4,7 +4,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #pragma once -#include +#include extern "C" { #include #include @@ -12,14 +12,14 @@ extern "C" { } #ifndef KAGUYA_USE_CPP11 -#if defined(__cpp_decltype) || __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) +#if defined(__cpp_decltype) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1800) #define KAGUYA_USE_CPP11 1 #else #define KAGUYA_USE_CPP11 0 #endif #endif - #if KAGUYA_USE_CPP11 #include #include @@ -38,8 +38,6 @@ extern "C" { #include #endif - - #ifndef KAGUYA_NO_USERDATA_TYPE_CHECK #define KAGUYA_NO_USERDATA_TYPE_CHECK 0 #endif @@ -52,13 +50,11 @@ extern "C" { #endif #endif - #ifdef KAGUYA_NO_VECTOR_AND_MAP_TO_TABLE #define KAGUYA_NO_STD_VECTOR_TO_TABLE #define KAGUYA_NO_STD_MAP_TO_TABLE #endif - #if !KAGUYA_USE_CPP11 #ifndef KAGUYA_FUNCTION_MAX_ARGS ///! max argumeent number for binding function. this define used C++03 only. @@ -80,7 +76,6 @@ extern "C" { #define KAGUYA_CLASS_MAX_BASE_CLASSES 9 #endif - #ifndef KAGUYA_USE_CXX_ABI_DEMANGLE #if defined(__GNUC__) || defined(__clang__) #define KAGUYA_USE_CXX_ABI_DEMANGLE 1 @@ -89,33 +84,30 @@ extern "C" { #endif #endif - #ifndef KAGUYA_USE_SHARED_LUAREF #define KAGUYA_USE_SHARED_LUAREF 0 #endif - - #ifndef KAGUYA_NOEXCEPT -# if KAGUYA_USE_CPP11 && (!defined(_MSC_VER) || _MSC_VER >= 1900) -# define KAGUYA_NOEXCEPT noexcept -# else -# define KAGUYA_NOEXCEPT throw() -# endif +#if KAGUYA_USE_CPP11 && (!defined(_MSC_VER) || _MSC_VER >= 1900) +#define KAGUYA_NOEXCEPT noexcept +#else +#define KAGUYA_NOEXCEPT throw() +#endif #endif #ifndef KAGUYA_DEPRECATED_FEATURE #if __cplusplus >= 201402L && defined(__has_cpp_attribute) -#if __has_cpp_attribute(deprecated) -//C++ standard depecated +#if __has_cpp_attribute(deprecated) +// C++ standard depecated #define KAGUYA_DEPRECATED_FEATURE(MSG) [[deprecated(MSG)]] #endif #endif #endif #ifndef KAGUYA_DEPRECATED_FEATURE #if defined(_MSC_VER) -//MSVC depecated -#define KAGUYA_DEPRECATED_FEATURE(MSG) __declspec(deprecated(MSG)) +// MSVC depecated +#define KAGUYA_DEPRECATED_FEATURE(MSG) __declspec(deprecated(MSG)) #elif defined(__GNUC__) || defined(__clang__) #define KAGUYA_DEPRECATED_FEATURE(MSG) __attribute__((deprecated)) #else @@ -126,30 +118,27 @@ extern "C" { #define KAGUYA_UNUSED(V) (void)(V) -namespace kaguya -{ +namespace kaguya { #if defined(_MSC_VER) && _MSC_VER <= 1500 - typedef unsigned char uint8_t; - typedef int int32_t; - typedef long long int64_t; +typedef unsigned char uint8_t; +typedef int int32_t; +typedef long long int64_t; #endif - namespace standard - { +namespace standard { #if KAGUYA_USE_CPP11 - using namespace std; +using namespace std; #define KAGUYA_STATIC_ASSERT static_assert #else - using namespace boost; +using namespace boost; #define KAGUYA_STATIC_ASSERT BOOST_STATIC_ASSERT_MSG #endif - } +} #if LUA_VERSION_NUM > 502 - typedef lua_Integer luaInt; +typedef lua_Integer luaInt; #else - typedef int32_t luaInt; +typedef int32_t luaInt; #endif } - diff --git a/include/kaguya/detail/lua_function_def.hpp b/include/kaguya/detail/lua_function_def.hpp index bdb55fe..80e606f 100644 --- a/include/kaguya/detail/lua_function_def.hpp +++ b/include/kaguya/detail/lua_function_def.hpp @@ -15,328 +15,281 @@ #include "kaguya/type.hpp" #include "kaguya/utility.hpp" - -namespace kaguya -{ - class LuaTable; - class LuaFunction; - - class FunctionResults; - - /** - * status of coroutine - */ - enum coroutine_status - { - COSTAT_RUNNING,//!< coroutine is running - COSTAT_SUSPENDED,//!< coroutine is suspended - COSTAT_NORMAL,//!< - COSTAT_DEAD//!< coroutine is dead - }; - - namespace detail - { - class FunctionResultProxy - { - public: - template - static RetType ReturnValue(lua_State* state, int restatus, int retindex, types::typetag tag); - static FunctionResults ReturnValue(lua_State* state, int restatus, int retindex, types::typetag tag); - static void ReturnValue(lua_State* state, int restatus, int retindex, types::typetag tag); - }; - - template - class LuaFunctionImpl - { - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - int push_(lua_State* state)const - { - return static_cast(this)->push(state); - } - - public: - /** - * set function environment table - */ - bool setFunctionEnv(const LuaTable& env); - /** - * set function environment to new table - */ - bool setFunctionEnv(NewTable env); - /** - * get function environment table - */ - LuaTable getFunctionEnv()const; +namespace kaguya { +class LuaTable; +class LuaFunction; + +class FunctionResults; + +/** +* status of coroutine +*/ +enum coroutine_status { + COSTAT_RUNNING, //!< coroutine is running + COSTAT_SUSPENDED, //!< coroutine is suspended + COSTAT_NORMAL, //!< + COSTAT_DEAD //!< coroutine is dead +}; + +namespace detail { +class FunctionResultProxy { +public: + template + static RetType ReturnValue(lua_State *state, int restatus, int retindex, + types::typetag tag); + static FunctionResults ReturnValue(lua_State *state, int restatus, + int retindex, + types::typetag tag); + static void ReturnValue(lua_State *state, int restatus, int retindex, + types::typetag tag); +}; + +template class LuaFunctionImpl { +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + int push_(lua_State *state) const { + return static_cast(this)->push(state); + } + +public: + /** + * set function environment table + */ + bool setFunctionEnv(const LuaTable &env); + /** + * set function environment to new table + */ + bool setFunctionEnv(NewTable env); + /** + * get function environment table + */ + LuaTable getFunctionEnv() const; #if KAGUYA_USE_CPP11 - template Result call(Args&&... args) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "nil"); - return Result(); - } - int argstart = lua_gettop(state) + 1; - push_(state); - int argnum = util::push_args(state, std::forward(args)...); - int result = lua_pcall_wrap(state, argnum, LUA_MULTRET); - except::checkErrorAndThrow(result, state); - return detail::FunctionResultProxy::ReturnValue(state, result, argstart, types::typetag()); - } - - template FunctionResults operator()(Args&&... args); + template Result call(Args &&... args) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "nil"); + return Result(); + } + int argstart = lua_gettop(state) + 1; + push_(state); + int argnum = util::push_args(state, std::forward(args)...); + int result = lua_pcall_wrap(state, argnum, LUA_MULTRET); + except::checkErrorAndThrow(result, state); + return detail::FunctionResultProxy::ReturnValue(state, result, argstart, + types::typetag()); + } + + template FunctionResults operator()(Args &&... args); #else -#define KAGUYA_CALL_DEF(N) \ - template\ - Result call(KAGUYA_PP_ARG_CR_DEF_REPEAT(N))\ - {\ - lua_State* state = state_();\ - if (!state)\ - {\ - except::typeMismatchError(state, "attempt to call nil value");\ - return Result();\ - }\ - int argstart = lua_gettop(state) + 1;\ - push_(state);\ - int argnum = util::push_args(state KAGUYA_PP_ARG_REPEAT_CONCAT(N));\ - int result = lua_pcall_wrap(state, argnum, LUA_MULTRET);\ - except::checkErrorAndThrow(result, state);\ - return detail::FunctionResultProxy::ReturnValue(state,result, argstart, types::typetag());\ - } - - - KAGUYA_CALL_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CALL_DEF) - +#define KAGUYA_CALL_DEF(N) \ + template \ + Result call(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)) { \ + lua_State *state = state_(); \ + if (!state) { \ + except::typeMismatchError(state, "attempt to call nil value"); \ + return Result(); \ + } \ + int argstart = lua_gettop(state) + 1; \ + push_(state); \ + int argnum = util::push_args(state KAGUYA_PP_ARG_REPEAT_CONCAT(N)); \ + int result = lua_pcall_wrap(state, argnum, LUA_MULTRET); \ + except::checkErrorAndThrow(result, state); \ + return detail::FunctionResultProxy::ReturnValue(state, result, argstart, \ + types::typetag()); \ + } + + KAGUYA_CALL_DEF(0) + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CALL_DEF) #undef KAGUYA_RESUME_DEF + inline FunctionResults operator()(); - inline FunctionResults operator()(); - - -#define KAGUYA_OP_FN_DEF(N) \ - template\ - inline FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)); +#define KAGUYA_OP_FN_DEF(N) \ + template \ + inline FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)); - -#define KAGUYA_FUNCTION_ARGS_DEF(N) +#define KAGUYA_FUNCTION_ARGS_DEF(N) #define KAGUYA_CALL_ARGS(N) KAGUYA_PP_ARG_REPEAT(N) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) #undef KAGUYA_OP_FN_DEF #undef KAGUYA_CALL_ARGS #undef KAGUYA_FUNCTION_ARGS_DEF #undef KAGUYA_CALL_DEF #endif - - - }; - - - template - class LuaThreadImpl - { - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - - public: +}; + +template class LuaThreadImpl { +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + +public: #if KAGUYA_USE_CPP11 - template Result resume(Args&&... args) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "attempt to call nil value"); - return Result(); - } - util::ScopedSavedStack save(state); - int corStackIndex = pushStackIndex_(state); - lua_State* thread = lua_tothread(state, corStackIndex); - if (!thread) - { - except::typeMismatchError(state, "not thread"); - return Result(); - } - int argstart = 1;//exist function in stack at first resume. - if (lua_status(thread) == LUA_YIELD) - { - argstart = 0; - } - util::push_args(thread, std::forward(args)...); - int argnum = lua_gettop(thread) - argstart; - if (argnum < 0) { argnum = 0; } - int result = lua_resume(thread, state, argnum); - except::checkErrorAndThrow(result, thread); - return detail::FunctionResultProxy::ReturnValue(thread, result, 1, types::typetag()); - } - template FunctionResults operator()(Args&&... args); + template Result resume(Args &&... args) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "attempt to call nil value"); + return Result(); + } + util::ScopedSavedStack save(state); + int corStackIndex = pushStackIndex_(state); + lua_State *thread = lua_tothread(state, corStackIndex); + if (!thread) { + except::typeMismatchError(state, "not thread"); + return Result(); + } + int argstart = 1; // exist function in stack at first resume. + if (lua_status(thread) == LUA_YIELD) { + argstart = 0; + } + util::push_args(thread, std::forward(args)...); + int argnum = lua_gettop(thread) - argstart; + if (argnum < 0) { + argnum = 0; + } + int result = lua_resume(thread, state, argnum); + except::checkErrorAndThrow(result, thread); + return detail::FunctionResultProxy::ReturnValue(thread, result, 1, + types::typetag()); + } + template FunctionResults operator()(Args &&... args); #else -#define KAGUYA_RESUME_DEF(N) \ - template\ - Result resume(KAGUYA_PP_ARG_CR_DEF_REPEAT(N))\ - {\ - lua_State* state = state_();\ - if (!state)\ - {\ - except::typeMismatchError(state, "attempt to call nil value");\ - return Result();\ - }\ - util::ScopedSavedStack save(state);\ - int corStackIndex = pushStackIndex_(state);\ - lua_State* thread = lua_tothread(state, corStackIndex);\ - if (!thread)\ - {\ - except::typeMismatchError(state, "not thread");\ - return Result();\ - }\ - int argstart = 1;\ - if (lua_status(thread) == LUA_YIELD)\ - {\ - argstart = 0;\ - }\ - util::push_args(thread KAGUYA_PP_ARG_REPEAT_CONCAT(N));\ - int argnum = lua_gettop(thread) - argstart;\ - if (argnum < 0) { argnum = 0; }\ - int result = lua_resume(thread, state, argnum);\ - except::checkErrorAndThrow(result, thread);\ - return detail::FunctionResultProxy::ReturnValue(thread,result, 1, types::typetag());\ - } - - KAGUYA_RESUME_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_RESUME_DEF) +#define KAGUYA_RESUME_DEF(N) \ + template \ + Result resume(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)) { \ + lua_State *state = state_(); \ + if (!state) { \ + except::typeMismatchError(state, "attempt to call nil value"); \ + return Result(); \ + } \ + util::ScopedSavedStack save(state); \ + int corStackIndex = pushStackIndex_(state); \ + lua_State *thread = lua_tothread(state, corStackIndex); \ + if (!thread) { \ + except::typeMismatchError(state, "not thread"); \ + return Result(); \ + } \ + int argstart = 1; \ + if (lua_status(thread) == LUA_YIELD) { \ + argstart = 0; \ + } \ + util::push_args(thread KAGUYA_PP_ARG_REPEAT_CONCAT(N)); \ + int argnum = lua_gettop(thread) - argstart; \ + if (argnum < 0) { \ + argnum = 0; \ + } \ + int result = lua_resume(thread, state, argnum); \ + except::checkErrorAndThrow(result, thread); \ + return detail::FunctionResultProxy::ReturnValue(thread, result, 1, \ + types::typetag()); \ + } + + KAGUYA_RESUME_DEF(0) + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_RESUME_DEF) #undef KAGUYA_RESUME_DEF - inline FunctionResults operator()(); + inline FunctionResults operator()(); -#define KAGUYA_OP_FN_DEF(N) \ - template\ - inline FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)); - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) +#define KAGUYA_OP_FN_DEF(N) \ + template \ + inline FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)); + + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) #undef KAGUYA_OP_FN_DEF #endif - - //! - //! @return state status - //! - int threadStatus()const - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "attempt to call nil value"); - return LUA_ERRRUN; - } - util::ScopedSavedStack save(state); - int corStackIndex = pushStackIndex_(state); - lua_State* thread = lua_tothread(state, corStackIndex); - - if (!thread) - { - except::typeMismatchError(state, "not thread"); - return LUA_ERRRUN; - } - return lua_status(thread); - } - - //! deprecate - int thread_status()const - { - return threadStatus(); - } - - - //! - //! @return coroutine status - //! - coroutine_status costatus(lua_State *l = 0)const - { - lua_State* state = state_(); - if (!state) - { - return COSTAT_DEAD; - } - util::ScopedSavedStack save(state); - int corStackIndex = pushStackIndex_(state); - lua_State* thread = lua_tothread(state, corStackIndex); - - if (!thread) - { - except::typeMismatchError(state, "not thread"); - return COSTAT_DEAD; - } - else if (thread == l) - { - return COSTAT_RUNNING; - } - else - { - switch (lua_status(thread)) - { - case LUA_YIELD: - return COSTAT_SUSPENDED; - case 0://LUA_OK - { - if (lua_gettop(thread) == 0) - { - return COSTAT_DEAD; - } - else - { - return COSTAT_SUSPENDED; - } - } - default: - break; - } - } - return COSTAT_DEAD; - - } - - //! - //! @return if coroutine status is dead, return true. Otherwise return false - //! - bool isThreadDead()const - { - return costatus() == COSTAT_DEAD; - } - - - /// @brief set function for thread running. - void setFunction(const LuaFunction& f); - - /// @brief get lua thread - lua_State* getthread() - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int corStackIndex = pushStackIndex_(state); - return lua_tothread(state, corStackIndex); - } - }; - } + //! + //! @return state status + //! + int threadStatus() const { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "attempt to call nil value"); + return LUA_ERRRUN; + } + util::ScopedSavedStack save(state); + int corStackIndex = pushStackIndex_(state); + lua_State *thread = lua_tothread(state, corStackIndex); + + if (!thread) { + except::typeMismatchError(state, "not thread"); + return LUA_ERRRUN; + } + return lua_status(thread); + } + + //! deprecate + int thread_status() const { return threadStatus(); } + + //! + //! @return coroutine status + //! + coroutine_status costatus(lua_State *l = 0) const { + lua_State *state = state_(); + if (!state) { + return COSTAT_DEAD; + } + util::ScopedSavedStack save(state); + int corStackIndex = pushStackIndex_(state); + lua_State *thread = lua_tothread(state, corStackIndex); + + if (!thread) { + except::typeMismatchError(state, "not thread"); + return COSTAT_DEAD; + } else if (thread == l) { + return COSTAT_RUNNING; + } else { + switch (lua_status(thread)) { + case LUA_YIELD: + return COSTAT_SUSPENDED; + case 0: // LUA_OK + { + if (lua_gettop(thread) == 0) { + return COSTAT_DEAD; + } else { + return COSTAT_SUSPENDED; + } + } + default: + break; + } + } + return COSTAT_DEAD; + } + + //! + //! @return if coroutine status is dead, return true. Otherwise return false + //! + bool isThreadDead() const { return costatus() == COSTAT_DEAD; } + + /// @brief set function for thread running. + void setFunction(const LuaFunction &f); + + /// @brief get lua thread + lua_State *getthread() { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int corStackIndex = pushStackIndex_(state); + return lua_tothread(state, corStackIndex); + } +}; +} } diff --git a/include/kaguya/detail/lua_ref_impl.hpp b/include/kaguya/detail/lua_ref_impl.hpp index 3ba2812..1123e8d 100644 --- a/include/kaguya/detail/lua_ref_impl.hpp +++ b/include/kaguya/detail/lua_ref_impl.hpp @@ -15,377 +15,304 @@ #include "kaguya/type.hpp" #include "kaguya/utility.hpp" +namespace kaguya { +/// @brief StackTop tag type +struct StackTop {}; -namespace kaguya -{ - /// @brief StackTop tag type - struct StackTop {}; +namespace Ref { +/// @brief NoMainCheck tag type +struct NoMainCheck {}; - namespace Ref - { - /// @brief NoMainCheck tag type - struct NoMainCheck {}; - - /// @brief reference to Lua stack value - class StackRef - { - protected: - lua_State *state_; - int stack_index_; - mutable bool pop_; +/// @brief reference to Lua stack value +class StackRef { +protected: + lua_State *state_; + int stack_index_; + mutable bool pop_; #if KAGUYA_USE_CPP11 - StackRef(StackRef&& src) :state_(src.state_), stack_index_(src.stack_index_), pop_(src.pop_) - { - src.pop_ = false; - } - StackRef& operator=(StackRef&& src) - { - state_ = src.state_; - stack_index_ = src.stack_index_; - pop_ = src.pop_; + StackRef(StackRef &&src) + : state_(src.state_), stack_index_(src.stack_index_), pop_(src.pop_) { + src.pop_ = false; + } + StackRef &operator=(StackRef &&src) { + state_ = src.state_; + stack_index_ = src.stack_index_; + pop_ = src.pop_; - src.pop_ = false; - return *this; - } + src.pop_ = false; + return *this; + } - StackRef(const StackRef&src) = delete; - StackRef& operator=(const StackRef&src) = delete; + StackRef(const StackRef &src) = delete; + StackRef &operator=(const StackRef &src) = delete; #else - StackRef(const StackRef&src) : state_(src.state_), stack_index_(src.stack_index_), pop_(src.pop_) - { - src.pop_ = false; - } - StackRef& operator=(const StackRef& src) - { - if (this != &src) - { - state_ = src.state_; - stack_index_ = src.stack_index_; - pop_ = src.pop_; + StackRef(const StackRef &src) + : state_(src.state_), stack_index_(src.stack_index_), pop_(src.pop_) { + src.pop_ = false; + } + StackRef &operator=(const StackRef &src) { + if (this != &src) { + state_ = src.state_; + stack_index_ = src.stack_index_; + pop_ = src.pop_; - src.pop_ = false; - } - return *this; - } + src.pop_ = false; + } + return *this; + } #endif - StackRef(lua_State* s, int index) :state_(s), stack_index_(lua_absindex(s, index)), pop_(true) - { - } - StackRef(lua_State* s, int index, bool pop) :state_(s), stack_index_(lua_absindex(s, index)), pop_(pop) - { - } - StackRef() :state_(0), stack_index_(0), pop_(false) - { - } - ~StackRef() - { - if (state_ && pop_) - { - if (lua_gettop(state_) >= stack_index_) - { - lua_settop(state_, stack_index_ - 1); - } - } - } - public: - + StackRef(lua_State *s, int index) + : state_(s), stack_index_(lua_absindex(s, index)), pop_(true) {} + StackRef(lua_State *s, int index, bool pop) + : state_(s), stack_index_(lua_absindex(s, index)), pop_(pop) {} + StackRef() : state_(0), stack_index_(0), pop_(false) {} + ~StackRef() { + if (state_ && pop_) { + if (lua_gettop(state_) >= stack_index_) { + lua_settop(state_, stack_index_ - 1); + } + } + } - bool isNilref()const { return state_ == 0 || lua_type(state_, stack_index_) == LUA_TNIL; } +public: + bool isNilref() const { + return state_ == 0 || lua_type(state_, stack_index_) == LUA_TNIL; + } - int push()const - { - lua_pushvalue(state_, stack_index_); - return 1; - } - int push(lua_State* state)const - { - lua_pushvalue(state_, stack_index_); - if (state_ != state) - { - lua_pushvalue(state_, stack_index_); - lua_xmove(state_, state, 1); - } - return 1; - } + int push() const { + lua_pushvalue(state_, stack_index_); + return 1; + } + int push(lua_State *state) const { + lua_pushvalue(state_, stack_index_); + if (state_ != state) { + lua_pushvalue(state_, stack_index_); + lua_xmove(state_, state, 1); + } + return 1; + } - int pushStackIndex(lua_State* state)const - { - if (state_ != state) - { - lua_pushvalue(state_, stack_index_); - lua_xmove(state_, state, 1); - return lua_gettop(state); - } - else - { - return stack_index_; - } - } - lua_State *state()const { return state_; } - }; + int pushStackIndex(lua_State *state) const { + if (state_ != state) { + lua_pushvalue(state_, stack_index_); + lua_xmove(state_, state, 1); + return lua_gettop(state); + } else { + return stack_index_; + } + } + lua_State *state() const { return state_; } +}; - /// @brief Reference to Lua value. Retain reference by LUA_REGISTRYINDEX - class RegistoryRef - { - public: +/// @brief Reference to Lua value. Retain reference by LUA_REGISTRYINDEX +class RegistoryRef { +public: #if KAGUYA_USE_SHARED_LUAREF - struct RefHolder - { - struct RefDeleter - { - RefDeleter(lua_State* L) : state_(L) - { - } - void operator()(int* ref) - { - luaL_unref(state_, LUA_REGISTRYINDEX, *ref); - delete ref; - } - lua_State* state_; - }; - RefHolder(lua_State* L, int ref) : state_(L), ref_(new int(ref), RefDeleter(L)) - { - } + struct RefHolder { + struct RefDeleter { + RefDeleter(lua_State *L) : state_(L) {} + void operator()(int *ref) { + luaL_unref(state_, LUA_REGISTRYINDEX, *ref); + delete ref; + } + lua_State *state_; + }; + RefHolder(lua_State *L, int ref) + : state_(L), ref_(new int(ref), RefDeleter(L)) {} - RefHolder(const RefHolder& src) :state_(src.state_), ref_(src.ref_) {} - RefHolder& operator =(const RefHolder& src) { - state_ = src.state_; - ref_ = src.ref_; - return *this; - } + RefHolder(const RefHolder &src) : state_(src.state_), ref_(src.ref_) {} + RefHolder &operator=(const RefHolder &src) { + state_ = src.state_; + ref_ = src.ref_; + return *this; + } #if KAGUYA_USE_RVALUE_REFERENCE - RefHolder(RefHolder&& src) :state_(0), ref_() - { - swap(src); - } - RefHolder& operator =(RefHolder&& src)throw() - { - swap(src); - return *this; - } + RefHolder(RefHolder &&src) : state_(0), ref_() { swap(src); } + RefHolder &operator=(RefHolder &&src) throw() { + swap(src); + return *this; + } #endif - void swap(RefHolder& other)throw() - { - std::swap(state_, other.state_); - std::swap(ref_, other.ref_); - } - int ref()const - { - if (state_ && ref_) { return *ref_; } - return LUA_REFNIL; - } - void reset() - { - ref_.reset(); - } - lua_State* state()const { return state_; } - private: - lua_State* state_; - standard::shared_ptr ref_; - }; + void swap(RefHolder &other) throw() { + std::swap(state_, other.state_); + std::swap(ref_, other.ref_); + } + int ref() const { + if (state_ && ref_) { + return *ref_; + } + return LUA_REFNIL; + } + void reset() { ref_.reset(); } + lua_State *state() const { return state_; } + + private: + lua_State *state_; + standard::shared_ptr ref_; + }; #else - struct RefHolder - { - RefHolder(lua_State* L, int ref) : state_(L), ref_(ref) - { - } - RefHolder(const RefHolder& src) :state_(src.state_), ref_(LUA_REFNIL) - { - if (state_) - { - lua_rawgeti(state_, LUA_REGISTRYINDEX, src.ref_); - ref_ = luaL_ref(state_, LUA_REGISTRYINDEX); - } - } - RefHolder& operator =(const RefHolder& src) - { - reset(); - state_ = src.state_; - if (state_) - { - lua_rawgeti(state_, LUA_REGISTRYINDEX, src.ref_); - ref_ = luaL_ref(state_, LUA_REGISTRYINDEX); - } - else - { - ref_ = LUA_REFNIL; - } - return *this; - } + struct RefHolder { + RefHolder(lua_State *L, int ref) : state_(L), ref_(ref) {} + RefHolder(const RefHolder &src) : state_(src.state_), ref_(LUA_REFNIL) { + if (state_) { + lua_rawgeti(state_, LUA_REGISTRYINDEX, src.ref_); + ref_ = luaL_ref(state_, LUA_REGISTRYINDEX); + } + } + RefHolder &operator=(const RefHolder &src) { + reset(); + state_ = src.state_; + if (state_) { + lua_rawgeti(state_, LUA_REGISTRYINDEX, src.ref_); + ref_ = luaL_ref(state_, LUA_REGISTRYINDEX); + } else { + ref_ = LUA_REFNIL; + } + return *this; + } #if KAGUYA_USE_RVALUE_REFERENCE - RefHolder(RefHolder&& src) throw() :state_(src.state_), ref_(src.ref_) - { - src.ref_ = LUA_REFNIL; - } - RefHolder& operator =(RefHolder&& src)throw() - { - swap(src); - return *this; - } + RefHolder(RefHolder &&src) throw() : state_(src.state_), ref_(src.ref_) { + src.ref_ = LUA_REFNIL; + } + RefHolder &operator=(RefHolder &&src) throw() { + swap(src); + return *this; + } #endif - void swap(RefHolder& other)throw() - { - std::swap(state_, other.state_); - std::swap(ref_, other.ref_); - } - int ref()const - { - if (state_) { return ref_; } - return LUA_REFNIL; - } - void reset() - { - if (ref_ != LUA_REFNIL && state_) - { - luaL_unref(state_, LUA_REGISTRYINDEX, ref_); - ref_ = LUA_REFNIL; - } - } - ~RefHolder() - { - reset(); - } + void swap(RefHolder &other) throw() { + std::swap(state_, other.state_); + std::swap(ref_, other.ref_); + } + int ref() const { + if (state_) { + return ref_; + } + return LUA_REFNIL; + } + void reset() { + if (ref_ != LUA_REFNIL && state_) { + luaL_unref(state_, LUA_REGISTRYINDEX, ref_); + ref_ = LUA_REFNIL; + } + } + ~RefHolder() { reset(); } - lua_State* state()const { return state_; } - private: - lua_State* state_; - int ref_; - }; + lua_State *state() const { return state_; } + + private: + lua_State *state_; + int ref_; + }; #endif - RegistoryRef(const RegistoryRef& src) : ref_(src.ref_) - { - } - RegistoryRef& operator =(const RegistoryRef& src) - { - if (this != &src) - { - ref_ = src.ref_; - } - return *this; - } + RegistoryRef(const RegistoryRef &src) : ref_(src.ref_) {} + RegistoryRef &operator=(const RegistoryRef &src) { + if (this != &src) { + ref_ = src.ref_; + } + return *this; + } - static int ref_from_stacktop(lua_State* state) - { - if (state) - { - return luaL_ref(state, LUA_REGISTRYINDEX); - } - else - { - return LUA_REFNIL; - } - } + static int ref_from_stacktop(lua_State *state) { + if (state) { + return luaL_ref(state, LUA_REGISTRYINDEX); + } else { + return LUA_REFNIL; + } + } #if KAGUYA_USE_RVALUE_REFERENCE - RegistoryRef(RegistoryRef&& src)throw() : ref_(0, LUA_REFNIL) - { - swap(src); - } - RegistoryRef& operator =(RegistoryRef&& src)throw() - { - swap(src); - return *this; - } + RegistoryRef(RegistoryRef &&src) throw() : ref_(0, LUA_REFNIL) { swap(src); } + RegistoryRef &operator=(RegistoryRef &&src) throw() { + swap(src); + return *this; + } #endif - RegistoryRef() : ref_(0, LUA_REFNIL) {} - RegistoryRef(lua_State* state) : ref_(state, LUA_REFNIL) {} - + RegistoryRef() : ref_(0, LUA_REFNIL) {} + RegistoryRef(lua_State *state) : ref_(state, LUA_REFNIL) {} - RegistoryRef(lua_State* state, StackTop, NoMainCheck) :ref_(state, ref_from_stacktop(state)) - { - } + RegistoryRef(lua_State *state, StackTop, NoMainCheck) + : ref_(state, ref_from_stacktop(state)) {} - RegistoryRef(lua_State* state, StackTop) : ref_(util::toMainThread(state), ref_from_stacktop(state)) - { - } + RegistoryRef(lua_State *state, StackTop) + : ref_(util::toMainThread(state), ref_from_stacktop(state)) {} - void swap(RegistoryRef& other)throw() - { - ref_.swap(other.ref_); - } + void swap(RegistoryRef &other) throw() { ref_.swap(other.ref_); } - template - RegistoryRef(lua_State* state, const T& v, NoMainCheck) : ref_(0, LUA_REFNIL) - { - if (!state) { return; } - util::ScopedSavedStack save(state); - util::one_push(state, v); - ref_ = RefHolder(state, ref_from_stacktop(state)); - } - template - RegistoryRef(lua_State* state, const T& v) : ref_(0, LUA_REFNIL) - { - if (!state) { return; } - util::ScopedSavedStack save(state); - util::one_push(state, v); - ref_ = RefHolder(util::toMainThread(state), ref_from_stacktop(state)); - } + template + RegistoryRef(lua_State *state, const T &v, NoMainCheck) + : ref_(0, LUA_REFNIL) { + if (!state) { + return; + } + util::ScopedSavedStack save(state); + util::one_push(state, v); + ref_ = RefHolder(state, ref_from_stacktop(state)); + } + template + RegistoryRef(lua_State *state, const T &v) : ref_(0, LUA_REFNIL) { + if (!state) { + return; + } + util::ScopedSavedStack save(state); + util::one_push(state, v); + ref_ = RefHolder(util::toMainThread(state), ref_from_stacktop(state)); + } #if KAGUYA_USE_CPP11 - template - RegistoryRef(lua_State* state, T&& v, NoMainCheck) : ref_(0, LUA_REFNIL) - { - if (!state) { return; } - util::ScopedSavedStack save(state); - util::one_push(state, standard::forward(v)); - ref_ = RefHolder(state, ref_from_stacktop(state)); - } - template - RegistoryRef(lua_State* state, T&& v) : ref_(0, LUA_REFNIL) - { - if (!state) { return; } - util::ScopedSavedStack save(state); - util::one_push(state, standard::forward(v)); - ref_ = RefHolder(util::toMainThread(state), ref_from_stacktop(state)); - } + template + RegistoryRef(lua_State *state, T &&v, NoMainCheck) : ref_(0, LUA_REFNIL) { + if (!state) { + return; + } + util::ScopedSavedStack save(state); + util::one_push(state, standard::forward(v)); + ref_ = RefHolder(state, ref_from_stacktop(state)); + } + template + RegistoryRef(lua_State *state, T &&v) : ref_(0, LUA_REFNIL) { + if (!state) { + return; + } + util::ScopedSavedStack save(state); + util::one_push(state, standard::forward(v)); + ref_ = RefHolder(util::toMainThread(state), ref_from_stacktop(state)); + } #endif - ~RegistoryRef() - { - try - { - unref(); - } - catch (...) {}//can't throw at Destructor - } + ~RegistoryRef() { + try { + unref(); + } catch (...) { + } // can't throw at Destructor + } - /// @brief push to Lua stack - int push()const - { - return push(ref_.state()); - } - /// @brief push to Lua stack - int push(lua_State* state)const - { - if (isNilref()) - { - lua_pushnil(state); - return 1; - } + /// @brief push to Lua stack + int push() const { return push(ref_.state()); } + /// @brief push to Lua stack + int push(lua_State *state) const { + if (isNilref()) { + lua_pushnil(state); + return 1; + } #if LUA_VERSION_NUM >= 502 - if (state != ref_.state()) - {//state check - assert(util::toMainThread(state) == util::toMainThread(ref_.state())); - } + if (state != ref_.state()) { // state check + assert(util::toMainThread(state) == util::toMainThread(ref_.state())); + } #endif - lua_rawgeti(state, LUA_REGISTRYINDEX, ref_.ref()); - return 1; - } + lua_rawgeti(state, LUA_REGISTRYINDEX, ref_.ref()); + return 1; + } - int pushStackIndex(lua_State* state)const - { - push(state); - return lua_gettop(state); - } - lua_State *state()const { return ref_.state(); } + int pushStackIndex(lua_State *state) const { + push(state); + return lua_gettop(state); + } + lua_State *state() const { return ref_.state(); } - bool isNilref()const { return ref_.ref() == LUA_REFNIL; } + bool isNilref() const { return ref_.ref() == LUA_REFNIL; } - void unref() - { - ref_.reset(); - } - private: - RefHolder ref_; - }; + void unref() { ref_.reset(); } - } +private: + RefHolder ref_; +}; +} } diff --git a/include/kaguya/detail/lua_table_def.hpp b/include/kaguya/detail/lua_table_def.hpp index 1978fe9..d7b7f82 100644 --- a/include/kaguya/detail/lua_table_def.hpp +++ b/include/kaguya/detail/lua_table_def.hpp @@ -13,559 +13,454 @@ #include "kaguya/type.hpp" #include "kaguya/utility.hpp" +namespace kaguya { +class LuaRef; +class LuaStackRef; +class LuaTable; +template class TableKeyReferenceProxy; +class MemberFunctionBinder; -namespace kaguya -{ - class LuaRef; - class LuaStackRef; - class LuaTable; - template - class TableKeyReferenceProxy; - class MemberFunctionBinder; +namespace detail { - namespace detail - { - - struct table_proxy - { +struct table_proxy { #if KAGUYA_USE_CPP11 - template - static void set(lua_State* state, int table_index, KEY&& key, V&& value) - { - util::one_push(state, std::forward(key)); - util::one_push(state, std::forward(value)); - lua_settable(state, table_index); - } - template - static void set(lua_State* state, int table_index, const char* key, V&& value) - { - util::one_push(state, std::forward(value)); - lua_setfield(state, table_index, key); - } - template - static void set(lua_State* state, int table_index, const std::string& key, V&& value) - { - set(state, table_index, key.c_str(), std::forward(value)); - } - - template - static void set(lua_State* state, int table_index, luaInt key, V&& value) - { - util::one_push(state, std::forward(value)); - lua_seti(state, table_index, key); - } - template - static void rawset(lua_State* state, int table_index, KEY&& key, V&& value) - { - util::one_push(state, std::forward(key)); - util::one_push(state, std::forward(value)); - lua_rawset(state, table_index); - } - template - static void rawset(lua_State* state, int table_index, luaInt key, V&& value) - { - util::one_push(state, std::forward(value)); - lua_rawseti(state, table_index, key); - } + template + static void set(lua_State *state, int table_index, KEY &&key, V &&value) { + util::one_push(state, std::forward(key)); + util::one_push(state, std::forward(value)); + lua_settable(state, table_index); + } + template + static void set(lua_State *state, int table_index, const char *key, + V &&value) { + util::one_push(state, std::forward(value)); + lua_setfield(state, table_index, key); + } + template + static void set(lua_State *state, int table_index, const std::string &key, + V &&value) { + set(state, table_index, key.c_str(), std::forward(value)); + } + + template + static void set(lua_State *state, int table_index, luaInt key, V &&value) { + util::one_push(state, std::forward(value)); + lua_seti(state, table_index, key); + } + template + static void rawset(lua_State *state, int table_index, KEY &&key, V &&value) { + util::one_push(state, std::forward(key)); + util::one_push(state, std::forward(value)); + lua_rawset(state, table_index); + } + template + static void rawset(lua_State *state, int table_index, luaInt key, V &&value) { + util::one_push(state, std::forward(value)); + lua_rawseti(state, table_index, key); + } #else - template - static void set(lua_State* state, int table_index, const KEY& key, const V& value) - { - util::one_push(state, key); - util::one_push(state, value); - lua_settable(state, table_index); - } - template - static void set(lua_State* state, int table_index, const char* key, const V& value) - { - util::one_push(state, value); - lua_setfield(state, table_index, key); - } - template - static void set(lua_State* state, int table_index, const std::string& key, const V& value) - { - util::one_push(state, value); - lua_setfield(state, table_index, key.c_str()); - } - - template - static void set(lua_State* state, int table_index, luaInt key, const V& value) - { - util::one_push(state, value); - lua_seti(state, table_index, key); - } - - template - static void rawset(lua_State* state, int table_index,const KEY& key,const V& value) - { - util::one_push(state, key); - util::one_push(state, value); - lua_rawset(state, table_index); - } - template - static void rawset(lua_State* state, int table_index, luaInt key, const V& value) - { - util::one_push(state, value); - lua_rawseti(state, table_index, key); - } + template + static void set(lua_State *state, int table_index, const KEY &key, + const V &value) { + util::one_push(state, key); + util::one_push(state, value); + lua_settable(state, table_index); + } + template + static void set(lua_State *state, int table_index, const char *key, + const V &value) { + util::one_push(state, value); + lua_setfield(state, table_index, key); + } + template + static void set(lua_State *state, int table_index, const std::string &key, + const V &value) { + util::one_push(state, value); + lua_setfield(state, table_index, key.c_str()); + } + + template + static void set(lua_State *state, int table_index, luaInt key, + const V &value) { + util::one_push(state, value); + lua_seti(state, table_index, key); + } + + template + static void rawset(lua_State *state, int table_index, const KEY &key, + const V &value) { + util::one_push(state, key); + util::one_push(state, value); + lua_rawset(state, table_index); + } + template + static void rawset(lua_State *state, int table_index, luaInt key, + const V &value) { + util::one_push(state, value); + lua_rawseti(state, table_index, key); + } #endif #if KAGUYA_USE_CPP11 - template - static void get(lua_State* state, int table_index, KEY&& key) - { - util::one_push(state, std::forward(key)); - lua_gettable(state, table_index); - } + template + static void get(lua_State *state, int table_index, KEY &&key) { + util::one_push(state, std::forward(key)); + lua_gettable(state, table_index); + } #endif - template - static void get(lua_State* state, int table_index, const KEY& key) - { - util::one_push(state, key); - lua_gettable(state, table_index); - } - static void get(lua_State* state, int table_index, const char* key) - { - lua_getfield(state, table_index, key); - } - static void get(lua_State* state, int table_index, const std::string& key) - { - lua_getfield(state, table_index, key.c_str()); - } - static void get(lua_State* state, int table_index, luaInt key) - { - lua_geti(state, table_index, key); - } + template + static void get(lua_State *state, int table_index, const KEY &key) { + util::one_push(state, key); + lua_gettable(state, table_index); + } + static void get(lua_State *state, int table_index, const char *key) { + lua_getfield(state, table_index, key); + } + static void get(lua_State *state, int table_index, const std::string &key) { + lua_getfield(state, table_index, key.c_str()); + } + static void get(lua_State *state, int table_index, luaInt key) { + lua_geti(state, table_index, key); + } #if KAGUYA_USE_CPP11 - template - static void rawget(lua_State* state, int table_index, KEY&& key) - { - util::one_push(state, std::forward(key)); - lua_rawget(state, table_index); - } + template + static void rawget(lua_State *state, int table_index, KEY &&key) { + util::one_push(state, std::forward(key)); + lua_rawget(state, table_index); + } #endif - template - static void rawget(lua_State* state, int table_index, const KEY& key) - { - util::one_push(state, key); - lua_rawget(state, table_index); - } - static void rawget(lua_State* state, int table_index, luaInt key) - { - lua_rawgeti(state, table_index, key); - } - }; - - template - class LuaTableOrUserDataImpl - { - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - int push_(lua_State* state)const - { - return static_cast(this)->push(state); - } - public: - - /// @brief set metatable - /// @param table metatable - bool setMetatable(const LuaTable& table); - - /// @brief get metatable - LuaTable getMetatable()const; - - - /// @brief table->*"function_name"() in c++ and table:function_name(); in lua is same - /// @param function_name function_name in table - MemberFunctionBinder operator->*(const char* function_name); - - /// @brief value = table[key]; - /// @param key key of table - /// @return reference of field value - template - typename lua_type_traits::get_type getField(const KEY& key)const - { - lua_State* state = state_(); - typedef typename lua_type_traits::get_type get_type; - if (!state) - { - except::typeMismatchError(state, "is nil"); - return get_type(); - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - - table_proxy::get(state, stackIndex, key); - - return lua_type_traits::get(state, -1); - } - - - /// @brief value = table[key]; - /// @param key key of table - /// @return reference of field value - template - LuaStackRef getField(const KEY& key)const; - - + template + static void rawget(lua_State *state, int table_index, const KEY &key) { + util::one_push(state, key); + lua_rawget(state, table_index); + } + static void rawget(lua_State *state, int table_index, luaInt key) { + lua_rawgeti(state, table_index, key); + } +}; + +template class LuaTableOrUserDataImpl { +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + int push_(lua_State *state) const { + return static_cast(this)->push(state); + } + +public: + /// @brief set metatable + /// @param table metatable + bool setMetatable(const LuaTable &table); + + /// @brief get metatable + LuaTable getMetatable() const; + + /// @brief table->*"function_name"() in c++ and table:function_name(); in lua + /// is same + /// @param function_name function_name in table + MemberFunctionBinder operator->*(const char *function_name); + + /// @brief value = table[key]; + /// @param key key of table + /// @return reference of field value + template + typename lua_type_traits::get_type getField(const KEY &key) const { + lua_State *state = state_(); + typedef typename lua_type_traits::get_type get_type; + if (!state) { + except::typeMismatchError(state, "is nil"); + return get_type(); + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + + table_proxy::get(state, stackIndex, key); + + return lua_type_traits::get(state, -1); + } + + /// @brief value = table[key]; + /// @param key key of table + /// @return reference of field value + template LuaStackRef getField(const KEY &key) const; #if KAGUYA_USE_CPP11 - /// @brief table[key] = value; - template - bool setField(K&& key, V&& value) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return false; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - - table_proxy::set(state, stackIndex, std::forward(key), std::forward(value)); - return true; - } + /// @brief table[key] = value; + template bool setField(K &&key, V &&value) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return false; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + + table_proxy::set(state, stackIndex, std::forward(key), + std::forward(value)); + return true; + } #else - /// @brief table[key] = value; - template - bool setField(const K& key, const V& value) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return false; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - - table_proxy::set(state, stackIndex, key, value); - - return true; - } + /// @brief table[key] = value; + template + bool setField(const K &key, const V &value) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return false; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + + table_proxy::set(state, stackIndex, key, value); + + return true; + } #endif - - /// @brief value = table[key]; - /// @param key key of table - /// @return reference of field value - template - LuaStackRef operator[](K key)const; - - - /// @brief value = table[key];or table[key] = value; - /// @param key key of table - /// @return reference of field value - template - TableKeyReferenceProxy operator[](K key); - }; - - template - class LuaTableImpl - { - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - int push_(lua_State* state)const - { - return static_cast(this)->push(state); - } - - template - struct gettablekey - { - typedef K key_type; - typedef void value_type; - std::vector& v_; - gettablekey(std::vector&v) :v_(v) {} - void operator ()(K key, const void*) - { - v_.push_back(key); - } - }; - template - struct gettablevalue - { - typedef void key_type; - typedef V value_type; - std::vector& v_; - gettablevalue(std::vector&v) :v_(v) {} - void operator ()(const void*, V value) - { - v_.push_back(value); - } - }; - template - struct gettablemap - { - typedef K key_type; - typedef V value_type; - std::map& m_; - gettablemap(std::map& m) :m_(m) {} - void operator ()(K key, V value) - { - m_[key] = value; - } - }; - public: - - + /// @brief value = table[key]; + /// @param key key of table + /// @return reference of field value + template LuaStackRef operator[](K key) const; + + /// @brief value = table[key];or table[key] = value; + /// @param key key of table + /// @return reference of field value + template TableKeyReferenceProxy operator[](K key); +}; + +template class LuaTableImpl { +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + int push_(lua_State *state) const { + return static_cast(this)->push(state); + } + + template struct gettablekey { + typedef K key_type; + typedef void value_type; + std::vector &v_; + gettablekey(std::vector &v) : v_(v) {} + void operator()(K key, const void *) { v_.push_back(key); } + }; + template struct gettablevalue { + typedef void key_type; + typedef V value_type; + std::vector &v_; + gettablevalue(std::vector &v) : v_(v) {} + void operator()(const void *, V value) { v_.push_back(value); } + }; + template struct gettablemap { + typedef K key_type; + typedef V value_type; + std::map &m_; + gettablemap(std::map &m) : m_(m) {} + void operator()(K key, V value) { m_[key] = value; } + }; + +public: #if KAGUYA_USE_CPP11 - /// @brief rawset(table,key,value) - template - bool setRawField(K&& key, V&& value) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return false; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - - table_proxy::rawset(state, stackIndex, std::forward(key), std::forward(value)); - - return true; - } + /// @brief rawset(table,key,value) + template bool setRawField(K &&key, V &&value) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return false; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + + table_proxy::rawset(state, stackIndex, std::forward(key), + std::forward(value)); + + return true; + } #else - /// @brief rawset(table,key,value) - template - bool setRawField(const K& key, const V& value) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return false; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - table_proxy::rawset(state, stackIndex, key, value); - return true; - } + /// @brief rawset(table,key,value) + template + bool setRawField(const K &key, const V &value) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return false; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + table_proxy::rawset(state, stackIndex, key, value); + return true; + } #endif - /// @brief value = rawget(table,key); - /// @param key key of table - /// @return reference of field value - template - typename lua_type_traits::get_type getRawField(const KEY& key)const - { - lua_State* state = state_(); - typedef typename lua_type_traits::get_type get_type; - if (!state) - { - except::typeMismatchError(state, "is nil"); - return get_type(); - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - - table_proxy::rawget(state, stackIndex, key); - - return lua_type_traits::get(state, -1); - } - /// @brief value = rawget(table,key); - /// @param key key of table - /// @return reference of field value - template - LuaStackRef getRawField(const KEY& key)const; - - - /// @brief foreach table fields - template < class K, class V, class Fun> void foreach_table(Fun f)const - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - lua_pushnil(state); - while (lua_next(state, stackIndex) != 0) - { - //backup key - lua_pushvalue(state, -2); - - f(lua_type_traits::get(state, -1), lua_type_traits::get(state, -2)); - lua_pop(state, 2);//pop key and value - } - } - - /// @brief foreach table fields - template < class K, class V, class Fun> void foreach_table_breakable(Fun f)const - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - lua_pushnil(state); - while (lua_next(state, stackIndex) != 0) - { - lua_pushvalue(state, -2);//backup key - - bool cont = f(lua_type_traits::get(state, -1), lua_type_traits::get(state, -2)); - lua_pop(state, 2);//pop key and value - if (!cont) - { - break; - } - } - } - - /// @brief If type is table or userdata, return keys. - /// @return field keys - template - std::vector keys()const - { - std::vector res; - util::ScopedSavedStack save(state_()); - int stackIndex = pushStackIndex_(state_()); - size_t size = lua_rawlen(state_(), stackIndex); - res.reserve(size); - foreach_table(gettablekey(res)); - return res; - } - - /// @brief If type is table or userdata, return keys. - /// @return field keys - template - std::vector keys()const - { - return keys >(); - } - std::vector keys()const; - - /// @brief If type is table or userdata, return values. - /// @return field value - template - std::vector values()const - { - std::vector res; - util::ScopedSavedStack save(state_()); - int stackIndex = pushStackIndex_(state_()); - size_t size = lua_rawlen(state_(), stackIndex); - res.reserve(size); - foreach_table(gettablevalue(res)); - return res; - } - - /// @brief If type is table or userdata, return values. - /// @return field value - template - std::vector values()const - { - return values >(); - } - std::vector values()const; - - /// @brief If type is table or userdata, return key value pair. - /// @return key value pair - template - std::map map()const - { - std::map res; - foreach_table(gettablemap(res)); - return res; - } - - /// @brief If type is table or userdata, return key value pair. - /// @return key value pair - template - std::map map()const - { - return map < K, V, C, std::allocator > >(); - } - - /// @brief If type is table or userdata, return key value pair. - /// @return key value pair - template - std::map map()const - { - return map >(); - } - std::map map()const; - }; - - template - class LuaUserDataImpl - { - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - int push_(lua_State* state)const - { - return static_cast(this)->push(state); - } - public: - /// @brief is type test - template - bool isType()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits::strictCheckType(state, pushStackIndex_(state)); - } - - template - bool isConvertible()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits::checkType(state, pushStackIndex_(state)); - } - - template - bool typeTest()const - { - return isType(); - } - template - bool weakTypeTest()const - { - return isConvertible(); - } - - templatetypename lua_type_traits::get_type get()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits::get(state, state ? pushStackIndex_(state) : 0); - } - - template - operator T()const - { - return get(); - } - }; - } + /// @brief value = rawget(table,key); + /// @param key key of table + /// @return reference of field value + template + typename lua_type_traits::get_type getRawField(const KEY &key) const { + lua_State *state = state_(); + typedef typename lua_type_traits::get_type get_type; + if (!state) { + except::typeMismatchError(state, "is nil"); + return get_type(); + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + + table_proxy::rawget(state, stackIndex, key); + + return lua_type_traits::get(state, -1); + } + /// @brief value = rawget(table,key); + /// @param key key of table + /// @return reference of field value + template LuaStackRef getRawField(const KEY &key) const; + + /// @brief foreach table fields + template void foreach_table(Fun f) const { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + lua_pushnil(state); + while (lua_next(state, stackIndex) != 0) { + // backup key + lua_pushvalue(state, -2); + + f(lua_type_traits::get(state, -1), lua_type_traits::get(state, -2)); + lua_pop(state, 2); // pop key and value + } + } + + /// @brief foreach table fields + template + void foreach_table_breakable(Fun f) const { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + lua_pushnil(state); + while (lua_next(state, stackIndex) != 0) { + lua_pushvalue(state, -2); // backup key + + bool cont = f(lua_type_traits::get(state, -1), + lua_type_traits::get(state, -2)); + lua_pop(state, 2); // pop key and value + if (!cont) { + break; + } + } + } + + /// @brief If type is table or userdata, return keys. + /// @return field keys + template std::vector keys() const { + std::vector res; + util::ScopedSavedStack save(state_()); + int stackIndex = pushStackIndex_(state_()); + size_t size = lua_rawlen(state_(), stackIndex); + res.reserve(size); + foreach_table(gettablekey(res)); + return res; + } + + /// @brief If type is table or userdata, return keys. + /// @return field keys + template std::vector keys() const { + return keys >(); + } + std::vector keys() const; + + /// @brief If type is table or userdata, return values. + /// @return field value + template std::vector values() const { + std::vector res; + util::ScopedSavedStack save(state_()); + int stackIndex = pushStackIndex_(state_()); + size_t size = lua_rawlen(state_(), stackIndex); + res.reserve(size); + foreach_table(gettablevalue(res)); + return res; + } + + /// @brief If type is table or userdata, return values. + /// @return field value + template std::vector values() const { + return values >(); + } + std::vector values() const; + + /// @brief If type is table or userdata, return key value pair. + /// @return key value pair + template + std::map map() const { + std::map res; + foreach_table(gettablemap(res)); + return res; + } + + /// @brief If type is table or userdata, return key value pair. + /// @return key value pair + template std::map map() const { + return map > >(); + } + + /// @brief If type is table or userdata, return key value pair. + /// @return key value pair + template std::map map() const { + return map >(); + } + std::map map() const; +}; + +template class LuaUserDataImpl { +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + int push_(lua_State *state) const { + return static_cast(this)->push(state); + } + +public: + /// @brief is type test + template bool isType() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits::strictCheckType(state, pushStackIndex_(state)); + } + + template bool isConvertible() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits::checkType(state, pushStackIndex_(state)); + } + + template bool typeTest() const { return isType(); } + template bool weakTypeTest() const { return isConvertible(); } + + template typename lua_type_traits::get_type get() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits::get(state, state ? pushStackIndex_(state) : 0); + } + + template operator T() const { return get(); } +}; +} } - diff --git a/include/kaguya/detail/lua_variant_def.hpp b/include/kaguya/detail/lua_variant_def.hpp index f5c63b5..d744a86 100644 --- a/include/kaguya/detail/lua_variant_def.hpp +++ b/include/kaguya/detail/lua_variant_def.hpp @@ -8,127 +8,97 @@ #include "kaguya/detail/lua_function_def.hpp" #include "kaguya/detail/lua_table_def.hpp" - -namespace kaguya -{ - class LuaRef; - class LuaTable; - template - class TableKeyReferenceProxy; - class MemberFunctionBinder; - - namespace detail { - - template - class LuaVariantImpl :public LuaTableImpl, - public LuaTableOrUserDataImpl, - public detail::LuaFunctionImpl, - public detail::LuaThreadImpl, - public LuaBasicTypeFunctions - { - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - public: - using LuaBasicTypeFunctions::type; - using LuaBasicTypeFunctions::typeName; - - /// @brief deprecated, use isType instead. - template - bool typeTest()const - { - return isType(); - } - - - /// @brief deprecated, use isConvertible instead. - template - bool weakTypeTest()const - { - return isConvertible(); - } - - /// @brief is type test - template - bool isType()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits::strictCheckType(state, pushStackIndex_(state)); - } - - template - bool isConvertible()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits::checkType(state, pushStackIndex_(state)); - } - - - - templatetypename lua_type_traits::get_type get()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits::get(state, state ? pushStackIndex_(state) : 0); - } - templatetypename lua_type_traits::get_type value_or(U v)const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - return lua_type_traits >::get(state, state ? pushStackIndex_(state) : 0).value_or(v); - } - - //deprecated. use get >() instead; - template - typename lua_type_traits::get_type get(bool& was_valid, bool allow_convertible = true)const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int stackindex = pushStackIndex_(state); - if (allow_convertible) - { - was_valid = lua_type_traits::checkType(state, stackindex); - } - else - { - was_valid = lua_type_traits::strictCheckType(state, stackindex); - } - if (was_valid) - { - return lua_type_traits::get(state, stackindex); - } - else - { - return T(); - } - } - template - operator T()const - { - return get(); - } +namespace kaguya { +class LuaRef; +class LuaTable; +template class TableKeyReferenceProxy; +class MemberFunctionBinder; + +namespace detail { + +template +class LuaVariantImpl : public LuaTableImpl, + public LuaTableOrUserDataImpl, + public detail::LuaFunctionImpl, + public detail::LuaThreadImpl, + public LuaBasicTypeFunctions { +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + +public: + using LuaBasicTypeFunctions::type; + using LuaBasicTypeFunctions::typeName; + + /// @brief deprecated, use isType instead. + template bool typeTest() const { return isType(); } + + /// @brief deprecated, use isConvertible instead. + template bool weakTypeTest() const { return isConvertible(); } + + /// @brief is type test + template bool isType() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits::strictCheckType(state, pushStackIndex_(state)); + } + + template bool isConvertible() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits::checkType(state, pushStackIndex_(state)); + } + + template typename lua_type_traits::get_type get() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits::get(state, state ? pushStackIndex_(state) : 0); + } + template + typename lua_type_traits::get_type value_or(U v) const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + return lua_type_traits >::get( + state, state ? pushStackIndex_(state) : 0) + .value_or(v); + } + + // deprecated. use get >() instead; + template + typename lua_type_traits::get_type + get(bool &was_valid, bool allow_convertible = true) const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int stackindex = pushStackIndex_(state); + if (allow_convertible) { + was_valid = lua_type_traits::checkType(state, stackindex); + } else { + was_valid = lua_type_traits::strictCheckType(state, stackindex); + } + if (was_valid) { + return lua_type_traits::get(state, stackindex); + } else { + return T(); + } + } + template operator T() const { return get(); } #if KAGUYA_USE_CPP11 - template FunctionResults operator()(Args&&... args); + template FunctionResults operator()(Args &&... args); #else - inline FunctionResults operator()(); - -#define KAGUYA_OP_FN_DEF(N) \ - template\ - inline FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)); + inline FunctionResults operator()(); +#define KAGUYA_OP_FN_DEF(N) \ + template \ + inline FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)); - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) #undef KAGUYA_OP_FN_DEF #endif - }; - } +}; +} } diff --git a/include/kaguya/error_handler.hpp b/include/kaguya/error_handler.hpp index 271007e..36db661 100644 --- a/include/kaguya/error_handler.hpp +++ b/include/kaguya/error_handler.hpp @@ -10,196 +10,165 @@ #include "kaguya/config.hpp" #include "kaguya/type.hpp" -namespace kaguya -{ - - inline const char* get_error_message(lua_State *state) - { - if (lua_type(state, -1) == LUA_TSTRING) - { - const char* message = lua_tostring(state, -1); - return message ? message : "unknown error"; - } - else - { - return "unknown error"; - } - } - inline int lua_pcall_wrap(lua_State* state, int argnum, int retnum) - { - int result = lua_pcall(state, argnum, retnum, 0); - return result; - } - - struct ErrorHandler - { - typedef standard::function function_type; - - - static bool handle(const char* message, lua_State *state) - { - function_type handler = getHandler(state); - if (handler) - { - handler(0, message); - return true; - } - return false; - } - static bool handle(int status_code, const char* message, lua_State *state) - { - function_type handler = getHandler(state); - if (handler) - { - handler(status_code, message); - return true; - } - return false; - } - static bool handle(int status_code, lua_State *state) - { - function_type handler = getHandler(state); - if (handler) - { - handler(status_code, get_error_message(state)); - return true; - } - return false; - } - - static function_type getHandler(lua_State* state) - { - function_type* funptr = getFunctionPointer(state); - if (funptr) - { - return *funptr; - } - return function_type(); - } - - - static void unregisterHandler(lua_State* state) - { - if (state) - { - function_type* funptr = getFunctionPointer(state); - if (funptr) - { - *funptr = function_type(); - } - } - } - static void registerHandler(lua_State* state, function_type f) - { - if (state) - { - function_type* funptr = getFunctionPointer(state); - if (!funptr) - { - util::ScopedSavedStack save(state); - lua_pushlightuserdata(state, handlerRegistryKey()); - void* ptr = lua_newuserdata(state, sizeof(function_type));//dummy data for gc call - funptr = new(ptr) function_type(); - - //create function_type metatable - lua_newtable(state); - lua_pushcclosure(state, &error_handler_cleanner, 0); - lua_setfield(state, -2, "__gc"); - lua_pushvalue(state, -1); - lua_setfield(state, -1, "__index"); - lua_setmetatable(state, -2); - - lua_rawset(state, LUA_REGISTRYINDEX); - } - *funptr = f; - } - } - - static void throwDefaultError(int status, const char* message=0) - { - switch (status) - { - case LUA_ERRSYNTAX: - throw LuaSyntaxError(status, message ? std::string(message) : "unknown syntax error"); - case LUA_ERRRUN: - throw LuaRuntimeError(status, message ? std::string(message) : "unknown runtime error"); - case LUA_ERRMEM: - throw LuaMemoryError(status, message ? std::string(message) : "lua memory allocation error"); - case LUA_ERRERR: - throw LuaErrorRunningError(status, message ? std::string(message) : "unknown error running error"); +namespace kaguya { +inline const char *get_error_message(lua_State *state) { + if (lua_type(state, -1) == LUA_TSTRING) { + const char *message = lua_tostring(state, -1); + return message ? message : "unknown error"; + } else { + return "unknown error"; + } +} +inline int lua_pcall_wrap(lua_State *state, int argnum, int retnum) { + int result = lua_pcall(state, argnum, retnum, 0); + return result; +} + +struct ErrorHandler { + typedef standard::function function_type; + + static bool handle(const char *message, lua_State *state) { + function_type handler = getHandler(state); + if (handler) { + handler(0, message); + return true; + } + return false; + } + static bool handle(int status_code, const char *message, lua_State *state) { + function_type handler = getHandler(state); + if (handler) { + handler(status_code, message); + return true; + } + return false; + } + static bool handle(int status_code, lua_State *state) { + function_type handler = getHandler(state); + if (handler) { + handler(status_code, get_error_message(state)); + return true; + } + return false; + } + + static function_type getHandler(lua_State *state) { + function_type *funptr = getFunctionPointer(state); + if (funptr) { + return *funptr; + } + return function_type(); + } + + static void unregisterHandler(lua_State *state) { + if (state) { + function_type *funptr = getFunctionPointer(state); + if (funptr) { + *funptr = function_type(); + } + } + } + static void registerHandler(lua_State *state, function_type f) { + if (state) { + function_type *funptr = getFunctionPointer(state); + if (!funptr) { + util::ScopedSavedStack save(state); + lua_pushlightuserdata(state, handlerRegistryKey()); + void *ptr = lua_newuserdata( + state, sizeof(function_type)); // dummy data for gc call + funptr = new (ptr) function_type(); + + // create function_type metatable + lua_newtable(state); + lua_pushcclosure(state, &error_handler_cleanner, 0); + lua_setfield(state, -2, "__gc"); + lua_pushvalue(state, -1); + lua_setfield(state, -1, "__index"); + lua_setmetatable(state, -2); + + lua_rawset(state, LUA_REGISTRYINDEX); + } + *funptr = f; + } + } + + static void throwDefaultError(int status, const char *message = 0) { + switch (status) { + case LUA_ERRSYNTAX: + throw LuaSyntaxError(status, message ? std::string(message) + : "unknown syntax error"); + case LUA_ERRRUN: + throw LuaRuntimeError(status, message ? std::string(message) + : "unknown runtime error"); + case LUA_ERRMEM: + throw LuaMemoryError(status, message ? std::string(message) + : "lua memory allocation error"); + case LUA_ERRERR: + throw LuaErrorRunningError(status, message + ? std::string(message) + : "unknown error running error"); #if LUA_VERSION_NUM >= 502 - case LUA_ERRGCMM: - throw LuaGCError(status, message ? std::string(message) : "unknown gc error"); + case LUA_ERRGCMM: + throw LuaGCError(status, + message ? std::string(message) : "unknown gc error"); #endif - default: - throw LuaUnknownError(status, message ? std::string(message) : "lua unknown error"); - } - } - private: - - static void* handlerRegistryKey() - { - static void* key; - return key; - } - static function_type* getFunctionPointer(lua_State* state) - { - if (state) - { - util::ScopedSavedStack save(state); - lua_pushlightuserdata(state, handlerRegistryKey()); - lua_rawget(state, LUA_REGISTRYINDEX); - function_type* ptr = (function_type*)lua_touserdata(state, -1); - return ptr; - } - return 0; - } - - ErrorHandler() {} - - ErrorHandler(const ErrorHandler&); - ErrorHandler& operator=(const ErrorHandler&); - - static int error_handler_cleanner(lua_State *state) - { - function_type* ptr = (function_type*)lua_touserdata(state, 1); - ptr->~function_type(); - return 0; - } - }; - - namespace except - { - inline void OtherError(lua_State *state, const std::string& message) - { - if (ErrorHandler::handle(message.c_str(), state)) - { - return; - } - } - inline void typeMismatchError(lua_State *state, const std::string& message) - { - if(ErrorHandler::handle(message.c_str(), state)) - { - return; - } - } - inline void memoryError(lua_State *state, const char* message) - { - if (ErrorHandler::handle(message, state)) - { - return; - } - } - inline bool checkErrorAndThrow(int status, lua_State *state) - { - if (status != 0 && status != LUA_YIELD) - { - ErrorHandler::handle(status, state); - - return false; - } - return true; - } - } + default: + throw LuaUnknownError(status, message ? std::string(message) + : "lua unknown error"); + } + } + +private: + static void *handlerRegistryKey() { + static void *key; + return key; + } + static function_type *getFunctionPointer(lua_State *state) { + if (state) { + util::ScopedSavedStack save(state); + lua_pushlightuserdata(state, handlerRegistryKey()); + lua_rawget(state, LUA_REGISTRYINDEX); + function_type *ptr = (function_type *)lua_touserdata(state, -1); + return ptr; + } + return 0; + } + + ErrorHandler() {} + + ErrorHandler(const ErrorHandler &); + ErrorHandler &operator=(const ErrorHandler &); + + static int error_handler_cleanner(lua_State *state) { + function_type *ptr = (function_type *)lua_touserdata(state, 1); + ptr->~function_type(); + return 0; + } +}; + +namespace except { +inline void OtherError(lua_State *state, const std::string &message) { + if (ErrorHandler::handle(message.c_str(), state)) { + return; + } +} +inline void typeMismatchError(lua_State *state, const std::string &message) { + if (ErrorHandler::handle(message.c_str(), state)) { + return; + } +} +inline void memoryError(lua_State *state, const char *message) { + if (ErrorHandler::handle(message, state)) { + return; + } +} +inline bool checkErrorAndThrow(int status, lua_State *state) { + if (status != 0 && status != LUA_YIELD) { + ErrorHandler::handle(status, state); + + return false; + } + return true; +} +} } diff --git a/include/kaguya/exception.hpp b/include/kaguya/exception.hpp index be508f4..a175a23 100644 --- a/include/kaguya/exception.hpp +++ b/include/kaguya/exception.hpp @@ -8,77 +8,85 @@ #include #include +namespace kaguya { +class LuaException : public std::exception { + int status_; + std::string what_; + const char *what_c_; +public: + LuaException(int status, const char *what) throw() + : status_(status), what_c_(what) {} + LuaException(int status, const std::string &what) + : status_(status), what_(what), what_c_(0) {} + int status() const throw() { return status_; } + const char *what() const throw() { return what_c_ ? what_c_ : what_.c_str(); } + ~LuaException() throw() {} +}; +class KaguyaException : public std::exception { + std::string what_; + const char *what_c_; -namespace kaguya -{ - class LuaException :public std::exception - { - int status_; - std::string what_; - const char* what_c_; - public: - LuaException(int status, const char* what)throw() :status_(status), what_c_(what) {} - LuaException(int status, const std::string& what) :status_(status), what_(what), what_c_(0) {} - int status()const throw() { return status_; } - const char* what() const throw() { return what_c_ ? what_c_ : what_.c_str(); } +public: + KaguyaException(const char *what) throw() : what_c_(what) {} + KaguyaException(const std::string &what) : what_(what), what_c_(0) {} + const char *what() const throw() { return what_c_ ? what_c_ : what_.c_str(); } - ~LuaException()throw() {} - }; - class KaguyaException :public std::exception - { - std::string what_; - const char* what_c_; - public: - KaguyaException(const char* what)throw() : what_c_(what) {} - KaguyaException(const std::string& what) : what_(what), what_c_(0) {} - const char* what() const throw() { return what_c_ ? what_c_ : what_.c_str(); } + ~KaguyaException() throw() {} +}; +class LuaTypeMismatch : public LuaException { +public: + LuaTypeMismatch() throw() : LuaException(0, "type mismatch!!") {} + LuaTypeMismatch(const char *what) throw() : LuaException(0, what) {} + LuaTypeMismatch(const std::string &what) : LuaException(0, what) {} +}; +class LuaMemoryError : public LuaException { +public: + LuaMemoryError(int status, const char *what) throw() + : LuaException(status, what) {} + LuaMemoryError(int status, const std::string &what) + : LuaException(status, what) {} +}; +class LuaRuntimeError : public LuaException { +public: + LuaRuntimeError(int status, const char *what) throw() + : LuaException(status, what) {} + LuaRuntimeError(int status, const std::string &what) + : LuaException(status, what) {} +}; +class LuaErrorRunningError : public LuaException { +public: + LuaErrorRunningError(int status, const char *what) throw() + : LuaException(status, what) {} + LuaErrorRunningError(int status, const std::string &what) + : LuaException(status, what) {} +}; +class LuaGCError : public LuaException { +public: + LuaGCError(int status, const char *what) throw() + : LuaException(status, what) {} + LuaGCError(int status, const std::string &what) + : LuaException(status, what) {} +}; +class LuaUnknownError : public LuaException { +public: + LuaUnknownError(int status, const char *what) throw() + : LuaException(status, what) {} + LuaUnknownError(int status, const std::string &what) + : LuaException(status, what) {} +}; - ~KaguyaException()throw() {} - }; - class LuaTypeMismatch :public LuaException { - public: - LuaTypeMismatch()throw():LuaException(0, "type mismatch!!") {} - LuaTypeMismatch(const char* what)throw() :LuaException(0, what) {} - LuaTypeMismatch(const std::string& what) :LuaException(0, what) {} - }; - class LuaMemoryError :public LuaException { - public: - LuaMemoryError(int status, const char* what)throw() :LuaException(status, what) {} - LuaMemoryError(int status, const std::string& what) :LuaException(status, what) {} - }; - class LuaRuntimeError :public LuaException { - public: - LuaRuntimeError(int status, const char* what)throw() :LuaException(status, what) {} - LuaRuntimeError(int status, const std::string& what) :LuaException(status, what) {} - }; - class LuaErrorRunningError :public LuaException { - public: - LuaErrorRunningError(int status, const char* what)throw() :LuaException(status, what) {} - LuaErrorRunningError(int status, const std::string& what) :LuaException(status, what) {} - }; - class LuaGCError :public LuaException { - public: - LuaGCError(int status, const char* what)throw() :LuaException(status, what) {} - LuaGCError(int status, const std::string& what) :LuaException(status, what) {} - }; - class LuaUnknownError :public LuaException { - public: - LuaUnknownError(int status, const char* what)throw() :LuaException(status, what) {} - LuaUnknownError(int status, const std::string& what) :LuaException(status, what) {} - }; +class LuaSyntaxError : public LuaException { +public: + LuaSyntaxError(int status, const std::string &what) + : LuaException(status, what) {} +}; - class LuaSyntaxError :public LuaException { - public: - LuaSyntaxError(int status, const std::string& what) :LuaException(status, what) {} - }; - - namespace except - { - void OtherError(lua_State *state, const std::string& message); - void typeMismatchError(lua_State *state, const std::string& message); - void memoryError(lua_State *state, const char* message); - bool checkErrorAndThrow(int status, lua_State *state); - } +namespace except { +void OtherError(lua_State *state, const std::string &message); +void typeMismatchError(lua_State *state, const std::string &message); +void memoryError(lua_State *state, const char *message); +bool checkErrorAndThrow(int status, lua_State *state); +} } diff --git a/include/kaguya/function_tuple_def.hpp b/include/kaguya/function_tuple_def.hpp index ab52303..13b86ef 100644 --- a/include/kaguya/function_tuple_def.hpp +++ b/include/kaguya/function_tuple_def.hpp @@ -10,102 +10,95 @@ #include "kaguya/utility.hpp" #include "kaguya/preprocess.hpp" -namespace kaguya -{ - namespace fntuple - { +namespace kaguya { +namespace fntuple { #if KAGUYA_USE_CPP11 && !defined(KAGUYA_FUNCTION_MAX_OVERLOADS) - // In Clang with libstdc++. - // std::tuple elements is limited to 16 for template depth limit - using std::tuple; - using std::get; - using std::tuple_element; - using std::tuple_size; +// In Clang with libstdc++. +// std::tuple elements is limited to 16 for template depth limit +using std::tuple; +using std::get; +using std::tuple_element; +using std::tuple_size; #else - using util::null_type; - //boost::tuple is max -#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(typename A,N) = null_type -#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_PP_STRUCT_TDEF_REP) - - template - struct tuple { - }; +using util::null_type; +// boost::tuple is max +#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(typename A, N) = null_type +#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_STRUCT_TDEF_REP) + +template +struct tuple {}; #undef KAGUYA_PP_STRUCT_TDEF_REP #undef KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT -#define KAGUYA_FUNCTION_TUPLE_ELEMENT(N) KAGUYA_PP_CAT(A,N) KAGUYA_PP_CAT(elem,N); -#define KAGUYA_FUNCTION_TUPLE_ELEMENT_INIT(N) KAGUYA_PP_CAT(elem,N)(KAGUYA_PP_CAT(a,N)) -#define KAGUYA_FUNCTION_TUPLE_IMPL_DEF(N) \ - template\ - struct tuple {\ - KAGUYA_PP_REPEAT(N,KAGUYA_FUNCTION_TUPLE_ELEMENT)\ - tuple(KAGUYA_PP_ARG_DEF_REPEAT(N)):KAGUYA_PP_REPEAT_ARG(N,KAGUYA_FUNCTION_TUPLE_ELEMENT_INIT){}\ - }; - - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_FUNCTION_TUPLE_IMPL_DEF) - - templatestruct tuple_size; - -#define KAGUYA_TUPLE_SIZE_DEF(N) \ - template< KAGUYA_PP_TEMPLATE_DEF_REPEAT(N)>\ - struct tuple_size >\ - {\ - static const size_t value = N;\ - };\ - - KAGUYA_TUPLE_SIZE_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_SIZE_DEF) +#define KAGUYA_FUNCTION_TUPLE_ELEMENT(N) \ + KAGUYA_PP_CAT(A, N) KAGUYA_PP_CAT(elem, N); +#define KAGUYA_FUNCTION_TUPLE_ELEMENT_INIT(N) \ + KAGUYA_PP_CAT(elem, N)(KAGUYA_PP_CAT(a, N)) +#define KAGUYA_FUNCTION_TUPLE_IMPL_DEF(N) \ + template \ + struct tuple { \ + KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_TUPLE_ELEMENT) \ + tuple(KAGUYA_PP_ARG_DEF_REPEAT(N)) \ + : KAGUYA_PP_REPEAT_ARG(N, KAGUYA_FUNCTION_TUPLE_ELEMENT_INIT) {} \ + }; + +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, + KAGUYA_FUNCTION_TUPLE_IMPL_DEF) + +template struct tuple_size; + +#define KAGUYA_TUPLE_SIZE_DEF(N) \ + template \ + struct tuple_size > { \ + static const size_t value = N; \ + }; + +KAGUYA_TUPLE_SIZE_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_SIZE_DEF) #undef KAGUYA_TUPLE_SIZE_DEF - - template - struct tuple_element - { - }; -#define KAGUYA_TUPLE_ELEMENT_DEF(N) \ - template\ - struct tuple_element, true>\ - {\ - typedef arg type;\ - };\ - template\ - struct tuple_element, false>\ - : tuple_element >\ - {\ - };\ - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_ELEMENT_DEF) +template +struct tuple_element {}; +#define KAGUYA_TUPLE_ELEMENT_DEF(N) \ + template \ + struct tuple_element< \ + remain, tuple, true> { \ + typedef arg type; \ + }; \ + template \ + struct tuple_element< \ + remain, tuple, false> \ + : tuple_element > { \ + }; + +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_ELEMENT_DEF) #undef KAGUYA_TUPLE_SIZE_DEF - templatestruct tuple_get_helper; -#define KAGUYA_TUPLE_GET_DEF(N) \ - templatestruct tuple_get_helper\ - {\ - static typename tuple_element::type& get(T& t)\ - {\ - return t.KAGUYA_PP_CAT(elem, N); \ - }\ - static const typename tuple_element::type& cget(const T& t)\ - {\ - return t.KAGUYA_PP_CAT(elem, N); \ - }\ - }; - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_GET_DEF) - - template - typename tuple_element::type& get(T& t) - { - return tuple_get_helper::get(t); - } - template - const typename tuple_element::type& get(const T& t) - { - return tuple_get_helper::cget(t); - } +template struct tuple_get_helper; +#define KAGUYA_TUPLE_GET_DEF(N) \ + template struct tuple_get_helper { \ + static typename tuple_element::type &get(T &t) { \ + return t.KAGUYA_PP_CAT(elem, N); \ + } \ + static const typename tuple_element::type &cget(const T &t) { \ + return t.KAGUYA_PP_CAT(elem, N); \ + } \ + }; +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_GET_DEF) + +template typename tuple_element::type &get(T &t) { + return tuple_get_helper::get(t); +} +template +const typename tuple_element::type &get(const T &t) { + return tuple_get_helper::cget(t); +} #endif - } - +} } diff --git a/include/kaguya/kaguya.hpp b/include/kaguya/kaguya.hpp index 4a6a953..29b269f 100644 --- a/include/kaguya/kaguya.hpp +++ b/include/kaguya/kaguya.hpp @@ -6,13 +6,9 @@ #pragma once #include "kaguya/config.hpp" - #include "kaguya/lua_ref.hpp" #include "kaguya/native_function.hpp" - #include "kaguya/state.hpp" - #include "kaguya/lua_ref_table.hpp" #include "kaguya/lua_ref_function.hpp" #include "kaguya/ref_tuple.hpp" - diff --git a/include/kaguya/lua_ref.hpp b/include/kaguya/lua_ref.hpp index ecd2371..1dd8f4f 100644 --- a/include/kaguya/lua_ref.hpp +++ b/include/kaguya/lua_ref.hpp @@ -11,685 +11,575 @@ #include #include #include + #include "kaguya/config.hpp" #include "kaguya/error_handler.hpp" #include "kaguya/type.hpp" #include "kaguya/utility.hpp" - #include "kaguya/detail/lua_ref_impl.hpp" #include "kaguya/detail/lua_variant_def.hpp" -namespace kaguya -{ - namespace util - { - template - inline Result get_result_impl(lua_State* l, int startindex, types::typetag) - { - return lua_type_traits::get(l, startindex); - } +namespace kaguya { +namespace util { +template +inline Result get_result_impl(lua_State *l, int startindex, + types::typetag) { + return lua_type_traits::get(l, startindex); +} #if KAGUYA_USE_CPP11 - inline standard::tuple<> get_result_tuple_impl(lua_State* , int , types::typetag > ) - { - return standard::tuple<>(); - } - template - inline standard::tuple get_result_tuple_impl(lua_State* l, int index, types::typetag > ) - { - return standard::tuple_cat(standard::tuple(lua_type_traits::get(l, index)), - get_result_tuple_impl(l, index + 1, types::typetag >())); - } - template - inline standard::tuple get_result_impl(lua_State* l, int startindex, types::typetag > tag) - { - return get_result_tuple_impl(l, startindex, tag); - } +inline standard::tuple<> +get_result_tuple_impl(lua_State *, int, types::typetag >) { + return standard::tuple<>(); +} +template +inline standard::tuple +get_result_tuple_impl(lua_State *l, int index, + types::typetag >) { + return standard::tuple_cat( + standard::tuple(lua_type_traits::get(l, index)), + get_result_tuple_impl(l, index + 1, + types::typetag >())); +} +template +inline standard::tuple +get_result_impl(lua_State *l, int startindex, + types::typetag > tag) { + return get_result_tuple_impl(l, startindex, tag); +} #else - inline standard::tuple<> get_result_impl(lua_State *l, int startindex, types::typetag > ) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(startindex); - return standard::tuple<>(); - } - -#define KAGUYA_GET_DEF(N) lua_type_traits::get(l, N + startindex - 1) -#define KAGUYA_GET_TUPLE_DEF(N) template\ - inline standard::tuple get_result_impl(lua_State *l,int startindex,types::typetag >)\ - {\ - return standard::tuple(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_GET_DEF));\ - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_TUPLE_SIZE, KAGUYA_GET_TUPLE_DEF) +inline standard::tuple<> get_result_impl(lua_State *l, int startindex, + types::typetag >) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(startindex); + return standard::tuple<>(); +} + +#define KAGUYA_GET_DEF(N) \ + lua_type_traits::get(l, N + startindex - 1) +#define KAGUYA_GET_TUPLE_DEF(N) \ + template \ + inline standard::tuple get_result_impl( \ + lua_State *l, int startindex, \ + types::typetag >) { \ + return standard::tuple( \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_GET_DEF)); \ + } +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_TUPLE_SIZE, KAGUYA_GET_TUPLE_DEF) #undef KAGUYA_GET_DEF #undef KAGUYA_GET_TUPLE_DEF #endif - template - inline Result get_result(lua_State* l, int startindex) - { - return get_result_impl(l, startindex, types::typetag()); - } - template<> - inline void get_result(lua_State* , int ) - { - } - } - - /// @addtogroup Lua_reference_types - - /// @ingroup Lua_reference_types - /// @brief Reference to any Lua data. - class LuaRef :public Ref::RegistoryRef, public detail::LuaVariantImpl - { - private: - static lua_State* toMainThread(lua_State* state) - { +template inline Result get_result(lua_State *l, int startindex) { + return get_result_impl(l, startindex, types::typetag()); +} +template <> inline void get_result(lua_State *, int) {} +} + +/// @addtogroup Lua_reference_types + +/// @ingroup Lua_reference_types +/// @brief Reference to any Lua data. +class LuaRef : public Ref::RegistoryRef, public detail::LuaVariantImpl { +private: + static lua_State *toMainThread(lua_State *state) { #if LUA_VERSION_NUM >= 502 - if (state) - { - lua_rawgeti(state, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); - lua_State* mainthread = lua_tothread(state, -1); - lua_pop(state, 1); - if (mainthread) - { - return mainthread; - } - } + if (state) { + lua_rawgeti(state, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); + lua_State *mainthread = lua_tothread(state, -1); + lua_pop(state, 1); + if (mainthread) { + return mainthread; + } + } #endif - return state; - } - public: - - - LuaRef(const Ref::RegistoryRef& src) :Ref::RegistoryRef(src) - { - } - LuaRef(const LuaRef& src) :Ref::RegistoryRef(src) - { - } - LuaRef& operator =(const LuaRef& src) - { - static_cast(*this) = src; - return *this; - } + return state; + } + +public: + LuaRef(const Ref::RegistoryRef &src) : Ref::RegistoryRef(src) {} + LuaRef(const LuaRef &src) : Ref::RegistoryRef(src) {} + LuaRef &operator=(const LuaRef &src) { + static_cast(*this) = src; + return *this; + } #if KAGUYA_USE_CPP11 - LuaRef(LuaRef&& src) :Ref::RegistoryRef(std::move(src)) {} + LuaRef(LuaRef &&src) : Ref::RegistoryRef(std::move(src)) {} - LuaRef& operator =(LuaRef&& src)throw() - { - swap(src); - return *this; - } + LuaRef &operator=(LuaRef &&src) throw() { + swap(src); + return *this; + } - LuaRef(RegistoryRef&& src)throw() :Ref::RegistoryRef(std::move(src)) {} - template - LuaRef(lua_State* state, T&& v, Ref::NoMainCheck) : Ref::RegistoryRef(state, std::move(v), Ref::NoMainCheck()) {} - template - LuaRef(lua_State* state, T&& v) : Ref::RegistoryRef(state, std::move(v)) {} + LuaRef(RegistoryRef &&src) throw() : Ref::RegistoryRef(std::move(src)) {} + template + LuaRef(lua_State *state, T &&v, Ref::NoMainCheck) + : Ref::RegistoryRef(state, std::move(v), Ref::NoMainCheck()) {} + template + LuaRef(lua_State *state, T &&v) : Ref::RegistoryRef(state, std::move(v)) {} #endif - LuaRef() {} - LuaRef(lua_State* state) :Ref::RegistoryRef(state) {} - - LuaRef(lua_State* state, StackTop, Ref::NoMainCheck) :Ref::RegistoryRef(state, StackTop(), Ref::NoMainCheck()) {} - - LuaRef(lua_State* state, StackTop) :Ref::RegistoryRef(state, StackTop()) - { - } - - - template - LuaRef(lua_State* state, const T& v, Ref::NoMainCheck) : Ref::RegistoryRef(state, v, Ref::NoMainCheck()) {} - template - LuaRef(lua_State* state, const T& v) : Ref::RegistoryRef(state, v) {} - - - const void* native_pointer()const - { - util::ScopedSavedStack save(state()); - push(state()); - return lua_topointer(state(), -1); - } - static void putindent(std::ostream& os, int indent) - { - while (indent-- > 0) - { - os << " "; - } - } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaRef - template<> - struct lua_type_traits - { - typedef LuaRef get_type; - typedef const LuaRef& push_type; - - static bool checkType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return true; - } - static bool strictCheckType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return false; - } - - static get_type get(lua_State* l, int index) - { - lua_pushvalue(l, index); - return LuaRef(l, StackTop()); - } - static int push(lua_State* l, push_type v) - { - return v.push(l); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaRef - template<> struct lua_type_traits :lua_type_traits {}; - - - - - class LuaStackRef :public Ref::StackRef, public detail::LuaVariantImpl - { - public: - LuaStackRef() :Ref::StackRef() - { - } - LuaStackRef(lua_State* s, int index) :Ref::StackRef(s, index, false) - { - } - LuaStackRef(lua_State* s, int index, bool popAtDestruct) :Ref::StackRef(s, index, popAtDestruct) - { - } + LuaRef() {} + LuaRef(lua_State *state) : Ref::RegistoryRef(state) {} + + LuaRef(lua_State *state, StackTop, Ref::NoMainCheck) + : Ref::RegistoryRef(state, StackTop(), Ref::NoMainCheck()) {} + + LuaRef(lua_State *state, StackTop) : Ref::RegistoryRef(state, StackTop()) {} + + template + LuaRef(lua_State *state, const T &v, Ref::NoMainCheck) + : Ref::RegistoryRef(state, v, Ref::NoMainCheck()) {} + template + LuaRef(lua_State *state, const T &v) : Ref::RegistoryRef(state, v) {} + + const void *native_pointer() const { + util::ScopedSavedStack save(state()); + push(state()); + return lua_topointer(state(), -1); + } + static void putindent(std::ostream &os, int indent) { + while (indent-- > 0) { + os << " "; + } + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaRef +template <> struct lua_type_traits { + typedef LuaRef get_type; + typedef const LuaRef &push_type; + + static bool checkType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return true; + } + static bool strictCheckType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return false; + } + + static get_type get(lua_State *l, int index) { + lua_pushvalue(l, index); + return LuaRef(l, StackTop()); + } + static int push(lua_State *l, push_type v) { return v.push(l); } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaRef +template <> struct lua_type_traits : lua_type_traits {}; + +class LuaStackRef : public Ref::StackRef, + public detail::LuaVariantImpl { +public: + LuaStackRef() : Ref::StackRef() {} + LuaStackRef(lua_State *s, int index) : Ref::StackRef(s, index, false) {} + LuaStackRef(lua_State *s, int index, bool popAtDestruct) + : Ref::StackRef(s, index, popAtDestruct) {} #if KAGUYA_USE_CPP11 - LuaStackRef(LuaStackRef&& src) : Ref::StackRef(std::move(src)) - { - src.pop_ = false; - } - LuaStackRef& operator=(LuaStackRef&& src) - { - if (this != &src) - { - Ref::StackRef::operator=(std::move(src)); - src.pop_ = false; - } - return *this; - } - LuaStackRef(const LuaStackRef&src) = delete; + LuaStackRef(LuaStackRef &&src) : Ref::StackRef(std::move(src)) { + src.pop_ = false; + } + LuaStackRef &operator=(LuaStackRef &&src) { + if (this != &src) { + Ref::StackRef::operator=(std::move(src)); + src.pop_ = false; + } + return *this; + } + LuaStackRef(const LuaStackRef &src) = delete; #else - LuaStackRef(const LuaStackRef&src) : Ref::StackRef(src) - { - src.pop_ = false; - } - LuaStackRef& operator=(const LuaStackRef&src) - { - if (this != &src) - { - Ref::StackRef::operator=(src); - src.pop_ = false; - } - return *this; - } + LuaStackRef(const LuaStackRef &src) : Ref::StackRef(src) { src.pop_ = false; } + LuaStackRef &operator=(const LuaStackRef &src) { + if (this != &src) { + Ref::StackRef::operator=(src); + src.pop_ = false; + } + return *this; + } #endif - }; - - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaStackRef - template<> - struct lua_type_traits - { - typedef LuaStackRef get_type; - typedef const LuaStackRef& push_type; - - static bool checkType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return true; - } - static bool strictCheckType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return false; - } - - static get_type get(lua_State* l, int index) - { - return LuaStackRef(l, index); - } - static int push(lua_State* l, push_type v) - { - return v.push(l); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaStackRef - template<> struct lua_type_traits :lua_type_traits {}; - - /// @ingroup Lua_reference_types - /// @brief Reference to Lua userdata. - class LuaUserData :public Ref::RegistoryRef - , public detail::LuaUserDataImpl - , public detail::LuaTableOrUserDataImpl - , public detail::LuaBasicTypeFunctions - { - - void typecheck() - { - int t = type(); - if (t != TYPE_USERDATA && t != TYPE_LIGHTUSERDATA &&t != TYPE_NIL && t != TYPE_NONE) - { - except::typeMismatchError(state(), "not user data"); - unref(); - } - } - public: - operator LuaRef() { - push(state()); - return LuaRef(state(), StackTop()); - } - LuaUserData(lua_State* state, StackTop) :Ref::RegistoryRef(state, StackTop()) - { - typecheck(); - } - template - LuaUserData(lua_State* state, const TYPE& table) : Ref::RegistoryRef(state, table) - { - typecheck(); - } - explicit LuaUserData(lua_State* state) :Ref::RegistoryRef(state, NilValue()) - { - typecheck(); - } - LuaUserData() - { - typecheck(); - } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaUserData - template<> struct lua_type_traits { - typedef LuaUserData get_type; - typedef LuaUserData push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TUSERDATA; - } - static bool checkType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TUSERDATA || lua_isnil(l, index); - } - static LuaUserData get(lua_State* l, int index) - { - lua_pushvalue(l, index); - return LuaUserData(l, StackTop()); - } - static int push(lua_State* l, const LuaUserData& ref) - { - return ref.push(l); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaUserData - template<> struct lua_type_traits :lua_type_traits {}; - - - /// @ingroup Lua_reference_types - /// @brief Reference to Lua table. - class LuaTable :public Ref::RegistoryRef - , public detail::LuaTableImpl - , public detail::LuaTableOrUserDataImpl - , public detail::LuaBasicTypeFunctions - { - - void typecheck() - { - int t = type(); - if (t != TYPE_TABLE && t != TYPE_NIL && t != TYPE_NONE) - { - except::typeMismatchError(state(), "not table"); - unref(); - } - } - public: - operator LuaRef() { - push(state()); - return LuaRef(state(), StackTop()); - } - LuaTable(lua_State* state, StackTop) :Ref::RegistoryRef(state, StackTop()) - { - typecheck(); - } - LuaTable(lua_State* state, const NewTable& table) :Ref::RegistoryRef(state, table) - { - typecheck(); - } - explicit LuaTable(lua_State* state) :Ref::RegistoryRef(state, NewTable()) - { - typecheck(); - } - LuaTable() - { - typecheck(); - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaTable - template<> struct lua_type_traits { - typedef LuaTable get_type; - typedef LuaTable push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_istable(l, index); - } - static bool checkType(lua_State* l, int index) - { - return lua_istable(l, index) || lua_isnil(l, index); - } - static LuaTable get(lua_State* l, int index) - { - lua_pushvalue(l, index); - return LuaTable(l, StackTop()); - } - static int push(lua_State* l, const LuaTable& ref) - { - return ref.push(l); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaTable - template<> struct lua_type_traits :lua_type_traits {}; - - /// @ingroup Lua_reference_types - /// @brief Reference to Lua function. - class LuaFunction :public Ref::RegistoryRef - , public detail::LuaFunctionImpl - , public detail::LuaBasicTypeFunctions - { - void typecheck() - { - int t = type(); - if (t != TYPE_FUNCTION && t != TYPE_NIL && t != TYPE_NONE) - { - except::typeMismatchError(state(), "not function"); - RegistoryRef::unref(); - } - } - - struct LuaLoadStreamWrapper - { - LuaLoadStreamWrapper(std::istream& stream) :preloaded_(false), stream_(stream) - { - buffer_.reserve(512); - skipComment(); - preloaded_ = !buffer_.empty(); - } - - void skipComment() - { - //skip bom - const char* bom = "\xEF\xBB\xBF"; - const char* bomseq = bom; - char c; - while (stream_.get(c)) - { - if (c != *bomseq)// not bom sequence - { - buffer_.assign(bom, bomseq); - buffer_.push_back(c); - break; - } - bomseq++; - if ('\0' == *bomseq) - { - return; - } - } - - //skip comment - if (!buffer_.empty() && buffer_.front() == '#') - { - buffer_.clear(); - std::string comment; - std::getline(stream_, comment); - } - } - - - static const char *getdata(lua_State *, void *ud, size_t *size) { - LuaLoadStreamWrapper *loader = static_cast(ud); - - if (loader->preloaded_) - { - loader->preloaded_ = false; - } - else - { - loader->buffer_.clear(); - } - - char c = 0; - while (loader->buffer_.size() < loader->buffer_.capacity() && loader->stream_.get(c)) - { - loader->buffer_.push_back(c); - } - *size = loader->buffer_.size(); - return loader->buffer_.empty() ? 0 : &loader->buffer_[0]; - } - private: - bool preloaded_; - std::vector buffer_; - std::istream& stream_; - }; - public: - - /// @brief construct with state and function . - /// @param state pointer to lua_State - /// @param f execute function for lua thread. e.g. kaguya::function(function_ptr),kaguya::overload(function_ptr) - template - LuaFunction(lua_State* state, F f) :Ref::RegistoryRef(state, f) - { - typecheck(); - } - - /// @brief construct with stack top value. - /// @param state pointer to lua_State - LuaFunction(lua_State* state, StackTop) :Ref::RegistoryRef(state, StackTop()) - { - typecheck(); - } - - /// @brief construct with nil reference. - LuaFunction() - { - } - - /// @brief load lua code . - /// @param state pointer to lua_State - /// @param luacode string - static LuaFunction loadstring(lua_State* state, const std::string& luacode) - { - return loadstring(state, luacode.c_str()); - } - /// @brief load lua code . - /// @param state pointer to lua_State - /// @param luacode string - static LuaFunction loadstring(lua_State* state, const char* luacode) - { - util::ScopedSavedStack save(state); - int status = luaL_loadstring(state, luacode); - - if (status) - { - ErrorHandler::handle(status, state); - lua_pushnil(state); - } - return LuaFunction(state, StackTop()); - } - - - /// @brief If there are no errors,compiled file as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param state pointer to lua_State - /// @param file file path of lua script - /// @return reference of lua function - static LuaFunction loadfile(lua_State* state, const std::string& file) - { - return loadfile(state, file.c_str()); - } - - /// @brief If there are no errors,compiled file as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param state pointer to lua_State - /// @param file file path of lua script - /// @return reference of lua function - static LuaFunction loadfile(lua_State* state, const char* file) - { - util::ScopedSavedStack save(state); - - int status = luaL_loadfile(state, file); - - if (status) - { - ErrorHandler::handle(status, state); - lua_pushnil(state); - } - return LuaFunction(state, StackTop()); - } - - /// @brief If there are no errors,compiled stream as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param state pointer to lua_State - /// @param stream stream of lua script data - /// @param chunkname use for error message. - /// @return reference of lua function - static LuaStackRef loadstreamtostack(lua_State* state, std::istream& stream, const char* chunkname = 0) - { - LuaLoadStreamWrapper wrapper(stream); +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaStackRef +template <> struct lua_type_traits { + typedef LuaStackRef get_type; + typedef const LuaStackRef &push_type; + + static bool checkType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return true; + } + static bool strictCheckType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return false; + } + + static get_type get(lua_State *l, int index) { return LuaStackRef(l, index); } + static int push(lua_State *l, push_type v) { return v.push(l); } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaStackRef +template <> +struct lua_type_traits : lua_type_traits {}; + +/// @ingroup Lua_reference_types +/// @brief Reference to Lua userdata. +class LuaUserData : public Ref::RegistoryRef, + public detail::LuaUserDataImpl, + public detail::LuaTableOrUserDataImpl, + public detail::LuaBasicTypeFunctions { + + void typecheck() { + int t = type(); + if (t != TYPE_USERDATA && t != TYPE_LIGHTUSERDATA && t != TYPE_NIL && + t != TYPE_NONE) { + except::typeMismatchError(state(), "not user data"); + unref(); + } + } + +public: + operator LuaRef() { + push(state()); + return LuaRef(state(), StackTop()); + } + LuaUserData(lua_State *state, StackTop) + : Ref::RegistoryRef(state, StackTop()) { + typecheck(); + } + template + LuaUserData(lua_State *state, const TYPE &table) + : Ref::RegistoryRef(state, table) { + typecheck(); + } + explicit LuaUserData(lua_State *state) + : Ref::RegistoryRef(state, NilValue()) { + typecheck(); + } + LuaUserData() { typecheck(); } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaUserData +template <> struct lua_type_traits { + typedef LuaUserData get_type; + typedef LuaUserData push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TUSERDATA; + } + static bool checkType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TUSERDATA || lua_isnil(l, index); + } + static LuaUserData get(lua_State *l, int index) { + lua_pushvalue(l, index); + return LuaUserData(l, StackTop()); + } + static int push(lua_State *l, const LuaUserData &ref) { return ref.push(l); } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaUserData +template <> +struct lua_type_traits : lua_type_traits {}; + +/// @ingroup Lua_reference_types +/// @brief Reference to Lua table. +class LuaTable : public Ref::RegistoryRef, + public detail::LuaTableImpl, + public detail::LuaTableOrUserDataImpl, + public detail::LuaBasicTypeFunctions { + + void typecheck() { + int t = type(); + if (t != TYPE_TABLE && t != TYPE_NIL && t != TYPE_NONE) { + except::typeMismatchError(state(), "not table"); + unref(); + } + } + +public: + operator LuaRef() { + push(state()); + return LuaRef(state(), StackTop()); + } + LuaTable(lua_State *state, StackTop) : Ref::RegistoryRef(state, StackTop()) { + typecheck(); + } + LuaTable(lua_State *state, const NewTable &table) + : Ref::RegistoryRef(state, table) { + typecheck(); + } + explicit LuaTable(lua_State *state) : Ref::RegistoryRef(state, NewTable()) { + typecheck(); + } + LuaTable() { typecheck(); } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaTable +template <> struct lua_type_traits { + typedef LuaTable get_type; + typedef LuaTable push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_istable(l, index); + } + static bool checkType(lua_State *l, int index) { + return lua_istable(l, index) || lua_isnil(l, index); + } + static LuaTable get(lua_State *l, int index) { + lua_pushvalue(l, index); + return LuaTable(l, StackTop()); + } + static int push(lua_State *l, const LuaTable &ref) { return ref.push(l); } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaTable +template <> +struct lua_type_traits : lua_type_traits {}; + +/// @ingroup Lua_reference_types +/// @brief Reference to Lua function. +class LuaFunction : public Ref::RegistoryRef, + public detail::LuaFunctionImpl, + public detail::LuaBasicTypeFunctions { + void typecheck() { + int t = type(); + if (t != TYPE_FUNCTION && t != TYPE_NIL && t != TYPE_NONE) { + except::typeMismatchError(state(), "not function"); + RegistoryRef::unref(); + } + } + + struct LuaLoadStreamWrapper { + LuaLoadStreamWrapper(std::istream &stream) + : preloaded_(false), stream_(stream) { + buffer_.reserve(512); + skipComment(); + preloaded_ = !buffer_.empty(); + } + + void skipComment() { + // skip bom + const char *bom = "\xEF\xBB\xBF"; + const char *bomseq = bom; + char c; + while (stream_.get(c)) { + if (c != *bomseq) // not bom sequence + { + buffer_.assign(bom, bomseq); + buffer_.push_back(c); + break; + } + bomseq++; + if ('\0' == *bomseq) { + return; + } + } + + // skip comment + if (!buffer_.empty() && buffer_.front() == '#') { + buffer_.clear(); + std::string comment; + std::getline(stream_, comment); + } + } + + static const char *getdata(lua_State *, void *ud, size_t *size) { + LuaLoadStreamWrapper *loader = static_cast(ud); + + if (loader->preloaded_) { + loader->preloaded_ = false; + } else { + loader->buffer_.clear(); + } + + char c = 0; + while (loader->buffer_.size() < loader->buffer_.capacity() && + loader->stream_.get(c)) { + loader->buffer_.push_back(c); + } + *size = loader->buffer_.size(); + return loader->buffer_.empty() ? 0 : &loader->buffer_[0]; + } + + private: + bool preloaded_; + std::vector buffer_; + std::istream &stream_; + }; + +public: + /// @brief construct with state and function . + /// @param state pointer to lua_State + /// @param f execute function for lua thread. e.g. + /// kaguya::function(function_ptr),kaguya::overload(function_ptr) + template + LuaFunction(lua_State *state, F f) : Ref::RegistoryRef(state, f) { + typecheck(); + } + + /// @brief construct with stack top value. + /// @param state pointer to lua_State + LuaFunction(lua_State *state, StackTop) + : Ref::RegistoryRef(state, StackTop()) { + typecheck(); + } + + /// @brief construct with nil reference. + LuaFunction() {} + + /// @brief load lua code . + /// @param state pointer to lua_State + /// @param luacode string + static LuaFunction loadstring(lua_State *state, const std::string &luacode) { + return loadstring(state, luacode.c_str()); + } + /// @brief load lua code . + /// @param state pointer to lua_State + /// @param luacode string + static LuaFunction loadstring(lua_State *state, const char *luacode) { + util::ScopedSavedStack save(state); + int status = luaL_loadstring(state, luacode); + + if (status) { + ErrorHandler::handle(status, state); + lua_pushnil(state); + } + return LuaFunction(state, StackTop()); + } + + /// @brief If there are no errors,compiled file as a Lua function and return. + /// Otherwise send error message to error handler and return nil reference + /// @param state pointer to lua_State + /// @param file file path of lua script + /// @return reference of lua function + static LuaFunction loadfile(lua_State *state, const std::string &file) { + return loadfile(state, file.c_str()); + } + + /// @brief If there are no errors,compiled file as a Lua function and return. + /// Otherwise send error message to error handler and return nil reference + /// @param state pointer to lua_State + /// @param file file path of lua script + /// @return reference of lua function + static LuaFunction loadfile(lua_State *state, const char *file) { + util::ScopedSavedStack save(state); + + int status = luaL_loadfile(state, file); + + if (status) { + ErrorHandler::handle(status, state); + lua_pushnil(state); + } + return LuaFunction(state, StackTop()); + } + + /// @brief If there are no errors,compiled stream as a Lua function and + /// return. + /// Otherwise send error message to error handler and return nil reference + /// @param state pointer to lua_State + /// @param stream stream of lua script data + /// @param chunkname use for error message. + /// @return reference of lua function + static LuaStackRef loadstreamtostack(lua_State *state, std::istream &stream, + const char *chunkname = 0) { + LuaLoadStreamWrapper wrapper(stream); #if LUA_VERSION_NUM >= 502 - int status = lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname, 0); + int status = + lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname, 0); #else - int status = lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname); + int status = + lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname); #endif - if (status) - { - ErrorHandler::handle(status, state); - lua_pushnil(state); - } - return LuaStackRef(state, -1, true); - } - - /// @brief If there are no errors,compiled stream as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param state pointer to lua_State - /// @param stream stream of lua script data - /// @param chunkname use for error message. - /// @return reference of lua function - static LuaFunction loadstream(lua_State* state, std::istream& stream, const char* chunkname = 0) - { - util::ScopedSavedStack save(state); - LuaLoadStreamWrapper wrapper(stream); + if (status) { + ErrorHandler::handle(status, state); + lua_pushnil(state); + } + return LuaStackRef(state, -1, true); + } + + /// @brief If there are no errors,compiled stream as a Lua function and + /// return. + /// Otherwise send error message to error handler and return nil reference + /// @param state pointer to lua_State + /// @param stream stream of lua script data + /// @param chunkname use for error message. + /// @return reference of lua function + static LuaFunction loadstream(lua_State *state, std::istream &stream, + const char *chunkname = 0) { + util::ScopedSavedStack save(state); + LuaLoadStreamWrapper wrapper(stream); #if LUA_VERSION_NUM >= 502 - int status = lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname, 0); + int status = + lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname, 0); #else - int status = lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname); + int status = + lua_load(state, &LuaLoadStreamWrapper::getdata, &wrapper, chunkname); #endif - if (status) - { - ErrorHandler::handle(status, state); - lua_pushnil(state); - } - return LuaFunction(state, StackTop()); - } - }; - - /// @ingroup Lua_reference_types - /// @brief Reference to Lua thread(coroutine). - class LuaThread :public Ref::RegistoryRef - , public detail::LuaThreadImpl - , public detail::LuaBasicTypeFunctions - { - void typecheck() - { - int t = type(); - if (t != TYPE_THREAD && t != TYPE_NIL && t != TYPE_NONE) - { - except::typeMismatchError(state(), "not lua thread"); - RegistoryRef::unref(); - } - } - public: - /// @brief construct with stack top value. - LuaThread(lua_State* state, StackTop) :Ref::RegistoryRef(state, StackTop()) - { - typecheck(); - } - /// @brief construct with new thread. - LuaThread(lua_State* state, const NewThread& t) :Ref::RegistoryRef(state, t) - { - } - /// @brief construct with nil reference. - LuaThread(lua_State* state) :Ref::RegistoryRef(state, NewThread()) - { - } - /// @brief construct with nil reference. - LuaThread() - { - } - /// @brief get lua thread - operator lua_State*() - { - return getthread(); - } - }; - - + if (status) { + ErrorHandler::handle(status, state); + lua_pushnil(state); + } + return LuaFunction(state, StackTop()); + } +}; + +/// @ingroup Lua_reference_types +/// @brief Reference to Lua thread(coroutine). +class LuaThread : public Ref::RegistoryRef, + public detail::LuaThreadImpl, + public detail::LuaBasicTypeFunctions { + void typecheck() { + int t = type(); + if (t != TYPE_THREAD && t != TYPE_NIL && t != TYPE_NONE) { + except::typeMismatchError(state(), "not lua thread"); + RegistoryRef::unref(); + } + } + +public: + /// @brief construct with stack top value. + LuaThread(lua_State *state, StackTop) : Ref::RegistoryRef(state, StackTop()) { + typecheck(); + } + /// @brief construct with new thread. + LuaThread(lua_State *state, const NewThread &t) + : Ref::RegistoryRef(state, t) {} + /// @brief construct with nil reference. + LuaThread(lua_State *state) : Ref::RegistoryRef(state, NewThread()) {} + /// @brief construct with nil reference. + LuaThread() {} + /// @brief get lua thread + operator lua_State *() { return getthread(); } +}; } - - #if KAGUYA_USE_CPP11 #else -namespace std -{ - template <> inline void swap(kaguya::LuaUserData& a, kaguya::LuaUserData& b) - { - a.swap(b); - } - template <> inline void swap(kaguya::LuaTable& a, kaguya::LuaTable& b) - { - a.swap(b); - } - template <> inline void swap(kaguya::LuaFunction& a, kaguya::LuaFunction& b) - { - a.swap(b); - } - template <> inline void swap(kaguya::LuaThread& a, kaguya::LuaThread& b) - { - a.swap(b); - } - template <> inline void swap(kaguya::LuaRef& a, kaguya::LuaRef& b) - { - a.swap(b); - } +namespace std { +template <> inline void swap(kaguya::LuaUserData &a, kaguya::LuaUserData &b) { + a.swap(b); +} +template <> inline void swap(kaguya::LuaTable &a, kaguya::LuaTable &b) { + a.swap(b); +} +template <> inline void swap(kaguya::LuaFunction &a, kaguya::LuaFunction &b) { + a.swap(b); +} +template <> inline void swap(kaguya::LuaThread &a, kaguya::LuaThread &b) { + a.swap(b); +} +template <> inline void swap(kaguya::LuaRef &a, kaguya::LuaRef &b) { + a.swap(b); +} } #endif diff --git a/include/kaguya/lua_ref_function.hpp b/include/kaguya/lua_ref_function.hpp index 8b42118..8445a30 100644 --- a/include/kaguya/lua_ref_function.hpp +++ b/include/kaguya/lua_ref_function.hpp @@ -13,289 +13,233 @@ #include "kaguya/exception.hpp" #include "kaguya/type.hpp" #include "kaguya/utility.hpp" - - #include "kaguya/detail/lua_function_def.hpp" #include "kaguya/detail/lua_variant_def.hpp" -namespace kaguya -{ - /// @brief function result value proxy class. - /// don't direct use. - class FunctionResults :public Ref::StackRef, public detail::LuaVariantImpl - { - FunctionResults(lua_State* state, int return_status, int startIndex) :Ref::StackRef(state, startIndex, true), state_(state), resultStatus_(return_status), resultCount_(lua_gettop(state) + 1 - startIndex) - { - } - FunctionResults(lua_State* state, int return_status, int startIndex, int endIndex) :Ref::StackRef(state, startIndex, true), state_(state), resultStatus_(return_status), resultCount_(endIndex - startIndex) - { - } - friend class detail::FunctionResultProxy; - public: - FunctionResults() :Ref::StackRef(), state_(0), resultStatus_(0), resultCount_(0) - { - } - FunctionResults(lua_State* state) :Ref::StackRef(state, 0, true), state_(state), resultStatus_(0), resultCount_(0) - { - } +namespace kaguya { +/// @brief function result value proxy class. +/// don't direct use. +class FunctionResults : public Ref::StackRef, + public detail::LuaVariantImpl { + FunctionResults(lua_State *state, int return_status, int startIndex) + : Ref::StackRef(state, startIndex, true), state_(state), + resultStatus_(return_status), + resultCount_(lua_gettop(state) + 1 - startIndex) {} + FunctionResults(lua_State *state, int return_status, int startIndex, + int endIndex) + : Ref::StackRef(state, startIndex, true), state_(state), + resultStatus_(return_status), resultCount_(endIndex - startIndex) {} + friend class detail::FunctionResultProxy; + +public: + FunctionResults() + : Ref::StackRef(), state_(0), resultStatus_(0), resultCount_(0) {} + FunctionResults(lua_State *state) + : Ref::StackRef(state, 0, true), state_(state), resultStatus_(0), + resultCount_(0) {} #if KAGUYA_USE_CPP11 - FunctionResults(FunctionResults&&src) : Ref::StackRef(std::move(src)), state_(src.state_), resultStatus_(src.resultStatus_), resultCount_(src.resultCount_) - { - src.state_ = 0; - } + FunctionResults(FunctionResults &&src) + : Ref::StackRef(std::move(src)), state_(src.state_), + resultStatus_(src.resultStatus_), resultCount_(src.resultCount_) { + src.state_ = 0; + } #else - FunctionResults(const FunctionResults&src) : Ref::StackRef(src), state_(src.state_), resultStatus_(src.resultStatus_), resultCount_(src.resultCount_) - { - src.state_ = 0; - } + FunctionResults(const FunctionResults &src) + : Ref::StackRef(src), state_(src.state_), + resultStatus_(src.resultStatus_), resultCount_(src.resultCount_) { + src.state_ = 0; + } #endif - ~FunctionResults() - { - } - - struct reference :public Ref::StackRef, public detail::LuaVariantImpl - { - reference(lua_State* s, int index) :Ref::StackRef(s, index, false) - { - } - - reference* operator->() - { - return this; - } - const reference* operator->()const - { - return this; - } - }; - templatestruct iterator_base - { - iterator_base(lua_State* s, int i) : state(s), stack_index(i) - { - } - templateiterator_base(const iterator_base& other) : state(other.state), stack_index(other.stack_index) - { - } - T operator*()const - { - return reference(state, stack_index); - } - T operator->()const - { - return reference(state, stack_index); - } - const iterator_base& operator++() - { - stack_index++; - return *this; - } - iterator_base operator++(int) - { - return iterator_base(state, stack_index++); - } - - iterator_base operator+=(int n) - { - stack_index += n; - return iterator_base(state, stack_index); - } - /** - * @name relational operators - * @brief - */ - //@{ - bool operator==(const iterator_base& other)const - { - return state == other.state && stack_index == other.stack_index; - } - bool operator!=(const iterator_base& other)const - { - return !(*this == other); - } - //@} - int index() const { return stack_index; } - private: - template friend struct iterator_base; - lua_State* state; - int stack_index; - }; - typedef iterator_base iterator; - typedef iterator_base const_iterator; - typedef reference const_reference; - - iterator begin() - { - return iterator(state_, stack_index_); - } - iterator end() - { - return iterator(state_, stack_index_ + resultCount_); - } - const_iterator begin()const - { - return const_iterator(state_, stack_index_); - } - const_iterator end()const - { - return const_iterator(state_, stack_index_ + resultCount_); - } - const_iterator cbegin()const - { - return const_iterator(state_, stack_index_); - } - const_iterator cend()const - { - return const_iterator(state_, stack_index_ + resultCount_); - } - - - template - Result get_result(types::typetag = types::typetag())const - { - return util::get_result(state_, stack_index_); - } - LuaStackRef get_result(types::typetag )const - { - pop_ = 0; - return LuaStackRef(state_, stack_index_, true); - } - lua_State* state()const { return state_; } - - template - typename lua_type_traits::get_type result_at(size_t index)const - { - if (index >= result_size()) - { - throw std::out_of_range("function result out of range"); - } - return lua_type_traits::get(state_, stack_index_ + static_cast(index)); - } - reference result_at(size_t index)const - { - if (index >= result_size()) - { - throw std::out_of_range("function result out of range"); - } - return reference(state_, stack_index_ + static_cast(index)); - } - - size_t result_size()const - { - return resultCount_; - } - - size_t resultStatus()const - { - return resultStatus_; - } - - operator LuaStackRef() - { - pop_ = 0; - return LuaStackRef(state_, stack_index_,true); - } - - private: - mutable lua_State* state_; - int resultStatus_; - int resultCount_; - - }; - - namespace detail - { - template - inline RetType FunctionResultProxy::ReturnValue(lua_State* state, int return_status, int retindex, types::typetag ) - { - return FunctionResults(state, return_status, retindex).get_result(types::typetag()); - } - inline FunctionResults FunctionResultProxy::ReturnValue(lua_State* state, int return_status, int retindex, types::typetag ) - { - return FunctionResults(state, return_status, retindex); - } - inline void FunctionResultProxy::ReturnValue(lua_State* state, int return_status, int retindex, types::typetag ) - { - KAGUYA_UNUSED(return_status); - lua_settop(state, retindex - 1); - } + ~FunctionResults() {} + + struct reference : public Ref::StackRef, + public detail::LuaVariantImpl { + reference(lua_State *s, int index) : Ref::StackRef(s, index, false) {} + + reference *operator->() { return this; } + const reference *operator->() const { return this; } + }; + template struct iterator_base { + iterator_base(lua_State *s, int i) : state(s), stack_index(i) {} + template + iterator_base(const iterator_base &other) + : state(other.state), stack_index(other.stack_index) {} + T operator*() const { return reference(state, stack_index); } + T operator->() const { return reference(state, stack_index); } + const iterator_base &operator++() { + stack_index++; + return *this; + } + iterator_base operator++(int) { + return iterator_base(state, stack_index++); + } + + iterator_base operator+=(int n) { + stack_index += n; + return iterator_base(state, stack_index); + } + /** + * @name relational operators + * @brief + */ + //@{ + bool operator==(const iterator_base &other) const { + return state == other.state && stack_index == other.stack_index; + } + bool operator!=(const iterator_base &other) const { + return !(*this == other); + } + //@} + int index() const { return stack_index; } + + private: + template friend struct iterator_base; + lua_State *state; + int stack_index; + }; + typedef iterator_base iterator; + typedef iterator_base const_iterator; + typedef reference const_reference; + + iterator begin() { return iterator(state_, stack_index_); } + iterator end() { return iterator(state_, stack_index_ + resultCount_); } + const_iterator begin() const { return const_iterator(state_, stack_index_); } + const_iterator end() const { + return const_iterator(state_, stack_index_ + resultCount_); + } + const_iterator cbegin() const { return const_iterator(state_, stack_index_); } + const_iterator cend() const { + return const_iterator(state_, stack_index_ + resultCount_); + } + + template + Result get_result(types::typetag = types::typetag()) const { + return util::get_result(state_, stack_index_); + } + LuaStackRef get_result(types::typetag) const { + pop_ = 0; + return LuaStackRef(state_, stack_index_, true); + } + lua_State *state() const { return state_; } + + template + typename lua_type_traits::get_type result_at(size_t index) const { + if (index >= result_size()) { + throw std::out_of_range("function result out of range"); + } + return lua_type_traits::get(state_, + stack_index_ + static_cast(index)); + } + reference result_at(size_t index) const { + if (index >= result_size()) { + throw std::out_of_range("function result out of range"); + } + return reference(state_, stack_index_ + static_cast(index)); + } + + size_t result_size() const { return resultCount_; } + + size_t resultStatus() const { return resultStatus_; } + + operator LuaStackRef() { + pop_ = 0; + return LuaStackRef(state_, stack_index_, true); + } + +private: + mutable lua_State *state_; + int resultStatus_; + int resultCount_; +}; + +namespace detail { +template +inline RetType FunctionResultProxy::ReturnValue(lua_State *state, + int return_status, int retindex, + types::typetag) { + return FunctionResults(state, return_status, retindex) + .get_result(types::typetag()); +} +inline FunctionResults +FunctionResultProxy::ReturnValue(lua_State *state, int return_status, + int retindex, + types::typetag) { + return FunctionResults(state, return_status, retindex); +} +inline void FunctionResultProxy::ReturnValue(lua_State *state, + int return_status, int retindex, + types::typetag) { + KAGUYA_UNUSED(return_status); + lua_settop(state, retindex - 1); +} #if KAGUYA_USE_CPP11 - templatetemplate - FunctionResults LuaFunctionImpl::operator()(Args&&... args) - { - return this->template call(std::forward(args)...); - } - - templatetemplate - FunctionResults LuaThreadImpl::operator()(Args&&... args) - { - return this->template resume(std::forward(args)...); - } - templatetemplate - FunctionResults LuaVariantImpl::operator()(Args&&... args) - { - int t = type(); - if (t == LUA_TTHREAD) - { - return this->template resume(std::forward(args)...); - } - else if (t == LUA_TFUNCTION) - { - return this->template call(std::forward(args)...); - } - else - { - except::typeMismatchError(state_(), " is not function or thread"); - return FunctionResults(state_()); - } - } +template +template +FunctionResults LuaFunctionImpl::operator()(Args &&... args) { + return this->template call(std::forward(args)...); +} + +template +template +FunctionResults LuaThreadImpl::operator()(Args &&... args) { + return this->template resume(std::forward(args)...); +} +template +template +FunctionResults LuaVariantImpl::operator()(Args &&... args) { + int t = type(); + if (t == LUA_TTHREAD) { + return this->template resume(std::forward(args)...); + } else if (t == LUA_TFUNCTION) { + return this->template call(std::forward(args)...); + } else { + except::typeMismatchError(state_(), " is not function or thread"); + return FunctionResults(state_()); + } +} #else -#define KAGUYA_TEMPLATE_PARAMETER(N)template +#define KAGUYA_TEMPLATE_PARAMETER(N) template #define KAGUYA_FUNCTION_ARGS_DEF(N) #define KAGUYA_CALL_ARGS(N) -#define KAGUYA_OP_FN_DEF(N) \ - KAGUYA_TEMPLATE_PARAMETER(N)\ - inline FunctionResults LuaFunctionImpl::operator()(KAGUYA_FUNCTION_ARGS_DEF(N))\ - {\ - return this->template call(KAGUYA_CALL_ARGS(N)); \ - }\ - KAGUYA_TEMPLATE_PARAMETER(N)\ - inline FunctionResults LuaThreadImpl::operator()(KAGUYA_FUNCTION_ARGS_DEF(N))\ - {\ - return this->template resume(KAGUYA_CALL_ARGS(N)); \ - }\ - KAGUYA_TEMPLATE_PARAMETER(N)\ - inline FunctionResults LuaVariantImpl::operator()(KAGUYA_FUNCTION_ARGS_DEF(N))\ - {\ - int t = type();\ - if (t == LUA_TTHREAD)\ - {\ - return this->template resume(KAGUYA_CALL_ARGS(N)); \ - }\ - else if (t == LUA_TFUNCTION)\ - {\ - return this->template call(KAGUYA_CALL_ARGS(N)); \ - }\ - else\ - {\ - except::typeMismatchError(state_(), " is not function or thread");\ - return FunctionResults(state_());\ - }\ - } - - KAGUYA_OP_FN_DEF(0) +#define KAGUYA_OP_FN_DEF(N) \ + KAGUYA_TEMPLATE_PARAMETER(N) \ + inline FunctionResults LuaFunctionImpl::operator()( \ + KAGUYA_FUNCTION_ARGS_DEF(N)) { \ + return this->template call(KAGUYA_CALL_ARGS(N)); \ + } \ + KAGUYA_TEMPLATE_PARAMETER(N) \ + inline FunctionResults LuaThreadImpl::operator()( \ + KAGUYA_FUNCTION_ARGS_DEF(N)) { \ + return this->template resume(KAGUYA_CALL_ARGS(N)); \ + } \ + KAGUYA_TEMPLATE_PARAMETER(N) \ + inline FunctionResults LuaVariantImpl::operator()( \ + KAGUYA_FUNCTION_ARGS_DEF(N)) { \ + int t = type(); \ + if (t == LUA_TTHREAD) { \ + return this->template resume(KAGUYA_CALL_ARGS(N)); \ + } else if (t == LUA_TFUNCTION) { \ + return this->template call(KAGUYA_CALL_ARGS(N)); \ + } else { \ + except::typeMismatchError(state_(), " is not function or thread"); \ + return FunctionResults(state_()); \ + } \ + } + +KAGUYA_OP_FN_DEF(0) #undef KAGUYA_TEMPLATE_PARAMETER #undef KAGUYA_FUNCTION_ARGS_DEF #undef KAGUYA_CALL_ARGS -#define KAGUYA_TEMPLATE_PARAMETER(N) template template +#define KAGUYA_TEMPLATE_PARAMETER(N) \ + template template #define KAGUYA_FUNCTION_ARGS_DEF(N) KAGUYA_PP_ARG_CR_DEF_REPEAT(N) #define KAGUYA_CALL_ARGS(N) KAGUYA_PP_ARG_REPEAT(N) - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) #undef KAGUYA_OP_FN_DEF #undef KAGUYA_TEMPLATE_PARAMETER @@ -304,170 +248,148 @@ namespace kaguya #undef KAGUYA_CALL_DEF #undef KAGUYA_OP_FN_DEF #endif - } - - inline std::ostream& operator<<(std::ostream& os, const FunctionResults& res) - { - for (FunctionResults::const_iterator it = res.begin(); it != res.end(); ++it) - { - if (it != res.begin()) - { - os << ","; - } - util::stackValueDump(os, res.state(), it.index()); - } - - return os; - } - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for FunctionResults - template<> struct lua_type_traits { - static int push(lua_State* l, const FunctionResults& ref) - { - int size = 0; - for (FunctionResults::const_iterator it = ref.cbegin(); it != ref.cend(); ++it) - { - size += it->push(l); - } - return size; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for FunctionResults::reference - template<> struct lua_type_traits { - static int push(lua_State* l, const FunctionResults::reference& ref) - { - return ref.push(l); - } - }; - template - FunctionResults::reference get(const FunctionResults& res) { return res.result_at(I); } - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaFunction - template<> struct lua_type_traits { - typedef LuaFunction get_type; - typedef LuaFunction push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_isfunction(l, index); - } - static bool checkType(lua_State* l, int index) - { - return lua_isfunction(l, index) || lua_isnil(l, index); - } - static LuaFunction get(lua_State* l, int index) - { - lua_pushvalue(l, index); - return LuaFunction(l, StackTop()); - } - static int push(lua_State* l, const LuaFunction& ref) - { - return ref.push(l); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaFunction - template<> struct lua_type_traits :lua_type_traits {}; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaThread - template<> struct lua_type_traits { - typedef LuaThread get_type; - typedef LuaThread push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_isthread(l, index); - } - static bool checkType(lua_State* l, int index) - { - return lua_isthread(l, index) || lua_isnil(l, index); - } - static LuaThread get(lua_State* l, int index) - { - lua_pushvalue(l, index); - return LuaThread(l, StackTop()); - } - static int push(lua_State* l, const LuaThread& ref) - { - return ref.push(l); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaThread - template<> struct lua_type_traits :lua_type_traits {}; - - - - /** - * @brief table and function binder. - * state["table"]->*"fun"() is table:fun() in Lua - * @param arg... function args - */ - class MemberFunctionBinder - { - public: - template - MemberFunctionBinder(LuaRef self, T key) :self_(self), fun_(self_.getField(key)) - { - } +} + +inline std::ostream &operator<<(std::ostream &os, const FunctionResults &res) { + for (FunctionResults::const_iterator it = res.begin(); it != res.end(); + ++it) { + if (it != res.begin()) { + os << ","; + } + util::stackValueDump(os, res.state(), it.index()); + } + + return os; +} + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for FunctionResults +template <> struct lua_type_traits { + static int push(lua_State *l, const FunctionResults &ref) { + int size = 0; + for (FunctionResults::const_iterator it = ref.cbegin(); it != ref.cend(); + ++it) { + size += it->push(l); + } + return size; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for FunctionResults::reference +template <> struct lua_type_traits { + static int push(lua_State *l, const FunctionResults::reference &ref) { + return ref.push(l); + } +}; +template +FunctionResults::reference get(const FunctionResults &res) { + return res.result_at(I); +} + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaFunction +template <> struct lua_type_traits { + typedef LuaFunction get_type; + typedef LuaFunction push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_isfunction(l, index); + } + static bool checkType(lua_State *l, int index) { + return lua_isfunction(l, index) || lua_isnil(l, index); + } + static LuaFunction get(lua_State *l, int index) { + lua_pushvalue(l, index); + return LuaFunction(l, StackTop()); + } + static int push(lua_State *l, const LuaFunction &ref) { return ref.push(l); } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaFunction +template <> +struct lua_type_traits : lua_type_traits {}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaThread +template <> struct lua_type_traits { + typedef LuaThread get_type; + typedef LuaThread push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_isthread(l, index); + } + static bool checkType(lua_State *l, int index) { + return lua_isthread(l, index) || lua_isnil(l, index); + } + static LuaThread get(lua_State *l, int index) { + lua_pushvalue(l, index); + return LuaThread(l, StackTop()); + } + static int push(lua_State *l, const LuaThread &ref) { return ref.push(l); } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaThread +template <> +struct lua_type_traits : lua_type_traits {}; + +/** +* @brief table and function binder. +* state["table"]->*"fun"() is table:fun() in Lua +* @param arg... function args +*/ +class MemberFunctionBinder { +public: + template + MemberFunctionBinder(LuaRef self, T key) + : self_(self), fun_(self_.getField(key)) {} #define KAGUYA_DELEGATE_LUAREF fun_ #define KAGUYA_DELEGATE_FIRST_ARG self_ #define KAGUYA_DELEGATE_FIRST_ARG_C KAGUYA_DELEGATE_FIRST_ARG, #if KAGUYA_USE_CPP11 - template - FunctionResults operator()(Args&&... args) - { - return KAGUYA_DELEGATE_LUAREF(KAGUYA_DELEGATE_FIRST_ARG_C std::forward(args)...); - } - - template - Result call(Args&&... args) - { - return KAGUYA_DELEGATE_LUAREF.call(KAGUYA_DELEGATE_FIRST_ARG_C std::forward(args)...); - } + template FunctionResults operator()(Args &&... args) { + return KAGUYA_DELEGATE_LUAREF( + KAGUYA_DELEGATE_FIRST_ARG_C std::forward(args)...); + } + + template Result call(Args &&... args) { + return KAGUYA_DELEGATE_LUAREF.call( + KAGUYA_DELEGATE_FIRST_ARG_C std::forward(args)...); + } #else -#define KAGUYA_OP_FN_DEF(N) \ - template \ - FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N))\ - {\ - return KAGUYA_DELEGATE_LUAREF(KAGUYA_DELEGATE_FIRST_ARG_C KAGUYA_PP_ARG_REPEAT(N));\ - } - - /** - * @brief If type is function, call lua function. - * If type is lua thread,start or resume lua thread. - * Otherwise send error message to error handler - */ - FunctionResults operator()() - { - return KAGUYA_DELEGATE_LUAREF(KAGUYA_DELEGATE_FIRST_ARG); - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) +#define KAGUYA_OP_FN_DEF(N) \ + template \ + FunctionResults operator()(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)) { \ + return KAGUYA_DELEGATE_LUAREF( \ + KAGUYA_DELEGATE_FIRST_ARG_C KAGUYA_PP_ARG_REPEAT(N)); \ + } + + /** + * @brief If type is function, call lua function. + * If type is lua thread,start or resume lua thread. + * Otherwise send error message to error handler + */ + FunctionResults operator()() { + return KAGUYA_DELEGATE_LUAREF(KAGUYA_DELEGATE_FIRST_ARG); + } + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OP_FN_DEF) #undef KAGUYA_OP_FN_DEF -#define KAGUYA_CALL_DEF(N) \ - template \ - Result call(KAGUYA_PP_ARG_CR_DEF_REPEAT(N))\ - {\ - return KAGUYA_DELEGATE_LUAREF.call(KAGUYA_DELEGATE_FIRST_ARG_C KAGUYA_PP_ARG_REPEAT(N));\ - } +#define KAGUYA_CALL_DEF(N) \ + template \ + Result call(KAGUYA_PP_ARG_CR_DEF_REPEAT(N)) { \ + return KAGUYA_DELEGATE_LUAREF.call( \ + KAGUYA_DELEGATE_FIRST_ARG_C KAGUYA_PP_ARG_REPEAT(N)); \ + } - template - Result call() - { - return KAGUYA_DELEGATE_LUAREF.call(KAGUYA_DELEGATE_FIRST_ARG); - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CALL_DEF) + template Result call() { + return KAGUYA_DELEGATE_LUAREF.call(KAGUYA_DELEGATE_FIRST_ARG); + } + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CALL_DEF) #undef KAGUYA_CALL_DEF #endif @@ -476,10 +398,10 @@ namespace kaguya #undef KAGUYA_DELEGATE_FIRST_ARG #undef KAGUYA_DELEGATE_LUAREF - private: - LuaRef self_;//Table or Userdata - LuaFunction fun_; - }; +private: + LuaRef self_; // Table or Userdata + LuaFunction fun_; +}; - typedef MemberFunctionBinder mem_fun_binder;//for backward conpatible +typedef MemberFunctionBinder mem_fun_binder; // for backward conpatible } diff --git a/include/kaguya/lua_ref_table.hpp b/include/kaguya/lua_ref_table.hpp index 597d512..20c721a 100644 --- a/include/kaguya/lua_ref_table.hpp +++ b/include/kaguya/lua_ref_table.hpp @@ -10,630 +10,579 @@ #include "kaguya/config.hpp" #include "kaguya/lua_ref.hpp" #include "kaguya/push_any.hpp" - #include "kaguya/detail/lua_ref_impl.hpp" #include "kaguya/detail/lua_table_def.hpp" -namespace kaguya -{ - class State; - - /** - * This class is the type returned by members of non-const LuaRef(Table) when directly accessing its elements. - */ - template - class TableKeyReferenceProxy : public detail::LuaVariantImpl > - { - public: - - int pushStackIndex(lua_State* state)const - { - push(state); - return lua_gettop(state); - } - lua_State* state()const { return state_; } - - friend class LuaRef; - friend class State; - - //! this is not copy.same assign from referenced value. - TableKeyReferenceProxy& operator=(const TableKeyReferenceProxy& src) - { - detail::table_proxy::set(state_, table_index_, key_, src); - return *this; - } - - - //! assign from T - template - TableKeyReferenceProxy& operator=(const T& src) - { - detail::table_proxy::set(state_, table_index_, key_, src); - return *this; - } +namespace kaguya { +class State; + +/** +* This class is the type returned by members of non-const LuaRef(Table) when +* directly accessing its elements. +*/ +template +class TableKeyReferenceProxy + : public detail::LuaVariantImpl > { +public: + int pushStackIndex(lua_State *state) const { + push(state); + return lua_gettop(state); + } + lua_State *state() const { return state_; } + + friend class LuaRef; + friend class State; + + //! this is not copy.same assign from referenced value. + TableKeyReferenceProxy &operator=(const TableKeyReferenceProxy &src) { + detail::table_proxy::set(state_, table_index_, key_, src); + return *this; + } + + //! assign from T + template TableKeyReferenceProxy &operator=(const T &src) { + detail::table_proxy::set(state_, table_index_, key_, src); + return *this; + } #if KAGUYA_USE_CPP11 - template - TableKeyReferenceProxy& operator=(T&& src) - { - detail::table_proxy::set(state_, table_index_, key_, std::forward(src)); - return *this; - } + template TableKeyReferenceProxy &operator=(T &&src) { + detail::table_proxy::set(state_, table_index_, key_, std::forward(src)); + return *this; + } #endif - bool isNilref()const { - if (!state_) - { - return false; - } - util::ScopedSavedStack save(state_); - push(state_); - return lua_isnoneornil(state_, -1); - } - - //! register class metatable to lua and set to table - template - void setClass(const UserdataMetatable& reg) - { - set_class(reg); - } - - //! set function - template - void setFunction(T f) - { - detail::table_proxy::set(state_, table_index_, key_, kaguya::function(f)); - } - - - int push(lua_State* state)const - { - int type = lua_type(state_, table_index_); - if (type != LUA_TTABLE - && type != LUA_TUSERDATA) - { - lua_pushnil(state); - return 1; - } - - detail::table_proxy::get(state_, table_index_, key_); - - if (state_ != state) - { - lua_xmove(state_, state, 1); - } - return 1; - - } - - int push()const - { - return push(state_); - } - - int type()const - { - util::ScopedSavedStack save(state_); - push(); - return lua_type(state_, -1); - } - - ~TableKeyReferenceProxy() - { - if (state_) - { - lua_settop(state_, stack_top_); - } - } - - ///!constructs the reference. Accessible only to kaguya::LuaRef itself - TableKeyReferenceProxy(const TableKeyReferenceProxy& src) : state_(src.state_), stack_top_(src.stack_top_), table_index_(src.table_index_), key_(src.key_) - { - src.state_ = 0; - } - - ///!constructs the reference. Accessible only to kaguya::LuaRef itself - TableKeyReferenceProxy(lua_State* state, int table_index, KEY key, int revstacktop) : state_(state), stack_top_(revstacktop), table_index_(table_index), key_(key) - { - } - private: - template - void set_class(const UserdataMetatable& reg) - { - detail::table_proxy::set(state_, table_index_, key_, reg.createMatatable(state_)); - } - - - ///!constructs the reference. Accessible only to kaguya::LuaRef itself - TableKeyReferenceProxy(lua_State* state, int table_index, const KEY& key, int revstacktop, const NoTypeCheck&) : state_(state), stack_top_(revstacktop), table_index_(table_index), key_(key) - { - } - - TableKeyReferenceProxy(const LuaTable& table, const KEY& key) : state_(table.state()), stack_top_(lua_gettop(state_)), key_(key) - { - util::one_push(state_, table); - table_index_ = stack_top_ + 1; - } - TableKeyReferenceProxy(const LuaRef& table, const KEY& key) : state_(table.state()), stack_top_(lua_gettop(state_)), key_(key) - { - util::one_push(state_, table); - table_index_ = stack_top_ + 1; - int t = lua_type(state_, table_index_); - if (t != LUA_TTABLE) - { - except::typeMismatchError(state_, lua_typename(state_, t) + std::string(" is not table")); - } - } - - mutable lua_State* state_;//mutable for RVO unsupported compiler - int stack_top_; - int table_index_; - KEY key_; - }; - - template - inline std::ostream& operator<<(std::ostream& os, const TableKeyReferenceProxy& ref) - { - lua_State* state = ref.state(); - util::ScopedSavedStack save(state); - int stackIndex = ref.pushStackIndex(state); - util::stackValueDump(os, state, stackIndex); - return os; - } - - namespace detail { - template - inline bool LuaFunctionImpl::setFunctionEnv(const LuaTable& env) - { - lua_State* state = state_(); - if (!state) - { - return false; - } - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - int t = lua_type(state, stackIndex); - if (t != LUA_TFUNCTION) - { - except::typeMismatchError(state, lua_typename(state, t) + std::string(" is not function")); - return false; - } - env.push(state); + bool isNilref() const { + if (!state_) { + return false; + } + util::ScopedSavedStack save(state_); + push(state_); + return lua_isnoneornil(state_, -1); + } + + //! register class metatable to lua and set to table + template + void setClass(const UserdataMetatable ®) { + set_class(reg); + } + + //! set function + template void setFunction(T f) { + detail::table_proxy::set(state_, table_index_, key_, kaguya::function(f)); + } + + int push(lua_State *state) const { + int type = lua_type(state_, table_index_); + if (type != LUA_TTABLE && type != LUA_TUSERDATA) { + lua_pushnil(state); + return 1; + } + + detail::table_proxy::get(state_, table_index_, key_); + + if (state_ != state) { + lua_xmove(state_, state, 1); + } + return 1; + } + + int push() const { return push(state_); } + + int type() const { + util::ScopedSavedStack save(state_); + push(); + return lua_type(state_, -1); + } + + ~TableKeyReferenceProxy() { + if (state_) { + lua_settop(state_, stack_top_); + } + } + + ///!constructs the reference. Accessible only to kaguya::LuaRef itself + TableKeyReferenceProxy(const TableKeyReferenceProxy &src) + : state_(src.state_), stack_top_(src.stack_top_), + table_index_(src.table_index_), key_(src.key_) { + src.state_ = 0; + } + + ///!constructs the reference. Accessible only to kaguya::LuaRef itself + TableKeyReferenceProxy(lua_State *state, int table_index, KEY key, + int revstacktop) + : state_(state), stack_top_(revstacktop), table_index_(table_index), + key_(key) {} + +private: + template + void set_class(const UserdataMetatable ®) { + detail::table_proxy::set(state_, table_index_, key_, + reg.createMatatable(state_)); + } + + ///!constructs the reference. Accessible only to kaguya::LuaRef itself + TableKeyReferenceProxy(lua_State *state, int table_index, const KEY &key, + int revstacktop, const NoTypeCheck &) + : state_(state), stack_top_(revstacktop), table_index_(table_index), + key_(key) {} + + TableKeyReferenceProxy(const LuaTable &table, const KEY &key) + : state_(table.state()), stack_top_(lua_gettop(state_)), key_(key) { + util::one_push(state_, table); + table_index_ = stack_top_ + 1; + } + TableKeyReferenceProxy(const LuaRef &table, const KEY &key) + : state_(table.state()), stack_top_(lua_gettop(state_)), key_(key) { + util::one_push(state_, table); + table_index_ = stack_top_ + 1; + int t = lua_type(state_, table_index_); + if (t != LUA_TTABLE) { + except::typeMismatchError(state_, lua_typename(state_, t) + + std::string(" is not table")); + } + } + + mutable lua_State *state_; // mutable for RVO unsupported compiler + int stack_top_; + int table_index_; + KEY key_; +}; + +template +inline std::ostream &operator<<(std::ostream &os, + const TableKeyReferenceProxy &ref) { + lua_State *state = ref.state(); + util::ScopedSavedStack save(state); + int stackIndex = ref.pushStackIndex(state); + util::stackValueDump(os, state, stackIndex); + return os; +} + +namespace detail { +template +inline bool LuaFunctionImpl::setFunctionEnv(const LuaTable &env) { + lua_State *state = state_(); + if (!state) { + return false; + } + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + int t = lua_type(state, stackIndex); + if (t != LUA_TFUNCTION) { + except::typeMismatchError(state, lua_typename(state, t) + + std::string(" is not function")); + return false; + } + env.push(state); #if LUA_VERSION_NUM >= 502 - lua_setupvalue(state, stackIndex, 1); + lua_setupvalue(state, stackIndex, 1); #else - lua_setfenv(state, stackIndex); + lua_setfenv(state, stackIndex); #endif - return true; - } - template - inline bool LuaFunctionImpl::setFunctionEnv(NewTable) - { - return setFunctionEnv(LuaTable(state_())); - } - - template - inline LuaTable LuaFunctionImpl::getFunctionEnv()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return LuaTable(); - } - int stackIndex = pushStackIndex_(state); - int t = lua_type(state, stackIndex); - if (t != LUA_TFUNCTION) - { - except::typeMismatchError(state, lua_typename(state, t) + std::string(" is not function")); - return LuaTable(); - } + return true; +} +template inline bool LuaFunctionImpl::setFunctionEnv(NewTable) { + return setFunctionEnv(LuaTable(state_())); +} + +template +inline LuaTable LuaFunctionImpl::getFunctionEnv() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + if (!state) { + except::typeMismatchError(state, "is nil"); + return LuaTable(); + } + int stackIndex = pushStackIndex_(state); + int t = lua_type(state, stackIndex); + if (t != LUA_TFUNCTION) { + except::typeMismatchError(state, lua_typename(state, t) + + std::string(" is not function")); + return LuaTable(); + } #if LUA_VERSION_NUM >= 502 - lua_getupvalue(state, stackIndex, 1); + lua_getupvalue(state, stackIndex, 1); #else - lua_getfenv(state, stackIndex); + lua_getfenv(state, stackIndex); #endif - return LuaTable(state, StackTop()); - } - - - template - void LuaThreadImpl::setFunction(const LuaFunction& f) - { - lua_State* corstate = getthread(); - if (corstate) - { - lua_settop(corstate, 0); - f.push(corstate); - } - } - - template - bool LuaTableOrUserDataImpl::setMetatable(const LuaTable& table) - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return false; - } - util::ScopedSavedStack save(state); - int stackindex = pushStackIndex_(state); - int t = lua_type(state, stackindex); - if (t != LUA_TTABLE && t != LUA_TUSERDATA) - { - except::typeMismatchError(state, lua_typename(state, t) + std::string(" is not table")); - return false; - } - table.push(); - return lua_setmetatable(state, stackindex) != 0; - } - template - LuaTable LuaTableOrUserDataImpl::getMetatable()const - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return LuaTable(); - } - util::ScopedSavedStack save(state); - int stackindex = pushStackIndex_(state); - int t = lua_type(state, stackindex); - if (t != LUA_TTABLE && t != LUA_TUSERDATA) - { - except::typeMismatchError(state, lua_typename(state, t) + std::string(" is not table")); - return LuaTable(); - } - if (!lua_getmetatable(state, stackindex)) - { - lua_pushnil(state); - } - return LuaTable(state, StackTop()); - } - template - MemberFunctionBinder LuaTableOrUserDataImpl::operator->*(const char* function_name) - { - push_(state_()); - return MemberFunctionBinder(LuaRef(state_(), StackTop()), function_name); - } - - - template template - LuaStackRef LuaTableOrUserDataImpl::getField(const KEY& key)const - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return LuaStackRef(); - } - push_(state); - detail::table_proxy::get(state,lua_gettop(state), key); - lua_remove(state, -2);//remove table - return LuaStackRef(state, -1, true); - } - template template - LuaStackRef LuaTableImpl::getRawField(const KEY& key)const - { - lua_State* state = state_(); - if (!state) - { - except::typeMismatchError(state, "is nil"); - return LuaStackRef(); - } - push_(state); - detail::table_proxy::rawget(state, lua_gettop(state) , key); - lua_remove(state, -2);//remove table - return LuaStackRef(state, -1, true); - } - - template template - LuaStackRef LuaTableOrUserDataImpl::operator[](KEY key)const - { - return getField(key); - } - - template - std::vector LuaTableImpl::values()const - { - return values(); - } - template - std::vector LuaTableImpl::keys()const - { - return keys(); - } - template - std::map LuaTableImpl::map()const - { - return map(); - } - - template template - TableKeyReferenceProxy LuaTableOrUserDataImpl::operator[](K key) - { - lua_State* state = state_(); - int stack_top = lua_gettop(state); - int stackindex = pushStackIndex_(state); - return TableKeyReferenceProxy(state, stackindex, key, stack_top); - } - } - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for TableKeyReferenceProxy - template - struct lua_type_traits > { - static int push(lua_State* l, const TableKeyReferenceProxy& ref) - { - return ref.push(l); - } - }; - + return LuaTable(state, StackTop()); +} + +template void LuaThreadImpl::setFunction(const LuaFunction &f) { + lua_State *corstate = getthread(); + if (corstate) { + lua_settop(corstate, 0); + f.push(corstate); + } +} + +template +bool LuaTableOrUserDataImpl::setMetatable(const LuaTable &table) { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return false; + } + util::ScopedSavedStack save(state); + int stackindex = pushStackIndex_(state); + int t = lua_type(state, stackindex); + if (t != LUA_TTABLE && t != LUA_TUSERDATA) { + except::typeMismatchError(state, lua_typename(state, t) + + std::string(" is not table")); + return false; + } + table.push(); + return lua_setmetatable(state, stackindex) != 0; +} +template LuaTable LuaTableOrUserDataImpl::getMetatable() const { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return LuaTable(); + } + util::ScopedSavedStack save(state); + int stackindex = pushStackIndex_(state); + int t = lua_type(state, stackindex); + if (t != LUA_TTABLE && t != LUA_TUSERDATA) { + except::typeMismatchError(state, lua_typename(state, t) + + std::string(" is not table")); + return LuaTable(); + } + if (!lua_getmetatable(state, stackindex)) { + lua_pushnil(state); + } + return LuaTable(state, StackTop()); +} +template +MemberFunctionBinder LuaTableOrUserDataImpl:: +operator->*(const char *function_name) { + push_(state_()); + return MemberFunctionBinder(LuaRef(state_(), StackTop()), function_name); +} + +template +template +LuaStackRef LuaTableOrUserDataImpl::getField(const KEY &key) const { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return LuaStackRef(); + } + push_(state); + detail::table_proxy::get(state, lua_gettop(state), key); + lua_remove(state, -2); // remove table + return LuaStackRef(state, -1, true); +} +template +template +LuaStackRef LuaTableImpl::getRawField(const KEY &key) const { + lua_State *state = state_(); + if (!state) { + except::typeMismatchError(state, "is nil"); + return LuaStackRef(); + } + push_(state); + detail::table_proxy::rawget(state, lua_gettop(state), key); + lua_remove(state, -2); // remove table + return LuaStackRef(state, -1, true); +} + +template +template +LuaStackRef LuaTableOrUserDataImpl::operator[](KEY key) const { + return getField(key); +} + +template std::vector LuaTableImpl::values() const { + return values(); +} +template std::vector LuaTableImpl::keys() const { + return keys(); +} +template std::map LuaTableImpl::map() const { + return map(); +} + +template +template +TableKeyReferenceProxy LuaTableOrUserDataImpl::operator[](K key) { + lua_State *state = state_(); + int stack_top = lua_gettop(state); + int stackindex = pushStackIndex_(state); + return TableKeyReferenceProxy(state, stackindex, key, stack_top); +} +} + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for TableKeyReferenceProxy +template struct lua_type_traits > { + static int push(lua_State *l, const TableKeyReferenceProxy &ref) { + return ref.push(l); + } +}; + #if KAGUYA_USE_CPP11 - /// @ingroup lua_type_traits - /// @brief lua_type_traits for std::array - template - struct lua_type_traits > - { - typedef std::array get_type; - typedef const std::array& push_type; - - static bool checkType(lua_State* l, int index) - { - if (lua_type(l, index) != LUA_TTABLE) { return false; } - - LuaStackRef table(l, index); - if (table.size() != S) { return false; }//TODO - bool valid = true; - table.foreach_table_breakable( - [&](const LuaStackRef& k, const LuaStackRef& v) {valid = valid && k.typeTest() && v.typeTest(); return valid; }); - return valid; - } - static bool strictCheckType(lua_State* l, int index) - { - if (lua_type(l, index) != LUA_TTABLE) { return false; } - - LuaStackRef table(l, index); - if (table.size() != S) { return false; }//TODO - bool valid = true; - table.foreach_table_breakable( - [&](const LuaStackRef& k, const LuaStackRef& v) {valid = valid && k.typeTest() && v.typeTest(); return valid; }); - return valid; - } - static get_type get(lua_State* l, int index) - { - if (lua_type(l, index) != LUA_TTABLE) - { - except::typeMismatchError(l, std::string("type mismatch")); - return get_type(); - } - LuaStackRef t(l, index); - if (t.size() != S)//TODO - { - except::typeMismatchError(l, std::string("type mismatch")); - } - get_type res; - t.foreach_table([&](size_t k, const T& v) { if (k > 0 && k <= S) { res[k - 1] = v; } }); - return res; - } - static int push(lua_State* l, push_type v) - { - lua_createtable(l, int(S), 0); - for (size_t i = 0;i +template struct lua_type_traits > { + typedef std::array get_type; + typedef const std::array &push_type; + + static bool checkType(lua_State *l, int index) { + if (lua_type(l, index) != LUA_TTABLE) { + return false; + } + + LuaStackRef table(l, index); + if (table.size() != S) { + return false; + } // TODO + bool valid = true; + table.foreach_table_breakable( + [&](const LuaStackRef &k, const LuaStackRef &v) { + valid = valid && k.typeTest() && v.typeTest(); + return valid; + }); + return valid; + } + static bool strictCheckType(lua_State *l, int index) { + if (lua_type(l, index) != LUA_TTABLE) { + return false; + } + + LuaStackRef table(l, index); + if (table.size() != S) { + return false; + } // TODO + bool valid = true; + table.foreach_table_breakable( + [&](const LuaStackRef &k, const LuaStackRef &v) { + valid = valid && k.typeTest() && v.typeTest(); + return valid; + }); + return valid; + } + static get_type get(lua_State *l, int index) { + if (lua_type(l, index) != LUA_TTABLE) { + except::typeMismatchError(l, std::string("type mismatch")); + return get_type(); + } + LuaStackRef t(l, index); + if (t.size() != S) // TODO + { + except::typeMismatchError(l, std::string("type mismatch")); + } + get_type res; + t.foreach_table([&](size_t k, const T &v) { + if (k > 0 && k <= S) { + res[k - 1] = v; + } + }); + return res; + } + static int push(lua_State *l, push_type v) { + lua_createtable(l, int(S), 0); + for (size_t i = 0; i < S; ++i) { + util::one_push(l, v[i]); + lua_rawseti(l, -2, i + 1); + } + return 1; + } +}; #endif #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE - /// @ingroup lua_type_traits - /// @brief lua_type_traits for std::vector - template - struct lua_type_traits > - { - typedef std::vector get_type; - typedef const std::vector& push_type; - struct checkTypeForEach - { - checkTypeForEach(bool& valid) :valid_(valid) {} - bool& valid_; - bool operator()(const LuaStackRef& k, const LuaStackRef& v) - { - valid_ = k.typeTest() && v.weakTypeTest(); - return valid_; - } - }; - struct strictCheckTypeForEach - { - strictCheckTypeForEach(bool& valid) :valid_(valid) {} - bool& valid_; - bool operator()(const LuaStackRef& k, const LuaStackRef& v) - { - valid_ = k.typeTest() && v.typeTest(); - return valid_; - } - }; - - static bool checkType(lua_State* l, int index) - { - LuaStackRef table(l, index); - if (table.type() != LuaRef::TYPE_TABLE) { return false; } - - bool valid = true; - table.foreach_table_breakable(checkTypeForEach(valid)); - return valid; - } - static bool strictCheckType(lua_State* l, int index) - { - LuaStackRef table(l, index); - if (table.type() != LuaRef::TYPE_TABLE) { return false; } - - bool valid = true; - table.foreach_table_breakable(strictCheckTypeForEach(valid)); - return valid; - } - - static get_type get(lua_State* l, int index) - { - if (lua_type(l, index) != LUA_TTABLE) - { - except::typeMismatchError(l, std::string("type mismatch")); - return get_type(); - } - return LuaStackRef(l, index).values(); - } +/// @ingroup lua_type_traits +/// @brief lua_type_traits for std::vector +template struct lua_type_traits > { + typedef std::vector get_type; + typedef const std::vector &push_type; + struct checkTypeForEach { + checkTypeForEach(bool &valid) : valid_(valid) {} + bool &valid_; + bool operator()(const LuaStackRef &k, const LuaStackRef &v) { + valid_ = k.typeTest() && v.weakTypeTest(); + return valid_; + } + }; + struct strictCheckTypeForEach { + strictCheckTypeForEach(bool &valid) : valid_(valid) {} + bool &valid_; + bool operator()(const LuaStackRef &k, const LuaStackRef &v) { + valid_ = k.typeTest() && v.typeTest(); + return valid_; + } + }; + + static bool checkType(lua_State *l, int index) { + LuaStackRef table(l, index); + if (table.type() != LuaRef::TYPE_TABLE) { + return false; + } + + bool valid = true; + table.foreach_table_breakable( + checkTypeForEach(valid)); + return valid; + } + static bool strictCheckType(lua_State *l, int index) { + LuaStackRef table(l, index); + if (table.type() != LuaRef::TYPE_TABLE) { + return false; + } + + bool valid = true; + table.foreach_table_breakable( + strictCheckTypeForEach(valid)); + return valid; + } + + static get_type get(lua_State *l, int index) { + if (lua_type(l, index) != LUA_TTABLE) { + except::typeMismatchError(l, std::string("type mismatch")); + return get_type(); + } + return LuaStackRef(l, index).values(); + } #if KAGUYA_USE_CPP11 - typedef std::vector&& move_push_type; - static int push(lua_State* l, move_push_type v) - { - lua_createtable(l, int(v.size()), 0); - int count = 1;//array is 1 origin in Lua - for (typename std::vector::iterator it = v.begin(); it != v.end(); ++it) - { - util::one_push(l, static_cast(*it)); - lua_rawseti(l, -2, count++); - } - return 1; - } + typedef std::vector &&move_push_type; + static int push(lua_State *l, move_push_type v) { + lua_createtable(l, int(v.size()), 0); + int count = 1; // array is 1 origin in Lua + for (typename std::vector::iterator it = v.begin(); it != v.end(); + ++it) { + util::one_push(l, static_cast(*it)); + lua_rawseti(l, -2, count++); + } + return 1; + } #endif - static int push(lua_State* l, push_type v) - { - lua_createtable(l, int(v.size()), 0); - int count = 1;//array is 1 origin in Lua - for (typename std::vector::const_iterator it = v.begin(); it != v.end(); ++it) - { - util::one_push(l, *it); - lua_rawseti(l, -2, count++); - } - return 1; - } - }; + static int push(lua_State *l, push_type v) { + lua_createtable(l, int(v.size()), 0); + int count = 1; // array is 1 origin in Lua + for (typename std::vector::const_iterator it = v.begin(); + it != v.end(); ++it) { + util::one_push(l, *it); + lua_rawseti(l, -2, count++); + } + return 1; + } +}; #endif #ifndef KAGUYA_NO_STD_MAP_TO_TABLE - /// @ingroup lua_type_traits - /// @brief lua_type_traits for std::map - template - struct lua_type_traits > - { - typedef std::map get_type; - typedef const std::map& push_type; - - struct checkTypeForEach - { - checkTypeForEach(bool& valid) :valid_(valid) {} - bool& valid_; - bool operator()(const LuaStackRef& k, const LuaStackRef& v) - { - valid_ = k.weakTypeTest() && v.weakTypeTest(); - return valid_; - } - }; - struct strictCheckTypeForEach - { - strictCheckTypeForEach(bool& valid) :valid_(valid) {} - bool& valid_; - bool operator()(const LuaStackRef& k, const LuaStackRef& v) - { - valid_ = k.typeTest() && v.typeTest(); - return valid_; - } - }; - static bool checkType(lua_State* l, int index) - { - LuaStackRef table(l, index); - if (table.type() != LuaRef::TYPE_TABLE) { return false; } - - bool valid = true; - table.foreach_table_breakable(checkTypeForEach(valid)); - return valid; - } - static bool strictCheckType(lua_State* l, int index) - { - LuaStackRef table(l, index); - if (table.type() != LuaRef::TYPE_TABLE) { return false; } - - bool valid = true; - table.foreach_table_breakable(strictCheckTypeForEach(valid)); - return valid; - } - - static get_type get(lua_State* l, int index) - { - if (lua_type(l, index) != LUA_TTABLE) - { - except::typeMismatchError(l, std::string("type mismatch")); - return get_type(); - } - return LuaStackRef(l, index).map(); - } - static int push(lua_State* l, push_type v) - { - lua_createtable(l, 0, int(v.size())); - for (typename std::map::const_iterator it = v.begin(); it != v.end(); ++it) - { - util::one_push(l, it->first); - util::one_push(l, it->second); - lua_rawset(l, -3); - } - return 1; - } - }; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for std::map +template +struct lua_type_traits > { + typedef std::map get_type; + typedef const std::map &push_type; + + struct checkTypeForEach { + checkTypeForEach(bool &valid) : valid_(valid) {} + bool &valid_; + bool operator()(const LuaStackRef &k, const LuaStackRef &v) { + valid_ = k.weakTypeTest() && v.weakTypeTest(); + return valid_; + } + }; + struct strictCheckTypeForEach { + strictCheckTypeForEach(bool &valid) : valid_(valid) {} + bool &valid_; + bool operator()(const LuaStackRef &k, const LuaStackRef &v) { + valid_ = k.typeTest() && v.typeTest(); + return valid_; + } + }; + static bool checkType(lua_State *l, int index) { + LuaStackRef table(l, index); + if (table.type() != LuaRef::TYPE_TABLE) { + return false; + } + + bool valid = true; + table.foreach_table_breakable( + checkTypeForEach(valid)); + return valid; + } + static bool strictCheckType(lua_State *l, int index) { + LuaStackRef table(l, index); + if (table.type() != LuaRef::TYPE_TABLE) { + return false; + } + + bool valid = true; + table.foreach_table_breakable( + strictCheckTypeForEach(valid)); + return valid; + } + + static get_type get(lua_State *l, int index) { + if (lua_type(l, index) != LUA_TTABLE) { + except::typeMismatchError(l, std::string("type mismatch")); + return get_type(); + } + return LuaStackRef(l, index).map(); + } + static int push(lua_State *l, push_type v) { + lua_createtable(l, 0, int(v.size())); + for (typename std::map::const_iterator it = v.begin(); + it != v.end(); ++it) { + util::one_push(l, it->first); + util::one_push(l, it->second); + lua_rawset(l, -3); + } + return 1; + } +}; #endif - struct TableDataElement { - typedef std::pair keyvalue_type; +struct TableDataElement { + typedef std::pair keyvalue_type; - template - TableDataElement(Value value) :keyvalue(keyvalue_type(AnyDataPusher(), value)) {} + template + TableDataElement(Value value) + : keyvalue(keyvalue_type(AnyDataPusher(), value)) {} - template - TableDataElement(Key key, Value value) : keyvalue(keyvalue_type(key, value)) {} - std::pair keyvalue; - }; + template + TableDataElement(Key key, Value value) + : keyvalue(keyvalue_type(key, value)) {} + std::pair keyvalue; +}; - struct TableData { - typedef std::pair data_type; +struct TableData { + typedef std::pair data_type; #if KAGUYA_USE_CPP11 - TableData(std::initializer_list list) :elements(list.begin(), list.end()) {} + TableData(std::initializer_list list) + : elements(list.begin(), list.end()) {} #endif - template - TableData(IT beg,IT end) :elements(beg, end) {} - - TableData(){} - std::vector elements; - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for TableData - template<> - struct lua_type_traits { - static int push(lua_State* l, const TableData& list) - { - lua_createtable(l, int(list.elements.size()), int(list.elements.size())); - int count = 1;//array is 1 origin in Lua - for (std::vector::const_iterator it = list.elements.begin(); it != list.elements.end() ; ++it) - { - const TableDataElement& v = *it; - if (v.keyvalue.first.empty()) - { - util::one_push(l, v.keyvalue.second); - lua_rawseti(l, -2, count++); - } - else - { - util::one_push(l, v.keyvalue.first); - util::one_push(l, v.keyvalue.second); - lua_rawset(l, -3); - } - } - return 1; - } - }; + template TableData(IT beg, IT end) : elements(beg, end) {} + + TableData() {} + std::vector elements; +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for TableData +template <> struct lua_type_traits { + static int push(lua_State *l, const TableData &list) { + lua_createtable(l, int(list.elements.size()), int(list.elements.size())); + int count = 1; // array is 1 origin in Lua + for (std::vector::const_iterator it = + list.elements.begin(); + it != list.elements.end(); ++it) { + const TableDataElement &v = *it; + if (v.keyvalue.first.empty()) { + util::one_push(l, v.keyvalue.second); + lua_rawseti(l, -2, count++); + } else { + util::one_push(l, v.keyvalue.first); + util::one_push(l, v.keyvalue.second); + lua_rawset(l, -3); + } + } + return 1; + } +}; } diff --git a/include/kaguya/metatable.hpp b/include/kaguya/metatable.hpp index b304c16..5585cd7 100644 --- a/include/kaguya/metatable.hpp +++ b/include/kaguya/metatable.hpp @@ -13,698 +13,683 @@ #include "kaguya/config.hpp" #include "kaguya/push_any.hpp" #include "kaguya/native_function.hpp" - - #include "kaguya/lua_ref_function.hpp" #define KAGUYA_PROPERTY_PREFIX "_prop_" -namespace kaguya -{ +namespace kaguya { -#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(class A,N) = void -#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_PP_STRUCT_TDEF_REP) +#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(class A, N) = void +#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_STRUCT_TDEF_REP) - template - struct MultipleBase { - }; +template +struct MultipleBase {}; #undef KAGUYA_PP_STRUCT_TDEF_REP #undef KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT } +namespace kaguya { +struct LuaCodeChunk { + LuaCodeChunk(const std::string &src, const std::string &name = "") + : code_(src), chunk_name_(name) {} + LuaCodeChunk(const char *src, const char *name = "") + : code_(src), chunk_name_(name ? name : "") {} + std::string code_; + std::string chunk_name_; +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaCodeChunk +template <> struct lua_type_traits { + static int push(lua_State *state, const LuaCodeChunk &ref) { + int status = luaL_loadbuffer( + state, ref.code_.c_str(), ref.code_.size(), + ref.chunk_name_.empty() ? ref.code_.c_str() : ref.chunk_name_.c_str()); + if (!except::checkErrorAndThrow(status, state)) { + return 0; + } + return 1; + } +}; +struct LuaCodeChunkExecute : LuaCodeChunk { + LuaCodeChunkExecute(const std::string &src, const std::string &name = "") + : LuaCodeChunk(src, name) {} + LuaCodeChunkExecute(const char *src, const char *name = "") + : LuaCodeChunk(src, name) {} +}; +typedef LuaCodeChunkExecute LuaCodeChunkResult; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for LuaCodeChunkResult +template <> struct lua_type_traits { + static int push(lua_State *state, const LuaCodeChunkExecute &ref) { + int status = luaL_loadbuffer( + state, ref.code_.c_str(), ref.code_.size(), + ref.chunk_name_.empty() ? ref.code_.c_str() : ref.chunk_name_.c_str()); + if (!except::checkErrorAndThrow(status, state)) { + return 0; + } + status = lua_pcall_wrap(state, 0, 1); + if (!except::checkErrorAndThrow(status, state)) { + return 0; + } + return 1; + } +}; + +namespace Metatable { +typedef std::map PropMapType; +typedef std::map MemberMapType; + +inline bool is_property_key(const char *keyname) { + return keyname && + strncmp(keyname, KAGUYA_PROPERTY_PREFIX, + sizeof(KAGUYA_PROPERTY_PREFIX) - 1) != 0; +} +inline int property_index_function(lua_State *L) { + // Lua + // local arg = {...};local metatable = arg[1]; + // return function(table, index) + // if string.find(index,KAGUYA_PROPERTY_PREFIX)~=0 then + // local propfun = metatable[KAGUYA_PROPERTY_PREFIX ..index]; + // if propfun then return propfun(table) end + // end + // return metatable[index] + // end + static const int table = 1; + static const int key = 2; + static const int metatable = lua_upvalueindex(1); + const char *strkey = lua_tostring(L, key); + + if (lua_type(L, 1) == LUA_TUSERDATA && is_property_key(strkey)) { + int type = lua_getfield_rtype( + L, metatable, (KAGUYA_PROPERTY_PREFIX + std::string(strkey)).c_str()); + if (type == LUA_TFUNCTION) { + lua_pushvalue(L, table); + lua_call(L, 1, 1); + return 1; + } + } + lua_pushvalue(L, key); + lua_gettable(L, metatable); + return 1; +} +inline int property_newindex_function(lua_State *L) { + // Lua + // local arg = {...};local metatable = arg[1]; + // return function(table, index, value) + // if type(table) == 'userdata' then + // if string.find(index,KAGUYA_PROPERTY_PREFIX)~=0 then + // local propfun = metatable[KAGUYA_PROPERTY_PREFIX..index]; + // if propfun then return propfun(table,value) end + // end + // end + // rawset(table,index,value) + // end + static const int table = 1; + static const int key = 2; + static const int value = 3; + static const int metatable = lua_upvalueindex(1); + const char *strkey = lua_tostring(L, 2); + + if (lua_type(L, 1) == LUA_TUSERDATA && is_property_key(strkey)) { + int type = lua_getfield_rtype( + L, metatable, (KAGUYA_PROPERTY_PREFIX + std::string(strkey)).c_str()); + if (type == LUA_TFUNCTION) { + lua_pushvalue(L, table); + lua_pushvalue(L, value); + lua_call(L, 2, 0); + return 0; + } + } + lua_pushvalue(L, key); + lua_pushvalue(L, value); + lua_rawset(L, table); + return 0; +} + +inline int multiple_base_index_function(lua_State *L) { + // Lua + // local arg = {...};local metabases = arg[1]; + // return function(t, k) + // for i = 1,#metabases do + // local v = metabases[i][k] + // if v then + // t[k] = v + // return v end + // end + // end + static const int table = 1; + static const int key = 2; + static const int metabases = lua_upvalueindex(1); + + lua_pushnil(L); + while (lua_next(L, metabases) != 0) { + if (lua_type(L, -1) == LUA_TTABLE) { + lua_pushvalue(L, key); + int type = lua_gettable_rtype(L, -2); + if (type != LUA_TNIL) { + lua_pushvalue(L, key); + lua_pushvalue(L, -2); + lua_settable(L, table); + return 1; + } + } + lua_settop(L, 3); // pop value + } + return 0; +} -namespace kaguya -{ - struct LuaCodeChunk - { - LuaCodeChunk(const std::string& src, const std::string& name = "") :code_(src), chunk_name_(name) {} - LuaCodeChunk(const char* src, const char* name = "") :code_(src), chunk_name_(name ? name : "") {} - std::string code_; - std::string chunk_name_; - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaCodeChunk - template<> struct lua_type_traits { - static int push(lua_State* state, const LuaCodeChunk& ref) - { - int status = luaL_loadbuffer(state, ref.code_.c_str(), ref.code_.size(), ref.chunk_name_.empty() ? ref.code_.c_str() : ref.chunk_name_.c_str()); - if (!except::checkErrorAndThrow(status, state)) { return 0; } - return 1; - } - }; - struct LuaCodeChunkExecute : LuaCodeChunk { - LuaCodeChunkExecute(const std::string& src, const std::string& name = "") :LuaCodeChunk(src, name) {} - LuaCodeChunkExecute(const char* src, const char* name = "") :LuaCodeChunk(src, name) {} - }; - typedef LuaCodeChunkExecute LuaCodeChunkResult; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for LuaCodeChunkResult - template<> struct lua_type_traits { - static int push(lua_State* state, const LuaCodeChunkExecute& ref) - { - int status = luaL_loadbuffer(state, ref.code_.c_str(), ref.code_.size(), ref.chunk_name_.empty()? ref.code_.c_str(): ref.chunk_name_.c_str()); - if (!except::checkErrorAndThrow(status, state)) { return 0; } - status = lua_pcall_wrap(state, 0, 1); - if (!except::checkErrorAndThrow(status, state)) { return 0; } - return 1; - } - }; - - - namespace Metatable - { - typedef std::map PropMapType; - typedef std::map MemberMapType; - - - inline bool is_property_key(const char* keyname) - { - return keyname && strncmp(keyname, KAGUYA_PROPERTY_PREFIX, sizeof(KAGUYA_PROPERTY_PREFIX) - 1) != 0; - } - inline int property_index_function(lua_State* L) - { - //Lua - //local arg = {...};local metatable = arg[1]; - //return function(table, index) - //if string.find(index,KAGUYA_PROPERTY_PREFIX)~=0 then - //local propfun = metatable[KAGUYA_PROPERTY_PREFIX ..index]; - //if propfun then return propfun(table) end - //end - //return metatable[index] - //end - static const int table = 1; - static const int key = 2; - static const int metatable = lua_upvalueindex(1); - const char* strkey = lua_tostring(L, key); - - if (lua_type(L, 1) == LUA_TUSERDATA && is_property_key(strkey)) - { - int type = lua_getfield_rtype(L, metatable, (KAGUYA_PROPERTY_PREFIX + std::string(strkey)).c_str()); - if (type == LUA_TFUNCTION) - { - lua_pushvalue(L, table); - lua_call(L, 1, 1); - return 1; - } - } - lua_pushvalue(L, key); - lua_gettable(L, metatable); - return 1; - } - inline int property_newindex_function(lua_State* L) - { - //Lua - //local arg = {...};local metatable = arg[1]; - // return function(table, index, value) - // if type(table) == 'userdata' then - // if string.find(index,KAGUYA_PROPERTY_PREFIX)~=0 then - // local propfun = metatable[KAGUYA_PROPERTY_PREFIX..index]; - // if propfun then return propfun(table,value) end - // end - // end - // rawset(table,index,value) - // end - static const int table = 1; - static const int key = 2; - static const int value = 3; - static const int metatable = lua_upvalueindex(1); - const char* strkey = lua_tostring(L, 2); - - if (lua_type(L, 1) == LUA_TUSERDATA && is_property_key(strkey)) - { - int type = lua_getfield_rtype(L, metatable, (KAGUYA_PROPERTY_PREFIX + std::string(strkey)).c_str()); - if (type == LUA_TFUNCTION) - { - lua_pushvalue(L, table); - lua_pushvalue(L, value); - lua_call(L, 2, 0); - return 0; - } - } - lua_pushvalue(L, key); - lua_pushvalue(L, value); - lua_rawset(L, table); - return 0; - } - - - inline int multiple_base_index_function(lua_State* L) - { - //Lua - //local arg = {...};local metabases = arg[1]; - //return function(t, k) - // for i = 1,#metabases do - // local v = metabases[i][k] - // if v then - // t[k] = v - // return v end - // end - //end - static const int table = 1; - static const int key = 2; - static const int metabases = lua_upvalueindex(1); - - lua_pushnil(L); - while (lua_next(L, metabases) != 0) - { - if (lua_type(L, -1) == LUA_TTABLE) - { - lua_pushvalue(L, key); - int type = lua_gettable_rtype(L, -2); - if (type != LUA_TNIL) - { - lua_pushvalue(L, key); - lua_pushvalue(L, -2); - lua_settable(L, table); - return 1; - } - } - lua_settop(L, 3);//pop value - } - return 0; - } - - - inline int call_constructor_function(lua_State* L) - { - //function(t,...) return t.new(...) end - lua_getfield(L, 1, "new"); - lua_replace(L, 1); - lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); - return lua_gettop(L); - } - inline void get_call_constructor_metatable(lua_State* L) - { - static int key = 0; - - int ttype = lua_rawgetp_rtype(L, LUA_REGISTRYINDEX, &key); - if (ttype != LUA_TTABLE) - { - lua_pop(L, 1); - lua_createtable(L, 0, 1); - lua_pushstring(L, "__call"); - lua_pushcfunction(L, &call_constructor_function); - lua_rawset(L, -3); - lua_pushvalue(L, -1); - lua_rawsetp(L, LUA_REGISTRYINDEX, &key); - } - } - - inline void setMembers(lua_State* state, int metatable_index, const MemberMapType& member_map, const PropMapType& property_map) - { - for (MemberMapType::const_iterator it = member_map.begin(); it != member_map.end(); ++it) - { - util::one_push(state,it->first); - util::one_push(state,it->second); - lua_rawset(state, metatable_index); - } - for (PropMapType::const_iterator it = property_map.begin(); it != property_map.end(); ++it) - { - util::one_push(state, KAGUYA_PROPERTY_PREFIX + it->first); - util::one_push(state, it->second); - lua_rawset(state, metatable_index); - } - } - - inline void setPropertyIndexMetamethod(lua_State* state, int metatable_index) - { - lua_pushstring(state, "__index"); - lua_pushvalue(state, metatable_index); - lua_pushcclosure(state, &property_index_function, 1); - lua_rawset(state, metatable_index); - } - - inline void setPropertyNewIndexMetamethod(lua_State* state, int metatable_index) - { - lua_pushstring(state, "__newindex"); - lua_pushvalue(state, metatable_index); - lua_pushcclosure(state, &property_newindex_function, 1); - lua_rawset(state, metatable_index); - } - inline void setMultipleBase(lua_State* state, int metatable_index, int metabase_array_index) - { - lua_createtable(state,0,1); - int newmetaindex = lua_gettop(state); - lua_pushstring(state, "__index"); - lua_pushvalue(state, metabase_array_index);//bind metabase_array to multiple_base_index_function - lua_pushcclosure(state, &multiple_base_index_function, 1); - lua_rawset(state, newmetaindex);//newmeta["__index"] = multiple_base_index_function - lua_setmetatable(state, metatable_index); // metatable.setMetatable(newmeta); - } - } - - /// class binding interface. - template - class UserdataMetatable - { - public: - - UserdataMetatable() - { - addStaticFunction("__gc", &class_userdata::destructor); - - KAGUYA_STATIC_ASSERT(is_registerable::value || !traits::is_std_vector::value, "std::vector is binding to lua-table by default.If you wants register for std::vector yourself," - "please define KAGUYA_NO_STD_VECTOR_TO_TABLE"); - - KAGUYA_STATIC_ASSERT(is_registerable::value || !traits::is_std_map::value, "std::map is binding to lua-table by default.If you wants register for std::map yourself," - "please define KAGUYA_NO_STD_MAP_TO_TABLE"); - - //can not register push specialized class - KAGUYA_STATIC_ASSERT(is_registerable::value, - "Can not register specialized of type conversion class. e.g. std::tuple"); - } - - LuaTable createMatatable(lua_State* state)const - { - util::ScopedSavedStack save(state); - if (!class_userdata::newmetatable(state)) - { - except::OtherError(state, typeid(class_type*).name() + std::string(" is already registered")); - return LuaTable(); - } - int metatable_index = lua_gettop(state); - Metatable::setMembers(state, metatable_index,member_map_,property_map_); - - if (!traits::is_same::value || !property_map_.empty())//if base class has property and derived class hasnt property. need property access metamethod - { - if (member_map_.count("__index") == 0) - { - Metatable::setPropertyIndexMetamethod(state, metatable_index); - } - - if (member_map_.count("__newindex") == 0) - { - Metatable::setPropertyNewIndexMetamethod(state, metatable_index); - } - } - else - { - if (member_map_.count("__index") == 0) - { - lua_pushstring(state, "__index"); - lua_pushvalue(state, metatable_index); - lua_rawset(state, metatable_index); - } - } - - set_base_metatable(state, metatable_index, types::typetag()); - - if (lua_getmetatable(state, metatable_index))//get base_metatable - { - lua_pushstring(state, "__call"); - lua_pushcfunction(state, &Metatable::call_constructor_function); - lua_rawset(state,-3);//base_metatable["__call"] = Metatable::call_constructor_function - } - else - { - Metatable::get_call_constructor_metatable(state); - lua_setmetatable(state, metatable_index); - } - - return LuaStackRef(state, metatable_index); - } +inline int call_constructor_function(lua_State *L) { + // function(t,...) return t.new(...) end + lua_getfield(L, 1, "new"); + lua_replace(L, 1); + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + return lua_gettop(L); +} +inline void get_call_constructor_metatable(lua_State *L) { + static int key = 0; + + int ttype = lua_rawgetp_rtype(L, LUA_REGISTRYINDEX, &key); + if (ttype != LUA_TTABLE) { + lua_pop(L, 1); + lua_createtable(L, 0, 1); + lua_pushstring(L, "__call"); + lua_pushcfunction(L, &call_constructor_function); + lua_rawset(L, -3); + lua_pushvalue(L, -1); + lua_rawsetp(L, LUA_REGISTRYINDEX, &key); + } +} +inline void setMembers(lua_State *state, int metatable_index, + const MemberMapType &member_map, + const PropMapType &property_map) { + for (MemberMapType::const_iterator it = member_map.begin(); + it != member_map.end(); ++it) { + util::one_push(state, it->first); + util::one_push(state, it->second); + lua_rawset(state, metatable_index); + } + for (PropMapType::const_iterator it = property_map.begin(); + it != property_map.end(); ++it) { + util::one_push(state, KAGUYA_PROPERTY_PREFIX + it->first); + util::one_push(state, it->second); + lua_rawset(state, metatable_index); + } +} + +inline void setPropertyIndexMetamethod(lua_State *state, int metatable_index) { + lua_pushstring(state, "__index"); + lua_pushvalue(state, metatable_index); + lua_pushcclosure(state, &property_index_function, 1); + lua_rawset(state, metatable_index); +} + +inline void setPropertyNewIndexMetamethod(lua_State *state, + int metatable_index) { + lua_pushstring(state, "__newindex"); + lua_pushvalue(state, metatable_index); + lua_pushcclosure(state, &property_newindex_function, 1); + lua_rawset(state, metatable_index); +} +inline void setMultipleBase(lua_State *state, int metatable_index, + int metabase_array_index) { + lua_createtable(state, 0, 1); + int newmetaindex = lua_gettop(state); + lua_pushstring(state, "__index"); + lua_pushvalue(state, metabase_array_index); // bind metabase_array to + // multiple_base_index_function + lua_pushcclosure(state, &multiple_base_index_function, 1); + lua_rawset(state, + newmetaindex); // newmeta["__index"] = multiple_base_index_function + lua_setmetatable(state, metatable_index); // metatable.setMetatable(newmeta); +} +} + +/// class binding interface. +template +class UserdataMetatable { +public: + UserdataMetatable() { + addStaticFunction("__gc", &class_userdata::destructor); + + KAGUYA_STATIC_ASSERT(is_registerable::value || + !traits::is_std_vector::value, + "std::vector is binding to lua-table by default.If " + "you wants register for std::vector yourself," + "please define KAGUYA_NO_STD_VECTOR_TO_TABLE"); + + KAGUYA_STATIC_ASSERT(is_registerable::value || + !traits::is_std_map::value, + "std::map is binding to lua-table by default.If you " + "wants register for std::map yourself," + "please define KAGUYA_NO_STD_MAP_TO_TABLE"); + + // can not register push specialized class + KAGUYA_STATIC_ASSERT(is_registerable::value, + "Can not register specialized of type conversion " + "class. e.g. std::tuple"); + } + + LuaTable createMatatable(lua_State *state) const { + util::ScopedSavedStack save(state); + if (!class_userdata::newmetatable(state)) { + except::OtherError(state, typeid(class_type *).name() + + std::string(" is already registered")); + return LuaTable(); + } + int metatable_index = lua_gettop(state); + Metatable::setMembers(state, metatable_index, member_map_, property_map_); + + if (!traits::is_same::value || + !property_map_.empty()) // if base class has property and derived class + // hasnt property. need property access + // metamethod + { + if (member_map_.count("__index") == 0) { + Metatable::setPropertyIndexMetamethod(state, metatable_index); + } + + if (member_map_.count("__newindex") == 0) { + Metatable::setPropertyNewIndexMetamethod(state, metatable_index); + } + } else { + if (member_map_.count("__index") == 0) { + lua_pushstring(state, "__index"); + lua_pushvalue(state, metatable_index); + lua_rawset(state, metatable_index); + } + } + + set_base_metatable(state, metatable_index, + types::typetag()); + + if (lua_getmetatable(state, metatable_index)) // get base_metatable + { + lua_pushstring(state, "__call"); + lua_pushcfunction(state, &Metatable::call_constructor_function); + lua_rawset(state, -3); // base_metatable["__call"] = + // Metatable::call_constructor_function + } else { + Metatable::get_call_constructor_metatable(state); + lua_setmetatable(state, metatable_index); + } + + return LuaStackRef(state, metatable_index); + } #if KAGUYA_USE_CPP11 - template - UserdataMetatable& setConstructors() - { - addOverloadedFunctions("new", typename ConstructorFunction::type()...); - return *this; - } -#else -#define KAGUYA_SET_CON_TYPE_DEF(N) typename ConstructorFunction::type() -#define KAGUYA_SET_CON_FN_DEF(N) \ - template\ - inline UserdataMetatable& setConstructors()\ - {\ - addOverloadedFunctions("new",KAGUYA_PP_REPEAT_ARG(N,KAGUYA_SET_CON_TYPE_DEF));\ - return *this;\ - } - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_SET_CON_FN_DEF) + template UserdataMetatable &setConstructors() { + addOverloadedFunctions( + "new", typename ConstructorFunction::type()...); + return *this; + } +#else +#define KAGUYA_SET_CON_TYPE_DEF(N) \ + typename ConstructorFunction::type() +#define KAGUYA_SET_CON_FN_DEF(N) \ + template \ + inline UserdataMetatable &setConstructors() { \ + addOverloadedFunctions("new", \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_SET_CON_TYPE_DEF)); \ + return *this; \ + } + + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_SET_CON_FN_DEF) #undef KAGUYA_SET_CON_FN_DEF #undef KAGUYA_SET_CON_TYPE_DEF #endif - - /// @brief add member property with getter function.(experimental) - /// @param name function name for lua - /// @param mem bind member data - template - UserdataMetatable& addProperty(const char* name, Ret class_type::* mem) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(kaguya::function(mem)); - return *this; - } - - /// @brief add member property with getter function.(experimental) - /// @param name function name for lua - /// @param getter getter function - template - UserdataMetatable& addProperty(const char* name, GetType(class_type::*getter)()const) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(kaguya::function(getter)); - return *this; - } - - /// @brief add member property with setter, getter functions.(experimental) - /// @param name function name for lua - /// @param getter getter function - /// @param setter setter function - template - UserdataMetatable& addProperty(const char* name, GetType(*getter)(const class_type*)) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(function(getter)); - return *this; - } - /// @brief add member property with setter, getter functions.(experimental) - /// @param name function name for lua - /// @param getter getter function - /// @param setter setter function - template - UserdataMetatable& addProperty(const char* name, GetType(*getter)(const class_type&)) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(function(getter)); - return *this; - } - - /// @brief add member property with setter, getter functions.(experimental) - /// @param name function name for lua - /// @param getter getter function - /// @param setter setter function - template - UserdataMetatable& addProperty(const char* name, GetType(class_type::*getter)()const, void (class_type::*setter)(SetType)) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(overload(getter, setter)); - return *this; - } - - - /// @brief add member property with external setter, getter functions.(experimental) - /// @param name function name for lua - /// @param getter getter function - /// @param setter setter function - template - UserdataMetatable& addProperty(const char* name, GetType(*getter)(const class_type*), void (*setter)(class_type*, SetType)) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(overload(getter, setter)); - return *this; - } - - /// @brief add member property with external setter, getter functions.(experimental) - /// @param name function name for lua - /// @param getter getter function - /// @param setter setter function - template - UserdataMetatable& addProperty(const char* name, GetType(*getter)(const class_type&), void(*setter)(class_type&, SetType)) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(overload(getter, setter)); - return *this; - } - - /// @brief add member property with getter function.(experimental) - /// @param name function name for lua - /// @param getter getter function - template - UserdataMetatable& addPropertyAny(const char* name, GetterType getter) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(function(getter)); - return *this; - } - /// @brief add member property with setter, getter functions.(experimental) - /// @param name function name for lua - /// @param getter getter function - /// @param setter setter function - template - UserdataMetatable& addPropertyAny(const char* name, GetterType getter, SetterType setter) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - property_map_[name] = AnyDataPusher(overload(getter, setter)); - return *this; - } - - /// @brief add non member function - /// @param name function name for lua - /// @param f function - template - UserdataMetatable& addStaticFunction(const char* name, Fun f) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - member_map_[name] = AnyDataPusher(kaguya::function(f)); - return *this; - } + /// @brief add member property with getter function.(experimental) + /// @param name function name for lua + /// @param mem bind member data + template + UserdataMetatable &addProperty(const char *name, Ret class_type::*mem) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(kaguya::function(mem)); + return *this; + } + + /// @brief add member property with getter function.(experimental) + /// @param name function name for lua + /// @param getter getter function + template + UserdataMetatable &addProperty(const char *name, + GetType (class_type::*getter)() const) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(kaguya::function(getter)); + return *this; + } + + /// @brief add member property with setter, getter functions.(experimental) + /// @param name function name for lua + /// @param getter getter function + /// @param setter setter function + template + UserdataMetatable &addProperty(const char *name, + GetType (*getter)(const class_type *)) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(function(getter)); + return *this; + } + /// @brief add member property with setter, getter functions.(experimental) + /// @param name function name for lua + /// @param getter getter function + /// @param setter setter function + template + UserdataMetatable &addProperty(const char *name, + GetType (*getter)(const class_type &)) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(function(getter)); + return *this; + } + + /// @brief add member property with setter, getter functions.(experimental) + /// @param name function name for lua + /// @param getter getter function + /// @param setter setter function + template + UserdataMetatable &addProperty(const char *name, + GetType (class_type::*getter)() const, + void (class_type::*setter)(SetType)) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(overload(getter, setter)); + return *this; + } + + /// @brief add member property with external setter, getter + /// functions.(experimental) + /// @param name function name for lua + /// @param getter getter function + /// @param setter setter function + template + UserdataMetatable &addProperty(const char *name, + GetType (*getter)(const class_type *), + void (*setter)(class_type *, SetType)) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(overload(getter, setter)); + return *this; + } + + /// @brief add member property with external setter, getter + /// functions.(experimental) + /// @param name function name for lua + /// @param getter getter function + /// @param setter setter function + template + UserdataMetatable &addProperty(const char *name, + GetType (*getter)(const class_type &), + void (*setter)(class_type &, SetType)) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(overload(getter, setter)); + return *this; + } + + /// @brief add member property with getter function.(experimental) + /// @param name function name for lua + /// @param getter getter function + template + UserdataMetatable &addPropertyAny(const char *name, GetterType getter) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(function(getter)); + return *this; + } + /// @brief add member property with setter, getter functions.(experimental) + /// @param name function name for lua + /// @param getter getter function + /// @param setter setter function + template + UserdataMetatable &addPropertyAny(const char *name, GetterType getter, + SetterType setter) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + property_map_[name] = AnyDataPusher(overload(getter, setter)); + return *this; + } + + /// @brief add non member function + /// @param name function name for lua + /// @param f function + template + UserdataMetatable &addStaticFunction(const char *name, Fun f) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + member_map_[name] = AnyDataPusher(kaguya::function(f)); + return *this; + } #if KAGUYA_USE_CPP11 - /// @brief assign overloaded from functions. - /// @param name name for lua - /// @param f functions - template - UserdataMetatable& addOverloadedFunctions(const char* name, Funcs... f) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - - member_map_[name] = AnyDataPusher(overload(f...)); - - return *this; - } - - /// @brief assign data by argument value. - /// @param name name for lua - /// @param d data - template - UserdataMetatable& addStaticField(const char* name, Data&& d) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - member_map_[name] = AnyDataPusher(std::forward(d)); - return *this; - } + /// @brief assign overloaded from functions. + /// @param name name for lua + /// @param f functions + template + UserdataMetatable &addOverloadedFunctions(const char *name, Funcs... f) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + + member_map_[name] = AnyDataPusher(overload(f...)); + + return *this; + } + + /// @brief assign data by argument value. + /// @param name name for lua + /// @param d data + template + UserdataMetatable &addStaticField(const char *name, Data &&d) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + member_map_[name] = AnyDataPusher(std::forward(d)); + return *this; + } #else -#define KAGUYA_ADD_OVERLOAD_FUNCTION_DEF(N) template\ - inline UserdataMetatable& addOverloadedFunctions(const char* name,KAGUYA_PP_ARG_CR_DEF_REPEAT(N))\ - {\ - if (has_key(name))\ - {\ - throw KaguyaException(std::string(name) + " is already registered.");\ - return *this;\ - }\ - member_map_[name] = AnyDataPusher(kaguya::overload(KAGUYA_PP_ARG_REPEAT(N)));\ - return *this;\ - } - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_ADD_OVERLOAD_FUNCTION_DEF) +#define KAGUYA_ADD_OVERLOAD_FUNCTION_DEF(N) \ + template \ + inline UserdataMetatable &addOverloadedFunctions( \ + const char *name, KAGUYA_PP_ARG_CR_DEF_REPEAT(N)) { \ + if (has_key(name)) { \ + throw KaguyaException(std::string(name) + " is already registered."); \ + return *this; \ + } \ + member_map_[name] = \ + AnyDataPusher(kaguya::overload(KAGUYA_PP_ARG_REPEAT(N))); \ + return *this; \ + } + + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, + KAGUYA_ADD_OVERLOAD_FUNCTION_DEF) #undef KAGUYA_ADD_OVERLOAD_FUNCTION_DEF - /// @brief assign data by argument value. - /// @param name name for lua - /// @param d data - template - UserdataMetatable& addStaticField(const char* name, const Data& d) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered."); - return *this; - } - member_map_[name] = AnyDataPusher(d); - return *this; - } + /// @brief assign data by argument value. + /// @param name name for lua + /// @param d data + template + UserdataMetatable &addStaticField(const char *name, const Data &d) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered."); + return *this; + } + member_map_[name] = AnyDataPusher(d); + return *this; + } #endif #if defined(_MSC_VER) && _MSC_VER <= 1800 - //can not write Ret class_type::* f on MSC++2013 - template - UserdataMetatable& addFunction(const char* name, Fun f) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered. To overload a function, use addOverloadedFunctions"); - return *this; - } - member_map_[name] = AnyDataPusher(kaguya::function(f)); - return *this; - } + // can not write Ret class_type::* f on MSC++2013 + template + UserdataMetatable &addFunction(const char *name, Fun f) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered. To " + "overload a function, use " + "addOverloadedFunctions"); + return *this; + } + member_map_[name] = AnyDataPusher(kaguya::function(f)); + return *this; + } #else - /// @brief assign function - /// @param name name for lua - /// @param f pointer to member function. - template - UserdataMetatable& addFunction(const char* name, Ret class_type::* f) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered. To overload a function, use addOverloadedFunctions"); - return *this; - } - member_map_[name] = AnyDataPusher(kaguya::function(f)); - return *this; - } + /// @brief assign function + /// @param name name for lua + /// @param f pointer to member function. + template + UserdataMetatable &addFunction(const char *name, Ret class_type::*f) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered. To " + "overload a function, use " + "addOverloadedFunctions"); + return *this; + } + member_map_[name] = AnyDataPusher(kaguya::function(f)); + return *this; + } #endif - /// @brief assign function - /// @param name name for lua - /// @param f member function object. - UserdataMetatable& addFunction(const char* name, PolymorphicMemberInvoker f) - { - if (has_key(name)) - { - throw KaguyaException(std::string(name) + " is already registered. To overload a function, use addOverloadedFunctions"); - return *this; - } - member_map_[name] = AnyDataPusher(kaguya::function(f)); - return *this; - } - private: - - void set_base_metatable(lua_State* , int , types::typetag)const - { - } - template - void set_base_metatable(lua_State* state, int metatable_index, types::typetag)const - { - class_userdata::get_metatable(state); - lua_setmetatable(state, metatable_index); // metatable.setMetatable(newmeta); - PointerConverter& pconverter = PointerConverter::get(state); - pconverter.add_type_conversion(); - } + /// @brief assign function + /// @param name name for lua + /// @param f member function object. + UserdataMetatable &addFunction(const char *name, PolymorphicMemberInvoker f) { + if (has_key(name)) { + throw KaguyaException(std::string(name) + " is already registered. To " + "overload a function, use " + "addOverloadedFunctions"); + return *this; + } + member_map_[name] = AnyDataPusher(kaguya::function(f)); + return *this; + } + +private: + void set_base_metatable(lua_State *, int, types::typetag) const {} + template + void set_base_metatable(lua_State *state, int metatable_index, + types::typetag) const { + class_userdata::get_metatable(state); + lua_setmetatable(state, + metatable_index); // metatable.setMetatable(newmeta); + PointerConverter &pconverter = PointerConverter::get(state); + pconverter.add_type_conversion(); + } #if KAGUYA_USE_CPP11 - template - void metatables(lua_State* state, int metabase_array_index, PointerConverter& pvtreg, types::typetag >)const - { - class_userdata::get_metatable(state); - lua_rawseti(state, metabase_array_index, lua_rawlen(state, metabase_array_index) + 1); - pvtreg.add_type_conversion(); - } - template - void metatables(lua_State* state, int metabase_array_index, PointerConverter& pvtreg, types::typetag >)const - { - class_userdata::get_metatable(state); - lua_rawseti(state, metabase_array_index, lua_rawlen(state, metabase_array_index) + 1); - pvtreg.add_type_conversion(); - metatables(state, metabase_array_index, pvtreg, types::typetag >()); - } - - template - void set_base_metatable(lua_State* state, int metatable_index, types::typetag > metatypes)const - { - PointerConverter& pconverter = PointerConverter::get(state); - - lua_createtable(state, sizeof...(Bases), 0); - int metabase_array_index = lua_gettop(state); - metatables(state, metabase_array_index, pconverter, metatypes); - Metatable::setMultipleBase(state, metatable_index, metabase_array_index); - } + template + void metatables(lua_State *state, int metabase_array_index, + PointerConverter &pvtreg, + types::typetag >) const { + class_userdata::get_metatable(state); + lua_rawseti(state, metabase_array_index, + lua_rawlen(state, metabase_array_index) + 1); + pvtreg.add_type_conversion(); + } + template + void metatables(lua_State *state, int metabase_array_index, + PointerConverter &pvtreg, + types::typetag >) const { + class_userdata::get_metatable(state); + lua_rawseti(state, metabase_array_index, + lua_rawlen(state, metabase_array_index) + 1); + pvtreg.add_type_conversion(); + metatables(state, metabase_array_index, pvtreg, + types::typetag >()); + } + + template + void + set_base_metatable(lua_State *state, int metatable_index, + types::typetag > metatypes) const { + PointerConverter &pconverter = PointerConverter::get(state); + + lua_createtable(state, sizeof...(Bases), 0); + int metabase_array_index = lua_gettop(state); + metatables(state, metabase_array_index, pconverter, metatypes); + Metatable::setMultipleBase(state, metatable_index, metabase_array_index); + } #else -#define KAGUYA_GET_BASE_METATABLE(N) class_userdata::get_metatable(state);\ - lua_rawseti(state, metabase_array_index, lua_rawlen(state, metabase_array_index) + 1); \ - pconverter.add_type_conversion(); -#define KAGUYA_MULTIPLE_INHERITANCE_SETBASE_DEF(N) \ - template\ - void set_base_metatable(lua_State* state, int metatable_index, types::typetag > )const\ - {\ - PointerConverter& pconverter = PointerConverter::get(state);\ - lua_createtable(state, N, 0);\ - int metabase_array_index = lua_gettop(state);\ - KAGUYA_PP_REPEAT(N, KAGUYA_GET_BASE_METATABLE); \ - Metatable::setMultipleBase(state, metatable_index, metabase_array_index);\ - }\ - - KAGUYA_PP_REPEAT_DEF(KAGUYA_CLASS_MAX_BASE_CLASSES, KAGUYA_MULTIPLE_INHERITANCE_SETBASE_DEF) +#define KAGUYA_GET_BASE_METATABLE(N) \ + class_userdata::get_metatable(state); \ + lua_rawseti(state, metabase_array_index, \ + lua_rawlen(state, metabase_array_index) + 1); \ + pconverter.add_type_conversion(); +#define KAGUYA_MULTIPLE_INHERITANCE_SETBASE_DEF(N) \ + template \ + void set_base_metatable( \ + lua_State *state, int metatable_index, \ + types::typetag >) const { \ + PointerConverter &pconverter = PointerConverter::get(state); \ + lua_createtable(state, N, 0); \ + int metabase_array_index = lua_gettop(state); \ + KAGUYA_PP_REPEAT(N, KAGUYA_GET_BASE_METATABLE); \ + Metatable::setMultipleBase(state, metatable_index, metabase_array_index); \ + } + + KAGUYA_PP_REPEAT_DEF(KAGUYA_CLASS_MAX_BASE_CLASSES, + KAGUYA_MULTIPLE_INHERITANCE_SETBASE_DEF) #undef KAGUYA_MULTIPLE_INHERITANCE_SETBASE_DEF #undef KAGUYA_GET_BASE_METATABLE #endif - bool has_key(const std::string& key) - { - if (member_map_.count(key) > 0) - { - return true; - } - if (property_map_.count(key) > 0) - { - return true; - } - std::string propkey = KAGUYA_PROPERTY_PREFIX + key; - if (member_map_.count(propkey) > 0)//_prop_keyname is reserved for property - { - return true; - } - return false; - } - - Metatable::PropMapType property_map_; - Metatable::MemberMapType member_map_; - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for UserdataMetatable - template struct lua_type_traits > { - typedef const UserdataMetatable& push_type; - - static int push(lua_State* l, push_type ref) - { - return ref.createMatatable(l).push(l); - } - }; + bool has_key(const std::string &key) { + if (member_map_.count(key) > 0) { + return true; + } + if (property_map_.count(key) > 0) { + return true; + } + std::string propkey = KAGUYA_PROPERTY_PREFIX + key; + if (member_map_.count(propkey) > 0) //_prop_keyname is reserved for property + { + return true; + } + return false; + } + + Metatable::PropMapType property_map_; + Metatable::MemberMapType member_map_; +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for UserdataMetatable +template +struct lua_type_traits > { + typedef const UserdataMetatable &push_type; + + static int push(lua_State *l, push_type ref) { + return ref.createMatatable(l).push(l); + } +}; } diff --git a/include/kaguya/native_function.hpp b/include/kaguya/native_function.hpp index 648af53..c441553 100644 --- a/include/kaguya/native_function.hpp +++ b/include/kaguya/native_function.hpp @@ -22,1050 +22,946 @@ #include "kaguya/function_tuple_def.hpp" -namespace kaguya -{ - struct FunctionImpl - { - virtual int invoke(lua_State *state) = 0; - virtual std::string argTypesName()const = 0; - virtual bool checkArgTypes(lua_State* state)const = 0; - virtual bool strictCheckArgTypes(lua_State* state)const = 0; - virtual int minArgCount()const=0; - virtual int maxArgCount()const=0; - virtual ~FunctionImpl() {} - }; - struct PolymorphicInvoker - { - typedef standard::shared_ptr holder_type; - PolymorphicInvoker(const holder_type& fptr) :fnc(fptr) {} - int invoke(lua_State *state)const { return fnc->invoke(state); } - std::string argTypesName()const { return fnc->argTypesName(); } - bool checkArgTypes(lua_State* state)const { return fnc->checkArgTypes(state); } - bool strictCheckArgTypes(lua_State* state)const { return fnc->strictCheckArgTypes(state); } - int minArgCount()const { return fnc->minArgCount(); } - int maxArgCount()const { return fnc->maxArgCount(); } - ~PolymorphicInvoker() {} - private: - holder_type fnc; - }; - struct PolymorphicMemberInvoker : PolymorphicInvoker{ - PolymorphicMemberInvoker(const holder_type& fptr) :PolymorphicInvoker(fptr) {} - }; - - namespace nativefunction - { - template - typename lua_type_traits::type>::get_type - getArgument(lua_State* state) - { - return lua_type_traits::type>::get(state, INDEX + 1); - } - - - template< typename T, typename Enable = void> - struct is_callable : traits::integral_constant::type>::value> {}; - - template - struct is_callable : traits::integral_constant {}; - - - - template - struct is_callable > :traits::integral_constant {}; - - // for constructors - template - int call(lua_State* state, ConstructorFunctor& con) - { - return con(state); - } - template - int call(lua_State* state, const ConstructorFunctor& con) - { - return con(state); - } - template - bool checkArgTypes(lua_State* state, const ConstructorFunctor& con, int opt_count = 0) - { - return con.checkArgTypes(state, opt_count); - } - template - bool strictCheckArgTypes(lua_State* state, const ConstructorFunctor& con, int opt_count = 0) - { - return con.strictCheckArgTypes(state, opt_count); - } - template - std::string argTypesName(const ConstructorFunctor& con) - { - return con.argTypesName(); - } - template - int minArgCount(const ConstructorFunctor& ) - { - return ConstructorFunctor::signature_type::argument_count; - } - template - int maxArgCount(const ConstructorFunctor& ) - { - return ConstructorFunctor::signature_type::argument_count; - } - - - // for data member - //using is_member_function_pointer in MSVC2010 : fatal error LNK1179: invalid or corrupt file: duplicate COMDAT '?value@?$result_@P8ABC@test_02_classreg@@AE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ@?$is_mem_fun_pointer_select@$0A@@detail@boost@@2_NB' - template - typename traits::enable_if::value, int>::type - call(lua_State* state, MemType T::* mptr) - { - T* this_ = lua_type_traits::get(state, 1); - if (lua_gettop(state) == 1) - { - if (!this_) - { - const T& this_ = lua_type_traits::get(state, 1); - if (is_usertype::value && !traits::is_pointer::value) - { - return util::push_args(state, standard::reference_wrapper(this_.*mptr)); - } - else - { - return util::push_args(state, this_.*mptr); - } - } - else - { - if (is_usertype::value && !traits::is_pointer::value) - { - return util::push_args(state, standard::reference_wrapper(this_->*mptr)); - } - else - { - return util::push_args(state, this_->*mptr); - } - } - } - else - { - if (!this_) - { - throw LuaTypeMismatch(); - } - this_->*mptr = lua_type_traits::get(state, 2); - return 0; - } - } - template - typename traits::enable_if::value, bool>::type - checkArgTypes(lua_State* state, MemType T::* , int opt_count = 0) - { - KAGUYA_UNUSED(opt_count); - if (lua_gettop(state) >= 2) - { - //setter typecheck - return lua_type_traits::checkType(state, 2) && lua_type_traits::checkType(state, 1); - } - //getter typecheck - return lua_type_traits::checkType(state, 1); - } - template - typename traits::enable_if::value, bool>::type - strictCheckArgTypes(lua_State* state, MemType T::* , int opt_count = 0) - { - KAGUYA_UNUSED(opt_count); - if (lua_gettop(state) == 2) - { - //setter typecheck - return lua_type_traits::strictCheckType(state, 2) && lua_type_traits::strictCheckType(state, 1); - } - //getter typecheck - return lua_type_traits::strictCheckType(state, 1); - } - template - typename traits::enable_if::value, std::string>::type - argTypesName(MemType T::* ) - { - return util::pretty_name(typeid(T*)) + ",[OPT] " + util::pretty_name(typeid(MemType)); - } - template - typename traits::enable_if::value, int>::type - minArgCount(MemType T::* ) - { - return 1; - } - template - typename traits::enable_if::value, int>::type - maxArgCount(MemType T::* ) - { - return 2; - } - - - inline int call(lua_State* state, const PolymorphicInvoker& f) - { - return f.invoke(state); - } - inline int call(lua_State* state, PolymorphicInvoker& f) - { - return f.invoke(state); - } - inline bool checkArgTypes(lua_State* state, const PolymorphicInvoker& f) - { - return f.checkArgTypes(state); - } - inline bool strictCheckArgTypes(lua_State* state, const PolymorphicInvoker& f) - { - return f.strictCheckArgTypes(state); - } - inline std::string argTypesName(const PolymorphicInvoker& f) - { - return f.argTypesName(); - } - inline int minArgCount(const PolymorphicInvoker& f) - { - return f.minArgCount(); - } - inline int maxArgCount(const PolymorphicInvoker& f) - { - return f.maxArgCount(); - } - - - template<> - struct is_callable:traits::integral_constant {}; - - - inline int call(lua_State* state, const PolymorphicMemberInvoker& f) - { - return f.invoke(state); - } - inline int call(lua_State* state, PolymorphicMemberInvoker& f) - { - return f.invoke(state); - } - inline bool checkArgTypes(lua_State* state, const PolymorphicMemberInvoker& f) - { - return f.checkArgTypes(state); - } - inline bool strictCheckArgTypes(lua_State* state, const PolymorphicMemberInvoker& f) - { - return f.strictCheckArgTypes(state); - } - inline std::string argTypesName(const PolymorphicMemberInvoker& f) - { - return f.argTypesName(); - } - inline int minArgCount(const PolymorphicMemberInvoker& f) - { - return f.minArgCount(); - } - inline int maxArgCount(const PolymorphicMemberInvoker& f) - { - return f.maxArgCount(); - } - - template<> - struct is_callable :traits::integral_constant {}; - } - - class VariadicArgType - { - public: - VariadicArgType(lua_State* state, int startIndex) :state_(state), startIndex_(startIndex), endIndex_(lua_gettop(state) + 1) - { - if (startIndex_ > endIndex_) - { - endIndex_ = startIndex_; - } - } - - template - operator std::vector()const - { - if (startIndex_ >= endIndex_) - { - return std::vector(); - } - std::vector result; - result.reserve(endIndex_ - startIndex_); - for (int index = startIndex_; index < endIndex_; ++index) - { - result.push_back(lua_type_traits::get(state_, index)); - } - return result; - } - - struct reference :public Ref::StackRef, public detail::LuaVariantImpl - { - reference(lua_State* s, int index) :Ref::StackRef(s, index, false) - { - } - - const reference* operator->()const - { - return this; - } - }; - - struct iterator - { - typedef std::random_access_iterator_tag iterator_category; - typedef VariadicArgType::reference reference; - typedef int difference_type; - typedef reference value_type; - typedef reference* pointer; - - iterator() :state_(0), stack_index_(0) - { - } - iterator(lua_State* state, int index) :state_(state), stack_index_(index) - { - } - reference operator*()const - { - return reference(state_, stack_index_); - } - reference operator->()const - { - return reference(state_, stack_index_); - } - iterator& operator++() - { - stack_index_++; - return *this; - } - iterator operator++(int) - { - return iterator(state_, stack_index_++); - } - - iterator& operator+=(int n) - { - stack_index_ += n; - return *this; - } - iterator operator+(int n)const - { - return iterator(state_, stack_index_+n); - } - iterator& operator--() - { - stack_index_--; - return *this; - } - iterator operator--(int) - { - return iterator(state_, stack_index_--); - } - iterator& operator-=(int n) - { - stack_index_ -= n; - return *this; - } - iterator operator-(int n)const - { - return iterator(state_, stack_index_ - n); - } - difference_type operator-(const iterator& n) - { - return stack_index_ - n.stack_index_; - } - - reference operator[](difference_type offset)const - { - return reference(state_, stack_index_ + offset); - } - /** - * @name relational operators - * @brief - */ - //@{ - bool operator==(const iterator& other)const - { - return state_ == other.state_ && stack_index_ == other.stack_index_; - } - bool operator!=(const iterator& other)const - { - return !(*this == other); - } - bool operator<(const iterator& other)const - { - return stack_index_ < other.stack_index_; - } - bool operator>(const iterator& other)const - { - return other < *this; - } - bool operator<=(const iterator& other)const - { - return other >= *this; - } - bool operator>=(const iterator& other)const - { - return !(*this < other); - } - //@} - private: - lua_State* state_; - int stack_index_; - }; - typedef iterator const_iterator; - typedef reference const_reference; - typedef reference value_type; - - iterator begin() - { - return iterator(state_, startIndex_); - } - iterator end() - { - return iterator(state_, endIndex_); - } - const_iterator cbegin() - { - return const_iterator(state_, startIndex_); - } - const_iterator cend() - { - return const_iterator(state_, endIndex_); - } - - - template - typename lua_type_traits::get_type at(size_t index)const - { - if (index >= size()) - { - throw std::out_of_range("variadic arguments out of range"); - } - return lua_type_traits::get(state_, startIndex_ + static_cast(index)); - } - - reference at(size_t index)const - { - if (index >= size()) - { - throw std::out_of_range("variadic arguments out of range"); - } - return reference(state_, startIndex_ + static_cast(index)); - } - - reference operator[](size_t index)const - { - return reference(state_, startIndex_ + static_cast(index)); - } - size_t size()const - { - return endIndex_ - startIndex_; - } - size_t empty()const - { - return endIndex_ == startIndex_; - } - private: - lua_State* state_; - int startIndex_; - int endIndex_; - }; - - inline VariadicArgType::iterator operator+(int n,const VariadicArgType::iterator& i) - { - return i + n; - } - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for VariadicArgType - template<> struct lua_type_traits - { - typedef VariadicArgType get_type; - - static bool strictCheckType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return true; - } - static bool checkType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return true; - } - static get_type get(lua_State* l, int index) - { - return VariadicArgType(l, index); - } - }; - - namespace nativefunction - { - static const int MAX_OVERLOAD_SCORE = 255; - templateuint8_t compute_function_matching_score(lua_State* state, const Fn& fn) - { - int argcount = lua_gettop(state); - - - if (strictCheckArgTypes(state, fn)) - { - const int minargcount = minArgCount(fn); - const int maxargcount = maxArgCount(fn); - if (minargcount <= argcount && maxargcount >= argcount) - { - return MAX_OVERLOAD_SCORE; - } - else - { - int diff = std::min(std::abs(argcount - minargcount), std::abs(argcount - maxargcount)); - return std::max(100 - diff, 51); - } - } - else if (checkArgTypes(state, fn)) - { - const int minargcount = minArgCount(fn); - const int maxargcount = maxArgCount(fn); - if (minargcount <= argcount && maxargcount >= argcount) - { - return 200; - } - else - { - int diff = std::min(std::abs(argcount - minargcount), std::abs(argcount - maxargcount)); - return std::max(50 - diff, 1); - } - } - else - { - return 0; - } - } - inline int pushArgmentTypeNames(lua_State *state, int top) - { - for (int i = 1; i <= top; i++) { - if (i != 1) - { - lua_pushliteral(state, ","); - } - - int type = lua_type(state, i); - if (type == LUA_TUSERDATA) - { - int nametype = luaL_getmetafield(state, i, "__name"); - if (nametype != LUA_TSTRING) - { - lua_pop(state, 1); - lua_pushstring(state, lua_typename(state, type)); - } - } - else - { - lua_pushstring(state, lua_typename(state, type)); - } - } - return lua_gettop(state) - top; - } - } +namespace kaguya { +struct FunctionImpl { + virtual int invoke(lua_State *state) = 0; + virtual std::string argTypesName() const = 0; + virtual bool checkArgTypes(lua_State *state) const = 0; + virtual bool strictCheckArgTypes(lua_State *state) const = 0; + virtual int minArgCount() const = 0; + virtual int maxArgCount() const = 0; + virtual ~FunctionImpl() {} +}; +struct PolymorphicInvoker { + typedef standard::shared_ptr holder_type; + PolymorphicInvoker(const holder_type &fptr) : fnc(fptr) {} + int invoke(lua_State *state) const { return fnc->invoke(state); } + std::string argTypesName() const { return fnc->argTypesName(); } + bool checkArgTypes(lua_State *state) const { + return fnc->checkArgTypes(state); + } + bool strictCheckArgTypes(lua_State *state) const { + return fnc->strictCheckArgTypes(state); + } + int minArgCount() const { return fnc->minArgCount(); } + int maxArgCount() const { return fnc->maxArgCount(); } + ~PolymorphicInvoker() {} + +private: + holder_type fnc; +}; +struct PolymorphicMemberInvoker : PolymorphicInvoker { + PolymorphicMemberInvoker(const holder_type &fptr) + : PolymorphicInvoker(fptr) {} +}; + +namespace nativefunction { +template +typename lua_type_traits::type>::get_type +getArgument(lua_State *state) { + return lua_type_traits::type>::get( + state, INDEX + 1); +} + +template +struct is_callable + : traits::integral_constant< + bool, !traits::is_same< + void, typename util::FunctionSignature::type>::value> {}; + +template +struct is_callable : traits::integral_constant {}; + +template +struct is_callable > + : traits::integral_constant {}; + +// for constructors +template int call(lua_State *state, ConstructorFunctor &con) { + return con(state); +} +template +int call(lua_State *state, const ConstructorFunctor &con) { + return con(state); +} +template +bool checkArgTypes(lua_State *state, const ConstructorFunctor &con, + int opt_count = 0) { + return con.checkArgTypes(state, opt_count); +} +template +bool strictCheckArgTypes(lua_State *state, const ConstructorFunctor &con, + int opt_count = 0) { + return con.strictCheckArgTypes(state, opt_count); +} +template std::string argTypesName(const ConstructorFunctor &con) { + return con.argTypesName(); +} +template int minArgCount(const ConstructorFunctor &) { + return ConstructorFunctor::signature_type::argument_count; +} +template int maxArgCount(const ConstructorFunctor &) { + return ConstructorFunctor::signature_type::argument_count; +} + +// for data member +// using is_member_function_pointer in MSVC2010 : fatal error LNK1179: invalid +// or corrupt file: duplicate COMDAT +// '?value@?$result_@P8ABC@test_02_classreg@@AE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ@?$is_mem_fun_pointer_select@$0A@@detail@boost@@2_NB' +template +typename traits::enable_if::value, int>::type +call(lua_State *state, MemType T::*mptr) { + T *this_ = lua_type_traits::get(state, 1); + if (lua_gettop(state) == 1) { + if (!this_) { + const T &this_ = lua_type_traits::get(state, 1); + if (is_usertype::value && !traits::is_pointer::value) { + return util::push_args( + state, standard::reference_wrapper(this_.*mptr)); + } else { + return util::push_args(state, this_.*mptr); + } + } else { + if (is_usertype::value && !traits::is_pointer::value) { + return util::push_args( + state, standard::reference_wrapper(this_->*mptr)); + } else { + return util::push_args(state, this_->*mptr); + } + } + } else { + if (!this_) { + throw LuaTypeMismatch(); + } + this_->*mptr = lua_type_traits::get(state, 2); + return 0; + } +} +template +typename traits::enable_if::value, bool>::type +checkArgTypes(lua_State *state, MemType T::*, int opt_count = 0) { + KAGUYA_UNUSED(opt_count); + if (lua_gettop(state) >= 2) { + // setter typecheck + return lua_type_traits::checkType(state, 2) && + lua_type_traits::checkType(state, 1); + } + // getter typecheck + return lua_type_traits::checkType(state, 1); +} +template +typename traits::enable_if::value, bool>::type +strictCheckArgTypes(lua_State *state, MemType T::*, int opt_count = 0) { + KAGUYA_UNUSED(opt_count); + if (lua_gettop(state) == 2) { + // setter typecheck + return lua_type_traits::strictCheckType(state, 2) && + lua_type_traits::strictCheckType(state, 1); + } + // getter typecheck + return lua_type_traits::strictCheckType(state, 1); +} +template +typename traits::enable_if::value, std::string>::type +argTypesName(MemType T::*) { + return util::pretty_name(typeid(T *)) + ",[OPT] " + + util::pretty_name(typeid(MemType)); +} +template +typename traits::enable_if::value, int>::type +minArgCount(MemType T::*) { + return 1; +} +template +typename traits::enable_if::value, int>::type +maxArgCount(MemType T::*) { + return 2; +} + +inline int call(lua_State *state, const PolymorphicInvoker &f) { + return f.invoke(state); +} +inline int call(lua_State *state, PolymorphicInvoker &f) { + return f.invoke(state); +} +inline bool checkArgTypes(lua_State *state, const PolymorphicInvoker &f) { + return f.checkArgTypes(state); +} +inline bool strictCheckArgTypes(lua_State *state, const PolymorphicInvoker &f) { + return f.strictCheckArgTypes(state); +} +inline std::string argTypesName(const PolymorphicInvoker &f) { + return f.argTypesName(); +} +inline int minArgCount(const PolymorphicInvoker &f) { return f.minArgCount(); } +inline int maxArgCount(const PolymorphicInvoker &f) { return f.maxArgCount(); } + +template <> +struct is_callable : traits::integral_constant { +}; + +inline int call(lua_State *state, const PolymorphicMemberInvoker &f) { + return f.invoke(state); +} +inline int call(lua_State *state, PolymorphicMemberInvoker &f) { + return f.invoke(state); +} +inline bool checkArgTypes(lua_State *state, const PolymorphicMemberInvoker &f) { + return f.checkArgTypes(state); +} +inline bool strictCheckArgTypes(lua_State *state, + const PolymorphicMemberInvoker &f) { + return f.strictCheckArgTypes(state); +} +inline std::string argTypesName(const PolymorphicMemberInvoker &f) { + return f.argTypesName(); +} +inline int minArgCount(const PolymorphicMemberInvoker &f) { + return f.minArgCount(); +} +inline int maxArgCount(const PolymorphicMemberInvoker &f) { + return f.maxArgCount(); +} + +template <> +struct is_callable + : traits::integral_constant {}; +} +class VariadicArgType { +public: + VariadicArgType(lua_State *state, int startIndex) + : state_(state), startIndex_(startIndex), + endIndex_(lua_gettop(state) + 1) { + if (startIndex_ > endIndex_) { + endIndex_ = startIndex_; + } + } + + template operator std::vector() const { + if (startIndex_ >= endIndex_) { + return std::vector(); + } + std::vector result; + result.reserve(endIndex_ - startIndex_); + for (int index = startIndex_; index < endIndex_; ++index) { + result.push_back(lua_type_traits::get(state_, index)); + } + return result; + } + + struct reference : public Ref::StackRef, + public detail::LuaVariantImpl { + reference(lua_State *s, int index) : Ref::StackRef(s, index, false) {} + + const reference *operator->() const { return this; } + }; + + struct iterator { + typedef std::random_access_iterator_tag iterator_category; + typedef VariadicArgType::reference reference; + typedef int difference_type; + typedef reference value_type; + typedef reference *pointer; + + iterator() : state_(0), stack_index_(0) {} + iterator(lua_State *state, int index) + : state_(state), stack_index_(index) {} + reference operator*() const { return reference(state_, stack_index_); } + reference operator->() const { return reference(state_, stack_index_); } + iterator &operator++() { + stack_index_++; + return *this; + } + iterator operator++(int) { return iterator(state_, stack_index_++); } + + iterator &operator+=(int n) { + stack_index_ += n; + return *this; + } + iterator operator+(int n) const { + return iterator(state_, stack_index_ + n); + } + iterator &operator--() { + stack_index_--; + return *this; + } + iterator operator--(int) { return iterator(state_, stack_index_--); } + iterator &operator-=(int n) { + stack_index_ -= n; + return *this; + } + iterator operator-(int n) const { + return iterator(state_, stack_index_ - n); + } + difference_type operator-(const iterator &n) { + return stack_index_ - n.stack_index_; + } + + reference operator[](difference_type offset) const { + return reference(state_, stack_index_ + offset); + } + /** + * @name relational operators + * @brief + */ + //@{ + bool operator==(const iterator &other) const { + return state_ == other.state_ && stack_index_ == other.stack_index_; + } + bool operator!=(const iterator &other) const { return !(*this == other); } + bool operator<(const iterator &other) const { + return stack_index_ < other.stack_index_; + } + bool operator>(const iterator &other) const { return other < *this; } + bool operator<=(const iterator &other) const { return other >= *this; } + bool operator>=(const iterator &other) const { return !(*this < other); } + //@} + private: + lua_State *state_; + int stack_index_; + }; + typedef iterator const_iterator; + typedef reference const_reference; + typedef reference value_type; + + iterator begin() { return iterator(state_, startIndex_); } + iterator end() { return iterator(state_, endIndex_); } + const_iterator cbegin() { return const_iterator(state_, startIndex_); } + const_iterator cend() { return const_iterator(state_, endIndex_); } + + template + typename lua_type_traits::get_type at(size_t index) const { + if (index >= size()) { + throw std::out_of_range("variadic arguments out of range"); + } + return lua_type_traits::get(state_, + startIndex_ + static_cast(index)); + } + + reference at(size_t index) const { + if (index >= size()) { + throw std::out_of_range("variadic arguments out of range"); + } + return reference(state_, startIndex_ + static_cast(index)); + } + + reference operator[](size_t index) const { + return reference(state_, startIndex_ + static_cast(index)); + } + size_t size() const { return endIndex_ - startIndex_; } + size_t empty() const { return endIndex_ == startIndex_; } + +private: + lua_State *state_; + int startIndex_; + int endIndex_; +}; + +inline VariadicArgType::iterator operator+(int n, + const VariadicArgType::iterator &i) { + return i + n; +} +/// @ingroup lua_type_traits +/// @brief lua_type_traits for VariadicArgType +template <> struct lua_type_traits { + typedef VariadicArgType get_type; + + static bool strictCheckType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return true; + } + static bool checkType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return true; + } + static get_type get(lua_State *l, int index) { + return VariadicArgType(l, index); + } +}; + +namespace nativefunction { +static const int MAX_OVERLOAD_SCORE = 255; +template +uint8_t compute_function_matching_score(lua_State *state, const Fn &fn) { + int argcount = lua_gettop(state); + + if (strictCheckArgTypes(state, fn)) { + const int minargcount = minArgCount(fn); + const int maxargcount = maxArgCount(fn); + if (minargcount <= argcount && maxargcount >= argcount) { + return MAX_OVERLOAD_SCORE; + } else { + int diff = std::min(std::abs(argcount - minargcount), + std::abs(argcount - maxargcount)); + return std::max(100 - diff, 51); + } + } else if (checkArgTypes(state, fn)) { + const int minargcount = minArgCount(fn); + const int maxargcount = maxArgCount(fn); + if (minargcount <= argcount && maxargcount >= argcount) { + return 200; + } else { + int diff = std::min(std::abs(argcount - minargcount), + std::abs(argcount - maxargcount)); + return std::max(50 - diff, 1); + } + } else { + return 0; + } +} +inline int pushArgmentTypeNames(lua_State *state, int top) { + for (int i = 1; i <= top; i++) { + if (i != 1) { + lua_pushliteral(state, ","); + } + + int type = lua_type(state, i); + if (type == LUA_TUSERDATA) { + int nametype = luaL_getmetafield(state, i, "__name"); + if (nametype != LUA_TSTRING) { + lua_pop(state, 1); + lua_pushstring(state, lua_typename(state, type)); + } + } else { + lua_pushstring(state, lua_typename(state, type)); + } + } + return lua_gettop(state) - top; +} +} #if KAGUYA_USE_CPP11 - namespace detail - { - template void function_match_scoring(lua_State* state, uint8_t* score_array, int current_index, const Fn& fn) - { - score_array[current_index] = nativefunction::compute_function_matching_score(state, fn); - } - template void function_match_scoring(lua_State* state, uint8_t* score_array, int current_index, const Fn& fn, const Functions&... fns) - { - score_array[current_index] = nativefunction::compute_function_matching_score(state, fn); - if (score_array[current_index] < nativefunction::MAX_OVERLOAD_SCORE) - { - function_match_scoring(state, score_array, current_index + 1, fns...); - } - } - template int best_function_index(lua_State* state, const Functions&... fns) - { - static const int fncount = sizeof...(fns); - uint8_t score[fncount] = {}; - function_match_scoring(state, score, 0, fns...); - uint8_t best_score = 0; - int best_score_index = -1; - for (int i = 0; i < fncount; ++i) - { - if (best_score < score[i]) - { - best_score = score[i]; - best_score_index = i; - if (best_score == nativefunction::MAX_OVERLOAD_SCORE) - { - break; - } - } - } - return best_score_index; - } - template int invoke_index(lua_State* state, int index, int current_index, Fn&& fn) - { - KAGUYA_UNUSED(index); - KAGUYA_UNUSED(current_index); - return nativefunction::call(state, fn); - } - template int invoke_index(lua_State* state, int index, int current_index, Fn&& fn, Functions&&... fns) - { - if (index == current_index) - { - return nativefunction::call(state, fn); - } - else - { - return invoke_index(state, index, current_index + 1, fns...); - } - } - - template int best_match_invoke(lua_State* state, Fun&& fn) - { - return nativefunction::call(state, fn); - } - - template int best_match_invoke(lua_State* state, Fun&& fn, Functions&&... fns) - { - int index = best_function_index(state, fn, fns...); - if (index >= 0) - { - assert(size_t(index) <= sizeof...(fns)); - return invoke_index(state, index, 0, fn, fns...); - } - else - { - throw LuaTypeMismatch(); - } - return 0; - } - - template int invoke_tuple_impl(lua_State* state, TupleType&& tuple, nativefunction::index_tuple) - { - return best_match_invoke(state, fntuple::get(tuple)...); - } - template int invoke_tuple(lua_State* state, TupleType&& tuple) - { - typedef typename std::decay::type ttype; - - typedef typename nativefunction::index_range<0, fntuple::tuple_size::value>::type indexrange; - - return invoke_tuple_impl(state, tuple, indexrange()); - } - - template void push_arg_typename(lua_State *state,const Fun& fn) - { - lua_pushliteral(state, "\t\t"); - lua_pushstring(state, nativefunction::argTypesName(fn).c_str()); - lua_pushliteral(state, "\n"); - } - - template void push_arg_typename(lua_State *state, const Fun& fn, const Functions&... fns) - { - lua_pushliteral(state, "\t\t"); - lua_pushstring(state, nativefunction::argTypesName(fn).c_str()); - lua_pushliteral(state, "\n"); - push_arg_typename(state,fns...); - } - template void push_arg_typename_tuple_impl(lua_State *state, TupleType&& tuple, nativefunction::index_tuple) - { - return push_arg_typename(state, fntuple::get(tuple)...); - } - templatevoid push_arg_typename_tuple(lua_State *state, TupleType&& tuple) - { - typedef typename std::decay::type ttype; - typedef typename nativefunction::index_range<0, fntuple::tuple_size::value>::type indexrange; - - return push_arg_typename_tuple_impl(state,tuple, indexrange()); - } - } +namespace detail { +template +void function_match_scoring(lua_State *state, uint8_t *score_array, + int current_index, const Fn &fn) { + score_array[current_index] = + nativefunction::compute_function_matching_score(state, fn); +} +template +void function_match_scoring(lua_State *state, uint8_t *score_array, + int current_index, const Fn &fn, + const Functions &... fns) { + score_array[current_index] = + nativefunction::compute_function_matching_score(state, fn); + if (score_array[current_index] < nativefunction::MAX_OVERLOAD_SCORE) { + function_match_scoring(state, score_array, current_index + 1, fns...); + } +} +template +int best_function_index(lua_State *state, const Functions &... fns) { + static const int fncount = sizeof...(fns); + uint8_t score[fncount] = {}; + function_match_scoring(state, score, 0, fns...); + uint8_t best_score = 0; + int best_score_index = -1; + for (int i = 0; i < fncount; ++i) { + if (best_score < score[i]) { + best_score = score[i]; + best_score_index = i; + if (best_score == nativefunction::MAX_OVERLOAD_SCORE) { + break; + } + } + } + return best_score_index; +} +template +int invoke_index(lua_State *state, int index, int current_index, Fn &&fn) { + KAGUYA_UNUSED(index); + KAGUYA_UNUSED(current_index); + return nativefunction::call(state, fn); +} +template +int invoke_index(lua_State *state, int index, int current_index, Fn &&fn, + Functions &&... fns) { + if (index == current_index) { + return nativefunction::call(state, fn); + } else { + return invoke_index(state, index, current_index + 1, fns...); + } +} + +template int best_match_invoke(lua_State *state, Fun &&fn) { + return nativefunction::call(state, fn); +} + +template +int best_match_invoke(lua_State *state, Fun &&fn, Functions &&... fns) { + int index = best_function_index(state, fn, fns...); + if (index >= 0) { + assert(size_t(index) <= sizeof...(fns)); + return invoke_index(state, index, 0, fn, fns...); + } else { + throw LuaTypeMismatch(); + } + return 0; +} + +template +int invoke_tuple_impl(lua_State *state, TupleType &&tuple, + nativefunction::index_tuple) { + return best_match_invoke(state, fntuple::get(tuple)...); +} +template +int invoke_tuple(lua_State *state, TupleType &&tuple) { + typedef typename std::decay::type ttype; + + typedef typename nativefunction::index_range< + 0, fntuple::tuple_size::value>::type indexrange; + + return invoke_tuple_impl(state, tuple, indexrange()); +} + +template +void push_arg_typename(lua_State *state, const Fun &fn) { + lua_pushliteral(state, "\t\t"); + lua_pushstring(state, nativefunction::argTypesName(fn).c_str()); + lua_pushliteral(state, "\n"); +} +template +void push_arg_typename(lua_State *state, const Fun &fn, + const Functions &... fns) { + lua_pushliteral(state, "\t\t"); + lua_pushstring(state, nativefunction::argTypesName(fn).c_str()); + lua_pushliteral(state, "\n"); + push_arg_typename(state, fns...); +} +template +void push_arg_typename_tuple_impl(lua_State *state, TupleType &&tuple, + nativefunction::index_tuple) { + return push_arg_typename(state, fntuple::get(tuple)...); +} +template +void push_arg_typename_tuple(lua_State *state, TupleType &&tuple) { + typedef typename std::decay::type ttype; + typedef typename nativefunction::index_range< + 0, fntuple::tuple_size::value>::type indexrange; + + return push_arg_typename_tuple_impl(state, tuple, indexrange()); +} +} #else - namespace detail - { -#define KAGUYA_FUNCTION_SCOREING(N) if (currentbestscore < nativefunction::MAX_OVERLOAD_SCORE) {\ - int score = nativefunction::compute_function_matching_score(state, fntuple::get(tuple));\ - if (currentbestscore < score) {\ - currentbestscore = score;\ - currentbestindex = N;\ - }\ - } -#define KAGUYA_FUNCTION_INVOKE(N) if (currentbestindex == N) {\ - return nativefunction::call(state, fntuple::get(tuple));\ - }\ - - -#define KAGUYA_ARG_PUSH_TYPENAMES(N)lua_pushliteral(state, "\t\t"); lua_pushstring(state, nativefunction::argTypesName(fntuple::get(tuple)).c_str());lua_pushliteral(state, "\n"); -#define KAGUYA_TEMPLATE_PARAMETER(N) template -#define KAGUYA_TUPLE_INVOKE_DEF(N) \ - KAGUYA_TEMPLATE_PARAMETER(N)\ - int invoke_tuple(lua_State* state, fntuple::tuple& tuple)\ - {\ - if(N==1){return nativefunction::call(state, fntuple::get<0>(tuple));}\ - int32_t currentbestscore = 0;\ - int32_t currentbestindex = -1;\ - KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_SCOREING);\ - KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_INVOKE);\ - throw LuaTypeMismatch(); \ - }\ - KAGUYA_TEMPLATE_PARAMETER(N)\ - void push_arg_typename_tuple(lua_State *state,fntuple::tuple& tuple)\ - {\ - KAGUYA_PP_REPEAT(N, KAGUYA_ARG_PUSH_TYPENAMES);\ - }\ - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_INVOKE_DEF) +namespace detail { +#define KAGUYA_FUNCTION_SCOREING(N) \ + if (currentbestscore < nativefunction::MAX_OVERLOAD_SCORE) { \ + int score = nativefunction::compute_function_matching_score( \ + state, fntuple::get(tuple)); \ + if (currentbestscore < score) { \ + currentbestscore = score; \ + currentbestindex = N; \ + } \ + } +#define KAGUYA_FUNCTION_INVOKE(N) \ + if (currentbestindex == N) { \ + return nativefunction::call(state, fntuple::get(tuple)); \ + } + +#define KAGUYA_ARG_PUSH_TYPENAMES(N) \ + lua_pushliteral(state, "\t\t"); \ + lua_pushstring( \ + state, \ + nativefunction::argTypesName(fntuple::get(tuple)).c_str()); \ + lua_pushliteral(state, "\n"); +#define KAGUYA_TEMPLATE_PARAMETER(N) template +#define KAGUYA_TUPLE_INVOKE_DEF(N) \ + KAGUYA_TEMPLATE_PARAMETER(N) \ + int invoke_tuple(lua_State *state, \ + fntuple::tuple &tuple) { \ + if (N == 1) { \ + return nativefunction::call(state, fntuple::get<0>(tuple)); \ + } \ + int32_t currentbestscore = 0; \ + int32_t currentbestindex = -1; \ + KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_SCOREING); \ + KAGUYA_PP_REPEAT(N, KAGUYA_FUNCTION_INVOKE); \ + throw LuaTypeMismatch(); \ + } \ + KAGUYA_TEMPLATE_PARAMETER(N) \ + void push_arg_typename_tuple( \ + lua_State *state, \ + fntuple::tuple &tuple) { \ + KAGUYA_PP_REPEAT(N, KAGUYA_ARG_PUSH_TYPENAMES); \ + } + +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_TUPLE_INVOKE_DEF) #undef KAGUYA_TEMPLATE_PARAMETER #undef KAGUYA_TUPLE_INVOKE_DEF #undef KAGUYA_ARG_TYPENAMES #undef KAGUYA_FUNCTION_INVOKE #undef KAGUYA_FUNCTION_SCOREING - template int invoke_tuple(lua_State* state, TupleType& tuple) - { - KAGUYA_UNUSED(state); - KAGUYA_UNUSED(tuple); - return 0; - } - } +template +int invoke_tuple(lua_State *state, TupleType &tuple) { + KAGUYA_UNUSED(state); + KAGUYA_UNUSED(tuple); + return 0; +} +} #endif +template struct FunctionInvokerType { + FunctionTuple functions; + FunctionInvokerType(const FunctionTuple &t) : functions(t) {} +}; + +template +inline FunctionInvokerType > function(T f) { + KAGUYA_STATIC_ASSERT( + nativefunction::is_callable::type>::value, + "argument need callable"); + return FunctionInvokerType >(fntuple::tuple(f)); +} - - template - struct FunctionInvokerType - { - FunctionTuple functions; - FunctionInvokerType(const FunctionTuple& t) :functions(t) {} - }; - - - - template - inline FunctionInvokerType > function(T f) - { - KAGUYA_STATIC_ASSERT(nativefunction::is_callable::type>::value, "argument need callable"); - return FunctionInvokerType >(fntuple::tuple(f)); - } - - template - inline FunctionInvokerType > > function(T f) - { - return FunctionInvokerType > >(fntuple::tuple >(standard::function(f))); - } +template +inline FunctionInvokerType > > +function(T f) { + return FunctionInvokerType > >( + fntuple::tuple >(standard::function(f))); +} #if KAGUYA_USE_CPP11 - template - FunctionInvokerType > overload(Functions... fns) - { - return FunctionInvokerType >(fntuple::tuple(fns...)); - } +template +FunctionInvokerType > overload(Functions... fns) { + return FunctionInvokerType >( + fntuple::tuple(fns...)); +} #else -#define KAGUYA_FOVERLOAD_DEF(N) template\ - FunctionInvokerType > overload(KAGUYA_PP_ARG_DEF_REPEAT(N))\ - {\ - typedef typename fntuple::tuple ttype;\ - return FunctionInvokerType(ttype(KAGUYA_PP_ARG_REPEAT(N)));\ - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_FOVERLOAD_DEF) +#define KAGUYA_FOVERLOAD_DEF(N) \ + template \ + FunctionInvokerType > \ + overload(KAGUYA_PP_ARG_DEF_REPEAT(N)) { \ + typedef typename fntuple::tuple ttype; \ + return FunctionInvokerType(ttype(KAGUYA_PP_ARG_REPEAT(N))); \ + } +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_OVERLOADS, KAGUYA_FOVERLOAD_DEF) #undef KAGUYA_FOVERLOAD_DEF #endif - struct luacfunction - { - lua_CFunction ptr; - - luacfunction(lua_CFunction f) :ptr(f) {} - operator lua_CFunction() { return ptr; } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for FunctionInvokerType - template struct lua_type_traits > - { - typedef FunctionInvokerType userdatatype; - typedef const FunctionInvokerType& push_type; - - static const char* build_arg_error_message(lua_State *state,const char* msg, FunctionTuple* tuple) - { - int stack_top = lua_gettop(state); - if (msg) { lua_pushstring(state, msg); } - lua_pushliteral(state, "Argument mismatch:"); - nativefunction::pushArgmentTypeNames(state, stack_top); - - lua_pushliteral(state, "\t candidate is:\n"); - detail::push_arg_typename_tuple(state, *tuple); - - lua_concat(state, lua_gettop(state) - stack_top); - return lua_tostring(state,-1); - } - - static int invoke(lua_State *state) - { - FunctionTuple* t = static_cast(lua_touserdata(state, lua_upvalueindex(1))); - - if (t) - { - try { - return detail::invoke_tuple(state, *t); - } - catch (LuaTypeMismatch &e) { - if (strcmp(e.what(), "type mismatch!!") == 0) - { - util::traceBack(state, build_arg_error_message(state, "maybe...", t)); - } - else - { - util::traceBack(state, e.what()); - } - } - catch (std::exception & e) { - util::traceBack(state, e.what()); - } - catch (...) { - util::traceBack(state, "Unknown exception"); - } - } - return lua_error(state); - } - - inline static int tuple_destructor(lua_State *state) - { - FunctionTuple* f = static_cast(lua_touserdata(state, 1)); - if (f) - { - f->~FunctionTuple(); - } - return 0; - } - - static int push(lua_State* state, push_type fns) - { - void* ptr = lua_newuserdata(state, sizeof(FunctionTuple)); - new(ptr) FunctionTuple(fns.functions); - lua_createtable(state, 0, 2); - lua_pushcclosure(state, &tuple_destructor, 0); - lua_setfield(state, -2, "__gc"); - lua_pushvalue(state, -1); - lua_setfield(state, -1, "__index"); - lua_setmetatable(state, -2); - lua_pushcclosure(state, &invoke, 1); - - return 1; - } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for c function - template struct lua_type_traits < T - , typename traits::enable_if::type>::value>::type > - { - static int push(lua_State* l, T f) - { - return util::one_push(l, kaguya::function(f)); - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for luacfunction - template<> struct lua_type_traits < luacfunction > - { - typedef luacfunction push_type; - typedef luacfunction get_type; - static bool strictCheckType(lua_State* l, int index) - { - return lua_iscfunction(l, index) != 0; - } - static bool checkType(lua_State* l, int index) - { - return lua_iscfunction(l, index) != 0; - } - static get_type get(lua_State* l, int index) - { - return lua_tocfunction(l,index); - } - static int push(lua_State* l, push_type f) - { - lua_pushcfunction(l, f); - return 1; - } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for std::function or boost::function - template struct lua_type_traits > { - typedef const standard::function& push_type; - typedef standard::function get_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TFUNCTION; - } - static bool checkType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TFUNCTION; - } - static get_type get(lua_State* l, int index) - { - if (!l || lua_type(l, index) != LUA_TFUNCTION) { - return get_type(); - } - lua_pushvalue(l, index); - return get_type(LuaFunction(l, StackTop())); - } - - static int push(lua_State* l, push_type v) - { - return util::one_push(l, kaguya::function(v)); - } - }; - - - template::type::result_type> - struct OverloadFunctionImpl : kaguya::FunctionImpl - { - typedef Ret result_type; - typedef typename util::FunctionSignature::type::c_function_type c_function_type; - - virtual result_type invoke_type(lua_State *state) = 0; - - virtual int invoke(lua_State *state) - { - return util::push_args(state, invoke_type(state)); - } - virtual std::string argTypesName()const { return nativefunction::argTypesName(c_function_type(0), maxArgCount() - minArgCount()); } - virtual bool checkArgTypes(lua_State* state)const { return kaguya::nativefunction::checkArgTypes(state, c_function_type(0), maxArgCount() - minArgCount()); } - virtual bool strictCheckArgTypes(lua_State* state)const { return kaguya::nativefunction::strictCheckArgTypes(state, c_function_type(0), maxArgCount() - minArgCount()); } - }; - - template - struct OverloadFunctionImpl : kaguya::FunctionImpl - { - typedef void result_type; - typedef typename util::FunctionSignature::type::c_function_type c_function_type; - - virtual result_type invoke_type(lua_State *state) = 0; - - virtual int invoke(lua_State *state) - { - invoke_type(state); - return 0; - } - virtual std::string argTypesName()const { return nativefunction::argTypesName(c_function_type(0), maxArgCount() - minArgCount()); } - virtual bool checkArgTypes(lua_State* state)const { return kaguya::nativefunction::checkArgTypes(state, c_function_type(0), maxArgCount() - minArgCount()); } - virtual bool strictCheckArgTypes(lua_State* state)const { return kaguya::nativefunction::strictCheckArgTypes(state, c_function_type(0), maxArgCount() - minArgCount()); } - }; +struct luacfunction { + lua_CFunction ptr; + + luacfunction(lua_CFunction f) : ptr(f) {} + operator lua_CFunction() { return ptr; } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for FunctionInvokerType +template +struct lua_type_traits > { + typedef FunctionInvokerType userdatatype; + typedef const FunctionInvokerType &push_type; + + static const char *build_arg_error_message(lua_State *state, const char *msg, + FunctionTuple *tuple) { + int stack_top = lua_gettop(state); + if (msg) { + lua_pushstring(state, msg); + } + lua_pushliteral(state, "Argument mismatch:"); + nativefunction::pushArgmentTypeNames(state, stack_top); + + lua_pushliteral(state, "\t candidate is:\n"); + detail::push_arg_typename_tuple(state, *tuple); + + lua_concat(state, lua_gettop(state) - stack_top); + return lua_tostring(state, -1); + } + + static int invoke(lua_State *state) { + FunctionTuple *t = static_cast( + lua_touserdata(state, lua_upvalueindex(1))); + + if (t) { + try { + return detail::invoke_tuple(state, *t); + } catch (LuaTypeMismatch &e) { + if (strcmp(e.what(), "type mismatch!!") == 0) { + util::traceBack(state, build_arg_error_message(state, "maybe...", t)); + } else { + util::traceBack(state, e.what()); + } + } catch (std::exception &e) { + util::traceBack(state, e.what()); + } catch (...) { + util::traceBack(state, "Unknown exception"); + } + } + return lua_error(state); + } + + inline static int tuple_destructor(lua_State *state) { + FunctionTuple *f = static_cast(lua_touserdata(state, 1)); + if (f) { + f->~FunctionTuple(); + } + return 0; + } + + static int push(lua_State *state, push_type fns) { + void *ptr = lua_newuserdata(state, sizeof(FunctionTuple)); + new (ptr) FunctionTuple(fns.functions); + lua_createtable(state, 0, 2); + lua_pushcclosure(state, &tuple_destructor, 0); + lua_setfield(state, -2, "__gc"); + lua_pushvalue(state, -1); + lua_setfield(state, -1, "__index"); + lua_setmetatable(state, -2); + lua_pushcclosure(state, &invoke, 1); + + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for c function +template +struct lua_type_traits< + T, typename traits::enable_if::type>::value>::type> { + static int push(lua_State *l, T f) { + return util::one_push(l, kaguya::function(f)); + } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for luacfunction +template <> struct lua_type_traits { + typedef luacfunction push_type; + typedef luacfunction get_type; + static bool strictCheckType(lua_State *l, int index) { + return lua_iscfunction(l, index) != 0; + } + static bool checkType(lua_State *l, int index) { + return lua_iscfunction(l, index) != 0; + } + static get_type get(lua_State *l, int index) { + return lua_tocfunction(l, index); + } + static int push(lua_State *l, push_type f) { + lua_pushcfunction(l, f); + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for std::function or boost::function +template struct lua_type_traits > { + typedef const standard::function &push_type; + typedef standard::function get_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TFUNCTION; + } + static bool checkType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TFUNCTION; + } + static get_type get(lua_State *l, int index) { + if (!l || lua_type(l, index) != LUA_TFUNCTION) { + return get_type(); + } + lua_pushvalue(l, index); + return get_type(LuaFunction(l, StackTop())); + } + + static int push(lua_State *l, push_type v) { + return util::one_push(l, kaguya::function(v)); + } +}; + +template ::type::result_type> +struct OverloadFunctionImpl : kaguya::FunctionImpl { + typedef Ret result_type; + typedef typename util::FunctionSignature::type::c_function_type + c_function_type; + + virtual result_type invoke_type(lua_State *state) = 0; + + virtual int invoke(lua_State *state) { + return util::push_args(state, invoke_type(state)); + } + virtual std::string argTypesName() const { + return nativefunction::argTypesName(c_function_type(0), + maxArgCount() - minArgCount()); + } + virtual bool checkArgTypes(lua_State *state) const { + return kaguya::nativefunction::checkArgTypes(state, c_function_type(0), + maxArgCount() - minArgCount()); + } + virtual bool strictCheckArgTypes(lua_State *state) const { + return kaguya::nativefunction::strictCheckArgTypes( + state, c_function_type(0), maxArgCount() - minArgCount()); + } +}; + +template +struct OverloadFunctionImpl : kaguya::FunctionImpl { + typedef void result_type; + typedef typename util::FunctionSignature::type::c_function_type + c_function_type; + + virtual result_type invoke_type(lua_State *state) = 0; + + virtual int invoke(lua_State *state) { + invoke_type(state); + return 0; + } + virtual std::string argTypesName() const { + return nativefunction::argTypesName(c_function_type(0), + maxArgCount() - minArgCount()); + } + virtual bool checkArgTypes(lua_State *state) const { + return kaguya::nativefunction::checkArgTypes(state, c_function_type(0), + maxArgCount() - minArgCount()); + } + virtual bool strictCheckArgTypes(lua_State *state) const { + return kaguya::nativefunction::strictCheckArgTypes( + state, c_function_type(0), maxArgCount() - minArgCount()); + } +}; } -#define KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REP(N) getArgument(state) -#define KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REP) -#define KAGUYA_INTERNAL_OVERLOAD_FUNCTION_INVOKE(N,FNAME,MINARG, MAXARG) if (argcount == KAGUYA_PP_ADD(MINARG,KAGUYA_PP_DEC(N))) { return FNAME(KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REPEAT(KAGUYA_PP_ADD(MINARG,KAGUYA_PP_DEC(N)))); } - -#define KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,FNAME, MINARG, MAXARG,CREATE_FN)\ -struct GENERATE_NAME\ -{\ - template\ - struct Function : kaguya::OverloadFunctionImpl\ - {\ - typedef typename kaguya::OverloadFunctionImpl::result_type result_type;\ - virtual result_type invoke_type(lua_State *state)\ - {\ - using namespace kaguya::nativefunction;\ - int argcount = lua_gettop(state);\ - KAGUYA_PP_REPEAT_DEF_VA_ARG(KAGUYA_PP_INC(KAGUYA_PP_SUB(MAXARG, MINARG)), KAGUYA_INTERNAL_OVERLOAD_FUNCTION_INVOKE, FNAME, MINARG, MAXARG)\ - throw kaguya::LuaTypeMismatch("argument count mismatch");\ - }\ - virtual int minArgCount()const { return MINARG; }\ - virtual int maxArgCount()const { return MAXARG; }\ - };\ - template kaguya::PolymorphicInvoker::holder_type create(F)\ - {\ - kaguya::OverloadFunctionImpl* ptr = new Function();\ - return kaguya::PolymorphicInvoker::holder_type(ptr);\ - }\ - template kaguya::PolymorphicInvoker::holder_type create()\ - {\ - kaguya::OverloadFunctionImpl* ptr = new Function();\ - return kaguya::PolymorphicInvoker::holder_type(ptr);\ - }\ - kaguya::PolymorphicInvoker operator()() { return CREATE_FN; }\ -}GENERATE_NAME; - - -#define KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REP(N) getArgument(state) -#define KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REP) -#define KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_INVOKE(N,FNAME,MINARG, MAXARG) if (argcount == 1 + KAGUYA_PP_ADD(MINARG,KAGUYA_PP_DEC(N))) { return (getArgument<0,F>(state)).FNAME(KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REPEAT(KAGUYA_PP_ADD(MINARG,KAGUYA_PP_DEC(N)))); } - -#define KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG,CREATE_FN)\ -struct GENERATE_NAME\ -{\ - template\ - struct Function : kaguya::OverloadFunctionImpl\ - {\ - typedef typename kaguya::OverloadFunctionImpl::result_type result_type;\ - virtual result_type invoke_type(lua_State *state)\ - {\ - using namespace kaguya::nativefunction;\ - int argcount = lua_gettop(state);\ - KAGUYA_PP_REPEAT_DEF_VA_ARG(KAGUYA_PP_INC(KAGUYA_PP_SUB(MAXARG, MINARG)), KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_INVOKE, FNAME, MINARG, MAXARG)\ - throw kaguya::LuaTypeMismatch("argument count mismatch");\ - }\ - virtual int minArgCount()const { return MINARG + 1; }\ - virtual int maxArgCount()const { return MAXARG + 1; }\ - };\ - template kaguya::PolymorphicMemberInvoker::holder_type create(F f)\ - {\ - KAGUYA_UNUSED(f);\ - kaguya::OverloadFunctionImpl* ptr = new Function();\ - return kaguya::PolymorphicMemberInvoker::holder_type(ptr);\ - }\ - template kaguya::PolymorphicMemberInvoker::holder_type create()\ - {\ - kaguya::OverloadFunctionImpl* ptr = new Function();\ - return kaguya::PolymorphicMemberInvoker::holder_type(ptr);\ - }\ - kaguya::PolymorphicMemberInvoker operator()()\ - {\ - return CREATE_FN;\ - }\ -}GENERATE_NAME; - - -/// @brief Generate wrapper function object for count based overloads with nonvoid return function. Include default arguments parameter function +#define KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REP(N) \ + getArgument(state) +#define KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REP) +#define KAGUYA_INTERNAL_OVERLOAD_FUNCTION_INVOKE(N, FNAME, MINARG, MAXARG) \ + if (argcount == KAGUYA_PP_ADD(MINARG, KAGUYA_PP_DEC(N))) { \ + return FNAME(KAGUYA_INTERNAL_OVERLOAD_FUNCTION_GET_REPEAT( \ + KAGUYA_PP_ADD(MINARG, KAGUYA_PP_DEC(N)))); \ + } + +#define KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME, FNAME, MINARG, \ + MAXARG, CREATE_FN) \ + \ +struct GENERATE_NAME \ +{ \ + template struct Function : kaguya::OverloadFunctionImpl { \ + typedef \ + typename kaguya::OverloadFunctionImpl::result_type result_type; \ + virtual result_type invoke_type(lua_State *state) { \ + using namespace kaguya::nativefunction; \ + int argcount = lua_gettop(state); \ + KAGUYA_PP_REPEAT_DEF_VA_ARG( \ + KAGUYA_PP_INC(KAGUYA_PP_SUB(MAXARG, MINARG)), \ + KAGUYA_INTERNAL_OVERLOAD_FUNCTION_INVOKE, FNAME, MINARG, MAXARG) \ + throw kaguya::LuaTypeMismatch("argument count mismatch"); \ + } \ + virtual int minArgCount() const { return MINARG; } \ + virtual int maxArgCount() const { return MAXARG; } \ + }; \ + template kaguya::PolymorphicInvoker::holder_type create(F) { \ + kaguya::OverloadFunctionImpl *ptr = new Function(); \ + return kaguya::PolymorphicInvoker::holder_type(ptr); \ + } \ + template kaguya::PolymorphicInvoker::holder_type create() { \ + kaguya::OverloadFunctionImpl *ptr = new Function(); \ + return kaguya::PolymorphicInvoker::holder_type(ptr); \ + } \ + kaguya::PolymorphicInvoker operator()() { return CREATE_FN; } \ + \ +} \ + GENERATE_NAME; + +#define KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REP(N) \ + getArgument(state) +#define KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REP) +#define KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_INVOKE(N, FNAME, MINARG, \ + MAXARG) \ + if (argcount == 1 + KAGUYA_PP_ADD(MINARG, KAGUYA_PP_DEC(N))) { \ + return (getArgument<0, F>(state)) \ + .FNAME(KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_GET_REPEAT( \ + KAGUYA_PP_ADD(MINARG, KAGUYA_PP_DEC(N)))); \ + } + +#define KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME, CLASS, FNAME, \ + MINARG, MAXARG, CREATE_FN) \ + \ +struct GENERATE_NAME \ +{ \ + template struct Function : kaguya::OverloadFunctionImpl { \ + typedef \ + typename kaguya::OverloadFunctionImpl::result_type result_type; \ + virtual result_type invoke_type(lua_State *state) { \ + using namespace kaguya::nativefunction; \ + int argcount = lua_gettop(state); \ + KAGUYA_PP_REPEAT_DEF_VA_ARG( \ + KAGUYA_PP_INC(KAGUYA_PP_SUB(MAXARG, MINARG)), \ + KAGUYA_INTERNAL_OVERLOAD_MEMBER_FUNCTION_INVOKE, FNAME, MINARG, \ + MAXARG) \ + throw kaguya::LuaTypeMismatch("argument count mismatch"); \ + } \ + virtual int minArgCount() const { return MINARG + 1; } \ + virtual int maxArgCount() const { return MAXARG + 1; } \ + }; \ + template \ + kaguya::PolymorphicMemberInvoker::holder_type create(F f) { \ + KAGUYA_UNUSED(f); \ + kaguya::OverloadFunctionImpl *ptr = new Function(); \ + return kaguya::PolymorphicMemberInvoker::holder_type(ptr); \ + } \ + template \ + kaguya::PolymorphicMemberInvoker::holder_type create() { \ + kaguya::OverloadFunctionImpl *ptr = new Function(); \ + return kaguya::PolymorphicMemberInvoker::holder_type(ptr); \ + } \ + kaguya::PolymorphicMemberInvoker operator()() { return CREATE_FN; } \ + \ +} \ + GENERATE_NAME; + +/// @brief Generate wrapper function object for count based overloads with +/// nonvoid return function. Include default arguments parameter function /// @param GENERATE_NAME generate function object name /// @param FNAME target function name /// @param MINARG minimum arguments count /// @param MAXARG maximum arguments count -#define KAGUYA_FUNCTION_OVERLOADS(GENERATE_NAME,FNAME, MINARG, MAXARG) KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,FNAME, MINARG, MAXARG,create(FNAME)) +#define KAGUYA_FUNCTION_OVERLOADS(GENERATE_NAME, FNAME, MINARG, MAXARG) \ + KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME, FNAME, MINARG, MAXARG, \ + create(FNAME)) - -/// @brief Generate wrapper function object for count based overloads with nonvoid return function. Include default arguments parameter function +/// @brief Generate wrapper function object for count based overloads with +/// nonvoid return function. Include default arguments parameter function /// @param GENERATE_NAME generate function object name /// @param FNAME target function name /// @param MINARG minimum arguments count /// @param MAXARG maximum arguments count /// @param SIGNATURE function signature. e,g, int(int) -#define KAGUYA_FUNCTION_OVERLOADS_WITH_SIGNATURE(GENERATE_NAME,FNAME, MINARG, MAXARG,SIGNATURE) KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,FNAME, MINARG, MAXARG,create()) - +#define KAGUYA_FUNCTION_OVERLOADS_WITH_SIGNATURE(GENERATE_NAME, FNAME, MINARG, \ + MAXARG, SIGNATURE) \ + KAGUYA_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME, FNAME, MINARG, MAXARG, \ + create()) -/// @brief Generate wrapper function object for count based overloads with nonvoid return function. Include default arguments parameter function +/// @brief Generate wrapper function object for count based overloads with +/// nonvoid return function. Include default arguments parameter function /// @param GENERATE_NAME generate function object name /// @param CLASS target class name /// @param FNAME target function name /// @param MINARG minimum arguments count /// @param MAXARG maximum arguments count -#define KAGUYA_MEMBER_FUNCTION_OVERLOADS(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG) KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG,create(&CLASS::FNAME)) +#define KAGUYA_MEMBER_FUNCTION_OVERLOADS(GENERATE_NAME, CLASS, FNAME, MINARG, \ + MAXARG) \ + KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL( \ + GENERATE_NAME, CLASS, FNAME, MINARG, MAXARG, create(&CLASS::FNAME)) -/// @brief Generate wrapper function object for count based overloads with nonvoid return function. Include default arguments parameter function +/// @brief Generate wrapper function object for count based overloads with +/// nonvoid return function. Include default arguments parameter function /// @param GENERATE_NAME generate function object name /// @param CLASS target class name /// @param FNAME target function name /// @param MINARG minimum arguments count /// @param MAXARG maximum arguments count /// @param SIGNATURE function signature. e,g, int(Test::*)(int) -#define KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG,SIGNATURE) KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL(GENERATE_NAME,CLASS,FNAME, MINARG, MAXARG,create()) +#define KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE( \ + GENERATE_NAME, CLASS, FNAME, MINARG, MAXARG, SIGNATURE) \ + KAGUYA_MEMBER_FUNCTION_OVERLOADS_INTERNAL( \ + GENERATE_NAME, CLASS, FNAME, MINARG, MAXARG, create()) diff --git a/include/kaguya/native_function_cxx03.hpp b/include/kaguya/native_function_cxx03.hpp index 16d303e..db3d920 100644 --- a/include/kaguya/native_function_cxx03.hpp +++ b/include/kaguya/native_function_cxx03.hpp @@ -10,175 +10,180 @@ #include "kaguya/utility.hpp" #include "kaguya/object.hpp" -namespace kaguya -{ - namespace nativefunction - { - - - -#define KAGUYA_INVOKE_SIG_TARG_DEF_CONCAT_REP(N) ,typename util::ArgumentType::type -#define KAGUYA_INVOKE_SIG_TARG_DEF_REPEAT_CONCAT(N) KAGUYA_PP_REPEAT(N, KAGUYA_INVOKE_SIG_TARG_DEF_CONCAT_REP) - -#define KAGUYA_GET_REP(N) ,lua_type_traits::get(state, N) -#define KAGUYA_FUNC_DEF(N) const util::FunctionSignatureType& fsig -#define KAGUYA_TYPENAME_REP(N) + ((MAX_ARG - opt_count < N)?"[OPT]":"") + util::pretty_name(typeid(KAGUYA_PP_CAT(A,N))) + "," -#define KAGUYA_TYPECHECK_REP(N) && (((MAX_ARG - opt_count < N) && lua_isnoneornil(state, N)) || lua_type_traits::checkType(state, N)) -#define KAGUYA_STRICT_TYPECHECK_REP(N) && (((MAX_ARG - opt_count < N) && lua_isnoneornil(state, N)) || lua_type_traits::strictCheckType(state, N)) -#define KAGUYA_CALL_FN_DEF(N) \ - template\ - inline typename traits::enable_if::value,int>::type \ - _call_apply(lua_State* state,F& f, KAGUYA_FUNC_DEF(N))\ - {\ - KAGUYA_UNUSED(fsig);\ - return util::push_args(state, util::invoke(f KAGUYA_PP_REPEAT(N,KAGUYA_GET_REP)));\ - }\ - template\ - inline typename traits::enable_if::value,int>::type \ - _call_apply(lua_State* state,F& f, KAGUYA_FUNC_DEF(N))\ - {\ - KAGUYA_UNUSED(state);\ - KAGUYA_UNUSED(fsig);\ - util::invoke(f KAGUYA_PP_REPEAT(N,KAGUYA_GET_REP));\ - return 0;\ - }\ - template\ - bool _ctype_apply(lua_State* state,KAGUYA_FUNC_DEF(N),int opt_count=0)\ - {\ - KAGUYA_UNUSED(state);\ - KAGUYA_UNUSED(opt_count);\ - KAGUYA_UNUSED(fsig);\ - const int MAX_ARG = N;(void)MAX_ARG;\ - return true KAGUYA_PP_REVERSE_REPEAT(N,KAGUYA_TYPECHECK_REP);\ - }\ - template\ - bool _sctype_apply(lua_State* state,KAGUYA_FUNC_DEF(N),int opt_count=0)\ - {\ - KAGUYA_UNUSED(state);\ - KAGUYA_UNUSED(opt_count);\ - KAGUYA_UNUSED(fsig);\ - const int MAX_ARG = N;(void)MAX_ARG;\ - return true KAGUYA_PP_REVERSE_REPEAT(N,KAGUYA_STRICT_TYPECHECK_REP);\ - }\ - template\ - std::string _type_name_apply(KAGUYA_FUNC_DEF(N),int opt_count)\ - {\ - KAGUYA_UNUSED(fsig);\ - KAGUYA_UNUSED(opt_count);\ - const int MAX_ARG = N;(void)MAX_ARG;\ - return std::string() KAGUYA_PP_REPEAT(N,KAGUYA_TYPENAME_REP);\ - } - - KAGUYA_CALL_FN_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CALL_FN_DEF) +namespace kaguya { +namespace nativefunction { + +#define KAGUYA_INVOKE_SIG_TARG_DEF_CONCAT_REP(N) \ + , typename util::ArgumentType::type +#define KAGUYA_INVOKE_SIG_TARG_DEF_REPEAT_CONCAT(N) \ + KAGUYA_PP_REPEAT(N, KAGUYA_INVOKE_SIG_TARG_DEF_CONCAT_REP) + +#define KAGUYA_GET_REP(N) , lua_type_traits::get(state, N) +#define KAGUYA_FUNC_DEF(N) \ + const util::FunctionSignatureType &fsig +#define KAGUYA_TYPENAME_REP(N) \ + +((MAX_ARG - opt_count < N) ? "[OPT]" : "") + \ + util::pretty_name(typeid(KAGUYA_PP_CAT(A, N))) + "," +#define KAGUYA_TYPECHECK_REP(N) \ + &&(((MAX_ARG - opt_count < N) && lua_isnoneornil(state, N)) || \ + lua_type_traits::checkType(state, N)) +#define KAGUYA_STRICT_TYPECHECK_REP(N) \ + &&(((MAX_ARG - opt_count < N) && lua_isnoneornil(state, N)) || \ + lua_type_traits::strictCheckType(state, N)) +#define KAGUYA_CALL_FN_DEF(N) \ + template \ + inline typename traits::enable_if::value, \ + int>::type \ + _call_apply(lua_State *state, F &f, KAGUYA_FUNC_DEF(N)) { \ + KAGUYA_UNUSED(fsig); \ + return util::push_args( \ + state, util::invoke( \ + f KAGUYA_PP_REPEAT(N, KAGUYA_GET_REP))); \ + } \ + template \ + inline \ + typename traits::enable_if::value, int>::type \ + _call_apply(lua_State *state, F &f, KAGUYA_FUNC_DEF(N)) { \ + KAGUYA_UNUSED(state); \ + KAGUYA_UNUSED(fsig); \ + util::invoke( \ + f KAGUYA_PP_REPEAT(N, KAGUYA_GET_REP)); \ + return 0; \ + } \ + template \ + bool _ctype_apply(lua_State *state, KAGUYA_FUNC_DEF(N), int opt_count = 0) { \ + KAGUYA_UNUSED(state); \ + KAGUYA_UNUSED(opt_count); \ + KAGUYA_UNUSED(fsig); \ + const int MAX_ARG = N; \ + (void)MAX_ARG; \ + return true KAGUYA_PP_REVERSE_REPEAT(N, KAGUYA_TYPECHECK_REP); \ + } \ + template \ + bool _sctype_apply(lua_State *state, KAGUYA_FUNC_DEF(N), \ + int opt_count = 0) { \ + KAGUYA_UNUSED(state); \ + KAGUYA_UNUSED(opt_count); \ + KAGUYA_UNUSED(fsig); \ + const int MAX_ARG = N; \ + (void)MAX_ARG; \ + return true KAGUYA_PP_REVERSE_REPEAT(N, KAGUYA_STRICT_TYPECHECK_REP); \ + } \ + template \ + std::string _type_name_apply(KAGUYA_FUNC_DEF(N), int opt_count) { \ + KAGUYA_UNUSED(fsig); \ + KAGUYA_UNUSED(opt_count); \ + const int MAX_ARG = N; \ + (void)MAX_ARG; \ + return std::string() KAGUYA_PP_REPEAT(N, KAGUYA_TYPENAME_REP); \ + } + +KAGUYA_CALL_FN_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CALL_FN_DEF) #undef KAGUYA_CALL_FN_DEF #undef KAGUYA_CALL_FN_DEF #undef KAGUYA_FUNC_DEF - template - int call(lua_State* state,F f) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return _call_apply(state, f, fsigtype()); - } - template - bool checkArgTypes(lua_State* state, const F& , int opt_count = 0) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return _ctype_apply(state, fsigtype(), opt_count); - } - template - bool strictCheckArgTypes(lua_State* state, const F& , int opt_count = 0) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return _sctype_apply(state, fsigtype(), opt_count); - } - - template - std::string argTypesName(const F& f, int opt_count = 0) - { - KAGUYA_UNUSED(f); - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return _type_name_apply(fsigtype(), opt_count); - } - template - int minArgCount(const F& f) - { - KAGUYA_UNUSED(f); - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return fsigtype::argument_count; - } - template - int maxArgCount(const F& f) - { - KAGUYA_UNUSED(f); - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return fsigtype::argument_count; - } - - ///! for constructor - templatestruct ConstructorFunctor; +template int call(lua_State *state, F f) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return _call_apply(state, f, fsigtype()); +} +template +bool checkArgTypes(lua_State *state, const F &, int opt_count = 0) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return _ctype_apply(state, fsigtype(), opt_count); +} +template +bool strictCheckArgTypes(lua_State *state, const F &, int opt_count = 0) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return _sctype_apply(state, fsigtype(), opt_count); +} -#define KAGUYA_CONSTRUCTOR_GET_REP(N) lua_type_traits::get(L, N) -#define KAGUYA_CONSTRUCTOR_CALL_FN_DEF(N) \ - template\ - struct ConstructorFunctor >\ - {\ - typedef util::FunctionSignatureType signature_type;\ - int operator()(lua_State* L)const\ - {\ - typedef ObjectWrapper wrapper_type;\ - void *storage = lua_newuserdata(L, sizeof(wrapper_type));\ - try { new(storage) wrapper_type(KAGUYA_PP_REPEAT_ARG(N,KAGUYA_CONSTRUCTOR_GET_REP)); }\ - catch (...) { lua_pop(L, 1); throw; }\ - class_userdata::setmetatable(L);\ - return 1;\ - }\ - bool checkArgTypes(lua_State* L, int opt_count = 0)const\ - {\ - return _ctype_apply(L, signature_type(), opt_count);\ - }\ - bool strictCheckArgTypes(lua_State* L, int opt_count = 0)const\ - {\ - return _sctype_apply(L, signature_type(), opt_count);\ - }\ - std::string argTypesName(int opt_count = 0)const\ - {\ - KAGUYA_UNUSED(opt_count);\ - return _type_name_apply(signature_type(),0);\ - }\ - }; +template std::string argTypesName(const F &f, int opt_count = 0) { + KAGUYA_UNUSED(f); + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return _type_name_apply(fsigtype(), opt_count); +} +template int minArgCount(const F &f) { + KAGUYA_UNUSED(f); + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return fsigtype::argument_count; +} +template int maxArgCount(const F &f) { + KAGUYA_UNUSED(f); + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return fsigtype::argument_count; +} - KAGUYA_CONSTRUCTOR_CALL_FN_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CONSTRUCTOR_CALL_FN_DEF) +///! for constructor +template struct ConstructorFunctor; + +#define KAGUYA_CONSTRUCTOR_GET_REP(N) \ + lua_type_traits::get(L, N) +#define KAGUYA_CONSTRUCTOR_CALL_FN_DEF(N) \ + template \ + struct ConstructorFunctor > { \ + typedef util::FunctionSignatureType< \ + ClassType KAGUYA_PP_TEMPLATE_ARG_REPEAT_CONCAT(N)> \ + signature_type; \ + int operator()(lua_State *L) const { \ + typedef ObjectWrapper wrapper_type; \ + void *storage = lua_newuserdata(L, sizeof(wrapper_type)); \ + try { \ + new (storage) \ + wrapper_type(KAGUYA_PP_REPEAT_ARG(N, KAGUYA_CONSTRUCTOR_GET_REP)); \ + } catch (...) { \ + lua_pop(L, 1); \ + throw; \ + } \ + class_userdata::setmetatable(L); \ + return 1; \ + } \ + bool checkArgTypes(lua_State *L, int opt_count = 0) const { \ + return _ctype_apply(L, signature_type(), opt_count); \ + } \ + bool strictCheckArgTypes(lua_State *L, int opt_count = 0) const { \ + return _sctype_apply(L, signature_type(), opt_count); \ + } \ + std::string argTypesName(int opt_count = 0) const { \ + KAGUYA_UNUSED(opt_count); \ + return _type_name_apply(signature_type(), 0); \ + } \ + }; + +KAGUYA_CONSTRUCTOR_CALL_FN_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CONSTRUCTOR_CALL_FN_DEF) #undef KAGUYA_CONSTRUCTOR_CALL_FN_DEF - - template struct ConstructorFunction; - -#define KAGUYA_F_TO_CONSIG_TYPE_DEF(N) ConstructorFunctor > -#define KAGUYA_F_TO_CONSIG_DEF(N) \ - template\ - struct ConstructorFunction\ - {\ - typedef KAGUYA_F_TO_CONSIG_TYPE_DEF(N) type;\ - };\ - template\ - struct ConstructorFunction\ - {\ - typedef KAGUYA_F_TO_CONSIG_TYPE_DEF(N) type;\ - }; - - KAGUYA_F_TO_CONSIG_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_F_TO_CONSIG_DEF) +template struct ConstructorFunction; + +#define KAGUYA_F_TO_CONSIG_TYPE_DEF(N) \ + ConstructorFunctor > +#define KAGUYA_F_TO_CONSIG_DEF(N) \ + template \ + struct ConstructorFunction { \ + typedef KAGUYA_F_TO_CONSIG_TYPE_DEF(N) type; \ + }; \ + template \ + struct ConstructorFunction { \ + typedef KAGUYA_F_TO_CONSIG_TYPE_DEF(N) type; \ + }; + +KAGUYA_F_TO_CONSIG_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_F_TO_CONSIG_DEF) #undef KAGUYA_F_TO_CONSIG_DEF - } - using nativefunction::ConstructorFunction; +} +using nativefunction::ConstructorFunction; } diff --git a/include/kaguya/native_function_cxx11.hpp b/include/kaguya/native_function_cxx11.hpp index a833de5..5186eac 100644 --- a/include/kaguya/native_function_cxx11.hpp +++ b/include/kaguya/native_function_cxx11.hpp @@ -10,209 +10,198 @@ #include "kaguya/utility.hpp" #include "kaguya/object.hpp" +namespace kaguya { +namespace nativefunction { +template struct index_tuple {}; + +template , + bool flag = first >= last> +struct index_range { + using type = result; +}; + +template +struct index_range, false> + : index_range > {}; + +template +int _call_apply(lua_State *state, F &&f, index_tuple, + util::FunctionSignatureType) { + return util::push_args( + state, util::invoke(f, lua_type_traits::get(state, Indexes)...)); +} +template +int _call_apply(lua_State *state, F &&f, index_tuple, + util::FunctionSignatureType) { + KAGUYA_UNUSED(state); + util::invoke(f, lua_type_traits::get(state, Indexes)...); + return 0; +} + +inline bool all_true() { return true; } +template +bool all_true(Arg f, Args... args) { // check from backward and lazy evaluation + return all_true(args...) && bool(f); +} + +inline void join(std::string &, const char *) {} +template +void join(std::string &result, const char *delim, const Arg &str, + const Args &... args) { + result += str; + result += delim; + join(result, delim, args...); +} + +template struct _wcheckeval { + _wcheckeval(lua_State *s, int i, bool opt) + : state(s), index(i), opt_arg(opt) {} + lua_State *state; + int index; + bool opt_arg; + operator bool() { + return (opt_arg && lua_isnoneornil(state, index)) || + lua_type_traits::checkType(state, index); + } +}; + +template struct _scheckeval { + _scheckeval(lua_State *s, int i, bool opt) + : state(s), index(i), opt_arg(opt) {} + lua_State *state; + int index; + bool opt_arg; + operator bool() { + return (opt_arg && lua_isnoneornil(state, index)) || + lua_type_traits::strictCheckType(state, index); + } +}; + +template +bool _ctype_apply(lua_State *state, index_tuple, + util::TypeTuple, int opt_count) { + KAGUYA_UNUSED(state); + KAGUYA_UNUSED(opt_count); + return all_true(_wcheckeval( + state, Indexes, sizeof...(Indexes) - opt_count < Indexes)...); +} +template +bool _sctype_apply(lua_State *state, index_tuple, + util::TypeTuple, int opt_count) { + KAGUYA_UNUSED(state); + KAGUYA_UNUSED(opt_count); + return all_true(_scheckeval( + state, Indexes, sizeof...(Indexes) - opt_count < Indexes)...); +} + +template +std::string _type_name_apply(index_tuple, util::TypeTuple, + int opt_count) { + KAGUYA_UNUSED(opt_count); + std::string result; + const int max_arg = sizeof...(Args); + join(result, ",", + (((max_arg - opt_count < int(Indexes)) ? std::string("[OPT]") + : std::string("")) + + util::pretty_name(typeid(Args)))...); + return result; +} + +template int call(lua_State *state, F &&f) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + typedef typename index_range<1, fsigtype::argument_count + 1>::type index; + return _call_apply(state, f, index(), fsigtype()); +} +template +bool checkArgTypes(lua_State *state, const F &, int opt_count = 0) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + typedef typename index_range<1, fsigtype::argument_count + 1>::type index; + typedef typename fsigtype::argument_type_tuple argument_type_tuple; + return _ctype_apply(state, index(), argument_type_tuple(), opt_count); +} +template +bool strictCheckArgTypes(lua_State *state, const F &, int opt_count = 0) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + typedef typename index_range<1, fsigtype::argument_count + 1>::type index; + typedef typename fsigtype::argument_type_tuple argument_type_tuple; + return _sctype_apply(state, index(), argument_type_tuple(), opt_count); +} -namespace kaguya +template std::string argTypesName(const F &, int opt_count = 0) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + typedef typename index_range<1, fsigtype::argument_count + 1>::type index; + typedef typename fsigtype::argument_type_tuple argument_type_tuple; + return _type_name_apply(index(), argument_type_tuple(), opt_count); +} +template int minArgCount(const F &) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return fsigtype::argument_count; +} +template int maxArgCount(const F &) { + typedef typename traits::decay::type ftype; + typedef typename util::FunctionSignature::type fsigtype; + return fsigtype::argument_count; +} + +// for constructor +template struct ConstructorFunctor; + +template +struct ConstructorFunctor > { + typedef util::FunctionSignatureType signature_type; + typedef typename index_range<1, sizeof...(Args) + 1>::type get_index; + + template + int invoke(lua_State *L, index_tuple) const { + typedef ObjectWrapper wrapper_type; + void *storage = lua_newuserdata(L, sizeof(wrapper_type)); + try { + new (storage) wrapper_type(lua_type_traits::get(L, Indexes)...); + } catch (...) { + lua_pop(L, 1); + throw; + } + + class_userdata::setmetatable(L); + return 1; + } + + int operator()(lua_State *L) const { return invoke(L, get_index()); } + + bool checkArgTypes(lua_State *L, int opt_count = 0) const { + return _ctype_apply(L, get_index(), + typename signature_type::argument_type_tuple(), + opt_count); + } + bool strictCheckArgTypes(lua_State *L, int opt_count = 0) const { + return _sctype_apply(L, get_index(), + typename signature_type::argument_type_tuple(), + opt_count); + } + std::string argTypesName(int opt_count = 0) const { + return _type_name_apply( + get_index(), typename signature_type::argument_type_tuple(), opt_count); + } +}; + +template struct ConstructorFunction; +template +struct ConstructorFunction { + typedef ConstructorFunctor > + type; +}; +template +struct ConstructorFunction // class type check version { - namespace nativefunction - { - template - struct index_tuple {}; - - template, bool flag = first >= last> - struct index_range - { - using type = result; - }; - - template - struct index_range, false> - : index_range> - {}; - - template - int _call_apply(lua_State* state, F&& f, index_tuple, util::FunctionSignatureType) - { - return util::push_args(state, util::invoke(f, lua_type_traits::get(state, Indexes)...)); - } - template - int _call_apply(lua_State* state, F&& f, index_tuple, util::FunctionSignatureType) - { - KAGUYA_UNUSED(state); - util::invoke(f, lua_type_traits::get(state, Indexes)...); - return 0; - } - - inline bool all_true() - { - return true; - } - templatebool all_true(Arg f, Args... args) - { //check from backward and lazy evaluation - return all_true(args...) && bool(f); - } - - inline void join(std::string& , const char* ) - { - } - templatevoid join(std::string& result, const char* delim, const Arg& str, const Args&... args) - { - result += str; - result += delim; - join(result, delim, args...); - } - - template - struct _wcheckeval - { - _wcheckeval(lua_State* s,int i, bool opt) :state(s), index(i), opt_arg(opt) {} - lua_State* state; - int index; - bool opt_arg; - operator bool() - { - return (opt_arg && lua_isnoneornil(state, index) )|| lua_type_traits::checkType(state, index); - } - }; - - template - struct _scheckeval - { - _scheckeval(lua_State* s, int i, bool opt) :state(s), index(i), opt_arg(opt) {} - lua_State* state; - int index; - bool opt_arg; - operator bool() - { - return (opt_arg && lua_isnoneornil(state, index)) || lua_type_traits::strictCheckType(state, index); - } - }; - - template - bool _ctype_apply(lua_State* state, index_tuple, util::TypeTuple, int opt_count) - { - KAGUYA_UNUSED(state); - KAGUYA_UNUSED(opt_count); - return all_true(_wcheckeval(state, Indexes, sizeof...(Indexes)-opt_count < Indexes)...); - } - template - bool _sctype_apply(lua_State* state, index_tuple, util::TypeTuple, int opt_count) - { - KAGUYA_UNUSED(state); - KAGUYA_UNUSED(opt_count); - return all_true(_scheckeval(state, Indexes, sizeof...(Indexes)-opt_count < Indexes)...); - } - - - template - std::string _type_name_apply(index_tuple, util::TypeTuple, int opt_count) - { - KAGUYA_UNUSED(opt_count); - std::string result; - const int max_arg = sizeof...(Args); - join(result, ",",(((max_arg -opt_count < int(Indexes))? std::string("[OPT]") :std::string("")) + util::pretty_name(typeid(Args)))...); - return result; - } - - template - int call(lua_State* state, F&& f) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - typedef typename index_range<1, fsigtype::argument_count + 1>::type index; - return _call_apply(state, f, index(), fsigtype()); - } - template - bool checkArgTypes(lua_State* state, const F& , int opt_count = 0) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - typedef typename index_range<1, fsigtype::argument_count + 1>::type index; - typedef typename fsigtype::argument_type_tuple argument_type_tuple; - return _ctype_apply(state, index(), argument_type_tuple(), opt_count); - } - template - bool strictCheckArgTypes(lua_State* state, const F& , int opt_count = 0) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - typedef typename index_range<1, fsigtype::argument_count +1>::type index; - typedef typename fsigtype::argument_type_tuple argument_type_tuple; - return _sctype_apply(state, index(), argument_type_tuple(), opt_count); - } - - template - std::string argTypesName(const F& , int opt_count = 0) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - typedef typename index_range<1, fsigtype::argument_count + 1>::type index; - typedef typename fsigtype::argument_type_tuple argument_type_tuple; - return _type_name_apply(index(), argument_type_tuple(), opt_count); - } - template - int minArgCount(const F& ) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return fsigtype::argument_count; - } - template - int maxArgCount(const F& ) - { - typedef typename traits::decay::type ftype; - typedef typename util::FunctionSignature::type fsigtype; - return fsigtype::argument_count; - } - - //for constructor - template - struct ConstructorFunctor; - - template - struct ConstructorFunctor> - { - typedef util::FunctionSignatureType signature_type; - typedef typename index_range<1, sizeof...(Args)+1>::type get_index; - - template int invoke(lua_State* L, index_tuple)const - { - typedef ObjectWrapper wrapper_type; - void *storage = lua_newuserdata(L, sizeof(wrapper_type)); - try { new(storage) wrapper_type(lua_type_traits::get(L, Indexes)...); } - catch (...) { lua_pop(L, 1); throw; } - - class_userdata::setmetatable(L); - return 1; - } - - int operator()(lua_State* L)const - { - return invoke(L, get_index()); - } - - bool checkArgTypes(lua_State* L,int opt_count = 0)const - { - return _ctype_apply(L, get_index(), typename signature_type::argument_type_tuple(), opt_count); - } - bool strictCheckArgTypes(lua_State* L, int opt_count = 0)const - { - return _sctype_apply(L, get_index(), typename signature_type::argument_type_tuple(), opt_count); - } - std::string argTypesName(int opt_count = 0)const - { - return _type_name_apply(get_index(),typename signature_type::argument_type_tuple(), opt_count); - } - }; - - template struct ConstructorFunction; - template struct ConstructorFunction - { - typedef ConstructorFunctor > type; - }; - template struct ConstructorFunction//class type check version - { - typedef ConstructorFunctor > type; - }; - } - using nativefunction::ConstructorFunction; + typedef ConstructorFunctor > + type; +}; +} +using nativefunction::ConstructorFunction; } diff --git a/include/kaguya/object.hpp b/include/kaguya/object.hpp index c0664cd..f066ba4 100644 --- a/include/kaguya/object.hpp +++ b/include/kaguya/object.hpp @@ -14,895 +14,794 @@ #include "kaguya/traits.hpp" #include "kaguya/exception.hpp" -namespace kaguya -{ - namespace types - { - template - struct typetag {}; - } - - inline void* metatable_name_key() { static int key; return &key; } - inline void* metatable_type_table_key() { static int key; return &key; } - - template - const std::type_info& metatableType() - { - return typeid(typename traits::decay::type); - } - template - inline std::string metatableName() - { - return util::pretty_name(metatableType()); - } - - struct ObjectWrapperBase - { - virtual const void* cget() = 0; - virtual void* get() = 0; - - virtual const std::type_info& type() = 0; - - virtual const std::type_info& native_type() { return type(); } - virtual void* native_get() { return get(); } - - ObjectWrapperBase() {} - virtual ~ObjectWrapperBase() {} - private: - - //noncopyable - ObjectWrapperBase(const ObjectWrapperBase&); - ObjectWrapperBase& operator=(const ObjectWrapperBase&); - }; - - template - struct ObjectWrapper : ObjectWrapperBase - { +namespace kaguya { +namespace types { +template struct typetag {}; +} + +inline void *metatable_name_key() { + static int key; + return &key; +} +inline void *metatable_type_table_key() { + static int key; + return &key; +} + +template const std::type_info &metatableType() { + return typeid(typename traits::decay::type); +} +template inline std::string metatableName() { + return util::pretty_name(metatableType()); +} + +struct ObjectWrapperBase { + virtual const void *cget() = 0; + virtual void *get() = 0; + + virtual const std::type_info &type() = 0; + + virtual const std::type_info &native_type() { return type(); } + virtual void *native_get() { return get(); } + + ObjectWrapperBase() {} + virtual ~ObjectWrapperBase() {} + +private: + // noncopyable + ObjectWrapperBase(const ObjectWrapperBase &); + ObjectWrapperBase &operator=(const ObjectWrapperBase &); +}; + +template struct ObjectWrapper : ObjectWrapperBase { #if KAGUYA_USE_CPP11 - template - ObjectWrapper(Args&&... args) : object_(std::forward(args)...) {} + template + ObjectWrapper(Args &&... args) : object_(std::forward(args)...) {} #else - ObjectWrapper() : object_() {} -#define KAGUYA_OBJECT_WRAPPER_CONSTRUCTOR_DEF(N) \ - template\ - ObjectWrapper(KAGUYA_PP_ARG_DEF_REPEAT(N)):object_(KAGUYA_PP_ARG_REPEAT(N)){} + ObjectWrapper() : object_() {} +#define KAGUYA_OBJECT_WRAPPER_CONSTRUCTOR_DEF(N) \ + template \ + ObjectWrapper(KAGUYA_PP_ARG_DEF_REPEAT(N)) \ + : object_(KAGUYA_PP_ARG_REPEAT(N)) {} - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_OBJECT_WRAPPER_CONSTRUCTOR_DEF) + KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, + KAGUYA_OBJECT_WRAPPER_CONSTRUCTOR_DEF) #undef KAGUYA_OBJECT_WRAPPER_CONSTRUCTOR_DEF #endif - virtual const std::type_info& type() - { - return metatableType(); - } - - virtual void* get() - { - return &object_; - } - virtual const void* cget() - { - return &object_; - } - private: - T object_; - }; - - struct ObjectSharedPointerWrapper : ObjectWrapperBase - { - template - ObjectSharedPointerWrapper(const standard::shared_ptr& sptr) :object_(standard::const_pointer_cast::type>(sptr)), type_(metatableType()), - shared_ptr_type_(metatableType::type> >()), const_value_(traits::is_const::value) {} + virtual const std::type_info &type() { return metatableType(); } + + virtual void *get() { return &object_; } + virtual const void *cget() { return &object_; } + +private: + T object_; +}; + +struct ObjectSharedPointerWrapper : ObjectWrapperBase { + template + ObjectSharedPointerWrapper(const standard::shared_ptr &sptr) + : object_(standard::const_pointer_cast< + typename standard::remove_const::type>(sptr)), + type_(metatableType()), + shared_ptr_type_( + metatableType< + standard::shared_ptr::type> >()), + const_value_(traits::is_const::value) {} #if KAGUYA_USE_RVALUE_REFERENCE - template - ObjectSharedPointerWrapper(standard::shared_ptr&& sptr) : object_(std::move(standard::const_pointer_cast::type>(sptr))), type_(metatableType()), - shared_ptr_type_(metatableType::type> >()), const_value_(traits::is_const::value) {} + template + ObjectSharedPointerWrapper(standard::shared_ptr &&sptr) + : object_(std::move(standard::const_pointer_cast< + typename standard::remove_const::type>(sptr))), + type_(metatableType()), + shared_ptr_type_( + metatableType< + standard::shared_ptr::type> >()), + const_value_(traits::is_const::value) {} #endif - virtual const std::type_info& type() - { - return type_; - } - virtual void* get() - { - return const_value_ ? 0 : object_.get(); - } - virtual const void* cget() - { - return object_.get(); - } - standard::shared_ptr object()const { return const_value_ ? standard::shared_ptr() : object_; } - standard::shared_ptr const_object()const { return object_; } - const std::type_info& shared_ptr_type()const { return shared_ptr_type_; } - - - virtual const std::type_info& native_type() - { - return metatableType >(); - } - virtual void* native_get() { return &object_; } - private: - standard::shared_ptr object_; - const std::type_info& type_; - - const std::type_info& shared_ptr_type_; - bool const_value_; - }; - - template - struct ObjectSmartPointerWrapper : ObjectWrapperBase - { - ObjectSmartPointerWrapper(const T& sptr) :object_(sptr) {} + virtual const std::type_info &type() { return type_; } + virtual void *get() { return const_value_ ? 0 : object_.get(); } + virtual const void *cget() { return object_.get(); } + standard::shared_ptr object() const { + return const_value_ ? standard::shared_ptr() : object_; + } + standard::shared_ptr const_object() const { return object_; } + const std::type_info &shared_ptr_type() const { return shared_ptr_type_; } + + virtual const std::type_info &native_type() { + return metatableType >(); + } + virtual void *native_get() { return &object_; } + +private: + standard::shared_ptr object_; + const std::type_info &type_; + + const std::type_info &shared_ptr_type_; + bool const_value_; +}; + +template +struct ObjectSmartPointerWrapper : ObjectWrapperBase { + ObjectSmartPointerWrapper(const T &sptr) : object_(sptr) {} #if KAGUYA_USE_RVALUE_REFERENCE - ObjectSmartPointerWrapper(T&& sptr) : object_(std::move(sptr)) {} + ObjectSmartPointerWrapper(T &&sptr) : object_(std::move(sptr)) {} #endif - virtual const std::type_info& type() - { - return metatableType(); - } - virtual void* get() - { - return object_ ? &(*object_) : 0; - } - virtual const void* cget() - { - return object_ ? &(*object_) : 0; - } - virtual const std::type_info& native_type() - { - return metatableType(); - } - virtual void* native_get() { return &object_; } - private: - T object_; - }; - - template - struct ObjectPointerWrapper : ObjectWrapperBase - { - ObjectPointerWrapper(T* ptr) :object_(ptr) {} - - virtual const std::type_info& type() - { - return metatableType(); - } - virtual void* get() - { - if (traits::is_const::value) - { - return 0; - } - return const_cast(static_cast(object_)); - } - virtual const void* cget() - { - return object_; - } - ~ObjectPointerWrapper() - { - } - protected: - T* object_; - }; - - //Customizable for ObjectPointerWrapper - template - struct ObjectPointerWrapperType - { - typedef ObjectPointerWrapper type; - }; - - //for internal use - struct PointerConverter - { - template - static void* base_pointer_cast(void* from) - { - return static_cast(static_cast(from)); - } - template - static standard::shared_ptr base_shared_pointer_cast(const standard::shared_ptr& from) - { - return standard::shared_ptr(standard::static_pointer_cast(from)); - } - - - typedef void* (*convert_function_type)(void*); - typedef standard::shared_ptr(*shared_ptr_convert_function_type)(const standard::shared_ptr&); - typedef std::pair convert_map_key; - - - template - void add_type_conversion() - { - add_function(metatableType(), metatableType(), &base_pointer_cast); - add_function(metatableType >(), metatableType >(), &base_shared_pointer_cast); - } - - - template - TO* get_pointer(ObjectWrapperBase* from)const - { - const std::type_info& to_type = metatableType(); - //unreachable - //if (to_type == from->type()) - //{ - // return static_cast(from->get()); - //} - std::map >::const_iterator match = function_map_.find(convert_map_key(to_type.name(), from->type().name())); - if (match != function_map_.end()) - { - return static_cast(pcvt_list_apply(from->get(), match->second)); - } - return 0; - - } - template - const TO* get_const_pointer(ObjectWrapperBase* from)const - { - const std::type_info& to_type = metatableType(); - //unreachable - //if (to_type == from->type()) - //{ - // return static_cast(from->cget()); - //} - std::map >::const_iterator match = function_map_.find(convert_map_key(to_type.name(), from->type().name())); - if (match != function_map_.end()) - { - return static_cast(pcvt_list_apply(const_cast(from->cget()), match->second)); - } - return 0; - } - - template - standard::shared_ptr get_shared_pointer(ObjectSharedPointerWrapper* from)const - { - const std::type_info& to_type = metatableType::type> >(); - //unreachable -// if (to_type == from->type()) -// { -// return standard::static_pointer_cast(from->object()); -// } - const std::type_info& from_type = from->shared_ptr_type(); - std::map >::const_iterator match = shared_ptr_function_map_.find(convert_map_key(to_type.name(), from_type.name())); - if (match != shared_ptr_function_map_.end()) - { - standard::shared_ptr sptr = from->object(); - - if (!sptr && standard::is_const::value) - { - sptr = standard::const_pointer_cast(from->const_object()); - } - - return standard::static_pointer_cast(pcvt_list_apply(sptr, match->second)); - } - return standard::shared_ptr(); - } - - template - T* get_pointer(ObjectWrapperBase* from, types::typetag ) - { - return get_pointer(from); - } - template - standard::shared_ptr get_pointer(ObjectWrapperBase* from, types::typetag >) - { - ObjectSharedPointerWrapper* ptr = dynamic_cast(from); - if (ptr) - { - return get_shared_pointer(ptr); - } - return standard::shared_ptr(); - } - - - static int deleter(lua_State *state) - { - PointerConverter* ptr = (PointerConverter*)lua_touserdata(state, 1); - ptr->~PointerConverter(); - return 0; - } - - static PointerConverter& get(lua_State* state) - { - static char kaguya_ptrcvt_key_ptr; - util::ScopedSavedStack save(state); - lua_pushlightuserdata(state, &kaguya_ptrcvt_key_ptr); - lua_rawget(state, LUA_REGISTRYINDEX); - if (lua_isuserdata(state, -1)) - { - return *static_cast(lua_touserdata(state, -1)); - } - else - { - void* ptr = lua_newuserdata(state, sizeof(PointerConverter));//dummy data for gc call - PointerConverter* converter = new(ptr) PointerConverter(); - - lua_createtable(state, 0, 2); - lua_pushcclosure(state, &deleter, 0); - lua_setfield(state, -2, "__gc"); - lua_pushvalue(state, -1); - lua_setfield(state, -2, "__index"); - lua_setmetatable(state, -2);//set to userdata - lua_pushlightuserdata(state, &kaguya_ptrcvt_key_ptr); - lua_pushvalue(state, -2); - lua_rawset(state, LUA_REGISTRYINDEX); - return *converter; - } - } - private: - void add_function(const std::type_info& to_type, const std::type_info& from_type, convert_function_type f) - { - std::map > add_map; - for (std::map >::iterator it = function_map_.begin(); - it != function_map_.end(); ++it) - { - if (it->first.second == to_type.name()) - { - std::vector newlist; - newlist.push_back(f); - newlist.insert(newlist.end(), it->second.begin(), it->second.end()); - add_map[convert_map_key(it->first.first, from_type.name())] = newlist; - } - } - function_map_.insert(add_map.begin(), add_map.end()); - - std::vector flist; flist.push_back(f); - function_map_[convert_map_key(to_type.name(), from_type.name())] = flist; - } - void add_function(const std::type_info& to_type, const std::type_info& from_type, shared_ptr_convert_function_type f) - { - std::map > add_map; - for (std::map >::iterator it = shared_ptr_function_map_.begin(); - it != shared_ptr_function_map_.end(); ++it) - { - if (it->first.second == to_type.name()) - { - std::vector newlist; - newlist.push_back(f); - newlist.insert(newlist.end(), it->second.begin(), it->second.end()); - add_map[convert_map_key(it->first.first, from_type.name())] = newlist; - } - } - shared_ptr_function_map_.insert(add_map.begin(), add_map.end()); - - std::vector flist; flist.push_back(f); - shared_ptr_function_map_[convert_map_key(to_type.name(), from_type.name())] = flist; - } - - void* pcvt_list_apply(void* ptr, const std::vector& flist)const - { - for (std::vector::const_iterator i = flist.begin(); i != flist.end(); ++i) - { - ptr = (*i)(ptr); - } - return ptr; - } - standard::shared_ptr pcvt_list_apply(standard::shared_ptr ptr, const std::vector& flist)const - { - for (std::vector::const_iterator i = flist.begin(); i != flist.end(); ++i) - { + virtual const std::type_info &type() { return metatableType(); } + virtual void *get() { return object_ ? &(*object_) : 0; } + virtual const void *cget() { return object_ ? &(*object_) : 0; } + virtual const std::type_info &native_type() { return metatableType(); } + virtual void *native_get() { return &object_; } + +private: + T object_; +}; + +template struct ObjectPointerWrapper : ObjectWrapperBase { + ObjectPointerWrapper(T *ptr) : object_(ptr) {} + + virtual const std::type_info &type() { return metatableType(); } + virtual void *get() { + if (traits::is_const::value) { + return 0; + } + return const_cast(static_cast(object_)); + } + virtual const void *cget() { return object_; } + ~ObjectPointerWrapper() {} + +protected: + T *object_; +}; + +// Customizable for ObjectPointerWrapper +template struct ObjectPointerWrapperType { + typedef ObjectPointerWrapper type; +}; + +// for internal use +struct PointerConverter { + template static void *base_pointer_cast(void *from) { + return static_cast(static_cast(from)); + } + template + static standard::shared_ptr + base_shared_pointer_cast(const standard::shared_ptr &from) { + return standard::shared_ptr(standard::static_pointer_cast(from)); + } + + typedef void *(*convert_function_type)(void *); + typedef standard::shared_ptr (*shared_ptr_convert_function_type)( + const standard::shared_ptr &); + typedef std::pair convert_map_key; + + template void add_type_conversion() { + add_function(metatableType(), metatableType(), + &base_pointer_cast); + add_function(metatableType >(), + metatableType >(), + &base_shared_pointer_cast); + } + + template TO *get_pointer(ObjectWrapperBase *from) const { + const std::type_info &to_type = metatableType(); + // unreachable + // if (to_type == from->type()) + //{ + // return static_cast(from->get()); + //} + std::map >::const_iterator match = + function_map_.find( + convert_map_key(to_type.name(), from->type().name())); + if (match != function_map_.end()) { + return static_cast(pcvt_list_apply(from->get(), match->second)); + } + return 0; + } + template + const TO *get_const_pointer(ObjectWrapperBase *from) const { + const std::type_info &to_type = metatableType(); + // unreachable + // if (to_type == from->type()) + //{ + // return static_cast(from->cget()); + //} + std::map >::const_iterator match = + function_map_.find( + convert_map_key(to_type.name(), from->type().name())); + if (match != function_map_.end()) { + return static_cast( + pcvt_list_apply(const_cast(from->cget()), match->second)); + } + return 0; + } + + template + standard::shared_ptr + get_shared_pointer(ObjectSharedPointerWrapper *from) const { + const std::type_info &to_type = metatableType< + standard::shared_ptr::type> >(); + // unreachable + // if (to_type == from->type()) + // { + // return + //standard::static_pointer_cast(from->object()); + // } + const std::type_info &from_type = from->shared_ptr_type(); + std::map >::const_iterator + match = shared_ptr_function_map_.find( + convert_map_key(to_type.name(), from_type.name())); + if (match != shared_ptr_function_map_.end()) { + standard::shared_ptr sptr = from->object(); + + if (!sptr && standard::is_const::value) { + sptr = standard::const_pointer_cast(from->const_object()); + } + + return standard::static_pointer_cast( + pcvt_list_apply(sptr, match->second)); + } + return standard::shared_ptr(); + } + + template + T *get_pointer(ObjectWrapperBase *from, types::typetag) { + return get_pointer(from); + } + template + standard::shared_ptr + get_pointer(ObjectWrapperBase *from, + types::typetag >) { + ObjectSharedPointerWrapper *ptr = + dynamic_cast(from); + if (ptr) { + return get_shared_pointer(ptr); + } + return standard::shared_ptr(); + } + + static int deleter(lua_State *state) { + PointerConverter *ptr = (PointerConverter *)lua_touserdata(state, 1); + ptr->~PointerConverter(); + return 0; + } + + static PointerConverter &get(lua_State *state) { + static char kaguya_ptrcvt_key_ptr; + util::ScopedSavedStack save(state); + lua_pushlightuserdata(state, &kaguya_ptrcvt_key_ptr); + lua_rawget(state, LUA_REGISTRYINDEX); + if (lua_isuserdata(state, -1)) { + return *static_cast(lua_touserdata(state, -1)); + } else { + void *ptr = lua_newuserdata( + state, sizeof(PointerConverter)); // dummy data for gc call + PointerConverter *converter = new (ptr) PointerConverter(); + + lua_createtable(state, 0, 2); + lua_pushcclosure(state, &deleter, 0); + lua_setfield(state, -2, "__gc"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_setmetatable(state, -2); // set to userdata + lua_pushlightuserdata(state, &kaguya_ptrcvt_key_ptr); + lua_pushvalue(state, -2); + lua_rawset(state, LUA_REGISTRYINDEX); + return *converter; + } + } + +private: + void add_function(const std::type_info &to_type, + const std::type_info &from_type, convert_function_type f) { + std::map > add_map; + for (std::map >::iterator it = + function_map_.begin(); + it != function_map_.end(); ++it) { + if (it->first.second == to_type.name()) { + std::vector newlist; + newlist.push_back(f); + newlist.insert(newlist.end(), it->second.begin(), it->second.end()); + add_map[convert_map_key(it->first.first, from_type.name())] = newlist; + } + } + function_map_.insert(add_map.begin(), add_map.end()); + + std::vector flist; + flist.push_back(f); + function_map_[convert_map_key(to_type.name(), from_type.name())] = flist; + } + void add_function(const std::type_info &to_type, + const std::type_info &from_type, + shared_ptr_convert_function_type f) { + std::map > + add_map; + for (std::map >::iterator it = + shared_ptr_function_map_.begin(); + it != shared_ptr_function_map_.end(); ++it) { + if (it->first.second == to_type.name()) { + std::vector newlist; + newlist.push_back(f); + newlist.insert(newlist.end(), it->second.begin(), it->second.end()); + add_map[convert_map_key(it->first.first, from_type.name())] = newlist; + } + } + shared_ptr_function_map_.insert(add_map.begin(), add_map.end()); + + std::vector flist; + flist.push_back(f); + shared_ptr_function_map_[convert_map_key(to_type.name(), + from_type.name())] = flist; + } + + void *pcvt_list_apply(void *ptr, + const std::vector &flist) const { + for (std::vector::const_iterator i = flist.begin(); + i != flist.end(); ++i) { + ptr = (*i)(ptr); + } + return ptr; + } + standard::shared_ptr pcvt_list_apply( + standard::shared_ptr ptr, + const std::vector &flist) const { + for (std::vector::const_iterator i = + flist.begin(); + i != flist.end(); ++i) { #if KAGUYA_USE_CPP11 - ptr = (*i)(std::move(ptr)); + ptr = (*i)(std::move(ptr)); #else - ptr = (*i)(ptr); + ptr = (*i)(ptr); #endif - } - return ptr; - } + } + return ptr; + } + PointerConverter() {} - PointerConverter() {} + std::map > function_map_; + std::map > + shared_ptr_function_map_; - std::map > function_map_; - std::map > shared_ptr_function_map_; + PointerConverter(PointerConverter &); + PointerConverter &operator=(PointerConverter &); +}; +namespace detail { +inline bool object_wrapper_type_check(lua_State *l, int index) { +#if KAGUYA_NO_USERDATA_TYPE_CHECK + return lua_isuserdata(l, index) && !lua_islightuserdata(l, index); +#endif + if (lua_getmetatable(l, index)) { + int type = lua_rawgetp_rtype(l, -1, metatable_name_key()); + lua_pop(l, 2); + return type == LUA_TSTRING; + } + return false; +} +} +inline ObjectWrapperBase *object_wrapper(lua_State *l, int index) { + if (detail::object_wrapper_type_check(l, index)) { + ObjectWrapperBase *ptr = + static_cast(lua_touserdata(l, index)); + return ptr; + } + return 0; +} - PointerConverter(PointerConverter&); - PointerConverter& operator=(PointerConverter&); - }; +template +inline ObjectWrapperBase * +object_wrapper(lua_State *l, int index, bool convert = true, + types::typetag = types::typetag()) { + if (detail::object_wrapper_type_check(l, index)) { + ObjectWrapperBase *ptr = + static_cast(lua_touserdata(l, index)); + + if (ptr->type() == metatableType()) { + return ptr; + } else if (convert) { + PointerConverter &pcvt = PointerConverter::get(l); + return pcvt.get_pointer(ptr, types::typetag()) ? ptr : 0; + } + return 0; + } + return 0; +} - namespace detail - { - inline bool object_wrapper_type_check(lua_State* l, int index) - { -#if KAGUYA_NO_USERDATA_TYPE_CHECK - return lua_isuserdata(l, index) && !lua_islightuserdata(l, index); -#endif - if (lua_getmetatable(l, index)) - { - int type = lua_rawgetp_rtype(l, -1, metatable_name_key()); - lua_pop(l, 2); - return type == LUA_TSTRING; - } - return false; - } - } - - inline ObjectWrapperBase* object_wrapper(lua_State* l, int index) - { - if (detail::object_wrapper_type_check(l, index)) - { - ObjectWrapperBase* ptr = static_cast(lua_touserdata(l, index)); - return ptr; - } - return 0; - } - - template - inline ObjectWrapperBase* object_wrapper(lua_State* l, int index, bool convert = true, types::typetag = types::typetag()) - { - if (detail::object_wrapper_type_check(l, index)) - { - ObjectWrapperBase* ptr = static_cast(lua_touserdata(l, index)); - - if (ptr->type() == metatableType()) - { - return ptr; - } - else if (convert) - { - PointerConverter& pcvt = PointerConverter::get(l); - return pcvt.get_pointer(ptr, types::typetag()) ? ptr : 0; - } - return 0; - } - return 0; - } - - template - T* get_pointer(lua_State* l, int index, types::typetag ) - { - int type = lua_type(l, index); - - if (type == LUA_TLIGHTUSERDATA) - { - return (T*)lua_topointer(l, index); - } - else if (type != LUA_TUSERDATA) - { - return 0; - } - else - { - ObjectWrapperBase* objwrapper = object_wrapper(l, index); - if (objwrapper) - { - const std::type_info& to_type = metatableType(); - if (objwrapper->type() == to_type) - { - return static_cast(objwrapper->get()); - } - if (objwrapper->native_type() == to_type) - { - return static_cast(objwrapper->native_get()); - } - else - { - PointerConverter& pcvt = PointerConverter::get(l); - return pcvt.get_pointer(objwrapper); - } - } - } - return 0; - } - template - const T* get_const_pointer(lua_State* l, int index, types::typetag ) - { - int type = lua_type(l, index); - - if (type == LUA_TLIGHTUSERDATA) - { - return (T*)lua_topointer(l, index); - } - else if (type != LUA_TUSERDATA) - { - return 0; - } - else - { - ObjectWrapperBase* objwrapper = object_wrapper(l, index); - if (objwrapper) - { - if (objwrapper->type() == metatableType()) - { - return static_cast(objwrapper->cget()); - } - else - { - PointerConverter& pcvt = PointerConverter::get(l); - return pcvt.get_const_pointer(objwrapper); - } - } - } - return 0; - } - template - const T* get_pointer(lua_State* l, int index, types::typetag ) - { - return get_const_pointer(l, index, types::typetag()); - } - - template - standard::shared_ptr get_shared_pointer(lua_State* l, int index, types::typetag ) - { - ObjectSharedPointerWrapper* ptr = dynamic_cast(object_wrapper(l, index)); - if (ptr) - { - const std::type_info& from_type = ptr->shared_ptr_type(); - const std::type_info& to_type = metatableType::type> >(); - if (from_type == to_type) - { - if (standard::is_const::value) - { - return standard::static_pointer_cast(standard::const_pointer_cast(ptr->const_object())); - } - else - { - return standard::static_pointer_cast(ptr->object()); - } - } - PointerConverter& pcvt = PointerConverter::get(l); - return pcvt.get_shared_pointer(ptr); - } - return standard::shared_ptr(); - } - inline standard::shared_ptr get_shared_pointer(lua_State* l, int index, types::typetag ) - { - ObjectSharedPointerWrapper* ptr = dynamic_cast(object_wrapper(l, index)); - if (ptr) - { - return ptr->object(); - } - return standard::shared_ptr(); - } - inline standard::shared_ptr get_shared_pointer(lua_State* l, int index, types::typetag ) - { - ObjectSharedPointerWrapper* ptr = dynamic_cast(object_wrapper(l, index)); - if (ptr) - { - return ptr->const_object(); - } - return standard::shared_ptr(); - } - - namespace class_userdata - { - templateinline void destructor(T* pointer) - { - if (pointer) - { - pointer->~T(); - } - } - inline bool get_metatable(lua_State* l, const std::type_info& typeinfo) - { - int ttype = lua_rawgetp_rtype(l, LUA_REGISTRYINDEX, metatable_type_table_key());//get metatable registry table - if (ttype != LUA_TTABLE) - { - lua_newtable(l); - lua_rawsetp(l, LUA_REGISTRYINDEX, metatable_type_table_key()); - return false; - } - int type = lua_rawgetp_rtype(l, -1, &typeinfo); - lua_remove(l, -2);//remove metatable registry table - return type != LUA_TNIL; - } - templatebool get_metatable(lua_State* l) - { - return get_metatable(l, metatableType()); - } - templatebool available_metatable(lua_State* l) - { - util::ScopedSavedStack save(l); - return get_metatable(l); - } - - inline bool newmetatable(lua_State* l, const std::type_info& typeinfo, const char* name) - { - if (get_metatable(l, typeinfo)) //already register - { - return false; // - } - lua_pop(l, 1); - lua_rawgetp_rtype(l, LUA_REGISTRYINDEX, metatable_type_table_key());//get metatable registry table - int metaregindex = lua_absindex(l, -1); - - lua_createtable(l, 0, 2); - lua_pushstring(l, name); - lua_pushvalue(l, -1); - lua_setfield(l, -3, "__name"); // metatable.__name = name - lua_rawsetp(l, -2, metatable_name_key()); - lua_pushvalue(l, -1); - lua_rawsetp(l, metaregindex, &typeinfo); - lua_remove(l, metaregindex);//remove metatable registry table - - return true; - } - templatebool newmetatable(lua_State* l) - { - return newmetatable(l, metatableType(), metatableName().c_str()); - } - - - templateinline int deleter(lua_State *state) - { - T* ptr = (T*)lua_touserdata(state, 1); - ptr->~T(); - return 0; - } - struct UnknownType {}; - inline void setmetatable(lua_State* l, const std::type_info& typeinfo) - { - //if not available metatable, set unknown class metatable - if (!get_metatable(l, typeinfo)) - { - lua_pop(l, 1); - if (!get_metatable(l)) - { - lua_pop(l, 1); - newmetatable(l); - lua_pushcclosure(l, &deleter, 0); - lua_setfield(l, -2, "__gc"); - } - } - lua_setmetatable(l, -2); - } - templatevoid setmetatable(lua_State* l) - { - setmetatable(l, metatableType()); - } - } - template - bool available_metatable(lua_State* l, types::typetag = types::typetag()) - { - return class_userdata::available_metatable(l); - } - - namespace util - { - templateinline bool object_checkType(lua_State* l, int index) - { - return object_wrapper(l, index) != 0; - } - templateinline bool object_strictCheckType(lua_State* l, int index) - { - return object_wrapper(l, index, false) != 0; - } - - templateinline optional object_getopt(lua_State* l, int index) - { - const typename traits::remove_reference::type* pointer = get_const_pointer(l, index, types::typetag::type>()); - if (!pointer) - { - return optional(); - } - return *pointer; - } - - templateinline T object_get(lua_State* l, int index) - { - const typename traits::remove_reference::type* pointer = get_const_pointer(l, index, types::typetag::type>()); - if (!pointer) - { - throw LuaTypeMismatch(); - } - return *pointer; - } - - template - struct ConvertibleRegisterHelperProxy - { - template < typename DataType > - ConvertibleRegisterHelperProxy(DataType v) - : holder_(new DataHolder(v)) { } - operator To() - { - return holder_->get(); - } - private: - struct DataHolderBase - { - virtual To get()const = 0; - virtual ~DataHolderBase() {} - }; - template < typename Type > - class DataHolder : public DataHolderBase - { - typedef typename traits::decay::type DataType; - public: - explicit DataHolder(DataType v) : data_(v) { } - virtual To get()const - { - return To(data_); - } - private: - DataType data_; - }; - standard::shared_ptr holder_; - }; +template T *get_pointer(lua_State *l, int index, types::typetag) { + int type = lua_type(l, index); + + if (type == LUA_TLIGHTUSERDATA) { + return (T *)lua_topointer(l, index); + } else if (type != LUA_TUSERDATA) { + return 0; + } else { + ObjectWrapperBase *objwrapper = object_wrapper(l, index); + if (objwrapper) { + const std::type_info &to_type = metatableType(); + if (objwrapper->type() == to_type) { + return static_cast(objwrapper->get()); + } + if (objwrapper->native_type() == to_type) { + return static_cast(objwrapper->native_get()); + } else { + PointerConverter &pcvt = PointerConverter::get(l); + return pcvt.get_pointer(objwrapper); + } + } + } + return 0; +} +template +const T *get_const_pointer(lua_State *l, int index, types::typetag) { + int type = lua_type(l, index); + + if (type == LUA_TLIGHTUSERDATA) { + return (T *)lua_topointer(l, index); + } else if (type != LUA_TUSERDATA) { + return 0; + } else { + ObjectWrapperBase *objwrapper = object_wrapper(l, index); + if (objwrapper) { + if (objwrapper->type() == metatableType()) { + return static_cast(objwrapper->cget()); + } else { + PointerConverter &pcvt = PointerConverter::get(l); + return pcvt.get_const_pointer(objwrapper); + } + } + } + return 0; +} +template +const T *get_pointer(lua_State *l, int index, types::typetag) { + return get_const_pointer(l, index, types::typetag()); +} + +template +standard::shared_ptr get_shared_pointer(lua_State *l, int index, + types::typetag) { + ObjectSharedPointerWrapper *ptr = + dynamic_cast(object_wrapper(l, index)); + if (ptr) { + const std::type_info &from_type = ptr->shared_ptr_type(); + const std::type_info &to_type = + metatableType::type> >(); + if (from_type == to_type) { + if (standard::is_const::value) { + return standard::static_pointer_cast( + standard::const_pointer_cast(ptr->const_object())); + } else { + return standard::static_pointer_cast(ptr->object()); + } + } + PointerConverter &pcvt = PointerConverter::get(l); + return pcvt.get_shared_pointer(ptr); + } + return standard::shared_ptr(); +} +inline standard::shared_ptr get_shared_pointer(lua_State *l, int index, + types::typetag) { + ObjectSharedPointerWrapper *ptr = + dynamic_cast(object_wrapper(l, index)); + if (ptr) { + return ptr->object(); + } + return standard::shared_ptr(); +} +inline standard::shared_ptr +get_shared_pointer(lua_State *l, int index, types::typetag) { + ObjectSharedPointerWrapper *ptr = + dynamic_cast(object_wrapper(l, index)); + if (ptr) { + return ptr->const_object(); + } + return standard::shared_ptr(); +} + +namespace class_userdata { +template inline void destructor(T *pointer) { + if (pointer) { + pointer->~T(); + } +} +inline bool get_metatable(lua_State *l, const std::type_info &typeinfo) { + int ttype = lua_rawgetp_rtype( + l, LUA_REGISTRYINDEX, + metatable_type_table_key()); // get metatable registry table + if (ttype != LUA_TTABLE) { + lua_newtable(l); + lua_rawsetp(l, LUA_REGISTRYINDEX, metatable_type_table_key()); + return false; + } + int type = lua_rawgetp_rtype(l, -1, &typeinfo); + lua_remove(l, -2); // remove metatable registry table + return type != LUA_TNIL; +} +template bool get_metatable(lua_State *l) { + return get_metatable(l, metatableType()); +} +template bool available_metatable(lua_State *l) { + util::ScopedSavedStack save(l); + return get_metatable(l); +} + +inline bool newmetatable(lua_State *l, const std::type_info &typeinfo, + const char *name) { + if (get_metatable(l, typeinfo)) // already register + { + return false; // + } + lua_pop(l, 1); + lua_rawgetp_rtype(l, LUA_REGISTRYINDEX, + metatable_type_table_key()); // get metatable registry table + int metaregindex = lua_absindex(l, -1); + + lua_createtable(l, 0, 2); + lua_pushstring(l, name); + lua_pushvalue(l, -1); + lua_setfield(l, -3, "__name"); // metatable.__name = name + lua_rawsetp(l, -2, metatable_name_key()); + lua_pushvalue(l, -1); + lua_rawsetp(l, metaregindex, &typeinfo); + lua_remove(l, metaregindex); // remove metatable registry table + + return true; +} +template bool newmetatable(lua_State *l) { + return newmetatable(l, metatableType(), metatableName().c_str()); +} + +template inline int deleter(lua_State *state) { + T *ptr = (T *)lua_touserdata(state, 1); + ptr->~T(); + return 0; +} +struct UnknownType {}; +inline void setmetatable(lua_State *l, const std::type_info &typeinfo) { + // if not available metatable, set unknown class metatable + if (!get_metatable(l, typeinfo)) { + lua_pop(l, 1); + if (!get_metatable(l)) { + lua_pop(l, 1); + newmetatable(l); + lua_pushcclosure(l, &deleter, 0); + lua_setfield(l, -2, "__gc"); + } + } + lua_setmetatable(l, -2); +} +template void setmetatable(lua_State *l) { + setmetatable(l, metatableType()); +} +} +template +bool available_metatable(lua_State *l, + types::typetag = types::typetag()) { + return class_userdata::available_metatable(l); +} + +namespace util { +template inline bool object_checkType(lua_State *l, int index) { + return object_wrapper(l, index) != 0; +} +template +inline bool object_strictCheckType(lua_State *l, int index) { + return object_wrapper(l, index, false) != 0; +} + +template +inline optional object_getopt(lua_State *l, int index) { + const typename traits::remove_reference::type *pointer = get_const_pointer( + l, index, types::typetag::type>()); + if (!pointer) { + return optional(); + } + return *pointer; +} + +template inline T object_get(lua_State *l, int index) { + const typename traits::remove_reference::type *pointer = get_const_pointer( + l, index, types::typetag::type>()); + if (!pointer) { + throw LuaTypeMismatch(); + } + return *pointer; +} + +template struct ConvertibleRegisterHelperProxy { + template + ConvertibleRegisterHelperProxy(DataType v) + : holder_(new DataHolder(v)) {} + operator To() { return holder_->get(); } + +private: + struct DataHolderBase { + virtual To get() const = 0; + virtual ~DataHolderBase() {} + }; + template class DataHolder : public DataHolderBase { + typedef typename traits::decay::type DataType; + + public: + explicit DataHolder(DataType v) : data_(v) {} + virtual To get() const { return To(data_); } + + private: + DataType data_; + }; + standard::shared_ptr holder_; +}; #if KAGUYA_USE_CPP11 - templateinline int object_push(lua_State* l, T&& v) - { - typedef ObjectWrapper::type> wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(std::forward(v)); - class_userdata::setmetatable(l); - return 1; - } - - namespace conv_helper_detail - { - template - bool checkType(lua_State*, int) - { - return false; - } - template - bool checkType(lua_State* l, int index) - { - return lua_type_traits::checkType(l, index) - || checkType(l, index); - } - template - bool strictCheckType(lua_State*, int) - { - return false; - } - template - bool strictCheckType(lua_State* l, int index) - { - return lua_type_traits::strictCheckType(l, index) - || strictCheckType(l, index); - ; - } - - template - To get(lua_State*, int) - { - throw LuaTypeMismatch(); - } - template - To get(lua_State* l, int index) - { - typedef optional::get_type> opt_type; - if (auto opt = lua_type_traits::get(l, index)) - { - return *opt; - } - return get(l, index); - } - } - - template - struct ConvertibleRegisterHelper - { - typedef To get_type; - - static bool checkType(lua_State* l, int index) - { - if (object_checkType(l, index)) - { - return true; - } - return conv_helper_detail::checkType(l, index); - } - static bool strictCheckType(lua_State* l, int index) - { - if (object_strictCheckType(l, index)) - { - return true; - } - return conv_helper_detail::strictCheckType(l, index); - } - - static get_type get(lua_State* l, int index) - { - if (auto opt = object_getopt(l, index)) - { - return *opt; - } - return conv_helper_detail::get(l, index); - } - }; +template inline int object_push(lua_State *l, T &&v) { + typedef ObjectWrapper::type> + wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new (storage) wrapper_type(std::forward(v)); + class_userdata::setmetatable(l); + return 1; +} + +namespace conv_helper_detail { +template bool checkType(lua_State *, int) { return false; } +template +bool checkType(lua_State *l, int index) { + return lua_type_traits::checkType(l, index) || + checkType(l, index); +} +template bool strictCheckType(lua_State *, int) { return false; } +template +bool strictCheckType(lua_State *l, int index) { + return lua_type_traits::strictCheckType(l, index) || + strictCheckType(l, index); + ; +} + +template To get(lua_State *, int) { throw LuaTypeMismatch(); } +template +To get(lua_State *l, int index) { + typedef optional::get_type> opt_type; + if (auto opt = lua_type_traits::get(l, index)) { + return *opt; + } + return get(l, index); +} +} + +template struct ConvertibleRegisterHelper { + typedef To get_type; + + static bool checkType(lua_State *l, int index) { + if (object_checkType(l, index)) { + return true; + } + return conv_helper_detail::checkType(l, index); + } + static bool strictCheckType(lua_State *l, int index) { + if (object_strictCheckType(l, index)) { + return true; + } + return conv_helper_detail::strictCheckType(l, index); + } + + static get_type get(lua_State *l, int index) { + if (auto opt = object_getopt(l, index)) { + return *opt; + } + return conv_helper_detail::get(l, index); + } +}; #else - templateinline int object_push(lua_State* l, T v) - { - typedef ObjectWrapper::type> wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(v); - class_userdata::setmetatable(l); - return 1; - } - namespace conv_helper_detail - { -#define KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_REP(N) || lua_type_traits::checkType(state, index) -#define KAGUYA_CONVERTIBLE_REG_HELPER_STRICT_CHECK_TYPE_REP(N) || lua_type_traits::strictCheckType(state, index) -#define KAGUYA_CONVERTIBLE_REG_HELPER_GET_OPT_TYPEDEF(N) typedef optional::get_type> KAGUYA_PP_CAT(opt_type, N); -#define KAGUYA_CONVERTIBLE_REG_HELPER_GET_REP(N) if (KAGUYA_PP_CAT(opt_type, N) opt = lua_type_traits::get(state, index)){return *opt;}else - - template - bool checkType(lua_State*, int, TypeTuple<>) - { - return false; - } - #define KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_DEF(N)\ - template \ - bool checkType(lua_State* state, int index, TypeTuple)\ - {\ - return false KAGUYA_PP_REPEAT(N, KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_REP);\ - } - - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_DEF) +template inline int object_push(lua_State *l, T v) { + typedef ObjectWrapper::type> + wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new (storage) wrapper_type(v); + class_userdata::setmetatable(l); + return 1; +} +namespace conv_helper_detail { +#define KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_REP(N) \ + || lua_type_traits::checkType(state, index) +#define KAGUYA_CONVERTIBLE_REG_HELPER_STRICT_CHECK_TYPE_REP(N) \ + || lua_type_traits::strictCheckType(state, index) +#define KAGUYA_CONVERTIBLE_REG_HELPER_GET_OPT_TYPEDEF(N) \ + typedef optional::get_type> \ + KAGUYA_PP_CAT(opt_type, N); +#define KAGUYA_CONVERTIBLE_REG_HELPER_GET_REP(N) \ + if (KAGUYA_PP_CAT(opt_type, N) opt = \ + lua_type_traits::get(state, index)) { \ + return *opt; \ + } else + +template bool checkType(lua_State *, int, TypeTuple<>) { + return false; +} +#define KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_DEF(N) \ + template \ + bool checkType(lua_State *state, int index, \ + TypeTuple) { \ + return false KAGUYA_PP_REPEAT( \ + N, KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_REP); \ + } + +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, + KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_DEF) #undef KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_DEF - template - bool strictCheckType(lua_State*, int, TypeTuple<>) - { - return false; - } -#define KAGUYA_CONVERTIBLE_REG_HELPER_ST_CHECK_TYPE_DEF(N)\ - template \ - bool strictCheckType(lua_State* state, int index, TypeTuple)\ - {\ - return false KAGUYA_PP_REPEAT(N, KAGUYA_CONVERTIBLE_REG_HELPER_STRICT_CHECK_TYPE_REP);\ - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CONVERTIBLE_REG_HELPER_ST_CHECK_TYPE_DEF) +template bool strictCheckType(lua_State *, int, TypeTuple<>) { + return false; +} +#define KAGUYA_CONVERTIBLE_REG_HELPER_ST_CHECK_TYPE_DEF(N) \ + template \ + bool strictCheckType(lua_State *state, int index, \ + TypeTuple) { \ + return false KAGUYA_PP_REPEAT( \ + N, KAGUYA_CONVERTIBLE_REG_HELPER_STRICT_CHECK_TYPE_REP); \ + } +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, + KAGUYA_CONVERTIBLE_REG_HELPER_ST_CHECK_TYPE_DEF) #undef KAGUYA_CONVERTIBLE_REG_HELPER_ST_CHECK_TYPE_DEF -#define KAGUYA_CONVERTIBLE_REG_HELPER_GET_DEF(N)\ - template \ - To get(lua_State* state, int index, TypeTuple)\ - {\ - KAGUYA_PP_REPEAT(N, KAGUYA_CONVERTIBLE_REG_HELPER_GET_OPT_TYPEDEF)\ - KAGUYA_PP_REPEAT(N, KAGUYA_CONVERTIBLE_REG_HELPER_GET_REP)\ - {throw LuaTypeMismatch();}\ - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CONVERTIBLE_REG_HELPER_GET_DEF) +#define KAGUYA_CONVERTIBLE_REG_HELPER_GET_DEF(N) \ + template \ + To get(lua_State *state, int index, \ + TypeTuple) { \ + KAGUYA_PP_REPEAT(N, KAGUYA_CONVERTIBLE_REG_HELPER_GET_OPT_TYPEDEF) \ + KAGUYA_PP_REPEAT(N, KAGUYA_CONVERTIBLE_REG_HELPER_GET_REP) { \ + throw LuaTypeMismatch(); \ + } \ + } +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, + KAGUYA_CONVERTIBLE_REG_HELPER_GET_DEF) #undef KAGUYA_CONVERTIBLE_REG_HELPER_GET_DEF #undef KAGUYA_CONVERTIBLE_REG_HELPER_CHECK_TYPE_REP #undef KAGUYA_CONVERTIBLE_REG_HELPER_STRICT_CHECK_TYPE_REP #undef KAGUYA_CONVERTIBLE_REG_HELPER_ST_GET_REP #undef KAGUYA_CONVERTIBLE_REG_HELPER_GET_REP - } - -#define KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REP(N) KAGUYA_PP_CAT(typename A,N) = null_type -#define KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REP) - - template - struct ConvertibleRegisterHelper { - typedef To get_type; - typedef TypeTuple conv_types; - - static bool checkType(lua_State* l, int index) - { - if (object_checkType(l, index)) - { - return true; - } - return conv_helper_detail::checkType(l, index, conv_types()); - } - static bool strictCheckType(lua_State* l, int index) - { - if (object_strictCheckType(l, index)) - { - return true; - } - return conv_helper_detail::strictCheckType(l, index, conv_types()); - } - static get_type get(lua_State* l, int index) - { - if (optional opt = object_getopt(l, index)) - { - return *opt; - } - return conv_helper_detail::get(l, index, conv_types()); - } - }; +} + +#define KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REP(N) \ + KAGUYA_PP_CAT(typename A, N) = null_type +#define KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REP) + +template +struct ConvertibleRegisterHelper { + typedef To get_type; + typedef TypeTuple + conv_types; + + static bool checkType(lua_State *l, int index) { + if (object_checkType(l, index)) { + return true; + } + return conv_helper_detail::checkType(l, index, conv_types()); + } + static bool strictCheckType(lua_State *l, int index) { + if (object_strictCheckType(l, index)) { + return true; + } + return conv_helper_detail::strictCheckType(l, index, conv_types()); + } + static get_type get(lua_State *l, int index) { + if (optional opt = object_getopt(l, index)) { + return *opt; + } + return conv_helper_detail::get(l, index, conv_types()); + } +}; #undef KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REP #undef KAGUYA_PP_CONVERTIBLE_REG_HELPER_DEF_REPEAT -#endif - } +#endif +} } diff --git a/include/kaguya/optional.hpp b/include/kaguya/optional.hpp index daceace..e52d2e6 100644 --- a/include/kaguya/optional.hpp +++ b/include/kaguya/optional.hpp @@ -7,257 +7,258 @@ #include #include "kaguya/config.hpp" -namespace kaguya -{ - /// @addtogroup optional - /// @{ - - struct bad_optional_access :std::exception {}; - struct nullopt_t {}; +namespace kaguya { +/// @addtogroup optional +/// @{ - /// @brief self implement for std::optional(C++17 feature). - templateclass optional - { - typedef void (optional::*bool_type)() const; - void this_type_does_not_support_comparisons() const {} - public: - optional() : value_(0) {}; - optional(nullopt_t) : value_(0) {}; - optional(const optional& other) : value_(0) - { - if (other) - { - value_ = new(&storage_) T(other.value()); - } - } - optional(const T& value) - { - value_ = new(&storage_) T(value); - } +struct bad_optional_access : std::exception {}; +struct nullopt_t {}; - ~optional() { - destruct(); - } - optional& operator=(nullopt_t) { destruct(); return *this; } - optional& operator=(const optional& other) - { - if (other) - { - *this = other.value(); - } - else - { - destruct(); - } - return *this; - } - optional& operator=(const T& value) - { - if (value_) - { - *value_ = value; - } - else - { - value_ = new(&storage_) T(value); - } - return *this; - } +/// @brief self implement for std::optional(C++17 feature). +template class optional { + typedef void (optional::*bool_type)() const; + void this_type_does_not_support_comparisons() const {} + +public: + optional() : value_(0){}; + optional(nullopt_t) : value_(0){}; + optional(const optional &other) : value_(0) { + if (other) { + value_ = new (&storage_) T(other.value()); + } + } + optional(const T &value) { value_ = new (&storage_) T(value); } + + ~optional() { destruct(); } + optional &operator=(nullopt_t) { + destruct(); + return *this; + } + optional &operator=(const optional &other) { + if (other) { + *this = other.value(); + } else { + destruct(); + } + return *this; + } + optional &operator=(const T &value) { + if (value_) { + *value_ = value; + } else { + value_ = new (&storage_) T(value); + } + return *this; + } #if KAGUYA_USE_CPP11 - optional(optional&& other) :value_(0) - { - if (other) - { - value_ = new(&storage_) T(std::move(other.value())); - } - } - optional(T&& value) - { - value_ = new(&storage_) T(std::move(value)); - } - optional& operator=(optional&& other) - { - if (other) - { - *this = std::move(other.value()); - } - else - { - destruct(); - } - return *this; - } - optional& operator=(T&& value) - { - if (value_) - { - *value_ = std::move(value); - } - else - { - value_ = new(&storage_) T(std::move(value)); - } - return *this; - } + optional(optional &&other) : value_(0) { + if (other) { + value_ = new (&storage_) T(std::move(other.value())); + } + } + optional(T &&value) { value_ = new (&storage_) T(std::move(value)); } + optional &operator=(optional &&other) { + if (other) { + *this = std::move(other.value()); + } else { + destruct(); + } + return *this; + } + optional &operator=(T &&value) { + if (value_) { + *value_ = std::move(value); + } else { + value_ = new (&storage_) T(std::move(value)); + } + return *this; + } #endif - operator bool_type() const - { - this_type_does_not_support_comparisons(); - return value_ != 0 ? &optional::this_type_does_not_support_comparisons : 0; - } - T& value() - { - if (value_) { return *value_; } - throw bad_optional_access(); - } - const T & value() const - { - if (value_) { return *value_; } - throw bad_optional_access(); - } + operator bool_type() const { + this_type_does_not_support_comparisons(); + return value_ != 0 ? &optional::this_type_does_not_support_comparisons : 0; + } + T &value() { + if (value_) { + return *value_; + } + throw bad_optional_access(); + } + const T &value() const { + if (value_) { + return *value_; + } + throw bad_optional_access(); + } #if KAGUYA_USE_CPP11 - template< class U > - T value_or(U&& default_value) const - { - if (value_) { return *value_; } - return default_value; - } + template T value_or(U &&default_value) const { + if (value_) { + return *value_; + } + return default_value; + } #else - template< class U > - T value_or(const U& default_value)const - { - if (value_) { return *value_; } - return default_value; - } + template T value_or(const U &default_value) const { + if (value_) { + return *value_; + } + return default_value; + } #endif - const T* operator->() const { assert(value_); return value_; } - T* operator->() { assert(value_); return value_; } - const T& operator*() const { assert(value_); return *value_; } - T& operator*() { assert(value_); return *value_; } - private: - void destruct() - { - if (value_) - { - value_->~T(); value_ = 0; - } - } + const T *operator->() const { + assert(value_); + return value_; + } + T *operator->() { + assert(value_); + return value_; + } + const T &operator*() const { + assert(value_); + return *value_; + } + T &operator*() { + assert(value_); + return *value_; + } + +private: + void destruct() { + if (value_) { + value_->~T(); + value_ = 0; + } + } - typename standard::aligned_storage::value>::type storage_; + typename standard::aligned_storage< + sizeof(T), standard::alignment_of::value>::type storage_; - T* value_; - }; + T *value_; +}; - /// @brief specialize optional for reference. - /// sizeof(optional) == sizeof(T*) - templateclass optional - { - typedef void (optional::*bool_type)() const; - void this_type_does_not_support_comparisons() const {} - public: - optional() : value_(0) {}; - optional(nullopt_t) : value_(0) {}; +/// @brief specialize optional for reference. +/// sizeof(optional) == sizeof(T*) +template class optional { + typedef void (optional::*bool_type)() const; + void this_type_does_not_support_comparisons() const {} - optional(const optional& other) :value_(other.value_) { } - optional(T& value) :value_(&value) { } +public: + optional() : value_(0){}; + optional(nullopt_t) : value_(0){}; - ~optional() { - } - optional& operator=(nullopt_t) { - value_ = 0; - return *this; - } - optional& operator=(const optional& other) - { - value_ = other.value_; - return *this; - } - optional& operator=(T& value) - { - value_ = &value; - return *this; - } - operator bool_type() const - { - this_type_does_not_support_comparisons(); - return value_ != 0 ? &optional::this_type_does_not_support_comparisons : 0; - } - T& value() - { - if (value_) { return *value_; } - throw bad_optional_access(); - } - const T & value() const - { - if (value_) { return *value_; } - throw bad_optional_access(); - } + optional(const optional &other) : value_(other.value_) {} + optional(T &value) : value_(&value) {} + + ~optional() {} + optional &operator=(nullopt_t) { + value_ = 0; + return *this; + } + optional &operator=(const optional &other) { + value_ = other.value_; + return *this; + } + optional &operator=(T &value) { + value_ = &value; + return *this; + } + operator bool_type() const { + this_type_does_not_support_comparisons(); + return value_ != 0 ? &optional::this_type_does_not_support_comparisons : 0; + } + T &value() { + if (value_) { + return *value_; + } + throw bad_optional_access(); + } + const T &value() const { + if (value_) { + return *value_; + } + throw bad_optional_access(); + } #if KAGUYA_USE_CPP11 - T& value_or(T& default_value) const - { - if (value_) { return *value_; } - return default_value; - } + T &value_or(T &default_value) const { + if (value_) { + return *value_; + } + return default_value; + } #else - T& value_or(T& default_value)const - { - if (value_) { return *value_; } - return default_value; - } + T &value_or(T &default_value) const { + if (value_) { + return *value_; + } + return default_value; + } #endif - const T* operator->() const { assert(value_); return value_; } - T* operator->() { assert(value_); return value_; } - const T& operator*() const { assert(value_); return *value_; } - T& operator*() { assert(value_); return *value_; } - private: - T* value_; - }; + const T *operator->() const { + assert(value_); + return value_; + } + T *operator->() { + assert(value_); + return value_; + } + const T &operator*() const { + assert(value_); + return *value_; + } + T &operator*() { + assert(value_); + return *value_; + } - /// @name relational operators - /// @brief - ///@{ - template< class T > - bool operator==(const optional& lhs, const optional& rhs) - { - if (bool(lhs) != bool(rhs)) { return false; } - if (bool(lhs) == false) { return true; } - return lhs.value() == rhs.value(); - } - template< class T > - bool operator!=(const optional& lhs, const optional& rhs) - { - return !(lhs == rhs); - } - template< class T > - bool operator<(const optional& lhs, const optional& rhs) - { - if (!bool(rhs)) { return false; } - if (!bool(lhs)) { return true; } - return lhs.value() < rhs.value(); - } - template< class T > - bool operator<=(const optional& lhs, const optional& rhs) - { - return !(rhs < lhs); - } - template< class T > - bool operator>(const optional& lhs, const optional& rhs) - { - return rhs < lhs; - } - template< class T > - bool operator>=(const optional& lhs, const optional& rhs) - { - return !(lhs < rhs); - } - /// @} +private: + T *value_; +}; - /// @} +/// @name relational operators +/// @brief +///@{ +template +bool operator==(const optional &lhs, const optional &rhs) { + if (bool(lhs) != bool(rhs)) { + return false; + } + if (bool(lhs) == false) { + return true; + } + return lhs.value() == rhs.value(); +} +template +bool operator!=(const optional &lhs, const optional &rhs) { + return !(lhs == rhs); } +template +bool operator<(const optional &lhs, const optional &rhs) { + if (!bool(rhs)) { + return false; + } + if (!bool(lhs)) { + return true; + } + return lhs.value() < rhs.value(); +} +template +bool operator<=(const optional &lhs, const optional &rhs) { + return !(rhs < lhs); +} +template +bool operator>(const optional &lhs, const optional &rhs) { + return rhs < lhs; +} +template +bool operator>=(const optional &lhs, const optional &rhs) { + return !(lhs < rhs); +} +/// @} +/// @} +} diff --git a/include/kaguya/preprocess.hpp b/include/kaguya/preprocess.hpp index 25d48bf..a7ed329 100644 --- a/include/kaguya/preprocess.hpp +++ b/include/kaguya/preprocess.hpp @@ -1,42 +1,54 @@ #pragma once -//for c++03 implement +// for c++03 implement #define KAGUYA_VA_ARG(...) __VA_ARGS__ -#define KAGUYA_PP_CAT(F,B) F##B +#define KAGUYA_PP_CAT(F, B) F##B #include "kaguya/preprocess_repeate.hpp" -#define KAGUYA_PP_VARIADIC_TARG_CONCAT_REP(N) ,KAGUYA_PP_CAT(A,N) -#define KAGUYA_PP_VARIADIC_TARG_REP(N) KAGUYA_PP_CAT(A,N) +#define KAGUYA_PP_VARIADIC_TARG_CONCAT_REP(N) , KAGUYA_PP_CAT(A, N) +#define KAGUYA_PP_VARIADIC_TARG_REP(N) KAGUYA_PP_CAT(A, N) -#define KAGUYA_PP_TEMPLATE_ARG_REPEAT_CONCAT(N) KAGUYA_PP_REPEAT(N, KAGUYA_PP_VARIADIC_TARG_CONCAT_REP) -#define KAGUYA_PP_TEMPLATE_ARG_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_VARIADIC_TARG_REP) +#define KAGUYA_PP_TEMPLATE_ARG_REPEAT_CONCAT(N) \ + KAGUYA_PP_REPEAT(N, KAGUYA_PP_VARIADIC_TARG_CONCAT_REP) +#define KAGUYA_PP_TEMPLATE_ARG_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_VARIADIC_TARG_REP) -#define KAGUYA_PP_ARG_DEF_CONCAT_REP(N) ,KAGUYA_PP_CAT(A,N) KAGUYA_PP_CAT(a,N) -#define KAGUYA_PP_ARG_DEF_REP(N) KAGUYA_PP_CAT(A,N) KAGUYA_PP_CAT(a,N) +#define KAGUYA_PP_ARG_DEF_CONCAT_REP(N) \ + , KAGUYA_PP_CAT(A, N) KAGUYA_PP_CAT(a, N) +#define KAGUYA_PP_ARG_DEF_REP(N) KAGUYA_PP_CAT(A, N) KAGUYA_PP_CAT(a, N) -#define KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N) KAGUYA_PP_REPEAT(N, KAGUYA_PP_ARG_DEF_CONCAT_REP) -#define KAGUYA_PP_ARG_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_ARG_DEF_REP) +#define KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N) \ + KAGUYA_PP_REPEAT(N, KAGUYA_PP_ARG_DEF_CONCAT_REP) +#define KAGUYA_PP_ARG_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_ARG_DEF_REP) -#define KAGUYA_PP_ARG_CR_DEF_CONCAT_REP(N) ,const KAGUYA_PP_CAT(A,N)& KAGUYA_PP_CAT(a,N) -#define KAGUYA_PP_ARG_CR_DEF_REP(N) const KAGUYA_PP_CAT(A,N)& KAGUYA_PP_CAT(a,N) +#define KAGUYA_PP_ARG_CR_DEF_CONCAT_REP(N) \ + , const KAGUYA_PP_CAT(A, N) & KAGUYA_PP_CAT(a, N) +#define KAGUYA_PP_ARG_CR_DEF_REP(N) \ + const KAGUYA_PP_CAT(A, N) & KAGUYA_PP_CAT(a, N) -#define KAGUYA_PP_ARG_CR_DEF_REPEAT_CONCAT(N) KAGUYA_PP_REPEAT(N, KAGUYA_PP_ARG_CR_DEF_CONCAT_REP) -#define KAGUYA_PP_ARG_CR_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_ARG_CR_DEF_REP) +#define KAGUYA_PP_ARG_CR_DEF_REPEAT_CONCAT(N) \ + KAGUYA_PP_REPEAT(N, KAGUYA_PP_ARG_CR_DEF_CONCAT_REP) +#define KAGUYA_PP_ARG_CR_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_ARG_CR_DEF_REP) -#define KAGUYA_PP_ARG_CONCAT_REP(N) ,KAGUYA_PP_CAT(a,N) -#define KAGUYA_PP_ARG_REP(N) KAGUYA_PP_CAT(a,N) +#define KAGUYA_PP_ARG_CONCAT_REP(N) , KAGUYA_PP_CAT(a, N) +#define KAGUYA_PP_ARG_REP(N) KAGUYA_PP_CAT(a, N) -#define KAGUYA_PP_ARG_REPEAT_CONCAT(N) KAGUYA_PP_REPEAT(N, KAGUYA_PP_ARG_CONCAT_REP) +#define KAGUYA_PP_ARG_REPEAT_CONCAT(N) \ + KAGUYA_PP_REPEAT(N, KAGUYA_PP_ARG_CONCAT_REP) #define KAGUYA_PP_ARG_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_ARG_REP) -#define KAGUYA_PP_VARIADIC_TDEF_CONCAT_REP(N) ,KAGUYA_PP_CAT(typename A,N) -#define KAGUYA_PP_VARIADIC_TDEF_REP(N) KAGUYA_PP_CAT(typename A,N) +#define KAGUYA_PP_VARIADIC_TDEF_CONCAT_REP(N) , KAGUYA_PP_CAT(typename A, N) +#define KAGUYA_PP_VARIADIC_TDEF_REP(N) KAGUYA_PP_CAT(typename A, N) -#define KAGUYA_PP_TEMPLATE_DEF_REPEAT_CONCAT(N) KAGUYA_PP_REPEAT(N,KAGUYA_PP_VARIADIC_TDEF_CONCAT_REP) -#define KAGUYA_PP_TEMPLATE_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_PP_VARIADIC_TDEF_REP) +#define KAGUYA_PP_TEMPLATE_DEF_REPEAT_CONCAT(N) \ + KAGUYA_PP_REPEAT(N, KAGUYA_PP_VARIADIC_TDEF_CONCAT_REP) +#define KAGUYA_PP_TEMPLATE_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_VARIADIC_TDEF_REP) -#define KAGUYA_PP_ADD(X,Y) KAGUYA_PP_WHILE(Y,X,KAGUYA_PP_INC) -#define KAGUYA_PP_SUB(X,Y) KAGUYA_PP_WHILE(Y,X,KAGUYA_PP_DEC) +#define KAGUYA_PP_ADD(X, Y) KAGUYA_PP_WHILE(Y, X, KAGUYA_PP_INC) +#define KAGUYA_PP_SUB(X, Y) KAGUYA_PP_WHILE(Y, X, KAGUYA_PP_DEC) diff --git a/include/kaguya/preprocess_repeate.hpp b/include/kaguya/preprocess_repeate.hpp index b00d878..79c3c0c 100644 --- a/include/kaguya/preprocess_repeate.hpp +++ b/include/kaguya/preprocess_repeate.hpp @@ -1,5 +1,6 @@ -//generated by generate_preprocess_macro.py +// generated by generate_preprocess_macro.py #pragma once + #define KAGUYA_PP_REPEAT0(MACRO) #define KAGUYA_PP_REPEAT1(MACRO) KAGUYA_PP_REPEAT0(MACRO) MACRO(1) #define KAGUYA_PP_REPEAT2(MACRO) KAGUYA_PP_REPEAT1(MACRO) MACRO(2) @@ -255,8 +256,8 @@ #define KAGUYA_PP_REPEAT252(MACRO) KAGUYA_PP_REPEAT251(MACRO) MACRO(252) #define KAGUYA_PP_REPEAT253(MACRO) KAGUYA_PP_REPEAT252(MACRO) MACRO(253) #define KAGUYA_PP_REPEAT254(MACRO) KAGUYA_PP_REPEAT253(MACRO) MACRO(254) -#define KAGUYA_PP_REPEAT(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REPEAT,COUNT)(MACRO) - +#define KAGUYA_PP_REPEAT(COUNT, MACRO) \ + KAGUYA_PP_CAT(KAGUYA_PP_REPEAT, COUNT)(MACRO) #define KAGUYA_PP_REPEAT_DEF0(MACRO) #define KAGUYA_PP_REPEAT_DEF1(MACRO) KAGUYA_PP_REPEAT_DEF0(MACRO) MACRO(1) @@ -513,266 +514,520 @@ #define KAGUYA_PP_REPEAT_DEF252(MACRO) KAGUYA_PP_REPEAT_DEF251(MACRO) MACRO(252) #define KAGUYA_PP_REPEAT_DEF253(MACRO) KAGUYA_PP_REPEAT_DEF252(MACRO) MACRO(253) #define KAGUYA_PP_REPEAT_DEF254(MACRO) KAGUYA_PP_REPEAT_DEF253(MACRO) MACRO(254) -#define KAGUYA_PP_REPEAT_DEF(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_DEF,COUNT)(MACRO) - +#define KAGUYA_PP_REPEAT_DEF(COUNT, MACRO) \ + KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_DEF, COUNT)(MACRO) #define KAGUYA_PP_REVERSE_REPEAT0(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT1(MACRO) MACRO(1) KAGUYA_PP_REVERSE_REPEAT0(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT2(MACRO) MACRO(2) KAGUYA_PP_REVERSE_REPEAT1(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT3(MACRO) MACRO(3) KAGUYA_PP_REVERSE_REPEAT2(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT4(MACRO) MACRO(4) KAGUYA_PP_REVERSE_REPEAT3(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT5(MACRO) MACRO(5) KAGUYA_PP_REVERSE_REPEAT4(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT6(MACRO) MACRO(6) KAGUYA_PP_REVERSE_REPEAT5(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT7(MACRO) MACRO(7) KAGUYA_PP_REVERSE_REPEAT6(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT8(MACRO) MACRO(8) KAGUYA_PP_REVERSE_REPEAT7(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT9(MACRO) MACRO(9) KAGUYA_PP_REVERSE_REPEAT8(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT10(MACRO) MACRO(10) KAGUYA_PP_REVERSE_REPEAT9(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT11(MACRO) MACRO(11) KAGUYA_PP_REVERSE_REPEAT10(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT12(MACRO) MACRO(12) KAGUYA_PP_REVERSE_REPEAT11(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT13(MACRO) MACRO(13) KAGUYA_PP_REVERSE_REPEAT12(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT14(MACRO) MACRO(14) KAGUYA_PP_REVERSE_REPEAT13(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT15(MACRO) MACRO(15) KAGUYA_PP_REVERSE_REPEAT14(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT16(MACRO) MACRO(16) KAGUYA_PP_REVERSE_REPEAT15(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT17(MACRO) MACRO(17) KAGUYA_PP_REVERSE_REPEAT16(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT18(MACRO) MACRO(18) KAGUYA_PP_REVERSE_REPEAT17(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT19(MACRO) MACRO(19) KAGUYA_PP_REVERSE_REPEAT18(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT20(MACRO) MACRO(20) KAGUYA_PP_REVERSE_REPEAT19(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT21(MACRO) MACRO(21) KAGUYA_PP_REVERSE_REPEAT20(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT22(MACRO) MACRO(22) KAGUYA_PP_REVERSE_REPEAT21(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT23(MACRO) MACRO(23) KAGUYA_PP_REVERSE_REPEAT22(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT24(MACRO) MACRO(24) KAGUYA_PP_REVERSE_REPEAT23(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT25(MACRO) MACRO(25) KAGUYA_PP_REVERSE_REPEAT24(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT26(MACRO) MACRO(26) KAGUYA_PP_REVERSE_REPEAT25(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT27(MACRO) MACRO(27) KAGUYA_PP_REVERSE_REPEAT26(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT28(MACRO) MACRO(28) KAGUYA_PP_REVERSE_REPEAT27(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT29(MACRO) MACRO(29) KAGUYA_PP_REVERSE_REPEAT28(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT30(MACRO) MACRO(30) KAGUYA_PP_REVERSE_REPEAT29(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT31(MACRO) MACRO(31) KAGUYA_PP_REVERSE_REPEAT30(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT32(MACRO) MACRO(32) KAGUYA_PP_REVERSE_REPEAT31(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT33(MACRO) MACRO(33) KAGUYA_PP_REVERSE_REPEAT32(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT34(MACRO) MACRO(34) KAGUYA_PP_REVERSE_REPEAT33(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT35(MACRO) MACRO(35) KAGUYA_PP_REVERSE_REPEAT34(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT36(MACRO) MACRO(36) KAGUYA_PP_REVERSE_REPEAT35(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT37(MACRO) MACRO(37) KAGUYA_PP_REVERSE_REPEAT36(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT38(MACRO) MACRO(38) KAGUYA_PP_REVERSE_REPEAT37(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT39(MACRO) MACRO(39) KAGUYA_PP_REVERSE_REPEAT38(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT40(MACRO) MACRO(40) KAGUYA_PP_REVERSE_REPEAT39(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT41(MACRO) MACRO(41) KAGUYA_PP_REVERSE_REPEAT40(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT42(MACRO) MACRO(42) KAGUYA_PP_REVERSE_REPEAT41(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT43(MACRO) MACRO(43) KAGUYA_PP_REVERSE_REPEAT42(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT44(MACRO) MACRO(44) KAGUYA_PP_REVERSE_REPEAT43(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT45(MACRO) MACRO(45) KAGUYA_PP_REVERSE_REPEAT44(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT46(MACRO) MACRO(46) KAGUYA_PP_REVERSE_REPEAT45(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT47(MACRO) MACRO(47) KAGUYA_PP_REVERSE_REPEAT46(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT48(MACRO) MACRO(48) KAGUYA_PP_REVERSE_REPEAT47(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT49(MACRO) MACRO(49) KAGUYA_PP_REVERSE_REPEAT48(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT50(MACRO) MACRO(50) KAGUYA_PP_REVERSE_REPEAT49(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT51(MACRO) MACRO(51) KAGUYA_PP_REVERSE_REPEAT50(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT52(MACRO) MACRO(52) KAGUYA_PP_REVERSE_REPEAT51(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT53(MACRO) MACRO(53) KAGUYA_PP_REVERSE_REPEAT52(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT54(MACRO) MACRO(54) KAGUYA_PP_REVERSE_REPEAT53(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT55(MACRO) MACRO(55) KAGUYA_PP_REVERSE_REPEAT54(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT56(MACRO) MACRO(56) KAGUYA_PP_REVERSE_REPEAT55(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT57(MACRO) MACRO(57) KAGUYA_PP_REVERSE_REPEAT56(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT58(MACRO) MACRO(58) KAGUYA_PP_REVERSE_REPEAT57(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT59(MACRO) MACRO(59) KAGUYA_PP_REVERSE_REPEAT58(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT60(MACRO) MACRO(60) KAGUYA_PP_REVERSE_REPEAT59(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT61(MACRO) MACRO(61) KAGUYA_PP_REVERSE_REPEAT60(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT62(MACRO) MACRO(62) KAGUYA_PP_REVERSE_REPEAT61(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT63(MACRO) MACRO(63) KAGUYA_PP_REVERSE_REPEAT62(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT64(MACRO) MACRO(64) KAGUYA_PP_REVERSE_REPEAT63(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT65(MACRO) MACRO(65) KAGUYA_PP_REVERSE_REPEAT64(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT66(MACRO) MACRO(66) KAGUYA_PP_REVERSE_REPEAT65(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT67(MACRO) MACRO(67) KAGUYA_PP_REVERSE_REPEAT66(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT68(MACRO) MACRO(68) KAGUYA_PP_REVERSE_REPEAT67(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT69(MACRO) MACRO(69) KAGUYA_PP_REVERSE_REPEAT68(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT70(MACRO) MACRO(70) KAGUYA_PP_REVERSE_REPEAT69(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT71(MACRO) MACRO(71) KAGUYA_PP_REVERSE_REPEAT70(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT72(MACRO) MACRO(72) KAGUYA_PP_REVERSE_REPEAT71(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT73(MACRO) MACRO(73) KAGUYA_PP_REVERSE_REPEAT72(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT74(MACRO) MACRO(74) KAGUYA_PP_REVERSE_REPEAT73(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT75(MACRO) MACRO(75) KAGUYA_PP_REVERSE_REPEAT74(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT76(MACRO) MACRO(76) KAGUYA_PP_REVERSE_REPEAT75(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT77(MACRO) MACRO(77) KAGUYA_PP_REVERSE_REPEAT76(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT78(MACRO) MACRO(78) KAGUYA_PP_REVERSE_REPEAT77(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT79(MACRO) MACRO(79) KAGUYA_PP_REVERSE_REPEAT78(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT80(MACRO) MACRO(80) KAGUYA_PP_REVERSE_REPEAT79(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT81(MACRO) MACRO(81) KAGUYA_PP_REVERSE_REPEAT80(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT82(MACRO) MACRO(82) KAGUYA_PP_REVERSE_REPEAT81(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT83(MACRO) MACRO(83) KAGUYA_PP_REVERSE_REPEAT82(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT84(MACRO) MACRO(84) KAGUYA_PP_REVERSE_REPEAT83(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT85(MACRO) MACRO(85) KAGUYA_PP_REVERSE_REPEAT84(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT86(MACRO) MACRO(86) KAGUYA_PP_REVERSE_REPEAT85(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT87(MACRO) MACRO(87) KAGUYA_PP_REVERSE_REPEAT86(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT88(MACRO) MACRO(88) KAGUYA_PP_REVERSE_REPEAT87(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT89(MACRO) MACRO(89) KAGUYA_PP_REVERSE_REPEAT88(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT90(MACRO) MACRO(90) KAGUYA_PP_REVERSE_REPEAT89(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT91(MACRO) MACRO(91) KAGUYA_PP_REVERSE_REPEAT90(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT92(MACRO) MACRO(92) KAGUYA_PP_REVERSE_REPEAT91(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT93(MACRO) MACRO(93) KAGUYA_PP_REVERSE_REPEAT92(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT94(MACRO) MACRO(94) KAGUYA_PP_REVERSE_REPEAT93(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT95(MACRO) MACRO(95) KAGUYA_PP_REVERSE_REPEAT94(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT96(MACRO) MACRO(96) KAGUYA_PP_REVERSE_REPEAT95(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT97(MACRO) MACRO(97) KAGUYA_PP_REVERSE_REPEAT96(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT98(MACRO) MACRO(98) KAGUYA_PP_REVERSE_REPEAT97(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT99(MACRO) MACRO(99) KAGUYA_PP_REVERSE_REPEAT98(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT100(MACRO) MACRO(100) KAGUYA_PP_REVERSE_REPEAT99(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT101(MACRO) MACRO(101) KAGUYA_PP_REVERSE_REPEAT100(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT102(MACRO) MACRO(102) KAGUYA_PP_REVERSE_REPEAT101(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT103(MACRO) MACRO(103) KAGUYA_PP_REVERSE_REPEAT102(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT104(MACRO) MACRO(104) KAGUYA_PP_REVERSE_REPEAT103(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT105(MACRO) MACRO(105) KAGUYA_PP_REVERSE_REPEAT104(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT106(MACRO) MACRO(106) KAGUYA_PP_REVERSE_REPEAT105(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT107(MACRO) MACRO(107) KAGUYA_PP_REVERSE_REPEAT106(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT108(MACRO) MACRO(108) KAGUYA_PP_REVERSE_REPEAT107(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT109(MACRO) MACRO(109) KAGUYA_PP_REVERSE_REPEAT108(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT110(MACRO) MACRO(110) KAGUYA_PP_REVERSE_REPEAT109(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT111(MACRO) MACRO(111) KAGUYA_PP_REVERSE_REPEAT110(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT112(MACRO) MACRO(112) KAGUYA_PP_REVERSE_REPEAT111(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT113(MACRO) MACRO(113) KAGUYA_PP_REVERSE_REPEAT112(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT114(MACRO) MACRO(114) KAGUYA_PP_REVERSE_REPEAT113(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT115(MACRO) MACRO(115) KAGUYA_PP_REVERSE_REPEAT114(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT116(MACRO) MACRO(116) KAGUYA_PP_REVERSE_REPEAT115(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT117(MACRO) MACRO(117) KAGUYA_PP_REVERSE_REPEAT116(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT118(MACRO) MACRO(118) KAGUYA_PP_REVERSE_REPEAT117(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT119(MACRO) MACRO(119) KAGUYA_PP_REVERSE_REPEAT118(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT120(MACRO) MACRO(120) KAGUYA_PP_REVERSE_REPEAT119(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT121(MACRO) MACRO(121) KAGUYA_PP_REVERSE_REPEAT120(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT122(MACRO) MACRO(122) KAGUYA_PP_REVERSE_REPEAT121(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT123(MACRO) MACRO(123) KAGUYA_PP_REVERSE_REPEAT122(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT124(MACRO) MACRO(124) KAGUYA_PP_REVERSE_REPEAT123(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT125(MACRO) MACRO(125) KAGUYA_PP_REVERSE_REPEAT124(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT126(MACRO) MACRO(126) KAGUYA_PP_REVERSE_REPEAT125(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT127(MACRO) MACRO(127) KAGUYA_PP_REVERSE_REPEAT126(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT128(MACRO) MACRO(128) KAGUYA_PP_REVERSE_REPEAT127(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT129(MACRO) MACRO(129) KAGUYA_PP_REVERSE_REPEAT128(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT130(MACRO) MACRO(130) KAGUYA_PP_REVERSE_REPEAT129(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT131(MACRO) MACRO(131) KAGUYA_PP_REVERSE_REPEAT130(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT132(MACRO) MACRO(132) KAGUYA_PP_REVERSE_REPEAT131(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT133(MACRO) MACRO(133) KAGUYA_PP_REVERSE_REPEAT132(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT134(MACRO) MACRO(134) KAGUYA_PP_REVERSE_REPEAT133(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT135(MACRO) MACRO(135) KAGUYA_PP_REVERSE_REPEAT134(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT136(MACRO) MACRO(136) KAGUYA_PP_REVERSE_REPEAT135(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT137(MACRO) MACRO(137) KAGUYA_PP_REVERSE_REPEAT136(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT138(MACRO) MACRO(138) KAGUYA_PP_REVERSE_REPEAT137(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT139(MACRO) MACRO(139) KAGUYA_PP_REVERSE_REPEAT138(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT140(MACRO) MACRO(140) KAGUYA_PP_REVERSE_REPEAT139(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT141(MACRO) MACRO(141) KAGUYA_PP_REVERSE_REPEAT140(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT142(MACRO) MACRO(142) KAGUYA_PP_REVERSE_REPEAT141(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT143(MACRO) MACRO(143) KAGUYA_PP_REVERSE_REPEAT142(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT144(MACRO) MACRO(144) KAGUYA_PP_REVERSE_REPEAT143(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT145(MACRO) MACRO(145) KAGUYA_PP_REVERSE_REPEAT144(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT146(MACRO) MACRO(146) KAGUYA_PP_REVERSE_REPEAT145(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT147(MACRO) MACRO(147) KAGUYA_PP_REVERSE_REPEAT146(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT148(MACRO) MACRO(148) KAGUYA_PP_REVERSE_REPEAT147(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT149(MACRO) MACRO(149) KAGUYA_PP_REVERSE_REPEAT148(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT150(MACRO) MACRO(150) KAGUYA_PP_REVERSE_REPEAT149(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT151(MACRO) MACRO(151) KAGUYA_PP_REVERSE_REPEAT150(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT152(MACRO) MACRO(152) KAGUYA_PP_REVERSE_REPEAT151(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT153(MACRO) MACRO(153) KAGUYA_PP_REVERSE_REPEAT152(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT154(MACRO) MACRO(154) KAGUYA_PP_REVERSE_REPEAT153(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT155(MACRO) MACRO(155) KAGUYA_PP_REVERSE_REPEAT154(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT156(MACRO) MACRO(156) KAGUYA_PP_REVERSE_REPEAT155(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT157(MACRO) MACRO(157) KAGUYA_PP_REVERSE_REPEAT156(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT158(MACRO) MACRO(158) KAGUYA_PP_REVERSE_REPEAT157(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT159(MACRO) MACRO(159) KAGUYA_PP_REVERSE_REPEAT158(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT160(MACRO) MACRO(160) KAGUYA_PP_REVERSE_REPEAT159(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT161(MACRO) MACRO(161) KAGUYA_PP_REVERSE_REPEAT160(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT162(MACRO) MACRO(162) KAGUYA_PP_REVERSE_REPEAT161(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT163(MACRO) MACRO(163) KAGUYA_PP_REVERSE_REPEAT162(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT164(MACRO) MACRO(164) KAGUYA_PP_REVERSE_REPEAT163(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT165(MACRO) MACRO(165) KAGUYA_PP_REVERSE_REPEAT164(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT166(MACRO) MACRO(166) KAGUYA_PP_REVERSE_REPEAT165(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT167(MACRO) MACRO(167) KAGUYA_PP_REVERSE_REPEAT166(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT168(MACRO) MACRO(168) KAGUYA_PP_REVERSE_REPEAT167(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT169(MACRO) MACRO(169) KAGUYA_PP_REVERSE_REPEAT168(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT170(MACRO) MACRO(170) KAGUYA_PP_REVERSE_REPEAT169(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT171(MACRO) MACRO(171) KAGUYA_PP_REVERSE_REPEAT170(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT172(MACRO) MACRO(172) KAGUYA_PP_REVERSE_REPEAT171(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT173(MACRO) MACRO(173) KAGUYA_PP_REVERSE_REPEAT172(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT174(MACRO) MACRO(174) KAGUYA_PP_REVERSE_REPEAT173(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT175(MACRO) MACRO(175) KAGUYA_PP_REVERSE_REPEAT174(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT176(MACRO) MACRO(176) KAGUYA_PP_REVERSE_REPEAT175(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT177(MACRO) MACRO(177) KAGUYA_PP_REVERSE_REPEAT176(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT178(MACRO) MACRO(178) KAGUYA_PP_REVERSE_REPEAT177(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT179(MACRO) MACRO(179) KAGUYA_PP_REVERSE_REPEAT178(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT180(MACRO) MACRO(180) KAGUYA_PP_REVERSE_REPEAT179(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT181(MACRO) MACRO(181) KAGUYA_PP_REVERSE_REPEAT180(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT182(MACRO) MACRO(182) KAGUYA_PP_REVERSE_REPEAT181(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT183(MACRO) MACRO(183) KAGUYA_PP_REVERSE_REPEAT182(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT184(MACRO) MACRO(184) KAGUYA_PP_REVERSE_REPEAT183(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT185(MACRO) MACRO(185) KAGUYA_PP_REVERSE_REPEAT184(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT186(MACRO) MACRO(186) KAGUYA_PP_REVERSE_REPEAT185(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT187(MACRO) MACRO(187) KAGUYA_PP_REVERSE_REPEAT186(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT188(MACRO) MACRO(188) KAGUYA_PP_REVERSE_REPEAT187(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT189(MACRO) MACRO(189) KAGUYA_PP_REVERSE_REPEAT188(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT190(MACRO) MACRO(190) KAGUYA_PP_REVERSE_REPEAT189(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT191(MACRO) MACRO(191) KAGUYA_PP_REVERSE_REPEAT190(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT192(MACRO) MACRO(192) KAGUYA_PP_REVERSE_REPEAT191(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT193(MACRO) MACRO(193) KAGUYA_PP_REVERSE_REPEAT192(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT194(MACRO) MACRO(194) KAGUYA_PP_REVERSE_REPEAT193(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT195(MACRO) MACRO(195) KAGUYA_PP_REVERSE_REPEAT194(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT196(MACRO) MACRO(196) KAGUYA_PP_REVERSE_REPEAT195(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT197(MACRO) MACRO(197) KAGUYA_PP_REVERSE_REPEAT196(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT198(MACRO) MACRO(198) KAGUYA_PP_REVERSE_REPEAT197(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT199(MACRO) MACRO(199) KAGUYA_PP_REVERSE_REPEAT198(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT200(MACRO) MACRO(200) KAGUYA_PP_REVERSE_REPEAT199(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT201(MACRO) MACRO(201) KAGUYA_PP_REVERSE_REPEAT200(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT202(MACRO) MACRO(202) KAGUYA_PP_REVERSE_REPEAT201(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT203(MACRO) MACRO(203) KAGUYA_PP_REVERSE_REPEAT202(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT204(MACRO) MACRO(204) KAGUYA_PP_REVERSE_REPEAT203(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT205(MACRO) MACRO(205) KAGUYA_PP_REVERSE_REPEAT204(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT206(MACRO) MACRO(206) KAGUYA_PP_REVERSE_REPEAT205(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT207(MACRO) MACRO(207) KAGUYA_PP_REVERSE_REPEAT206(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT208(MACRO) MACRO(208) KAGUYA_PP_REVERSE_REPEAT207(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT209(MACRO) MACRO(209) KAGUYA_PP_REVERSE_REPEAT208(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT210(MACRO) MACRO(210) KAGUYA_PP_REVERSE_REPEAT209(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT211(MACRO) MACRO(211) KAGUYA_PP_REVERSE_REPEAT210(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT212(MACRO) MACRO(212) KAGUYA_PP_REVERSE_REPEAT211(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT213(MACRO) MACRO(213) KAGUYA_PP_REVERSE_REPEAT212(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT214(MACRO) MACRO(214) KAGUYA_PP_REVERSE_REPEAT213(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT215(MACRO) MACRO(215) KAGUYA_PP_REVERSE_REPEAT214(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT216(MACRO) MACRO(216) KAGUYA_PP_REVERSE_REPEAT215(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT217(MACRO) MACRO(217) KAGUYA_PP_REVERSE_REPEAT216(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT218(MACRO) MACRO(218) KAGUYA_PP_REVERSE_REPEAT217(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT219(MACRO) MACRO(219) KAGUYA_PP_REVERSE_REPEAT218(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT220(MACRO) MACRO(220) KAGUYA_PP_REVERSE_REPEAT219(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT221(MACRO) MACRO(221) KAGUYA_PP_REVERSE_REPEAT220(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT222(MACRO) MACRO(222) KAGUYA_PP_REVERSE_REPEAT221(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT223(MACRO) MACRO(223) KAGUYA_PP_REVERSE_REPEAT222(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT224(MACRO) MACRO(224) KAGUYA_PP_REVERSE_REPEAT223(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT225(MACRO) MACRO(225) KAGUYA_PP_REVERSE_REPEAT224(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT226(MACRO) MACRO(226) KAGUYA_PP_REVERSE_REPEAT225(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT227(MACRO) MACRO(227) KAGUYA_PP_REVERSE_REPEAT226(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT228(MACRO) MACRO(228) KAGUYA_PP_REVERSE_REPEAT227(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT229(MACRO) MACRO(229) KAGUYA_PP_REVERSE_REPEAT228(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT230(MACRO) MACRO(230) KAGUYA_PP_REVERSE_REPEAT229(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT231(MACRO) MACRO(231) KAGUYA_PP_REVERSE_REPEAT230(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT232(MACRO) MACRO(232) KAGUYA_PP_REVERSE_REPEAT231(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT233(MACRO) MACRO(233) KAGUYA_PP_REVERSE_REPEAT232(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT234(MACRO) MACRO(234) KAGUYA_PP_REVERSE_REPEAT233(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT235(MACRO) MACRO(235) KAGUYA_PP_REVERSE_REPEAT234(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT236(MACRO) MACRO(236) KAGUYA_PP_REVERSE_REPEAT235(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT237(MACRO) MACRO(237) KAGUYA_PP_REVERSE_REPEAT236(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT238(MACRO) MACRO(238) KAGUYA_PP_REVERSE_REPEAT237(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT239(MACRO) MACRO(239) KAGUYA_PP_REVERSE_REPEAT238(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT240(MACRO) MACRO(240) KAGUYA_PP_REVERSE_REPEAT239(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT241(MACRO) MACRO(241) KAGUYA_PP_REVERSE_REPEAT240(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT242(MACRO) MACRO(242) KAGUYA_PP_REVERSE_REPEAT241(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT243(MACRO) MACRO(243) KAGUYA_PP_REVERSE_REPEAT242(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT244(MACRO) MACRO(244) KAGUYA_PP_REVERSE_REPEAT243(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT245(MACRO) MACRO(245) KAGUYA_PP_REVERSE_REPEAT244(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT246(MACRO) MACRO(246) KAGUYA_PP_REVERSE_REPEAT245(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT247(MACRO) MACRO(247) KAGUYA_PP_REVERSE_REPEAT246(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT248(MACRO) MACRO(248) KAGUYA_PP_REVERSE_REPEAT247(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT249(MACRO) MACRO(249) KAGUYA_PP_REVERSE_REPEAT248(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT250(MACRO) MACRO(250) KAGUYA_PP_REVERSE_REPEAT249(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT251(MACRO) MACRO(251) KAGUYA_PP_REVERSE_REPEAT250(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT252(MACRO) MACRO(252) KAGUYA_PP_REVERSE_REPEAT251(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT253(MACRO) MACRO(253) KAGUYA_PP_REVERSE_REPEAT252(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT254(MACRO) MACRO(254) KAGUYA_PP_REVERSE_REPEAT253(MACRO) -#define KAGUYA_PP_REVERSE_REPEAT(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REVERSE_REPEAT,COUNT)(MACRO) - +#define KAGUYA_PP_REVERSE_REPEAT1(MACRO) \ + MACRO(1) KAGUYA_PP_REVERSE_REPEAT0(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT2(MACRO) \ + MACRO(2) KAGUYA_PP_REVERSE_REPEAT1(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT3(MACRO) \ + MACRO(3) KAGUYA_PP_REVERSE_REPEAT2(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT4(MACRO) \ + MACRO(4) KAGUYA_PP_REVERSE_REPEAT3(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT5(MACRO) \ + MACRO(5) KAGUYA_PP_REVERSE_REPEAT4(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT6(MACRO) \ + MACRO(6) KAGUYA_PP_REVERSE_REPEAT5(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT7(MACRO) \ + MACRO(7) KAGUYA_PP_REVERSE_REPEAT6(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT8(MACRO) \ + MACRO(8) KAGUYA_PP_REVERSE_REPEAT7(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT9(MACRO) \ + MACRO(9) KAGUYA_PP_REVERSE_REPEAT8(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT10(MACRO) \ + MACRO(10) KAGUYA_PP_REVERSE_REPEAT9(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT11(MACRO) \ + MACRO(11) KAGUYA_PP_REVERSE_REPEAT10(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT12(MACRO) \ + MACRO(12) KAGUYA_PP_REVERSE_REPEAT11(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT13(MACRO) \ + MACRO(13) KAGUYA_PP_REVERSE_REPEAT12(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT14(MACRO) \ + MACRO(14) KAGUYA_PP_REVERSE_REPEAT13(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT15(MACRO) \ + MACRO(15) KAGUYA_PP_REVERSE_REPEAT14(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT16(MACRO) \ + MACRO(16) KAGUYA_PP_REVERSE_REPEAT15(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT17(MACRO) \ + MACRO(17) KAGUYA_PP_REVERSE_REPEAT16(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT18(MACRO) \ + MACRO(18) KAGUYA_PP_REVERSE_REPEAT17(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT19(MACRO) \ + MACRO(19) KAGUYA_PP_REVERSE_REPEAT18(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT20(MACRO) \ + MACRO(20) KAGUYA_PP_REVERSE_REPEAT19(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT21(MACRO) \ + MACRO(21) KAGUYA_PP_REVERSE_REPEAT20(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT22(MACRO) \ + MACRO(22) KAGUYA_PP_REVERSE_REPEAT21(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT23(MACRO) \ + MACRO(23) KAGUYA_PP_REVERSE_REPEAT22(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT24(MACRO) \ + MACRO(24) KAGUYA_PP_REVERSE_REPEAT23(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT25(MACRO) \ + MACRO(25) KAGUYA_PP_REVERSE_REPEAT24(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT26(MACRO) \ + MACRO(26) KAGUYA_PP_REVERSE_REPEAT25(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT27(MACRO) \ + MACRO(27) KAGUYA_PP_REVERSE_REPEAT26(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT28(MACRO) \ + MACRO(28) KAGUYA_PP_REVERSE_REPEAT27(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT29(MACRO) \ + MACRO(29) KAGUYA_PP_REVERSE_REPEAT28(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT30(MACRO) \ + MACRO(30) KAGUYA_PP_REVERSE_REPEAT29(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT31(MACRO) \ + MACRO(31) KAGUYA_PP_REVERSE_REPEAT30(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT32(MACRO) \ + MACRO(32) KAGUYA_PP_REVERSE_REPEAT31(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT33(MACRO) \ + MACRO(33) KAGUYA_PP_REVERSE_REPEAT32(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT34(MACRO) \ + MACRO(34) KAGUYA_PP_REVERSE_REPEAT33(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT35(MACRO) \ + MACRO(35) KAGUYA_PP_REVERSE_REPEAT34(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT36(MACRO) \ + MACRO(36) KAGUYA_PP_REVERSE_REPEAT35(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT37(MACRO) \ + MACRO(37) KAGUYA_PP_REVERSE_REPEAT36(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT38(MACRO) \ + MACRO(38) KAGUYA_PP_REVERSE_REPEAT37(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT39(MACRO) \ + MACRO(39) KAGUYA_PP_REVERSE_REPEAT38(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT40(MACRO) \ + MACRO(40) KAGUYA_PP_REVERSE_REPEAT39(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT41(MACRO) \ + MACRO(41) KAGUYA_PP_REVERSE_REPEAT40(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT42(MACRO) \ + MACRO(42) KAGUYA_PP_REVERSE_REPEAT41(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT43(MACRO) \ + MACRO(43) KAGUYA_PP_REVERSE_REPEAT42(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT44(MACRO) \ + MACRO(44) KAGUYA_PP_REVERSE_REPEAT43(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT45(MACRO) \ + MACRO(45) KAGUYA_PP_REVERSE_REPEAT44(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT46(MACRO) \ + MACRO(46) KAGUYA_PP_REVERSE_REPEAT45(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT47(MACRO) \ + MACRO(47) KAGUYA_PP_REVERSE_REPEAT46(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT48(MACRO) \ + MACRO(48) KAGUYA_PP_REVERSE_REPEAT47(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT49(MACRO) \ + MACRO(49) KAGUYA_PP_REVERSE_REPEAT48(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT50(MACRO) \ + MACRO(50) KAGUYA_PP_REVERSE_REPEAT49(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT51(MACRO) \ + MACRO(51) KAGUYA_PP_REVERSE_REPEAT50(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT52(MACRO) \ + MACRO(52) KAGUYA_PP_REVERSE_REPEAT51(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT53(MACRO) \ + MACRO(53) KAGUYA_PP_REVERSE_REPEAT52(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT54(MACRO) \ + MACRO(54) KAGUYA_PP_REVERSE_REPEAT53(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT55(MACRO) \ + MACRO(55) KAGUYA_PP_REVERSE_REPEAT54(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT56(MACRO) \ + MACRO(56) KAGUYA_PP_REVERSE_REPEAT55(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT57(MACRO) \ + MACRO(57) KAGUYA_PP_REVERSE_REPEAT56(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT58(MACRO) \ + MACRO(58) KAGUYA_PP_REVERSE_REPEAT57(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT59(MACRO) \ + MACRO(59) KAGUYA_PP_REVERSE_REPEAT58(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT60(MACRO) \ + MACRO(60) KAGUYA_PP_REVERSE_REPEAT59(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT61(MACRO) \ + MACRO(61) KAGUYA_PP_REVERSE_REPEAT60(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT62(MACRO) \ + MACRO(62) KAGUYA_PP_REVERSE_REPEAT61(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT63(MACRO) \ + MACRO(63) KAGUYA_PP_REVERSE_REPEAT62(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT64(MACRO) \ + MACRO(64) KAGUYA_PP_REVERSE_REPEAT63(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT65(MACRO) \ + MACRO(65) KAGUYA_PP_REVERSE_REPEAT64(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT66(MACRO) \ + MACRO(66) KAGUYA_PP_REVERSE_REPEAT65(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT67(MACRO) \ + MACRO(67) KAGUYA_PP_REVERSE_REPEAT66(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT68(MACRO) \ + MACRO(68) KAGUYA_PP_REVERSE_REPEAT67(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT69(MACRO) \ + MACRO(69) KAGUYA_PP_REVERSE_REPEAT68(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT70(MACRO) \ + MACRO(70) KAGUYA_PP_REVERSE_REPEAT69(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT71(MACRO) \ + MACRO(71) KAGUYA_PP_REVERSE_REPEAT70(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT72(MACRO) \ + MACRO(72) KAGUYA_PP_REVERSE_REPEAT71(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT73(MACRO) \ + MACRO(73) KAGUYA_PP_REVERSE_REPEAT72(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT74(MACRO) \ + MACRO(74) KAGUYA_PP_REVERSE_REPEAT73(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT75(MACRO) \ + MACRO(75) KAGUYA_PP_REVERSE_REPEAT74(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT76(MACRO) \ + MACRO(76) KAGUYA_PP_REVERSE_REPEAT75(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT77(MACRO) \ + MACRO(77) KAGUYA_PP_REVERSE_REPEAT76(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT78(MACRO) \ + MACRO(78) KAGUYA_PP_REVERSE_REPEAT77(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT79(MACRO) \ + MACRO(79) KAGUYA_PP_REVERSE_REPEAT78(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT80(MACRO) \ + MACRO(80) KAGUYA_PP_REVERSE_REPEAT79(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT81(MACRO) \ + MACRO(81) KAGUYA_PP_REVERSE_REPEAT80(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT82(MACRO) \ + MACRO(82) KAGUYA_PP_REVERSE_REPEAT81(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT83(MACRO) \ + MACRO(83) KAGUYA_PP_REVERSE_REPEAT82(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT84(MACRO) \ + MACRO(84) KAGUYA_PP_REVERSE_REPEAT83(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT85(MACRO) \ + MACRO(85) KAGUYA_PP_REVERSE_REPEAT84(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT86(MACRO) \ + MACRO(86) KAGUYA_PP_REVERSE_REPEAT85(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT87(MACRO) \ + MACRO(87) KAGUYA_PP_REVERSE_REPEAT86(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT88(MACRO) \ + MACRO(88) KAGUYA_PP_REVERSE_REPEAT87(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT89(MACRO) \ + MACRO(89) KAGUYA_PP_REVERSE_REPEAT88(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT90(MACRO) \ + MACRO(90) KAGUYA_PP_REVERSE_REPEAT89(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT91(MACRO) \ + MACRO(91) KAGUYA_PP_REVERSE_REPEAT90(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT92(MACRO) \ + MACRO(92) KAGUYA_PP_REVERSE_REPEAT91(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT93(MACRO) \ + MACRO(93) KAGUYA_PP_REVERSE_REPEAT92(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT94(MACRO) \ + MACRO(94) KAGUYA_PP_REVERSE_REPEAT93(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT95(MACRO) \ + MACRO(95) KAGUYA_PP_REVERSE_REPEAT94(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT96(MACRO) \ + MACRO(96) KAGUYA_PP_REVERSE_REPEAT95(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT97(MACRO) \ + MACRO(97) KAGUYA_PP_REVERSE_REPEAT96(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT98(MACRO) \ + MACRO(98) KAGUYA_PP_REVERSE_REPEAT97(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT99(MACRO) \ + MACRO(99) KAGUYA_PP_REVERSE_REPEAT98(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT100(MACRO) \ + MACRO(100) KAGUYA_PP_REVERSE_REPEAT99(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT101(MACRO) \ + MACRO(101) KAGUYA_PP_REVERSE_REPEAT100(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT102(MACRO) \ + MACRO(102) KAGUYA_PP_REVERSE_REPEAT101(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT103(MACRO) \ + MACRO(103) KAGUYA_PP_REVERSE_REPEAT102(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT104(MACRO) \ + MACRO(104) KAGUYA_PP_REVERSE_REPEAT103(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT105(MACRO) \ + MACRO(105) KAGUYA_PP_REVERSE_REPEAT104(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT106(MACRO) \ + MACRO(106) KAGUYA_PP_REVERSE_REPEAT105(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT107(MACRO) \ + MACRO(107) KAGUYA_PP_REVERSE_REPEAT106(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT108(MACRO) \ + MACRO(108) KAGUYA_PP_REVERSE_REPEAT107(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT109(MACRO) \ + MACRO(109) KAGUYA_PP_REVERSE_REPEAT108(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT110(MACRO) \ + MACRO(110) KAGUYA_PP_REVERSE_REPEAT109(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT111(MACRO) \ + MACRO(111) KAGUYA_PP_REVERSE_REPEAT110(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT112(MACRO) \ + MACRO(112) KAGUYA_PP_REVERSE_REPEAT111(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT113(MACRO) \ + MACRO(113) KAGUYA_PP_REVERSE_REPEAT112(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT114(MACRO) \ + MACRO(114) KAGUYA_PP_REVERSE_REPEAT113(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT115(MACRO) \ + MACRO(115) KAGUYA_PP_REVERSE_REPEAT114(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT116(MACRO) \ + MACRO(116) KAGUYA_PP_REVERSE_REPEAT115(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT117(MACRO) \ + MACRO(117) KAGUYA_PP_REVERSE_REPEAT116(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT118(MACRO) \ + MACRO(118) KAGUYA_PP_REVERSE_REPEAT117(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT119(MACRO) \ + MACRO(119) KAGUYA_PP_REVERSE_REPEAT118(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT120(MACRO) \ + MACRO(120) KAGUYA_PP_REVERSE_REPEAT119(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT121(MACRO) \ + MACRO(121) KAGUYA_PP_REVERSE_REPEAT120(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT122(MACRO) \ + MACRO(122) KAGUYA_PP_REVERSE_REPEAT121(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT123(MACRO) \ + MACRO(123) KAGUYA_PP_REVERSE_REPEAT122(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT124(MACRO) \ + MACRO(124) KAGUYA_PP_REVERSE_REPEAT123(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT125(MACRO) \ + MACRO(125) KAGUYA_PP_REVERSE_REPEAT124(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT126(MACRO) \ + MACRO(126) KAGUYA_PP_REVERSE_REPEAT125(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT127(MACRO) \ + MACRO(127) KAGUYA_PP_REVERSE_REPEAT126(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT128(MACRO) \ + MACRO(128) KAGUYA_PP_REVERSE_REPEAT127(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT129(MACRO) \ + MACRO(129) KAGUYA_PP_REVERSE_REPEAT128(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT130(MACRO) \ + MACRO(130) KAGUYA_PP_REVERSE_REPEAT129(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT131(MACRO) \ + MACRO(131) KAGUYA_PP_REVERSE_REPEAT130(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT132(MACRO) \ + MACRO(132) KAGUYA_PP_REVERSE_REPEAT131(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT133(MACRO) \ + MACRO(133) KAGUYA_PP_REVERSE_REPEAT132(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT134(MACRO) \ + MACRO(134) KAGUYA_PP_REVERSE_REPEAT133(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT135(MACRO) \ + MACRO(135) KAGUYA_PP_REVERSE_REPEAT134(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT136(MACRO) \ + MACRO(136) KAGUYA_PP_REVERSE_REPEAT135(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT137(MACRO) \ + MACRO(137) KAGUYA_PP_REVERSE_REPEAT136(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT138(MACRO) \ + MACRO(138) KAGUYA_PP_REVERSE_REPEAT137(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT139(MACRO) \ + MACRO(139) KAGUYA_PP_REVERSE_REPEAT138(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT140(MACRO) \ + MACRO(140) KAGUYA_PP_REVERSE_REPEAT139(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT141(MACRO) \ + MACRO(141) KAGUYA_PP_REVERSE_REPEAT140(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT142(MACRO) \ + MACRO(142) KAGUYA_PP_REVERSE_REPEAT141(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT143(MACRO) \ + MACRO(143) KAGUYA_PP_REVERSE_REPEAT142(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT144(MACRO) \ + MACRO(144) KAGUYA_PP_REVERSE_REPEAT143(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT145(MACRO) \ + MACRO(145) KAGUYA_PP_REVERSE_REPEAT144(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT146(MACRO) \ + MACRO(146) KAGUYA_PP_REVERSE_REPEAT145(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT147(MACRO) \ + MACRO(147) KAGUYA_PP_REVERSE_REPEAT146(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT148(MACRO) \ + MACRO(148) KAGUYA_PP_REVERSE_REPEAT147(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT149(MACRO) \ + MACRO(149) KAGUYA_PP_REVERSE_REPEAT148(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT150(MACRO) \ + MACRO(150) KAGUYA_PP_REVERSE_REPEAT149(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT151(MACRO) \ + MACRO(151) KAGUYA_PP_REVERSE_REPEAT150(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT152(MACRO) \ + MACRO(152) KAGUYA_PP_REVERSE_REPEAT151(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT153(MACRO) \ + MACRO(153) KAGUYA_PP_REVERSE_REPEAT152(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT154(MACRO) \ + MACRO(154) KAGUYA_PP_REVERSE_REPEAT153(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT155(MACRO) \ + MACRO(155) KAGUYA_PP_REVERSE_REPEAT154(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT156(MACRO) \ + MACRO(156) KAGUYA_PP_REVERSE_REPEAT155(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT157(MACRO) \ + MACRO(157) KAGUYA_PP_REVERSE_REPEAT156(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT158(MACRO) \ + MACRO(158) KAGUYA_PP_REVERSE_REPEAT157(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT159(MACRO) \ + MACRO(159) KAGUYA_PP_REVERSE_REPEAT158(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT160(MACRO) \ + MACRO(160) KAGUYA_PP_REVERSE_REPEAT159(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT161(MACRO) \ + MACRO(161) KAGUYA_PP_REVERSE_REPEAT160(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT162(MACRO) \ + MACRO(162) KAGUYA_PP_REVERSE_REPEAT161(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT163(MACRO) \ + MACRO(163) KAGUYA_PP_REVERSE_REPEAT162(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT164(MACRO) \ + MACRO(164) KAGUYA_PP_REVERSE_REPEAT163(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT165(MACRO) \ + MACRO(165) KAGUYA_PP_REVERSE_REPEAT164(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT166(MACRO) \ + MACRO(166) KAGUYA_PP_REVERSE_REPEAT165(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT167(MACRO) \ + MACRO(167) KAGUYA_PP_REVERSE_REPEAT166(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT168(MACRO) \ + MACRO(168) KAGUYA_PP_REVERSE_REPEAT167(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT169(MACRO) \ + MACRO(169) KAGUYA_PP_REVERSE_REPEAT168(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT170(MACRO) \ + MACRO(170) KAGUYA_PP_REVERSE_REPEAT169(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT171(MACRO) \ + MACRO(171) KAGUYA_PP_REVERSE_REPEAT170(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT172(MACRO) \ + MACRO(172) KAGUYA_PP_REVERSE_REPEAT171(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT173(MACRO) \ + MACRO(173) KAGUYA_PP_REVERSE_REPEAT172(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT174(MACRO) \ + MACRO(174) KAGUYA_PP_REVERSE_REPEAT173(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT175(MACRO) \ + MACRO(175) KAGUYA_PP_REVERSE_REPEAT174(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT176(MACRO) \ + MACRO(176) KAGUYA_PP_REVERSE_REPEAT175(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT177(MACRO) \ + MACRO(177) KAGUYA_PP_REVERSE_REPEAT176(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT178(MACRO) \ + MACRO(178) KAGUYA_PP_REVERSE_REPEAT177(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT179(MACRO) \ + MACRO(179) KAGUYA_PP_REVERSE_REPEAT178(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT180(MACRO) \ + MACRO(180) KAGUYA_PP_REVERSE_REPEAT179(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT181(MACRO) \ + MACRO(181) KAGUYA_PP_REVERSE_REPEAT180(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT182(MACRO) \ + MACRO(182) KAGUYA_PP_REVERSE_REPEAT181(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT183(MACRO) \ + MACRO(183) KAGUYA_PP_REVERSE_REPEAT182(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT184(MACRO) \ + MACRO(184) KAGUYA_PP_REVERSE_REPEAT183(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT185(MACRO) \ + MACRO(185) KAGUYA_PP_REVERSE_REPEAT184(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT186(MACRO) \ + MACRO(186) KAGUYA_PP_REVERSE_REPEAT185(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT187(MACRO) \ + MACRO(187) KAGUYA_PP_REVERSE_REPEAT186(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT188(MACRO) \ + MACRO(188) KAGUYA_PP_REVERSE_REPEAT187(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT189(MACRO) \ + MACRO(189) KAGUYA_PP_REVERSE_REPEAT188(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT190(MACRO) \ + MACRO(190) KAGUYA_PP_REVERSE_REPEAT189(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT191(MACRO) \ + MACRO(191) KAGUYA_PP_REVERSE_REPEAT190(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT192(MACRO) \ + MACRO(192) KAGUYA_PP_REVERSE_REPEAT191(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT193(MACRO) \ + MACRO(193) KAGUYA_PP_REVERSE_REPEAT192(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT194(MACRO) \ + MACRO(194) KAGUYA_PP_REVERSE_REPEAT193(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT195(MACRO) \ + MACRO(195) KAGUYA_PP_REVERSE_REPEAT194(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT196(MACRO) \ + MACRO(196) KAGUYA_PP_REVERSE_REPEAT195(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT197(MACRO) \ + MACRO(197) KAGUYA_PP_REVERSE_REPEAT196(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT198(MACRO) \ + MACRO(198) KAGUYA_PP_REVERSE_REPEAT197(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT199(MACRO) \ + MACRO(199) KAGUYA_PP_REVERSE_REPEAT198(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT200(MACRO) \ + MACRO(200) KAGUYA_PP_REVERSE_REPEAT199(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT201(MACRO) \ + MACRO(201) KAGUYA_PP_REVERSE_REPEAT200(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT202(MACRO) \ + MACRO(202) KAGUYA_PP_REVERSE_REPEAT201(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT203(MACRO) \ + MACRO(203) KAGUYA_PP_REVERSE_REPEAT202(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT204(MACRO) \ + MACRO(204) KAGUYA_PP_REVERSE_REPEAT203(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT205(MACRO) \ + MACRO(205) KAGUYA_PP_REVERSE_REPEAT204(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT206(MACRO) \ + MACRO(206) KAGUYA_PP_REVERSE_REPEAT205(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT207(MACRO) \ + MACRO(207) KAGUYA_PP_REVERSE_REPEAT206(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT208(MACRO) \ + MACRO(208) KAGUYA_PP_REVERSE_REPEAT207(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT209(MACRO) \ + MACRO(209) KAGUYA_PP_REVERSE_REPEAT208(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT210(MACRO) \ + MACRO(210) KAGUYA_PP_REVERSE_REPEAT209(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT211(MACRO) \ + MACRO(211) KAGUYA_PP_REVERSE_REPEAT210(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT212(MACRO) \ + MACRO(212) KAGUYA_PP_REVERSE_REPEAT211(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT213(MACRO) \ + MACRO(213) KAGUYA_PP_REVERSE_REPEAT212(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT214(MACRO) \ + MACRO(214) KAGUYA_PP_REVERSE_REPEAT213(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT215(MACRO) \ + MACRO(215) KAGUYA_PP_REVERSE_REPEAT214(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT216(MACRO) \ + MACRO(216) KAGUYA_PP_REVERSE_REPEAT215(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT217(MACRO) \ + MACRO(217) KAGUYA_PP_REVERSE_REPEAT216(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT218(MACRO) \ + MACRO(218) KAGUYA_PP_REVERSE_REPEAT217(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT219(MACRO) \ + MACRO(219) KAGUYA_PP_REVERSE_REPEAT218(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT220(MACRO) \ + MACRO(220) KAGUYA_PP_REVERSE_REPEAT219(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT221(MACRO) \ + MACRO(221) KAGUYA_PP_REVERSE_REPEAT220(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT222(MACRO) \ + MACRO(222) KAGUYA_PP_REVERSE_REPEAT221(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT223(MACRO) \ + MACRO(223) KAGUYA_PP_REVERSE_REPEAT222(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT224(MACRO) \ + MACRO(224) KAGUYA_PP_REVERSE_REPEAT223(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT225(MACRO) \ + MACRO(225) KAGUYA_PP_REVERSE_REPEAT224(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT226(MACRO) \ + MACRO(226) KAGUYA_PP_REVERSE_REPEAT225(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT227(MACRO) \ + MACRO(227) KAGUYA_PP_REVERSE_REPEAT226(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT228(MACRO) \ + MACRO(228) KAGUYA_PP_REVERSE_REPEAT227(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT229(MACRO) \ + MACRO(229) KAGUYA_PP_REVERSE_REPEAT228(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT230(MACRO) \ + MACRO(230) KAGUYA_PP_REVERSE_REPEAT229(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT231(MACRO) \ + MACRO(231) KAGUYA_PP_REVERSE_REPEAT230(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT232(MACRO) \ + MACRO(232) KAGUYA_PP_REVERSE_REPEAT231(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT233(MACRO) \ + MACRO(233) KAGUYA_PP_REVERSE_REPEAT232(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT234(MACRO) \ + MACRO(234) KAGUYA_PP_REVERSE_REPEAT233(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT235(MACRO) \ + MACRO(235) KAGUYA_PP_REVERSE_REPEAT234(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT236(MACRO) \ + MACRO(236) KAGUYA_PP_REVERSE_REPEAT235(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT237(MACRO) \ + MACRO(237) KAGUYA_PP_REVERSE_REPEAT236(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT238(MACRO) \ + MACRO(238) KAGUYA_PP_REVERSE_REPEAT237(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT239(MACRO) \ + MACRO(239) KAGUYA_PP_REVERSE_REPEAT238(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT240(MACRO) \ + MACRO(240) KAGUYA_PP_REVERSE_REPEAT239(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT241(MACRO) \ + MACRO(241) KAGUYA_PP_REVERSE_REPEAT240(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT242(MACRO) \ + MACRO(242) KAGUYA_PP_REVERSE_REPEAT241(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT243(MACRO) \ + MACRO(243) KAGUYA_PP_REVERSE_REPEAT242(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT244(MACRO) \ + MACRO(244) KAGUYA_PP_REVERSE_REPEAT243(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT245(MACRO) \ + MACRO(245) KAGUYA_PP_REVERSE_REPEAT244(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT246(MACRO) \ + MACRO(246) KAGUYA_PP_REVERSE_REPEAT245(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT247(MACRO) \ + MACRO(247) KAGUYA_PP_REVERSE_REPEAT246(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT248(MACRO) \ + MACRO(248) KAGUYA_PP_REVERSE_REPEAT247(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT249(MACRO) \ + MACRO(249) KAGUYA_PP_REVERSE_REPEAT248(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT250(MACRO) \ + MACRO(250) KAGUYA_PP_REVERSE_REPEAT249(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT251(MACRO) \ + MACRO(251) KAGUYA_PP_REVERSE_REPEAT250(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT252(MACRO) \ + MACRO(252) KAGUYA_PP_REVERSE_REPEAT251(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT253(MACRO) \ + MACRO(253) KAGUYA_PP_REVERSE_REPEAT252(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT254(MACRO) \ + MACRO(254) KAGUYA_PP_REVERSE_REPEAT253(MACRO) +#define KAGUYA_PP_REVERSE_REPEAT(COUNT, MACRO) \ + KAGUYA_PP_CAT(KAGUYA_PP_REVERSE_REPEAT, COUNT)(MACRO) #define KAGUYA_PP_REPEAT_ARG0(MACRO) #define KAGUYA_PP_REPEAT_ARG1(MACRO) MACRO(1) @@ -875,678 +1130,1341 @@ #define KAGUYA_PP_REPEAT_ARG98(MACRO) KAGUYA_PP_REPEAT_ARG97(MACRO), MACRO(98) #define KAGUYA_PP_REPEAT_ARG99(MACRO) KAGUYA_PP_REPEAT_ARG98(MACRO), MACRO(99) #define KAGUYA_PP_REPEAT_ARG100(MACRO) KAGUYA_PP_REPEAT_ARG99(MACRO), MACRO(100) -#define KAGUYA_PP_REPEAT_ARG101(MACRO) KAGUYA_PP_REPEAT_ARG100(MACRO), MACRO(101) -#define KAGUYA_PP_REPEAT_ARG102(MACRO) KAGUYA_PP_REPEAT_ARG101(MACRO), MACRO(102) -#define KAGUYA_PP_REPEAT_ARG103(MACRO) KAGUYA_PP_REPEAT_ARG102(MACRO), MACRO(103) -#define KAGUYA_PP_REPEAT_ARG104(MACRO) KAGUYA_PP_REPEAT_ARG103(MACRO), MACRO(104) -#define KAGUYA_PP_REPEAT_ARG105(MACRO) KAGUYA_PP_REPEAT_ARG104(MACRO), MACRO(105) -#define KAGUYA_PP_REPEAT_ARG106(MACRO) KAGUYA_PP_REPEAT_ARG105(MACRO), MACRO(106) -#define KAGUYA_PP_REPEAT_ARG107(MACRO) KAGUYA_PP_REPEAT_ARG106(MACRO), MACRO(107) -#define KAGUYA_PP_REPEAT_ARG108(MACRO) KAGUYA_PP_REPEAT_ARG107(MACRO), MACRO(108) -#define KAGUYA_PP_REPEAT_ARG109(MACRO) KAGUYA_PP_REPEAT_ARG108(MACRO), MACRO(109) -#define KAGUYA_PP_REPEAT_ARG110(MACRO) KAGUYA_PP_REPEAT_ARG109(MACRO), MACRO(110) -#define KAGUYA_PP_REPEAT_ARG111(MACRO) KAGUYA_PP_REPEAT_ARG110(MACRO), MACRO(111) -#define KAGUYA_PP_REPEAT_ARG112(MACRO) KAGUYA_PP_REPEAT_ARG111(MACRO), MACRO(112) -#define KAGUYA_PP_REPEAT_ARG113(MACRO) KAGUYA_PP_REPEAT_ARG112(MACRO), MACRO(113) -#define KAGUYA_PP_REPEAT_ARG114(MACRO) KAGUYA_PP_REPEAT_ARG113(MACRO), MACRO(114) -#define KAGUYA_PP_REPEAT_ARG115(MACRO) KAGUYA_PP_REPEAT_ARG114(MACRO), MACRO(115) -#define KAGUYA_PP_REPEAT_ARG116(MACRO) KAGUYA_PP_REPEAT_ARG115(MACRO), MACRO(116) -#define KAGUYA_PP_REPEAT_ARG117(MACRO) KAGUYA_PP_REPEAT_ARG116(MACRO), MACRO(117) -#define KAGUYA_PP_REPEAT_ARG118(MACRO) KAGUYA_PP_REPEAT_ARG117(MACRO), MACRO(118) -#define KAGUYA_PP_REPEAT_ARG119(MACRO) KAGUYA_PP_REPEAT_ARG118(MACRO), MACRO(119) -#define KAGUYA_PP_REPEAT_ARG120(MACRO) KAGUYA_PP_REPEAT_ARG119(MACRO), MACRO(120) -#define KAGUYA_PP_REPEAT_ARG121(MACRO) KAGUYA_PP_REPEAT_ARG120(MACRO), MACRO(121) -#define KAGUYA_PP_REPEAT_ARG122(MACRO) KAGUYA_PP_REPEAT_ARG121(MACRO), MACRO(122) -#define KAGUYA_PP_REPEAT_ARG123(MACRO) KAGUYA_PP_REPEAT_ARG122(MACRO), MACRO(123) -#define KAGUYA_PP_REPEAT_ARG124(MACRO) KAGUYA_PP_REPEAT_ARG123(MACRO), MACRO(124) -#define KAGUYA_PP_REPEAT_ARG125(MACRO) KAGUYA_PP_REPEAT_ARG124(MACRO), MACRO(125) -#define KAGUYA_PP_REPEAT_ARG126(MACRO) KAGUYA_PP_REPEAT_ARG125(MACRO), MACRO(126) -#define KAGUYA_PP_REPEAT_ARG127(MACRO) KAGUYA_PP_REPEAT_ARG126(MACRO), MACRO(127) -#define KAGUYA_PP_REPEAT_ARG128(MACRO) KAGUYA_PP_REPEAT_ARG127(MACRO), MACRO(128) -#define KAGUYA_PP_REPEAT_ARG129(MACRO) KAGUYA_PP_REPEAT_ARG128(MACRO), MACRO(129) -#define KAGUYA_PP_REPEAT_ARG130(MACRO) KAGUYA_PP_REPEAT_ARG129(MACRO), MACRO(130) -#define KAGUYA_PP_REPEAT_ARG131(MACRO) KAGUYA_PP_REPEAT_ARG130(MACRO), MACRO(131) -#define KAGUYA_PP_REPEAT_ARG132(MACRO) KAGUYA_PP_REPEAT_ARG131(MACRO), MACRO(132) -#define KAGUYA_PP_REPEAT_ARG133(MACRO) KAGUYA_PP_REPEAT_ARG132(MACRO), MACRO(133) -#define KAGUYA_PP_REPEAT_ARG134(MACRO) KAGUYA_PP_REPEAT_ARG133(MACRO), MACRO(134) -#define KAGUYA_PP_REPEAT_ARG135(MACRO) KAGUYA_PP_REPEAT_ARG134(MACRO), MACRO(135) -#define KAGUYA_PP_REPEAT_ARG136(MACRO) KAGUYA_PP_REPEAT_ARG135(MACRO), MACRO(136) -#define KAGUYA_PP_REPEAT_ARG137(MACRO) KAGUYA_PP_REPEAT_ARG136(MACRO), MACRO(137) -#define KAGUYA_PP_REPEAT_ARG138(MACRO) KAGUYA_PP_REPEAT_ARG137(MACRO), MACRO(138) -#define KAGUYA_PP_REPEAT_ARG139(MACRO) KAGUYA_PP_REPEAT_ARG138(MACRO), MACRO(139) -#define KAGUYA_PP_REPEAT_ARG140(MACRO) KAGUYA_PP_REPEAT_ARG139(MACRO), MACRO(140) -#define KAGUYA_PP_REPEAT_ARG141(MACRO) KAGUYA_PP_REPEAT_ARG140(MACRO), MACRO(141) -#define KAGUYA_PP_REPEAT_ARG142(MACRO) KAGUYA_PP_REPEAT_ARG141(MACRO), MACRO(142) -#define KAGUYA_PP_REPEAT_ARG143(MACRO) KAGUYA_PP_REPEAT_ARG142(MACRO), MACRO(143) -#define KAGUYA_PP_REPEAT_ARG144(MACRO) KAGUYA_PP_REPEAT_ARG143(MACRO), MACRO(144) -#define KAGUYA_PP_REPEAT_ARG145(MACRO) KAGUYA_PP_REPEAT_ARG144(MACRO), MACRO(145) -#define KAGUYA_PP_REPEAT_ARG146(MACRO) KAGUYA_PP_REPEAT_ARG145(MACRO), MACRO(146) -#define KAGUYA_PP_REPEAT_ARG147(MACRO) KAGUYA_PP_REPEAT_ARG146(MACRO), MACRO(147) -#define KAGUYA_PP_REPEAT_ARG148(MACRO) KAGUYA_PP_REPEAT_ARG147(MACRO), MACRO(148) -#define KAGUYA_PP_REPEAT_ARG149(MACRO) KAGUYA_PP_REPEAT_ARG148(MACRO), MACRO(149) -#define KAGUYA_PP_REPEAT_ARG150(MACRO) KAGUYA_PP_REPEAT_ARG149(MACRO), MACRO(150) -#define KAGUYA_PP_REPEAT_ARG151(MACRO) KAGUYA_PP_REPEAT_ARG150(MACRO), MACRO(151) -#define KAGUYA_PP_REPEAT_ARG152(MACRO) KAGUYA_PP_REPEAT_ARG151(MACRO), MACRO(152) -#define KAGUYA_PP_REPEAT_ARG153(MACRO) KAGUYA_PP_REPEAT_ARG152(MACRO), MACRO(153) -#define KAGUYA_PP_REPEAT_ARG154(MACRO) KAGUYA_PP_REPEAT_ARG153(MACRO), MACRO(154) -#define KAGUYA_PP_REPEAT_ARG155(MACRO) KAGUYA_PP_REPEAT_ARG154(MACRO), MACRO(155) -#define KAGUYA_PP_REPEAT_ARG156(MACRO) KAGUYA_PP_REPEAT_ARG155(MACRO), MACRO(156) -#define KAGUYA_PP_REPEAT_ARG157(MACRO) KAGUYA_PP_REPEAT_ARG156(MACRO), MACRO(157) -#define KAGUYA_PP_REPEAT_ARG158(MACRO) KAGUYA_PP_REPEAT_ARG157(MACRO), MACRO(158) -#define KAGUYA_PP_REPEAT_ARG159(MACRO) KAGUYA_PP_REPEAT_ARG158(MACRO), MACRO(159) -#define KAGUYA_PP_REPEAT_ARG160(MACRO) KAGUYA_PP_REPEAT_ARG159(MACRO), MACRO(160) -#define KAGUYA_PP_REPEAT_ARG161(MACRO) KAGUYA_PP_REPEAT_ARG160(MACRO), MACRO(161) -#define KAGUYA_PP_REPEAT_ARG162(MACRO) KAGUYA_PP_REPEAT_ARG161(MACRO), MACRO(162) -#define KAGUYA_PP_REPEAT_ARG163(MACRO) KAGUYA_PP_REPEAT_ARG162(MACRO), MACRO(163) -#define KAGUYA_PP_REPEAT_ARG164(MACRO) KAGUYA_PP_REPEAT_ARG163(MACRO), MACRO(164) -#define KAGUYA_PP_REPEAT_ARG165(MACRO) KAGUYA_PP_REPEAT_ARG164(MACRO), MACRO(165) -#define KAGUYA_PP_REPEAT_ARG166(MACRO) KAGUYA_PP_REPEAT_ARG165(MACRO), MACRO(166) -#define KAGUYA_PP_REPEAT_ARG167(MACRO) KAGUYA_PP_REPEAT_ARG166(MACRO), MACRO(167) -#define KAGUYA_PP_REPEAT_ARG168(MACRO) KAGUYA_PP_REPEAT_ARG167(MACRO), MACRO(168) -#define KAGUYA_PP_REPEAT_ARG169(MACRO) KAGUYA_PP_REPEAT_ARG168(MACRO), MACRO(169) -#define KAGUYA_PP_REPEAT_ARG170(MACRO) KAGUYA_PP_REPEAT_ARG169(MACRO), MACRO(170) -#define KAGUYA_PP_REPEAT_ARG171(MACRO) KAGUYA_PP_REPEAT_ARG170(MACRO), MACRO(171) -#define KAGUYA_PP_REPEAT_ARG172(MACRO) KAGUYA_PP_REPEAT_ARG171(MACRO), MACRO(172) -#define KAGUYA_PP_REPEAT_ARG173(MACRO) KAGUYA_PP_REPEAT_ARG172(MACRO), MACRO(173) -#define KAGUYA_PP_REPEAT_ARG174(MACRO) KAGUYA_PP_REPEAT_ARG173(MACRO), MACRO(174) -#define KAGUYA_PP_REPEAT_ARG175(MACRO) KAGUYA_PP_REPEAT_ARG174(MACRO), MACRO(175) -#define KAGUYA_PP_REPEAT_ARG176(MACRO) KAGUYA_PP_REPEAT_ARG175(MACRO), MACRO(176) -#define KAGUYA_PP_REPEAT_ARG177(MACRO) KAGUYA_PP_REPEAT_ARG176(MACRO), MACRO(177) -#define KAGUYA_PP_REPEAT_ARG178(MACRO) KAGUYA_PP_REPEAT_ARG177(MACRO), MACRO(178) -#define KAGUYA_PP_REPEAT_ARG179(MACRO) KAGUYA_PP_REPEAT_ARG178(MACRO), MACRO(179) -#define KAGUYA_PP_REPEAT_ARG180(MACRO) KAGUYA_PP_REPEAT_ARG179(MACRO), MACRO(180) -#define KAGUYA_PP_REPEAT_ARG181(MACRO) KAGUYA_PP_REPEAT_ARG180(MACRO), MACRO(181) -#define KAGUYA_PP_REPEAT_ARG182(MACRO) KAGUYA_PP_REPEAT_ARG181(MACRO), MACRO(182) -#define KAGUYA_PP_REPEAT_ARG183(MACRO) KAGUYA_PP_REPEAT_ARG182(MACRO), MACRO(183) -#define KAGUYA_PP_REPEAT_ARG184(MACRO) KAGUYA_PP_REPEAT_ARG183(MACRO), MACRO(184) -#define KAGUYA_PP_REPEAT_ARG185(MACRO) KAGUYA_PP_REPEAT_ARG184(MACRO), MACRO(185) -#define KAGUYA_PP_REPEAT_ARG186(MACRO) KAGUYA_PP_REPEAT_ARG185(MACRO), MACRO(186) -#define KAGUYA_PP_REPEAT_ARG187(MACRO) KAGUYA_PP_REPEAT_ARG186(MACRO), MACRO(187) -#define KAGUYA_PP_REPEAT_ARG188(MACRO) KAGUYA_PP_REPEAT_ARG187(MACRO), MACRO(188) -#define KAGUYA_PP_REPEAT_ARG189(MACRO) KAGUYA_PP_REPEAT_ARG188(MACRO), MACRO(189) -#define KAGUYA_PP_REPEAT_ARG190(MACRO) KAGUYA_PP_REPEAT_ARG189(MACRO), MACRO(190) -#define KAGUYA_PP_REPEAT_ARG191(MACRO) KAGUYA_PP_REPEAT_ARG190(MACRO), MACRO(191) -#define KAGUYA_PP_REPEAT_ARG192(MACRO) KAGUYA_PP_REPEAT_ARG191(MACRO), MACRO(192) -#define KAGUYA_PP_REPEAT_ARG193(MACRO) KAGUYA_PP_REPEAT_ARG192(MACRO), MACRO(193) -#define KAGUYA_PP_REPEAT_ARG194(MACRO) KAGUYA_PP_REPEAT_ARG193(MACRO), MACRO(194) -#define KAGUYA_PP_REPEAT_ARG195(MACRO) KAGUYA_PP_REPEAT_ARG194(MACRO), MACRO(195) -#define KAGUYA_PP_REPEAT_ARG196(MACRO) KAGUYA_PP_REPEAT_ARG195(MACRO), MACRO(196) -#define KAGUYA_PP_REPEAT_ARG197(MACRO) KAGUYA_PP_REPEAT_ARG196(MACRO), MACRO(197) -#define KAGUYA_PP_REPEAT_ARG198(MACRO) KAGUYA_PP_REPEAT_ARG197(MACRO), MACRO(198) -#define KAGUYA_PP_REPEAT_ARG199(MACRO) KAGUYA_PP_REPEAT_ARG198(MACRO), MACRO(199) -#define KAGUYA_PP_REPEAT_ARG200(MACRO) KAGUYA_PP_REPEAT_ARG199(MACRO), MACRO(200) -#define KAGUYA_PP_REPEAT_ARG201(MACRO) KAGUYA_PP_REPEAT_ARG200(MACRO), MACRO(201) -#define KAGUYA_PP_REPEAT_ARG202(MACRO) KAGUYA_PP_REPEAT_ARG201(MACRO), MACRO(202) -#define KAGUYA_PP_REPEAT_ARG203(MACRO) KAGUYA_PP_REPEAT_ARG202(MACRO), MACRO(203) -#define KAGUYA_PP_REPEAT_ARG204(MACRO) KAGUYA_PP_REPEAT_ARG203(MACRO), MACRO(204) -#define KAGUYA_PP_REPEAT_ARG205(MACRO) KAGUYA_PP_REPEAT_ARG204(MACRO), MACRO(205) -#define KAGUYA_PP_REPEAT_ARG206(MACRO) KAGUYA_PP_REPEAT_ARG205(MACRO), MACRO(206) -#define KAGUYA_PP_REPEAT_ARG207(MACRO) KAGUYA_PP_REPEAT_ARG206(MACRO), MACRO(207) -#define KAGUYA_PP_REPEAT_ARG208(MACRO) KAGUYA_PP_REPEAT_ARG207(MACRO), MACRO(208) -#define KAGUYA_PP_REPEAT_ARG209(MACRO) KAGUYA_PP_REPEAT_ARG208(MACRO), MACRO(209) -#define KAGUYA_PP_REPEAT_ARG210(MACRO) KAGUYA_PP_REPEAT_ARG209(MACRO), MACRO(210) -#define KAGUYA_PP_REPEAT_ARG211(MACRO) KAGUYA_PP_REPEAT_ARG210(MACRO), MACRO(211) -#define KAGUYA_PP_REPEAT_ARG212(MACRO) KAGUYA_PP_REPEAT_ARG211(MACRO), MACRO(212) -#define KAGUYA_PP_REPEAT_ARG213(MACRO) KAGUYA_PP_REPEAT_ARG212(MACRO), MACRO(213) -#define KAGUYA_PP_REPEAT_ARG214(MACRO) KAGUYA_PP_REPEAT_ARG213(MACRO), MACRO(214) -#define KAGUYA_PP_REPEAT_ARG215(MACRO) KAGUYA_PP_REPEAT_ARG214(MACRO), MACRO(215) -#define KAGUYA_PP_REPEAT_ARG216(MACRO) KAGUYA_PP_REPEAT_ARG215(MACRO), MACRO(216) -#define KAGUYA_PP_REPEAT_ARG217(MACRO) KAGUYA_PP_REPEAT_ARG216(MACRO), MACRO(217) -#define KAGUYA_PP_REPEAT_ARG218(MACRO) KAGUYA_PP_REPEAT_ARG217(MACRO), MACRO(218) -#define KAGUYA_PP_REPEAT_ARG219(MACRO) KAGUYA_PP_REPEAT_ARG218(MACRO), MACRO(219) -#define KAGUYA_PP_REPEAT_ARG220(MACRO) KAGUYA_PP_REPEAT_ARG219(MACRO), MACRO(220) -#define KAGUYA_PP_REPEAT_ARG221(MACRO) KAGUYA_PP_REPEAT_ARG220(MACRO), MACRO(221) -#define KAGUYA_PP_REPEAT_ARG222(MACRO) KAGUYA_PP_REPEAT_ARG221(MACRO), MACRO(222) -#define KAGUYA_PP_REPEAT_ARG223(MACRO) KAGUYA_PP_REPEAT_ARG222(MACRO), MACRO(223) -#define KAGUYA_PP_REPEAT_ARG224(MACRO) KAGUYA_PP_REPEAT_ARG223(MACRO), MACRO(224) -#define KAGUYA_PP_REPEAT_ARG225(MACRO) KAGUYA_PP_REPEAT_ARG224(MACRO), MACRO(225) -#define KAGUYA_PP_REPEAT_ARG226(MACRO) KAGUYA_PP_REPEAT_ARG225(MACRO), MACRO(226) -#define KAGUYA_PP_REPEAT_ARG227(MACRO) KAGUYA_PP_REPEAT_ARG226(MACRO), MACRO(227) -#define KAGUYA_PP_REPEAT_ARG228(MACRO) KAGUYA_PP_REPEAT_ARG227(MACRO), MACRO(228) -#define KAGUYA_PP_REPEAT_ARG229(MACRO) KAGUYA_PP_REPEAT_ARG228(MACRO), MACRO(229) -#define KAGUYA_PP_REPEAT_ARG230(MACRO) KAGUYA_PP_REPEAT_ARG229(MACRO), MACRO(230) -#define KAGUYA_PP_REPEAT_ARG231(MACRO) KAGUYA_PP_REPEAT_ARG230(MACRO), MACRO(231) -#define KAGUYA_PP_REPEAT_ARG232(MACRO) KAGUYA_PP_REPEAT_ARG231(MACRO), MACRO(232) -#define KAGUYA_PP_REPEAT_ARG233(MACRO) KAGUYA_PP_REPEAT_ARG232(MACRO), MACRO(233) -#define KAGUYA_PP_REPEAT_ARG234(MACRO) KAGUYA_PP_REPEAT_ARG233(MACRO), MACRO(234) -#define KAGUYA_PP_REPEAT_ARG235(MACRO) KAGUYA_PP_REPEAT_ARG234(MACRO), MACRO(235) -#define KAGUYA_PP_REPEAT_ARG236(MACRO) KAGUYA_PP_REPEAT_ARG235(MACRO), MACRO(236) -#define KAGUYA_PP_REPEAT_ARG237(MACRO) KAGUYA_PP_REPEAT_ARG236(MACRO), MACRO(237) -#define KAGUYA_PP_REPEAT_ARG238(MACRO) KAGUYA_PP_REPEAT_ARG237(MACRO), MACRO(238) -#define KAGUYA_PP_REPEAT_ARG239(MACRO) KAGUYA_PP_REPEAT_ARG238(MACRO), MACRO(239) -#define KAGUYA_PP_REPEAT_ARG240(MACRO) KAGUYA_PP_REPEAT_ARG239(MACRO), MACRO(240) -#define KAGUYA_PP_REPEAT_ARG241(MACRO) KAGUYA_PP_REPEAT_ARG240(MACRO), MACRO(241) -#define KAGUYA_PP_REPEAT_ARG242(MACRO) KAGUYA_PP_REPEAT_ARG241(MACRO), MACRO(242) -#define KAGUYA_PP_REPEAT_ARG243(MACRO) KAGUYA_PP_REPEAT_ARG242(MACRO), MACRO(243) -#define KAGUYA_PP_REPEAT_ARG244(MACRO) KAGUYA_PP_REPEAT_ARG243(MACRO), MACRO(244) -#define KAGUYA_PP_REPEAT_ARG245(MACRO) KAGUYA_PP_REPEAT_ARG244(MACRO), MACRO(245) -#define KAGUYA_PP_REPEAT_ARG246(MACRO) KAGUYA_PP_REPEAT_ARG245(MACRO), MACRO(246) -#define KAGUYA_PP_REPEAT_ARG247(MACRO) KAGUYA_PP_REPEAT_ARG246(MACRO), MACRO(247) -#define KAGUYA_PP_REPEAT_ARG248(MACRO) KAGUYA_PP_REPEAT_ARG247(MACRO), MACRO(248) -#define KAGUYA_PP_REPEAT_ARG249(MACRO) KAGUYA_PP_REPEAT_ARG248(MACRO), MACRO(249) -#define KAGUYA_PP_REPEAT_ARG250(MACRO) KAGUYA_PP_REPEAT_ARG249(MACRO), MACRO(250) -#define KAGUYA_PP_REPEAT_ARG251(MACRO) KAGUYA_PP_REPEAT_ARG250(MACRO), MACRO(251) -#define KAGUYA_PP_REPEAT_ARG252(MACRO) KAGUYA_PP_REPEAT_ARG251(MACRO), MACRO(252) -#define KAGUYA_PP_REPEAT_ARG253(MACRO) KAGUYA_PP_REPEAT_ARG252(MACRO), MACRO(253) -#define KAGUYA_PP_REPEAT_ARG254(MACRO) KAGUYA_PP_REPEAT_ARG253(MACRO), MACRO(254) -#define KAGUYA_PP_REPEAT_ARG(COUNT,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_ARG,COUNT)(MACRO) - +#define KAGUYA_PP_REPEAT_ARG101(MACRO) \ + KAGUYA_PP_REPEAT_ARG100(MACRO), MACRO(101) +#define KAGUYA_PP_REPEAT_ARG102(MACRO) \ + KAGUYA_PP_REPEAT_ARG101(MACRO), MACRO(102) +#define KAGUYA_PP_REPEAT_ARG103(MACRO) \ + KAGUYA_PP_REPEAT_ARG102(MACRO), MACRO(103) +#define KAGUYA_PP_REPEAT_ARG104(MACRO) \ + KAGUYA_PP_REPEAT_ARG103(MACRO), MACRO(104) +#define KAGUYA_PP_REPEAT_ARG105(MACRO) \ + KAGUYA_PP_REPEAT_ARG104(MACRO), MACRO(105) +#define KAGUYA_PP_REPEAT_ARG106(MACRO) \ + KAGUYA_PP_REPEAT_ARG105(MACRO), MACRO(106) +#define KAGUYA_PP_REPEAT_ARG107(MACRO) \ + KAGUYA_PP_REPEAT_ARG106(MACRO), MACRO(107) +#define KAGUYA_PP_REPEAT_ARG108(MACRO) \ + KAGUYA_PP_REPEAT_ARG107(MACRO), MACRO(108) +#define KAGUYA_PP_REPEAT_ARG109(MACRO) \ + KAGUYA_PP_REPEAT_ARG108(MACRO), MACRO(109) +#define KAGUYA_PP_REPEAT_ARG110(MACRO) \ + KAGUYA_PP_REPEAT_ARG109(MACRO), MACRO(110) +#define KAGUYA_PP_REPEAT_ARG111(MACRO) \ + KAGUYA_PP_REPEAT_ARG110(MACRO), MACRO(111) +#define KAGUYA_PP_REPEAT_ARG112(MACRO) \ + KAGUYA_PP_REPEAT_ARG111(MACRO), MACRO(112) +#define KAGUYA_PP_REPEAT_ARG113(MACRO) \ + KAGUYA_PP_REPEAT_ARG112(MACRO), MACRO(113) +#define KAGUYA_PP_REPEAT_ARG114(MACRO) \ + KAGUYA_PP_REPEAT_ARG113(MACRO), MACRO(114) +#define KAGUYA_PP_REPEAT_ARG115(MACRO) \ + KAGUYA_PP_REPEAT_ARG114(MACRO), MACRO(115) +#define KAGUYA_PP_REPEAT_ARG116(MACRO) \ + KAGUYA_PP_REPEAT_ARG115(MACRO), MACRO(116) +#define KAGUYA_PP_REPEAT_ARG117(MACRO) \ + KAGUYA_PP_REPEAT_ARG116(MACRO), MACRO(117) +#define KAGUYA_PP_REPEAT_ARG118(MACRO) \ + KAGUYA_PP_REPEAT_ARG117(MACRO), MACRO(118) +#define KAGUYA_PP_REPEAT_ARG119(MACRO) \ + KAGUYA_PP_REPEAT_ARG118(MACRO), MACRO(119) +#define KAGUYA_PP_REPEAT_ARG120(MACRO) \ + KAGUYA_PP_REPEAT_ARG119(MACRO), MACRO(120) +#define KAGUYA_PP_REPEAT_ARG121(MACRO) \ + KAGUYA_PP_REPEAT_ARG120(MACRO), MACRO(121) +#define KAGUYA_PP_REPEAT_ARG122(MACRO) \ + KAGUYA_PP_REPEAT_ARG121(MACRO), MACRO(122) +#define KAGUYA_PP_REPEAT_ARG123(MACRO) \ + KAGUYA_PP_REPEAT_ARG122(MACRO), MACRO(123) +#define KAGUYA_PP_REPEAT_ARG124(MACRO) \ + KAGUYA_PP_REPEAT_ARG123(MACRO), MACRO(124) +#define KAGUYA_PP_REPEAT_ARG125(MACRO) \ + KAGUYA_PP_REPEAT_ARG124(MACRO), MACRO(125) +#define KAGUYA_PP_REPEAT_ARG126(MACRO) \ + KAGUYA_PP_REPEAT_ARG125(MACRO), MACRO(126) +#define KAGUYA_PP_REPEAT_ARG127(MACRO) \ + KAGUYA_PP_REPEAT_ARG126(MACRO), MACRO(127) +#define KAGUYA_PP_REPEAT_ARG128(MACRO) \ + KAGUYA_PP_REPEAT_ARG127(MACRO), MACRO(128) +#define KAGUYA_PP_REPEAT_ARG129(MACRO) \ + KAGUYA_PP_REPEAT_ARG128(MACRO), MACRO(129) +#define KAGUYA_PP_REPEAT_ARG130(MACRO) \ + KAGUYA_PP_REPEAT_ARG129(MACRO), MACRO(130) +#define KAGUYA_PP_REPEAT_ARG131(MACRO) \ + KAGUYA_PP_REPEAT_ARG130(MACRO), MACRO(131) +#define KAGUYA_PP_REPEAT_ARG132(MACRO) \ + KAGUYA_PP_REPEAT_ARG131(MACRO), MACRO(132) +#define KAGUYA_PP_REPEAT_ARG133(MACRO) \ + KAGUYA_PP_REPEAT_ARG132(MACRO), MACRO(133) +#define KAGUYA_PP_REPEAT_ARG134(MACRO) \ + KAGUYA_PP_REPEAT_ARG133(MACRO), MACRO(134) +#define KAGUYA_PP_REPEAT_ARG135(MACRO) \ + KAGUYA_PP_REPEAT_ARG134(MACRO), MACRO(135) +#define KAGUYA_PP_REPEAT_ARG136(MACRO) \ + KAGUYA_PP_REPEAT_ARG135(MACRO), MACRO(136) +#define KAGUYA_PP_REPEAT_ARG137(MACRO) \ + KAGUYA_PP_REPEAT_ARG136(MACRO), MACRO(137) +#define KAGUYA_PP_REPEAT_ARG138(MACRO) \ + KAGUYA_PP_REPEAT_ARG137(MACRO), MACRO(138) +#define KAGUYA_PP_REPEAT_ARG139(MACRO) \ + KAGUYA_PP_REPEAT_ARG138(MACRO), MACRO(139) +#define KAGUYA_PP_REPEAT_ARG140(MACRO) \ + KAGUYA_PP_REPEAT_ARG139(MACRO), MACRO(140) +#define KAGUYA_PP_REPEAT_ARG141(MACRO) \ + KAGUYA_PP_REPEAT_ARG140(MACRO), MACRO(141) +#define KAGUYA_PP_REPEAT_ARG142(MACRO) \ + KAGUYA_PP_REPEAT_ARG141(MACRO), MACRO(142) +#define KAGUYA_PP_REPEAT_ARG143(MACRO) \ + KAGUYA_PP_REPEAT_ARG142(MACRO), MACRO(143) +#define KAGUYA_PP_REPEAT_ARG144(MACRO) \ + KAGUYA_PP_REPEAT_ARG143(MACRO), MACRO(144) +#define KAGUYA_PP_REPEAT_ARG145(MACRO) \ + KAGUYA_PP_REPEAT_ARG144(MACRO), MACRO(145) +#define KAGUYA_PP_REPEAT_ARG146(MACRO) \ + KAGUYA_PP_REPEAT_ARG145(MACRO), MACRO(146) +#define KAGUYA_PP_REPEAT_ARG147(MACRO) \ + KAGUYA_PP_REPEAT_ARG146(MACRO), MACRO(147) +#define KAGUYA_PP_REPEAT_ARG148(MACRO) \ + KAGUYA_PP_REPEAT_ARG147(MACRO), MACRO(148) +#define KAGUYA_PP_REPEAT_ARG149(MACRO) \ + KAGUYA_PP_REPEAT_ARG148(MACRO), MACRO(149) +#define KAGUYA_PP_REPEAT_ARG150(MACRO) \ + KAGUYA_PP_REPEAT_ARG149(MACRO), MACRO(150) +#define KAGUYA_PP_REPEAT_ARG151(MACRO) \ + KAGUYA_PP_REPEAT_ARG150(MACRO), MACRO(151) +#define KAGUYA_PP_REPEAT_ARG152(MACRO) \ + KAGUYA_PP_REPEAT_ARG151(MACRO), MACRO(152) +#define KAGUYA_PP_REPEAT_ARG153(MACRO) \ + KAGUYA_PP_REPEAT_ARG152(MACRO), MACRO(153) +#define KAGUYA_PP_REPEAT_ARG154(MACRO) \ + KAGUYA_PP_REPEAT_ARG153(MACRO), MACRO(154) +#define KAGUYA_PP_REPEAT_ARG155(MACRO) \ + KAGUYA_PP_REPEAT_ARG154(MACRO), MACRO(155) +#define KAGUYA_PP_REPEAT_ARG156(MACRO) \ + KAGUYA_PP_REPEAT_ARG155(MACRO), MACRO(156) +#define KAGUYA_PP_REPEAT_ARG157(MACRO) \ + KAGUYA_PP_REPEAT_ARG156(MACRO), MACRO(157) +#define KAGUYA_PP_REPEAT_ARG158(MACRO) \ + KAGUYA_PP_REPEAT_ARG157(MACRO), MACRO(158) +#define KAGUYA_PP_REPEAT_ARG159(MACRO) \ + KAGUYA_PP_REPEAT_ARG158(MACRO), MACRO(159) +#define KAGUYA_PP_REPEAT_ARG160(MACRO) \ + KAGUYA_PP_REPEAT_ARG159(MACRO), MACRO(160) +#define KAGUYA_PP_REPEAT_ARG161(MACRO) \ + KAGUYA_PP_REPEAT_ARG160(MACRO), MACRO(161) +#define KAGUYA_PP_REPEAT_ARG162(MACRO) \ + KAGUYA_PP_REPEAT_ARG161(MACRO), MACRO(162) +#define KAGUYA_PP_REPEAT_ARG163(MACRO) \ + KAGUYA_PP_REPEAT_ARG162(MACRO), MACRO(163) +#define KAGUYA_PP_REPEAT_ARG164(MACRO) \ + KAGUYA_PP_REPEAT_ARG163(MACRO), MACRO(164) +#define KAGUYA_PP_REPEAT_ARG165(MACRO) \ + KAGUYA_PP_REPEAT_ARG164(MACRO), MACRO(165) +#define KAGUYA_PP_REPEAT_ARG166(MACRO) \ + KAGUYA_PP_REPEAT_ARG165(MACRO), MACRO(166) +#define KAGUYA_PP_REPEAT_ARG167(MACRO) \ + KAGUYA_PP_REPEAT_ARG166(MACRO), MACRO(167) +#define KAGUYA_PP_REPEAT_ARG168(MACRO) \ + KAGUYA_PP_REPEAT_ARG167(MACRO), MACRO(168) +#define KAGUYA_PP_REPEAT_ARG169(MACRO) \ + KAGUYA_PP_REPEAT_ARG168(MACRO), MACRO(169) +#define KAGUYA_PP_REPEAT_ARG170(MACRO) \ + KAGUYA_PP_REPEAT_ARG169(MACRO), MACRO(170) +#define KAGUYA_PP_REPEAT_ARG171(MACRO) \ + KAGUYA_PP_REPEAT_ARG170(MACRO), MACRO(171) +#define KAGUYA_PP_REPEAT_ARG172(MACRO) \ + KAGUYA_PP_REPEAT_ARG171(MACRO), MACRO(172) +#define KAGUYA_PP_REPEAT_ARG173(MACRO) \ + KAGUYA_PP_REPEAT_ARG172(MACRO), MACRO(173) +#define KAGUYA_PP_REPEAT_ARG174(MACRO) \ + KAGUYA_PP_REPEAT_ARG173(MACRO), MACRO(174) +#define KAGUYA_PP_REPEAT_ARG175(MACRO) \ + KAGUYA_PP_REPEAT_ARG174(MACRO), MACRO(175) +#define KAGUYA_PP_REPEAT_ARG176(MACRO) \ + KAGUYA_PP_REPEAT_ARG175(MACRO), MACRO(176) +#define KAGUYA_PP_REPEAT_ARG177(MACRO) \ + KAGUYA_PP_REPEAT_ARG176(MACRO), MACRO(177) +#define KAGUYA_PP_REPEAT_ARG178(MACRO) \ + KAGUYA_PP_REPEAT_ARG177(MACRO), MACRO(178) +#define KAGUYA_PP_REPEAT_ARG179(MACRO) \ + KAGUYA_PP_REPEAT_ARG178(MACRO), MACRO(179) +#define KAGUYA_PP_REPEAT_ARG180(MACRO) \ + KAGUYA_PP_REPEAT_ARG179(MACRO), MACRO(180) +#define KAGUYA_PP_REPEAT_ARG181(MACRO) \ + KAGUYA_PP_REPEAT_ARG180(MACRO), MACRO(181) +#define KAGUYA_PP_REPEAT_ARG182(MACRO) \ + KAGUYA_PP_REPEAT_ARG181(MACRO), MACRO(182) +#define KAGUYA_PP_REPEAT_ARG183(MACRO) \ + KAGUYA_PP_REPEAT_ARG182(MACRO), MACRO(183) +#define KAGUYA_PP_REPEAT_ARG184(MACRO) \ + KAGUYA_PP_REPEAT_ARG183(MACRO), MACRO(184) +#define KAGUYA_PP_REPEAT_ARG185(MACRO) \ + KAGUYA_PP_REPEAT_ARG184(MACRO), MACRO(185) +#define KAGUYA_PP_REPEAT_ARG186(MACRO) \ + KAGUYA_PP_REPEAT_ARG185(MACRO), MACRO(186) +#define KAGUYA_PP_REPEAT_ARG187(MACRO) \ + KAGUYA_PP_REPEAT_ARG186(MACRO), MACRO(187) +#define KAGUYA_PP_REPEAT_ARG188(MACRO) \ + KAGUYA_PP_REPEAT_ARG187(MACRO), MACRO(188) +#define KAGUYA_PP_REPEAT_ARG189(MACRO) \ + KAGUYA_PP_REPEAT_ARG188(MACRO), MACRO(189) +#define KAGUYA_PP_REPEAT_ARG190(MACRO) \ + KAGUYA_PP_REPEAT_ARG189(MACRO), MACRO(190) +#define KAGUYA_PP_REPEAT_ARG191(MACRO) \ + KAGUYA_PP_REPEAT_ARG190(MACRO), MACRO(191) +#define KAGUYA_PP_REPEAT_ARG192(MACRO) \ + KAGUYA_PP_REPEAT_ARG191(MACRO), MACRO(192) +#define KAGUYA_PP_REPEAT_ARG193(MACRO) \ + KAGUYA_PP_REPEAT_ARG192(MACRO), MACRO(193) +#define KAGUYA_PP_REPEAT_ARG194(MACRO) \ + KAGUYA_PP_REPEAT_ARG193(MACRO), MACRO(194) +#define KAGUYA_PP_REPEAT_ARG195(MACRO) \ + KAGUYA_PP_REPEAT_ARG194(MACRO), MACRO(195) +#define KAGUYA_PP_REPEAT_ARG196(MACRO) \ + KAGUYA_PP_REPEAT_ARG195(MACRO), MACRO(196) +#define KAGUYA_PP_REPEAT_ARG197(MACRO) \ + KAGUYA_PP_REPEAT_ARG196(MACRO), MACRO(197) +#define KAGUYA_PP_REPEAT_ARG198(MACRO) \ + KAGUYA_PP_REPEAT_ARG197(MACRO), MACRO(198) +#define KAGUYA_PP_REPEAT_ARG199(MACRO) \ + KAGUYA_PP_REPEAT_ARG198(MACRO), MACRO(199) +#define KAGUYA_PP_REPEAT_ARG200(MACRO) \ + KAGUYA_PP_REPEAT_ARG199(MACRO), MACRO(200) +#define KAGUYA_PP_REPEAT_ARG201(MACRO) \ + KAGUYA_PP_REPEAT_ARG200(MACRO), MACRO(201) +#define KAGUYA_PP_REPEAT_ARG202(MACRO) \ + KAGUYA_PP_REPEAT_ARG201(MACRO), MACRO(202) +#define KAGUYA_PP_REPEAT_ARG203(MACRO) \ + KAGUYA_PP_REPEAT_ARG202(MACRO), MACRO(203) +#define KAGUYA_PP_REPEAT_ARG204(MACRO) \ + KAGUYA_PP_REPEAT_ARG203(MACRO), MACRO(204) +#define KAGUYA_PP_REPEAT_ARG205(MACRO) \ + KAGUYA_PP_REPEAT_ARG204(MACRO), MACRO(205) +#define KAGUYA_PP_REPEAT_ARG206(MACRO) \ + KAGUYA_PP_REPEAT_ARG205(MACRO), MACRO(206) +#define KAGUYA_PP_REPEAT_ARG207(MACRO) \ + KAGUYA_PP_REPEAT_ARG206(MACRO), MACRO(207) +#define KAGUYA_PP_REPEAT_ARG208(MACRO) \ + KAGUYA_PP_REPEAT_ARG207(MACRO), MACRO(208) +#define KAGUYA_PP_REPEAT_ARG209(MACRO) \ + KAGUYA_PP_REPEAT_ARG208(MACRO), MACRO(209) +#define KAGUYA_PP_REPEAT_ARG210(MACRO) \ + KAGUYA_PP_REPEAT_ARG209(MACRO), MACRO(210) +#define KAGUYA_PP_REPEAT_ARG211(MACRO) \ + KAGUYA_PP_REPEAT_ARG210(MACRO), MACRO(211) +#define KAGUYA_PP_REPEAT_ARG212(MACRO) \ + KAGUYA_PP_REPEAT_ARG211(MACRO), MACRO(212) +#define KAGUYA_PP_REPEAT_ARG213(MACRO) \ + KAGUYA_PP_REPEAT_ARG212(MACRO), MACRO(213) +#define KAGUYA_PP_REPEAT_ARG214(MACRO) \ + KAGUYA_PP_REPEAT_ARG213(MACRO), MACRO(214) +#define KAGUYA_PP_REPEAT_ARG215(MACRO) \ + KAGUYA_PP_REPEAT_ARG214(MACRO), MACRO(215) +#define KAGUYA_PP_REPEAT_ARG216(MACRO) \ + KAGUYA_PP_REPEAT_ARG215(MACRO), MACRO(216) +#define KAGUYA_PP_REPEAT_ARG217(MACRO) \ + KAGUYA_PP_REPEAT_ARG216(MACRO), MACRO(217) +#define KAGUYA_PP_REPEAT_ARG218(MACRO) \ + KAGUYA_PP_REPEAT_ARG217(MACRO), MACRO(218) +#define KAGUYA_PP_REPEAT_ARG219(MACRO) \ + KAGUYA_PP_REPEAT_ARG218(MACRO), MACRO(219) +#define KAGUYA_PP_REPEAT_ARG220(MACRO) \ + KAGUYA_PP_REPEAT_ARG219(MACRO), MACRO(220) +#define KAGUYA_PP_REPEAT_ARG221(MACRO) \ + KAGUYA_PP_REPEAT_ARG220(MACRO), MACRO(221) +#define KAGUYA_PP_REPEAT_ARG222(MACRO) \ + KAGUYA_PP_REPEAT_ARG221(MACRO), MACRO(222) +#define KAGUYA_PP_REPEAT_ARG223(MACRO) \ + KAGUYA_PP_REPEAT_ARG222(MACRO), MACRO(223) +#define KAGUYA_PP_REPEAT_ARG224(MACRO) \ + KAGUYA_PP_REPEAT_ARG223(MACRO), MACRO(224) +#define KAGUYA_PP_REPEAT_ARG225(MACRO) \ + KAGUYA_PP_REPEAT_ARG224(MACRO), MACRO(225) +#define KAGUYA_PP_REPEAT_ARG226(MACRO) \ + KAGUYA_PP_REPEAT_ARG225(MACRO), MACRO(226) +#define KAGUYA_PP_REPEAT_ARG227(MACRO) \ + KAGUYA_PP_REPEAT_ARG226(MACRO), MACRO(227) +#define KAGUYA_PP_REPEAT_ARG228(MACRO) \ + KAGUYA_PP_REPEAT_ARG227(MACRO), MACRO(228) +#define KAGUYA_PP_REPEAT_ARG229(MACRO) \ + KAGUYA_PP_REPEAT_ARG228(MACRO), MACRO(229) +#define KAGUYA_PP_REPEAT_ARG230(MACRO) \ + KAGUYA_PP_REPEAT_ARG229(MACRO), MACRO(230) +#define KAGUYA_PP_REPEAT_ARG231(MACRO) \ + KAGUYA_PP_REPEAT_ARG230(MACRO), MACRO(231) +#define KAGUYA_PP_REPEAT_ARG232(MACRO) \ + KAGUYA_PP_REPEAT_ARG231(MACRO), MACRO(232) +#define KAGUYA_PP_REPEAT_ARG233(MACRO) \ + KAGUYA_PP_REPEAT_ARG232(MACRO), MACRO(233) +#define KAGUYA_PP_REPEAT_ARG234(MACRO) \ + KAGUYA_PP_REPEAT_ARG233(MACRO), MACRO(234) +#define KAGUYA_PP_REPEAT_ARG235(MACRO) \ + KAGUYA_PP_REPEAT_ARG234(MACRO), MACRO(235) +#define KAGUYA_PP_REPEAT_ARG236(MACRO) \ + KAGUYA_PP_REPEAT_ARG235(MACRO), MACRO(236) +#define KAGUYA_PP_REPEAT_ARG237(MACRO) \ + KAGUYA_PP_REPEAT_ARG236(MACRO), MACRO(237) +#define KAGUYA_PP_REPEAT_ARG238(MACRO) \ + KAGUYA_PP_REPEAT_ARG237(MACRO), MACRO(238) +#define KAGUYA_PP_REPEAT_ARG239(MACRO) \ + KAGUYA_PP_REPEAT_ARG238(MACRO), MACRO(239) +#define KAGUYA_PP_REPEAT_ARG240(MACRO) \ + KAGUYA_PP_REPEAT_ARG239(MACRO), MACRO(240) +#define KAGUYA_PP_REPEAT_ARG241(MACRO) \ + KAGUYA_PP_REPEAT_ARG240(MACRO), MACRO(241) +#define KAGUYA_PP_REPEAT_ARG242(MACRO) \ + KAGUYA_PP_REPEAT_ARG241(MACRO), MACRO(242) +#define KAGUYA_PP_REPEAT_ARG243(MACRO) \ + KAGUYA_PP_REPEAT_ARG242(MACRO), MACRO(243) +#define KAGUYA_PP_REPEAT_ARG244(MACRO) \ + KAGUYA_PP_REPEAT_ARG243(MACRO), MACRO(244) +#define KAGUYA_PP_REPEAT_ARG245(MACRO) \ + KAGUYA_PP_REPEAT_ARG244(MACRO), MACRO(245) +#define KAGUYA_PP_REPEAT_ARG246(MACRO) \ + KAGUYA_PP_REPEAT_ARG245(MACRO), MACRO(246) +#define KAGUYA_PP_REPEAT_ARG247(MACRO) \ + KAGUYA_PP_REPEAT_ARG246(MACRO), MACRO(247) +#define KAGUYA_PP_REPEAT_ARG248(MACRO) \ + KAGUYA_PP_REPEAT_ARG247(MACRO), MACRO(248) +#define KAGUYA_PP_REPEAT_ARG249(MACRO) \ + KAGUYA_PP_REPEAT_ARG248(MACRO), MACRO(249) +#define KAGUYA_PP_REPEAT_ARG250(MACRO) \ + KAGUYA_PP_REPEAT_ARG249(MACRO), MACRO(250) +#define KAGUYA_PP_REPEAT_ARG251(MACRO) \ + KAGUYA_PP_REPEAT_ARG250(MACRO), MACRO(251) +#define KAGUYA_PP_REPEAT_ARG252(MACRO) \ + KAGUYA_PP_REPEAT_ARG251(MACRO), MACRO(252) +#define KAGUYA_PP_REPEAT_ARG253(MACRO) \ + KAGUYA_PP_REPEAT_ARG252(MACRO), MACRO(253) +#define KAGUYA_PP_REPEAT_ARG254(MACRO) \ + KAGUYA_PP_REPEAT_ARG253(MACRO), MACRO(254) +#define KAGUYA_PP_REPEAT_ARG(COUNT, MACRO) \ + KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_ARG, COUNT)(MACRO) #define KAGUYA_PP_REPEAT_DEF_VA_ARG0(MACRO, ...) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG1(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG0(MACRO,__VA_ARGS__) MACRO(1,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG2(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG1(MACRO,__VA_ARGS__) MACRO(2,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG3(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG2(MACRO,__VA_ARGS__) MACRO(3,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG4(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG3(MACRO,__VA_ARGS__) MACRO(4,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG5(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG4(MACRO,__VA_ARGS__) MACRO(5,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG6(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG5(MACRO,__VA_ARGS__) MACRO(6,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG7(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG6(MACRO,__VA_ARGS__) MACRO(7,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG8(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG7(MACRO,__VA_ARGS__) MACRO(8,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG9(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG8(MACRO,__VA_ARGS__) MACRO(9,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG10(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG9(MACRO,__VA_ARGS__) MACRO(10,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG11(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG10(MACRO,__VA_ARGS__) MACRO(11,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG12(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG11(MACRO,__VA_ARGS__) MACRO(12,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG13(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG12(MACRO,__VA_ARGS__) MACRO(13,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG14(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG13(MACRO,__VA_ARGS__) MACRO(14,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG15(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG14(MACRO,__VA_ARGS__) MACRO(15,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG16(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG15(MACRO,__VA_ARGS__) MACRO(16,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG17(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG16(MACRO,__VA_ARGS__) MACRO(17,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG18(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG17(MACRO,__VA_ARGS__) MACRO(18,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG19(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG18(MACRO,__VA_ARGS__) MACRO(19,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG20(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG19(MACRO,__VA_ARGS__) MACRO(20,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG21(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG20(MACRO,__VA_ARGS__) MACRO(21,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG22(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG21(MACRO,__VA_ARGS__) MACRO(22,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG23(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG22(MACRO,__VA_ARGS__) MACRO(23,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG24(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG23(MACRO,__VA_ARGS__) MACRO(24,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG25(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG24(MACRO,__VA_ARGS__) MACRO(25,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG26(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG25(MACRO,__VA_ARGS__) MACRO(26,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG27(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG26(MACRO,__VA_ARGS__) MACRO(27,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG28(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG27(MACRO,__VA_ARGS__) MACRO(28,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG29(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG28(MACRO,__VA_ARGS__) MACRO(29,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG30(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG29(MACRO,__VA_ARGS__) MACRO(30,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG31(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG30(MACRO,__VA_ARGS__) MACRO(31,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG32(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG31(MACRO,__VA_ARGS__) MACRO(32,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG33(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG32(MACRO,__VA_ARGS__) MACRO(33,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG34(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG33(MACRO,__VA_ARGS__) MACRO(34,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG35(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG34(MACRO,__VA_ARGS__) MACRO(35,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG36(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG35(MACRO,__VA_ARGS__) MACRO(36,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG37(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG36(MACRO,__VA_ARGS__) MACRO(37,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG38(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG37(MACRO,__VA_ARGS__) MACRO(38,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG39(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG38(MACRO,__VA_ARGS__) MACRO(39,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG40(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG39(MACRO,__VA_ARGS__) MACRO(40,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG41(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG40(MACRO,__VA_ARGS__) MACRO(41,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG42(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG41(MACRO,__VA_ARGS__) MACRO(42,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG43(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG42(MACRO,__VA_ARGS__) MACRO(43,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG44(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG43(MACRO,__VA_ARGS__) MACRO(44,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG45(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG44(MACRO,__VA_ARGS__) MACRO(45,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG46(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG45(MACRO,__VA_ARGS__) MACRO(46,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG47(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG46(MACRO,__VA_ARGS__) MACRO(47,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG48(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG47(MACRO,__VA_ARGS__) MACRO(48,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG49(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG48(MACRO,__VA_ARGS__) MACRO(49,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG50(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG49(MACRO,__VA_ARGS__) MACRO(50,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG51(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG50(MACRO,__VA_ARGS__) MACRO(51,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG52(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG51(MACRO,__VA_ARGS__) MACRO(52,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG53(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG52(MACRO,__VA_ARGS__) MACRO(53,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG54(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG53(MACRO,__VA_ARGS__) MACRO(54,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG55(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG54(MACRO,__VA_ARGS__) MACRO(55,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG56(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG55(MACRO,__VA_ARGS__) MACRO(56,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG57(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG56(MACRO,__VA_ARGS__) MACRO(57,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG58(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG57(MACRO,__VA_ARGS__) MACRO(58,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG59(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG58(MACRO,__VA_ARGS__) MACRO(59,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG60(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG59(MACRO,__VA_ARGS__) MACRO(60,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG61(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG60(MACRO,__VA_ARGS__) MACRO(61,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG62(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG61(MACRO,__VA_ARGS__) MACRO(62,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG63(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG62(MACRO,__VA_ARGS__) MACRO(63,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG64(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG63(MACRO,__VA_ARGS__) MACRO(64,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG65(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG64(MACRO,__VA_ARGS__) MACRO(65,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG66(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG65(MACRO,__VA_ARGS__) MACRO(66,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG67(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG66(MACRO,__VA_ARGS__) MACRO(67,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG68(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG67(MACRO,__VA_ARGS__) MACRO(68,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG69(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG68(MACRO,__VA_ARGS__) MACRO(69,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG70(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG69(MACRO,__VA_ARGS__) MACRO(70,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG71(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG70(MACRO,__VA_ARGS__) MACRO(71,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG72(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG71(MACRO,__VA_ARGS__) MACRO(72,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG73(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG72(MACRO,__VA_ARGS__) MACRO(73,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG74(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG73(MACRO,__VA_ARGS__) MACRO(74,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG75(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG74(MACRO,__VA_ARGS__) MACRO(75,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG76(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG75(MACRO,__VA_ARGS__) MACRO(76,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG77(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG76(MACRO,__VA_ARGS__) MACRO(77,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG78(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG77(MACRO,__VA_ARGS__) MACRO(78,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG79(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG78(MACRO,__VA_ARGS__) MACRO(79,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG80(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG79(MACRO,__VA_ARGS__) MACRO(80,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG81(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG80(MACRO,__VA_ARGS__) MACRO(81,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG82(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG81(MACRO,__VA_ARGS__) MACRO(82,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG83(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG82(MACRO,__VA_ARGS__) MACRO(83,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG84(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG83(MACRO,__VA_ARGS__) MACRO(84,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG85(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG84(MACRO,__VA_ARGS__) MACRO(85,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG86(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG85(MACRO,__VA_ARGS__) MACRO(86,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG87(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG86(MACRO,__VA_ARGS__) MACRO(87,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG88(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG87(MACRO,__VA_ARGS__) MACRO(88,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG89(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG88(MACRO,__VA_ARGS__) MACRO(89,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG90(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG89(MACRO,__VA_ARGS__) MACRO(90,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG91(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG90(MACRO,__VA_ARGS__) MACRO(91,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG92(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG91(MACRO,__VA_ARGS__) MACRO(92,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG93(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG92(MACRO,__VA_ARGS__) MACRO(93,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG94(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG93(MACRO,__VA_ARGS__) MACRO(94,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG95(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG94(MACRO,__VA_ARGS__) MACRO(95,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG96(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG95(MACRO,__VA_ARGS__) MACRO(96,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG97(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG96(MACRO,__VA_ARGS__) MACRO(97,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG98(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG97(MACRO,__VA_ARGS__) MACRO(98,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG99(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG98(MACRO,__VA_ARGS__) MACRO(99,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG100(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG99(MACRO,__VA_ARGS__) MACRO(100,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG101(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG100(MACRO,__VA_ARGS__) MACRO(101,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG102(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG101(MACRO,__VA_ARGS__) MACRO(102,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG103(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG102(MACRO,__VA_ARGS__) MACRO(103,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG104(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG103(MACRO,__VA_ARGS__) MACRO(104,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG105(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG104(MACRO,__VA_ARGS__) MACRO(105,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG106(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG105(MACRO,__VA_ARGS__) MACRO(106,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG107(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG106(MACRO,__VA_ARGS__) MACRO(107,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG108(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG107(MACRO,__VA_ARGS__) MACRO(108,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG109(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG108(MACRO,__VA_ARGS__) MACRO(109,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG110(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG109(MACRO,__VA_ARGS__) MACRO(110,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG111(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG110(MACRO,__VA_ARGS__) MACRO(111,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG112(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG111(MACRO,__VA_ARGS__) MACRO(112,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG113(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG112(MACRO,__VA_ARGS__) MACRO(113,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG114(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG113(MACRO,__VA_ARGS__) MACRO(114,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG115(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG114(MACRO,__VA_ARGS__) MACRO(115,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG116(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG115(MACRO,__VA_ARGS__) MACRO(116,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG117(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG116(MACRO,__VA_ARGS__) MACRO(117,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG118(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG117(MACRO,__VA_ARGS__) MACRO(118,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG119(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG118(MACRO,__VA_ARGS__) MACRO(119,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG120(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG119(MACRO,__VA_ARGS__) MACRO(120,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG121(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG120(MACRO,__VA_ARGS__) MACRO(121,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG122(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG121(MACRO,__VA_ARGS__) MACRO(122,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG123(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG122(MACRO,__VA_ARGS__) MACRO(123,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG124(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG123(MACRO,__VA_ARGS__) MACRO(124,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG125(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG124(MACRO,__VA_ARGS__) MACRO(125,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG126(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG125(MACRO,__VA_ARGS__) MACRO(126,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG127(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG126(MACRO,__VA_ARGS__) MACRO(127,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG128(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG127(MACRO,__VA_ARGS__) MACRO(128,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG129(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG128(MACRO,__VA_ARGS__) MACRO(129,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG130(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG129(MACRO,__VA_ARGS__) MACRO(130,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG131(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG130(MACRO,__VA_ARGS__) MACRO(131,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG132(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG131(MACRO,__VA_ARGS__) MACRO(132,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG133(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG132(MACRO,__VA_ARGS__) MACRO(133,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG134(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG133(MACRO,__VA_ARGS__) MACRO(134,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG135(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG134(MACRO,__VA_ARGS__) MACRO(135,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG136(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG135(MACRO,__VA_ARGS__) MACRO(136,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG137(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG136(MACRO,__VA_ARGS__) MACRO(137,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG138(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG137(MACRO,__VA_ARGS__) MACRO(138,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG139(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG138(MACRO,__VA_ARGS__) MACRO(139,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG140(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG139(MACRO,__VA_ARGS__) MACRO(140,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG141(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG140(MACRO,__VA_ARGS__) MACRO(141,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG142(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG141(MACRO,__VA_ARGS__) MACRO(142,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG143(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG142(MACRO,__VA_ARGS__) MACRO(143,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG144(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG143(MACRO,__VA_ARGS__) MACRO(144,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG145(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG144(MACRO,__VA_ARGS__) MACRO(145,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG146(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG145(MACRO,__VA_ARGS__) MACRO(146,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG147(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG146(MACRO,__VA_ARGS__) MACRO(147,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG148(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG147(MACRO,__VA_ARGS__) MACRO(148,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG149(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG148(MACRO,__VA_ARGS__) MACRO(149,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG150(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG149(MACRO,__VA_ARGS__) MACRO(150,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG151(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG150(MACRO,__VA_ARGS__) MACRO(151,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG152(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG151(MACRO,__VA_ARGS__) MACRO(152,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG153(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG152(MACRO,__VA_ARGS__) MACRO(153,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG154(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG153(MACRO,__VA_ARGS__) MACRO(154,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG155(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG154(MACRO,__VA_ARGS__) MACRO(155,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG156(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG155(MACRO,__VA_ARGS__) MACRO(156,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG157(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG156(MACRO,__VA_ARGS__) MACRO(157,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG158(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG157(MACRO,__VA_ARGS__) MACRO(158,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG159(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG158(MACRO,__VA_ARGS__) MACRO(159,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG160(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG159(MACRO,__VA_ARGS__) MACRO(160,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG161(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG160(MACRO,__VA_ARGS__) MACRO(161,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG162(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG161(MACRO,__VA_ARGS__) MACRO(162,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG163(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG162(MACRO,__VA_ARGS__) MACRO(163,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG164(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG163(MACRO,__VA_ARGS__) MACRO(164,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG165(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG164(MACRO,__VA_ARGS__) MACRO(165,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG166(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG165(MACRO,__VA_ARGS__) MACRO(166,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG167(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG166(MACRO,__VA_ARGS__) MACRO(167,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG168(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG167(MACRO,__VA_ARGS__) MACRO(168,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG169(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG168(MACRO,__VA_ARGS__) MACRO(169,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG170(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG169(MACRO,__VA_ARGS__) MACRO(170,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG171(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG170(MACRO,__VA_ARGS__) MACRO(171,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG172(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG171(MACRO,__VA_ARGS__) MACRO(172,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG173(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG172(MACRO,__VA_ARGS__) MACRO(173,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG174(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG173(MACRO,__VA_ARGS__) MACRO(174,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG175(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG174(MACRO,__VA_ARGS__) MACRO(175,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG176(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG175(MACRO,__VA_ARGS__) MACRO(176,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG177(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG176(MACRO,__VA_ARGS__) MACRO(177,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG178(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG177(MACRO,__VA_ARGS__) MACRO(178,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG179(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG178(MACRO,__VA_ARGS__) MACRO(179,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG180(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG179(MACRO,__VA_ARGS__) MACRO(180,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG181(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG180(MACRO,__VA_ARGS__) MACRO(181,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG182(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG181(MACRO,__VA_ARGS__) MACRO(182,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG183(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG182(MACRO,__VA_ARGS__) MACRO(183,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG184(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG183(MACRO,__VA_ARGS__) MACRO(184,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG185(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG184(MACRO,__VA_ARGS__) MACRO(185,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG186(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG185(MACRO,__VA_ARGS__) MACRO(186,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG187(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG186(MACRO,__VA_ARGS__) MACRO(187,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG188(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG187(MACRO,__VA_ARGS__) MACRO(188,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG189(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG188(MACRO,__VA_ARGS__) MACRO(189,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG190(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG189(MACRO,__VA_ARGS__) MACRO(190,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG191(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG190(MACRO,__VA_ARGS__) MACRO(191,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG192(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG191(MACRO,__VA_ARGS__) MACRO(192,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG193(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG192(MACRO,__VA_ARGS__) MACRO(193,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG194(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG193(MACRO,__VA_ARGS__) MACRO(194,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG195(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG194(MACRO,__VA_ARGS__) MACRO(195,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG196(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG195(MACRO,__VA_ARGS__) MACRO(196,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG197(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG196(MACRO,__VA_ARGS__) MACRO(197,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG198(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG197(MACRO,__VA_ARGS__) MACRO(198,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG199(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG198(MACRO,__VA_ARGS__) MACRO(199,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG200(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG199(MACRO,__VA_ARGS__) MACRO(200,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG201(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG200(MACRO,__VA_ARGS__) MACRO(201,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG202(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG201(MACRO,__VA_ARGS__) MACRO(202,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG203(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG202(MACRO,__VA_ARGS__) MACRO(203,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG204(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG203(MACRO,__VA_ARGS__) MACRO(204,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG205(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG204(MACRO,__VA_ARGS__) MACRO(205,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG206(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG205(MACRO,__VA_ARGS__) MACRO(206,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG207(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG206(MACRO,__VA_ARGS__) MACRO(207,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG208(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG207(MACRO,__VA_ARGS__) MACRO(208,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG209(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG208(MACRO,__VA_ARGS__) MACRO(209,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG210(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG209(MACRO,__VA_ARGS__) MACRO(210,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG211(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG210(MACRO,__VA_ARGS__) MACRO(211,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG212(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG211(MACRO,__VA_ARGS__) MACRO(212,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG213(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG212(MACRO,__VA_ARGS__) MACRO(213,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG214(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG213(MACRO,__VA_ARGS__) MACRO(214,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG215(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG214(MACRO,__VA_ARGS__) MACRO(215,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG216(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG215(MACRO,__VA_ARGS__) MACRO(216,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG217(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG216(MACRO,__VA_ARGS__) MACRO(217,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG218(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG217(MACRO,__VA_ARGS__) MACRO(218,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG219(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG218(MACRO,__VA_ARGS__) MACRO(219,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG220(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG219(MACRO,__VA_ARGS__) MACRO(220,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG221(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG220(MACRO,__VA_ARGS__) MACRO(221,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG222(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG221(MACRO,__VA_ARGS__) MACRO(222,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG223(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG222(MACRO,__VA_ARGS__) MACRO(223,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG224(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG223(MACRO,__VA_ARGS__) MACRO(224,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG225(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG224(MACRO,__VA_ARGS__) MACRO(225,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG226(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG225(MACRO,__VA_ARGS__) MACRO(226,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG227(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG226(MACRO,__VA_ARGS__) MACRO(227,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG228(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG227(MACRO,__VA_ARGS__) MACRO(228,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG229(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG228(MACRO,__VA_ARGS__) MACRO(229,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG230(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG229(MACRO,__VA_ARGS__) MACRO(230,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG231(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG230(MACRO,__VA_ARGS__) MACRO(231,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG232(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG231(MACRO,__VA_ARGS__) MACRO(232,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG233(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG232(MACRO,__VA_ARGS__) MACRO(233,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG234(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG233(MACRO,__VA_ARGS__) MACRO(234,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG235(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG234(MACRO,__VA_ARGS__) MACRO(235,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG236(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG235(MACRO,__VA_ARGS__) MACRO(236,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG237(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG236(MACRO,__VA_ARGS__) MACRO(237,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG238(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG237(MACRO,__VA_ARGS__) MACRO(238,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG239(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG238(MACRO,__VA_ARGS__) MACRO(239,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG240(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG239(MACRO,__VA_ARGS__) MACRO(240,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG241(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG240(MACRO,__VA_ARGS__) MACRO(241,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG242(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG241(MACRO,__VA_ARGS__) MACRO(242,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG243(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG242(MACRO,__VA_ARGS__) MACRO(243,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG244(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG243(MACRO,__VA_ARGS__) MACRO(244,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG245(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG244(MACRO,__VA_ARGS__) MACRO(245,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG246(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG245(MACRO,__VA_ARGS__) MACRO(246,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG247(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG246(MACRO,__VA_ARGS__) MACRO(247,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG248(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG247(MACRO,__VA_ARGS__) MACRO(248,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG249(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG248(MACRO,__VA_ARGS__) MACRO(249,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG250(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG249(MACRO,__VA_ARGS__) MACRO(250,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG251(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG250(MACRO,__VA_ARGS__) MACRO(251,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG252(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG251(MACRO,__VA_ARGS__) MACRO(252,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG253(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG252(MACRO,__VA_ARGS__) MACRO(253,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG254(MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG253(MACRO,__VA_ARGS__) MACRO(254,__VA_ARGS__)) -#define KAGUYA_PP_REPEAT_DEF_VA_ARG(COUNT,MACRO, ...) KAGUYA_VA_ARG(KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_DEF_VA_ARG,COUNT)(MACRO,__VA_ARGS__)) - - -#define KAGUYA_PP_WHILE0(MACRO,R) R -#define KAGUYA_PP_WHILE1(MACRO,R) MACRO(KAGUYA_PP_WHILE0(MACRO,R)) -#define KAGUYA_PP_WHILE2(MACRO,R) MACRO(KAGUYA_PP_WHILE1(MACRO,R)) -#define KAGUYA_PP_WHILE3(MACRO,R) MACRO(KAGUYA_PP_WHILE2(MACRO,R)) -#define KAGUYA_PP_WHILE4(MACRO,R) MACRO(KAGUYA_PP_WHILE3(MACRO,R)) -#define KAGUYA_PP_WHILE5(MACRO,R) MACRO(KAGUYA_PP_WHILE4(MACRO,R)) -#define KAGUYA_PP_WHILE6(MACRO,R) MACRO(KAGUYA_PP_WHILE5(MACRO,R)) -#define KAGUYA_PP_WHILE7(MACRO,R) MACRO(KAGUYA_PP_WHILE6(MACRO,R)) -#define KAGUYA_PP_WHILE8(MACRO,R) MACRO(KAGUYA_PP_WHILE7(MACRO,R)) -#define KAGUYA_PP_WHILE9(MACRO,R) MACRO(KAGUYA_PP_WHILE8(MACRO,R)) -#define KAGUYA_PP_WHILE10(MACRO,R) MACRO(KAGUYA_PP_WHILE9(MACRO,R)) -#define KAGUYA_PP_WHILE11(MACRO,R) MACRO(KAGUYA_PP_WHILE10(MACRO,R)) -#define KAGUYA_PP_WHILE12(MACRO,R) MACRO(KAGUYA_PP_WHILE11(MACRO,R)) -#define KAGUYA_PP_WHILE13(MACRO,R) MACRO(KAGUYA_PP_WHILE12(MACRO,R)) -#define KAGUYA_PP_WHILE14(MACRO,R) MACRO(KAGUYA_PP_WHILE13(MACRO,R)) -#define KAGUYA_PP_WHILE15(MACRO,R) MACRO(KAGUYA_PP_WHILE14(MACRO,R)) -#define KAGUYA_PP_WHILE16(MACRO,R) MACRO(KAGUYA_PP_WHILE15(MACRO,R)) -#define KAGUYA_PP_WHILE17(MACRO,R) MACRO(KAGUYA_PP_WHILE16(MACRO,R)) -#define KAGUYA_PP_WHILE18(MACRO,R) MACRO(KAGUYA_PP_WHILE17(MACRO,R)) -#define KAGUYA_PP_WHILE19(MACRO,R) MACRO(KAGUYA_PP_WHILE18(MACRO,R)) -#define KAGUYA_PP_WHILE20(MACRO,R) MACRO(KAGUYA_PP_WHILE19(MACRO,R)) -#define KAGUYA_PP_WHILE21(MACRO,R) MACRO(KAGUYA_PP_WHILE20(MACRO,R)) -#define KAGUYA_PP_WHILE22(MACRO,R) MACRO(KAGUYA_PP_WHILE21(MACRO,R)) -#define KAGUYA_PP_WHILE23(MACRO,R) MACRO(KAGUYA_PP_WHILE22(MACRO,R)) -#define KAGUYA_PP_WHILE24(MACRO,R) MACRO(KAGUYA_PP_WHILE23(MACRO,R)) -#define KAGUYA_PP_WHILE25(MACRO,R) MACRO(KAGUYA_PP_WHILE24(MACRO,R)) -#define KAGUYA_PP_WHILE26(MACRO,R) MACRO(KAGUYA_PP_WHILE25(MACRO,R)) -#define KAGUYA_PP_WHILE27(MACRO,R) MACRO(KAGUYA_PP_WHILE26(MACRO,R)) -#define KAGUYA_PP_WHILE28(MACRO,R) MACRO(KAGUYA_PP_WHILE27(MACRO,R)) -#define KAGUYA_PP_WHILE29(MACRO,R) MACRO(KAGUYA_PP_WHILE28(MACRO,R)) -#define KAGUYA_PP_WHILE30(MACRO,R) MACRO(KAGUYA_PP_WHILE29(MACRO,R)) -#define KAGUYA_PP_WHILE31(MACRO,R) MACRO(KAGUYA_PP_WHILE30(MACRO,R)) -#define KAGUYA_PP_WHILE32(MACRO,R) MACRO(KAGUYA_PP_WHILE31(MACRO,R)) -#define KAGUYA_PP_WHILE33(MACRO,R) MACRO(KAGUYA_PP_WHILE32(MACRO,R)) -#define KAGUYA_PP_WHILE34(MACRO,R) MACRO(KAGUYA_PP_WHILE33(MACRO,R)) -#define KAGUYA_PP_WHILE35(MACRO,R) MACRO(KAGUYA_PP_WHILE34(MACRO,R)) -#define KAGUYA_PP_WHILE36(MACRO,R) MACRO(KAGUYA_PP_WHILE35(MACRO,R)) -#define KAGUYA_PP_WHILE37(MACRO,R) MACRO(KAGUYA_PP_WHILE36(MACRO,R)) -#define KAGUYA_PP_WHILE38(MACRO,R) MACRO(KAGUYA_PP_WHILE37(MACRO,R)) -#define KAGUYA_PP_WHILE39(MACRO,R) MACRO(KAGUYA_PP_WHILE38(MACRO,R)) -#define KAGUYA_PP_WHILE40(MACRO,R) MACRO(KAGUYA_PP_WHILE39(MACRO,R)) -#define KAGUYA_PP_WHILE41(MACRO,R) MACRO(KAGUYA_PP_WHILE40(MACRO,R)) -#define KAGUYA_PP_WHILE42(MACRO,R) MACRO(KAGUYA_PP_WHILE41(MACRO,R)) -#define KAGUYA_PP_WHILE43(MACRO,R) MACRO(KAGUYA_PP_WHILE42(MACRO,R)) -#define KAGUYA_PP_WHILE44(MACRO,R) MACRO(KAGUYA_PP_WHILE43(MACRO,R)) -#define KAGUYA_PP_WHILE45(MACRO,R) MACRO(KAGUYA_PP_WHILE44(MACRO,R)) -#define KAGUYA_PP_WHILE46(MACRO,R) MACRO(KAGUYA_PP_WHILE45(MACRO,R)) -#define KAGUYA_PP_WHILE47(MACRO,R) MACRO(KAGUYA_PP_WHILE46(MACRO,R)) -#define KAGUYA_PP_WHILE48(MACRO,R) MACRO(KAGUYA_PP_WHILE47(MACRO,R)) -#define KAGUYA_PP_WHILE49(MACRO,R) MACRO(KAGUYA_PP_WHILE48(MACRO,R)) -#define KAGUYA_PP_WHILE50(MACRO,R) MACRO(KAGUYA_PP_WHILE49(MACRO,R)) -#define KAGUYA_PP_WHILE51(MACRO,R) MACRO(KAGUYA_PP_WHILE50(MACRO,R)) -#define KAGUYA_PP_WHILE52(MACRO,R) MACRO(KAGUYA_PP_WHILE51(MACRO,R)) -#define KAGUYA_PP_WHILE53(MACRO,R) MACRO(KAGUYA_PP_WHILE52(MACRO,R)) -#define KAGUYA_PP_WHILE54(MACRO,R) MACRO(KAGUYA_PP_WHILE53(MACRO,R)) -#define KAGUYA_PP_WHILE55(MACRO,R) MACRO(KAGUYA_PP_WHILE54(MACRO,R)) -#define KAGUYA_PP_WHILE56(MACRO,R) MACRO(KAGUYA_PP_WHILE55(MACRO,R)) -#define KAGUYA_PP_WHILE57(MACRO,R) MACRO(KAGUYA_PP_WHILE56(MACRO,R)) -#define KAGUYA_PP_WHILE58(MACRO,R) MACRO(KAGUYA_PP_WHILE57(MACRO,R)) -#define KAGUYA_PP_WHILE59(MACRO,R) MACRO(KAGUYA_PP_WHILE58(MACRO,R)) -#define KAGUYA_PP_WHILE60(MACRO,R) MACRO(KAGUYA_PP_WHILE59(MACRO,R)) -#define KAGUYA_PP_WHILE61(MACRO,R) MACRO(KAGUYA_PP_WHILE60(MACRO,R)) -#define KAGUYA_PP_WHILE62(MACRO,R) MACRO(KAGUYA_PP_WHILE61(MACRO,R)) -#define KAGUYA_PP_WHILE63(MACRO,R) MACRO(KAGUYA_PP_WHILE62(MACRO,R)) -#define KAGUYA_PP_WHILE64(MACRO,R) MACRO(KAGUYA_PP_WHILE63(MACRO,R)) -#define KAGUYA_PP_WHILE65(MACRO,R) MACRO(KAGUYA_PP_WHILE64(MACRO,R)) -#define KAGUYA_PP_WHILE66(MACRO,R) MACRO(KAGUYA_PP_WHILE65(MACRO,R)) -#define KAGUYA_PP_WHILE67(MACRO,R) MACRO(KAGUYA_PP_WHILE66(MACRO,R)) -#define KAGUYA_PP_WHILE68(MACRO,R) MACRO(KAGUYA_PP_WHILE67(MACRO,R)) -#define KAGUYA_PP_WHILE69(MACRO,R) MACRO(KAGUYA_PP_WHILE68(MACRO,R)) -#define KAGUYA_PP_WHILE70(MACRO,R) MACRO(KAGUYA_PP_WHILE69(MACRO,R)) -#define KAGUYA_PP_WHILE71(MACRO,R) MACRO(KAGUYA_PP_WHILE70(MACRO,R)) -#define KAGUYA_PP_WHILE72(MACRO,R) MACRO(KAGUYA_PP_WHILE71(MACRO,R)) -#define KAGUYA_PP_WHILE73(MACRO,R) MACRO(KAGUYA_PP_WHILE72(MACRO,R)) -#define KAGUYA_PP_WHILE74(MACRO,R) MACRO(KAGUYA_PP_WHILE73(MACRO,R)) -#define KAGUYA_PP_WHILE75(MACRO,R) MACRO(KAGUYA_PP_WHILE74(MACRO,R)) -#define KAGUYA_PP_WHILE76(MACRO,R) MACRO(KAGUYA_PP_WHILE75(MACRO,R)) -#define KAGUYA_PP_WHILE77(MACRO,R) MACRO(KAGUYA_PP_WHILE76(MACRO,R)) -#define KAGUYA_PP_WHILE78(MACRO,R) MACRO(KAGUYA_PP_WHILE77(MACRO,R)) -#define KAGUYA_PP_WHILE79(MACRO,R) MACRO(KAGUYA_PP_WHILE78(MACRO,R)) -#define KAGUYA_PP_WHILE80(MACRO,R) MACRO(KAGUYA_PP_WHILE79(MACRO,R)) -#define KAGUYA_PP_WHILE81(MACRO,R) MACRO(KAGUYA_PP_WHILE80(MACRO,R)) -#define KAGUYA_PP_WHILE82(MACRO,R) MACRO(KAGUYA_PP_WHILE81(MACRO,R)) -#define KAGUYA_PP_WHILE83(MACRO,R) MACRO(KAGUYA_PP_WHILE82(MACRO,R)) -#define KAGUYA_PP_WHILE84(MACRO,R) MACRO(KAGUYA_PP_WHILE83(MACRO,R)) -#define KAGUYA_PP_WHILE85(MACRO,R) MACRO(KAGUYA_PP_WHILE84(MACRO,R)) -#define KAGUYA_PP_WHILE86(MACRO,R) MACRO(KAGUYA_PP_WHILE85(MACRO,R)) -#define KAGUYA_PP_WHILE87(MACRO,R) MACRO(KAGUYA_PP_WHILE86(MACRO,R)) -#define KAGUYA_PP_WHILE88(MACRO,R) MACRO(KAGUYA_PP_WHILE87(MACRO,R)) -#define KAGUYA_PP_WHILE89(MACRO,R) MACRO(KAGUYA_PP_WHILE88(MACRO,R)) -#define KAGUYA_PP_WHILE90(MACRO,R) MACRO(KAGUYA_PP_WHILE89(MACRO,R)) -#define KAGUYA_PP_WHILE91(MACRO,R) MACRO(KAGUYA_PP_WHILE90(MACRO,R)) -#define KAGUYA_PP_WHILE92(MACRO,R) MACRO(KAGUYA_PP_WHILE91(MACRO,R)) -#define KAGUYA_PP_WHILE93(MACRO,R) MACRO(KAGUYA_PP_WHILE92(MACRO,R)) -#define KAGUYA_PP_WHILE94(MACRO,R) MACRO(KAGUYA_PP_WHILE93(MACRO,R)) -#define KAGUYA_PP_WHILE95(MACRO,R) MACRO(KAGUYA_PP_WHILE94(MACRO,R)) -#define KAGUYA_PP_WHILE96(MACRO,R) MACRO(KAGUYA_PP_WHILE95(MACRO,R)) -#define KAGUYA_PP_WHILE97(MACRO,R) MACRO(KAGUYA_PP_WHILE96(MACRO,R)) -#define KAGUYA_PP_WHILE98(MACRO,R) MACRO(KAGUYA_PP_WHILE97(MACRO,R)) -#define KAGUYA_PP_WHILE99(MACRO,R) MACRO(KAGUYA_PP_WHILE98(MACRO,R)) -#define KAGUYA_PP_WHILE100(MACRO,R) MACRO(KAGUYA_PP_WHILE99(MACRO,R)) -#define KAGUYA_PP_WHILE101(MACRO,R) MACRO(KAGUYA_PP_WHILE100(MACRO,R)) -#define KAGUYA_PP_WHILE102(MACRO,R) MACRO(KAGUYA_PP_WHILE101(MACRO,R)) -#define KAGUYA_PP_WHILE103(MACRO,R) MACRO(KAGUYA_PP_WHILE102(MACRO,R)) -#define KAGUYA_PP_WHILE104(MACRO,R) MACRO(KAGUYA_PP_WHILE103(MACRO,R)) -#define KAGUYA_PP_WHILE105(MACRO,R) MACRO(KAGUYA_PP_WHILE104(MACRO,R)) -#define KAGUYA_PP_WHILE106(MACRO,R) MACRO(KAGUYA_PP_WHILE105(MACRO,R)) -#define KAGUYA_PP_WHILE107(MACRO,R) MACRO(KAGUYA_PP_WHILE106(MACRO,R)) -#define KAGUYA_PP_WHILE108(MACRO,R) MACRO(KAGUYA_PP_WHILE107(MACRO,R)) -#define KAGUYA_PP_WHILE109(MACRO,R) MACRO(KAGUYA_PP_WHILE108(MACRO,R)) -#define KAGUYA_PP_WHILE110(MACRO,R) MACRO(KAGUYA_PP_WHILE109(MACRO,R)) -#define KAGUYA_PP_WHILE111(MACRO,R) MACRO(KAGUYA_PP_WHILE110(MACRO,R)) -#define KAGUYA_PP_WHILE112(MACRO,R) MACRO(KAGUYA_PP_WHILE111(MACRO,R)) -#define KAGUYA_PP_WHILE113(MACRO,R) MACRO(KAGUYA_PP_WHILE112(MACRO,R)) -#define KAGUYA_PP_WHILE114(MACRO,R) MACRO(KAGUYA_PP_WHILE113(MACRO,R)) -#define KAGUYA_PP_WHILE115(MACRO,R) MACRO(KAGUYA_PP_WHILE114(MACRO,R)) -#define KAGUYA_PP_WHILE116(MACRO,R) MACRO(KAGUYA_PP_WHILE115(MACRO,R)) -#define KAGUYA_PP_WHILE117(MACRO,R) MACRO(KAGUYA_PP_WHILE116(MACRO,R)) -#define KAGUYA_PP_WHILE118(MACRO,R) MACRO(KAGUYA_PP_WHILE117(MACRO,R)) -#define KAGUYA_PP_WHILE119(MACRO,R) MACRO(KAGUYA_PP_WHILE118(MACRO,R)) -#define KAGUYA_PP_WHILE120(MACRO,R) MACRO(KAGUYA_PP_WHILE119(MACRO,R)) -#define KAGUYA_PP_WHILE121(MACRO,R) MACRO(KAGUYA_PP_WHILE120(MACRO,R)) -#define KAGUYA_PP_WHILE122(MACRO,R) MACRO(KAGUYA_PP_WHILE121(MACRO,R)) -#define KAGUYA_PP_WHILE123(MACRO,R) MACRO(KAGUYA_PP_WHILE122(MACRO,R)) -#define KAGUYA_PP_WHILE124(MACRO,R) MACRO(KAGUYA_PP_WHILE123(MACRO,R)) -#define KAGUYA_PP_WHILE125(MACRO,R) MACRO(KAGUYA_PP_WHILE124(MACRO,R)) -#define KAGUYA_PP_WHILE126(MACRO,R) MACRO(KAGUYA_PP_WHILE125(MACRO,R)) -#define KAGUYA_PP_WHILE127(MACRO,R) MACRO(KAGUYA_PP_WHILE126(MACRO,R)) -#define KAGUYA_PP_WHILE128(MACRO,R) MACRO(KAGUYA_PP_WHILE127(MACRO,R)) -#define KAGUYA_PP_WHILE129(MACRO,R) MACRO(KAGUYA_PP_WHILE128(MACRO,R)) -#define KAGUYA_PP_WHILE130(MACRO,R) MACRO(KAGUYA_PP_WHILE129(MACRO,R)) -#define KAGUYA_PP_WHILE131(MACRO,R) MACRO(KAGUYA_PP_WHILE130(MACRO,R)) -#define KAGUYA_PP_WHILE132(MACRO,R) MACRO(KAGUYA_PP_WHILE131(MACRO,R)) -#define KAGUYA_PP_WHILE133(MACRO,R) MACRO(KAGUYA_PP_WHILE132(MACRO,R)) -#define KAGUYA_PP_WHILE134(MACRO,R) MACRO(KAGUYA_PP_WHILE133(MACRO,R)) -#define KAGUYA_PP_WHILE135(MACRO,R) MACRO(KAGUYA_PP_WHILE134(MACRO,R)) -#define KAGUYA_PP_WHILE136(MACRO,R) MACRO(KAGUYA_PP_WHILE135(MACRO,R)) -#define KAGUYA_PP_WHILE137(MACRO,R) MACRO(KAGUYA_PP_WHILE136(MACRO,R)) -#define KAGUYA_PP_WHILE138(MACRO,R) MACRO(KAGUYA_PP_WHILE137(MACRO,R)) -#define KAGUYA_PP_WHILE139(MACRO,R) MACRO(KAGUYA_PP_WHILE138(MACRO,R)) -#define KAGUYA_PP_WHILE140(MACRO,R) MACRO(KAGUYA_PP_WHILE139(MACRO,R)) -#define KAGUYA_PP_WHILE141(MACRO,R) MACRO(KAGUYA_PP_WHILE140(MACRO,R)) -#define KAGUYA_PP_WHILE142(MACRO,R) MACRO(KAGUYA_PP_WHILE141(MACRO,R)) -#define KAGUYA_PP_WHILE143(MACRO,R) MACRO(KAGUYA_PP_WHILE142(MACRO,R)) -#define KAGUYA_PP_WHILE144(MACRO,R) MACRO(KAGUYA_PP_WHILE143(MACRO,R)) -#define KAGUYA_PP_WHILE145(MACRO,R) MACRO(KAGUYA_PP_WHILE144(MACRO,R)) -#define KAGUYA_PP_WHILE146(MACRO,R) MACRO(KAGUYA_PP_WHILE145(MACRO,R)) -#define KAGUYA_PP_WHILE147(MACRO,R) MACRO(KAGUYA_PP_WHILE146(MACRO,R)) -#define KAGUYA_PP_WHILE148(MACRO,R) MACRO(KAGUYA_PP_WHILE147(MACRO,R)) -#define KAGUYA_PP_WHILE149(MACRO,R) MACRO(KAGUYA_PP_WHILE148(MACRO,R)) -#define KAGUYA_PP_WHILE150(MACRO,R) MACRO(KAGUYA_PP_WHILE149(MACRO,R)) -#define KAGUYA_PP_WHILE151(MACRO,R) MACRO(KAGUYA_PP_WHILE150(MACRO,R)) -#define KAGUYA_PP_WHILE152(MACRO,R) MACRO(KAGUYA_PP_WHILE151(MACRO,R)) -#define KAGUYA_PP_WHILE153(MACRO,R) MACRO(KAGUYA_PP_WHILE152(MACRO,R)) -#define KAGUYA_PP_WHILE154(MACRO,R) MACRO(KAGUYA_PP_WHILE153(MACRO,R)) -#define KAGUYA_PP_WHILE155(MACRO,R) MACRO(KAGUYA_PP_WHILE154(MACRO,R)) -#define KAGUYA_PP_WHILE156(MACRO,R) MACRO(KAGUYA_PP_WHILE155(MACRO,R)) -#define KAGUYA_PP_WHILE157(MACRO,R) MACRO(KAGUYA_PP_WHILE156(MACRO,R)) -#define KAGUYA_PP_WHILE158(MACRO,R) MACRO(KAGUYA_PP_WHILE157(MACRO,R)) -#define KAGUYA_PP_WHILE159(MACRO,R) MACRO(KAGUYA_PP_WHILE158(MACRO,R)) -#define KAGUYA_PP_WHILE160(MACRO,R) MACRO(KAGUYA_PP_WHILE159(MACRO,R)) -#define KAGUYA_PP_WHILE161(MACRO,R) MACRO(KAGUYA_PP_WHILE160(MACRO,R)) -#define KAGUYA_PP_WHILE162(MACRO,R) MACRO(KAGUYA_PP_WHILE161(MACRO,R)) -#define KAGUYA_PP_WHILE163(MACRO,R) MACRO(KAGUYA_PP_WHILE162(MACRO,R)) -#define KAGUYA_PP_WHILE164(MACRO,R) MACRO(KAGUYA_PP_WHILE163(MACRO,R)) -#define KAGUYA_PP_WHILE165(MACRO,R) MACRO(KAGUYA_PP_WHILE164(MACRO,R)) -#define KAGUYA_PP_WHILE166(MACRO,R) MACRO(KAGUYA_PP_WHILE165(MACRO,R)) -#define KAGUYA_PP_WHILE167(MACRO,R) MACRO(KAGUYA_PP_WHILE166(MACRO,R)) -#define KAGUYA_PP_WHILE168(MACRO,R) MACRO(KAGUYA_PP_WHILE167(MACRO,R)) -#define KAGUYA_PP_WHILE169(MACRO,R) MACRO(KAGUYA_PP_WHILE168(MACRO,R)) -#define KAGUYA_PP_WHILE170(MACRO,R) MACRO(KAGUYA_PP_WHILE169(MACRO,R)) -#define KAGUYA_PP_WHILE171(MACRO,R) MACRO(KAGUYA_PP_WHILE170(MACRO,R)) -#define KAGUYA_PP_WHILE172(MACRO,R) MACRO(KAGUYA_PP_WHILE171(MACRO,R)) -#define KAGUYA_PP_WHILE173(MACRO,R) MACRO(KAGUYA_PP_WHILE172(MACRO,R)) -#define KAGUYA_PP_WHILE174(MACRO,R) MACRO(KAGUYA_PP_WHILE173(MACRO,R)) -#define KAGUYA_PP_WHILE175(MACRO,R) MACRO(KAGUYA_PP_WHILE174(MACRO,R)) -#define KAGUYA_PP_WHILE176(MACRO,R) MACRO(KAGUYA_PP_WHILE175(MACRO,R)) -#define KAGUYA_PP_WHILE177(MACRO,R) MACRO(KAGUYA_PP_WHILE176(MACRO,R)) -#define KAGUYA_PP_WHILE178(MACRO,R) MACRO(KAGUYA_PP_WHILE177(MACRO,R)) -#define KAGUYA_PP_WHILE179(MACRO,R) MACRO(KAGUYA_PP_WHILE178(MACRO,R)) -#define KAGUYA_PP_WHILE180(MACRO,R) MACRO(KAGUYA_PP_WHILE179(MACRO,R)) -#define KAGUYA_PP_WHILE181(MACRO,R) MACRO(KAGUYA_PP_WHILE180(MACRO,R)) -#define KAGUYA_PP_WHILE182(MACRO,R) MACRO(KAGUYA_PP_WHILE181(MACRO,R)) -#define KAGUYA_PP_WHILE183(MACRO,R) MACRO(KAGUYA_PP_WHILE182(MACRO,R)) -#define KAGUYA_PP_WHILE184(MACRO,R) MACRO(KAGUYA_PP_WHILE183(MACRO,R)) -#define KAGUYA_PP_WHILE185(MACRO,R) MACRO(KAGUYA_PP_WHILE184(MACRO,R)) -#define KAGUYA_PP_WHILE186(MACRO,R) MACRO(KAGUYA_PP_WHILE185(MACRO,R)) -#define KAGUYA_PP_WHILE187(MACRO,R) MACRO(KAGUYA_PP_WHILE186(MACRO,R)) -#define KAGUYA_PP_WHILE188(MACRO,R) MACRO(KAGUYA_PP_WHILE187(MACRO,R)) -#define KAGUYA_PP_WHILE189(MACRO,R) MACRO(KAGUYA_PP_WHILE188(MACRO,R)) -#define KAGUYA_PP_WHILE190(MACRO,R) MACRO(KAGUYA_PP_WHILE189(MACRO,R)) -#define KAGUYA_PP_WHILE191(MACRO,R) MACRO(KAGUYA_PP_WHILE190(MACRO,R)) -#define KAGUYA_PP_WHILE192(MACRO,R) MACRO(KAGUYA_PP_WHILE191(MACRO,R)) -#define KAGUYA_PP_WHILE193(MACRO,R) MACRO(KAGUYA_PP_WHILE192(MACRO,R)) -#define KAGUYA_PP_WHILE194(MACRO,R) MACRO(KAGUYA_PP_WHILE193(MACRO,R)) -#define KAGUYA_PP_WHILE195(MACRO,R) MACRO(KAGUYA_PP_WHILE194(MACRO,R)) -#define KAGUYA_PP_WHILE196(MACRO,R) MACRO(KAGUYA_PP_WHILE195(MACRO,R)) -#define KAGUYA_PP_WHILE197(MACRO,R) MACRO(KAGUYA_PP_WHILE196(MACRO,R)) -#define KAGUYA_PP_WHILE198(MACRO,R) MACRO(KAGUYA_PP_WHILE197(MACRO,R)) -#define KAGUYA_PP_WHILE199(MACRO,R) MACRO(KAGUYA_PP_WHILE198(MACRO,R)) -#define KAGUYA_PP_WHILE200(MACRO,R) MACRO(KAGUYA_PP_WHILE199(MACRO,R)) -#define KAGUYA_PP_WHILE201(MACRO,R) MACRO(KAGUYA_PP_WHILE200(MACRO,R)) -#define KAGUYA_PP_WHILE202(MACRO,R) MACRO(KAGUYA_PP_WHILE201(MACRO,R)) -#define KAGUYA_PP_WHILE203(MACRO,R) MACRO(KAGUYA_PP_WHILE202(MACRO,R)) -#define KAGUYA_PP_WHILE204(MACRO,R) MACRO(KAGUYA_PP_WHILE203(MACRO,R)) -#define KAGUYA_PP_WHILE205(MACRO,R) MACRO(KAGUYA_PP_WHILE204(MACRO,R)) -#define KAGUYA_PP_WHILE206(MACRO,R) MACRO(KAGUYA_PP_WHILE205(MACRO,R)) -#define KAGUYA_PP_WHILE207(MACRO,R) MACRO(KAGUYA_PP_WHILE206(MACRO,R)) -#define KAGUYA_PP_WHILE208(MACRO,R) MACRO(KAGUYA_PP_WHILE207(MACRO,R)) -#define KAGUYA_PP_WHILE209(MACRO,R) MACRO(KAGUYA_PP_WHILE208(MACRO,R)) -#define KAGUYA_PP_WHILE210(MACRO,R) MACRO(KAGUYA_PP_WHILE209(MACRO,R)) -#define KAGUYA_PP_WHILE211(MACRO,R) MACRO(KAGUYA_PP_WHILE210(MACRO,R)) -#define KAGUYA_PP_WHILE212(MACRO,R) MACRO(KAGUYA_PP_WHILE211(MACRO,R)) -#define KAGUYA_PP_WHILE213(MACRO,R) MACRO(KAGUYA_PP_WHILE212(MACRO,R)) -#define KAGUYA_PP_WHILE214(MACRO,R) MACRO(KAGUYA_PP_WHILE213(MACRO,R)) -#define KAGUYA_PP_WHILE215(MACRO,R) MACRO(KAGUYA_PP_WHILE214(MACRO,R)) -#define KAGUYA_PP_WHILE216(MACRO,R) MACRO(KAGUYA_PP_WHILE215(MACRO,R)) -#define KAGUYA_PP_WHILE217(MACRO,R) MACRO(KAGUYA_PP_WHILE216(MACRO,R)) -#define KAGUYA_PP_WHILE218(MACRO,R) MACRO(KAGUYA_PP_WHILE217(MACRO,R)) -#define KAGUYA_PP_WHILE219(MACRO,R) MACRO(KAGUYA_PP_WHILE218(MACRO,R)) -#define KAGUYA_PP_WHILE220(MACRO,R) MACRO(KAGUYA_PP_WHILE219(MACRO,R)) -#define KAGUYA_PP_WHILE221(MACRO,R) MACRO(KAGUYA_PP_WHILE220(MACRO,R)) -#define KAGUYA_PP_WHILE222(MACRO,R) MACRO(KAGUYA_PP_WHILE221(MACRO,R)) -#define KAGUYA_PP_WHILE223(MACRO,R) MACRO(KAGUYA_PP_WHILE222(MACRO,R)) -#define KAGUYA_PP_WHILE224(MACRO,R) MACRO(KAGUYA_PP_WHILE223(MACRO,R)) -#define KAGUYA_PP_WHILE225(MACRO,R) MACRO(KAGUYA_PP_WHILE224(MACRO,R)) -#define KAGUYA_PP_WHILE226(MACRO,R) MACRO(KAGUYA_PP_WHILE225(MACRO,R)) -#define KAGUYA_PP_WHILE227(MACRO,R) MACRO(KAGUYA_PP_WHILE226(MACRO,R)) -#define KAGUYA_PP_WHILE228(MACRO,R) MACRO(KAGUYA_PP_WHILE227(MACRO,R)) -#define KAGUYA_PP_WHILE229(MACRO,R) MACRO(KAGUYA_PP_WHILE228(MACRO,R)) -#define KAGUYA_PP_WHILE230(MACRO,R) MACRO(KAGUYA_PP_WHILE229(MACRO,R)) -#define KAGUYA_PP_WHILE231(MACRO,R) MACRO(KAGUYA_PP_WHILE230(MACRO,R)) -#define KAGUYA_PP_WHILE232(MACRO,R) MACRO(KAGUYA_PP_WHILE231(MACRO,R)) -#define KAGUYA_PP_WHILE233(MACRO,R) MACRO(KAGUYA_PP_WHILE232(MACRO,R)) -#define KAGUYA_PP_WHILE234(MACRO,R) MACRO(KAGUYA_PP_WHILE233(MACRO,R)) -#define KAGUYA_PP_WHILE235(MACRO,R) MACRO(KAGUYA_PP_WHILE234(MACRO,R)) -#define KAGUYA_PP_WHILE236(MACRO,R) MACRO(KAGUYA_PP_WHILE235(MACRO,R)) -#define KAGUYA_PP_WHILE237(MACRO,R) MACRO(KAGUYA_PP_WHILE236(MACRO,R)) -#define KAGUYA_PP_WHILE238(MACRO,R) MACRO(KAGUYA_PP_WHILE237(MACRO,R)) -#define KAGUYA_PP_WHILE239(MACRO,R) MACRO(KAGUYA_PP_WHILE238(MACRO,R)) -#define KAGUYA_PP_WHILE240(MACRO,R) MACRO(KAGUYA_PP_WHILE239(MACRO,R)) -#define KAGUYA_PP_WHILE241(MACRO,R) MACRO(KAGUYA_PP_WHILE240(MACRO,R)) -#define KAGUYA_PP_WHILE242(MACRO,R) MACRO(KAGUYA_PP_WHILE241(MACRO,R)) -#define KAGUYA_PP_WHILE243(MACRO,R) MACRO(KAGUYA_PP_WHILE242(MACRO,R)) -#define KAGUYA_PP_WHILE244(MACRO,R) MACRO(KAGUYA_PP_WHILE243(MACRO,R)) -#define KAGUYA_PP_WHILE245(MACRO,R) MACRO(KAGUYA_PP_WHILE244(MACRO,R)) -#define KAGUYA_PP_WHILE246(MACRO,R) MACRO(KAGUYA_PP_WHILE245(MACRO,R)) -#define KAGUYA_PP_WHILE247(MACRO,R) MACRO(KAGUYA_PP_WHILE246(MACRO,R)) -#define KAGUYA_PP_WHILE248(MACRO,R) MACRO(KAGUYA_PP_WHILE247(MACRO,R)) -#define KAGUYA_PP_WHILE249(MACRO,R) MACRO(KAGUYA_PP_WHILE248(MACRO,R)) -#define KAGUYA_PP_WHILE250(MACRO,R) MACRO(KAGUYA_PP_WHILE249(MACRO,R)) -#define KAGUYA_PP_WHILE251(MACRO,R) MACRO(KAGUYA_PP_WHILE250(MACRO,R)) -#define KAGUYA_PP_WHILE252(MACRO,R) MACRO(KAGUYA_PP_WHILE251(MACRO,R)) -#define KAGUYA_PP_WHILE253(MACRO,R) MACRO(KAGUYA_PP_WHILE252(MACRO,R)) -#define KAGUYA_PP_WHILE254(MACRO,R) MACRO(KAGUYA_PP_WHILE253(MACRO,R)) -#define KAGUYA_PP_WHILE(COUNT,R,MACRO) KAGUYA_PP_CAT(KAGUYA_PP_WHILE,COUNT)(MACRO,R) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG1(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG0(MACRO, __VA_ARGS__) \ + MACRO(1, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG2(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG1(MACRO, __VA_ARGS__) \ + MACRO(2, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG3(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG2(MACRO, __VA_ARGS__) \ + MACRO(3, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG4(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG3(MACRO, __VA_ARGS__) \ + MACRO(4, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG5(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG4(MACRO, __VA_ARGS__) \ + MACRO(5, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG6(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG5(MACRO, __VA_ARGS__) \ + MACRO(6, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG7(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG6(MACRO, __VA_ARGS__) \ + MACRO(7, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG8(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG7(MACRO, __VA_ARGS__) \ + MACRO(8, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG9(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG8(MACRO, __VA_ARGS__) \ + MACRO(9, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG10(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG9(MACRO, __VA_ARGS__) \ + MACRO(10, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG11(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG10(MACRO, __VA_ARGS__) \ + MACRO(11, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG12(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG11(MACRO, __VA_ARGS__) \ + MACRO(12, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG13(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG12(MACRO, __VA_ARGS__) \ + MACRO(13, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG14(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG13(MACRO, __VA_ARGS__) \ + MACRO(14, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG15(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG14(MACRO, __VA_ARGS__) \ + MACRO(15, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG16(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG15(MACRO, __VA_ARGS__) \ + MACRO(16, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG17(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG16(MACRO, __VA_ARGS__) \ + MACRO(17, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG18(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG17(MACRO, __VA_ARGS__) \ + MACRO(18, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG19(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG18(MACRO, __VA_ARGS__) \ + MACRO(19, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG20(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG19(MACRO, __VA_ARGS__) \ + MACRO(20, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG21(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG20(MACRO, __VA_ARGS__) \ + MACRO(21, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG22(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG21(MACRO, __VA_ARGS__) \ + MACRO(22, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG23(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG22(MACRO, __VA_ARGS__) \ + MACRO(23, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG24(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG23(MACRO, __VA_ARGS__) \ + MACRO(24, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG25(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG24(MACRO, __VA_ARGS__) \ + MACRO(25, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG26(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG25(MACRO, __VA_ARGS__) \ + MACRO(26, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG27(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG26(MACRO, __VA_ARGS__) \ + MACRO(27, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG28(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG27(MACRO, __VA_ARGS__) \ + MACRO(28, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG29(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG28(MACRO, __VA_ARGS__) \ + MACRO(29, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG30(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG29(MACRO, __VA_ARGS__) \ + MACRO(30, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG31(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG30(MACRO, __VA_ARGS__) \ + MACRO(31, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG32(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG31(MACRO, __VA_ARGS__) \ + MACRO(32, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG33(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG32(MACRO, __VA_ARGS__) \ + MACRO(33, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG34(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG33(MACRO, __VA_ARGS__) \ + MACRO(34, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG35(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG34(MACRO, __VA_ARGS__) \ + MACRO(35, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG36(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG35(MACRO, __VA_ARGS__) \ + MACRO(36, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG37(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG36(MACRO, __VA_ARGS__) \ + MACRO(37, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG38(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG37(MACRO, __VA_ARGS__) \ + MACRO(38, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG39(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG38(MACRO, __VA_ARGS__) \ + MACRO(39, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG40(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG39(MACRO, __VA_ARGS__) \ + MACRO(40, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG41(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG40(MACRO, __VA_ARGS__) \ + MACRO(41, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG42(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG41(MACRO, __VA_ARGS__) \ + MACRO(42, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG43(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG42(MACRO, __VA_ARGS__) \ + MACRO(43, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG44(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG43(MACRO, __VA_ARGS__) \ + MACRO(44, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG45(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG44(MACRO, __VA_ARGS__) \ + MACRO(45, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG46(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG45(MACRO, __VA_ARGS__) \ + MACRO(46, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG47(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG46(MACRO, __VA_ARGS__) \ + MACRO(47, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG48(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG47(MACRO, __VA_ARGS__) \ + MACRO(48, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG49(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG48(MACRO, __VA_ARGS__) \ + MACRO(49, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG50(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG49(MACRO, __VA_ARGS__) \ + MACRO(50, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG51(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG50(MACRO, __VA_ARGS__) \ + MACRO(51, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG52(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG51(MACRO, __VA_ARGS__) \ + MACRO(52, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG53(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG52(MACRO, __VA_ARGS__) \ + MACRO(53, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG54(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG53(MACRO, __VA_ARGS__) \ + MACRO(54, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG55(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG54(MACRO, __VA_ARGS__) \ + MACRO(55, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG56(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG55(MACRO, __VA_ARGS__) \ + MACRO(56, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG57(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG56(MACRO, __VA_ARGS__) \ + MACRO(57, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG58(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG57(MACRO, __VA_ARGS__) \ + MACRO(58, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG59(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG58(MACRO, __VA_ARGS__) \ + MACRO(59, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG60(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG59(MACRO, __VA_ARGS__) \ + MACRO(60, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG61(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG60(MACRO, __VA_ARGS__) \ + MACRO(61, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG62(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG61(MACRO, __VA_ARGS__) \ + MACRO(62, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG63(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG62(MACRO, __VA_ARGS__) \ + MACRO(63, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG64(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG63(MACRO, __VA_ARGS__) \ + MACRO(64, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG65(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG64(MACRO, __VA_ARGS__) \ + MACRO(65, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG66(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG65(MACRO, __VA_ARGS__) \ + MACRO(66, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG67(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG66(MACRO, __VA_ARGS__) \ + MACRO(67, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG68(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG67(MACRO, __VA_ARGS__) \ + MACRO(68, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG69(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG68(MACRO, __VA_ARGS__) \ + MACRO(69, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG70(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG69(MACRO, __VA_ARGS__) \ + MACRO(70, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG71(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG70(MACRO, __VA_ARGS__) \ + MACRO(71, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG72(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG71(MACRO, __VA_ARGS__) \ + MACRO(72, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG73(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG72(MACRO, __VA_ARGS__) \ + MACRO(73, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG74(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG73(MACRO, __VA_ARGS__) \ + MACRO(74, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG75(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG74(MACRO, __VA_ARGS__) \ + MACRO(75, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG76(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG75(MACRO, __VA_ARGS__) \ + MACRO(76, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG77(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG76(MACRO, __VA_ARGS__) \ + MACRO(77, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG78(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG77(MACRO, __VA_ARGS__) \ + MACRO(78, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG79(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG78(MACRO, __VA_ARGS__) \ + MACRO(79, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG80(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG79(MACRO, __VA_ARGS__) \ + MACRO(80, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG81(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG80(MACRO, __VA_ARGS__) \ + MACRO(81, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG82(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG81(MACRO, __VA_ARGS__) \ + MACRO(82, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG83(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG82(MACRO, __VA_ARGS__) \ + MACRO(83, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG84(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG83(MACRO, __VA_ARGS__) \ + MACRO(84, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG85(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG84(MACRO, __VA_ARGS__) \ + MACRO(85, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG86(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG85(MACRO, __VA_ARGS__) \ + MACRO(86, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG87(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG86(MACRO, __VA_ARGS__) \ + MACRO(87, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG88(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG87(MACRO, __VA_ARGS__) \ + MACRO(88, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG89(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG88(MACRO, __VA_ARGS__) \ + MACRO(89, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG90(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG89(MACRO, __VA_ARGS__) \ + MACRO(90, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG91(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG90(MACRO, __VA_ARGS__) \ + MACRO(91, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG92(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG91(MACRO, __VA_ARGS__) \ + MACRO(92, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG93(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG92(MACRO, __VA_ARGS__) \ + MACRO(93, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG94(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG93(MACRO, __VA_ARGS__) \ + MACRO(94, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG95(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG94(MACRO, __VA_ARGS__) \ + MACRO(95, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG96(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG95(MACRO, __VA_ARGS__) \ + MACRO(96, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG97(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG96(MACRO, __VA_ARGS__) \ + MACRO(97, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG98(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG97(MACRO, __VA_ARGS__) \ + MACRO(98, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG99(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG98(MACRO, __VA_ARGS__) \ + MACRO(99, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG100(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG99(MACRO, __VA_ARGS__) \ + MACRO(100, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG101(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG100(MACRO, __VA_ARGS__) \ + MACRO(101, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG102(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG101(MACRO, __VA_ARGS__) \ + MACRO(102, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG103(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG102(MACRO, __VA_ARGS__) \ + MACRO(103, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG104(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG103(MACRO, __VA_ARGS__) \ + MACRO(104, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG105(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG104(MACRO, __VA_ARGS__) \ + MACRO(105, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG106(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG105(MACRO, __VA_ARGS__) \ + MACRO(106, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG107(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG106(MACRO, __VA_ARGS__) \ + MACRO(107, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG108(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG107(MACRO, __VA_ARGS__) \ + MACRO(108, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG109(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG108(MACRO, __VA_ARGS__) \ + MACRO(109, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG110(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG109(MACRO, __VA_ARGS__) \ + MACRO(110, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG111(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG110(MACRO, __VA_ARGS__) \ + MACRO(111, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG112(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG111(MACRO, __VA_ARGS__) \ + MACRO(112, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG113(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG112(MACRO, __VA_ARGS__) \ + MACRO(113, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG114(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG113(MACRO, __VA_ARGS__) \ + MACRO(114, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG115(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG114(MACRO, __VA_ARGS__) \ + MACRO(115, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG116(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG115(MACRO, __VA_ARGS__) \ + MACRO(116, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG117(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG116(MACRO, __VA_ARGS__) \ + MACRO(117, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG118(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG117(MACRO, __VA_ARGS__) \ + MACRO(118, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG119(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG118(MACRO, __VA_ARGS__) \ + MACRO(119, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG120(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG119(MACRO, __VA_ARGS__) \ + MACRO(120, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG121(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG120(MACRO, __VA_ARGS__) \ + MACRO(121, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG122(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG121(MACRO, __VA_ARGS__) \ + MACRO(122, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG123(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG122(MACRO, __VA_ARGS__) \ + MACRO(123, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG124(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG123(MACRO, __VA_ARGS__) \ + MACRO(124, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG125(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG124(MACRO, __VA_ARGS__) \ + MACRO(125, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG126(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG125(MACRO, __VA_ARGS__) \ + MACRO(126, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG127(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG126(MACRO, __VA_ARGS__) \ + MACRO(127, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG128(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG127(MACRO, __VA_ARGS__) \ + MACRO(128, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG129(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG128(MACRO, __VA_ARGS__) \ + MACRO(129, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG130(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG129(MACRO, __VA_ARGS__) \ + MACRO(130, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG131(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG130(MACRO, __VA_ARGS__) \ + MACRO(131, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG132(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG131(MACRO, __VA_ARGS__) \ + MACRO(132, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG133(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG132(MACRO, __VA_ARGS__) \ + MACRO(133, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG134(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG133(MACRO, __VA_ARGS__) \ + MACRO(134, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG135(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG134(MACRO, __VA_ARGS__) \ + MACRO(135, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG136(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG135(MACRO, __VA_ARGS__) \ + MACRO(136, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG137(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG136(MACRO, __VA_ARGS__) \ + MACRO(137, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG138(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG137(MACRO, __VA_ARGS__) \ + MACRO(138, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG139(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG138(MACRO, __VA_ARGS__) \ + MACRO(139, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG140(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG139(MACRO, __VA_ARGS__) \ + MACRO(140, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG141(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG140(MACRO, __VA_ARGS__) \ + MACRO(141, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG142(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG141(MACRO, __VA_ARGS__) \ + MACRO(142, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG143(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG142(MACRO, __VA_ARGS__) \ + MACRO(143, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG144(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG143(MACRO, __VA_ARGS__) \ + MACRO(144, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG145(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG144(MACRO, __VA_ARGS__) \ + MACRO(145, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG146(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG145(MACRO, __VA_ARGS__) \ + MACRO(146, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG147(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG146(MACRO, __VA_ARGS__) \ + MACRO(147, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG148(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG147(MACRO, __VA_ARGS__) \ + MACRO(148, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG149(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG148(MACRO, __VA_ARGS__) \ + MACRO(149, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG150(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG149(MACRO, __VA_ARGS__) \ + MACRO(150, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG151(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG150(MACRO, __VA_ARGS__) \ + MACRO(151, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG152(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG151(MACRO, __VA_ARGS__) \ + MACRO(152, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG153(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG152(MACRO, __VA_ARGS__) \ + MACRO(153, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG154(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG153(MACRO, __VA_ARGS__) \ + MACRO(154, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG155(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG154(MACRO, __VA_ARGS__) \ + MACRO(155, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG156(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG155(MACRO, __VA_ARGS__) \ + MACRO(156, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG157(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG156(MACRO, __VA_ARGS__) \ + MACRO(157, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG158(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG157(MACRO, __VA_ARGS__) \ + MACRO(158, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG159(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG158(MACRO, __VA_ARGS__) \ + MACRO(159, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG160(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG159(MACRO, __VA_ARGS__) \ + MACRO(160, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG161(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG160(MACRO, __VA_ARGS__) \ + MACRO(161, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG162(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG161(MACRO, __VA_ARGS__) \ + MACRO(162, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG163(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG162(MACRO, __VA_ARGS__) \ + MACRO(163, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG164(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG163(MACRO, __VA_ARGS__) \ + MACRO(164, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG165(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG164(MACRO, __VA_ARGS__) \ + MACRO(165, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG166(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG165(MACRO, __VA_ARGS__) \ + MACRO(166, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG167(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG166(MACRO, __VA_ARGS__) \ + MACRO(167, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG168(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG167(MACRO, __VA_ARGS__) \ + MACRO(168, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG169(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG168(MACRO, __VA_ARGS__) \ + MACRO(169, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG170(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG169(MACRO, __VA_ARGS__) \ + MACRO(170, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG171(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG170(MACRO, __VA_ARGS__) \ + MACRO(171, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG172(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG171(MACRO, __VA_ARGS__) \ + MACRO(172, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG173(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG172(MACRO, __VA_ARGS__) \ + MACRO(173, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG174(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG173(MACRO, __VA_ARGS__) \ + MACRO(174, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG175(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG174(MACRO, __VA_ARGS__) \ + MACRO(175, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG176(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG175(MACRO, __VA_ARGS__) \ + MACRO(176, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG177(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG176(MACRO, __VA_ARGS__) \ + MACRO(177, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG178(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG177(MACRO, __VA_ARGS__) \ + MACRO(178, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG179(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG178(MACRO, __VA_ARGS__) \ + MACRO(179, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG180(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG179(MACRO, __VA_ARGS__) \ + MACRO(180, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG181(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG180(MACRO, __VA_ARGS__) \ + MACRO(181, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG182(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG181(MACRO, __VA_ARGS__) \ + MACRO(182, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG183(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG182(MACRO, __VA_ARGS__) \ + MACRO(183, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG184(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG183(MACRO, __VA_ARGS__) \ + MACRO(184, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG185(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG184(MACRO, __VA_ARGS__) \ + MACRO(185, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG186(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG185(MACRO, __VA_ARGS__) \ + MACRO(186, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG187(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG186(MACRO, __VA_ARGS__) \ + MACRO(187, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG188(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG187(MACRO, __VA_ARGS__) \ + MACRO(188, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG189(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG188(MACRO, __VA_ARGS__) \ + MACRO(189, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG190(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG189(MACRO, __VA_ARGS__) \ + MACRO(190, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG191(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG190(MACRO, __VA_ARGS__) \ + MACRO(191, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG192(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG191(MACRO, __VA_ARGS__) \ + MACRO(192, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG193(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG192(MACRO, __VA_ARGS__) \ + MACRO(193, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG194(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG193(MACRO, __VA_ARGS__) \ + MACRO(194, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG195(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG194(MACRO, __VA_ARGS__) \ + MACRO(195, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG196(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG195(MACRO, __VA_ARGS__) \ + MACRO(196, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG197(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG196(MACRO, __VA_ARGS__) \ + MACRO(197, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG198(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG197(MACRO, __VA_ARGS__) \ + MACRO(198, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG199(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG198(MACRO, __VA_ARGS__) \ + MACRO(199, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG200(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG199(MACRO, __VA_ARGS__) \ + MACRO(200, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG201(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG200(MACRO, __VA_ARGS__) \ + MACRO(201, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG202(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG201(MACRO, __VA_ARGS__) \ + MACRO(202, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG203(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG202(MACRO, __VA_ARGS__) \ + MACRO(203, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG204(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG203(MACRO, __VA_ARGS__) \ + MACRO(204, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG205(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG204(MACRO, __VA_ARGS__) \ + MACRO(205, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG206(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG205(MACRO, __VA_ARGS__) \ + MACRO(206, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG207(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG206(MACRO, __VA_ARGS__) \ + MACRO(207, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG208(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG207(MACRO, __VA_ARGS__) \ + MACRO(208, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG209(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG208(MACRO, __VA_ARGS__) \ + MACRO(209, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG210(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG209(MACRO, __VA_ARGS__) \ + MACRO(210, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG211(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG210(MACRO, __VA_ARGS__) \ + MACRO(211, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG212(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG211(MACRO, __VA_ARGS__) \ + MACRO(212, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG213(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG212(MACRO, __VA_ARGS__) \ + MACRO(213, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG214(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG213(MACRO, __VA_ARGS__) \ + MACRO(214, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG215(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG214(MACRO, __VA_ARGS__) \ + MACRO(215, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG216(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG215(MACRO, __VA_ARGS__) \ + MACRO(216, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG217(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG216(MACRO, __VA_ARGS__) \ + MACRO(217, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG218(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG217(MACRO, __VA_ARGS__) \ + MACRO(218, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG219(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG218(MACRO, __VA_ARGS__) \ + MACRO(219, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG220(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG219(MACRO, __VA_ARGS__) \ + MACRO(220, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG221(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG220(MACRO, __VA_ARGS__) \ + MACRO(221, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG222(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG221(MACRO, __VA_ARGS__) \ + MACRO(222, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG223(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG222(MACRO, __VA_ARGS__) \ + MACRO(223, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG224(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG223(MACRO, __VA_ARGS__) \ + MACRO(224, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG225(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG224(MACRO, __VA_ARGS__) \ + MACRO(225, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG226(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG225(MACRO, __VA_ARGS__) \ + MACRO(226, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG227(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG226(MACRO, __VA_ARGS__) \ + MACRO(227, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG228(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG227(MACRO, __VA_ARGS__) \ + MACRO(228, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG229(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG228(MACRO, __VA_ARGS__) \ + MACRO(229, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG230(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG229(MACRO, __VA_ARGS__) \ + MACRO(230, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG231(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG230(MACRO, __VA_ARGS__) \ + MACRO(231, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG232(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG231(MACRO, __VA_ARGS__) \ + MACRO(232, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG233(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG232(MACRO, __VA_ARGS__) \ + MACRO(233, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG234(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG233(MACRO, __VA_ARGS__) \ + MACRO(234, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG235(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG234(MACRO, __VA_ARGS__) \ + MACRO(235, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG236(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG235(MACRO, __VA_ARGS__) \ + MACRO(236, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG237(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG236(MACRO, __VA_ARGS__) \ + MACRO(237, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG238(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG237(MACRO, __VA_ARGS__) \ + MACRO(238, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG239(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG238(MACRO, __VA_ARGS__) \ + MACRO(239, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG240(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG239(MACRO, __VA_ARGS__) \ + MACRO(240, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG241(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG240(MACRO, __VA_ARGS__) \ + MACRO(241, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG242(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG241(MACRO, __VA_ARGS__) \ + MACRO(242, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG243(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG242(MACRO, __VA_ARGS__) \ + MACRO(243, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG244(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG243(MACRO, __VA_ARGS__) \ + MACRO(244, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG245(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG244(MACRO, __VA_ARGS__) \ + MACRO(245, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG246(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG245(MACRO, __VA_ARGS__) \ + MACRO(246, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG247(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG246(MACRO, __VA_ARGS__) \ + MACRO(247, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG248(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG247(MACRO, __VA_ARGS__) \ + MACRO(248, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG249(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG248(MACRO, __VA_ARGS__) \ + MACRO(249, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG250(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG249(MACRO, __VA_ARGS__) \ + MACRO(250, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG251(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG250(MACRO, __VA_ARGS__) \ + MACRO(251, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG252(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG251(MACRO, __VA_ARGS__) \ + MACRO(252, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG253(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG252(MACRO, __VA_ARGS__) \ + MACRO(253, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG254(MACRO, ...) \ + KAGUYA_VA_ARG(KAGUYA_PP_REPEAT_DEF_VA_ARG253(MACRO, __VA_ARGS__) \ + MACRO(254, __VA_ARGS__)) +#define KAGUYA_PP_REPEAT_DEF_VA_ARG(COUNT, MACRO, ...) \ + KAGUYA_VA_ARG( \ + KAGUYA_PP_CAT(KAGUYA_PP_REPEAT_DEF_VA_ARG, COUNT)(MACRO, __VA_ARGS__)) +#define KAGUYA_PP_WHILE0(MACRO, R) R +#define KAGUYA_PP_WHILE1(MACRO, R) MACRO(KAGUYA_PP_WHILE0(MACRO, R)) +#define KAGUYA_PP_WHILE2(MACRO, R) MACRO(KAGUYA_PP_WHILE1(MACRO, R)) +#define KAGUYA_PP_WHILE3(MACRO, R) MACRO(KAGUYA_PP_WHILE2(MACRO, R)) +#define KAGUYA_PP_WHILE4(MACRO, R) MACRO(KAGUYA_PP_WHILE3(MACRO, R)) +#define KAGUYA_PP_WHILE5(MACRO, R) MACRO(KAGUYA_PP_WHILE4(MACRO, R)) +#define KAGUYA_PP_WHILE6(MACRO, R) MACRO(KAGUYA_PP_WHILE5(MACRO, R)) +#define KAGUYA_PP_WHILE7(MACRO, R) MACRO(KAGUYA_PP_WHILE6(MACRO, R)) +#define KAGUYA_PP_WHILE8(MACRO, R) MACRO(KAGUYA_PP_WHILE7(MACRO, R)) +#define KAGUYA_PP_WHILE9(MACRO, R) MACRO(KAGUYA_PP_WHILE8(MACRO, R)) +#define KAGUYA_PP_WHILE10(MACRO, R) MACRO(KAGUYA_PP_WHILE9(MACRO, R)) +#define KAGUYA_PP_WHILE11(MACRO, R) MACRO(KAGUYA_PP_WHILE10(MACRO, R)) +#define KAGUYA_PP_WHILE12(MACRO, R) MACRO(KAGUYA_PP_WHILE11(MACRO, R)) +#define KAGUYA_PP_WHILE13(MACRO, R) MACRO(KAGUYA_PP_WHILE12(MACRO, R)) +#define KAGUYA_PP_WHILE14(MACRO, R) MACRO(KAGUYA_PP_WHILE13(MACRO, R)) +#define KAGUYA_PP_WHILE15(MACRO, R) MACRO(KAGUYA_PP_WHILE14(MACRO, R)) +#define KAGUYA_PP_WHILE16(MACRO, R) MACRO(KAGUYA_PP_WHILE15(MACRO, R)) +#define KAGUYA_PP_WHILE17(MACRO, R) MACRO(KAGUYA_PP_WHILE16(MACRO, R)) +#define KAGUYA_PP_WHILE18(MACRO, R) MACRO(KAGUYA_PP_WHILE17(MACRO, R)) +#define KAGUYA_PP_WHILE19(MACRO, R) MACRO(KAGUYA_PP_WHILE18(MACRO, R)) +#define KAGUYA_PP_WHILE20(MACRO, R) MACRO(KAGUYA_PP_WHILE19(MACRO, R)) +#define KAGUYA_PP_WHILE21(MACRO, R) MACRO(KAGUYA_PP_WHILE20(MACRO, R)) +#define KAGUYA_PP_WHILE22(MACRO, R) MACRO(KAGUYA_PP_WHILE21(MACRO, R)) +#define KAGUYA_PP_WHILE23(MACRO, R) MACRO(KAGUYA_PP_WHILE22(MACRO, R)) +#define KAGUYA_PP_WHILE24(MACRO, R) MACRO(KAGUYA_PP_WHILE23(MACRO, R)) +#define KAGUYA_PP_WHILE25(MACRO, R) MACRO(KAGUYA_PP_WHILE24(MACRO, R)) +#define KAGUYA_PP_WHILE26(MACRO, R) MACRO(KAGUYA_PP_WHILE25(MACRO, R)) +#define KAGUYA_PP_WHILE27(MACRO, R) MACRO(KAGUYA_PP_WHILE26(MACRO, R)) +#define KAGUYA_PP_WHILE28(MACRO, R) MACRO(KAGUYA_PP_WHILE27(MACRO, R)) +#define KAGUYA_PP_WHILE29(MACRO, R) MACRO(KAGUYA_PP_WHILE28(MACRO, R)) +#define KAGUYA_PP_WHILE30(MACRO, R) MACRO(KAGUYA_PP_WHILE29(MACRO, R)) +#define KAGUYA_PP_WHILE31(MACRO, R) MACRO(KAGUYA_PP_WHILE30(MACRO, R)) +#define KAGUYA_PP_WHILE32(MACRO, R) MACRO(KAGUYA_PP_WHILE31(MACRO, R)) +#define KAGUYA_PP_WHILE33(MACRO, R) MACRO(KAGUYA_PP_WHILE32(MACRO, R)) +#define KAGUYA_PP_WHILE34(MACRO, R) MACRO(KAGUYA_PP_WHILE33(MACRO, R)) +#define KAGUYA_PP_WHILE35(MACRO, R) MACRO(KAGUYA_PP_WHILE34(MACRO, R)) +#define KAGUYA_PP_WHILE36(MACRO, R) MACRO(KAGUYA_PP_WHILE35(MACRO, R)) +#define KAGUYA_PP_WHILE37(MACRO, R) MACRO(KAGUYA_PP_WHILE36(MACRO, R)) +#define KAGUYA_PP_WHILE38(MACRO, R) MACRO(KAGUYA_PP_WHILE37(MACRO, R)) +#define KAGUYA_PP_WHILE39(MACRO, R) MACRO(KAGUYA_PP_WHILE38(MACRO, R)) +#define KAGUYA_PP_WHILE40(MACRO, R) MACRO(KAGUYA_PP_WHILE39(MACRO, R)) +#define KAGUYA_PP_WHILE41(MACRO, R) MACRO(KAGUYA_PP_WHILE40(MACRO, R)) +#define KAGUYA_PP_WHILE42(MACRO, R) MACRO(KAGUYA_PP_WHILE41(MACRO, R)) +#define KAGUYA_PP_WHILE43(MACRO, R) MACRO(KAGUYA_PP_WHILE42(MACRO, R)) +#define KAGUYA_PP_WHILE44(MACRO, R) MACRO(KAGUYA_PP_WHILE43(MACRO, R)) +#define KAGUYA_PP_WHILE45(MACRO, R) MACRO(KAGUYA_PP_WHILE44(MACRO, R)) +#define KAGUYA_PP_WHILE46(MACRO, R) MACRO(KAGUYA_PP_WHILE45(MACRO, R)) +#define KAGUYA_PP_WHILE47(MACRO, R) MACRO(KAGUYA_PP_WHILE46(MACRO, R)) +#define KAGUYA_PP_WHILE48(MACRO, R) MACRO(KAGUYA_PP_WHILE47(MACRO, R)) +#define KAGUYA_PP_WHILE49(MACRO, R) MACRO(KAGUYA_PP_WHILE48(MACRO, R)) +#define KAGUYA_PP_WHILE50(MACRO, R) MACRO(KAGUYA_PP_WHILE49(MACRO, R)) +#define KAGUYA_PP_WHILE51(MACRO, R) MACRO(KAGUYA_PP_WHILE50(MACRO, R)) +#define KAGUYA_PP_WHILE52(MACRO, R) MACRO(KAGUYA_PP_WHILE51(MACRO, R)) +#define KAGUYA_PP_WHILE53(MACRO, R) MACRO(KAGUYA_PP_WHILE52(MACRO, R)) +#define KAGUYA_PP_WHILE54(MACRO, R) MACRO(KAGUYA_PP_WHILE53(MACRO, R)) +#define KAGUYA_PP_WHILE55(MACRO, R) MACRO(KAGUYA_PP_WHILE54(MACRO, R)) +#define KAGUYA_PP_WHILE56(MACRO, R) MACRO(KAGUYA_PP_WHILE55(MACRO, R)) +#define KAGUYA_PP_WHILE57(MACRO, R) MACRO(KAGUYA_PP_WHILE56(MACRO, R)) +#define KAGUYA_PP_WHILE58(MACRO, R) MACRO(KAGUYA_PP_WHILE57(MACRO, R)) +#define KAGUYA_PP_WHILE59(MACRO, R) MACRO(KAGUYA_PP_WHILE58(MACRO, R)) +#define KAGUYA_PP_WHILE60(MACRO, R) MACRO(KAGUYA_PP_WHILE59(MACRO, R)) +#define KAGUYA_PP_WHILE61(MACRO, R) MACRO(KAGUYA_PP_WHILE60(MACRO, R)) +#define KAGUYA_PP_WHILE62(MACRO, R) MACRO(KAGUYA_PP_WHILE61(MACRO, R)) +#define KAGUYA_PP_WHILE63(MACRO, R) MACRO(KAGUYA_PP_WHILE62(MACRO, R)) +#define KAGUYA_PP_WHILE64(MACRO, R) MACRO(KAGUYA_PP_WHILE63(MACRO, R)) +#define KAGUYA_PP_WHILE65(MACRO, R) MACRO(KAGUYA_PP_WHILE64(MACRO, R)) +#define KAGUYA_PP_WHILE66(MACRO, R) MACRO(KAGUYA_PP_WHILE65(MACRO, R)) +#define KAGUYA_PP_WHILE67(MACRO, R) MACRO(KAGUYA_PP_WHILE66(MACRO, R)) +#define KAGUYA_PP_WHILE68(MACRO, R) MACRO(KAGUYA_PP_WHILE67(MACRO, R)) +#define KAGUYA_PP_WHILE69(MACRO, R) MACRO(KAGUYA_PP_WHILE68(MACRO, R)) +#define KAGUYA_PP_WHILE70(MACRO, R) MACRO(KAGUYA_PP_WHILE69(MACRO, R)) +#define KAGUYA_PP_WHILE71(MACRO, R) MACRO(KAGUYA_PP_WHILE70(MACRO, R)) +#define KAGUYA_PP_WHILE72(MACRO, R) MACRO(KAGUYA_PP_WHILE71(MACRO, R)) +#define KAGUYA_PP_WHILE73(MACRO, R) MACRO(KAGUYA_PP_WHILE72(MACRO, R)) +#define KAGUYA_PP_WHILE74(MACRO, R) MACRO(KAGUYA_PP_WHILE73(MACRO, R)) +#define KAGUYA_PP_WHILE75(MACRO, R) MACRO(KAGUYA_PP_WHILE74(MACRO, R)) +#define KAGUYA_PP_WHILE76(MACRO, R) MACRO(KAGUYA_PP_WHILE75(MACRO, R)) +#define KAGUYA_PP_WHILE77(MACRO, R) MACRO(KAGUYA_PP_WHILE76(MACRO, R)) +#define KAGUYA_PP_WHILE78(MACRO, R) MACRO(KAGUYA_PP_WHILE77(MACRO, R)) +#define KAGUYA_PP_WHILE79(MACRO, R) MACRO(KAGUYA_PP_WHILE78(MACRO, R)) +#define KAGUYA_PP_WHILE80(MACRO, R) MACRO(KAGUYA_PP_WHILE79(MACRO, R)) +#define KAGUYA_PP_WHILE81(MACRO, R) MACRO(KAGUYA_PP_WHILE80(MACRO, R)) +#define KAGUYA_PP_WHILE82(MACRO, R) MACRO(KAGUYA_PP_WHILE81(MACRO, R)) +#define KAGUYA_PP_WHILE83(MACRO, R) MACRO(KAGUYA_PP_WHILE82(MACRO, R)) +#define KAGUYA_PP_WHILE84(MACRO, R) MACRO(KAGUYA_PP_WHILE83(MACRO, R)) +#define KAGUYA_PP_WHILE85(MACRO, R) MACRO(KAGUYA_PP_WHILE84(MACRO, R)) +#define KAGUYA_PP_WHILE86(MACRO, R) MACRO(KAGUYA_PP_WHILE85(MACRO, R)) +#define KAGUYA_PP_WHILE87(MACRO, R) MACRO(KAGUYA_PP_WHILE86(MACRO, R)) +#define KAGUYA_PP_WHILE88(MACRO, R) MACRO(KAGUYA_PP_WHILE87(MACRO, R)) +#define KAGUYA_PP_WHILE89(MACRO, R) MACRO(KAGUYA_PP_WHILE88(MACRO, R)) +#define KAGUYA_PP_WHILE90(MACRO, R) MACRO(KAGUYA_PP_WHILE89(MACRO, R)) +#define KAGUYA_PP_WHILE91(MACRO, R) MACRO(KAGUYA_PP_WHILE90(MACRO, R)) +#define KAGUYA_PP_WHILE92(MACRO, R) MACRO(KAGUYA_PP_WHILE91(MACRO, R)) +#define KAGUYA_PP_WHILE93(MACRO, R) MACRO(KAGUYA_PP_WHILE92(MACRO, R)) +#define KAGUYA_PP_WHILE94(MACRO, R) MACRO(KAGUYA_PP_WHILE93(MACRO, R)) +#define KAGUYA_PP_WHILE95(MACRO, R) MACRO(KAGUYA_PP_WHILE94(MACRO, R)) +#define KAGUYA_PP_WHILE96(MACRO, R) MACRO(KAGUYA_PP_WHILE95(MACRO, R)) +#define KAGUYA_PP_WHILE97(MACRO, R) MACRO(KAGUYA_PP_WHILE96(MACRO, R)) +#define KAGUYA_PP_WHILE98(MACRO, R) MACRO(KAGUYA_PP_WHILE97(MACRO, R)) +#define KAGUYA_PP_WHILE99(MACRO, R) MACRO(KAGUYA_PP_WHILE98(MACRO, R)) +#define KAGUYA_PP_WHILE100(MACRO, R) MACRO(KAGUYA_PP_WHILE99(MACRO, R)) +#define KAGUYA_PP_WHILE101(MACRO, R) MACRO(KAGUYA_PP_WHILE100(MACRO, R)) +#define KAGUYA_PP_WHILE102(MACRO, R) MACRO(KAGUYA_PP_WHILE101(MACRO, R)) +#define KAGUYA_PP_WHILE103(MACRO, R) MACRO(KAGUYA_PP_WHILE102(MACRO, R)) +#define KAGUYA_PP_WHILE104(MACRO, R) MACRO(KAGUYA_PP_WHILE103(MACRO, R)) +#define KAGUYA_PP_WHILE105(MACRO, R) MACRO(KAGUYA_PP_WHILE104(MACRO, R)) +#define KAGUYA_PP_WHILE106(MACRO, R) MACRO(KAGUYA_PP_WHILE105(MACRO, R)) +#define KAGUYA_PP_WHILE107(MACRO, R) MACRO(KAGUYA_PP_WHILE106(MACRO, R)) +#define KAGUYA_PP_WHILE108(MACRO, R) MACRO(KAGUYA_PP_WHILE107(MACRO, R)) +#define KAGUYA_PP_WHILE109(MACRO, R) MACRO(KAGUYA_PP_WHILE108(MACRO, R)) +#define KAGUYA_PP_WHILE110(MACRO, R) MACRO(KAGUYA_PP_WHILE109(MACRO, R)) +#define KAGUYA_PP_WHILE111(MACRO, R) MACRO(KAGUYA_PP_WHILE110(MACRO, R)) +#define KAGUYA_PP_WHILE112(MACRO, R) MACRO(KAGUYA_PP_WHILE111(MACRO, R)) +#define KAGUYA_PP_WHILE113(MACRO, R) MACRO(KAGUYA_PP_WHILE112(MACRO, R)) +#define KAGUYA_PP_WHILE114(MACRO, R) MACRO(KAGUYA_PP_WHILE113(MACRO, R)) +#define KAGUYA_PP_WHILE115(MACRO, R) MACRO(KAGUYA_PP_WHILE114(MACRO, R)) +#define KAGUYA_PP_WHILE116(MACRO, R) MACRO(KAGUYA_PP_WHILE115(MACRO, R)) +#define KAGUYA_PP_WHILE117(MACRO, R) MACRO(KAGUYA_PP_WHILE116(MACRO, R)) +#define KAGUYA_PP_WHILE118(MACRO, R) MACRO(KAGUYA_PP_WHILE117(MACRO, R)) +#define KAGUYA_PP_WHILE119(MACRO, R) MACRO(KAGUYA_PP_WHILE118(MACRO, R)) +#define KAGUYA_PP_WHILE120(MACRO, R) MACRO(KAGUYA_PP_WHILE119(MACRO, R)) +#define KAGUYA_PP_WHILE121(MACRO, R) MACRO(KAGUYA_PP_WHILE120(MACRO, R)) +#define KAGUYA_PP_WHILE122(MACRO, R) MACRO(KAGUYA_PP_WHILE121(MACRO, R)) +#define KAGUYA_PP_WHILE123(MACRO, R) MACRO(KAGUYA_PP_WHILE122(MACRO, R)) +#define KAGUYA_PP_WHILE124(MACRO, R) MACRO(KAGUYA_PP_WHILE123(MACRO, R)) +#define KAGUYA_PP_WHILE125(MACRO, R) MACRO(KAGUYA_PP_WHILE124(MACRO, R)) +#define KAGUYA_PP_WHILE126(MACRO, R) MACRO(KAGUYA_PP_WHILE125(MACRO, R)) +#define KAGUYA_PP_WHILE127(MACRO, R) MACRO(KAGUYA_PP_WHILE126(MACRO, R)) +#define KAGUYA_PP_WHILE128(MACRO, R) MACRO(KAGUYA_PP_WHILE127(MACRO, R)) +#define KAGUYA_PP_WHILE129(MACRO, R) MACRO(KAGUYA_PP_WHILE128(MACRO, R)) +#define KAGUYA_PP_WHILE130(MACRO, R) MACRO(KAGUYA_PP_WHILE129(MACRO, R)) +#define KAGUYA_PP_WHILE131(MACRO, R) MACRO(KAGUYA_PP_WHILE130(MACRO, R)) +#define KAGUYA_PP_WHILE132(MACRO, R) MACRO(KAGUYA_PP_WHILE131(MACRO, R)) +#define KAGUYA_PP_WHILE133(MACRO, R) MACRO(KAGUYA_PP_WHILE132(MACRO, R)) +#define KAGUYA_PP_WHILE134(MACRO, R) MACRO(KAGUYA_PP_WHILE133(MACRO, R)) +#define KAGUYA_PP_WHILE135(MACRO, R) MACRO(KAGUYA_PP_WHILE134(MACRO, R)) +#define KAGUYA_PP_WHILE136(MACRO, R) MACRO(KAGUYA_PP_WHILE135(MACRO, R)) +#define KAGUYA_PP_WHILE137(MACRO, R) MACRO(KAGUYA_PP_WHILE136(MACRO, R)) +#define KAGUYA_PP_WHILE138(MACRO, R) MACRO(KAGUYA_PP_WHILE137(MACRO, R)) +#define KAGUYA_PP_WHILE139(MACRO, R) MACRO(KAGUYA_PP_WHILE138(MACRO, R)) +#define KAGUYA_PP_WHILE140(MACRO, R) MACRO(KAGUYA_PP_WHILE139(MACRO, R)) +#define KAGUYA_PP_WHILE141(MACRO, R) MACRO(KAGUYA_PP_WHILE140(MACRO, R)) +#define KAGUYA_PP_WHILE142(MACRO, R) MACRO(KAGUYA_PP_WHILE141(MACRO, R)) +#define KAGUYA_PP_WHILE143(MACRO, R) MACRO(KAGUYA_PP_WHILE142(MACRO, R)) +#define KAGUYA_PP_WHILE144(MACRO, R) MACRO(KAGUYA_PP_WHILE143(MACRO, R)) +#define KAGUYA_PP_WHILE145(MACRO, R) MACRO(KAGUYA_PP_WHILE144(MACRO, R)) +#define KAGUYA_PP_WHILE146(MACRO, R) MACRO(KAGUYA_PP_WHILE145(MACRO, R)) +#define KAGUYA_PP_WHILE147(MACRO, R) MACRO(KAGUYA_PP_WHILE146(MACRO, R)) +#define KAGUYA_PP_WHILE148(MACRO, R) MACRO(KAGUYA_PP_WHILE147(MACRO, R)) +#define KAGUYA_PP_WHILE149(MACRO, R) MACRO(KAGUYA_PP_WHILE148(MACRO, R)) +#define KAGUYA_PP_WHILE150(MACRO, R) MACRO(KAGUYA_PP_WHILE149(MACRO, R)) +#define KAGUYA_PP_WHILE151(MACRO, R) MACRO(KAGUYA_PP_WHILE150(MACRO, R)) +#define KAGUYA_PP_WHILE152(MACRO, R) MACRO(KAGUYA_PP_WHILE151(MACRO, R)) +#define KAGUYA_PP_WHILE153(MACRO, R) MACRO(KAGUYA_PP_WHILE152(MACRO, R)) +#define KAGUYA_PP_WHILE154(MACRO, R) MACRO(KAGUYA_PP_WHILE153(MACRO, R)) +#define KAGUYA_PP_WHILE155(MACRO, R) MACRO(KAGUYA_PP_WHILE154(MACRO, R)) +#define KAGUYA_PP_WHILE156(MACRO, R) MACRO(KAGUYA_PP_WHILE155(MACRO, R)) +#define KAGUYA_PP_WHILE157(MACRO, R) MACRO(KAGUYA_PP_WHILE156(MACRO, R)) +#define KAGUYA_PP_WHILE158(MACRO, R) MACRO(KAGUYA_PP_WHILE157(MACRO, R)) +#define KAGUYA_PP_WHILE159(MACRO, R) MACRO(KAGUYA_PP_WHILE158(MACRO, R)) +#define KAGUYA_PP_WHILE160(MACRO, R) MACRO(KAGUYA_PP_WHILE159(MACRO, R)) +#define KAGUYA_PP_WHILE161(MACRO, R) MACRO(KAGUYA_PP_WHILE160(MACRO, R)) +#define KAGUYA_PP_WHILE162(MACRO, R) MACRO(KAGUYA_PP_WHILE161(MACRO, R)) +#define KAGUYA_PP_WHILE163(MACRO, R) MACRO(KAGUYA_PP_WHILE162(MACRO, R)) +#define KAGUYA_PP_WHILE164(MACRO, R) MACRO(KAGUYA_PP_WHILE163(MACRO, R)) +#define KAGUYA_PP_WHILE165(MACRO, R) MACRO(KAGUYA_PP_WHILE164(MACRO, R)) +#define KAGUYA_PP_WHILE166(MACRO, R) MACRO(KAGUYA_PP_WHILE165(MACRO, R)) +#define KAGUYA_PP_WHILE167(MACRO, R) MACRO(KAGUYA_PP_WHILE166(MACRO, R)) +#define KAGUYA_PP_WHILE168(MACRO, R) MACRO(KAGUYA_PP_WHILE167(MACRO, R)) +#define KAGUYA_PP_WHILE169(MACRO, R) MACRO(KAGUYA_PP_WHILE168(MACRO, R)) +#define KAGUYA_PP_WHILE170(MACRO, R) MACRO(KAGUYA_PP_WHILE169(MACRO, R)) +#define KAGUYA_PP_WHILE171(MACRO, R) MACRO(KAGUYA_PP_WHILE170(MACRO, R)) +#define KAGUYA_PP_WHILE172(MACRO, R) MACRO(KAGUYA_PP_WHILE171(MACRO, R)) +#define KAGUYA_PP_WHILE173(MACRO, R) MACRO(KAGUYA_PP_WHILE172(MACRO, R)) +#define KAGUYA_PP_WHILE174(MACRO, R) MACRO(KAGUYA_PP_WHILE173(MACRO, R)) +#define KAGUYA_PP_WHILE175(MACRO, R) MACRO(KAGUYA_PP_WHILE174(MACRO, R)) +#define KAGUYA_PP_WHILE176(MACRO, R) MACRO(KAGUYA_PP_WHILE175(MACRO, R)) +#define KAGUYA_PP_WHILE177(MACRO, R) MACRO(KAGUYA_PP_WHILE176(MACRO, R)) +#define KAGUYA_PP_WHILE178(MACRO, R) MACRO(KAGUYA_PP_WHILE177(MACRO, R)) +#define KAGUYA_PP_WHILE179(MACRO, R) MACRO(KAGUYA_PP_WHILE178(MACRO, R)) +#define KAGUYA_PP_WHILE180(MACRO, R) MACRO(KAGUYA_PP_WHILE179(MACRO, R)) +#define KAGUYA_PP_WHILE181(MACRO, R) MACRO(KAGUYA_PP_WHILE180(MACRO, R)) +#define KAGUYA_PP_WHILE182(MACRO, R) MACRO(KAGUYA_PP_WHILE181(MACRO, R)) +#define KAGUYA_PP_WHILE183(MACRO, R) MACRO(KAGUYA_PP_WHILE182(MACRO, R)) +#define KAGUYA_PP_WHILE184(MACRO, R) MACRO(KAGUYA_PP_WHILE183(MACRO, R)) +#define KAGUYA_PP_WHILE185(MACRO, R) MACRO(KAGUYA_PP_WHILE184(MACRO, R)) +#define KAGUYA_PP_WHILE186(MACRO, R) MACRO(KAGUYA_PP_WHILE185(MACRO, R)) +#define KAGUYA_PP_WHILE187(MACRO, R) MACRO(KAGUYA_PP_WHILE186(MACRO, R)) +#define KAGUYA_PP_WHILE188(MACRO, R) MACRO(KAGUYA_PP_WHILE187(MACRO, R)) +#define KAGUYA_PP_WHILE189(MACRO, R) MACRO(KAGUYA_PP_WHILE188(MACRO, R)) +#define KAGUYA_PP_WHILE190(MACRO, R) MACRO(KAGUYA_PP_WHILE189(MACRO, R)) +#define KAGUYA_PP_WHILE191(MACRO, R) MACRO(KAGUYA_PP_WHILE190(MACRO, R)) +#define KAGUYA_PP_WHILE192(MACRO, R) MACRO(KAGUYA_PP_WHILE191(MACRO, R)) +#define KAGUYA_PP_WHILE193(MACRO, R) MACRO(KAGUYA_PP_WHILE192(MACRO, R)) +#define KAGUYA_PP_WHILE194(MACRO, R) MACRO(KAGUYA_PP_WHILE193(MACRO, R)) +#define KAGUYA_PP_WHILE195(MACRO, R) MACRO(KAGUYA_PP_WHILE194(MACRO, R)) +#define KAGUYA_PP_WHILE196(MACRO, R) MACRO(KAGUYA_PP_WHILE195(MACRO, R)) +#define KAGUYA_PP_WHILE197(MACRO, R) MACRO(KAGUYA_PP_WHILE196(MACRO, R)) +#define KAGUYA_PP_WHILE198(MACRO, R) MACRO(KAGUYA_PP_WHILE197(MACRO, R)) +#define KAGUYA_PP_WHILE199(MACRO, R) MACRO(KAGUYA_PP_WHILE198(MACRO, R)) +#define KAGUYA_PP_WHILE200(MACRO, R) MACRO(KAGUYA_PP_WHILE199(MACRO, R)) +#define KAGUYA_PP_WHILE201(MACRO, R) MACRO(KAGUYA_PP_WHILE200(MACRO, R)) +#define KAGUYA_PP_WHILE202(MACRO, R) MACRO(KAGUYA_PP_WHILE201(MACRO, R)) +#define KAGUYA_PP_WHILE203(MACRO, R) MACRO(KAGUYA_PP_WHILE202(MACRO, R)) +#define KAGUYA_PP_WHILE204(MACRO, R) MACRO(KAGUYA_PP_WHILE203(MACRO, R)) +#define KAGUYA_PP_WHILE205(MACRO, R) MACRO(KAGUYA_PP_WHILE204(MACRO, R)) +#define KAGUYA_PP_WHILE206(MACRO, R) MACRO(KAGUYA_PP_WHILE205(MACRO, R)) +#define KAGUYA_PP_WHILE207(MACRO, R) MACRO(KAGUYA_PP_WHILE206(MACRO, R)) +#define KAGUYA_PP_WHILE208(MACRO, R) MACRO(KAGUYA_PP_WHILE207(MACRO, R)) +#define KAGUYA_PP_WHILE209(MACRO, R) MACRO(KAGUYA_PP_WHILE208(MACRO, R)) +#define KAGUYA_PP_WHILE210(MACRO, R) MACRO(KAGUYA_PP_WHILE209(MACRO, R)) +#define KAGUYA_PP_WHILE211(MACRO, R) MACRO(KAGUYA_PP_WHILE210(MACRO, R)) +#define KAGUYA_PP_WHILE212(MACRO, R) MACRO(KAGUYA_PP_WHILE211(MACRO, R)) +#define KAGUYA_PP_WHILE213(MACRO, R) MACRO(KAGUYA_PP_WHILE212(MACRO, R)) +#define KAGUYA_PP_WHILE214(MACRO, R) MACRO(KAGUYA_PP_WHILE213(MACRO, R)) +#define KAGUYA_PP_WHILE215(MACRO, R) MACRO(KAGUYA_PP_WHILE214(MACRO, R)) +#define KAGUYA_PP_WHILE216(MACRO, R) MACRO(KAGUYA_PP_WHILE215(MACRO, R)) +#define KAGUYA_PP_WHILE217(MACRO, R) MACRO(KAGUYA_PP_WHILE216(MACRO, R)) +#define KAGUYA_PP_WHILE218(MACRO, R) MACRO(KAGUYA_PP_WHILE217(MACRO, R)) +#define KAGUYA_PP_WHILE219(MACRO, R) MACRO(KAGUYA_PP_WHILE218(MACRO, R)) +#define KAGUYA_PP_WHILE220(MACRO, R) MACRO(KAGUYA_PP_WHILE219(MACRO, R)) +#define KAGUYA_PP_WHILE221(MACRO, R) MACRO(KAGUYA_PP_WHILE220(MACRO, R)) +#define KAGUYA_PP_WHILE222(MACRO, R) MACRO(KAGUYA_PP_WHILE221(MACRO, R)) +#define KAGUYA_PP_WHILE223(MACRO, R) MACRO(KAGUYA_PP_WHILE222(MACRO, R)) +#define KAGUYA_PP_WHILE224(MACRO, R) MACRO(KAGUYA_PP_WHILE223(MACRO, R)) +#define KAGUYA_PP_WHILE225(MACRO, R) MACRO(KAGUYA_PP_WHILE224(MACRO, R)) +#define KAGUYA_PP_WHILE226(MACRO, R) MACRO(KAGUYA_PP_WHILE225(MACRO, R)) +#define KAGUYA_PP_WHILE227(MACRO, R) MACRO(KAGUYA_PP_WHILE226(MACRO, R)) +#define KAGUYA_PP_WHILE228(MACRO, R) MACRO(KAGUYA_PP_WHILE227(MACRO, R)) +#define KAGUYA_PP_WHILE229(MACRO, R) MACRO(KAGUYA_PP_WHILE228(MACRO, R)) +#define KAGUYA_PP_WHILE230(MACRO, R) MACRO(KAGUYA_PP_WHILE229(MACRO, R)) +#define KAGUYA_PP_WHILE231(MACRO, R) MACRO(KAGUYA_PP_WHILE230(MACRO, R)) +#define KAGUYA_PP_WHILE232(MACRO, R) MACRO(KAGUYA_PP_WHILE231(MACRO, R)) +#define KAGUYA_PP_WHILE233(MACRO, R) MACRO(KAGUYA_PP_WHILE232(MACRO, R)) +#define KAGUYA_PP_WHILE234(MACRO, R) MACRO(KAGUYA_PP_WHILE233(MACRO, R)) +#define KAGUYA_PP_WHILE235(MACRO, R) MACRO(KAGUYA_PP_WHILE234(MACRO, R)) +#define KAGUYA_PP_WHILE236(MACRO, R) MACRO(KAGUYA_PP_WHILE235(MACRO, R)) +#define KAGUYA_PP_WHILE237(MACRO, R) MACRO(KAGUYA_PP_WHILE236(MACRO, R)) +#define KAGUYA_PP_WHILE238(MACRO, R) MACRO(KAGUYA_PP_WHILE237(MACRO, R)) +#define KAGUYA_PP_WHILE239(MACRO, R) MACRO(KAGUYA_PP_WHILE238(MACRO, R)) +#define KAGUYA_PP_WHILE240(MACRO, R) MACRO(KAGUYA_PP_WHILE239(MACRO, R)) +#define KAGUYA_PP_WHILE241(MACRO, R) MACRO(KAGUYA_PP_WHILE240(MACRO, R)) +#define KAGUYA_PP_WHILE242(MACRO, R) MACRO(KAGUYA_PP_WHILE241(MACRO, R)) +#define KAGUYA_PP_WHILE243(MACRO, R) MACRO(KAGUYA_PP_WHILE242(MACRO, R)) +#define KAGUYA_PP_WHILE244(MACRO, R) MACRO(KAGUYA_PP_WHILE243(MACRO, R)) +#define KAGUYA_PP_WHILE245(MACRO, R) MACRO(KAGUYA_PP_WHILE244(MACRO, R)) +#define KAGUYA_PP_WHILE246(MACRO, R) MACRO(KAGUYA_PP_WHILE245(MACRO, R)) +#define KAGUYA_PP_WHILE247(MACRO, R) MACRO(KAGUYA_PP_WHILE246(MACRO, R)) +#define KAGUYA_PP_WHILE248(MACRO, R) MACRO(KAGUYA_PP_WHILE247(MACRO, R)) +#define KAGUYA_PP_WHILE249(MACRO, R) MACRO(KAGUYA_PP_WHILE248(MACRO, R)) +#define KAGUYA_PP_WHILE250(MACRO, R) MACRO(KAGUYA_PP_WHILE249(MACRO, R)) +#define KAGUYA_PP_WHILE251(MACRO, R) MACRO(KAGUYA_PP_WHILE250(MACRO, R)) +#define KAGUYA_PP_WHILE252(MACRO, R) MACRO(KAGUYA_PP_WHILE251(MACRO, R)) +#define KAGUYA_PP_WHILE253(MACRO, R) MACRO(KAGUYA_PP_WHILE252(MACRO, R)) +#define KAGUYA_PP_WHILE254(MACRO, R) MACRO(KAGUYA_PP_WHILE253(MACRO, R)) +#define KAGUYA_PP_WHILE(COUNT, R, MACRO) \ + KAGUYA_PP_CAT(KAGUYA_PP_WHILE, COUNT)(MACRO, R) #define KAGUYA_PP_INC0 1 #define KAGUYA_PP_INC1 2 @@ -1803,8 +2721,7 @@ #define KAGUYA_PP_INC252 253 #define KAGUYA_PP_INC253 254 #define KAGUYA_PP_INC254 255 -#define KAGUYA_PP_INC(N) KAGUYA_PP_CAT(KAGUYA_PP_INC,N) - +#define KAGUYA_PP_INC(N) KAGUYA_PP_CAT(KAGUYA_PP_INC, N) #define KAGUYA_PP_DEC1 0 #define KAGUYA_PP_DEC2 1 @@ -2060,4 +2977,4 @@ #define KAGUYA_PP_DEC252 251 #define KAGUYA_PP_DEC253 252 #define KAGUYA_PP_DEC254 253 -#define KAGUYA_PP_DEC(N) KAGUYA_PP_CAT(KAGUYA_PP_DEC,N) +#define KAGUYA_PP_DEC(N) KAGUYA_PP_CAT(KAGUYA_PP_DEC, N) diff --git a/include/kaguya/push_any.hpp b/include/kaguya/push_any.hpp index 9f586e8..4793b3a 100644 --- a/include/kaguya/push_any.hpp +++ b/include/kaguya/push_any.hpp @@ -9,92 +9,83 @@ #include "kaguya/traits.hpp" #include "kaguya/utility.hpp" -namespace kaguya -{ - /// @brief any data holder class for push to lua - class AnyDataPusher - { - public: - int pushToLua(lua_State* state)const - { - if (empty()) - { - lua_pushnil(state); - return 1; - } - else - { - return holder_->pushToLua(state); - } - } +namespace kaguya { +/// @brief any data holder class for push to lua +class AnyDataPusher { +public: + int pushToLua(lua_State *state) const { + if (empty()) { + lua_pushnil(state); + return 1; + } else { + return holder_->pushToLua(state); + } + } - AnyDataPusher() : holder_() { } + AnyDataPusher() : holder_() {} - template < typename DataType > - AnyDataPusher(const DataType& v) - : holder_(new DataHolder(v)) { } + template + AnyDataPusher(const DataType &v) : holder_(new DataHolder(v)) {} #if KAGUYA_USE_CPP11 - AnyDataPusher(AnyDataPusher&& other) : holder_(std::move(other.holder_)) { } - AnyDataPusher & operator = (AnyDataPusher&& rhs) - { - holder_ = std::move(rhs.holder_); - return *this; - } - template < typename DataType > - AnyDataPusher(DataType&& v) - : holder_(new DataHolder(std::move(v))) { } + AnyDataPusher(AnyDataPusher &&other) : holder_(std::move(other.holder_)) {} + AnyDataPusher &operator=(AnyDataPusher &&rhs) { + holder_ = std::move(rhs.holder_); + return *this; + } + template + AnyDataPusher(DataType &&v) + : holder_(new DataHolder(std::move(v))) {} #endif - AnyDataPusher(const AnyDataPusher& other) - : holder_(other.holder_) { } - AnyDataPusher& operator = (const AnyDataPusher& other) - { - holder_ = other.holder_; - return *this; - } + AnyDataPusher(const AnyDataPusher &other) : holder_(other.holder_) {} + AnyDataPusher &operator=(const AnyDataPusher &other) { + holder_ = other.holder_; + return *this; + } - bool empty()const { return !holder_.get(); } - private: - struct DataHolderBase - { - virtual int pushToLua(lua_State* data)const = 0; - // virtual DataHolderBase * clone(void) = 0; - virtual ~DataHolderBase() {} - }; - template < typename Type > - class DataHolder : public DataHolderBase - { - typedef typename traits::decay::type DataType; - public: + bool empty() const { return !holder_.get(); } + +private: + struct DataHolderBase { + virtual int pushToLua(lua_State *data) const = 0; + // virtual DataHolderBase * clone(void) = 0; + virtual ~DataHolderBase() {} + }; + template class DataHolder : public DataHolderBase { + typedef typename traits::decay::type DataType; + + public: #if KAGUYA_USE_CPP11 - explicit DataHolder(DataType&& v) : data_(std::forward(v)) { } + explicit DataHolder(DataType &&v) : data_(std::forward(v)) {} #else - explicit DataHolder(const DataType& v) : data_(v){ } + explicit DataHolder(const DataType &v) : data_(v) {} #endif - virtual int pushToLua(lua_State* state)const - { - return util::push_args(state, data_); - } - private: - DataType data_; - }; - //specialize for string literal - template struct DataHolder :DataHolder { - explicit DataHolder(const char* v) : DataHolder(std::string(v, v[N - 1] != '\0' ? v + N : v + N - 1)) {} - }; - template struct DataHolder :DataHolder { - explicit DataHolder(const char* v) : DataHolder(std::string(v, v[N - 1] != '\0' ? v + N : v + N - 1)) {} - }; - standard::shared_ptr holder_; - }; + virtual int pushToLua(lua_State *state) const { + return util::push_args(state, data_); + } + private: + DataType data_; + }; + // specialize for string literal + template struct DataHolder : DataHolder { + explicit DataHolder(const char *v) + : DataHolder( + std::string(v, v[N - 1] != '\0' ? v + N : v + N - 1)) {} + }; + template struct DataHolder : DataHolder { + explicit DataHolder(const char *v) + : DataHolder( + std::string(v, v[N - 1] != '\0' ? v + N : v + N - 1)) {} + }; + standard::shared_ptr holder_; +}; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for AnyDataPusher - template<> struct lua_type_traits { - static int push(lua_State* l, const AnyDataPusher& data) - { - return data.pushToLua(l); - } - }; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for AnyDataPusher +template <> struct lua_type_traits { + static int push(lua_State *l, const AnyDataPusher &data) { + return data.pushToLua(l); + } +}; } diff --git a/include/kaguya/push_tuple.hpp b/include/kaguya/push_tuple.hpp index 6279168..2e0f1f1 100644 --- a/include/kaguya/push_tuple.hpp +++ b/include/kaguya/push_tuple.hpp @@ -8,53 +8,46 @@ #include "kaguya/config.hpp" #include "kaguya/traits.hpp" -namespace kaguya -{ +namespace kaguya { #if KAGUYA_USE_CPP11 - namespace detail - { - templatestruct index_tuple {}; - template, bool flag = first >= last> - struct index_range - { - using type = result; - }; - template - struct index_range, false> - : index_range> - {}; +namespace detail { +template struct index_tuple {}; +template , + bool flag = first >= last> +struct index_range { + using type = result; +}; +template +struct index_range, false> + : index_range > {}; - template - int push_tuple(lua_State* l, index_tuple , std::tuple&& v) - { - return util::push_args(l, std::get(v)...); - } - } +template +int push_tuple(lua_State *l, index_tuple, std::tuple &&v) { + return util::push_args(l, std::get(v)...); +} +} - /// @ingroup lua_type_traits - /// @brief lua_type_traits for std::tuple or boost::tuple - template - struct lua_type_traits > - { - static int push(lua_State* l, std::tuple&& v) - { - typename detail::index_range<0, sizeof...(Args)>::type index; - return detail::push_tuple(l, index, std::forward< std::tuple >(v)); - } - }; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for std::tuple or boost::tuple +template struct lua_type_traits > { + static int push(lua_State *l, std::tuple &&v) { + typename detail::index_range<0, sizeof...(Args)>::type index; + return detail::push_tuple(l, index, std::forward >(v)); + } +}; #else -#define KAGUYA_PP_GET_DATA(N) standard::get(v) -#define KAGUYA_PUSH_TUPLE_DEF(N) template\ - struct lua_type_traits >\ - {\ - static int push(lua_State* l, const standard::tuple& v)\ - {\ - return util::push_args(l, KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_GET_DATA));\ - }\ - }; - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_TUPLE_SIZE, KAGUYA_PUSH_TUPLE_DEF) +#define KAGUYA_PP_GET_DATA(N) standard::get(v) +#define KAGUYA_PUSH_TUPLE_DEF(N) \ + template \ + struct lua_type_traits > { \ + static int \ + push(lua_State *l, \ + const standard::tuple &v) { \ + return util::push_args(l, KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_GET_DATA)); \ + } \ + }; +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_TUPLE_SIZE, KAGUYA_PUSH_TUPLE_DEF) #undef KAGUYA_PP_GET_DATA #undef KAGUYA_PUSH_TUPLE_DEF #endif } - diff --git a/include/kaguya/ref_tuple.hpp b/include/kaguya/ref_tuple.hpp index 6620d45..192673c 100644 --- a/include/kaguya/ref_tuple.hpp +++ b/include/kaguya/ref_tuple.hpp @@ -7,45 +7,40 @@ #include "kaguya/config.hpp" -namespace kaguya -{ +namespace kaguya { - template - struct ref_tuple - { - RefTuple tref; - ref_tuple(const RefTuple& va) :tref(va) {} - void operator=(const FunctionResults& fres) - { - tref = fres.get_result(types::typetag()); - } - template - void operator=(const T& fres) - { - tref = fres; - } - }; +template struct ref_tuple { + RefTuple tref; + ref_tuple(const RefTuple &va) : tref(va) {} + void operator=(const FunctionResults &fres) { + tref = fres.get_result(types::typetag()); + } + template void operator=(const T &fres) { tref = fres; } +}; #if KAGUYA_USE_CPP11 - template - ref_tuple, standard::tuple> tie(Args&... va) - { - typedef standard::tuple RefTuple; - typedef standard::tuple GetTuple; - return ref_tuple(RefTuple(va...)); - } +template +ref_tuple, standard::tuple > +tie(Args &... va) { + typedef standard::tuple RefTuple; + typedef standard::tuple GetTuple; + return ref_tuple(RefTuple(va...)); +} #else -#define KAGUYA_VARIADIC_REFARG_REP(N) KAGUYA_PP_CAT(A,N)& KAGUYA_PP_CAT(a,N) -#define KAGUYA_VARIADIC_TREFARG_REP(N) KAGUYA_PP_CAT(A,N)& -#define KAGUYA_TEMPLATE_REFARG_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N, KAGUYA_VARIADIC_TREFARG_REP) +#define KAGUYA_VARIADIC_REFARG_REP(N) KAGUYA_PP_CAT(A, N) & KAGUYA_PP_CAT(a, N) +#define KAGUYA_VARIADIC_TREFARG_REP(N) KAGUYA_PP_CAT(A, N) & +#define KAGUYA_TEMPLATE_REFARG_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_VARIADIC_TREFARG_REP) #define KAGUYA_REF_TUPLE(N) standard::tuple #define KAGUYA_GET_TUPLE(N) standard::tuple -#define KAGUYA_REF_TUPLE_DEF(N) template\ - ref_tuple tie(KAGUYA_PP_REPEAT_ARG(N, KAGUYA_VARIADIC_REFARG_REP))\ - {\ - return ref_tuple(KAGUYA_REF_TUPLE(N)(KAGUYA_PP_ARG_REPEAT(N)));\ - } +#define KAGUYA_REF_TUPLE_DEF(N) \ + template \ + ref_tuple tie( \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_VARIADIC_REFARG_REP)) { \ + return ref_tuple( \ + KAGUYA_REF_TUPLE(N)(KAGUYA_PP_ARG_REPEAT(N))); \ + } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_TUPLE_SIZE, KAGUYA_REF_TUPLE_DEF) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_TUPLE_SIZE, KAGUYA_REF_TUPLE_DEF) #undef KAGUYA_VARIADIC_REFARG_REP #undef KAGUYA_TEMPLATE_REFARG_REPEAT #undef KAGUYA_REF_TUPLE diff --git a/include/kaguya/state.hpp b/include/kaguya/state.hpp index fe6ff33..d4aff2f 100644 --- a/include/kaguya/state.hpp +++ b/include/kaguya/state.hpp @@ -17,589 +17,486 @@ #include "kaguya/lua_ref_table.hpp" #include "kaguya/lua_ref_function.hpp" -namespace kaguya -{ - /// @addtogroup State - /// @{ - - /// @brief Load library info type @see State::openlibs @see State::State(const LoadLibs &libs) - typedef std::pair LoadLib; - - /// @brief Load libraries info @see State::openlibs @see State::State(const LoadLibs &libs) - typedef std::vector LoadLibs; - - /// @brief return no load library type @see State::State(const LoadLibs &libs) - inline LoadLibs NoLoadLib() { return LoadLibs(); } - - /// @brief All load standard libraries type @see State::openlibs - struct AllLoadLibs {}; - - template - void * AllocatorFunction(void *ud, - void *ptr, - size_t osize, - size_t nsize) - { - Allocator* allocator = static_cast(ud); - if (nsize == 0) - { - allocator->deallocate(ptr, osize); - } - else if (ptr) - { - return allocator->reallocate(ptr, nsize); - } - else - { - return allocator->allocate(nsize); - } - return 0; - } - - struct DefaultAllocator - { - typedef void* pointer; - typedef size_t size_type; - pointer allocate(size_type n) - { - return std::malloc(n); - } - pointer reallocate(pointer p, size_type n) - { - return std::realloc(p,n); - } - void deallocate(pointer p, size_type n) - { - KAGUYA_UNUSED(n); - std::free(p); - } - }; - - /// lua_State wrap class - class State - { - standard::shared_ptr allocator_holder_; - lua_State *state_; - bool created_; - - //non copyable - State(const State&); - State& operator =(const State&); - - - - static int initializing_panic(lua_State *L) { - ErrorHandler::throwDefaultError(lua_status(L), lua_tostring(L, -1)); - return 0; // return to Lua to abort - } - static int default_panic(lua_State *L) { - if (ErrorHandler::handle(lua_status(L), L)) - { - return 0; - } - fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", lua_tostring(L, -1)); - fflush(stderr); - return 0; // return to Lua to abort - } - static void stderror_out(int status, const char* message) - { - KAGUYA_UNUSED(status); - std::cerr << message << std::endl; - } - - templatevoid init(const Libs& lib) - { - if (state_) - { - lua_atpanic(state_, &initializing_panic); - try - { - if (!ErrorHandler::getHandler(state_)) - { - setErrorHandler(&stderror_out); - } - openlibs(lib); - lua_atpanic(state_, &default_panic); - } - catch (const LuaException&) - { - lua_close(state_); state_ = 0; - } - } - } - - public: - - /// @brief create Lua state with lua standard library - State() :allocator_holder_(), state_(luaL_newstate()), created_(true) - { - init(AllLoadLibs()); - } - - /// @brief create Lua state with lua standard library. Can not use this constructor at luajit. error message is 'Must use luaL_newstate() for 64 bit target' - /// @param allocator allocator for memory allocation @see DefaultAllocator - template - State(standard::shared_ptr allocator) :allocator_holder_(allocator), state_(lua_newstate(&AllocatorFunction, allocator_holder_.get())), created_(true) - { - init(AllLoadLibs()); - } - - /// @brief create Lua state with (or without) libraries. - /// @param libs load libraries - /// e.g. LoadLibs libs;libs.push_back(LoadLib("libname",libfunction));State state(libs); - /// e.g. State state({{"libname",libfunction}}); for c++ 11 - State(const LoadLibs& libs) : allocator_holder_(), state_(luaL_newstate()), created_(true) - { - init(libs); - } - - /// @brief create Lua state with (or without) libraries. Can not use this constructor at luajit. error message is 'Must use luaL_newstate() for 64 bit target' - /// @param libs load libraries - /// @param allocator allocator for memory allocation @see DefaultAllocator - template - State(const LoadLibs& libs, standard::shared_ptr allocator) : allocator_holder_(allocator), state_(lua_newstate(&AllocatorFunction, allocator_holder_.get())), created_(true) - { - init(libs); - } - - /// @brief construct using created lua_State. - /// @param lua created lua_State. It is not call lua_close() in this class - State(lua_State* lua) :state_(lua), created_(false) - { - if (state_) - { - if (!ErrorHandler::getHandler(state_)) - { - setErrorHandler(&stderror_out); - } - } - } - ~State() - { - if (created_ && state_) - { - lua_close(state_); - } - } - - /// @brief set error handler for lua error. - void setErrorHandler(standard::function errorfunction) - { - if (!state_) { return; } - util::ScopedSavedStack save(state_); - ErrorHandler::registerHandler(state_, errorfunction); - } - - - /// @brief load all lua standard library - void openlibs(AllLoadLibs = AllLoadLibs()) - { - if (!state_) { return; } - luaL_openlibs(state_); - } - - /// @brief load lua library - LuaStackRef openlib(const LoadLib& lib) - { - if (!state_) { return LuaStackRef(); } - luaL_requiref(state_, lib.first.c_str(), lib.second, 1); - return LuaStackRef(state_, -1, true); - } - /// @brief load lua library - LuaStackRef openlib(std::string name, lua_CFunction f) - { - return openlib(LoadLib(name, f)); - } - - - - /// @brief load lua libraries - void openlibs(const LoadLibs& libs) - { - for (LoadLibs::const_iterator it = libs.begin(); it != libs.end(); ++it) - { - openlib(*it); - } - } - - /// @brief If there are no errors,compiled file as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param file file path of lua script - /// @return reference of lua function - LuaFunction loadfile(const std::string& file) - { - return LuaFunction::loadfile(state_, file); - } - /// @brief If there are no errors,compiled file as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param file file path of lua script - /// @return reference of lua function - LuaFunction loadfile(const char* file) - { - return LuaFunction::loadfile(state_, file); - } - - - /// @brief If there are no errors,compiled stream as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param stream stream of lua script - /// @param chunkname chunkname of lua script - /// @return reference of lua function - LuaFunction loadstream(std::istream& stream, const char* chunkname=0) - { - return LuaFunction::loadstream(state_, stream, chunkname); - } - /// @brief Loads and runs the given stream. - /// @param stream stream of lua script - /// @param chunkname chunkname of lua script - /// @param env execute env table - /// @return If there are no errors, returns true.Otherwise return false - bool dostream(std::istream& stream, const char* chunkname = 0, const LuaTable& env = LuaTable()) - { - util::ScopedSavedStack save(state_); - LuaStackRef f = LuaFunction::loadstreamtostack(state_,stream,chunkname); - if (!f) - {//load failed - return false; - } - if (!env.isNilref()) - { - f.setFunctionEnv(env); - } - - FunctionResults ret= f.call(); - return !ret.resultStatus(); - } - - /// @brief If there are no errors,compiled string as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param str lua code - /// @return reference of lua function - LuaFunction loadstring(const std::string& str) - { - return LuaFunction::loadstring(state_, str); - } - /// @brief If there are no errors,compiled string as a Lua function and return. - /// Otherwise send error message to error handler and return nil reference - /// @param str lua code - /// @return reference of lua function - LuaFunction loadstring(const char* str) - { - return LuaFunction::loadstring(state_, str); - } - - /// @brief Loads and runs the given file. - /// @param file file path of lua script - /// @param env execute env table - /// @return If there are no errors, returns true.Otherwise return false - bool dofile(const std::string& file, const LuaTable& env = LuaTable()) - { - return dofile(file.c_str(), env); - } - - /// @brief Loads and runs the given file. - /// @param file file path of lua script - /// @param env execute env table - /// @return If there are no errors, returns true.Otherwise return false - bool dofile(const char* file, const LuaTable& env = LuaTable()) - { - util::ScopedSavedStack save(state_); - - int status = luaL_loadfile(state_, file); - - if (status) - { - ErrorHandler::handle(status, state_); - return false; - } - - if (!env.isNilref()) - {//register _ENV - env.push(); +namespace kaguya { +/// @addtogroup State +/// @{ + +/// @brief Load library info type @see State::openlibs @see State::State(const +/// LoadLibs &libs) +typedef std::pair LoadLib; + +/// @brief Load libraries info @see State::openlibs @see State::State(const +/// LoadLibs &libs) +typedef std::vector LoadLibs; + +/// @brief return no load library type @see State::State(const LoadLibs &libs) +inline LoadLibs NoLoadLib() { return LoadLibs(); } + +/// @brief All load standard libraries type @see State::openlibs +struct AllLoadLibs {}; + +template +void *AllocatorFunction(void *ud, void *ptr, size_t osize, size_t nsize) { + Allocator *allocator = static_cast(ud); + if (nsize == 0) { + allocator->deallocate(ptr, osize); + } else if (ptr) { + return allocator->reallocate(ptr, nsize); + } else { + return allocator->allocate(nsize); + } + return 0; +} + +struct DefaultAllocator { + typedef void *pointer; + typedef size_t size_type; + pointer allocate(size_type n) { return std::malloc(n); } + pointer reallocate(pointer p, size_type n) { return std::realloc(p, n); } + void deallocate(pointer p, size_type n) { + KAGUYA_UNUSED(n); + std::free(p); + } +}; + +/// lua_State wrap class +class State { + standard::shared_ptr allocator_holder_; + lua_State *state_; + bool created_; + + // non copyable + State(const State &); + State &operator=(const State &); + + static int initializing_panic(lua_State *L) { + ErrorHandler::throwDefaultError(lua_status(L), lua_tostring(L, -1)); + return 0; // return to Lua to abort + } + static int default_panic(lua_State *L) { + if (ErrorHandler::handle(lua_status(L), L)) { + return 0; + } + fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + fflush(stderr); + return 0; // return to Lua to abort + } + static void stderror_out(int status, const char *message) { + KAGUYA_UNUSED(status); + std::cerr << message << std::endl; + } + + template void init(const Libs &lib) { + if (state_) { + lua_atpanic(state_, &initializing_panic); + try { + if (!ErrorHandler::getHandler(state_)) { + setErrorHandler(&stderror_out); + } + openlibs(lib); + lua_atpanic(state_, &default_panic); + } catch (const LuaException &) { + lua_close(state_); + state_ = 0; + } + } + } + +public: + /// @brief create Lua state with lua standard library + State() : allocator_holder_(), state_(luaL_newstate()), created_(true) { + init(AllLoadLibs()); + } + + /// @brief create Lua state with lua standard library. Can not use this + /// constructor at luajit. error message is 'Must use luaL_newstate() for 64 + /// bit target' + /// @param allocator allocator for memory allocation @see DefaultAllocator + template + State(standard::shared_ptr allocator) + : allocator_holder_(allocator), + state_(lua_newstate(&AllocatorFunction, + allocator_holder_.get())), + created_(true) { + init(AllLoadLibs()); + } + + /// @brief create Lua state with (or without) libraries. + /// @param libs load libraries + /// e.g. LoadLibs libs;libs.push_back(LoadLib("libname",libfunction));State + /// state(libs); + /// e.g. State state({{"libname",libfunction}}); for c++ 11 + State(const LoadLibs &libs) + : allocator_holder_(), state_(luaL_newstate()), created_(true) { + init(libs); + } + + /// @brief create Lua state with (or without) libraries. Can not use this + /// constructor at luajit. error message is 'Must use luaL_newstate() for 64 + /// bit target' + /// @param libs load libraries + /// @param allocator allocator for memory allocation @see DefaultAllocator + template + State(const LoadLibs &libs, standard::shared_ptr allocator) + : allocator_holder_(allocator), + state_(lua_newstate(&AllocatorFunction, + allocator_holder_.get())), + created_(true) { + init(libs); + } + + /// @brief construct using created lua_State. + /// @param lua created lua_State. It is not call lua_close() in this class + State(lua_State *lua) : state_(lua), created_(false) { + if (state_) { + if (!ErrorHandler::getHandler(state_)) { + setErrorHandler(&stderror_out); + } + } + } + ~State() { + if (created_ && state_) { + lua_close(state_); + } + } + + /// @brief set error handler for lua error. + void + setErrorHandler(standard::function + errorfunction) { + if (!state_) { + return; + } + util::ScopedSavedStack save(state_); + ErrorHandler::registerHandler(state_, errorfunction); + } + + /// @brief load all lua standard library + void openlibs(AllLoadLibs = AllLoadLibs()) { + if (!state_) { + return; + } + luaL_openlibs(state_); + } + + /// @brief load lua library + LuaStackRef openlib(const LoadLib &lib) { + if (!state_) { + return LuaStackRef(); + } + luaL_requiref(state_, lib.first.c_str(), lib.second, 1); + return LuaStackRef(state_, -1, true); + } + /// @brief load lua library + LuaStackRef openlib(std::string name, lua_CFunction f) { + return openlib(LoadLib(name, f)); + } + + /// @brief load lua libraries + void openlibs(const LoadLibs &libs) { + for (LoadLibs::const_iterator it = libs.begin(); it != libs.end(); ++it) { + openlib(*it); + } + } + + /// @brief If there are no errors,compiled file as a Lua function and return. + /// Otherwise send error message to error handler and return nil reference + /// @param file file path of lua script + /// @return reference of lua function + LuaFunction loadfile(const std::string &file) { + return LuaFunction::loadfile(state_, file); + } + /// @brief If there are no errors,compiled file as a Lua function and return. + /// Otherwise send error message to error handler and return nil reference + /// @param file file path of lua script + /// @return reference of lua function + LuaFunction loadfile(const char *file) { + return LuaFunction::loadfile(state_, file); + } + + /// @brief If there are no errors,compiled stream as a Lua function and + /// return. + /// Otherwise send error message to error handler and return nil reference + /// @param stream stream of lua script + /// @param chunkname chunkname of lua script + /// @return reference of lua function + LuaFunction loadstream(std::istream &stream, const char *chunkname = 0) { + return LuaFunction::loadstream(state_, stream, chunkname); + } + /// @brief Loads and runs the given stream. + /// @param stream stream of lua script + /// @param chunkname chunkname of lua script + /// @param env execute env table + /// @return If there are no errors, returns true.Otherwise return false + bool dostream(std::istream &stream, const char *chunkname = 0, + const LuaTable &env = LuaTable()) { + util::ScopedSavedStack save(state_); + LuaStackRef f = LuaFunction::loadstreamtostack(state_, stream, chunkname); + if (!f) { // load failed + return false; + } + if (!env.isNilref()) { + f.setFunctionEnv(env); + } + + FunctionResults ret = f.call(); + return !ret.resultStatus(); + } + + /// @brief If there are no errors,compiled string as a Lua function and + /// return. + /// Otherwise send error message to error handler and return nil reference + /// @param str lua code + /// @return reference of lua function + LuaFunction loadstring(const std::string &str) { + return LuaFunction::loadstring(state_, str); + } + /// @brief If there are no errors,compiled string as a Lua function and + /// return. + /// Otherwise send error message to error handler and return nil reference + /// @param str lua code + /// @return reference of lua function + LuaFunction loadstring(const char *str) { + return LuaFunction::loadstring(state_, str); + } + + /// @brief Loads and runs the given file. + /// @param file file path of lua script + /// @param env execute env table + /// @return If there are no errors, returns true.Otherwise return false + bool dofile(const std::string &file, const LuaTable &env = LuaTable()) { + return dofile(file.c_str(), env); + } + + /// @brief Loads and runs the given file. + /// @param file file path of lua script + /// @param env execute env table + /// @return If there are no errors, returns true.Otherwise return false + bool dofile(const char *file, const LuaTable &env = LuaTable()) { + util::ScopedSavedStack save(state_); + + int status = luaL_loadfile(state_, file); + + if (status) { + ErrorHandler::handle(status, state_); + return false; + } + + if (!env.isNilref()) { // register _ENV + env.push(); #if LUA_VERSION_NUM >= 502 - lua_setupvalue(state_, -2, 1); + lua_setupvalue(state_, -2, 1); #else - lua_setfenv(state_, -2); + lua_setfenv(state_, -2); #endif - } - - status = lua_pcall_wrap(state_, 0, LUA_MULTRET); - if (status) - { - ErrorHandler::handle(status, state_); - return false; - } - return true; - } - - - /// @brief Loads and runs the given string. - /// @param str lua script cpde - /// @param env execute env table - /// @return If there are no errors, returns true.Otherwise return false - bool dostring(const char* str, const LuaTable& env = LuaTable()) - { - util::ScopedSavedStack save(state_); - - int status = luaL_loadstring(state_, str); - if (status) - { - ErrorHandler::handle(status, state_); - return false; - } - if (!env.isNilref()) - {//register _ENV - env.push(); + } + + status = lua_pcall_wrap(state_, 0, LUA_MULTRET); + if (status) { + ErrorHandler::handle(status, state_); + return false; + } + return true; + } + + /// @brief Loads and runs the given string. + /// @param str lua script cpde + /// @param env execute env table + /// @return If there are no errors, returns true.Otherwise return false + bool dostring(const char *str, const LuaTable &env = LuaTable()) { + util::ScopedSavedStack save(state_); + + int status = luaL_loadstring(state_, str); + if (status) { + ErrorHandler::handle(status, state_); + return false; + } + if (!env.isNilref()) { // register _ENV + env.push(); #if LUA_VERSION_NUM >= 502 - lua_setupvalue(state_, -2, 1); + lua_setupvalue(state_, -2, 1); #else - lua_setfenv(state_, -2); + lua_setfenv(state_, -2); #endif - } - status = lua_pcall_wrap(state_, 0, LUA_MULTRET); - if (status) - { - ErrorHandler::handle(status, state_); - return false; - } - return true; - } - /// @brief Loads and runs the given string. - /// @param str lua script cpde - /// @param env execute env table - /// @return If there are no errors, returns true.Otherwise return false - bool dostring(const std::string& str, const LuaTable& env = LuaTable()) - { - return dostring(str.c_str(), env); - } - - /// @brief Loads and runs the given string. - /// @param str lua script cpde - /// @return If there are no errors, returns true.Otherwise return false - bool operator()(const std::string& str) - { - return dostring(str); - } - - /// @brief Loads and runs the given string. - /// @param str lua script cpde - /// @return If there are no errors, returns true.Otherwise return false - bool operator()(const char* str) - { - return dostring(str); - } - - /// @brief return element reference from global table - /// @param str table key - /// @return proxy class for reference to table. - TableKeyReferenceProxy operator[](const std::string& str) - { - int stack_top = lua_gettop(state_); - util::push_args(state_, GlobalTable()); - int table_index = stack_top + 1; - return TableKeyReferenceProxy(state_, table_index, str, stack_top, NoTypeCheck()); - } - - - /// @brief return element reference from global table - /// @param str table key - /// @return proxy class for reference to table. - - TableKeyReferenceProxy operator[](const char* str) - { - int stack_top = lua_gettop(state_); - util::push_args(state_, GlobalTable()); - int table_index = stack_top + 1; - return TableKeyReferenceProxy(state_, table_index, str, stack_top, NoTypeCheck()); - } - - - /// @brief return global table - /// @return global table. - LuaTable globalTable() - { - return newRef(GlobalTable()); - } - - - /// @brief create new Lua reference from argument value - /// @return Lua reference. - template - LuaRef newRef(const T& value) - { - return LuaRef(state_, value); - } + } + status = lua_pcall_wrap(state_, 0, LUA_MULTRET); + if (status) { + ErrorHandler::handle(status, state_); + return false; + } + return true; + } + /// @brief Loads and runs the given string. + /// @param str lua script cpde + /// @param env execute env table + /// @return If there are no errors, returns true.Otherwise return false + bool dostring(const std::string &str, const LuaTable &env = LuaTable()) { + return dostring(str.c_str(), env); + } + + /// @brief Loads and runs the given string. + /// @param str lua script cpde + /// @return If there are no errors, returns true.Otherwise return false + bool operator()(const std::string &str) { return dostring(str); } + + /// @brief Loads and runs the given string. + /// @param str lua script cpde + /// @return If there are no errors, returns true.Otherwise return false + bool operator()(const char *str) { return dostring(str); } + + /// @brief return element reference from global table + /// @param str table key + /// @return proxy class for reference to table. + TableKeyReferenceProxy operator[](const std::string &str) { + int stack_top = lua_gettop(state_); + util::push_args(state_, GlobalTable()); + int table_index = stack_top + 1; + return TableKeyReferenceProxy(state_, table_index, str, + stack_top, NoTypeCheck()); + } + + /// @brief return element reference from global table + /// @param str table key + /// @return proxy class for reference to table. + + TableKeyReferenceProxy operator[](const char *str) { + int stack_top = lua_gettop(state_); + util::push_args(state_, GlobalTable()); + int table_index = stack_top + 1; + return TableKeyReferenceProxy(state_, table_index, str, + stack_top, NoTypeCheck()); + } + + /// @brief return global table + /// @return global table. + LuaTable globalTable() { return newRef(GlobalTable()); } + + /// @brief create new Lua reference from argument value + /// @return Lua reference. + template LuaRef newRef(const T &value) { + return LuaRef(state_, value); + } #if KAGUYA_USE_CPP11 - - /// @brief create new Lua reference from argument value - /// @return Lua reference. - template - LuaRef newRef(T&& value) - { - return LuaRef(state_, std::forward(value)); - } + + /// @brief create new Lua reference from argument value + /// @return Lua reference. + template LuaRef newRef(T &&value) { + return LuaRef(state_, std::forward(value)); + } #endif - - /// @brief create new Lua table - /// @return Lua table reference. - LuaTable newTable() - { - return LuaTable(state_); - } - - /// @brief create new Lua table - /// @param reserve_array reserved array count - /// @param reserve_record reserved record count - /// @return Lua table reference. - LuaTable newTable(int reserve_array, int reserve_record) - { - return LuaTable(state_, NewTable(reserve_array, reserve_record)); - } - - - /// @brief create new Lua thread - /// @return Lua thread reference. - LuaThread newThread() - { - return LuaThread(state_); - } - - /// @brief create new Lua thread with lua function - /// @param f function - /// @return Lua thread reference. - LuaThread newThread(const LuaFunction& f) - { - LuaThread cor(state_); - cor.setFunction(f); - return cor; - } - - - /// @brief argument value push to stack. - /// @param value value - template - void pushToStack(T value) - { - util::push_args(state_, value); - } - - /// @brief pop from stack. - /// @return reference to pop value. - LuaRef popFromStack() - { - return LuaRef(state_, StackTop()); - } - - /// @brief Garbage Collection of Lua - struct GCType - { - GCType(lua_State* state) :state_(state) {} - - /// @brief Performs a full garbage-collection cycle. - void collect() - { - lua_gc(state_, LUA_GCCOLLECT, 0); - } - /// @brief Performs an incremental step of garbage collection. - /// @return If returns true,the step finished a collection cycle. - bool step() - { - return lua_gc(state_, LUA_GCSTEP, 0) == 1; - } - - /// @brief Performs an incremental step of garbage collection. - /// @param size the collector will perform as if that amount of memory (in KBytes) had been allocated by Lua. - bool step(int size) - { - return lua_gc(state_, LUA_GCSTEP, size) == 1; - } - - /// @brief enable gc - void restart() { enable(); } - - /// @brief disable gc - void stop() { disable(); } - - - /// @brief returns the total memory in use by Lua in Kbytes. - int count()const { return lua_gc(state_, LUA_GCCOUNT, 0); } - - - /// @brief sets arg as the new value for the pause of the collector. Returns the previous value for pause. - int steppause(int value) { return lua_gc(state_, LUA_GCSETPAUSE, value); } - - /// @brief sets arg as the new value for the step multiplier of the collector. Returns the previous value for step. - int setstepmul(int value) { return lua_gc(state_, LUA_GCSETSTEPMUL, value); } - - - /// @brief enable gc - void enable() - { - lua_gc(state_, LUA_GCRESTART, 0); - } - - - /// @brief disable gc - void disable() - { - lua_gc(state_, LUA_GCSTOP, 0); - } + /// @brief create new Lua table + /// @return Lua table reference. + LuaTable newTable() { return LuaTable(state_); } + + /// @brief create new Lua table + /// @param reserve_array reserved array count + /// @param reserve_record reserved record count + /// @return Lua table reference. + LuaTable newTable(int reserve_array, int reserve_record) { + return LuaTable(state_, NewTable(reserve_array, reserve_record)); + } + + /// @brief create new Lua thread + /// @return Lua thread reference. + LuaThread newThread() { return LuaThread(state_); } + + /// @brief create new Lua thread with lua function + /// @param f function + /// @return Lua thread reference. + LuaThread newThread(const LuaFunction &f) { + LuaThread cor(state_); + cor.setFunction(f); + return cor; + } + + /// @brief argument value push to stack. + /// @param value value + template void pushToStack(T value) { + util::push_args(state_, value); + } + + /// @brief pop from stack. + /// @return reference to pop value. + LuaRef popFromStack() { return LuaRef(state_, StackTop()); } + + /// @brief Garbage Collection of Lua + struct GCType { + GCType(lua_State *state) : state_(state) {} + + /// @brief Performs a full garbage-collection cycle. + void collect() { lua_gc(state_, LUA_GCCOLLECT, 0); } + /// @brief Performs an incremental step of garbage collection. + /// @return If returns true,the step finished a collection cycle. + bool step() { return lua_gc(state_, LUA_GCSTEP, 0) == 1; } + + /// @brief Performs an incremental step of garbage collection. + /// @param size the collector will perform as if that amount of memory (in + /// KBytes) had been allocated by Lua. + bool step(int size) { return lua_gc(state_, LUA_GCSTEP, size) == 1; } + + /// @brief enable gc + void restart() { enable(); } + + /// @brief disable gc + void stop() { disable(); } + + /// @brief returns the total memory in use by Lua in Kbytes. + int count() const { return lua_gc(state_, LUA_GCCOUNT, 0); } + + /// @brief sets arg as the new value for the pause of the collector. Returns + /// the previous value for pause. + int steppause(int value) { return lua_gc(state_, LUA_GCSETPAUSE, value); } + + /// @brief sets arg as the new value for the step multiplier of the + /// collector. Returns the previous value for step. + int setstepmul(int value) { + return lua_gc(state_, LUA_GCSETSTEPMUL, value); + } + + /// @brief enable gc + void enable() { lua_gc(state_, LUA_GCRESTART, 0); } + + /// @brief disable gc + void disable() { lua_gc(state_, LUA_GCSTOP, 0); } #if LUA_VERSION_NUM >= 502 - - /// @brief returns a boolean that tells whether the collector is running - bool isrunning()const { return isenabled(); } - - /// @brief returns a boolean that tells whether the collector is running - bool isenabled()const - { - return lua_gc(state_, LUA_GCISRUNNING, 0) != 0; - } + + /// @brief returns a boolean that tells whether the collector is running + bool isrunning() const { return isenabled(); } + + /// @brief returns a boolean that tells whether the collector is running + bool isenabled() const { return lua_gc(state_, LUA_GCISRUNNING, 0) != 0; } #endif - private: - lua_State* state_; - }; - - // /@brief return Garbage collection interface. - GCType gc()const - { - return GCType(state_); - } - /// @brief performs a full garbage-collection cycle. - void garbageCollect() - { - gc().collect(); - } - - /// @brief returns the current amount of memory (in Kbytes) in use by Lua. - size_t useKBytes()const - { - return size_t(gc().count()); - } - - - - - /// @brief create Table and push to stack. - /// using for Lua module - /// @return return Lua Table Reference - LuaTable newLib() - { - LuaTable newtable = newTable(); - newtable.push(state_); - return newtable; - } - - - /// @brief return lua_State*. - /// @return lua_State* - lua_State *state() { return state_; }; - - - /// @brief check valid lua_State. - bool isInvalid() const { return !state_; } - }; - - /// @} + private: + lua_State *state_; + }; + + // /@brief return Garbage collection interface. + GCType gc() const { return GCType(state_); } + /// @brief performs a full garbage-collection cycle. + void garbageCollect() { gc().collect(); } + + /// @brief returns the current amount of memory (in Kbytes) in use by Lua. + size_t useKBytes() const { return size_t(gc().count()); } + + /// @brief create Table and push to stack. + /// using for Lua module + /// @return return Lua Table Reference + LuaTable newLib() { + LuaTable newtable = newTable(); + newtable.push(state_); + return newtable; + } + + /// @brief return lua_State*. + /// @return lua_State* + lua_State *state() { return state_; }; + + /// @brief check valid lua_State. + bool isInvalid() const { return !state_; } +}; + +/// @} } diff --git a/include/kaguya/traits.hpp b/include/kaguya/traits.hpp index ced954d..e1a9ce4 100644 --- a/include/kaguya/traits.hpp +++ b/include/kaguya/traits.hpp @@ -12,151 +12,146 @@ #include "kaguya/config.hpp" #include "kaguya/optional.hpp" -namespace kaguya -{ - namespace traits - { - using standard::integral_constant; - using standard::true_type; - using standard::false_type; - using standard::remove_reference; - using standard::remove_pointer; - using standard::remove_const; - using standard::remove_volatile; - using standard::remove_cv; - using standard::is_function; - using standard::is_floating_point; - using standard::is_integral; - using standard::is_enum; - using standard::is_convertible; - using standard::is_same; - using standard::is_arithmetic; - using standard::is_union; - using standard::is_class; - using standard::is_pointer; - using standard::is_lvalue_reference; - using standard::is_const; - using standard::is_void; +namespace kaguya { +namespace traits { +using standard::integral_constant; +using standard::true_type; +using standard::false_type; +using standard::remove_reference; +using standard::remove_pointer; +using standard::remove_const; +using standard::remove_volatile; +using standard::remove_cv; +using standard::is_function; +using standard::is_floating_point; +using standard::is_integral; +using standard::is_enum; +using standard::is_convertible; +using standard::is_same; +using standard::is_arithmetic; +using standard::is_union; +using standard::is_class; +using standard::is_pointer; +using standard::is_lvalue_reference; +using standard::is_const; +using standard::is_void; #if KAGUYA_USE_CPP11 - using std::enable_if; +using std::enable_if; #else - template struct enable_if: boost::enable_if_c {}; +template +struct enable_if : boost::enable_if_c {}; #endif - class Helper{}; - /// @brief Check if T_Mem is a member object of a type. That is true if it is not a member function - /// Required as MSVC throws a COMDAT error when using is_member_object_pointer - template - struct is_object{ - typedef typename standard::is_member_function_pointer::type NotResult; - enum{ value = !NotResult::value }; - }; - - /// @brief Similar to std::decay but also removes const and volatile modifiers if T is neither an array nor a function - template< class T > - struct decay { - private: - ///@ If T is a reference type, the type referrered to by T. Otherwise, T. - typedef typename standard::remove_reference::type U; - public: - typedef typename standard::conditional< - standard::is_array::value, - typename standard::remove_extent::type*, - typename standard::conditional< - is_function::value, - typename standard::add_pointer::type, - typename standard::remove_cv::type - >::type - >::type type; - }; - - /// @brief Trait class that identifies whether T is a const reference type. - template struct is_const_reference : false_type {}; - template struct is_const_reference : true_type {}; - - /// @brief Obtains the type T without top-level const and reference. - template< typename T > - struct remove_const_and_reference { - /// @brief If T is const or reference, the same type as T but with the const reference removed.Otherwise, T - typedef T type; - }; - /// @brief Obtains the type T without top-level const and reference. - template< typename T > - struct remove_const_and_reference { - /// @brief If T is const or reference, the same type as T but with the const reference removed.Otherwise, T - typedef T type; - }; - /// @brief Obtains the type T without top-level const and reference. - template< typename T > - struct remove_const_and_reference { - /// @brief If T is const or reference, the same type as T but with the const reference removed.Otherwise, T - typedef T type; - }; - /// @brief Obtains the type T without top-level const and reference. - template< typename T > - struct remove_const_and_reference { - /// @brief If T is const or reference, the same type as T but with the const reference removed.Otherwise, T - typedef T type; - }; - - /// @brief Obtains the type T without top-level const reference. - template< typename T > - struct remove_const_reference { - /// @brief If T is const reference, the same type as T but with the const reference removed.Otherwise, T - typedef T type; - }; - /// @brief Obtains the type T without top-level const reference. - template< typename T > - struct remove_const_reference { - /// @brief If T is const reference, the same type as T but with the const reference removed.Otherwise, T - typedef T type; - }; - - /// @brief Trait class that identifies whether T is a std::vector type. - template struct is_std_vector : false_type {}; - template struct is_std_vector > : true_type {}; - - /// @brief Trait class that identifies whether T is a std::map type. - template struct is_std_map : false_type {}; - template struct is_std_map > : true_type {}; - - } - - - /// @addtogroup lua_type_traits - - /// @ingroup lua_type_traits - /// @brief If you want to customize the conversion to type of lua yourself , - /// implement specialize of this class - template - struct lua_type_traits - { - typedef void Registerable; - - typedef typename traits::decay::type NCRT; - typedef const NCRT& get_type; - typedef optional opt_type; - typedef const NCRT& push_type; - - static bool checkType(lua_State* l, int index); - static bool strictCheckType(lua_State* l, int index); - - static get_type get(lua_State* l, int index); - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT; - static int push(lua_State* l, push_type v); -#if KAGUYA_USE_RVALUE_REFERENCE - static int push(lua_State* l, NCRT&& v); -#endif - }; +class Helper {}; +/// @brief Check if T_Mem is a member object of a type. That is true if it is +/// not a member function +/// Required as MSVC throws a COMDAT error when using is_member_object_pointer +template struct is_object { + typedef typename standard::is_member_function_pointer::type + NotResult; + enum { value = !NotResult::value }; +}; + +/// @brief Similar to std::decay but also removes const and volatile modifiers +/// if T is neither an array nor a function +template struct decay { +private: + ///@ If T is a reference type, the type referrered to by T. Otherwise, T. + typedef typename standard::remove_reference::type U; + +public: + typedef typename standard::conditional< + standard::is_array::value, typename standard::remove_extent::type *, + typename standard::conditional< + is_function::value, typename standard::add_pointer::type, + typename standard::remove_cv::type>::type>::type type; +}; + +/// @brief Trait class that identifies whether T is a const reference type. +template struct is_const_reference : false_type {}; +template struct is_const_reference : true_type {}; + +/// @brief Obtains the type T without top-level const and reference. +template struct remove_const_and_reference { + /// @brief If T is const or reference, the same type as T but with the const + /// reference removed.Otherwise, T + typedef T type; +}; +/// @brief Obtains the type T without top-level const and reference. +template struct remove_const_and_reference { + /// @brief If T is const or reference, the same type as T but with the const + /// reference removed.Otherwise, T + typedef T type; +}; +/// @brief Obtains the type T without top-level const and reference. +template struct remove_const_and_reference { + /// @brief If T is const or reference, the same type as T but with the const + /// reference removed.Otherwise, T + typedef T type; +}; +/// @brief Obtains the type T without top-level const and reference. +template struct remove_const_and_reference { + /// @brief If T is const or reference, the same type as T but with the const + /// reference removed.Otherwise, T + typedef T type; +}; + +/// @brief Obtains the type T without top-level const reference. +template struct remove_const_reference { + /// @brief If T is const reference, the same type as T but with the const + /// reference removed.Otherwise, T + typedef T type; +}; +/// @brief Obtains the type T without top-level const reference. +template struct remove_const_reference { + /// @brief If T is const reference, the same type as T but with the const + /// reference removed.Otherwise, T + typedef T type; +}; + +/// @brief Trait class that identifies whether T is a std::vector type. +template struct is_std_vector : false_type {}; +template +struct is_std_vector > : true_type {}; + +/// @brief Trait class that identifies whether T is a std::map type. +template struct is_std_map : false_type {}; +template +struct is_std_map > : true_type {}; +} + +/// @addtogroup lua_type_traits +/// @ingroup lua_type_traits +/// @brief If you want to customize the conversion to type of lua yourself , +/// implement specialize of this class +template struct lua_type_traits { + typedef void Registerable; - /// @brief Trait class that identifies whether T is a userdata type. - template< typename T, typename Enable = void> - struct is_usertype : traits::false_type {}; - template< typename T> - struct is_usertype::Registerable> : traits::true_type {}; + typedef typename traits::decay::type NCRT; + typedef const NCRT &get_type; + typedef optional opt_type; + typedef const NCRT &push_type; - /// @brief Trait class that identifies whether T is a registerable by UserdataMetatable. - template< typename T> - struct is_registerable : is_usertype {}; + static bool checkType(lua_State *l, int index); + static bool strictCheckType(lua_State *l, int index); + + static get_type get(lua_State *l, int index); + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT; + static int push(lua_State *l, push_type v); +#if KAGUYA_USE_RVALUE_REFERENCE + static int push(lua_State *l, NCRT &&v); +#endif +}; + +/// @brief Trait class that identifies whether T is a userdata type. +template +struct is_usertype : traits::false_type {}; +template +struct is_usertype::Registerable> + : traits::true_type {}; + +/// @brief Trait class that identifies whether T is a registerable by +/// UserdataMetatable. +template struct is_registerable : is_usertype {}; } diff --git a/include/kaguya/type.hpp b/include/kaguya/type.hpp index cbf1344..dc18bfb 100644 --- a/include/kaguya/type.hpp +++ b/include/kaguya/type.hpp @@ -13,1056 +13,913 @@ #include "kaguya/traits.hpp" #include "kaguya/object.hpp" #include "kaguya/exception.hpp" - #include "kaguya/push_tuple.hpp" +namespace kaguya { - -namespace kaguya -{ - - //default implements - template - bool lua_type_traits::checkType(lua_State* l, int index) - { - return object_wrapper(l, index) != 0; - } - template - bool lua_type_traits::strictCheckType(lua_State* l, int index) - { - return object_wrapper(l, index, false) != 0; - } - template - typename lua_type_traits::opt_type lua_type_traits::opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - const typename traits::remove_reference::type* pointer = get_const_pointer(l, index, types::typetag::type>()); - if (!pointer) - { - return opt_type(); - } - return *pointer; - } - template - typename lua_type_traits::get_type lua_type_traits::get(lua_State* l, int index) - { - const typename traits::remove_reference::type* pointer = get_const_pointer(l, index, types::typetag::type>()); - if (!pointer) - { - throw LuaTypeMismatch(); - } - return *pointer; - } - template - int lua_type_traits::push(lua_State* l, push_type v) - { - return util::object_push(l, v); - } +// default implements +template +bool lua_type_traits::checkType(lua_State *l, int index) { + return object_wrapper(l, index) != 0; +} +template +bool lua_type_traits::strictCheckType(lua_State *l, int index) { + return object_wrapper(l, index, false) != 0; +} +template +typename lua_type_traits::opt_type +lua_type_traits::opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + const typename traits::remove_reference::type *pointer = get_const_pointer( + l, index, types::typetag::type>()); + if (!pointer) { + return opt_type(); + } + return *pointer; +} +template +typename lua_type_traits::get_type +lua_type_traits::get(lua_State *l, int index) { + const typename traits::remove_reference::type *pointer = get_const_pointer( + l, index, types::typetag::type>()); + if (!pointer) { + throw LuaTypeMismatch(); + } + return *pointer; +} +template +int lua_type_traits::push(lua_State *l, push_type v) { + return util::object_push(l, v); +} #if KAGUYA_USE_RVALUE_REFERENCE - template - int lua_type_traits::push(lua_State* l, NCRT&& v) - { - return util::object_push(l,std::forward(v)); - } +template +int lua_type_traits::push(lua_State *l, NCRT &&v) { + return util::object_push(l, std::forward(v)); +} #endif - /// @ingroup lua_type_traits - /// @brief lua_type_traits for const reference type - template struct lua_type_traits::value>::type> :lua_type_traits::type > {}; - - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for lvalue reference type - template struct lua_type_traits < REF - , typename traits::enable_if::value && !traits::is_const::type>::value>::type > - { - typedef void Registerable; - - typedef REF get_type; - typedef optional opt_type; - typedef REF push_type; - typedef typename traits::remove_reference::type T; - - static bool strictCheckType(lua_State* l, int index) - { - return object_wrapper(l, index, false) != 0; - } - static bool checkType(lua_State* l, int index) - { - if (lua_type(l, index) == LUA_TLIGHTUSERDATA) - { - return true; - } - return object_wrapper(l, index) != 0; - } - static get_type get(lua_State* l, int index) - { - T* pointer = get_pointer(l, index, types::typetag()); - if (!pointer) - { - throw LuaTypeMismatch(); - } - return *pointer; - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - T* pointer = get_pointer(l, index, types::typetag()); - if (!pointer) - { - return opt_type(); - } - return opt_type(*pointer); - } - static int push(lua_State* l, push_type v) - { - if (!available_metatable(l)) - { - lua_pushlightuserdata(l, const_cast::type*>(&v)); - } - else - { - typedef typename ObjectPointerWrapperType::type wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(&v); - class_userdata::setmetatable(l); - } - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for pointer type - template struct lua_type_traits < PTR - , typename traits::enable_if::type>::value && !traits::is_function::type>::value>::type > - { - typedef void Registerable; - - typedef PTR get_type; - typedef optional opt_type; - typedef PTR push_type; - typedef typename traits::remove_pointer::type T; - - static bool strictCheckType(lua_State* l, int index) - { - return object_wrapper(l, index, false) != 0; - } - static bool checkType(lua_State* l, int index) - { - int type = lua_type(l, index); - if (type == LUA_TLIGHTUSERDATA - || type == LUA_TNIL - || type == LUA_TNONE) - { - return true; - } - return object_wrapper(l, index) != 0; - } - static get_type get(lua_State* l, int index) - { - int type = lua_type(l, index); - if (type == LUA_TUSERDATA || type == LUA_TLIGHTUSERDATA) - { - return get_pointer(l, index, types::typetag()); - } - - if (type == LUA_TNIL - || type == LUA_TNONE) - { - return 0; - } - throw LuaTypeMismatch(); - return 0; - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - int type = lua_type(l, index); - if (type == LUA_TUSERDATA || type == LUA_TLIGHTUSERDATA) - { - return get_pointer(l, index, types::typetag()); - } - if (type == LUA_TNIL - || type == LUA_TNONE) - { - return opt_type(0); - } - return opt_type(); - } - static int push(lua_State* l, push_type v) - { - if (!v) - { - lua_pushnil(l); - } - else if (!available_metatable(l)) - { - lua_pushlightuserdata(l, const_cast::type*>(v)); - } - else - { - typedef typename ObjectPointerWrapperType::type wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(v); - class_userdata::setmetatable(l); - } - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for bool - template<> struct lua_type_traits { - typedef bool get_type; - typedef optional opt_type; - typedef bool push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TBOOLEAN; - } - static bool checkType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return true; - } - static bool get(lua_State* l, int index) - { - return l && lua_toboolean(l, index) != 0; - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - if (l) - { - return opt_type(lua_toboolean(l, index) != 0); - } - else - { - return opt_type(); - } - } - static int push(lua_State* l, bool s) - { - lua_pushboolean(l, s); - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for void - template<> struct lua_type_traits { - typedef void* get_type; - typedef void* push_type; - - static bool strictCheckType(lua_State* , int ) - { - return true; - } - static bool checkType(lua_State* , int ) - { - return true; - } - static get_type get(lua_State* , int ) - { - return 0; - } - static int push(lua_State* , push_type ) - { - return 0; - } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for reference_wrapper - template struct lua_type_traits > { - typedef const standard::reference_wrapper& push_type; - - static int push(lua_State* l, push_type v) - { - return util::push_args(l, &v.get()); - } - }; - - namespace detail - { - - template< typename T, typename Enable = void> - struct has_optional_get : traits::false_type {}; - template< typename T> - struct has_optional_get::opt_type>::value>::type - > : traits::true_type {}; - - - template - typename traits::enable_if::value, optional >::type - opt_helper(lua_State* state, int index)KAGUYA_NOEXCEPT - { - return lua_type_traits::opt(state, index); - } - template - typename traits::enable_if::value, optional >::type - opt_helper(lua_State* state, int index) - { - try - { - return lua_type_traits::get(state, index); - } - catch (...) - { - return optional(); - } - } - } - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for optional - template struct lua_type_traits > { - typedef const optional& push_type; - typedef optional get_type; - - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type_traits::strictCheckType(l, index); - } - static bool checkType(lua_State* l, int index) - { - KAGUYA_UNUSED(l); - KAGUYA_UNUSED(index); - return true; - } - static get_type get(lua_State* l, int index)KAGUYA_NOEXCEPT - { - return detail::opt_helper(l,index); - } - - static int push(lua_State* l, push_type v)KAGUYA_NOEXCEPT - { - if (v) - { - return util::push_args(l, v.value()); - } - else - { - lua_pushnil(l); - } - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for shared_ptr - template struct lua_type_traits > { - typedef const standard::shared_ptr& push_type; - typedef standard::shared_ptr get_type; - - static bool strictCheckType(lua_State* l, int index) - { - ObjectSharedPointerWrapper* wrapper = dynamic_cast(object_wrapper(l, index)); - const std::type_info& type = metatableType::type > >(); - return wrapper && (wrapper->shared_ptr_type() == type); - } - static bool checkType(lua_State* l, int index) - { - return get_shared_pointer(l, index, types::typetag()) || lua_isnil(l, index); - } - static get_type get(lua_State* l, int index) - { - if (lua_isnil(l, index)) { - return get_type(); - } - return get_shared_pointer(l, index, types::typetag()); - } - - static int push(lua_State* l, push_type v) - { - if (v) - { - typedef ObjectSharedPointerWrapper wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(v); - class_userdata::setmetatable(l); - } - else - { - lua_pushnil(l); - } - return 1; - } - }; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for const reference type +template +struct lua_type_traits< + T, typename traits::enable_if::value>::type> + : lua_type_traits::type> {}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for lvalue reference type +template +struct lua_type_traits< + REF, typename traits::enable_if< + traits::is_lvalue_reference::value && + !traits::is_const< + typename traits::remove_reference::type>::value>::type> { + typedef void Registerable; + + typedef REF get_type; + typedef optional opt_type; + typedef REF push_type; + typedef typename traits::remove_reference::type T; + + static bool strictCheckType(lua_State *l, int index) { + return object_wrapper(l, index, false) != 0; + } + static bool checkType(lua_State *l, int index) { + if (lua_type(l, index) == LUA_TLIGHTUSERDATA) { + return true; + } + return object_wrapper(l, index) != 0; + } + static get_type get(lua_State *l, int index) { + T *pointer = get_pointer(l, index, types::typetag()); + if (!pointer) { + throw LuaTypeMismatch(); + } + return *pointer; + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + T *pointer = get_pointer(l, index, types::typetag()); + if (!pointer) { + return opt_type(); + } + return opt_type(*pointer); + } + static int push(lua_State *l, push_type v) { + if (!available_metatable(l)) { + lua_pushlightuserdata( + l, const_cast::type *>(&v)); + } else { + typedef typename ObjectPointerWrapperType::type wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new (storage) wrapper_type(&v); + class_userdata::setmetatable(l); + } + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for pointer type +template +struct lua_type_traits< + PTR, typename traits::enable_if< + traits::is_pointer< + typename traits::remove_const_reference::type>::value && + !traits::is_function< + typename traits::remove_pointer::type>::value>::type> { + typedef void Registerable; + + typedef PTR get_type; + typedef optional opt_type; + typedef PTR push_type; + typedef typename traits::remove_pointer::type T; + + static bool strictCheckType(lua_State *l, int index) { + return object_wrapper(l, index, false) != 0; + } + static bool checkType(lua_State *l, int index) { + int type = lua_type(l, index); + if (type == LUA_TLIGHTUSERDATA || type == LUA_TNIL || type == LUA_TNONE) { + return true; + } + return object_wrapper(l, index) != 0; + } + static get_type get(lua_State *l, int index) { + int type = lua_type(l, index); + if (type == LUA_TUSERDATA || type == LUA_TLIGHTUSERDATA) { + return get_pointer(l, index, types::typetag()); + } + + if (type == LUA_TNIL || type == LUA_TNONE) { + return 0; + } + throw LuaTypeMismatch(); + return 0; + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + int type = lua_type(l, index); + if (type == LUA_TUSERDATA || type == LUA_TLIGHTUSERDATA) { + return get_pointer(l, index, types::typetag()); + } + if (type == LUA_TNIL || type == LUA_TNONE) { + return opt_type(0); + } + return opt_type(); + } + static int push(lua_State *l, push_type v) { + if (!v) { + lua_pushnil(l); + } else if (!available_metatable(l)) { + lua_pushlightuserdata( + l, const_cast::type *>(v)); + } else { + typedef typename ObjectPointerWrapperType::type wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new (storage) wrapper_type(v); + class_userdata::setmetatable(l); + } + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for bool +template <> struct lua_type_traits { + typedef bool get_type; + typedef optional opt_type; + typedef bool push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TBOOLEAN; + } + static bool checkType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return true; + } + static bool get(lua_State *l, int index) { + return l && lua_toboolean(l, index) != 0; + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + if (l) { + return opt_type(lua_toboolean(l, index) != 0); + } else { + return opt_type(); + } + } + static int push(lua_State *l, bool s) { + lua_pushboolean(l, s); + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for void +template <> struct lua_type_traits { + typedef void *get_type; + typedef void *push_type; + + static bool strictCheckType(lua_State *, int) { return true; } + static bool checkType(lua_State *, int) { return true; } + static get_type get(lua_State *, int) { return 0; } + static int push(lua_State *, push_type) { return 0; } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for reference_wrapper +template struct lua_type_traits > { + typedef const standard::reference_wrapper &push_type; + + static int push(lua_State *l, push_type v) { + return util::push_args(l, &v.get()); + } +}; + +namespace detail { + +template +struct has_optional_get : traits::false_type {}; +template +struct has_optional_get< + T, typename traits::enable_if::opt_type>::value>::type> + : traits::true_type {}; + +template +typename traits::enable_if::value, optional >::type +opt_helper(lua_State *state, int index) KAGUYA_NOEXCEPT { + return lua_type_traits::opt(state, index); +} +template +typename traits::enable_if::value, optional >::type +opt_helper(lua_State *state, int index) { + try { + return lua_type_traits::get(state, index); + } catch (...) { + return optional(); + } +} +} + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for optional +template struct lua_type_traits > { + typedef const optional &push_type; + typedef optional get_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type_traits::strictCheckType(l, index); + } + static bool checkType(lua_State *l, int index) { + KAGUYA_UNUSED(l); + KAGUYA_UNUSED(index); + return true; + } + static get_type get(lua_State *l, int index) KAGUYA_NOEXCEPT { + return detail::opt_helper(l, index); + } + + static int push(lua_State *l, push_type v) KAGUYA_NOEXCEPT { + if (v) { + return util::push_args(l, v.value()); + } else { + lua_pushnil(l); + } + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for shared_ptr +template struct lua_type_traits > { + typedef const standard::shared_ptr &push_type; + typedef standard::shared_ptr get_type; + + static bool strictCheckType(lua_State *l, int index) { + ObjectSharedPointerWrapper *wrapper = + dynamic_cast(object_wrapper(l, index)); + const std::type_info &type = + metatableType::type> >(); + return wrapper && (wrapper->shared_ptr_type() == type); + } + static bool checkType(lua_State *l, int index) { + return get_shared_pointer(l, index, types::typetag()) || + lua_isnil(l, index); + } + static get_type get(lua_State *l, int index) { + if (lua_isnil(l, index)) { + return get_type(); + } + return get_shared_pointer(l, index, types::typetag()); + } + + static int push(lua_State *l, push_type v) { + if (v) { + typedef ObjectSharedPointerWrapper wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new (storage) wrapper_type(v); + class_userdata::setmetatable(l); + } else { + lua_pushnil(l); + } + return 1; + } +}; #if KAGUYA_USE_CPP11 - /// @ingroup lua_type_traits - /// @brief lua_type_traits for unique_ptr - template struct lua_type_traits > { - typedef std::unique_ptr&& push_type; - typedef std::unique_ptr& get_type; - typedef std::unique_ptr type; - - static bool strictCheckType(lua_State* l, int index) - { - return object_wrapper(l, index, false) != 0; - } - static bool checkType(lua_State* l, int index) - { - return object_wrapper(l, index) != 0 || - lua_isnil(l, index); - } - static get_type get(lua_State* l, int index) - { - type* pointer = get_pointer(l, index, types::typetag()); - if (!pointer) - { - throw LuaTypeMismatch(); - } - return *pointer; - } - - static int push(lua_State* l, push_type v) - { - if (v) - { - typedef ObjectSmartPointerWrapper wrapper_type; - void *storage = lua_newuserdata(l, sizeof(wrapper_type)); - new(storage) wrapper_type(std::forward(v)); - class_userdata::setmetatable(l); - } - else - { - lua_pushnil(l); - } - return 1; - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for nullptr - template<> struct lua_type_traits { - typedef const std::nullptr_t& push_type; - typedef std::nullptr_t get_type; - typedef optional opt_type; - - static bool checkType(lua_State* l, int index) - { - return lua_isnoneornil(l, index); - } - static bool strictCheckType(lua_State* l, int index) - { - return lua_isnil(l, index); - } - static opt_type opt(lua_State* l, int index) - { - if (!lua_isnoneornil(l, index)) { - return opt_type(); - } - return nullptr; - } - static get_type get(lua_State* l, int index) - { - if (!lua_isnoneornil(l, index)) { - throw LuaTypeMismatch(); - } - return nullptr; - } - - static int push(lua_State* l, const std::nullptr_t& ) - { - lua_pushnil(l); - return 1; - } - }; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for unique_ptr +template +struct lua_type_traits > { + typedef std::unique_ptr &&push_type; + typedef std::unique_ptr &get_type; + typedef std::unique_ptr type; + + static bool strictCheckType(lua_State *l, int index) { + return object_wrapper(l, index, false) != 0; + } + static bool checkType(lua_State *l, int index) { + return object_wrapper(l, index) != 0 || lua_isnil(l, index); + } + static get_type get(lua_State *l, int index) { + type *pointer = get_pointer(l, index, types::typetag()); + if (!pointer) { + throw LuaTypeMismatch(); + } + return *pointer; + } + + static int push(lua_State *l, push_type v) { + if (v) { + typedef ObjectSmartPointerWrapper wrapper_type; + void *storage = lua_newuserdata(l, sizeof(wrapper_type)); + new (storage) wrapper_type(std::forward(v)); + class_userdata::setmetatable(l); + } else { + lua_pushnil(l); + } + return 1; + } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for nullptr +template <> struct lua_type_traits { + typedef const std::nullptr_t &push_type; + typedef std::nullptr_t get_type; + typedef optional opt_type; + + static bool checkType(lua_State *l, int index) { + return lua_isnoneornil(l, index); + } + static bool strictCheckType(lua_State *l, int index) { + return lua_isnil(l, index); + } + static opt_type opt(lua_State *l, int index) { + if (!lua_isnoneornil(l, index)) { + return opt_type(); + } + return nullptr; + } + static get_type get(lua_State *l, int index) { + if (!lua_isnoneornil(l, index)) { + throw LuaTypeMismatch(); + } + return nullptr; + } + + static int push(lua_State *l, const std::nullptr_t &) { + lua_pushnil(l); + return 1; + } +}; #endif - /// @ingroup lua_type_traits - /// @brief lua_type_traits for ObjectWrapperBase* - template<> struct lua_type_traits { - typedef ObjectWrapperBase* get_type; - typedef ObjectWrapperBase* push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return object_wrapper(l, index) != 0; - } - static bool checkType(lua_State* l, int index) - { - return object_wrapper(l, index) != 0; - } - static get_type get(lua_State* l, int index) - { - return object_wrapper(l, index); - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for native type of luathread(lua_State*) - template<> struct lua_type_traits { - typedef lua_State* get_type; - typedef lua_State* push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_isthread(l, index); - } - static bool checkType(lua_State* l, int index) - { - return lua_isthread(l, index); - } - static lua_State* get(lua_State* l, int index) - { - return lua_tothread(l, index); - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for floating point number value - template struct lua_type_traits < T - , typename traits::enable_if::value>::type > - { - typedef typename traits::remove_const_reference::type get_type; - typedef optional opt_type; - typedef lua_Number push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TNUMBER; - } - static bool checkType(lua_State* l, int index) - { - return lua_isnumber(l, index) != 0; - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - int isnum = 0; - get_type num = static_cast(lua_tonumberx(l, index, &isnum)); - if (!isnum) { - return opt_type(); - } - return num; - } - static get_type get(lua_State* l, int index) - { - int isnum=0; - get_type num = static_cast(lua_tonumberx(l,index,&isnum)); - if (!isnum) { - throw LuaTypeMismatch(); - } - return num; - } - static int push(lua_State* l, lua_Number s) - { - lua_pushnumber(l, s); - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for integral number value - template struct lua_type_traits::value>::type> - { - typedef typename traits::remove_const_reference::type get_type; - typedef optional opt_type; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for ObjectWrapperBase* +template <> struct lua_type_traits { + typedef ObjectWrapperBase *get_type; + typedef ObjectWrapperBase *push_type; + + static bool strictCheckType(lua_State *l, int index) { + return object_wrapper(l, index) != 0; + } + static bool checkType(lua_State *l, int index) { + return object_wrapper(l, index) != 0; + } + static get_type get(lua_State *l, int index) { + return object_wrapper(l, index); + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for native type of luathread(lua_State*) +template <> struct lua_type_traits { + typedef lua_State *get_type; + typedef lua_State *push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_isthread(l, index); + } + static bool checkType(lua_State *l, int index) { + return lua_isthread(l, index); + } + static lua_State *get(lua_State *l, int index) { + return lua_tothread(l, index); + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for floating point number value +template +struct lua_type_traits< + T, typename traits::enable_if::value>::type> { + typedef typename traits::remove_const_reference::type get_type; + typedef optional opt_type; + typedef lua_Number push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TNUMBER; + } + static bool checkType(lua_State *l, int index) { + return lua_isnumber(l, index) != 0; + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + int isnum = 0; + get_type num = static_cast(lua_tonumberx(l, index, &isnum)); + if (!isnum) { + return opt_type(); + } + return num; + } + static get_type get(lua_State *l, int index) { + int isnum = 0; + get_type num = static_cast(lua_tonumberx(l, index, &isnum)); + if (!isnum) { + throw LuaTypeMismatch(); + } + return num; + } + static int push(lua_State *l, lua_Number s) { + lua_pushnumber(l, s); + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for integral number value +template +struct lua_type_traits< + T, typename traits::enable_if::value>::type> { + typedef typename traits::remove_const_reference::type get_type; + typedef optional opt_type; #if LUA_VERSION_NUM >= 503 - typedef lua_Integer push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_isinteger(l, index) != 0; - } - static bool checkType(lua_State* l, int index) - { - return lua_isnumber(l, index) != 0; - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - int isnum = 0; - get_type num = static_cast(lua_tointegerx(l, index, &isnum)); - if (!isnum) { - return opt_type(); - } - return num; - } - static get_type get(lua_State* l, int index) - { - int isnum = 0; - get_type num = static_cast(lua_tointegerx(l, index, &isnum)); - if (!isnum) { - throw LuaTypeMismatch(); - } - return num; - } - static int push(lua_State* l, lua_Integer s) - { - lua_pushinteger(l, s); - return 1; - } + typedef lua_Integer push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_isinteger(l, index) != 0; + } + static bool checkType(lua_State *l, int index) { + return lua_isnumber(l, index) != 0; + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + int isnum = 0; + get_type num = static_cast(lua_tointegerx(l, index, &isnum)); + if (!isnum) { + return opt_type(); + } + return num; + } + static get_type get(lua_State *l, int index) { + int isnum = 0; + get_type num = static_cast(lua_tointegerx(l, index, &isnum)); + if (!isnum) { + throw LuaTypeMismatch(); + } + return num; + } + static int push(lua_State *l, lua_Integer s) { + lua_pushinteger(l, s); + return 1; + } #else - typedef typename lua_type_traits::push_type push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type_traits::strictCheckType(l, index); - } - static bool checkType(lua_State* l, int index) - { - return lua_type_traits::checkType(l, index); - } - static get_type get(lua_State* l, int index) - { - return static_cast(lua_type_traits::get(l, index)); - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - lua_type_traits::opt_type v = lua_type_traits::opt(l, index); - if (!v) { - return opt_type(); - } - return static_cast(*v); - } - static int push(lua_State* l, push_type s) - { - return util::push_args(l, s); - } + typedef typename lua_type_traits::push_type push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type_traits::strictCheckType(l, index); + } + static bool checkType(lua_State *l, int index) { + return lua_type_traits::checkType(l, index); + } + static get_type get(lua_State *l, int index) { + return static_cast(lua_type_traits::get(l, index)); + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + lua_type_traits::opt_type v = + lua_type_traits::opt(l, index); + if (!v) { + return opt_type(); + } + return static_cast(*v); + } + static int push(lua_State *l, push_type s) { return util::push_args(l, s); } #endif - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for enum - template struct lua_type_traits::value>::type> - { - typedef typename traits::remove_const_reference::type get_type; - typedef optional opt_type; - typedef typename traits::remove_const_reference::type push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type_traits::strictCheckType(l, index); - } - static bool checkType(lua_State* l, int index) - { - return lua_type_traits::checkType(l, index); - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - if (lua_type_traits::opt_type t = lua_type_traits::opt(l, index)) - { - return opt_type(static_cast(*t)); - } - return opt_type(); - } - static get_type get(lua_State* l, int index) - { - return static_cast(lua_type_traits::get(l, index)); - } - static int push(lua_State* l, push_type s) - { - return util::push_args(l, static_cast::push_type>(s)); - } - }; - - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for cstring - template<> struct lua_type_traits { - typedef const char* get_type; - typedef optional opt_type; - typedef const char* push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TSTRING; - } - static bool checkType(lua_State* l, int index) - { - return lua_isstring(l, index) != 0; - } - static get_type get(lua_State* l, int index) - { - const char* buffer = lua_tostring(l, index); - if (!buffer) { - throw LuaTypeMismatch(); - } - return buffer; - } - static opt_type opt(lua_State* l, int index) - { - const char* buffer = lua_tostring(l, index); - if (!buffer) { - return opt_type(); - } - return buffer; - } - static int push(lua_State* l, const char* s) - { - lua_pushstring(l, s); - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for cstring - template struct lua_type_traits { - typedef std::string get_type; - typedef const char* push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TSTRING; - } - static bool checkType(lua_State* l, int index) - { - return lua_isstring(l, index) != 0; - } - static const char* get(lua_State* l, int index) - { - const char* buffer = lua_tostring(l, index); - if (!buffer) { - throw LuaTypeMismatch(); - } - return buffer; - } - static int push(lua_State* l, const char s[N]) - { - lua_pushlstring(l, s, s[N - 1] != '\0' ? N : N - 1); - return 1; - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for cstring - template struct lua_type_traits :lua_type_traits {}; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for std::string - template<> struct lua_type_traits { - typedef std::string get_type; - typedef optional opt_type; - typedef const std::string& push_type; - - static bool strictCheckType(lua_State* l, int index) - { - return lua_type(l, index) == LUA_TSTRING; - } - static bool checkType(lua_State* l, int index) - { - return lua_isstring(l, index) != 0; - } - static opt_type opt(lua_State* l, int index)KAGUYA_NOEXCEPT - { - size_t size = 0; - const char* buffer = lua_tolstring(l, index, &size); - if (!buffer) { - return opt_type(); - } - return std::string(buffer, size); - } - static get_type get(lua_State* l, int index) - { - if (opt_type o = opt(l, index)) - { - return *o; - } - throw LuaTypeMismatch(); - } - static int push(lua_State* l, const std::string& s) - { - lua_pushlstring(l, s.c_str(), s.size()); - return 1; - } - }; - - - struct NewTable { - NewTable() :reserve_array_(0), reserve_record_(0) {} - NewTable(int reserve_array, int reserve_record_) :reserve_array_(reserve_array), reserve_record_(reserve_record_) {} - int reserve_array_; - int reserve_record_; - }; - struct NewThread {}; - struct GlobalTable {}; - struct NilValue {}; - - struct NoTypeCheck {}; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for NewTable, push only - template<> struct lua_type_traits { - static int push(lua_State* l, const NewTable& table) - { - lua_createtable(l, table.reserve_array_, table.reserve_record_); - return 1; - } - }; - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for NewThread, push only - template<> struct lua_type_traits { - static int push(lua_State* l, const NewThread&) - { - lua_newthread(l); - return 1; - } - }; - /// @ingroup lua_type_traits - /// @brief lua_type_traits for NilValue, similar to nullptr_t - /// If you using C++11, recommend use nullptr instead. - template<> struct lua_type_traits { - typedef NilValue get_type; - typedef optional opt_type; - typedef NilValue push_type; - - static bool checkType(lua_State* l, int index) - { - return lua_isnoneornil(l, index); - } - static bool strictCheckType(lua_State* l, int index) - { - return lua_isnil(l, index); - } - - static opt_type opt(lua_State* l, int index) - { - if (!checkType(l, index)) { - return opt_type(); - } - return NilValue(); - } - static get_type get(lua_State* l, int index) - { - if (!checkType(l, index)) { - throw LuaTypeMismatch(); - } - return NilValue(); - } - static int push(lua_State* l, const NilValue&) - { - lua_pushnil(l); - return 1; - } - }; - inline std::ostream& operator<<(std::ostream& os, const NilValue&) - { - return os << "nil"; - } - inline bool operator==(const NilValue&, const NilValue&) - { - return true; - } - inline bool operator!=(const NilValue&, const NilValue&) - { - return false; - } - - /// @ingroup lua_type_traits - /// @brief lua_type_traits for GlobalTable, push only - template<> struct lua_type_traits { - static int push(lua_State* l, const GlobalTable&) - { - lua_pushglobaltable(l); - return 1; - } - }; - - - namespace detail - { - template - class LuaBasicTypeFunctions - { - template friend class LuaBasicTypeFunctions; - typedef void (LuaBasicTypeFunctions::*bool_type)() const; - void this_type_does_not_support_comparisons() const {} - - public: - enum value_type - { - TYPE_NONE = LUA_TNONE,//!< none type - TYPE_NIL = LUA_TNIL,//!< nil type - TYPE_BOOLEAN = LUA_TBOOLEAN,//!< boolean type - TYPE_LIGHTUSERDATA = LUA_TLIGHTUSERDATA,//!< light userdata type - TYPE_NUMBER = LUA_TNUMBER,//!< number type - TYPE_STRING = LUA_TSTRING,//!< string type - TYPE_TABLE = LUA_TTABLE,//!< table type - TYPE_FUNCTION = LUA_TFUNCTION,//!< function type - TYPE_USERDATA = LUA_TUSERDATA,//!< userdata type - TYPE_THREAD = LUA_TTHREAD//!< thread(coroutine) type - }; - - /// @brief If reference value is none or nil return true. Otherwise false. - bool isNilref_()const { - int t = type(); - return t == LUA_TNIL || t == LUA_TNONE; - } - - /// @brief Equivalent to `#` operator for strings and tables with no metamethods. - /// Follows Lua's reference manual documentation of `lua_rawlen`, ie. types other - /// than tables, strings or userdatas return 0. - /// @return Size of table, string length or userdata memory block size. - size_t size() const { - lua_State* state = state_(); - if (!state) { return 0; } - util::ScopedSavedStack save(state); - int index = pushStackIndex_(state); - - return lua_rawlen(state, index); - } - - //return type - int type() const - { - lua_State* state = state_(); - if (!state) - { - return LUA_TNONE; - } - util::ScopedSavedStack save(state); - return lua_type(state, pushStackIndex_(state)); - } - - //return type name - const char* typeName()const - { - return lua_typename(state_(), type()); - } - - operator bool_type() const - { - lua_State* state = state_(); - if (!state) - { - return 0;//hasn't lua_State - } - util::ScopedSavedStack save(state); - int stackindex = pushStackIndex_(state); - int t = lua_type(state, stackindex); - if (t == LUA_TNONE) - { - return 0;//none - } - return lua_toboolean(state, stackindex) ? &LuaBasicTypeFunctions::this_type_does_not_support_comparisons : 0; - } - - - /** - * @name relational operators - * @brief - */ - //@{ - template - inline bool operator==(const LuaBasicTypeFunctions& rhs)const - { - if (isNilref_() || rhs.isNilref_()) { return !isNilref_() == !rhs.isNilref_(); } - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int index = pushStackIndex_(state); - int rhsindex = rhs.pushStackIndex_(state); - return lua_compare(state, index, rhsindex, LUA_OPEQ) != 0; - } - template - inline bool operator<(const LuaBasicTypeFunctions& rhs)const - { - if (isNilref_() || rhs.isNilref_()) { return !isNilref_() != !rhs.isNilref_(); } - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int index = pushStackIndex_(state); - int rhsindex = rhs.pushStackIndex_(state); - return lua_compare(state, index, rhsindex, LUA_OPLT) != 0; - } - template - inline bool operator<=(const LuaBasicTypeFunctions& rhs)const - { - if (isNilref_() || rhs.isNilref_()) { return !isNilref_() == !rhs.isNilref_(); } - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int index = pushStackIndex_(state); - int rhsindex = rhs.pushStackIndex_(state); - return lua_compare(state, index, rhsindex, LUA_OPLE) != 0; - } - template - inline bool operator>=(const LuaBasicTypeFunctions& rhs)const - { - return rhs <= (*this); - } - template - inline bool operator>(const LuaBasicTypeFunctions& rhs)const - { - return rhs < (*this); - } - template - inline bool operator!=(const LuaBasicTypeFunctions& rhs)const - { - return !this->operator==(rhs); - } - - template - inline typename traits::enable_if*>::value, bool>::type operator==(const T& rhs)const - { - if (optional::get_type> d = checkGet_()) - { - return *d == rhs; - } - return false; - } - template - inline typename traits::enable_if*>::value, bool>::type operator!=(const T& rhs)const - { - return !((*this) == rhs); - } - //@} - - void dump(std::ostream& os)const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int stackIndex = pushStackIndex_(state); - util::stackValueDump(os, state, stackIndex); - } - private: - lua_State* state_()const - { - return static_cast(this)->state(); - } - int pushStackIndex_(lua_State* state)const - { - return static_cast(this)->pushStackIndex(state); - } - template - optional::get_type> checkGet_()const - { - lua_State* state = state_(); - util::ScopedSavedStack save(state); - int stackindex = pushStackIndex_(state); - return lua_type_traits::get_type> >::get(state, stackindex); - } - }; - template - inline std::ostream& operator<<(std::ostream& os, const LuaBasicTypeFunctions& ref) - { - ref.dump(os); - return os; - } - /** - * @name relational operators - * @brief - */ - //@{ - -#define KAGUYA_ENABLE_IF_NOT_LUAREF(RETTYPE) typename traits::enable_if*>::value, RETTYPE>::type - template - inline KAGUYA_ENABLE_IF_NOT_LUAREF(bool) operator == (const T& lhs, const LuaBasicTypeFunctions& rhs) - { - return rhs == lhs; - } - template - inline KAGUYA_ENABLE_IF_NOT_LUAREF(bool) operator != (const T& lhs, const LuaBasicTypeFunctions& rhs) - { - return !(rhs == lhs); - } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for enum +template +struct lua_type_traits< + T, typename traits::enable_if::value>::type> { + typedef typename traits::remove_const_reference::type get_type; + typedef optional opt_type; + typedef typename traits::remove_const_reference::type push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type_traits::strictCheckType(l, index); + } + static bool checkType(lua_State *l, int index) { + return lua_type_traits::checkType(l, index); + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + if (lua_type_traits::opt_type t = + lua_type_traits::opt(l, index)) { + return opt_type(static_cast(*t)); + } + return opt_type(); + } + static get_type get(lua_State *l, int index) { + return static_cast(lua_type_traits::get(l, index)); + } + static int push(lua_State *l, push_type s) { + return util::push_args( + l, static_cast::push_type>(s)); + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for cstring +template <> struct lua_type_traits { + typedef const char *get_type; + typedef optional opt_type; + typedef const char *push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TSTRING; + } + static bool checkType(lua_State *l, int index) { + return lua_isstring(l, index) != 0; + } + static get_type get(lua_State *l, int index) { + const char *buffer = lua_tostring(l, index); + if (!buffer) { + throw LuaTypeMismatch(); + } + return buffer; + } + static opt_type opt(lua_State *l, int index) { + const char *buffer = lua_tostring(l, index); + if (!buffer) { + return opt_type(); + } + return buffer; + } + static int push(lua_State *l, const char *s) { + lua_pushstring(l, s); + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for cstring +template struct lua_type_traits { + typedef std::string get_type; + typedef const char *push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TSTRING; + } + static bool checkType(lua_State *l, int index) { + return lua_isstring(l, index) != 0; + } + static const char *get(lua_State *l, int index) { + const char *buffer = lua_tostring(l, index); + if (!buffer) { + throw LuaTypeMismatch(); + } + return buffer; + } + static int push(lua_State *l, const char s[N]) { + lua_pushlstring(l, s, s[N - 1] != '\0' ? N : N - 1); + return 1; + } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for cstring +template +struct lua_type_traits : lua_type_traits {}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for std::string +template <> struct lua_type_traits { + typedef std::string get_type; + typedef optional opt_type; + typedef const std::string &push_type; + + static bool strictCheckType(lua_State *l, int index) { + return lua_type(l, index) == LUA_TSTRING; + } + static bool checkType(lua_State *l, int index) { + return lua_isstring(l, index) != 0; + } + static opt_type opt(lua_State *l, int index) KAGUYA_NOEXCEPT { + size_t size = 0; + const char *buffer = lua_tolstring(l, index, &size); + if (!buffer) { + return opt_type(); + } + return std::string(buffer, size); + } + static get_type get(lua_State *l, int index) { + if (opt_type o = opt(l, index)) { + return *o; + } + throw LuaTypeMismatch(); + } + static int push(lua_State *l, const std::string &s) { + lua_pushlstring(l, s.c_str(), s.size()); + return 1; + } +}; + +struct NewTable { + NewTable() : reserve_array_(0), reserve_record_(0) {} + NewTable(int reserve_array, int reserve_record_) + : reserve_array_(reserve_array), reserve_record_(reserve_record_) {} + int reserve_array_; + int reserve_record_; +}; +struct NewThread {}; +struct GlobalTable {}; +struct NilValue {}; + +struct NoTypeCheck {}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for NewTable, push only +template <> struct lua_type_traits { + static int push(lua_State *l, const NewTable &table) { + lua_createtable(l, table.reserve_array_, table.reserve_record_); + return 1; + } +}; + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for NewThread, push only +template <> struct lua_type_traits { + static int push(lua_State *l, const NewThread &) { + lua_newthread(l); + return 1; + } +}; +/// @ingroup lua_type_traits +/// @brief lua_type_traits for NilValue, similar to nullptr_t +/// If you using C++11, recommend use nullptr instead. +template <> struct lua_type_traits { + typedef NilValue get_type; + typedef optional opt_type; + typedef NilValue push_type; + + static bool checkType(lua_State *l, int index) { + return lua_isnoneornil(l, index); + } + static bool strictCheckType(lua_State *l, int index) { + return lua_isnil(l, index); + } + + static opt_type opt(lua_State *l, int index) { + if (!checkType(l, index)) { + return opt_type(); + } + return NilValue(); + } + static get_type get(lua_State *l, int index) { + if (!checkType(l, index)) { + throw LuaTypeMismatch(); + } + return NilValue(); + } + static int push(lua_State *l, const NilValue &) { + lua_pushnil(l); + return 1; + } +}; +inline std::ostream &operator<<(std::ostream &os, const NilValue &) { + return os << "nil"; +} +inline bool operator==(const NilValue &, const NilValue &) { return true; } +inline bool operator!=(const NilValue &, const NilValue &) { return false; } + +/// @ingroup lua_type_traits +/// @brief lua_type_traits for GlobalTable, push only +template <> struct lua_type_traits { + static int push(lua_State *l, const GlobalTable &) { + lua_pushglobaltable(l); + return 1; + } +}; + +namespace detail { +template class LuaBasicTypeFunctions { + template friend class LuaBasicTypeFunctions; + typedef void (LuaBasicTypeFunctions::*bool_type)() const; + void this_type_does_not_support_comparisons() const {} + +public: + enum value_type { + TYPE_NONE = LUA_TNONE, //!< none type + TYPE_NIL = LUA_TNIL, //!< nil type + TYPE_BOOLEAN = LUA_TBOOLEAN, //!< boolean type + TYPE_LIGHTUSERDATA = LUA_TLIGHTUSERDATA, //!< light userdata type + TYPE_NUMBER = LUA_TNUMBER, //!< number type + TYPE_STRING = LUA_TSTRING, //!< string type + TYPE_TABLE = LUA_TTABLE, //!< table type + TYPE_FUNCTION = LUA_TFUNCTION, //!< function type + TYPE_USERDATA = LUA_TUSERDATA, //!< userdata type + TYPE_THREAD = LUA_TTHREAD //!< thread(coroutine) type + }; + + /// @brief If reference value is none or nil return true. Otherwise false. + bool isNilref_() const { + int t = type(); + return t == LUA_TNIL || t == LUA_TNONE; + } + + /// @brief Equivalent to `#` operator for strings and tables with no + /// metamethods. + /// Follows Lua's reference manual documentation of `lua_rawlen`, ie. types + /// other + /// than tables, strings or userdatas return 0. + /// @return Size of table, string length or userdata memory block size. + size_t size() const { + lua_State *state = state_(); + if (!state) { + return 0; + } + util::ScopedSavedStack save(state); + int index = pushStackIndex_(state); + + return lua_rawlen(state, index); + } + + // return type + int type() const { + lua_State *state = state_(); + if (!state) { + return LUA_TNONE; + } + util::ScopedSavedStack save(state); + return lua_type(state, pushStackIndex_(state)); + } + + // return type name + const char *typeName() const { return lua_typename(state_(), type()); } + + operator bool_type() const { + lua_State *state = state_(); + if (!state) { + return 0; // hasn't lua_State + } + util::ScopedSavedStack save(state); + int stackindex = pushStackIndex_(state); + int t = lua_type(state, stackindex); + if (t == LUA_TNONE) { + return 0; // none + } + return lua_toboolean(state, stackindex) + ? &LuaBasicTypeFunctions::this_type_does_not_support_comparisons + : 0; + } + + /** + * @name relational operators + * @brief + */ + //@{ + template + inline bool operator==(const LuaBasicTypeFunctions &rhs) const { + if (isNilref_() || rhs.isNilref_()) { + return !isNilref_() == !rhs.isNilref_(); + } + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int index = pushStackIndex_(state); + int rhsindex = rhs.pushStackIndex_(state); + return lua_compare(state, index, rhsindex, LUA_OPEQ) != 0; + } + template + inline bool operator<(const LuaBasicTypeFunctions &rhs) const { + if (isNilref_() || rhs.isNilref_()) { + return !isNilref_() != !rhs.isNilref_(); + } + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int index = pushStackIndex_(state); + int rhsindex = rhs.pushStackIndex_(state); + return lua_compare(state, index, rhsindex, LUA_OPLT) != 0; + } + template + inline bool operator<=(const LuaBasicTypeFunctions &rhs) const { + if (isNilref_() || rhs.isNilref_()) { + return !isNilref_() == !rhs.isNilref_(); + } + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int index = pushStackIndex_(state); + int rhsindex = rhs.pushStackIndex_(state); + return lua_compare(state, index, rhsindex, LUA_OPLE) != 0; + } + template + inline bool operator>=(const LuaBasicTypeFunctions &rhs) const { + return rhs <= (*this); + } + template + inline bool operator>(const LuaBasicTypeFunctions &rhs) const { + return rhs < (*this); + } + template + inline bool operator!=(const LuaBasicTypeFunctions &rhs) const { + return !this->operator==(rhs); + } + + template + inline typename traits::enable_if< + !traits::is_convertible *>::value, + bool>::type + operator==(const T &rhs) const { + if (optional::get_type> d = checkGet_()) { + return *d == rhs; + } + return false; + } + template + inline typename traits::enable_if< + !traits::is_convertible *>::value, + bool>::type + operator!=(const T &rhs) const { + return !((*this) == rhs); + } + //@} + + void dump(std::ostream &os) const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int stackIndex = pushStackIndex_(state); + util::stackValueDump(os, state, stackIndex); + } + +private: + lua_State *state_() const { + return static_cast(this)->state(); + } + int pushStackIndex_(lua_State *state) const { + return static_cast(this)->pushStackIndex(state); + } + template + optional::get_type> checkGet_() const { + lua_State *state = state_(); + util::ScopedSavedStack save(state); + int stackindex = pushStackIndex_(state); + return lua_type_traits< + optional::get_type> >::get(state, + stackindex); + } +}; +template +inline std::ostream &operator<<(std::ostream &os, + const LuaBasicTypeFunctions &ref) { + ref.dump(os); + return os; +} +/** +* @name relational operators +* @brief +*/ +//@{ + +#define KAGUYA_ENABLE_IF_NOT_LUAREF(RETTYPE) \ + typename traits::enable_if< \ + !traits::is_convertible *>::value, \ + RETTYPE>::type +template +inline KAGUYA_ENABLE_IF_NOT_LUAREF(bool) +operator==(const T &lhs, const LuaBasicTypeFunctions &rhs) { + return rhs == lhs; +} +template +inline KAGUYA_ENABLE_IF_NOT_LUAREF(bool) +operator!=(const T &lhs, const LuaBasicTypeFunctions &rhs) { + return !(rhs == lhs); +} #undef KAGUYA_ENABLE_IF_NOT_LUAREF - //@} - } - - +//@} +} } diff --git a/include/kaguya/utility.hpp b/include/kaguya/utility.hpp index 32d8035..5074ea5 100644 --- a/include/kaguya/utility.hpp +++ b/include/kaguya/utility.hpp @@ -5,6 +5,10 @@ #pragma once #include +#if KAGUYA_USE_CXX_ABI_DEMANGLE +#include +#endif + #include "kaguya/config.hpp" #include "kaguya/compatibility.hpp" #include "kaguya/traits.hpp" @@ -17,248 +21,212 @@ #include "kaguya/utility_cxx03.hpp" #endif -#if KAGUYA_USE_CXX_ABI_DEMANGLE -#include -#endif - -namespace kaguya -{ - namespace util - { - /// @brief save stack count and restore on destructor - class ScopedSavedStack { - lua_State * state_; - int saved_top_index_; - - public: - /// @brief save stack count - /// @param state - explicit ScopedSavedStack(lua_State * state) - : state_(state), - saved_top_index_(state_ ? lua_gettop(state_):0) - { - } - - /// @brief save stack count - /// @param state - /// @param count stack count - explicit ScopedSavedStack(lua_State * state, int count) - : state_(state), - saved_top_index_(count) - {} - - /// @brief restore stack count - ~ScopedSavedStack() { - if (state_) { - lua_settop(state_, saved_top_index_); - } - } - - private: - ScopedSavedStack(ScopedSavedStack const &); - ScopedSavedStack & operator=(ScopedSavedStack const &); - }; - inline void traceBack(lua_State* state, const char* message, int level = 0) - { +namespace kaguya { +namespace util { +/// @brief save stack count and restore on destructor +class ScopedSavedStack { + lua_State *state_; + int saved_top_index_; + +public: + /// @brief save stack count + /// @param state + explicit ScopedSavedStack(lua_State *state) + : state_(state), saved_top_index_(state_ ? lua_gettop(state_) : 0) {} + + /// @brief save stack count + /// @param state + /// @param count stack count + explicit ScopedSavedStack(lua_State *state, int count) + : state_(state), saved_top_index_(count) {} + + /// @brief restore stack count + ~ScopedSavedStack() { + if (state_) { + lua_settop(state_, saved_top_index_); + } + } + +private: + ScopedSavedStack(ScopedSavedStack const &); + ScopedSavedStack &operator=(ScopedSavedStack const &); +}; +inline void traceBack(lua_State *state, const char *message, int level = 0) { #if LUA_VERSION_NUM >= 502 - luaL_traceback(state, state, message, level); + luaL_traceback(state, state, message, level); #else - KAGUYA_UNUSED(level); - lua_pushstring(state, message); + KAGUYA_UNUSED(level); + lua_pushstring(state, message); #endif - } - - inline void stackDump(lua_State *L) { - int i; - int top = lua_gettop(L); - for (i = 1; i <= top; i++) { /* repeat for each level */ - int t = lua_type(L, i); - switch (t) { - - case LUA_TSTRING: /* strings */ - printf("`%s'", lua_tostring(L, i)); - break; - - case LUA_TBOOLEAN: /* booleans */ - printf(lua_toboolean(L, i) ? "true" : "false"); - break; - - case LUA_TNUMBER: /* numbers */ - printf("%g", lua_tonumber(L, i)); - break; - case LUA_TUSERDATA: - if (luaL_getmetafield(L, i, "__name") == LUA_TSTRING) - { - printf("userdata:%s", lua_tostring(L, -1)); - lua_pop(L, 1); - break; - } - default: /* other values */ - printf("%s", lua_typename(L, t)); - break; - - } - printf(" "); /* put a separator */ - } - printf("\n"); /* end the listing */ - } - - inline void stackValueDump(std::ostream& os, lua_State* state, int stackIndex, int max_recursive = 2) - { - stackIndex = lua_absindex(state, stackIndex); - util::ScopedSavedStack save(state); - int type = lua_type(state, stackIndex); - switch (type) - { - case LUA_TNONE: - os << "none"; - break; - case LUA_TNIL: - os << "nil"; - break; - case LUA_TBOOLEAN: - os << ((lua_toboolean(state, stackIndex) != 0) ? "true" : "false"); - break; - case LUA_TNUMBER: - os << lua_tonumber(state, stackIndex); - break; - case LUA_TSTRING: - os << "'" << lua_tostring(state, stackIndex) << "'"; - break; - case LUA_TTABLE: - { - os << "{"; - if (max_recursive <= 1) - { - os << "..."; - } - else - { - lua_pushnil(state); - if ((lua_next(state, stackIndex) != 0)) - { - stackValueDump(os, state, -2, max_recursive - 1); - os << "="; - stackValueDump(os, state, -1, max_recursive - 1); - lua_pop(state, 1);//pop value - - while (lua_next(state, stackIndex) != 0) - { - os << ","; - stackValueDump(os, state, -2, max_recursive - 1); - os << "="; - stackValueDump(os, state, -1, max_recursive - 1); - lua_pop(state, 1);//pop value - } - } - } - os << "}"; - } - break; - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - case LUA_TTHREAD: - os << lua_typename(state, type) << "(" << lua_topointer(state, stackIndex) << ")"; - break; - case LUA_TFUNCTION: - os << lua_typename(state, type); - break; - default: - os << "unknown type value"; - break; - } - } - +} +inline void stackDump(lua_State *L) { + int i; + int top = lua_gettop(L); + for (i = 1; i <= top; i++) { /* repeat for each level */ + int t = lua_type(L, i); + switch (t) { + + case LUA_TSTRING: /* strings */ + printf("`%s'", lua_tostring(L, i)); + break; + + case LUA_TBOOLEAN: /* booleans */ + printf(lua_toboolean(L, i) ? "true" : "false"); + break; + + case LUA_TNUMBER: /* numbers */ + printf("%g", lua_tonumber(L, i)); + break; + case LUA_TUSERDATA: + if (luaL_getmetafield(L, i, "__name") == LUA_TSTRING) { + printf("userdata:%s", lua_tostring(L, -1)); + lua_pop(L, 1); + break; + } + default: /* other values */ + printf("%s", lua_typename(L, t)); + break; + } + printf(" "); /* put a separator */ + } + printf("\n"); /* end the listing */ +} +inline void stackValueDump(std::ostream &os, lua_State *state, int stackIndex, + int max_recursive = 2) { + stackIndex = lua_absindex(state, stackIndex); + util::ScopedSavedStack save(state); + int type = lua_type(state, stackIndex); + switch (type) { + case LUA_TNONE: + os << "none"; + break; + case LUA_TNIL: + os << "nil"; + break; + case LUA_TBOOLEAN: + os << ((lua_toboolean(state, stackIndex) != 0) ? "true" : "false"); + break; + case LUA_TNUMBER: + os << lua_tonumber(state, stackIndex); + break; + case LUA_TSTRING: + os << "'" << lua_tostring(state, stackIndex) << "'"; + break; + case LUA_TTABLE: { + os << "{"; + if (max_recursive <= 1) { + os << "..."; + } else { + lua_pushnil(state); + if ((lua_next(state, stackIndex) != 0)) { + stackValueDump(os, state, -2, max_recursive - 1); + os << "="; + stackValueDump(os, state, -1, max_recursive - 1); + lua_pop(state, 1); // pop value + + while (lua_next(state, stackIndex) != 0) { + os << ","; + stackValueDump(os, state, -2, max_recursive - 1); + os << "="; + stackValueDump(os, state, -1, max_recursive - 1); + lua_pop(state, 1); // pop value + } + } + } + os << "}"; + } break; + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + case LUA_TTHREAD: + os << lua_typename(state, type) << "(" << lua_topointer(state, stackIndex) + << ")"; + break; + case LUA_TFUNCTION: + os << lua_typename(state, type); + break; + default: + os << "unknown type value"; + break; + } +} - inline lua_State* toMainThread(lua_State* state) - { +inline lua_State *toMainThread(lua_State *state) { #if LUA_VERSION_NUM >= 502 - if (state) - { - lua_rawgeti(state, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); - lua_State* mainthread = lua_tothread(state, -1); - lua_pop(state, 1); - if (mainthread) - { - return mainthread; - } - } + if (state) { + lua_rawgeti(state, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD); + lua_State *mainthread = lua_tothread(state, -1); + lua_pop(state, 1); + if (mainthread) { + return mainthread; + } + } #endif - return state; - } + return state; +} #if KAGUYA_USE_CPP11 - inline int push_args(lua_State *) - { - return 0; - } - template - inline int push_args(lua_State *l, Arg&& arg, Args&&... args) - { - int c = lua_type_traits::type>::push(l, std::forward(arg)); - return c + push_args(l, std::forward(args)...); - } - template - inline int push_args(lua_State *l, const Arg& arg, Args&&... args) - { - int c = lua_type_traits::push(l, arg); - return c + push_args(l, std::forward(args)...); - } +inline int push_args(lua_State *) { return 0; } +template +inline int push_args(lua_State *l, Arg &&arg, Args &&... args) { + int c = lua_type_traits::type>::push( + l, std::forward(arg)); + return c + push_args(l, std::forward(args)...); +} +template +inline int push_args(lua_State *l, const Arg &arg, Args &&... args) { + int c = lua_type_traits::push(l, arg); + return c + push_args(l, std::forward(args)...); +} #else - inline int push_args(lua_State *) - { - return 0; - } - -#define KAGUYA_PUSH_DEF(N) c+=lua_type_traits::push(l, KAGUYA_PP_CAT(a,N)); -#define KAGUYA_PUSH_ARG_DEF(N) template\ - inline int push_args(lua_State *l,KAGUYA_PP_ARG_CR_DEF_REPEAT(N))\ - {\ - int c =0;\ - KAGUYA_PP_REPEAT(N,KAGUYA_PUSH_DEF)\ - return c;\ - } - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_PUSH_ARG_DEF) +inline int push_args(lua_State *) { return 0; } + +#define KAGUYA_PUSH_DEF(N) \ + c += lua_type_traits::push(l, KAGUYA_PP_CAT(a, N)); +#define KAGUYA_PUSH_ARG_DEF(N) \ + template \ + inline int push_args(lua_State *l, KAGUYA_PP_ARG_CR_DEF_REPEAT(N)) { \ + int c = 0; \ + KAGUYA_PP_REPEAT(N, KAGUYA_PUSH_DEF) \ + return c; \ + } +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_PUSH_ARG_DEF) #undef KAGUYA_PUSH_DEF #undef KAGUYA_PUSH_ARG_DEF #endif - #if KAGUYA_USE_CPP11 - template - inline bool one_push(lua_State* state, T&& v) - { - int count = util::push_args(state, std::forward(v)); - if (count > 1) { lua_pop(state, count - 1); } - return count != 0; - } +template inline bool one_push(lua_State *state, T &&v) { + int count = util::push_args(state, std::forward(v)); + if (count > 1) { + lua_pop(state, count - 1); + } + return count != 0; +} #else - template - inline bool one_push(lua_State* state, const T& v) - { - int count = util::push_args(state, v); - if (count > 1) { lua_pop(state, count - 1); } - return count != 0; - } +template inline bool one_push(lua_State *state, const T &v) { + int count = util::push_args(state, v); + if (count > 1) { + lua_pop(state, count - 1); + } + return count != 0; +} #endif - - inline std::string pretty_name(const std::type_info& t) - { +inline std::string pretty_name(const std::type_info &t) { #if KAGUYA_USE_CXX_ABI_DEMANGLE - int status = 0; - char* demangle_name = abi::__cxa_demangle(t.name(), 0, 0, &status); - struct deleter { - char* data; - deleter(char* d):data(d){} - ~deleter(){ std::free(data); } - }d(demangle_name); - return demangle_name; + int status = 0; + char *demangle_name = abi::__cxa_demangle(t.name(), 0, 0, &status); + struct deleter { + char *data; + deleter(char *d) : data(d) {} + ~deleter() { std::free(data); } + } d(demangle_name); + return demangle_name; #else - return t.name(); + return t.name(); #endif - } - } +} +} } diff --git a/include/kaguya/utility_cxx03.hpp b/include/kaguya/utility_cxx03.hpp index 8f44c2e..80e9ef0 100644 --- a/include/kaguya/utility_cxx03.hpp +++ b/include/kaguya/utility_cxx03.hpp @@ -8,165 +8,169 @@ #include "kaguya/config.hpp" -namespace kaguya -{ - namespace util - { - ///! - struct null_type {}; +namespace kaguya { +namespace util { +///! +struct null_type {}; +#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(typename A, N) = null_type +#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) \ + KAGUYA_PP_REPEAT_ARG(N, KAGUYA_PP_STRUCT_TDEF_REP) -#define KAGUYA_PP_STRUCT_TDEF_REP(N) KAGUYA_PP_CAT(typename A,N) = null_type -#define KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT(N) KAGUYA_PP_REPEAT_ARG(N,KAGUYA_PP_STRUCT_TDEF_REP) +template +struct TypeTuple {}; - template - struct TypeTuple { - }; +template struct TypeTupleSize; - templatestruct TypeTupleSize; +#define KAGUYA_TYPE_TUPLE_SIZE_DEF(N) \ + template \ + struct TypeTupleSize > { \ + static const size_t value = N; \ + }; -#define KAGUYA_TYPE_TUPLE_SIZE_DEF(N) \ - template< KAGUYA_PP_TEMPLATE_DEF_REPEAT(N)>\ - struct TypeTupleSize >\ - {\ - static const size_t value = N;\ - };\ - - KAGUYA_TYPE_TUPLE_SIZE_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_TYPE_TUPLE_SIZE_DEF) +KAGUYA_TYPE_TUPLE_SIZE_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_TYPE_TUPLE_SIZE_DEF) #undef KAGUYA_TYPE_TUPLE_SIZE_DEF - templatestruct CFuntionType; -#define KAGUYA_CFUNCTION_TYPE_DEF(N) \ - template\ - struct CFuntionType >\ - {\ - typedef Ret (*type)(KAGUYA_PP_TEMPLATE_ARG_REPEAT(N));\ - };\ +template struct CFuntionType; +#define KAGUYA_CFUNCTION_TYPE_DEF(N) \ + template \ + struct CFuntionType > { \ + typedef Ret (*type)(KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)); \ + }; - KAGUYA_CFUNCTION_TYPE_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CFUNCTION_TYPE_DEF) +KAGUYA_CFUNCTION_TYPE_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_CFUNCTION_TYPE_DEF) #undef KAGUYA_CFUNCTION_TYPE_DEF - - template - struct FunctionSignatureType { - typedef Ret result_type; - typedef TypeTuple argument_type_tuple; - static const size_t argument_count = TypeTupleSize::value; - typedef typename CFuntionType::type c_function_type; - }; - - template - struct FunctionSignature ; - -#define KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF(N) \ - template \ - struct FunctionSignature {\ - typedef FunctionSignatureType type;\ - };\ - template \ - struct FunctionSignature {\ - typedef FunctionSignatureType type;\ - };\ - - -#define KAGUYA_FUNCTION_SIGNATURE_DEF(N) \ - template\ - struct FunctionSignature {\ - typedef FunctionSignatureType type;\ - };\ - template\ - struct FunctionSignature {\ - typedef FunctionSignatureType type;\ - };\ - template\ - struct FunctionSignature > {\ - typedef FunctionSignatureType type;\ - };\ - - KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_PP_DEC(KAGUYA_FUNCTION_MAX_ARGS), KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF) +template +struct FunctionSignatureType { + typedef Ret result_type; + typedef TypeTuple + argument_type_tuple; + static const size_t argument_count = + TypeTupleSize::value; + typedef typename CFuntionType::type c_function_type; +}; + +template struct FunctionSignature; + +#define KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF(N) \ + template \ + struct FunctionSignature { \ + typedef FunctionSignatureType \ + type; \ + }; \ + template \ + struct FunctionSignature { \ + typedef FunctionSignatureType< \ + Ret, const T & KAGUYA_PP_TEMPLATE_ARG_REPEAT_CONCAT(N)> \ + type; \ + }; + +#define KAGUYA_FUNCTION_SIGNATURE_DEF(N) \ + template \ + struct FunctionSignature { \ + typedef FunctionSignatureType \ + type; \ + }; \ + template \ + struct FunctionSignature { \ + typedef FunctionSignatureType \ + type; \ + }; \ + template \ + struct FunctionSignature< \ + standard::function > { \ + typedef FunctionSignatureType \ + type; \ + }; + +KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_PP_DEC(KAGUYA_FUNCTION_MAX_ARGS), + KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF) #undef KAGUYA_MEMBER_FUNCTION_SIGNATURE_DEF - KAGUYA_FUNCTION_SIGNATURE_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_FUNCTION_SIGNATURE_DEF) +KAGUYA_FUNCTION_SIGNATURE_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_FUNCTION_SIGNATURE_DEF) #undef KAGUYA_FUNCTION_SIGNATURE_DEF - template - struct FunctionResultType - { - typedef typename FunctionSignature::type::result_type type; - }; - - template - struct TypeIndexGet - { - }; - -#define KAGUYA_TYPE_INDEX_GET_DEF(N) \ - template\ - struct TypeIndexGet, true>\ - {\ - typedef arg type;\ - };\ - template\ - struct TypeIndexGet, false>\ - : TypeIndexGet >\ - {\ - };\ +template struct FunctionResultType { + typedef typename FunctionSignature::type::result_type type; +}; + +template +struct TypeIndexGet {}; + +#define KAGUYA_TYPE_INDEX_GET_DEF(N) \ + template \ + struct TypeIndexGet< \ + remain, TypeTuple, true> { \ + typedef arg type; \ + }; \ + template \ + struct TypeIndexGet< \ + remain, TypeTuple, false> \ + : TypeIndexGet > {}; // KAGUYA_TYPE_INDEX_GET_DEF(0); - KAGUYA_PP_REPEAT_DEF(KAGUYA_PP_DEC(KAGUYA_FUNCTION_MAX_ARGS), KAGUYA_TYPE_INDEX_GET_DEF) +KAGUYA_PP_REPEAT_DEF(KAGUYA_PP_DEC(KAGUYA_FUNCTION_MAX_ARGS), + KAGUYA_TYPE_INDEX_GET_DEF) #undef KAGUYA_TYPE_INDEX_GET_DEF - template - struct ArgumentType - { - typedef typename TypeIndexGet::type::argument_type_tuple>::type type; - }; - - - namespace detail - { - -#define KAGUYA_INVOKE_HELPER_DEF(N) \ - template\ - typename FunctionResultType::type invoke_helper(typename FunctionResultType::type(T::*f)(KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)), ThisType this_ KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N))\ - {\ - return (this_.*f)(KAGUYA_PP_ARG_REPEAT(N));\ - }\ - template\ - typename FunctionResultType::type invoke_helper(typename FunctionResultType::type(T::*f)(KAGUYA_PP_TEMPLATE_ARG_REPEAT(N))const,ThisType this_ KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N))\ - {\ - return (this_.*f)(KAGUYA_PP_ARG_REPEAT(N));\ - }\ - template\ - typename FunctionResultType::type invoke_helper(F f KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N))\ - {\ - return f(KAGUYA_PP_ARG_REPEAT(N));\ - }\ - - KAGUYA_INVOKE_HELPER_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_INVOKE_HELPER_DEF) +template struct ArgumentType { + typedef typename TypeIndexGet< + N, typename FunctionSignature::type::argument_type_tuple>::type type; +}; + +namespace detail { + +#define KAGUYA_INVOKE_HELPER_DEF(N) \ + template \ + typename FunctionResultType::type invoke_helper( \ + typename FunctionResultType::type (T::*f)( \ + KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)), \ + ThisType this_ KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N)) { \ + return (this_.*f)(KAGUYA_PP_ARG_REPEAT(N)); \ + } \ + template \ + typename FunctionResultType::type invoke_helper( \ + typename FunctionResultType::type (T::*f)( \ + KAGUYA_PP_TEMPLATE_ARG_REPEAT(N)) const, \ + ThisType this_ KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N)) { \ + return (this_.*f)(KAGUYA_PP_ARG_REPEAT(N)); \ + } \ + template \ + typename FunctionResultType::type invoke_helper( \ + F f KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N)) { \ + return f(KAGUYA_PP_ARG_REPEAT(N)); \ + } + +KAGUYA_INVOKE_HELPER_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_INVOKE_HELPER_DEF) #undef KAGUYA_INVOKE_HELPER_DEF - } - - -#define KAGUYA_INVOKE_DEF(N) \ - template\ - typename FunctionResultType::type invoke(F f KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N))\ - {\ - return detail::invoke_helper(f KAGUYA_PP_ARG_REPEAT_CONCAT(N)); \ - }\ - - KAGUYA_INVOKE_DEF(0) - KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_INVOKE_DEF) +} + +#define KAGUYA_INVOKE_DEF(N) \ + template \ + typename FunctionResultType::type invoke( \ + F f KAGUYA_PP_ARG_DEF_REPEAT_CONCAT(N)) { \ + return detail::invoke_helper( \ + f KAGUYA_PP_ARG_REPEAT_CONCAT(N)); \ + } + +KAGUYA_INVOKE_DEF(0) +KAGUYA_PP_REPEAT_DEF(KAGUYA_FUNCTION_MAX_ARGS, KAGUYA_INVOKE_DEF) #undef KAGUYA_INVOKE_DEF #undef KAGUYA_PP_STRUCT_TDEF_REP #undef KAGUYA_PP_STRUCT_TEMPLATE_DEF_REPEAT - - - } - +} } diff --git a/include/kaguya/utility_cxx11.hpp b/include/kaguya/utility_cxx11.hpp index 9b726d0..e611bf2 100644 --- a/include/kaguya/utility_cxx11.hpp +++ b/include/kaguya/utility_cxx11.hpp @@ -8,132 +8,113 @@ #include "kaguya/config.hpp" -namespace kaguya -{ - namespace util - { - struct null_type {}; - - template - struct TypeTuple { - }; - template - struct FunctionSignatureType { - typedef Ret result_type; - typedef TypeTuple argument_type_tuple; - static const size_t argument_count = sizeof...(Args); - typedef Ret(*c_function_type)(Args...); - }; - template - struct FunctorSignature {}; - - template - struct FunctorSignature { - typedef FunctionSignatureType type; - }; - template - struct FunctorSignature { - typedef FunctionSignatureType type; - }; +namespace kaguya { +namespace util { +struct null_type {}; + +template struct TypeTuple {}; +template struct FunctionSignatureType { + typedef Ret result_type; + typedef TypeTuple argument_type_tuple; + static const size_t argument_count = sizeof...(Args); + typedef Ret (*c_function_type)(Args...); +}; +template struct FunctorSignature {}; + +template +struct FunctorSignature { + typedef FunctionSignatureType type; +}; +template +struct FunctorSignature { + typedef FunctionSignatureType type; +}; #if defined(_MSC_VER) && _MSC_VER < 1900 - template - struct FunctionSignature : public FunctorSignature {}; +template +struct FunctionSignature : public FunctorSignature {}; #else - template - struct FunctionSignature; +template struct FunctionSignature; - template < typename T, typename = void> - struct has_operator_fn :std::false_type {}; - template < typename T > - struct has_operator_fn::value>::type> :std::true_type {}; +template +struct has_operator_fn : std::false_type {}; +template +struct has_operator_fn::value>::type> + : std::true_type {}; - template - struct FunctionSignature::value>::type> - : public FunctorSignature {}; +template +struct FunctionSignature< + T, typename std::enable_if::value>::type> + : public FunctorSignature {}; #endif - template - struct FunctionSignature { - typedef FunctionSignatureType type; - }; - template - struct FunctionSignature { - typedef FunctionSignatureType type; - }; +template +struct FunctionSignature { + typedef FunctionSignatureType type; +}; +template +struct FunctionSignature { + typedef FunctionSignatureType type; +}; #if defined(_MSC_VER) && _MSC_VER >= 1900 || defined(__cpp_ref_qualifiers) - template - struct FunctionSignature { - typedef FunctionSignatureType type; - }; - template - struct FunctionSignature { - typedef FunctionSignatureType type; - }; +template +struct FunctionSignature { + typedef FunctionSignatureType type; +}; +template +struct FunctionSignature { + typedef FunctionSignatureType type; +}; #endif +template struct FunctionSignature { + typedef FunctionSignatureType type; +}; +template struct FunctionSignature { + typedef FunctionSignatureType type; +}; + +template struct FunctionResultType { + typedef typename FunctionSignature::type::result_type type; +}; + +template +struct TypeIndexGet; + +template +struct TypeIndexGet, true> { + typedef Arg type; +}; + +template +struct TypeIndexGet, false> + : TypeIndexGet > {}; +template struct ArgumentType { + typedef typename TypeIndexGet< + N, typename FunctionSignature::type::argument_type_tuple>::type type; +}; + +namespace detail { +template +auto invoke_helper(F &&f, ThisType &&this_, Args &&... args) + -> decltype((std::forward(this_).* + f)(std::forward(args)...)) { + return (std::forward(this_).*f)(std::forward(args)...); +} - template - struct FunctionSignature { - typedef FunctionSignatureType type; - }; - template - struct FunctionSignature { - typedef FunctionSignatureType type; - }; - - template - struct FunctionResultType - { - typedef typename FunctionSignature::type::result_type type; - }; - - - - template - struct TypeIndexGet; - - template - struct TypeIndexGet, true> - { - typedef Arg type; - }; - - template - struct TypeIndexGet, false> - : TypeIndexGet > - { - }; - template - struct ArgumentType - { - typedef typename TypeIndexGet::type::argument_type_tuple>::type type; - }; - - - - namespace detail - { - template - auto invoke_helper(F&& f, ThisType&& this_, Args&&... args) -> decltype((std::forward(this_).*f)(std::forward(args)...)) - { - return (std::forward(this_).*f)(std::forward(args)...); - } - - template - auto invoke_helper(F&& f, Args&&... args) -> decltype(f(std::forward(args)...)) - { - return f(std::forward(args)...); - } - } - template - typename FunctionResultType::type>::type invoke(F&& f, Args&&... args) - { - return detail::invoke_helper(std::forward(f), std::forward(args)...); - } - - } - +template +auto invoke_helper(F &&f, Args &&... args) + -> decltype(f(std::forward(args)...)) { + return f(std::forward(args)...); +} +} +template +typename FunctionResultType::type>::type +invoke(F &&f, Args &&... args) { + return detail::invoke_helper(std::forward(f), std::forward(args)...); +} +} } diff --git a/test/test_01_primitive.cpp b/test/test_01_primitive.cpp index bf285aa..77e4347 100644 --- a/test/test_01_primitive.cpp +++ b/test/test_01_primitive.cpp @@ -1,317 +1,291 @@ #include "kaguya/kaguya.hpp" #include "test_util.hpp" - KAGUYA_TEST_GROUP_START(test_01_primitive) using namespace kaguya_test_util; -KAGUYA_TEST_FUNCTION_DEF(bool_get)(kaguya::State& state) -{ - state("value = true"); - TEST_EQUAL(state["value"], true); +KAGUYA_TEST_FUNCTION_DEF(bool_get)(kaguya::State &state) { + state("value = true"); + TEST_EQUAL(state["value"], true); } -KAGUYA_TEST_FUNCTION_DEF(int_get)(kaguya::State& state) -{ - state("value = 3"); - TEST_EQUAL(state["value"], int(3)); +KAGUYA_TEST_FUNCTION_DEF(int_get)(kaguya::State &state) { + state("value = 3"); + TEST_EQUAL(state["value"], int(3)); } -KAGUYA_TEST_FUNCTION_DEF(string_get)(kaguya::State& state) -{ - state("value = 'test'"); - TEST_EQUAL(state["value"], "test"); - TEST_EQUAL(state["value"], std::string("test")); +KAGUYA_TEST_FUNCTION_DEF(string_get)(kaguya::State &state) { + state("value = 'test'"); + TEST_EQUAL(state["value"], "test"); + TEST_EQUAL(state["value"], std::string("test")); } -KAGUYA_TEST_FUNCTION_DEF(table_get1)(kaguya::State& state) -{ - state("value = {1,32,'teststr'}"); +KAGUYA_TEST_FUNCTION_DEF(table_get1)(kaguya::State &state) { + state("value = {1,32,'teststr'}"); - TEST_EQUAL(state["value"][1], 1); - TEST_EQUAL(state["value"][2], 32); - TEST_EQUAL(state["value"][3], "teststr"); + TEST_EQUAL(state["value"][1], 1); + TEST_EQUAL(state["value"][2], 32); + TEST_EQUAL(state["value"][3], "teststr"); } -KAGUYA_TEST_FUNCTION_DEF(table_get2)(kaguya::State& state) -{ - state("value={out=32,str='gjgj'}"); - state("value['in'] = 'test'"); - kaguya::LuaRef value = state["value"]; - - TEST_EQUAL(value["str"], "gjgj"); - TEST_EQUAL(value["in"], "test"); - TEST_EQUAL(value["out"], "32"); +KAGUYA_TEST_FUNCTION_DEF(table_get2)(kaguya::State &state) { + state("value={out=32,str='gjgj'}"); + state("value['in'] = 'test'"); + kaguya::LuaRef value = state["value"]; + + TEST_EQUAL(value["str"], "gjgj"); + TEST_EQUAL(value["in"], "test"); + TEST_EQUAL(value["out"], "32"); } -KAGUYA_TEST_FUNCTION_DEF(bool_set)(kaguya::State& state) -{ - state["value"] = true; - TEST_EQUAL(state["value"] , true); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == true)")); - state["value"] = false; - TEST_EQUAL(state["value"], false); - TEST_CHECK(!state["value"]); - TEST_CHECK(state("assert(value == false)")); +KAGUYA_TEST_FUNCTION_DEF(bool_set)(kaguya::State &state) { + state["value"] = true; + TEST_EQUAL(state["value"], true); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == true)")); + state["value"] = false; + TEST_EQUAL(state["value"], false); + TEST_CHECK(!state["value"]); + TEST_CHECK(state("assert(value == false)")); } -KAGUYA_TEST_FUNCTION_DEF(int_set)(kaguya::State& state) -{ - state["value"] = 3; - TEST_EQUAL(state["value"], 3); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 3)")); - state["value"] = 0; - TEST_EQUAL(state["value"], 0); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 0)")); +KAGUYA_TEST_FUNCTION_DEF(int_set)(kaguya::State &state) { + state["value"] = 3; + TEST_EQUAL(state["value"], 3); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 3)")); + state["value"] = 0; + TEST_EQUAL(state["value"], 0); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 0)")); } -KAGUYA_TEST_FUNCTION_DEF(short_set)(kaguya::State& state) -{ - state["value"] = short(3); - TEST_EQUAL(state["value"], short(3)); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 3)")); - state["value"] = short(0); - TEST_EQUAL(state["value"], short(0)); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 0)")); +KAGUYA_TEST_FUNCTION_DEF(short_set)(kaguya::State &state) { + state["value"] = short(3); + TEST_EQUAL(state["value"], short(3)); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 3)")); + state["value"] = short(0); + TEST_EQUAL(state["value"], short(0)); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 0)")); } -KAGUYA_TEST_FUNCTION_DEF(char_set)(kaguya::State& state) -{ - state["value"] = char(3); - TEST_EQUAL(state["value"], char(3)); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 3)")); - state["value"] = char(0); - TEST_EQUAL(state["value"], char(0)); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 0)")); +KAGUYA_TEST_FUNCTION_DEF(char_set)(kaguya::State &state) { + state["value"] = char(3); + TEST_EQUAL(state["value"], char(3)); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 3)")); + state["value"] = char(0); + TEST_EQUAL(state["value"], char(0)); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 0)")); } -KAGUYA_TEST_FUNCTION_DEF(float_set)(kaguya::State& state) -{ - state["value"] = 5.5f; - TEST_EQUAL(state["value"], 5.5f); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 5.5,value)")); +KAGUYA_TEST_FUNCTION_DEF(float_set)(kaguya::State &state) { + state["value"] = 5.5f; + TEST_EQUAL(state["value"], 5.5f); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 5.5,value)")); } -KAGUYA_TEST_FUNCTION_DEF(double_set)(kaguya::State& state) -{ - state["value"] = 5.5; - TEST_EQUAL(state["value"], 5.5); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 5.5,value)")); +KAGUYA_TEST_FUNCTION_DEF(double_set)(kaguya::State &state) { + state["value"] = 5.5; + TEST_EQUAL(state["value"], 5.5); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 5.5,value)")); } - -KAGUYA_TEST_FUNCTION_DEF(string_set)(kaguya::State& state) -{ - state["value"] = "test"; - TEST_EQUAL(state["value"], "test"); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 'test')")); - state["value"] = "test2"; - TEST_EQUAL(state["value"], "test2"); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 'test2')")); - state["value"] = ""; - TEST_EQUAL(state["value"], ""); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == '')")); - - state["value"] = "false"; - TEST_EQUAL(state["value"], "false"); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 'false')")); - - state["value"] = std::string("test"); - TEST_EQUAL(state["value"], std::string("test")); - TEST_CHECK(state("assert(value == 'test')")); - - std::string org = std::string("t\0est", 5); - state["value"] = org; - TEST_EQUAL(state["value"], org); - - state["value"] = "t\0est"; - TEST_EQUAL(state["value"].size(), 5); - TEST_EQUAL(state["value"], std::string("t\0est",5)); +KAGUYA_TEST_FUNCTION_DEF(string_set)(kaguya::State &state) { + state["value"] = "test"; + TEST_EQUAL(state["value"], "test"); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 'test')")); + state["value"] = "test2"; + TEST_EQUAL(state["value"], "test2"); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 'test2')")); + state["value"] = ""; + TEST_EQUAL(state["value"], ""); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == '')")); + + state["value"] = "false"; + TEST_EQUAL(state["value"], "false"); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 'false')")); + + state["value"] = std::string("test"); + TEST_EQUAL(state["value"], std::string("test")); + TEST_CHECK(state("assert(value == 'test')")); + + std::string org = std::string("t\0est", 5); + state["value"] = org; + TEST_EQUAL(state["value"], org); + + state["value"] = "t\0est"; + TEST_EQUAL(state["value"].size(), 5); + TEST_EQUAL(state["value"], std::string("t\0est", 5)); } -KAGUYA_TEST_FUNCTION_DEF(table_set)(kaguya::State& state) -{ - state["value"] = kaguya::NewTable(); - state["value"]["abc"] = kaguya::NewTable(); - state["value"]["abc"]["def"] = 7; - state["value"]["abc"]["bbb"] = "test"; - TEST_CHECK(state("assert(value.abc.def == 7 and value.abc.bbb == 'test')")); +KAGUYA_TEST_FUNCTION_DEF(table_set)(kaguya::State &state) { + state["value"] = kaguya::NewTable(); + state["value"]["abc"] = kaguya::NewTable(); + state["value"]["abc"]["def"] = 7; + state["value"]["abc"]["bbb"] = "test"; + TEST_CHECK(state("assert(value.abc.def == 7 and value.abc.bbb == 'test')")); } -KAGUYA_TEST_FUNCTION_DEF(nilAndNull)(kaguya::State& state) -{ - // Nil and 0 resolve to different values - state["value"] = (void*)0; - TEST_CHECK(state("assert(value == nil)")); - TEST_CHECK(state("assert(value ~= 0)")); - state["value"] = kaguya::NilValue(); - TEST_CHECK(state("assert(value == nil)")); - TEST_CHECK(state("assert(value ~= 0)")); - state["value"] = 0; - TEST_CHECK(state("assert(value ~= nil)")); - TEST_CHECK(state("assert(value == 0)")); - - state("value = 0"); - TEST_CHECK(state["value"]); // !=nil && != false - TEST_CHECK(!state["value"].isNilref()); - TEST_CHECK(!state["value"].typeTest()); - TEST_CHECK(state["value"].typeTest()); - TEST_CHECK(state["value"].typeTest()); - TEST_EQUAL(state["value"], 0); - TEST_COMPARE_NE(state["value"], (void*)0); - TEST_COMPARE_NE(state["value"], kaguya::NilValue()); +KAGUYA_TEST_FUNCTION_DEF(nilAndNull)(kaguya::State &state) { + // Nil and 0 resolve to different values + state["value"] = (void *)0; + TEST_CHECK(state("assert(value == nil)")); + TEST_CHECK(state("assert(value ~= 0)")); + state["value"] = kaguya::NilValue(); + TEST_CHECK(state("assert(value == nil)")); + TEST_CHECK(state("assert(value ~= 0)")); + state["value"] = 0; + TEST_CHECK(state("assert(value ~= nil)")); + TEST_CHECK(state("assert(value == 0)")); + + state("value = 0"); + TEST_CHECK(state["value"]); // !=nil && != false + TEST_CHECK(!state["value"].isNilref()); + TEST_CHECK(!state["value"].typeTest()); + TEST_CHECK(state["value"].typeTest()); + TEST_CHECK(state["value"].typeTest()); + TEST_EQUAL(state["value"], 0); + TEST_COMPARE_NE(state["value"], (void *)0); + TEST_COMPARE_NE(state["value"], kaguya::NilValue()); #if KAGUYA_USE_CPP11 - TEST_COMPARE_NE(state["value"], nullptr); + TEST_COMPARE_NE(state["value"], nullptr); #endif - - state("value = nil"); - TEST_CHECK(!state["value"]); - TEST_CHECK(state["value"].isNilref()); - TEST_CHECK(state["value"].typeTest()); - TEST_CHECK(!state["value"].typeTest()); - TEST_CHECK(!state["value"].typeTest()); - TEST_EQUAL(state["value"], (void*)0); - TEST_COMPARE_NE(state["value"], 0); - TEST_EQUAL(state["value"], kaguya::NilValue()); + + state("value = nil"); + TEST_CHECK(!state["value"]); + TEST_CHECK(state["value"].isNilref()); + TEST_CHECK(state["value"].typeTest()); + TEST_CHECK(!state["value"].typeTest()); + TEST_CHECK(!state["value"].typeTest()); + TEST_EQUAL(state["value"], (void *)0); + TEST_COMPARE_NE(state["value"], 0); + TEST_EQUAL(state["value"], kaguya::NilValue()); #if KAGUYA_USE_CPP11 - TEST_EQUAL(state["value"], nullptr); + TEST_EQUAL(state["value"], nullptr); #endif } -KAGUYA_TEST_FUNCTION_DEF(optional_set)(kaguya::State& state) -{ - state["value"] = kaguya::optional(5.5); - TEST_EQUAL(state["value"], 5.5); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 5.5,value)")); - { - kaguya::optional v = state["value"].get >(); - TEST_EQUAL(*v, 5.5); - } - state["value"] = kaguya::optional(); - TEST_CHECK(state("assert(value == nil)")); - { - kaguya::optional v = state["value"].get >(); - TEST_CHECK(!v); - } - - - state["value"] = kaguya::optional("test"); - TEST_EQUAL(state["value"], "test"); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 'test')")); - { - kaguya::optional v = state["value"].get >(); - TEST_CHECK(strcmp(*v, "test")==0); - } - state["value"] = kaguya::optional(); - TEST_CHECK(state("assert(value == nil)")); - { - kaguya::optional v = state["value"].get >(); - TEST_CHECK(!v); - } - - - state["value"] = kaguya::optional("test"); - TEST_EQUAL(state["value"], "test"); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 'test')")); - { - kaguya::optional v = state["value"].get >(); - TEST_EQUAL(*v, "test"); - } - state["value"] = kaguya::optional(); - TEST_CHECK(state("assert(value == nil)")); - { - kaguya::optional v = state["value"].get >(); - TEST_CHECK(!v); - } +KAGUYA_TEST_FUNCTION_DEF(optional_set)(kaguya::State &state) { + state["value"] = kaguya::optional(5.5); + TEST_EQUAL(state["value"], 5.5); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 5.5,value)")); + { + kaguya::optional v = + state["value"].get >(); + TEST_EQUAL(*v, 5.5); + } + state["value"] = kaguya::optional(); + TEST_CHECK(state("assert(value == nil)")); + { + kaguya::optional v = + state["value"].get >(); + TEST_CHECK(!v); + } + + state["value"] = kaguya::optional("test"); + TEST_EQUAL(state["value"], "test"); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 'test')")); + { + kaguya::optional v = + state["value"].get >(); + TEST_CHECK(strcmp(*v, "test") == 0); + } + state["value"] = kaguya::optional(); + TEST_CHECK(state("assert(value == nil)")); + { + kaguya::optional v = + state["value"].get >(); + TEST_CHECK(!v); + } + + state["value"] = kaguya::optional("test"); + TEST_EQUAL(state["value"], "test"); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 'test')")); + { + kaguya::optional v = + state["value"].get >(); + TEST_EQUAL(*v, "test"); + } + state["value"] = kaguya::optional(); + TEST_CHECK(state("assert(value == nil)")); + { + kaguya::optional v = + state["value"].get >(); + TEST_CHECK(!v); + } } -enum testenum -{ - Foo = 0, - Bar = 1 -}; +enum testenum { Foo = 0, Bar = 1 }; -KAGUYA_TEST_FUNCTION_DEF(enum_set)(kaguya::State& state) -{ - state["value"] = Foo; - TEST_EQUAL(state["value"], Foo); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 0)")); +KAGUYA_TEST_FUNCTION_DEF(enum_set)(kaguya::State &state) { + state["value"] = Foo; + TEST_EQUAL(state["value"], Foo); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 0)")); } -KAGUYA_TEST_FUNCTION_DEF(enum_get)(kaguya::State& state) -{ - state("value = 1"); - TEST_EQUAL(state["value"], Bar); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 1)")); +KAGUYA_TEST_FUNCTION_DEF(enum_get)(kaguya::State &state) { + state("value = 1"); + TEST_EQUAL(state["value"], Bar); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 1)")); } - -KAGUYA_TEST_FUNCTION_DEF(minmax_overflow_check)(kaguya::State& state) -{ - state["value"] = std::numeric_limits::min(); - TEST_EQUAL(state["value"], std::numeric_limits::min()); - state["value"] = std::numeric_limits::max(); - TEST_EQUAL(state["value"], std::numeric_limits::max()); - - state["value"] = std::numeric_limits::min(); - TEST_EQUAL(state["value"], std::numeric_limits::min()); - state["value"] = std::numeric_limits::max(); - TEST_EQUAL(state["value"], std::numeric_limits::max()); - - state["value"] = std::numeric_limits::min(); - TEST_EQUAL(state["value"], std::numeric_limits::min()); - state["value"] = std::numeric_limits::max(); - TEST_EQUAL(state["value"], std::numeric_limits::max()); +KAGUYA_TEST_FUNCTION_DEF(minmax_overflow_check)(kaguya::State &state) { + state["value"] = std::numeric_limits::min(); + TEST_EQUAL(state["value"], std::numeric_limits::min()); + state["value"] = std::numeric_limits::max(); + TEST_EQUAL(state["value"], std::numeric_limits::max()); + + state["value"] = std::numeric_limits::min(); + TEST_EQUAL(state["value"], std::numeric_limits::min()); + state["value"] = std::numeric_limits::max(); + TEST_EQUAL(state["value"], std::numeric_limits::max()); + + state["value"] = std::numeric_limits::min(); + TEST_EQUAL(state["value"], std::numeric_limits::min()); + state["value"] = std::numeric_limits::max(); + TEST_EQUAL(state["value"], std::numeric_limits::max()); } - -KAGUYA_TEST_FUNCTION_DEF(map_set)(kaguya::State& state) -{ - std::map setmap; - setmap["3"] = 23232; - setmap["4"] = 232; - setmap["5"] = 23; - state["value"] = setmap; - TEST_CHECK(state["value"]); - TEST_CHECK(state["value"] == setmap); - - std::vector v; - TEST_CHECK(state["value"] != v); +KAGUYA_TEST_FUNCTION_DEF(map_set)(kaguya::State &state) { + std::map setmap; + setmap["3"] = 23232; + setmap["4"] = 232; + setmap["5"] = 23; + state["value"] = setmap; + TEST_CHECK(state["value"]); + TEST_CHECK(state["value"] == setmap); + + std::vector v; + TEST_CHECK(state["value"] != v); } -KAGUYA_TEST_FUNCTION_DEF(vector_set)(kaguya::State& state) -{ - std::vector setvec; - setvec.push_back("342"); - setvec.push_back("32"); - state["value"] = setvec; - TEST_CHECK(state["value"]); - TEST_CHECK(state["value"] == setvec); +KAGUYA_TEST_FUNCTION_DEF(vector_set)(kaguya::State &state) { + std::vector setvec; + setvec.push_back("342"); + setvec.push_back("32"); + state["value"] = setvec; + TEST_CHECK(state["value"]); + TEST_CHECK(state["value"] == setvec); - std::map m; - TEST_CHECK(state["value"] != m); + std::map m; + TEST_CHECK(state["value"] != m); } -KAGUYA_TEST_FUNCTION_DEF(vector_set2)(kaguya::State& state) -{ - std::vector > setvec; - setvec.push_back(std::vector(12, "332")); - setvec.push_back(std::vector(42, "3232")); - state["value"] = setvec; - TEST_CHECK(state["value"]); - TEST_CHECK(state["value"] == setvec); - - std::map m; - TEST_CHECK(state["value"] != m); +KAGUYA_TEST_FUNCTION_DEF(vector_set2)(kaguya::State &state) { + std::vector > setvec; + setvec.push_back(std::vector(12, "332")); + setvec.push_back(std::vector(42, "3232")); + state["value"] = setvec; + TEST_CHECK(state["value"]); + TEST_CHECK(state["value"] == setvec); + + std::map m; + TEST_CHECK(state["value"] != m); } - KAGUYA_TEST_GROUP_END(test_01_primitive) diff --git a/test/test_02_classreg.cpp b/test/test_02_classreg.cpp index f8226be..51f6348 100644 --- a/test/test_02_classreg.cpp +++ b/test/test_02_classreg.cpp @@ -1,1733 +1,1534 @@ #include "kaguya/kaguya.hpp" #include "test_util.hpp" +namespace { +struct SelfRefCounted { + static int all_object_count; // for simple leak check -namespace -{ - struct SelfRefCounted - { - static int all_object_count;//for simple leak check - - SelfRefCounted() :refcount(0) - { - all_object_count++; - } - virtual ~SelfRefCounted() { all_object_count--; } - - void AddRef() { refcount++; } - void ReleaseRef() { refcount--; - if (refcount == 0) - { - delete this; - } - } - - int get_ref_count()const { return refcount; } - - int refcount; - private: - SelfRefCounted(const SelfRefCounted&); - SelfRefCounted& operator=(const SelfRefCounted&); - }; - int SelfRefCounted::all_object_count = 0; - - struct RefObjectA : SelfRefCounted {}; - struct RefObjectB : SelfRefCounted {}; + SelfRefCounted() : refcount(0) { all_object_count++; } + virtual ~SelfRefCounted() { all_object_count--; } + + void AddRef() { refcount++; } + void ReleaseRef() { + refcount--; + if (refcount == 0) { + delete this; + } + } + + int get_ref_count() const { return refcount; } + + int refcount; + +private: + SelfRefCounted(const SelfRefCounted &); + SelfRefCounted &operator=(const SelfRefCounted &); +}; +int SelfRefCounted::all_object_count = 0; + +struct RefObjectA : SelfRefCounted {}; +struct RefObjectB : SelfRefCounted {}; } -namespace kaguya -{ - template - struct SelfRefCountedPtrWrapper : ObjectPointerWrapper - { - SelfRefCountedPtrWrapper(T* ptr):ObjectPointerWrapper(ptr) - { - if (ptr) - { - ptr->AddRef(); - } - } - virtual ~SelfRefCountedPtrWrapper() - { - if (ObjectPointerWrapper::object_) - { - ObjectPointerWrapper::object_->ReleaseRef(); - } - } - }; - - template - struct isSelfCountedObjectPointer : kaguya::standard::conditional< - kaguya::standard::is_convertible::value, - kaguya::standard::true_type, kaguya::standard::false_type>::type {}; - - template - struct ObjectPointerWrapperType::value>::type > - { - typedef SelfRefCountedPtrWrapper::type> type; - }; +namespace kaguya { +template struct SelfRefCountedPtrWrapper : ObjectPointerWrapper { + SelfRefCountedPtrWrapper(T *ptr) : ObjectPointerWrapper(ptr) { + if (ptr) { + ptr->AddRef(); + } + } + virtual ~SelfRefCountedPtrWrapper() { + if (ObjectPointerWrapper::object_) { + ObjectPointerWrapper::object_->ReleaseRef(); + } + } +}; + +template +struct isSelfCountedObjectPointer + : kaguya::standard::conditional< + kaguya::standard::is_convertible::value, + kaguya::standard::true_type, kaguya::standard::false_type>::type {}; + +template +struct ObjectPointerWrapperType< + T, typename traits::enable_if::value>::type> { + typedef SelfRefCountedPtrWrapper::type> type; +}; } KAGUYA_TEST_GROUP_START(test_02_classreg) using namespace kaguya_test_util; -struct ABC -{ - int intmember; - std::string stringmember; - - ABC() :intmember(0) {} - ABC(int a) :intmember(a) { } - ABC(const char* a) :intmember(0), stringmember(a) { } - ABC(std::string a) :intmember(0), stringmember(a) { } - ABC(int intmem, const std::string& strmem) :intmember(intmem), stringmember(strmem) { } - ABC(const std::string& strmem, int intmem) :intmember(intmem), stringmember(strmem) { } - ABC(const ABC&src) :intmember(src.intmember), stringmember(src.stringmember) {} - - - bool operator ==(const ABC& rhs)const { - return intmember == rhs.intmember && stringmember == rhs.stringmember; - } - bool operator <(const ABC& rhs)const { - return intmember < rhs.intmember || (intmember == rhs.intmember && stringmember < rhs.stringmember); - } - bool operator !=(const ABC& rhs)const { - return !(*this == rhs); - } - bool operator >(const ABC& rhs)const { - return (rhs < *this); - } - bool operator >=(const ABC& rhs)const { - return !(*this < rhs); - } - bool operator <=(const ABC& rhs)const { - return !(*this > rhs); - } - - int getInt() const { - return intmember; - } - void setInt(const int& n) { - intmember = n; - } - std::string getString()const { - return stringmember; - } - void setString(std::string str) { stringmember = str; } - - ABC copy()const { return *this; } - const ABC& references()const { return *this; } - const ABC& const_references()const { return *this; } - ABC& references() { return *this; } - ABC* pointer() { return this; } - const ABC* const_pointer()const { return this; } - kaguya::standard::shared_ptr shared_copy() { return kaguya::standard::shared_ptr(new ABC(*this)); } +struct ABC { + int intmember; + std::string stringmember; + + ABC() : intmember(0) {} + ABC(int a) : intmember(a) {} + ABC(const char *a) : intmember(0), stringmember(a) {} + ABC(std::string a) : intmember(0), stringmember(a) {} + ABC(int intmem, const std::string &strmem) + : intmember(intmem), stringmember(strmem) {} + ABC(const std::string &strmem, int intmem) + : intmember(intmem), stringmember(strmem) {} + ABC(const ABC &src) + : intmember(src.intmember), stringmember(src.stringmember) {} + + bool operator==(const ABC &rhs) const { + return intmember == rhs.intmember && stringmember == rhs.stringmember; + } + bool operator<(const ABC &rhs) const { + return intmember < rhs.intmember || + (intmember == rhs.intmember && stringmember < rhs.stringmember); + } + bool operator!=(const ABC &rhs) const { return !(*this == rhs); } + bool operator>(const ABC &rhs) const { return (rhs < *this); } + bool operator>=(const ABC &rhs) const { return !(*this < rhs); } + bool operator<=(const ABC &rhs) const { return !(*this > rhs); } + + int getInt() const { return intmember; } + void setInt(const int &n) { intmember = n; } + std::string getString() const { return stringmember; } + void setString(std::string str) { stringmember = str; } + + ABC copy() const { return *this; } + const ABC &references() const { return *this; } + const ABC &const_references() const { return *this; } + ABC &references() { return *this; } + ABC *pointer() { return this; } + const ABC *const_pointer() const { return this; } + kaguya::standard::shared_ptr shared_copy() { + return kaguya::standard::shared_ptr(new ABC(*this)); + } }; -KAGUYA_TEST_FUNCTION_DEF(default_constructor)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - ); +KAGUYA_TEST_FUNCTION_DEF(default_constructor)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors()); - TEST_CHECK(state("value = assert(ABC.new())")); + TEST_CHECK(state("value = assert(ABC.new())")); } -KAGUYA_TEST_FUNCTION_DEF(int_constructor)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getInt", &ABC::getInt) - ); - - TEST_CHECK(state("value = assert(ABC.new(32))")); - TEST_CHECK(state("assert(value:getInt() == 32)")); - TEST_EQUAL(state["value"]["getInt"](state["value"]), 32); - TEST_EQUAL((state["value"]->*"getInt")(), 32); +KAGUYA_TEST_FUNCTION_DEF(int_constructor)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors().addFunction( + "getInt", &ABC::getInt)); + + TEST_CHECK(state("value = assert(ABC.new(32))")); + TEST_CHECK(state("assert(value:getInt() == 32)")); + TEST_EQUAL(state["value"]["getInt"](state["value"]), 32); + TEST_EQUAL((state["value"]->*"getInt")(), 32); } -KAGUYA_TEST_FUNCTION_DEF(string_constructor)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getString", &ABC::getString) - ); - - TEST_CHECK(state("value = assert(ABC.new('string_value'))")); - TEST_CHECK(state("assert(value:getString() == 'string_value')")); -} -KAGUYA_TEST_FUNCTION_DEF(overloaded_constructor)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getString", &ABC::getString) - .addFunction("getInt", &ABC::getInt) - .addFunction("setInt", &ABC::setInt) - ); - - TEST_CHECK(state("value = assert(ABC.new(32))")); - TEST_CHECK(state("assert(value:getInt() == 32)")); - TEST_CHECK(state("value = assert(ABC.new('string_value'))")); - TEST_CHECK(state("assert(value:getString() == 'string_value')")); - TEST_CHECK(state("value = assert(ABC.new('string_value2',54))")); - TEST_CHECK(state("assert(value:getString() == 'string_value2')")); - TEST_CHECK(state("assert(value:getInt() == 54)")); - TEST_CHECK(state("value = assert(ABC.new(64,'string_value3'))")); - TEST_CHECK(state("assert(value:getString() == 'string_value3')")); - TEST_CHECK(state("assert(value:getInt() == 64)")); - - TEST_CHECK(state("value:setInt(33)")); - TEST_CHECK(state("assert(value:getInt() == 33)")); - TEST_EQUAL(state["value"]["getInt"](state["value"]), 33); - TEST_EQUAL((state["value"]->*"getInt")(), 33); -} - +KAGUYA_TEST_FUNCTION_DEF(string_constructor)(kaguya::State &state) { + state["ABC"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addFunction("getString", &ABC::getString)); -ABC createABC(int,int,int) -{ - return ABC(324343); + TEST_CHECK(state("value = assert(ABC.new('string_value'))")); + TEST_CHECK(state("assert(value:getString() == 'string_value')")); } -KAGUYA_TEST_FUNCTION_DEF(overloaded_constructor2)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .addOverloadedFunctions("new", - kaguya::ConstructorFunction::type(), - kaguya::ConstructorFunction::type(), - kaguya::ConstructorFunction::type(), - kaguya::ConstructorFunction::type(), - kaguya::ConstructorFunction::type(), - kaguya::ConstructorFunction::type(), - &createABC) - .addFunction("getString", &ABC::getString) - .addFunction("getInt", &ABC::getInt) - .addFunction("setInt", &ABC::setInt) - ); - - TEST_CHECK(state("value = assert(ABC.new(32))")); - TEST_CHECK(state("assert(value:getInt() == 32)")); - TEST_CHECK(state("value = assert(ABC.new('string_value'))")); - TEST_CHECK(state("assert(value:getString() == 'string_value')")); - TEST_CHECK(state("value = assert(ABC.new('string_value2',54))")); - TEST_CHECK(state("assert(value:getString() == 'string_value2')")); - TEST_CHECK(state("assert(value:getInt() == 54)")); - TEST_CHECK(state("value = assert(ABC.new(64,'string_value3'))")); - TEST_CHECK(state("assert(value:getString() == 'string_value3')")); - TEST_CHECK(state("assert(value:getInt() == 64)")); - - TEST_CHECK(state("value = assert(ABC.new(1,2,3))"));//use createABC - TEST_CHECK(state("assert(value:getInt() == 324343)")); - - TEST_CHECK(state("value:setInt(33)")); - TEST_CHECK(state("assert(value:getInt() == 33)")); +KAGUYA_TEST_FUNCTION_DEF(overloaded_constructor)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("getString", &ABC::getString) + .addFunction("getInt", &ABC::getInt) + .addFunction("setInt", &ABC::setInt)); + + TEST_CHECK(state("value = assert(ABC.new(32))")); + TEST_CHECK(state("assert(value:getInt() == 32)")); + TEST_CHECK(state("value = assert(ABC.new('string_value'))")); + TEST_CHECK(state("assert(value:getString() == 'string_value')")); + TEST_CHECK(state("value = assert(ABC.new('string_value2',54))")); + TEST_CHECK(state("assert(value:getString() == 'string_value2')")); + TEST_CHECK(state("assert(value:getInt() == 54)")); + TEST_CHECK(state("value = assert(ABC.new(64,'string_value3'))")); + TEST_CHECK(state("assert(value:getString() == 'string_value3')")); + TEST_CHECK(state("assert(value:getInt() == 64)")); + + TEST_CHECK(state("value:setInt(33)")); + TEST_CHECK(state("assert(value:getInt() == 33)")); + TEST_EQUAL(state["value"]["getInt"](state["value"]), 33); + TEST_EQUAL((state["value"]->*"getInt")(), 33); } -KAGUYA_TEST_FUNCTION_DEF(copy_constructor)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getString", &ABC::getString) - .addFunction("setString", &ABC::setString) - .addFunction("getInt", &ABC::getInt) - .addOverloadedFunctions("references", static_cast(&ABC::references), static_cast(&ABC::references)) - .addFunction("const_pointer", &ABC::const_pointer) - .addFunction("pointer", &ABC::pointer) - .addFunction("copy", &ABC::copy) - .addFunction("shared_copy", &ABC::shared_copy) - ); - - - TEST_CHECK(state("value = assert(ABC.new(64,'string_value3'))")); - TEST_CHECK(state("value2 = assert(value:copy())")); - TEST_CHECK(state("assert(value2:getString() == 'string_value3')")); - TEST_CHECK(state("assert(value2:getInt() == 64)")); - TEST_CHECK(state("value3 = assert(value:references())")); - TEST_CHECK(state("cvalue = assert(value:const_pointer())")); - TEST_CHECK(state("assert(cvalue:getString() == 'string_value3')")); - TEST_CHECK(state("assert(cvalue:getInt() == 64)")); - - TEST_CHECK(state("assert(value3:getString() == 'string_value3')")); - TEST_CHECK(state("assert(value3:getInt() == 64)")); - TEST_CHECK(state("value4 = assert(value:pointer())")); - TEST_CHECK(state("assert(value4:getString() == 'string_value3')")); - TEST_CHECK(state("assert(value4:getInt() == 64)")); - - TEST_CHECK(state("value5 = assert(value:shared_copy())")); - TEST_CHECK(state("value =1")); - state.garbageCollect();//warning!! value3 and value4 to dangling pointer - TEST_CHECK(state("assert(value5:getString() == 'string_value3')")); - TEST_CHECK(state("assert(value5:getInt() == 64)")); - - - { - kaguya::standard::shared_ptr shared_ptr(new ABC("shared_object", 53)); - state["shared_object"] = shared_ptr; - } - TEST_CHECK(state("assert(shared_object:getInt() == 53)")); - TEST_CHECK(state("assert(shared_object:getString() =='shared_object')")); - - TEST_CHECK(state["value5"].weakTypeTest()); - TEST_CHECK(state["value5"].typeTest()); - - - kaguya::ObjectWrapperBase* wrapper = state["value2"]; - TEST_CHECK(wrapper->get()); - TEST_CHECK(wrapper->cget() == wrapper->get()); - TEST_CHECK(wrapper->native_get() == wrapper->get()); - TEST_CHECK(wrapper->native_get() == wrapper->cget()); - - - kaguya::ObjectWrapperBase* shared_wrapper = state["value5"]; - TEST_CHECK(shared_wrapper->get()); - TEST_CHECK(shared_wrapper->cget() == shared_wrapper->get()); - TEST_CHECK(shared_wrapper->native_get() != shared_wrapper->get()); - TEST_CHECK(shared_wrapper->native_get() != shared_wrapper->cget()); +ABC createABC(int, int, int) { return ABC(324343); } +KAGUYA_TEST_FUNCTION_DEF(overloaded_constructor2)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable() + .addOverloadedFunctions( + "new", kaguya::ConstructorFunction::type(), + kaguya::ConstructorFunction::type(), + kaguya::ConstructorFunction::type(), + kaguya::ConstructorFunction::type(), + kaguya::ConstructorFunction::type(), + kaguya::ConstructorFunction::type(), + &createABC) + .addFunction("getString", &ABC::getString) + .addFunction("getInt", &ABC::getInt) + .addFunction("setInt", &ABC::setInt)); + + TEST_CHECK(state("value = assert(ABC.new(32))")); + TEST_CHECK(state("assert(value:getInt() == 32)")); + TEST_CHECK(state("value = assert(ABC.new('string_value'))")); + TEST_CHECK(state("assert(value:getString() == 'string_value')")); + TEST_CHECK(state("value = assert(ABC.new('string_value2',54))")); + TEST_CHECK(state("assert(value:getString() == 'string_value2')")); + TEST_CHECK(state("assert(value:getInt() == 54)")); + TEST_CHECK(state("value = assert(ABC.new(64,'string_value3'))")); + TEST_CHECK(state("assert(value:getString() == 'string_value3')")); + TEST_CHECK(state("assert(value:getInt() == 64)")); + + TEST_CHECK(state("value = assert(ABC.new(1,2,3))")); // use createABC + TEST_CHECK(state("assert(value:getInt() == 324343)")); + + TEST_CHECK(state("value:setInt(33)")); + TEST_CHECK(state("assert(value:getInt() == 33)")); } -KAGUYA_TEST_FUNCTION_DEF(data_member_bind)(kaguya::State& state) -{ +KAGUYA_TEST_FUNCTION_DEF(copy_constructor)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("getString", &ABC::getString) + .addFunction("setString", &ABC::setString) + .addFunction("getInt", &ABC::getInt) + .addOverloadedFunctions( + "references", static_cast(&ABC::references), + static_cast(&ABC::references)) + .addFunction("const_pointer", &ABC::const_pointer) + .addFunction("pointer", &ABC::pointer) + .addFunction("copy", &ABC::copy) + .addFunction("shared_copy", &ABC::shared_copy)); + + TEST_CHECK(state("value = assert(ABC.new(64,'string_value3'))")); + TEST_CHECK(state("value2 = assert(value:copy())")); + TEST_CHECK(state("assert(value2:getString() == 'string_value3')")); + TEST_CHECK(state("assert(value2:getInt() == 64)")); + TEST_CHECK(state("value3 = assert(value:references())")); + TEST_CHECK(state("cvalue = assert(value:const_pointer())")); + TEST_CHECK(state("assert(cvalue:getString() == 'string_value3')")); + TEST_CHECK(state("assert(cvalue:getInt() == 64)")); + + TEST_CHECK(state("assert(value3:getString() == 'string_value3')")); + TEST_CHECK(state("assert(value3:getInt() == 64)")); + TEST_CHECK(state("value4 = assert(value:pointer())")); + TEST_CHECK(state("assert(value4:getString() == 'string_value3')")); + TEST_CHECK(state("assert(value4:getInt() == 64)")); + + TEST_CHECK(state("value5 = assert(value:shared_copy())")); + TEST_CHECK(state("value =1")); + state.garbageCollect(); // warning!! value3 and value4 to dangling pointer + TEST_CHECK(state("assert(value5:getString() == 'string_value3')")); + TEST_CHECK(state("assert(value5:getInt() == 64)")); + + { + kaguya::standard::shared_ptr shared_ptr(new ABC("shared_object", 53)); + state["shared_object"] = shared_ptr; + } + TEST_CHECK(state("assert(shared_object:getInt() == 53)")); + TEST_CHECK(state("assert(shared_object:getString() =='shared_object')")); + + TEST_CHECK(state["value5"].weakTypeTest()); + TEST_CHECK(state["value5"].typeTest()); + + kaguya::ObjectWrapperBase *wrapper = state["value2"]; + TEST_CHECK(wrapper->get()); + TEST_CHECK(wrapper->cget() == wrapper->get()); + TEST_CHECK(wrapper->native_get() == wrapper->get()); + TEST_CHECK(wrapper->native_get() == wrapper->cget()); + + kaguya::ObjectWrapperBase *shared_wrapper = state["value5"]; + TEST_CHECK(shared_wrapper->get()); + TEST_CHECK(shared_wrapper->cget() == shared_wrapper->get()); + TEST_CHECK(shared_wrapper->native_get() != shared_wrapper->get()); + TEST_CHECK(shared_wrapper->native_get() != shared_wrapper->cget()); +} - kaguya::LuaFunction f = state.loadstring("return 3,4"); - kaguya::LuaFunction f2 = state.loadstring("return 7,8,9"); +KAGUYA_TEST_FUNCTION_DEF(data_member_bind)(kaguya::State &state) { - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("intmember", &ABC::intmember) - .addFunction("stringmember", &ABC::stringmember) - .addStaticField("static_data", f()) - .addStaticField("static_data2", f2()) - ); + kaguya::LuaFunction f = state.loadstring("return 3,4"); + kaguya::LuaFunction f2 = state.loadstring("return 7,8,9"); - TEST_CHECK(state("value = assert(ABC.new(64))")); - TEST_CHECK(state("assert(value:intmember() == 64)")); + state["ABC"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addFunction("intmember", &ABC::intmember) + .addFunction("stringmember", &ABC::stringmember) + .addStaticField("static_data", f()) + .addStaticField("static_data2", f2())); - TEST_CHECK(state("assert(value.static_data == 3)")); - TEST_CHECK(state("assert(value.static_data2 == 7)")); + TEST_CHECK(state("value = assert(ABC.new(64))")); + TEST_CHECK(state("assert(value:intmember() == 64)")); - TEST_CHECK(state("value:intmember(4)")); - TEST_CHECK(state("assert(value:intmember() == 4)")); + TEST_CHECK(state("assert(value.static_data == 3)")); + TEST_CHECK(state("assert(value.static_data2 == 7)")); + TEST_CHECK(state("value:intmember(4)")); + TEST_CHECK(state("assert(value:intmember() == 4)")); - TEST_CHECK(state("value:stringmember('test')")); - TEST_CHECK(state("assert(value:stringmember() == 'test')")); + TEST_CHECK(state("value:stringmember('test')")); + TEST_CHECK(state("assert(value:stringmember() == 'test')")); } -KAGUYA_TEST_FUNCTION_DEF(codechunkregtest)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .addStaticField("luafunc", kaguya::LuaCodeChunkResult("return function(a,b) return a*b end")) - .addStaticField("luafunc2", kaguya::LuaCodeChunk("local arg = {...}; return arg[1]*arg[2]")) - ); - ABC abc; - state["abc"] = &abc; - - TEST_CHECK(state("assert(abc.luafunc(3,4) == 12)")); - TEST_CHECK(state("assert(abc.luafunc2(3,4) == 12)")); +KAGUYA_TEST_FUNCTION_DEF(codechunkregtest)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable() + .addStaticField("luafunc", kaguya::LuaCodeChunkResult( + "return function(a,b) return a*b end")) + .addStaticField( + "luafunc2", + kaguya::LuaCodeChunk("local arg = {...}; return arg[1]*arg[2]"))); + ABC abc; + state["abc"] = &abc; + + TEST_CHECK(state("assert(abc.luafunc(3,4) == 12)")); + TEST_CHECK(state("assert(abc.luafunc2(3,4) == 12)")); } -KAGUYA_TEST_FUNCTION_DEF(overload_member_function)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addOverloadedFunctions("setmember", &ABC::intmember, &ABC::stringmember) - .addFunction("intdata", &ABC::intmember) - .addFunction("stringdata", &ABC::stringmember) - ); +KAGUYA_TEST_FUNCTION_DEF(overload_member_function)(kaguya::State &state) { + state["ABC"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addOverloadedFunctions("setmember", + &ABC::intmember, + &ABC::stringmember) + .addFunction("intdata", &ABC::intmember) + .addFunction("stringdata", &ABC::stringmember)); - TEST_CHECK(state("value = assert(ABC.new(64))")); - TEST_CHECK(state("assert(value:intdata() == 64)")); + TEST_CHECK(state("value = assert(ABC.new(64))")); + TEST_CHECK(state("assert(value:intdata() == 64)")); - TEST_CHECK(state("value:setmember(4)")); - TEST_CHECK(state("assert(value:intdata() == 4)")); + TEST_CHECK(state("value:setmember(4)")); + TEST_CHECK(state("assert(value:intdata() == 4)")); - TEST_CHECK(state("value:setmember('test')")); - TEST_CHECK(state("assert(value:stringdata() == 'test')")); + TEST_CHECK(state("value:setmember('test')")); + TEST_CHECK(state("assert(value:stringdata() == 'test')")); } struct Foo { - int func() { return 1; } - int func(int param) { return param; } + int func() { return 1; } + int func(int param) { return param; } }; -KAGUYA_TEST_FUNCTION_DEF(overload_member_function2)(kaguya::State& state) -{ - state["Foo"].setClass(kaguya::UserdataMetatable() - .addOverloadedFunctions("func",static_cast(&Foo::func), static_cast(&Foo::func)) - ); - state["foo"] = Foo(); - state("assert(foo:func() == 1)"); - state("assert(foo:func(64) == 64)"); +KAGUYA_TEST_FUNCTION_DEF(overload_member_function2)(kaguya::State &state) { + state["Foo"].setClass(kaguya::UserdataMetatable().addOverloadedFunctions( + "func", static_cast(&Foo::func), + static_cast(&Foo::func))); + state["foo"] = Foo(); + state("assert(foo:func() == 1)"); + state("assert(foo:func(64) == 64)"); } -KAGUYA_TEST_FUNCTION_DEF(overload_member_function3)(kaguya::State& state) -{ - state["Foo"].setClass(kaguya::UserdataMetatable() - .addStaticField("func", kaguya::overload(static_cast(&Foo::func), static_cast(&Foo::func))) - ); - state["foo"] = Foo(); - state("assert(foo:func() == 1)"); - state("assert(foo:func(32) == 32)"); +KAGUYA_TEST_FUNCTION_DEF(overload_member_function3)(kaguya::State &state) { + state["Foo"].setClass(kaguya::UserdataMetatable().addStaticField( + "func", kaguya::overload(static_cast(&Foo::func), + static_cast(&Foo::func)))); + state["foo"] = Foo(); + state("assert(foo:func() == 1)"); + state("assert(foo:func(32) == 32)"); } -KAGUYA_TEST_FUNCTION_DEF(operator_bind)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("__eq", &ABC::operator==) - .addFunction("__lt", &ABC::operator<) - .addFunction("__le", &ABC::operator<=) - ); - - TEST_CHECK(state("value1 = assert(ABC.new(64))")); - TEST_CHECK(state("value2 = assert(ABC.new(64))")); - TEST_CHECK(state("assert(value1 == value2)")); - TEST_CHECK(state("assert(value1 >= value2)")); - - TEST_CHECK(state("value1 = assert(ABC.new(64))")); - TEST_CHECK(state("value2 = assert(ABC.new(61))")); - TEST_CHECK(state("assert(value1 ~= value2)")); - TEST_CHECK(state("assert(value1 > value2)")); - TEST_CHECK(state("assert(value1 >= value2)")); +KAGUYA_TEST_FUNCTION_DEF(operator_bind)(kaguya::State &state) { + state["ABC"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addFunction("__eq", &ABC::operator==) + .addFunction("__lt", &ABC::operator<) + .addFunction("__le", &ABC::operator<=)); + + TEST_CHECK(state("value1 = assert(ABC.new(64))")); + TEST_CHECK(state("value2 = assert(ABC.new(64))")); + TEST_CHECK(state("assert(value1 == value2)")); + TEST_CHECK(state("assert(value1 >= value2)")); + + TEST_CHECK(state("value1 = assert(ABC.new(64))")); + TEST_CHECK(state("value2 = assert(ABC.new(61))")); + TEST_CHECK(state("assert(value1 ~= value2)")); + TEST_CHECK(state("assert(value1 > value2)")); + TEST_CHECK(state("assert(value1 >= value2)")); } -KAGUYA_TEST_FUNCTION_DEF(add_field)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addStaticField("TEST", 1) - .addStaticField("TEST2", "343") - .addStaticField("TEST3", 133.23) - .addStaticField("TEST4", std::string("test")) - ); - - TEST_CHECK(state("assert(ABC.TEST == 1)")); - TEST_CHECK(state("assert(ABC.TEST2 == '343')")); - TEST_CHECK(state("assert(ABC.TEST3 == 133.23)")); - TEST_CHECK(state("assert(ABC.TEST4 == 'test')")); +KAGUYA_TEST_FUNCTION_DEF(add_field)(kaguya::State &state) { + state["ABC"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addStaticField("TEST", 1) + .addStaticField("TEST2", "343") + .addStaticField("TEST3", 133.23) + .addStaticField("TEST4", std::string("test"))); + + TEST_CHECK(state("assert(ABC.TEST == 1)")); + TEST_CHECK(state("assert(ABC.TEST2 == '343')")); + TEST_CHECK(state("assert(ABC.TEST3 == 133.23)")); + TEST_CHECK(state("assert(ABC.TEST4 == 'test')")); } +struct CopyableClass { + CopyableClass(int i) : member(i) {} + bool operator==(const CopyableClass &rhs) const { + return member == rhs.member; + } + bool operator!=(const CopyableClass &rhs) const { + return member != rhs.member; + } + int member; -struct CopyableClass -{ - CopyableClass(int i) :member(i) {} - bool operator==(const CopyableClass& rhs)const - { - return member == rhs.member; - } - bool operator!=(const CopyableClass& rhs)const - { - return member != rhs.member; - } - int member; private: - CopyableClass(); + CopyableClass(); }; -KAGUYA_TEST_FUNCTION_DEF(copyable_class_test)(kaguya::State& state) -{ - state["CopyableClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("__eq", &CopyableClass::operator==) - ); - state["copy"] = CopyableClass(2); - state["copy2"] = CopyableClass(2); - TEST_CHECK(state("assert(copy2 == copy)")); - TEST_CHECK(state["copy"] == CopyableClass(2)); - TEST_CHECK(CopyableClass(2) == state["copy"]); - CopyableClass copy = state["copy"]; - TEST_CHECK(copy == CopyableClass(2)); - - CopyableClass src(5); - state["copied"] = src; - src.member = 12; - CopyableClass copied = state["copied"]; - TEST_CHECK(copied != src); - TEST_CHECK(state("assert(copied ~= copy)")); +KAGUYA_TEST_FUNCTION_DEF(copyable_class_test)(kaguya::State &state) { + state["CopyableClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("__eq", &CopyableClass::operator==)); + state["copy"] = CopyableClass(2); + state["copy2"] = CopyableClass(2); + TEST_CHECK(state("assert(copy2 == copy)")); + TEST_CHECK(state["copy"] == CopyableClass(2)); + TEST_CHECK(CopyableClass(2) == state["copy"]); + CopyableClass copy = state["copy"]; + TEST_CHECK(copy == CopyableClass(2)); + + CopyableClass src(5); + state["copied"] = src; + src.member = 12; + CopyableClass copied = state["copied"]; + TEST_CHECK(copied != src); + TEST_CHECK(state("assert(copied ~= copy)")); } +struct NoncopyableClass { + NoncopyableClass(int i) : member(i) {} + bool operator==(const NoncopyableClass &rhs) const { + return member == rhs.member; + } + bool operator!=(const NoncopyableClass &rhs) const { + return member != rhs.member; + } -struct NoncopyableClass -{ - NoncopyableClass(int i) :member(i) {} - bool operator==(const NoncopyableClass& rhs)const - { - return member == rhs.member; - } - bool operator!=(const NoncopyableClass& rhs)const - { - return member != rhs.member; - } private: - NoncopyableClass(); - NoncopyableClass(const NoncopyableClass&); - NoncopyableClass& operator=(const NoncopyableClass&); - int member; + NoncopyableClass(); + NoncopyableClass(const NoncopyableClass &); + NoncopyableClass &operator=(const NoncopyableClass &); + int member; }; -KAGUYA_TEST_FUNCTION_DEF(noncopyable_class_test)(kaguya::State& state) -{ - state["NoncopyableClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("__eq", &NoncopyableClass::operator==) - ); - - NoncopyableClass noncopy(2); - state["noncopy"] = &noncopy; - - const NoncopyableClass* noncpyref = state["noncopy"]; - TEST_CHECK(noncpyref == &noncopy); -} +KAGUYA_TEST_FUNCTION_DEF(noncopyable_class_test)(kaguya::State &state) { + state["NoncopyableClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("__eq", &NoncopyableClass::operator==)); + NoncopyableClass noncopy(2); + state["noncopy"] = &noncopy; + const NoncopyableClass *noncpyref = state["noncopy"]; + TEST_CHECK(noncpyref == &noncopy); +} -KAGUYA_TEST_FUNCTION_DEF(registering_object_instance)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("get_value", &ABC::getInt) - ); - - ABC abc(43); - //register object pointer - state["abc"] = &abc; - state("assert(43 == abc:get_value())"); - //or copy instance - state["copy_abc"] = abc; - state("assert(43 == copy_abc:get_value())"); - //or registering shared pointer - state["shared_abc"] = kaguya::standard::shared_ptr(new ABC(43));//kaguya::standard::shared_ptr is std::shared_ptr or boost::shared_ptr. - state("assert(43 == shared_abc:get_value())"); +KAGUYA_TEST_FUNCTION_DEF(registering_object_instance)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors().addFunction( + "get_value", &ABC::getInt)); + + ABC abc(43); + // register object pointer + state["abc"] = &abc; + state("assert(43 == abc:get_value())"); + // or copy instance + state["copy_abc"] = abc; + state("assert(43 == copy_abc:get_value())"); + // or registering shared pointer + state["shared_abc"] = kaguya::standard::shared_ptr( + new ABC(43)); // kaguya::standard::shared_ptr is std::shared_ptr or + // boost::shared_ptr. + state("assert(43 == shared_abc:get_value())"); } -struct Member -{ - Member() :a(0) {}; - Member(int i) :a(i) {}; - int a; +struct Member { + Member() : a(0){}; + Member(int i) : a(i){}; + int a; }; -struct Base -{ - Base() :a(0) {}; - int a; - Member member; - - void set(int d) { a = d; } - int get()const { return a; } +struct Base { + Base() : a(0){}; + int a; + Member member; + void set(int d) { a = d; } + int get() const { return a; } - void member_set(const Member& d) { member = d; } - const Member& member_get()const { return member; } + void member_set(const Member &d) { member = d; } + const Member &member_get() const { return member; } }; -struct Derived :Base -{ - Derived() :b(0) {}; - int b; +struct Derived : Base { + Derived() : b(0){}; + int b; }; -struct Derived2 :Derived -{ - Derived2() :c(0) {}; - int c; +struct Derived2 : Derived { + Derived2() : c(0){}; + int c; }; +struct PureVirtualBase { + PureVirtualBase(){}; + virtual ~PureVirtualBase(){}; -struct PureVirtualBase -{ - PureVirtualBase() {}; - virtual ~PureVirtualBase() {}; - - virtual void test() = 0; - virtual void default_arg(int a = 0) = 0; - virtual void const_test() const = 0; - virtual void const_default_arg(int a = 0) const = 0; + virtual void test() = 0; + virtual void default_arg(int a = 0) = 0; + virtual void const_test() const = 0; + virtual void const_default_arg(int a = 0) const = 0; }; -int base_function(Base* b) { - TEST_CHECK(b); - b->a = 1; - return b->a; +int base_function(Base *b) { + TEST_CHECK(b); + b->a = 1; + return b->a; } -int derived_function(Derived* d) { - TEST_CHECK(d); - d->b = 2; - return d->b; +int derived_function(Derived *d) { + TEST_CHECK(d); + d->b = 2; + return d->b; } -KAGUYA_TEST_FUNCTION_DEF(registering_derived_class)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .addFunction("a", &Base::a) - ); - - state["Derived"].setClass(kaguya::UserdataMetatable() - .addFunction("b", &Derived::b) - .addStaticFunction("test", derived_function) - ); - state["Derived2"].setClass(kaguya::UserdataMetatable() - .addFunction("c", &Derived2::c) - .addStaticFunction("test", derived_function) - ); - - Derived2 derived2; - Derived derived; - Base base; - state["base"] = &base; - state["derived"] = kaguya::standard::ref(derived); - state["derived2"] = kaguya::standard::ref(derived2); - state["base_function"] = &base_function; - state["derived_function"] = &derived_function; - TEST_CHECK(state("assert(1 == base_function(base))")); - TEST_CHECK(state("assert(1 == base_function(derived))")); - TEST_CHECK(state("assert(1 == base_function(derived2))")); - TEST_CHECK(state("assert(2 == derived_function(derived))")); - TEST_CHECK(state("assert(2 == derived_function(derived2))")); - TEST_CHECK(state("assert(1 == base:a())")); - TEST_CHECK(state("assert(1 == derived:a())")); - TEST_CHECK(state("assert(2 == derived:b())")); - TEST_CHECK(state("assert(1 == derived2:a())")); - TEST_CHECK(state("assert(2 == derived2:b())")); - TEST_EQUAL(derived.b, 2); - TEST_EQUAL(derived2.b, 2); - TEST_CHECK(state("assert(2 == derived.test(derived))")); +KAGUYA_TEST_FUNCTION_DEF(registering_derived_class)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().addFunction("a", &Base::a)); + + state["Derived"].setClass(kaguya::UserdataMetatable() + .addFunction("b", &Derived::b) + .addStaticFunction("test", derived_function)); + state["Derived2"].setClass(kaguya::UserdataMetatable() + .addFunction("c", &Derived2::c) + .addStaticFunction("test", derived_function)); + + Derived2 derived2; + Derived derived; + Base base; + state["base"] = &base; + state["derived"] = kaguya::standard::ref(derived); + state["derived2"] = kaguya::standard::ref(derived2); + state["base_function"] = &base_function; + state["derived_function"] = &derived_function; + TEST_CHECK(state("assert(1 == base_function(base))")); + TEST_CHECK(state("assert(1 == base_function(derived))")); + TEST_CHECK(state("assert(1 == base_function(derived2))")); + TEST_CHECK(state("assert(2 == derived_function(derived))")); + TEST_CHECK(state("assert(2 == derived_function(derived2))")); + TEST_CHECK(state("assert(1 == base:a())")); + TEST_CHECK(state("assert(1 == derived:a())")); + TEST_CHECK(state("assert(2 == derived:b())")); + TEST_CHECK(state("assert(1 == derived2:a())")); + TEST_CHECK(state("assert(2 == derived2:b())")); + TEST_EQUAL(derived.b, 2); + TEST_EQUAL(derived2.b, 2); + TEST_CHECK(state("assert(2 == derived.test(derived))")); } int receive_shared_ptr_function(kaguya::standard::shared_ptr d) { - TEST_CHECK(d); - d->b = 5; - return d->b; + TEST_CHECK(d); + d->b = 5; + return d->b; } int receive_base_shared_ptr_function(kaguya::standard::shared_ptr d) { - TEST_CHECK(d); - d->a = 2; - return d->a; + TEST_CHECK(d); + d->a = 2; + return d->a; } -int receive_base_shared_ptr_function_null(kaguya::standard::shared_ptr d) { - TEST_CHECK(!d); - return 4; +int receive_base_shared_ptr_function_null( + kaguya::standard::shared_ptr d) { + TEST_CHECK(!d); + return 4; } int receive_void_shared_ptr_function(kaguya::standard::shared_ptr d) { - TEST_CHECK(d); - return 6; + TEST_CHECK(d); + return 6; } -KAGUYA_TEST_FUNCTION_DEF(registering_shared_ptr)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .addFunction("a", &Base::a) - ); - - state["Derived"].setClass(kaguya::UserdataMetatable() - .addFunction("b", &Derived::b) - ); - - kaguya::standard::shared_ptr derived(new Derived()); - kaguya::standard::shared_ptr base(new Base()); - kaguya::standard::shared_ptr const_derived(new Derived()); - kaguya::standard::shared_ptr const_base(new Base()); - state["base"] = base; - state["derived"] = derived; - state["const_base"] = const_base; - state["const_derived"] = const_derived; - state["non_shared_base"] = Base(); - state["base_function"] = &base_function; - state["derived_function"] = &derived_function; - state["receive_shared_ptr_function"] = &receive_shared_ptr_function; - state["receive_base_shared_ptr_function"] = &receive_base_shared_ptr_function; - - - state["receive_shared_ptr_function_null"] = &receive_base_shared_ptr_function_null; - state["receive_void_shared_ptr_function"] = &receive_void_shared_ptr_function; - - - - TEST_CHECK(state("assert(1 == base_function(base))")); - TEST_EQUAL(base->a, 1); - TEST_CHECK(state("assert(1 == base_function(derived))")); - TEST_EQUAL(derived->a, 1); - TEST_CHECK(state("assert(2 == derived_function(derived))")); - TEST_CHECK(state("assert(1 == base:a())")); - TEST_CHECK(state("assert(1 == derived:a())")); - TEST_CHECK(state("assert(2 == derived:b())")); - TEST_EQUAL(derived->b, 2); - TEST_CHECK(state("assert(5 == receive_shared_ptr_function(derived))")); - TEST_EQUAL(derived->b, 5); - TEST_CHECK(state("assert(2 == receive_base_shared_ptr_function(derived))")); - TEST_EQUAL(derived->a, 2); - TEST_CHECK(state("assert(4 == receive_shared_ptr_function_null(non_shared_base))")); - TEST_CHECK(state("assert(6 == receive_void_shared_ptr_function(base))")); - TEST_CHECK(state("assert(6 == receive_void_shared_ptr_function(derived))")); - - TEST_EQUAL(derived->a, 2); - - { - kaguya::standard::shared_ptr d; - kaguya::standard::shared_ptr b; - kaguya::standard::shared_ptr v; - TEST_CHECK(!(d = state["base"])); - TEST_CHECK(b = state["base"]); - TEST_CHECK(v = state["base"]); - TEST_CHECK(d = state["derived"]); - TEST_CHECK(b = state["derived"]); - TEST_CHECK(v = state["derived"]); - - TEST_CHECK(!(d = state["non_shared_base"])); - TEST_CHECK(!(b = state["non_shared_base"])); - TEST_CHECK(!(v = state["non_shared_base"])); - - TEST_CHECK(!(d = state["const_base"])); - TEST_CHECK(!(b = state["const_base"])); - TEST_CHECK(!(v = state["const_base"])); - TEST_CHECK(!(d = state["const_derived"])); - TEST_CHECK(!(b = state["const_derived"])); - TEST_CHECK(!(v = state["const_derived"])); - } - { - kaguya::standard::shared_ptr cd; - kaguya::standard::shared_ptr cb; - kaguya::standard::shared_ptr cv; - TEST_CHECK(!(cd = state["base"])); - TEST_CHECK(cb = state["base"]); - TEST_CHECK(cv = state["base"]); - TEST_CHECK(cd = state["derived"]); - TEST_CHECK(cb = state["derived"]); - TEST_CHECK(cv = state["derived"]); - - TEST_CHECK(!(cd = state["non_shared_base"])); - TEST_CHECK(!(cb = state["non_shared_base"])); - TEST_CHECK(!(cv = state["non_shared_base"])); - TEST_CHECK(!(cv = state["non_shared_base"])); - - TEST_CHECK(!(cd = state["const_base"])); - TEST_CHECK((cb = state["const_base"])); - TEST_CHECK((cv = state["const_base"])); - TEST_CHECK((cd = state["const_derived"])); - TEST_CHECK((cb = state["const_derived"])); - TEST_CHECK((cv = state["const_derived"])); - } +KAGUYA_TEST_FUNCTION_DEF(registering_shared_ptr)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().addFunction("a", &Base::a)); + + state["Derived"].setClass( + kaguya::UserdataMetatable().addFunction("b", &Derived::b)); + + kaguya::standard::shared_ptr derived(new Derived()); + kaguya::standard::shared_ptr base(new Base()); + kaguya::standard::shared_ptr const_derived(new Derived()); + kaguya::standard::shared_ptr const_base(new Base()); + state["base"] = base; + state["derived"] = derived; + state["const_base"] = const_base; + state["const_derived"] = const_derived; + state["non_shared_base"] = Base(); + state["base_function"] = &base_function; + state["derived_function"] = &derived_function; + state["receive_shared_ptr_function"] = &receive_shared_ptr_function; + state["receive_base_shared_ptr_function"] = &receive_base_shared_ptr_function; + + state["receive_shared_ptr_function_null"] = + &receive_base_shared_ptr_function_null; + state["receive_void_shared_ptr_function"] = &receive_void_shared_ptr_function; + + TEST_CHECK(state("assert(1 == base_function(base))")); + TEST_EQUAL(base->a, 1); + TEST_CHECK(state("assert(1 == base_function(derived))")); + TEST_EQUAL(derived->a, 1); + TEST_CHECK(state("assert(2 == derived_function(derived))")); + TEST_CHECK(state("assert(1 == base:a())")); + TEST_CHECK(state("assert(1 == derived:a())")); + TEST_CHECK(state("assert(2 == derived:b())")); + TEST_EQUAL(derived->b, 2); + TEST_CHECK(state("assert(5 == receive_shared_ptr_function(derived))")); + TEST_EQUAL(derived->b, 5); + TEST_CHECK(state("assert(2 == receive_base_shared_ptr_function(derived))")); + TEST_EQUAL(derived->a, 2); + TEST_CHECK( + state("assert(4 == receive_shared_ptr_function_null(non_shared_base))")); + TEST_CHECK(state("assert(6 == receive_void_shared_ptr_function(base))")); + TEST_CHECK(state("assert(6 == receive_void_shared_ptr_function(derived))")); + + TEST_EQUAL(derived->a, 2); + + { + kaguya::standard::shared_ptr d; + kaguya::standard::shared_ptr b; + kaguya::standard::shared_ptr v; + TEST_CHECK(!(d = state["base"])); + TEST_CHECK(b = state["base"]); + TEST_CHECK(v = state["base"]); + TEST_CHECK(d = state["derived"]); + TEST_CHECK(b = state["derived"]); + TEST_CHECK(v = state["derived"]); + + TEST_CHECK(!(d = state["non_shared_base"])); + TEST_CHECK(!(b = state["non_shared_base"])); + TEST_CHECK(!(v = state["non_shared_base"])); + + TEST_CHECK(!(d = state["const_base"])); + TEST_CHECK(!(b = state["const_base"])); + TEST_CHECK(!(v = state["const_base"])); + TEST_CHECK(!(d = state["const_derived"])); + TEST_CHECK(!(b = state["const_derived"])); + TEST_CHECK(!(v = state["const_derived"])); + } + { + kaguya::standard::shared_ptr cd; + kaguya::standard::shared_ptr cb; + kaguya::standard::shared_ptr cv; + TEST_CHECK(!(cd = state["base"])); + TEST_CHECK(cb = state["base"]); + TEST_CHECK(cv = state["base"]); + TEST_CHECK(cd = state["derived"]); + TEST_CHECK(cb = state["derived"]); + TEST_CHECK(cv = state["derived"]); + + TEST_CHECK(!(cd = state["non_shared_base"])); + TEST_CHECK(!(cb = state["non_shared_base"])); + TEST_CHECK(!(cv = state["non_shared_base"])); + TEST_CHECK(!(cv = state["non_shared_base"])); + + TEST_CHECK(!(cd = state["const_base"])); + TEST_CHECK((cb = state["const_base"])); + TEST_CHECK((cv = state["const_base"])); + TEST_CHECK((cd = state["const_derived"])); + TEST_CHECK((cb = state["const_derived"])); + TEST_CHECK((cv = state["const_derived"])); + } #if !KAGUYA_NO_USERDATA_TYPE_CHECK - { - lua_newuserdata(state.state(), 100); - kaguya::LuaRef myuserdata(state.state(), kaguya::StackTop()); - kaguya::standard::shared_ptr cd; - kaguya::standard::shared_ptr cb; - kaguya::standard::shared_ptr cv; - state["nokaguya_udata"] = myuserdata; - - TEST_CHECK(!(cd = state["nokaguya_udata"])); - TEST_CHECK(!(cb = state["nokaguya_udata"])); - TEST_CHECK(!(cv = state["nokaguya_udata"])); - TEST_CHECK(!(cv = state["nokaguya_udata"])); - } + { + lua_newuserdata(state.state(), 100); + kaguya::LuaRef myuserdata(state.state(), kaguya::StackTop()); + kaguya::standard::shared_ptr cd; + kaguya::standard::shared_ptr cb; + kaguya::standard::shared_ptr cv; + state["nokaguya_udata"] = myuserdata; + + TEST_CHECK(!(cd = state["nokaguya_udata"])); + TEST_CHECK(!(cb = state["nokaguya_udata"])); + TEST_CHECK(!(cv = state["nokaguya_udata"])); + TEST_CHECK(!(cv = state["nokaguya_udata"])); + } #endif - - state["shared_ptr_function"] = kaguya::overload(&receive_shared_ptr_function, &receive_base_shared_ptr_function); - TEST_CHECK(state("assert(5 == shared_ptr_function(derived))")); - TEST_EQUAL(derived->b, 5); - TEST_CHECK(state("assert(2 == shared_ptr_function(base))")); - TEST_EQUAL(base->a, 2); - - state["shared_ptr_function"] = kaguya::overload(&receive_base_shared_ptr_function, &receive_shared_ptr_function); - TEST_CHECK(state("assert(5 == shared_ptr_function(derived))")); - TEST_EQUAL(derived->b, 5); - TEST_CHECK(state("assert(2 == shared_ptr_function(base))")); - TEST_EQUAL(base->a, 2); - - - //first function is always miss.second function typecheck - state["shared_ptr_function"] = kaguya::overload(®istering_derived_class, &receive_base_shared_ptr_function); - TEST_CHECK(state("assert(2 == shared_ptr_function(derived))")); - TEST_EQUAL(derived->a, 2); - + state["shared_ptr_function"] = kaguya::overload( + &receive_shared_ptr_function, &receive_base_shared_ptr_function); + TEST_CHECK(state("assert(5 == shared_ptr_function(derived))")); + TEST_EQUAL(derived->b, 5); + TEST_CHECK(state("assert(2 == shared_ptr_function(base))")); + TEST_EQUAL(base->a, 2); + + state["shared_ptr_function"] = kaguya::overload( + &receive_base_shared_ptr_function, &receive_shared_ptr_function); + TEST_CHECK(state("assert(5 == shared_ptr_function(derived))")); + TEST_EQUAL(derived->b, 5); + TEST_CHECK(state("assert(2 == shared_ptr_function(base))")); + TEST_EQUAL(base->a, 2); + + // first function is always miss.second function typecheck + state["shared_ptr_function"] = kaguya::overload( + ®istering_derived_class, &receive_base_shared_ptr_function); + TEST_CHECK(state("assert(2 == shared_ptr_function(derived))")); + TEST_EQUAL(derived->a, 2); } -struct shared_ptr_fun -{ - kaguya::standard::shared_ptr& ptr; - shared_ptr_fun(kaguya::standard::shared_ptr& r) :ptr(r) {} - void operator()(kaguya::standard::shared_ptr p) - { - ptr = p; - } +struct shared_ptr_fun { + kaguya::standard::shared_ptr &ptr; + shared_ptr_fun(kaguya::standard::shared_ptr &r) : ptr(r) {} + void operator()(kaguya::standard::shared_ptr p) { ptr = p; } }; -KAGUYA_TEST_FUNCTION_DEF(shared_ptr_null)(kaguya::State& state) -{ - kaguya::standard::shared_ptr ptr(new int(5)); - state["foo"] = kaguya::function)>(shared_ptr_fun(ptr)); - state("foo(nil)"); - TEST_EQUAL(ptr, 0); +KAGUYA_TEST_FUNCTION_DEF(shared_ptr_null)(kaguya::State &state) { + kaguya::standard::shared_ptr ptr(new int(5)); + state["foo"] = kaguya::function)>( + shared_ptr_fun(ptr)); + state("foo(nil)"); + TEST_EQUAL(ptr, 0); } -struct Base2 -{ - Base2() :b(0) {}; - int b; - int test2() { return 1192; } - int test() { return 794; } - int consttest()const { return 794; } +struct Base2 { + Base2() : b(0){}; + int b; + int test2() { return 1192; } + int test() { return 794; } + int consttest() const { return 794; } }; struct Base3 {}; -struct MultipleInheritance :Base, Base2 -{ - MultipleInheritance() :d(0) {}; - int d; - int test() { return 1192; } - int test3() { return 710; } - int consttest2()const { return 1560; } +struct MultipleInheritance : Base, Base2 { + MultipleInheritance() : d(0){}; + int d; + int test() { return 1192; } + int test3() { return 710; } + int consttest2() const { return 1560; } }; -struct MultipleInheritance2 :MultipleInheritance, Base3 -{ - MultipleInheritance2() :e(0) {}; - int e; +struct MultipleInheritance2 : MultipleInheritance, Base3 { + MultipleInheritance2() : e(0){}; + int e; }; - -KAGUYA_TEST_FUNCTION_DEF(multiple_inheritance)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Base::a) - ); - state["Base2"].setClass(kaguya::UserdataMetatable() - .addProperty("b", &Base2::b) - .addFunction("test", &Base2::test) - .addFunction("test2", &Base2::test2) - .addFunction("consttest", &Base2::consttest) - ); - state["Base3"].setClass(kaguya::UserdataMetatable() - ); - state["MultipleInheritance"].setClass(kaguya::UserdataMetatable >() - .addFunction("d", &MultipleInheritance::d) - .addProperty("propd", &MultipleInheritance::d) - .addFunction("test", &MultipleInheritance::test) - .addFunction("consttest2", &MultipleInheritance::consttest2) - .addFunction("test3", &MultipleInheritance::test3)); - - state["MultipleInheritance2"].setClass(kaguya::UserdataMetatable >() - .addFunction("e", &MultipleInheritance2::e)); - - MultipleInheritance data; - - state["testobj"] = &data; - TEST_CHECK(state("testobj:d(3)")); - TEST_CHECK(state("assert(testobj:d() == 3)")); - TEST_EQUAL(data.d, 3); - TEST_CHECK(state("testobj.propd= 4")); - TEST_CHECK(state("assert(testobj.propd == 4)")); - TEST_EQUAL(data.d, 4); - TEST_CHECK(state("assert(testobj:test()==1192)")); - TEST_CHECK(state("assert(testobj:test2()==1192)")); - TEST_CHECK(state("assert(testobj:test3()==710)")); - TEST_CHECK(state("assert(testobj:consttest()==794)")); - TEST_CHECK(state("testobj.a= 1")); - TEST_CHECK(state("assert(testobj.a == 1)")); - TEST_EQUAL(data.a, 1); - TEST_CHECK(state("testobj.a= 2")); - TEST_CHECK(state("assert(testobj.a == 2)")); - TEST_EQUAL(data.a, 2); - TEST_CHECK(state("testobj.b= 2")); - TEST_CHECK(state("assert(testobj.b == 2)")); - TEST_EQUAL(data.b, 2); - TEST_CHECK(state("testobj.b= 5")); - TEST_CHECK(state("assert(testobj.b == 5)")); - TEST_EQUAL(data.b, 5); - - - { - MultipleInheritance test; - state["test"] = &test; - TEST_CHECK(state("test.b= 2")); - TEST_CHECK(state("assert(test.b == 2)")); - TEST_EQUAL(test.b, 2); - } - { - MultipleInheritance2 test; - state["test"] = &test; - TEST_CHECK(state("test.b= 4")); - TEST_CHECK(state("assert(test.b == 4)")); - TEST_EQUAL(test.b, 4); - } - - - state["constobj"] = static_cast(&data); - TEST_CHECK(state("assert(constobj:consttest()==794)")); - TEST_CHECK(state("assert(constobj:consttest2()==1560)")); +KAGUYA_TEST_FUNCTION_DEF(multiple_inheritance)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().addProperty("a", &Base::a)); + state["Base2"].setClass(kaguya::UserdataMetatable() + .addProperty("b", &Base2::b) + .addFunction("test", &Base2::test) + .addFunction("test2", &Base2::test2) + .addFunction("consttest", &Base2::consttest)); + state["Base3"].setClass(kaguya::UserdataMetatable()); + state["MultipleInheritance"].setClass( + kaguya::UserdataMetatable >() + .addFunction("d", &MultipleInheritance::d) + .addProperty("propd", &MultipleInheritance::d) + .addFunction("test", &MultipleInheritance::test) + .addFunction("consttest2", &MultipleInheritance::consttest2) + .addFunction("test3", &MultipleInheritance::test3)); + + state["MultipleInheritance2"].setClass( + kaguya::UserdataMetatable< + MultipleInheritance2, + kaguya::MultipleBase >() + .addFunction("e", &MultipleInheritance2::e)); + + MultipleInheritance data; + + state["testobj"] = &data; + TEST_CHECK(state("testobj:d(3)")); + TEST_CHECK(state("assert(testobj:d() == 3)")); + TEST_EQUAL(data.d, 3); + TEST_CHECK(state("testobj.propd= 4")); + TEST_CHECK(state("assert(testobj.propd == 4)")); + TEST_EQUAL(data.d, 4); + TEST_CHECK(state("assert(testobj:test()==1192)")); + TEST_CHECK(state("assert(testobj:test2()==1192)")); + TEST_CHECK(state("assert(testobj:test3()==710)")); + TEST_CHECK(state("assert(testobj:consttest()==794)")); + TEST_CHECK(state("testobj.a= 1")); + TEST_CHECK(state("assert(testobj.a == 1)")); + TEST_EQUAL(data.a, 1); + TEST_CHECK(state("testobj.a= 2")); + TEST_CHECK(state("assert(testobj.a == 2)")); + TEST_EQUAL(data.a, 2); + TEST_CHECK(state("testobj.b= 2")); + TEST_CHECK(state("assert(testobj.b == 2)")); + TEST_EQUAL(data.b, 2); + TEST_CHECK(state("testobj.b= 5")); + TEST_CHECK(state("assert(testobj.b == 5)")); + TEST_EQUAL(data.b, 5); + + { + MultipleInheritance test; + state["test"] = &test; + TEST_CHECK(state("test.b= 2")); + TEST_CHECK(state("assert(test.b == 2)")); + TEST_EQUAL(test.b, 2); + } + { + MultipleInheritance2 test; + state["test"] = &test; + TEST_CHECK(state("test.b= 4")); + TEST_CHECK(state("assert(test.b == 4)")); + TEST_EQUAL(test.b, 4); + } + + state["constobj"] = static_cast(&data); + TEST_CHECK(state("assert(constobj:consttest()==794)")); + TEST_CHECK(state("assert(constobj:consttest2()==1560)")); } -KAGUYA_TEST_FUNCTION_DEF(add_property)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - .addProperty("member", &Base::member) - .addFunction("memberf", &Base::member) - ); - - state["Member"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Member::a) - ); - - state["Derived"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("b", &Derived::b) - ); - - state["Derived"]["test_value"] = 55; - - Derived derived; - Base base; - const Base* constbase = &base; - state["base"] = &base; - state["derived"] = kaguya::standard::ref(derived); - - TEST_CHECK(state("assert(55 == derived.test_value)")); - - TEST_CHECK(state("base.a=1")); - TEST_CHECK(state("derived.a = 2")); - TEST_CHECK(state("derived.b=3")); - TEST_CHECK(state("derived.member.a=5")); - TEST_CHECK(state("assert(1 == base.a)")); - TEST_CHECK(state("assert(2 == derived.a)")); - TEST_CHECK(state("assert(3 == derived.b)")); - TEST_CHECK(state("assert(5 == derived.member.a)")); - TEST_EQUAL(base.a, 1); - TEST_EQUAL(derived.a, 2); - TEST_EQUAL(derived.b, 3); - TEST_EQUAL(derived.member.a, 5); - - TEST_CHECK(state("base2 = Base.new()")); - TEST_CHECK(state("base2.a=5")); - TEST_CHECK(state("assert(5 == base2.a)")); - - base.a = 3; - base.member.a = 6; - state["constbase"] = constbase; - TEST_CHECK(state("assert(3 == constbase.a)")); - TEST_CHECK(state("assert(6 == constbase.member.a)")); - TEST_CHECK(state("assert(6 == constbase.memberf(constbase).a)")); +KAGUYA_TEST_FUNCTION_DEF(add_property)(kaguya::State &state) { + state["Base"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addProperty("a", &Base::a) + .addProperty("member", &Base::member) + .addFunction("memberf", &Base::member)); + + state["Member"].setClass( + kaguya::UserdataMetatable().addProperty("a", &Member::a)); + + state["Derived"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addProperty("b", &Derived::b)); + + state["Derived"]["test_value"] = 55; + + Derived derived; + Base base; + const Base *constbase = &base; + state["base"] = &base; + state["derived"] = kaguya::standard::ref(derived); + + TEST_CHECK(state("assert(55 == derived.test_value)")); + + TEST_CHECK(state("base.a=1")); + TEST_CHECK(state("derived.a = 2")); + TEST_CHECK(state("derived.b=3")); + TEST_CHECK(state("derived.member.a=5")); + TEST_CHECK(state("assert(1 == base.a)")); + TEST_CHECK(state("assert(2 == derived.a)")); + TEST_CHECK(state("assert(3 == derived.b)")); + TEST_CHECK(state("assert(5 == derived.member.a)")); + TEST_EQUAL(base.a, 1); + TEST_EQUAL(derived.a, 2); + TEST_EQUAL(derived.b, 3); + TEST_EQUAL(derived.member.a, 5); + + TEST_CHECK(state("base2 = Base.new()")); + TEST_CHECK(state("base2.a=5")); + TEST_CHECK(state("assert(5 == base2.a)")); + + base.a = 3; + base.member.a = 6; + state["constbase"] = constbase; + TEST_CHECK(state("assert(3 == constbase.a)")); + TEST_CHECK(state("assert(6 == constbase.member.a)")); + TEST_CHECK(state("assert(6 == constbase.memberf(constbase).a)")); } -KAGUYA_TEST_FUNCTION_DEF(add_property_case2)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - - state["Derived"].setClass(kaguya::UserdataMetatable() - .setConstructors() - ); - - Derived derived; - Base base; - state["base"] = &base; - state["derived"] = kaguya::standard::ref(derived); - TEST_CHECK(state("base.a=1")); - TEST_CHECK(state("derived.a = 2")); - TEST_CHECK(state("assert(1 == base.a)")); - TEST_CHECK(state("assert(2 == derived.a)")); - TEST_EQUAL(base.a, 1); - TEST_EQUAL(derived.a, 2); +KAGUYA_TEST_FUNCTION_DEF(add_property_case2)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + + state["Derived"].setClass( + kaguya::UserdataMetatable().setConstructors()); + + Derived derived; + Base base; + state["base"] = &base; + state["derived"] = kaguya::standard::ref(derived); + TEST_CHECK(state("base.a=1")); + TEST_CHECK(state("derived.a = 2")); + TEST_CHECK(state("assert(1 == base.a)")); + TEST_CHECK(state("assert(2 == derived.a)")); + TEST_EQUAL(base.a, 1); + TEST_EQUAL(derived.a, 2); } -KAGUYA_TEST_FUNCTION_DEF(add_property_with_setter_getter)(kaguya::State& state) -{ - state["Member"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Member::a) - ); - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("prop", &Base::get, &Base::set) - .addProperty("class_prop", &Base::member_get, &Base::member_set) - ); - Base base; - state["obj"] = &base; - TEST_CHECK(state("obj.prop=1")); - TEST_CHECK(state("assert(obj.prop==1)")); - TEST_EQUAL(base.a, 1); - TEST_CHECK(state("obj.prop=22")); - TEST_CHECK(state("assert(obj.prop==22)")); - TEST_EQUAL(base.a, 22); - - TEST_CHECK(state("obj.class_prop=Member.new(5)"));//set - TEST_CHECK(state("assert(obj.class_prop.a==5)"));//get - TEST_EQUAL(base.member.a, 5); - - TEST_CHECK(state("obj.class_prop=Member.new(33)"));//set - TEST_CHECK(state("assert(obj.class_prop.a==33)"));//get - TEST_EQUAL(base.member.a, 33); +KAGUYA_TEST_FUNCTION_DEF(add_property_with_setter_getter) +(kaguya::State &state) { + state["Member"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addProperty("a", &Member::a)); + state["Base"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addProperty("prop", &Base::get, &Base::set) + .addProperty("class_prop", &Base::member_get, &Base::member_set)); + Base base; + state["obj"] = &base; + TEST_CHECK(state("obj.prop=1")); + TEST_CHECK(state("assert(obj.prop==1)")); + TEST_EQUAL(base.a, 1); + TEST_CHECK(state("obj.prop=22")); + TEST_CHECK(state("assert(obj.prop==22)")); + TEST_EQUAL(base.a, 22); + + TEST_CHECK(state("obj.class_prop=Member.new(5)")); // set + TEST_CHECK(state("assert(obj.class_prop.a==5)")); // get + TEST_EQUAL(base.member.a, 5); + + TEST_CHECK(state("obj.class_prop=Member.new(33)")); // set + TEST_CHECK(state("assert(obj.class_prop.a==33)")); // get + TEST_EQUAL(base.member.a, 33); } -struct Prop -{ - Prop() :a(0) {} - int a; +struct Prop { + Prop() : a(0) {} + int a; }; -struct PropHolder -{ - Prop mem; - ~PropHolder() { - } +struct PropHolder { + Prop mem; + ~PropHolder() {} }; -KAGUYA_TEST_FUNCTION_DEF(add_property_ref_check)(kaguya::State& state) -{ - state["Prop"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Prop::a) - ); - - state["PropHolder"].setClass(kaguya::UserdataMetatable() - .addProperty("mem", &PropHolder::mem) - ); - - PropHolder prop; - state["prop"] = ∝ - TEST_CHECK(state("prop.mem.a=455")); - TEST_EQUAL(prop.mem.a, 455); - - {//member retain not supported now -// state["prop"] = PropHolder(); -// TEST_CHECK(state("member = prop.mem")); -// TEST_CHECK(state("prop = nil")); -// state.garbageCollect(); -// TEST_CHECK(state("member.a = 3232")); - } +KAGUYA_TEST_FUNCTION_DEF(add_property_ref_check)(kaguya::State &state) { + state["Prop"].setClass( + kaguya::UserdataMetatable().addProperty("a", &Prop::a)); + + state["PropHolder"].setClass( + kaguya::UserdataMetatable().addProperty("mem", + &PropHolder::mem)); + + PropHolder prop; + state["prop"] = ∝ + TEST_CHECK(state("prop.mem.a=455")); + TEST_EQUAL(prop.mem.a, 455); + + { // member retain not supported now + // state["prop"] = PropHolder(); + // TEST_CHECK(state("member = prop.mem")); + // TEST_CHECK(state("prop = nil")); + // state.garbageCollect(); + // TEST_CHECK(state("member.a = 3232")); + } } -KAGUYA_TEST_FUNCTION_DEF(object_take_copy)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - - TEST_CHECK(state("fn = function(object,value) object.a = value end")); - { - Base base; - base.a = 232; - state["obj"] = base; - TEST_CHECK(state("assert(obj.a==232)")); - TEST_CHECK(state("obj.a = 2")); - TEST_CHECK(state("assert(obj.a==2)")); - TEST_EQUAL(base.a, 232); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==2)")); - - state["fn"](base, 54); - TEST_EQUAL(base.a, 232); - } - {// - Base basesrc; - Base& base = basesrc; - base.a = 232; - state["obj"] = base; - TEST_CHECK(state("assert(obj.a==232)")); - TEST_CHECK(state("obj.a = 2")); - TEST_CHECK(state("assert(obj.a==2)")); - TEST_EQUAL(base.a, 232); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==2)")); - - state["fn"](base, 54); - TEST_EQUAL(base.a, 232); - } - {// - Base basesrc; - const Base& base = basesrc; - basesrc.a = 232; - state["obj"] = base; - TEST_CHECK(state("assert(obj.a==232)")); - TEST_CHECK(state("obj.a = 2")); - TEST_CHECK(state("assert(obj.a==2)")); - TEST_EQUAL(base.a, 232); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==2)")); - - state["fn"](base, 54); - TEST_EQUAL(base.a, 232); - } +KAGUYA_TEST_FUNCTION_DEF(object_take_copy)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + + TEST_CHECK(state("fn = function(object,value) object.a = value end")); + { + Base base; + base.a = 232; + state["obj"] = base; + TEST_CHECK(state("assert(obj.a==232)")); + TEST_CHECK(state("obj.a = 2")); + TEST_CHECK(state("assert(obj.a==2)")); + TEST_EQUAL(base.a, 232); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==2)")); + + state["fn"](base, 54); + TEST_EQUAL(base.a, 232); + } + { // + Base basesrc; + Base &base = basesrc; + base.a = 232; + state["obj"] = base; + TEST_CHECK(state("assert(obj.a==232)")); + TEST_CHECK(state("obj.a = 2")); + TEST_CHECK(state("assert(obj.a==2)")); + TEST_EQUAL(base.a, 232); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==2)")); + + state["fn"](base, 54); + TEST_EQUAL(base.a, 232); + } + { // + Base basesrc; + const Base &base = basesrc; + basesrc.a = 232; + state["obj"] = base; + TEST_CHECK(state("assert(obj.a==232)")); + TEST_CHECK(state("obj.a = 2")); + TEST_CHECK(state("assert(obj.a==2)")); + TEST_EQUAL(base.a, 232); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==2)")); + + state["fn"](base, 54); + TEST_EQUAL(base.a, 232); + } } -KAGUYA_TEST_FUNCTION_DEF(object_take_pointer)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - TEST_CHECK(state("fn = function(object,value) object.a = value end")); - - Base base; - base.a = 232; - state["obj"] = &base; - TEST_CHECK(state("assert(obj.a==232)")); - TEST_CHECK(state("obj.a = 2")); - TEST_CHECK(state("assert(obj.a==2)")); - TEST_EQUAL(base.a, 2); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==2)")); - - state["fn"](&base, 54); - TEST_EQUAL(base.a, 54); - +KAGUYA_TEST_FUNCTION_DEF(object_take_pointer)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + TEST_CHECK(state("fn = function(object,value) object.a = value end")); + + Base base; + base.a = 232; + state["obj"] = &base; + TEST_CHECK(state("assert(obj.a==232)")); + TEST_CHECK(state("obj.a = 2")); + TEST_CHECK(state("assert(obj.a==2)")); + TEST_EQUAL(base.a, 2); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==2)")); + + state["fn"](&base, 54); + TEST_EQUAL(base.a, 54); } -KAGUYA_TEST_FUNCTION_DEF(object_take_reference)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - TEST_CHECK(state("fn = function(object,value) object.a = value end")); - - Base base; - base.a = 232; - state["obj"] = kaguya::standard::ref(base); - TEST_CHECK(state("assert(obj.a==232)")); - TEST_CHECK(state("obj.a = 2")); - TEST_CHECK(state("assert(obj.a==2)")); - TEST_EQUAL(base.a, 2); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==2)")); - - state["fn"](kaguya::standard::ref(base), 54); - TEST_EQUAL(base.a, 54); +KAGUYA_TEST_FUNCTION_DEF(object_take_reference)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + TEST_CHECK(state("fn = function(object,value) object.a = value end")); + + Base base; + base.a = 232; + state["obj"] = kaguya::standard::ref(base); + TEST_CHECK(state("assert(obj.a==232)")); + TEST_CHECK(state("obj.a = 2")); + TEST_CHECK(state("assert(obj.a==2)")); + TEST_EQUAL(base.a, 2); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==2)")); + + state["fn"](kaguya::standard::ref(base), 54); + TEST_EQUAL(base.a, 54); } -KAGUYA_TEST_FUNCTION_DEF(object_take_const_reference)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - TEST_CHECK(state("fn = function(object,value) object.a = value end")); - - Base basesrc; - basesrc.a = 232; - const Base* base = &basesrc; - state["obj"] = base; - TEST_CHECK(state("assert(obj.a==232)")); - // TEST_CHECK(!state("obj.a = 2"));//cannot assign - TEST_CHECK(state("assert(obj.a==232)")); - TEST_EQUAL(base->a, 232); - - basesrc.a = 22; - TEST_CHECK(state("assert(obj.a==22)")); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==22)")); - - // state["fn"](base, 54);//cannot assign - TEST_EQUAL(base->a, 22); +KAGUYA_TEST_FUNCTION_DEF(object_take_const_reference)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + TEST_CHECK(state("fn = function(object,value) object.a = value end")); + + Base basesrc; + basesrc.a = 232; + const Base *base = &basesrc; + state["obj"] = base; + TEST_CHECK(state("assert(obj.a==232)")); + // TEST_CHECK(!state("obj.a = 2"));//cannot assign + TEST_CHECK(state("assert(obj.a==232)")); + TEST_EQUAL(base->a, 232); + + basesrc.a = 22; + TEST_CHECK(state("assert(obj.a==22)")); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==22)")); + + // state["fn"](base, 54);//cannot assign + TEST_EQUAL(base->a, 22); } -KAGUYA_TEST_FUNCTION_DEF(object_take_const_pointer)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - TEST_CHECK(state("fn = function(object,value) object.a = value end")); - - Base basesrc; - basesrc.a = 232; - const Base& base = basesrc; - state["obj"] = kaguya::standard::ref(base); - TEST_CHECK(state("assert(obj.a==232)")); - // TEST_CHECK(!state("obj.a = 2"));//cannot assign - TEST_CHECK(state("assert(obj.a==232)")); - TEST_EQUAL(base.a, 232); - - basesrc.a = 22; - TEST_CHECK(state("assert(obj.a==22)")); - - state.garbageCollect(); - TEST_CHECK(state("assert(obj.a==22)")); - - // state["fn"](base, 54);//cannot assign - TEST_EQUAL(base.a, 22); +KAGUYA_TEST_FUNCTION_DEF(object_take_const_pointer)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + TEST_CHECK(state("fn = function(object,value) object.a = value end")); + + Base basesrc; + basesrc.a = 232; + const Base &base = basesrc; + state["obj"] = kaguya::standard::ref(base); + TEST_CHECK(state("assert(obj.a==232)")); + // TEST_CHECK(!state("obj.a = 2"));//cannot assign + TEST_CHECK(state("assert(obj.a==232)")); + TEST_EQUAL(base.a, 232); + + basesrc.a = 22; + TEST_CHECK(state("assert(obj.a==22)")); + + state.garbageCollect(); + TEST_CHECK(state("assert(obj.a==22)")); + + // state["fn"](base, 54);//cannot assign + TEST_EQUAL(base.a, 22); } -KAGUYA_TEST_FUNCTION_DEF(null_shared_ptr)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - - - state["test"] = kaguya::standard::shared_ptr(); - TEST_CHECK(state("assert(test==nil)")); +KAGUYA_TEST_FUNCTION_DEF(null_shared_ptr)(kaguya::State &state) { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + state["test"] = kaguya::standard::shared_ptr(); + TEST_CHECK(state("assert(test==nil)")); - state["test"] = kaguya::standard::shared_ptr(); + state["test"] = kaguya::standard::shared_ptr(); - TEST_CHECK(state("assert(test==nil)")); + TEST_CHECK(state("assert(test==nil)")); - state["test"] = kaguya::standard::shared_ptr(); - TEST_CHECK(state("assert(test==nil)")); + state["test"] = kaguya::standard::shared_ptr(); + TEST_CHECK(state("assert(test==nil)")); - kaguya::standard::shared_ptr sptr = state["test"]; - TEST_CHECK(!sptr); + kaguya::standard::shared_ptr sptr = state["test"]; + TEST_CHECK(!sptr); } int TestClass2_objectcount = 0; -struct TestClass2 -{ - TestClass2() - { - TestClass2_objectcount++; - } - TestClass2(const TestClass2& src):data(src.data) - { - TestClass2_objectcount++; - } - ~TestClass2() - { - TestClass2_objectcount--; - } - std::vector data; +struct TestClass2 { + TestClass2() { TestClass2_objectcount++; } + TestClass2(const TestClass2 &src) : data(src.data) { + TestClass2_objectcount++; + } + ~TestClass2() { TestClass2_objectcount--; } + std::vector data; }; - -KAGUYA_TEST_FUNCTION_DEF(not_registered_object)(kaguya::State&) -{ - TEST_CHECK(TestClass2_objectcount == 0); - { - kaguya::State state; - state["data"] = TestClass2(); - } - TEST_CHECK(TestClass2_objectcount==0); +KAGUYA_TEST_FUNCTION_DEF(not_registered_object)(kaguya::State &) { + TEST_CHECK(TestClass2_objectcount == 0); + { + kaguya::State state; + state["data"] = TestClass2(); + } + TEST_CHECK(TestClass2_objectcount == 0); } - - std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; } -KAGUYA_TEST_FUNCTION_DEF(error_check)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - .addFunction("fa", &Base::a) - .addProperty("member", &Base::member) - .addFunction("memberf", &Base::member) - ); - +KAGUYA_TEST_FUNCTION_DEF(error_check)(kaguya::State &state) { + state["Base"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addProperty("a", &Base::a) + .addFunction("fa", &Base::a) + .addProperty("member", &Base::member) + .addFunction("memberf", &Base::member)); - state["test"] = Base(); - TEST_CHECK(state("assert(test~=nil)")); + state["test"] = Base(); + TEST_CHECK(state("assert(test~=nil)")); - TEST_CHECK(state("test.fa(test)")); - TEST_CHECK(state("test:fa()")); + TEST_CHECK(state("test.fa(test)")); + TEST_CHECK(state("test:fa()")); - state.setErrorHandler(ignore_error_fun); - last_error_message = ""; + state.setErrorHandler(ignore_error_fun); + last_error_message = ""; - state("test.fa()");//error - TEST_COMPARE_NE(last_error_message , ""); - - last_error_message = ""; - state("assert(6 == test.memberf(nil).a)"); - TEST_COMPARE_NE(last_error_message, ""); + state("test.fa()"); // error + TEST_COMPARE_NE(last_error_message, ""); + last_error_message = ""; + state("assert(6 == test.memberf(nil).a)"); + TEST_COMPARE_NE(last_error_message, ""); } - - -KAGUYA_TEST_FUNCTION_DEF(duplicate_register_member_error_throw_test)(kaguya::State& state) -{ - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - bool catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("a", &Base::a) - .addProperty("a", &Base::a) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Base::a) - .addStaticFunction("a", &Base::a) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - catch_except = false; - try - { - std::string data_value("value"); - state["Base"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Base::a) - .addStaticField("a", data_value) - ); - TEST_EQUAL(data_value, "value"); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Base::a) - .addOverloadedFunctions("a", &Base::a) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - - catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .addOverloadedFunctions("a", &Base::a) - .addProperty("a", &Base::get) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - - - catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .addOverloadedFunctions("a", &Base::a) - .addProperty("a", &Base::get, &Base::set) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - - catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .addFunction("a", &Base::a) - .addFunction("a", &Base::get) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - - - catch_except = false; - try - { - CopyableClass copy = state["a"]; - TEST_CHECK(false);//unreachable - TEST_CHECK(copy.member); - } - catch (const kaguya::LuaTypeMismatch& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("mismatch") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(duplicate_register_member_error_throw_test) +(kaguya::State &state) { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + bool catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addFunction("a", &Base::a) + .addProperty("a", &Base::a)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .addProperty("a", &Base::a) + .addStaticFunction("a", &Base::a)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + catch_except = false; + try { + std::string data_value("value"); + state["Base"].setClass(kaguya::UserdataMetatable() + .addProperty("a", &Base::a) + .addStaticField("a", data_value)); + TEST_EQUAL(data_value, "value"); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .addProperty("a", &Base::a) + .addOverloadedFunctions("a", &Base::a)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + + catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .addOverloadedFunctions("a", &Base::a) + .addProperty("a", &Base::get)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + + catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .addOverloadedFunctions("a", &Base::a) + .addProperty("a", &Base::get, &Base::set)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + + catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .addFunction("a", &Base::a) + .addFunction("a", &Base::get)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + + catch_except = false; + try { + CopyableClass copy = state["a"]; + TEST_CHECK(false); // unreachable + TEST_CHECK(copy.member); + } catch (const kaguya::LuaTypeMismatch &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("mismatch") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } -KAGUYA_TEST_FUNCTION_DEF(duplicate_register_member_error_throw_test2)(kaguya::State& state) -{ - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - - bool catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - .addProperty("a", &Base::a) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(duplicate_register_member_error_throw_test2) +(kaguya::State &state) { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + + bool catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addProperty("a", &Base::a) + .addProperty("a", &Base::a)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } -KAGUYA_TEST_FUNCTION_DEF(duplicate_register_member_error_throw_test3)(kaguya::State& state) -{ - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - - bool catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - .addStaticField("a", 3) - ); - } - catch (const kaguya::KaguyaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("already registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(duplicate_register_member_error_throw_test3) +(kaguya::State &state) { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + + bool catch_except = false; + try { + state["Base"].setClass(kaguya::UserdataMetatable() + .setConstructors() + .addProperty("a", &Base::a) + .addStaticField("a", 3)); + } catch (const kaguya::KaguyaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("already registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } -KAGUYA_TEST_FUNCTION_DEF(duplicate_register_class_error_throw_test)(kaguya::State& state) -{ - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - - bool catch_except = false; - try - { - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - state["Base3"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base::a) - ); - } - catch (const kaguya::LuaException& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("registered") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(duplicate_register_class_error_throw_test) +(kaguya::State &state) { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + + bool catch_except = false; + try { + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + state["Base3"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base::a)); + } catch (const kaguya::LuaException &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("registered") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } +KAGUYA_TEST_FUNCTION_DEF(this_typemismatch_error_test)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + state["ABC"].setClass(kaguya::UserdataMetatable() + .addOverloadedFunctions("setmember", + &ABC::intmember, + &ABC::stringmember) + .addFunction("intdata", &ABC::intmember) + .addFunction("stringdata", &ABC::stringmember) + .addFunction("getInt", &ABC::getInt) + .addFunction("setInt", &ABC::setInt) + .addFunction("shared_copy", &ABC::shared_copy) + .addFunction("const_pointer", &ABC::const_pointer)); + + state["test"] = ABC(); + state["other"] = Base(); + + TEST_CHECK(state("assert(test~=nil)")); + TEST_CHECK(state("test.setmember(test,'')")); + + last_error_message = ""; + state("test.setmember()"); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); + + last_error_message = ""; + state("test.intdata()"); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); + + last_error_message = ""; + state("test.getInt()"); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); + + last_error_message = ""; + state("test.setInt()"); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); + + last_error_message = ""; + state("test.shared_copy()"); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); + + last_error_message = ""; + state("test.const_pointer(other)"); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); +} +KAGUYA_TEST_FUNCTION_DEF(self_refcounted_object)(kaguya::State &) { + // test for self reference counted class + // see SelfRefCountedPtrWrapper and specialized ObjectPointerWrapperType for + // SelfRefCounted + TEST_EQUAL(SelfRefCounted::all_object_count, 0); + + { + kaguya::State state; + state["RefObjectA"].setClass(kaguya::UserdataMetatable()); + state["RefObjectA"].setClass(kaguya::UserdataMetatable()); + + state["a"] = new RefObjectA; + state["b"] = new RefObjectB; + TEST_EQUAL(SelfRefCounted::all_object_count, 2); + + RefObjectA *ptr = state["a"]; + state["c"] = ptr; + TEST_EQUAL(SelfRefCounted::all_object_count, 2); + } + TEST_EQUAL(SelfRefCounted::all_object_count, 0); +} -KAGUYA_TEST_FUNCTION_DEF(this_typemismatch_error_test)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - state["ABC"].setClass(kaguya::UserdataMetatable() - .addOverloadedFunctions("setmember", &ABC::intmember, &ABC::stringmember) - .addFunction("intdata", &ABC::intmember) - .addFunction("stringdata", &ABC::stringmember) - .addFunction("getInt", &ABC::getInt) - .addFunction("setInt", &ABC::setInt) - .addFunction("shared_copy", &ABC::shared_copy) - .addFunction("const_pointer", &ABC::const_pointer) - ); - - state["test"] = ABC(); - state["other"] = Base(); - - TEST_CHECK(state("assert(test~=nil)")); - TEST_CHECK(state("test.setmember(test,'')")); - - last_error_message = ""; - state("test.setmember()"); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); - - last_error_message = ""; - state("test.intdata()"); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); - - last_error_message = ""; - state("test.getInt()"); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); - - last_error_message = ""; - state("test.setInt()"); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); - - last_error_message = ""; - state("test.shared_copy()"); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); - - last_error_message = ""; - state("test.const_pointer(other)"); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); +int testindexfn(ABC *self, int key) { return self->intmember * key; } +void testnewindexfn(ABC *self, int key, int value) { + TEST_CHECK(self); + TEST_EQUAL(key, 1); + TEST_EQUAL(value, 3); } +KAGUYA_TEST_FUNCTION_DEF(self_register_index_object)(kaguya::State &state) { -KAGUYA_TEST_FUNCTION_DEF(self_refcounted_object)(kaguya::State& ) -{ - //test for self reference counted class - //see SelfRefCountedPtrWrapper and specialized ObjectPointerWrapperType for SelfRefCounted - TEST_EQUAL(SelfRefCounted::all_object_count,0); - - { - kaguya::State state; - state["RefObjectA"].setClass(kaguya::UserdataMetatable()); - state["RefObjectA"].setClass(kaguya::UserdataMetatable()); + state["ABC"].setClass(kaguya::UserdataMetatable() + .addStaticFunction("__index", &testindexfn) + .addStaticFunction("__newindex", &testnewindexfn)); + ABC obj; + state["obj"] = ABC(3); + state("assert(obj[3]==9);"); + state("obj[1]=3;"); - state["a"] = new RefObjectA; - state["b"] = new RefObjectB; - TEST_EQUAL(SelfRefCounted::all_object_count, 2); + { // other way + kaguya::State state; + state["ABC"].setClass(kaguya::UserdataMetatable()); - RefObjectA* ptr = state["a"]; - state["c"] = ptr; - TEST_EQUAL(SelfRefCounted::all_object_count, 2); - } - TEST_EQUAL(SelfRefCounted::all_object_count, 0); + state["ABC"]["__index"] = kaguya::function(&testindexfn); + state["ABC"]["__newindex"] = kaguya::function(&testindexfn); + ABC obj; + state["obj"] = ABC(3); + state("assert(obj[3]==9);"); + state("obj[1]=3;"); + } } -int testindexfn(ABC* self, int key) -{ - return self->intmember * key; +KAGUYA_TEST_FUNCTION_DEF(call_constructor)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors().addFunction( + "getInt", &ABC::getInt)); + + TEST_CHECK(state("value = assert(ABC(32))")); + TEST_CHECK(state("assert(value:getInt() == 32)")); + + state["Foo"].setClass( + kaguya::UserdataMetatable().setConstructors()); + TEST_CHECK(state("value = assert(Foo())")); + + state["Base"].setClass(kaguya::UserdataMetatable() + .addProperty("a", &Base::a) + .addFunction("__call", &Base::get) + .setConstructors()); + state["Base2"].setClass(kaguya::UserdataMetatable() + .addProperty("b", &Base2::b) + .addFunction("__call", &Base2::test) + .setConstructors()); + state["MultipleInheritance"].setClass( + kaguya::UserdataMetatable >() + .setConstructors() + .addFunction("__call", &MultipleInheritance::test) + .addFunction("d", &MultipleInheritance::d)); + + TEST_CHECK(state("multiinheritance = assert(MultipleInheritance())")); + TEST_CHECK(state("assert(multiinheritance:d() == 0)")); + TEST_CHECK(state("assert(multiinheritance.a == 0)")); + TEST_CHECK(state("assert(multiinheritance.b == 0)")); + TEST_CHECK(state("assert(multiinheritance() == 1192)")); + + TEST_CHECK(state("base2 = assert(Base2())")); + TEST_CHECK(state("assert(base2.b == 0)")); + TEST_CHECK(state("assert(base2() == 794)")); + TEST_CHECK(state("base = assert(Base())")); + TEST_CHECK(state("assert(base.a == 0)")); + TEST_CHECK(state("base.a = 4 assert(base.a == 4) assert(base() == 4)")); } -void testnewindexfn(ABC* self, int key,int value) -{ - TEST_CHECK(self); - TEST_EQUAL(key, 1); - TEST_EQUAL(value, 3); +KAGUYA_TEST_FUNCTION_DEF(int_call_constructor_manual)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors().addFunction( + "getInt", &ABC::getInt)); + kaguya::LuaTable constructor_table = state.newTable(); + constructor_table["__call"] = kaguya::LuaCodeChunkResult( + "return function(t,...) return t.new(...) end"); + state["ABC"].setMetatable(constructor_table); + + TEST_CHECK(state("value = assert(ABC(32))")); + TEST_CHECK(state("assert(value:getInt() == 32)")); } -KAGUYA_TEST_FUNCTION_DEF(self_register_index_object)(kaguya::State& state) -{ - - state["ABC"].setClass(kaguya::UserdataMetatable() - .addStaticFunction("__index", &testindexfn) - .addStaticFunction("__newindex", &testnewindexfn)); - ABC obj; - state["obj"] = ABC(3); - state("assert(obj[3]==9);"); - state("obj[1]=3;"); - - {//other way - kaguya::State state; - state["ABC"].setClass(kaguya::UserdataMetatable()); - - state["ABC"]["__index"] = kaguya::function(&testindexfn); - state["ABC"]["__newindex"] = kaguya::function(&testindexfn); - - ABC obj; - state["obj"] = ABC(3); - state("assert(obj[3]==9);"); - state("obj[1]=3;"); - } -} - -KAGUYA_TEST_FUNCTION_DEF(call_constructor)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getInt", &ABC::getInt) - ); - - TEST_CHECK(state("value = assert(ABC(32))")); - TEST_CHECK(state("assert(value:getInt() == 32)")); - - state["Foo"].setClass(kaguya::UserdataMetatable() - .setConstructors() - ); - TEST_CHECK(state("value = assert(Foo())")); - - - state["Base"].setClass(kaguya::UserdataMetatable() - .addProperty("a", &Base::a) - .addFunction("__call", &Base::get) - .setConstructors() - ); - state["Base2"].setClass(kaguya::UserdataMetatable() - .addProperty("b", &Base2::b) - .addFunction("__call", &Base2::test) - .setConstructors() - ); - state["MultipleInheritance"].setClass(kaguya::UserdataMetatable >() - .setConstructors() - .addFunction("__call", &MultipleInheritance::test) - .addFunction("d", &MultipleInheritance::d) - ); - - TEST_CHECK(state("multiinheritance = assert(MultipleInheritance())")); - TEST_CHECK(state("assert(multiinheritance:d() == 0)")); - TEST_CHECK(state("assert(multiinheritance.a == 0)")); - TEST_CHECK(state("assert(multiinheritance.b == 0)")); - TEST_CHECK(state("assert(multiinheritance() == 1192)")); - - TEST_CHECK(state("base2 = assert(Base2())")); - TEST_CHECK(state("assert(base2.b == 0)")); - TEST_CHECK(state("assert(base2() == 794)")); - TEST_CHECK(state("base = assert(Base())")); - TEST_CHECK(state("assert(base.a == 0)")); - TEST_CHECK(state("base.a = 4 assert(base.a == 4) assert(base() == 4)")); -} -KAGUYA_TEST_FUNCTION_DEF(int_call_constructor_manual)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getInt", &ABC::getInt) - ); - kaguya::LuaTable constructor_table = state.newTable(); - constructor_table["__call"] = kaguya::LuaCodeChunkResult("return function(t,...) return t.new(...) end"); - state["ABC"].setMetatable(constructor_table); - - TEST_CHECK(state("value = assert(ABC(32))")); - TEST_CHECK(state("assert(value:getInt() == 32)")); +KAGUYA_TEST_FUNCTION_DEF(constructor_arg_type_mismatch_error) +(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors().addFunction( + "getInt", &ABC::getInt)); + state.setErrorHandler(ignore_error_fun); + + last_error_message = ""; + bool res = state("v = ABC.new('abc')"); + TEST_CHECK(!res); + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); } +KAGUYA_TEST_FUNCTION_DEF(arg_type_mismatch_error)(kaguya::State &state) { + state["ABC"].setClass( + kaguya::UserdataMetatable().setConstructors().addFunction( + "setInt", &ABC::setInt)); + state.setErrorHandler(ignore_error_fun); -KAGUYA_TEST_FUNCTION_DEF(constructor_arg_type_mismatch_error)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("getInt", &ABC::getInt) - ); - state.setErrorHandler(ignore_error_fun); - - last_error_message = ""; - bool res = state("v = ABC.new('abc')"); - TEST_CHECK(!res); - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); -} + last_error_message = ""; + TEST_CHECK(state("value = assert(ABC.new(32))")); -KAGUYA_TEST_FUNCTION_DEF(arg_type_mismatch_error)(kaguya::State& state) -{ - state["ABC"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("setInt", &ABC::setInt) - ); - state.setErrorHandler(ignore_error_fun); + TEST_CHECK(!state("value:setInt('abc')")); - last_error_message = ""; - TEST_CHECK(state("value = assert(ABC.new(32))")); - - TEST_CHECK(!state("value:setInt('abc')")); - - TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); -} -int Base_a_getter(const Base* self) -{ - return self->a; + TEST_CHECK(last_error_message.find("mismatch") != std::string::npos); } -void Base_a_setter(Base* self,int v) -{ - self->a = v; +int Base_a_getter(const Base *self) { return self->a; } +void Base_a_setter(Base *self, int v) { self->a = v; } +KAGUYA_TEST_FUNCTION_DEF(add_property_external)(kaguya::State &state) { + + state["Base"].setClass( + kaguya::UserdataMetatable().setConstructors().addProperty( + "a", &Base_a_getter, &Base_a_setter)); + Base base; + state["base"] = &base; + TEST_CHECK(state("base.a=1")); + TEST_CHECK(state("assert(1 == base.a)")); + TEST_EQUAL(base.a, 1); } -KAGUYA_TEST_FUNCTION_DEF(add_property_external)(kaguya::State& state) -{ - - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("a", &Base_a_getter,&Base_a_setter) - ); - Base base; - state["base"] = &base; - TEST_CHECK(state("base.a=1")); - TEST_CHECK(state("assert(1 == base.a)")); - TEST_EQUAL(base.a, 1); -} -KAGUYA_TEST_FUNCTION_DEF(add_property_any)(kaguya::State& state) -{ - - state["Base"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addPropertyAny("a", &Base_a_getter, &Base_a_setter) - ); - Base base; - state["base"] = &base; - TEST_CHECK(state("base.a=1")); - TEST_CHECK(state("assert(1 == base.a)")); - TEST_EQUAL(base.a, 1); +KAGUYA_TEST_FUNCTION_DEF(add_property_any)(kaguya::State &state) { + + state["Base"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addPropertyAny("a", &Base_a_getter, &Base_a_setter)); + Base base; + state["base"] = &base; + TEST_CHECK(state("base.a=1")); + TEST_CHECK(state("assert(1 == base.a)")); + TEST_EQUAL(base.a, 1); } +KAGUYA_MEMBER_FUNCTION_OVERLOADS(PureVirtualBase_defarg_test, PureVirtualBase, + default_arg, 0, 1) +KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE( + PureVirtualBase_const_defarg_test, PureVirtualBase, const_default_arg, 0, 1, + void (PureVirtualBase::*)(int) const) + +struct PureVirtualDerived : PureVirtualBase { + PureVirtualDerived(int &t) : v(t){}; + virtual ~PureVirtualDerived(){}; + + virtual void test() { v = 1; }; + virtual void default_arg(int a = 0) { v = a; } + virtual void const_test() const { v = 2; }; + virtual void const_default_arg(int a = 0) const { v = a; } -KAGUYA_MEMBER_FUNCTION_OVERLOADS(PureVirtualBase_defarg_test, PureVirtualBase, default_arg, 0, 1) -KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(PureVirtualBase_const_defarg_test, PureVirtualBase, const_default_arg, 0, 1, void(PureVirtualBase::*)(int)const) - -struct PureVirtualDerived : PureVirtualBase -{ - PureVirtualDerived(int& t) :v(t) {}; - virtual ~PureVirtualDerived() {}; - - virtual void test() { - v = 1; - }; - virtual void default_arg(int a = 0) { - v = a; - } - virtual void const_test()const { - v = 2; - }; - virtual void const_default_arg(int a = 0) const - { - v = a; - } - - int& v; + int &v; }; -KAGUYA_TEST_FUNCTION_DEF(pure_virtual_test)(kaguya::State& state) -{ - - state["PureVirtualBase"].setClass(kaguya::UserdataMetatable() - .addFunction("test", &PureVirtualBase::test) - .addFunction("const_test", &PureVirtualBase::const_test) - .addFunction("default_arg", PureVirtualBase_defarg_test()) - .addFunction("const_default_arg", PureVirtualBase_const_defarg_test()) - ); - - state["PureVirtualDerived"].setClass(kaguya::UserdataMetatable() - .addFunction("test", &PureVirtualDerived::test) - ); - int test = 0; - PureVirtualDerived virtual_test(test); - state["test"] = &virtual_test; - TEST_CHECK(state("test:test()")); - TEST_EQUAL(test, 1); - TEST_CHECK(state("test:const_test()")); - TEST_EQUAL(test, 2); - TEST_CHECK(state("test:default_arg()")); - TEST_EQUAL(test, 0); - TEST_CHECK(state("test:default_arg(6)")); - TEST_EQUAL(test, 6); - TEST_CHECK(state("test:const_default_arg()")); - TEST_EQUAL(test, 0); - TEST_CHECK(state("test:const_default_arg(6)")); - TEST_EQUAL(test, 6); - - test = 0; - PureVirtualBase* pure_virtual_test = &virtual_test; - state["test"] = pure_virtual_test; - TEST_CHECK(state("test:test()")); - TEST_EQUAL(test, 1); - TEST_CHECK(state("test:const_test()")); - TEST_EQUAL(test, 2); - TEST_CHECK(state("test:default_arg()")); - TEST_EQUAL(test, 0); - TEST_CHECK(state("test:default_arg(6)")); - TEST_EQUAL(test, 6); - TEST_CHECK(state("test:const_default_arg()")); - TEST_EQUAL(test, 0); - TEST_CHECK(state("test:const_default_arg(6)")); - TEST_EQUAL(test, 6); +KAGUYA_TEST_FUNCTION_DEF(pure_virtual_test)(kaguya::State &state) { + + state["PureVirtualBase"].setClass( + kaguya::UserdataMetatable() + .addFunction("test", &PureVirtualBase::test) + .addFunction("const_test", &PureVirtualBase::const_test) + .addFunction("default_arg", PureVirtualBase_defarg_test()) + .addFunction("const_default_arg", + PureVirtualBase_const_defarg_test())); + + state["PureVirtualDerived"].setClass( + kaguya::UserdataMetatable() + .addFunction("test", &PureVirtualDerived::test)); + int test = 0; + PureVirtualDerived virtual_test(test); + state["test"] = &virtual_test; + TEST_CHECK(state("test:test()")); + TEST_EQUAL(test, 1); + TEST_CHECK(state("test:const_test()")); + TEST_EQUAL(test, 2); + TEST_CHECK(state("test:default_arg()")); + TEST_EQUAL(test, 0); + TEST_CHECK(state("test:default_arg(6)")); + TEST_EQUAL(test, 6); + TEST_CHECK(state("test:const_default_arg()")); + TEST_EQUAL(test, 0); + TEST_CHECK(state("test:const_default_arg(6)")); + TEST_EQUAL(test, 6); + + test = 0; + PureVirtualBase *pure_virtual_test = &virtual_test; + state["test"] = pure_virtual_test; + TEST_CHECK(state("test:test()")); + TEST_EQUAL(test, 1); + TEST_CHECK(state("test:const_test()")); + TEST_EQUAL(test, 2); + TEST_CHECK(state("test:default_arg()")); + TEST_EQUAL(test, 0); + TEST_CHECK(state("test:default_arg(6)")); + TEST_EQUAL(test, 6); + TEST_CHECK(state("test:const_default_arg()")); + TEST_EQUAL(test, 0); + TEST_CHECK(state("test:const_default_arg(6)")); + TEST_EQUAL(test, 6); } KAGUYA_TEST_GROUP_END(test_02_classreg) diff --git a/test/test_03_function.cpp b/test/test_03_function.cpp index e72ec10..a70e968 100644 --- a/test/test_03_function.cpp +++ b/test/test_03_function.cpp @@ -5,577 +5,492 @@ KAGUYA_TEST_GROUP_START(test_03_function) using namespace kaguya_test_util; int arg = 0; -void free_standing_function(int r) -{ - arg = r; -} -int free_standing_function2() -{ - return 12; -} -int free_standing_function3(const char* text) -{ - return atoi(text); -} +void free_standing_function(int r) { arg = r; } +int free_standing_function2() { return 12; } +int free_standing_function3(const char *text) { return atoi(text); } -KAGUYA_TEST_FUNCTION_DEF(free_standing_function_test)(kaguya::State& state) -{ - state["ABC"] = &free_standing_function; - state["ABC"](54); - state["free2"] = &free_standing_function2; - TEST_EQUAL(arg, 54); - TEST_CHECK(state["free2"]() == 12.0); +KAGUYA_TEST_FUNCTION_DEF(free_standing_function_test)(kaguya::State &state) { + state["ABC"] = &free_standing_function; + state["ABC"](54); + state["free2"] = &free_standing_function2; + TEST_EQUAL(arg, 54); + TEST_CHECK(state["free2"]() == 12.0); - state["free3"] = &free_standing_function3; - TEST_CHECK(state["free3"]("54") == 54.0); + state["free3"] = &free_standing_function3; + TEST_CHECK(state["free3"]("54") == 54.0); } - - - -kaguya::standard::tuple tuplefun() -{ - return kaguya::standard::tuple(12, "23"); +kaguya::standard::tuple tuplefun() { + return kaguya::standard::tuple(12, "23"); } -KAGUYA_TEST_FUNCTION_DEF(multi_return_function_test)(kaguya::State& state) -{ - state["multresfun2"] = kaguya::function(tuplefun); +KAGUYA_TEST_FUNCTION_DEF(multi_return_function_test)(kaguya::State &state) { + state["multresfun2"] = kaguya::function(tuplefun); - state("a,b = multresfun2()"); - TEST_CHECK(state("assert(a == 12 and b == '23')")); + state("a,b = multresfun2()"); + TEST_CHECK(state("assert(a == 12 and b == '23')")); } -void pointerfun(void* pointer) -{ - TEST_EQUAL(pointer, 0); -} -void const_pointerfun(const void* pointer) -{ - TEST_EQUAL(pointer, 0); -} +void pointerfun(void *pointer) { TEST_EQUAL(pointer, 0); } +void const_pointerfun(const void *pointer) { TEST_EQUAL(pointer, 0); } std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; -} -KAGUYA_TEST_FUNCTION_DEF(nil_to_nullpointer)(kaguya::State& state) -{ - state["pointerfun"] = kaguya::function(pointerfun); - TEST_CHECK(state("pointerfun(nil)")); - state["const_pointerfun"] = kaguya::function(const_pointerfun); - TEST_CHECK(state("const_pointerfun(nil)")); - - state.setErrorHandler(ignore_error_fun); - TEST_CHECK(!state("pointerfun(32)"));// is error - TEST_CHECK(!state("pointerfun('232')"));// is error -} -KAGUYA_TEST_FUNCTION_DEF(noargs_to_nullpointer)(kaguya::State& state) -{ - state["pointerfun"] = kaguya::function(pointerfun); - TEST_CHECK(state("pointerfun()")); - state["const_pointerfun"] = kaguya::function(const_pointerfun); - TEST_CHECK(state("const_pointerfun()")); -} - - -struct Foo -{ - std::string bar; - void setBar(std::string b) { bar = b; } +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; +} +KAGUYA_TEST_FUNCTION_DEF(nil_to_nullpointer)(kaguya::State &state) { + state["pointerfun"] = kaguya::function(pointerfun); + TEST_CHECK(state("pointerfun(nil)")); + state["const_pointerfun"] = kaguya::function(const_pointerfun); + TEST_CHECK(state("const_pointerfun(nil)")); + + state.setErrorHandler(ignore_error_fun); + TEST_CHECK(!state("pointerfun(32)")); // is error + TEST_CHECK(!state("pointerfun('232')")); // is error +} +KAGUYA_TEST_FUNCTION_DEF(noargs_to_nullpointer)(kaguya::State &state) { + state["pointerfun"] = kaguya::function(pointerfun); + TEST_CHECK(state("pointerfun()")); + state["const_pointerfun"] = kaguya::function(const_pointerfun); + TEST_CHECK(state("const_pointerfun()")); +} + +struct Foo { + std::string bar; + void setBar(std::string b) { bar = b; } }; -struct Bar -{ - std::string member; - Bar() {} - Bar(const std::string& data) :member(data) {} +struct Bar { + std::string member; + Bar() {} + Bar(const std::string &data) : member(data) {} }; -KAGUYA_TEST_FUNCTION_DEF(native_function_call_test)(kaguya::State& state) -{ - using namespace kaguya::nativefunction; - Foo foo; - state.newRef(6).push(); - state.newRef(9).push(); - state.newRef(2).push(); - int getarg = getArgument<0, void(int, int, int)>(state.state()); - TEST_EQUAL(getarg, 6); - getarg = getArgument<1, void(int, int, int)>(state.state()); - TEST_EQUAL(getarg, 9); - getarg = getArgument<2, void(int, int, int)>(state.state()); - TEST_EQUAL(getarg, 2); - - call(state.state(), &free_standing_function); - - lua_settop(state.state(), 0); - state.newRef(&foo).push(); - state.newRef("Bar").push(); - call(state.state(), &Foo::setBar); - - - lua_settop(state.state(), 0); +KAGUYA_TEST_FUNCTION_DEF(native_function_call_test)(kaguya::State &state) { + using namespace kaguya::nativefunction; + Foo foo; + state.newRef(6).push(); + state.newRef(9).push(); + state.newRef(2).push(); + int getarg = getArgument<0, void(int, int, int)>(state.state()); + TEST_EQUAL(getarg, 6); + getarg = getArgument<1, void(int, int, int)>(state.state()); + TEST_EQUAL(getarg, 9); + getarg = getArgument<2, void(int, int, int)>(state.state()); + TEST_EQUAL(getarg, 2); + + call(state.state(), &free_standing_function); + + lua_settop(state.state(), 0); + state.newRef(&foo).push(); + state.newRef("Bar").push(); + call(state.state(), &Foo::setBar); + + lua_settop(state.state(), 0); #if KAGUYA_USE_CPP11 - state.newRef(&foo).push(); - state.newRef(9).push(); - call(state.state(), [](Foo* foo, int b) { - TEST_EQUAL(b, 9); - foo->setBar("fromlambda"); - }); - TEST_EQUAL(foo.bar, "fromlambda"); - - std::string capture("capture"); - call(state.state(), [=](Foo* foo, int b) { - TEST_EQUAL(b, 9); - foo->setBar(capture + "lambda"); - }); - TEST_EQUAL(foo.bar, "capturelambda"); + state.newRef(&foo).push(); + state.newRef(9).push(); + call(state.state(), [](Foo *foo, int b) { + TEST_EQUAL(b, 9); + foo->setBar("fromlambda"); + }); + TEST_EQUAL(foo.bar, "fromlambda"); + + std::string capture("capture"); + call(state.state(), [=](Foo *foo, int b) { + TEST_EQUAL(b, 9); + foo->setBar(capture + "lambda"); + }); + TEST_EQUAL(foo.bar, "capturelambda"); #endif - lua_settop(state.state(), 0); + lua_settop(state.state(), 0); } -int overload1() -{ - return 1; -} -int overload2(const std::string&) -{ - return 2; -} -int overload3(int) -{ - return 3; -} +int overload1() { return 1; } +int overload2(const std::string &) { return 2; } +int overload3(int) { return 3; } #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE -int overload4(const std::vector& ) -{ - return 4; -} +int overload4(const std::vector &) { return 4; } #endif #ifndef KAGUYA_NO_STD_MAP_TO_TABLE -int overload5(const std::map& ) -{ - return 5; -} +int overload5(const std::map &) { return 5; } // This function after the first to trigger weak type test -int overload6(const std::map& , int b) -{ - return b; -} +int overload6(const std::map &, int b) { return b; } #endif -int overload7(void*) -{ - return 7; -} +int overload7(void *) { return 7; } -int overload8(const Foo*) -{ - return 8; -} -int overload9(Bar*) -{ - return 9; -} -int overload10(const kaguya::standard::function fn) -{ - TEST_EQUAL(fn(), 1); - return 10; +int overload8(const Foo *) { return 8; } +int overload9(Bar *) { return 9; } +int overload10(const kaguya::standard::function fn) { + TEST_EQUAL(fn(), 1); + return 10; } -KAGUYA_TEST_FUNCTION_DEF(overload)(kaguya::State& state) -{ - state["overloaded_function"] = kaguya::overload(overload1, overload2, overload3 +KAGUYA_TEST_FUNCTION_DEF(overload)(kaguya::State &state) { + state["overloaded_function"] = + kaguya::overload(overload1, overload2, overload3 #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE - , overload4 + , + overload4 #endif #ifndef KAGUYA_NO_STD_MAP_TO_TABLE - , overload5 - , overload6 + , + overload5, overload6 #endif - , overload7 - , overload8 - , overload9 - ); - kaguya::LuaFunction f = state["overloaded_function"]; - TEST_EQUAL(f(), 1); - TEST_EQUAL(f(""), 2); - TEST_EQUAL(f(121), 3); + , + overload7, overload8, overload9); + kaguya::LuaFunction f = state["overloaded_function"]; + TEST_EQUAL(f(), 1); + TEST_EQUAL(f(""), 2); + TEST_EQUAL(f(121), 3); #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE - TEST_CHECK(state("assert(overloaded_function({3,4,2,4,5}) == 4)")); + TEST_CHECK(state("assert(overloaded_function({3,4,2,4,5}) == 4)")); #endif #ifndef KAGUYA_NO_STD_MAP_TO_TABLE - TEST_CHECK(state("assert(overloaded_function({a='3',b='3'}) == 5)")); - TEST_CHECK(state("assert(overloaded_function({a='3',b='3'}, 6) == 6)")); + TEST_CHECK(state("assert(overloaded_function({a='3',b='3'}) == 5)")); + TEST_CHECK(state("assert(overloaded_function({a='3',b='3'}, 6) == 6)")); #endif - TEST_EQUAL(f((void*)0), 7); - TEST_CHECK(state("assert(overloaded_function(nil) == 7)")); - + TEST_EQUAL(f((void *)0), 7); + TEST_CHECK(state("assert(overloaded_function(nil) == 7)")); - state["Foo"].setClass(kaguya::UserdataMetatable()); - state["Bar"].setClass(kaguya::UserdataMetatable()); + state["Foo"].setClass(kaguya::UserdataMetatable()); + state["Bar"].setClass(kaguya::UserdataMetatable()); - TEST_EQUAL(f(Foo()), 8); - TEST_EQUAL(f(Bar()), 9); + TEST_EQUAL(f(Foo()), 8); + TEST_EQUAL(f(Bar()), 9); - - - state["overloaded_function2"] = kaguya::overload(overload1, overload2, overload3 - , overload10 - ); - kaguya::LuaFunction f2 = state["overloaded_function2"]; - TEST_EQUAL(f2(kaguya::standard::function(overload1)), 10); + state["overloaded_function2"] = + kaguya::overload(overload1, overload2, overload3, overload10); + kaguya::LuaFunction f2 = state["overloaded_function2"]; + TEST_EQUAL(f2(kaguya::standard::function(overload1)), 10); } - -KAGUYA_TEST_FUNCTION_DEF(result_to_table)(kaguya::State& state) -{ - state["result_to_table"] = kaguya::function(overload1); - state["result"] = state["result_to_table"](); - TEST_EQUAL(state["result"], 1); +KAGUYA_TEST_FUNCTION_DEF(result_to_table)(kaguya::State &state) { + state["result_to_table"] = kaguya::function(overload1); + state["result"] = state["result_to_table"](); + TEST_EQUAL(state["result"], 1); } -void nested_function_call(kaguya::LuaStackRef function, kaguya::LuaStackRef value, kaguya::LuaStackRef value2) -{ - function(value, value2); +void nested_function_call(kaguya::LuaStackRef function, + kaguya::LuaStackRef value, + kaguya::LuaStackRef value2) { + function(value, value2); } -KAGUYA_TEST_FUNCTION_DEF(nested_function_call_test)(kaguya::State& state) -{ - state["nested_function_call"] = kaguya::function(nested_function_call); +KAGUYA_TEST_FUNCTION_DEF(nested_function_call_test)(kaguya::State &state) { + state["nested_function_call"] = kaguya::function(nested_function_call); - state("nested_function_call(function(value,value2) assert(value == 32);assert(value2 == 'text') end,32,'text')"); + state("nested_function_call(function(value,value2) assert(value == " + "32);assert(value2 == 'text') end,32,'text')"); } -void nested_function_call2(kaguya::LuaStackRef function, const kaguya::LuaStackRef& table, kaguya::LuaStackRef value2) -{ - function(table["key"], value2); +void nested_function_call2(kaguya::LuaStackRef function, + const kaguya::LuaStackRef &table, + kaguya::LuaStackRef value2) { + function(table["key"], value2); } +KAGUYA_TEST_FUNCTION_DEF(nested_function_call_test2)(kaguya::State &state) { + state["nested_function_call"] = kaguya::function(nested_function_call2); -KAGUYA_TEST_FUNCTION_DEF(nested_function_call_test2)(kaguya::State& state) -{ - state["nested_function_call"] = kaguya::function(nested_function_call2); - - state("nested_function_call(function(value,value2) assert(value==32);assert(value2 == 'text') end,{key=32},'text')"); - + state("nested_function_call(function(value,value2) " + "assert(value==32);assert(value2 == 'text') end,{key=32},'text')"); } -namespace functioncall_testfunction -{ - int called = 0; - void testcall() - { - called = 1; - } - void testcall2(int) - { - called = 2; - } +namespace functioncall_testfunction { +int called = 0; +void testcall() { called = 1; } +void testcall2(int) { called = 2; } } -KAGUYA_TEST_FUNCTION_DEF(functioncall)(kaguya::State& state) -{ - using namespace functioncall_testfunction; - kaguya::standard::function f = testcall; - kaguya::standard::function f2 = testcall2; - state["testcall"] = &testcall; - state["testcall"](); - TEST_EQUAL(called, 1); - called = 0; +KAGUYA_TEST_FUNCTION_DEF(functioncall)(kaguya::State &state) { + using namespace functioncall_testfunction; + kaguya::standard::function f = testcall; + kaguya::standard::function f2 = testcall2; + state["testcall"] = &testcall; + state["testcall"](); + TEST_EQUAL(called, 1); + called = 0; - state["testcall"] = kaguya::function(f); - state["testcall"](); - TEST_EQUAL(called, 1); + state["testcall"] = kaguya::function(f); + state["testcall"](); + TEST_EQUAL(called, 1); - state["overloaded"] = kaguya::overload(testcall2, testcall, f, f2); - state["overloaded"](); - TEST_EQUAL(called, 1); - state["overloaded"](1); - TEST_EQUAL(called, 2); - state["overloaded"](1, 2); - TEST_EQUAL(called, 2); - state["overloaded"]("test"); - TEST_EQUAL(called, 1); + state["overloaded"] = kaguya::overload(testcall2, testcall, f, f2); + state["overloaded"](); + TEST_EQUAL(called, 1); + state["overloaded"](1); + TEST_EQUAL(called, 2); + state["overloaded"](1, 2); + TEST_EQUAL(called, 2); + state["overloaded"]("test"); + TEST_EQUAL(called, 1); } -int cfunction(lua_State* L) -{ - TEST_EQUAL(lua_tointeger(L, 1), 3); - return 0; +int cfunction(lua_State *L) { + TEST_EQUAL(lua_tointeger(L, 1), 3); + return 0; } -int coroutinefn(lua_State* cor) -{ - using namespace kaguya; - lua_resume(cor, 0, 0); - return static_cast(lua_tointeger(cor, 1)); +int coroutinefn(lua_State *cor) { + using namespace kaguya; + lua_resume(cor, 0, 0); + return static_cast(lua_tointeger(cor, 1)); } -KAGUYA_TEST_FUNCTION_DEF(luacfunction)(kaguya::State& state) -{ - state["cfunction"] = kaguya::luacfunction(&cfunction); +KAGUYA_TEST_FUNCTION_DEF(luacfunction)(kaguya::State &state) { + state["cfunction"] = kaguya::luacfunction(&cfunction); - state.dostring("cfunction(3)"); + state.dostring("cfunction(3)"); - state["coroutinefn"] = kaguya::function(&coroutinefn); - state.dostring("assert(coroutinefn( coroutine.create(function () return 8 end) ) == 8)"); + state["coroutinefn"] = kaguya::function(&coroutinefn); + state.dostring( + "assert(coroutinefn( coroutine.create(function () return 8 end) ) == 8)"); - state["coroutinefn"] = &coroutinefn; - state.dostring("assert(coroutinefn( coroutine.create(function () return 3 end) ) == 3)"); + state["coroutinefn"] = &coroutinefn; + state.dostring( + "assert(coroutinefn( coroutine.create(function () return 3 end) ) == 3)"); } -int defargfn(int a = 3, int b = 2, int c = 1) -{ - return a*b*c; -} +int defargfn(int a = 3, int b = 2, int c = 1) { return a * b * c; } KAGUYA_FUNCTION_OVERLOADS(defargfn_wrapper, defargfn, 0, 3) -KAGUYA_TEST_FUNCTION_DEF(defaultarguments)(kaguya::State& state) -{ - state["defargfn"] = kaguya::function(defargfn_wrapper()); +KAGUYA_TEST_FUNCTION_DEF(defaultarguments)(kaguya::State &state) { + state["defargfn"] = kaguya::function(defargfn_wrapper()); - state.dostring("assert(defargfn() == 6)"); - state.dostring("assert(defargfn(6) == 12)"); - state.dostring("assert(defargfn(6,5) == 30)"); - state.dostring("assert(defargfn(2,2,2) == 8)"); + state.dostring("assert(defargfn() == 6)"); + state.dostring("assert(defargfn(6) == 12)"); + state.dostring("assert(defargfn(6,5) == 30)"); + state.dostring("assert(defargfn(2,2,2) == 8)"); } -KAGUYA_MEMBER_FUNCTION_OVERLOADS(mem_defargfn_wrapper, TestClass, default_arg, 0, 3) -KAGUYA_TEST_FUNCTION_DEF(member_function_defaultarguments)(kaguya::State& state) -{ +KAGUYA_MEMBER_FUNCTION_OVERLOADS(mem_defargfn_wrapper, TestClass, default_arg, + 0, 3) +KAGUYA_TEST_FUNCTION_DEF(member_function_defaultarguments) +(kaguya::State &state) { - state["TestClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("defargfn", mem_defargfn_wrapper()) - ); + state["TestClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("defargfn", mem_defargfn_wrapper())); - state.dostring("test = TestClass.new()"); + state.dostring("test = TestClass.new()"); - state.dostring("assert(test:defargfn() == 6)"); - state.dostring("assert(test:defargfn(6) == 12)"); - state.dostring("assert(test:defargfn(6,5) == 30)"); - state.dostring("assert(test:defargfn(2,2,2) == 8)"); + state.dostring("assert(test:defargfn() == 6)"); + state.dostring("assert(test:defargfn(6) == 12)"); + state.dostring("assert(test:defargfn(6,5) == 30)"); + state.dostring("assert(test:defargfn(2,2,2) == 8)"); } - -void void_defargfn(int a = 3, int b = 2, int c = 1) -{ -TEST_EQUAL(a, 3); -TEST_EQUAL(b, 2); -TEST_EQUAL(c, 1); +void void_defargfn(int a = 3, int b = 2, int c = 1) { + TEST_EQUAL(a, 3); + TEST_EQUAL(b, 2); + TEST_EQUAL(c, 1); } KAGUYA_FUNCTION_OVERLOADS(void_defargfn_wrapper, void_defargfn, 0, 3) -KAGUYA_TEST_FUNCTION_DEF(void_defaultarguments)(kaguya::State& state) -{ - state["defargfn"] = kaguya::function(void_defargfn_wrapper()); +KAGUYA_TEST_FUNCTION_DEF(void_defaultarguments)(kaguya::State &state) { + state["defargfn"] = kaguya::function(void_defargfn_wrapper()); - state.dostring("defargfn()"); - state.dostring("defargfn(3)"); - state.dostring("defargfn(3,2)"); - state.dostring("defargfn(3,2,1)"); + state.dostring("defargfn()"); + state.dostring("defargfn(3)"); + state.dostring("defargfn(3,2)"); + state.dostring("defargfn(3,2,1)"); } -KAGUYA_MEMBER_FUNCTION_OVERLOADS(default_set_wrapper, TestClass, default_set, 0, 3) +KAGUYA_MEMBER_FUNCTION_OVERLOADS(default_set_wrapper, TestClass, default_set, 0, + 3) -KAGUYA_TEST_FUNCTION_DEF(member_void_function_defaultarguments)(kaguya::State& state) -{ +KAGUYA_TEST_FUNCTION_DEF(member_void_function_defaultarguments) +(kaguya::State &state) { - state["TestClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("defargfn", default_set_wrapper()) - .addFunction("getInt", &TestClass::getInt) - ); + state["TestClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("defargfn", default_set_wrapper()) + .addFunction("getInt", &TestClass::getInt)); - state.dostring("test = TestClass.new()"); + state.dostring("test = TestClass.new()"); - state.dostring("test:defargfn() assert(test:getInt() == 6)"); - state.dostring("test:defargfn(6) assert(test:getInt() == 12)"); - state.dostring("test:defargfn(6,5) assert(test:getInt() == 30)"); - state.dostring("test:defargfn(2,2,2) assert(test:getInt() == 8)"); + state.dostring("test:defargfn() assert(test:getInt() == 6)"); + state.dostring("test:defargfn(6) assert(test:getInt() == 12)"); + state.dostring("test:defargfn(6,5) assert(test:getInt() == 30)"); + state.dostring("test:defargfn(2,2,2) assert(test:getInt() == 8)"); } - -std::string defargfn2(std::string a, std::string b = "b", std::string c = "c") -{ - return a + b + c; +std::string defargfn2(std::string a, std::string b = "b", std::string c = "c") { + return a + b + c; } - - KAGUYA_FUNCTION_OVERLOADS(defargfn2_wrapper, defargfn2, 1, 3) -KAGUYA_TEST_FUNCTION_DEF(defaultarguments_overload)(kaguya::State& state) -{ - state["defargfn"] = kaguya::overload(defargfn_wrapper(), defargfn2_wrapper()); +KAGUYA_TEST_FUNCTION_DEF(defaultarguments_overload)(kaguya::State &state) { + state["defargfn"] = kaguya::overload(defargfn_wrapper(), defargfn2_wrapper()); - state.dostring("assert(defargfn() == 6)"); - state.dostring("assert(defargfn(6) == 12)"); - state.dostring("assert(defargfn(6,5) == 30)"); - state.dostring("assert(defargfn(2,2,2) == 8)"); + state.dostring("assert(defargfn() == 6)"); + state.dostring("assert(defargfn(6) == 12)"); + state.dostring("assert(defargfn(6,5) == 30)"); + state.dostring("assert(defargfn(2,2,2) == 8)"); - state.dostring("assert(defargfn('a') == 'abc')"); - state.dostring("assert(defargfn('a','b') == 'abc')"); - state.dostring("assert(defargfn('a','b','c') == 'abc')"); - state.dostring("assert(defargfn('d','e','f') == 'def')"); + state.dostring("assert(defargfn('a') == 'abc')"); + state.dostring("assert(defargfn('a','b') == 'abc')"); + state.dostring("assert(defargfn('a','b','c') == 'abc')"); + state.dostring("assert(defargfn('d','e','f') == 'def')"); } +KAGUYA_FUNCTION_OVERLOADS_WITH_SIGNATURE(defargfn_wrapper_with_sig, defargfn, 0, + 3, int(int, int, int)) -KAGUYA_FUNCTION_OVERLOADS_WITH_SIGNATURE(defargfn_wrapper_with_sig, defargfn, 0, 3,int(int,int,int)) - -KAGUYA_TEST_FUNCTION_DEF(defaultarguments_overload_with_sig)(kaguya::State& state) -{ - state["defargfn"] = kaguya::function(defargfn_wrapper_with_sig()); +KAGUYA_TEST_FUNCTION_DEF(defaultarguments_overload_with_sig) +(kaguya::State &state) { + state["defargfn"] = kaguya::function(defargfn_wrapper_with_sig()); - state.dostring("assert(defargfn() == 6)"); - state.dostring("assert(defargfn(6) == 12)"); - state.dostring("assert(defargfn(6,5) == 30)"); - state.dostring("assert(defargfn(2,2,2) == 8)"); + state.dostring("assert(defargfn() == 6)"); + state.dostring("assert(defargfn(6) == 12)"); + state.dostring("assert(defargfn(6,5) == 30)"); + state.dostring("assert(defargfn(2,2,2) == 8)"); } +KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(mem_defargfn_wrapper_with_sig, + TestClass, default_arg, 0, 3, + int (TestClass::*)(int, int, + int)) -KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(mem_defargfn_wrapper_with_sig, TestClass, default_arg, 0, 3,int(TestClass::*)(int,int,int)) +KAGUYA_TEST_FUNCTION_DEF(member_function_defaultarguments_with_sig) +(kaguya::State &state) { -KAGUYA_TEST_FUNCTION_DEF(member_function_defaultarguments_with_sig)(kaguya::State& state) -{ + state["TestClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("defargfn", mem_defargfn_wrapper_with_sig())); - state["TestClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("defargfn", mem_defargfn_wrapper_with_sig()) - ); + state.dostring("test = TestClass.new()"); - state.dostring("test = TestClass.new()"); - - state.dostring("assert(test:defargfn() == 6)"); - state.dostring("assert(test:defargfn(6) == 12)"); - state.dostring("assert(test:defargfn(6,5) == 30)"); - state.dostring("assert(test:defargfn(2,2,2) == 8)"); + state.dostring("assert(test:defargfn() == 6)"); + state.dostring("assert(test:defargfn(6) == 12)"); + state.dostring("assert(test:defargfn(6,5) == 30)"); + state.dostring("assert(test:defargfn(2,2,2) == 8)"); } -KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(TestClass_default_set_overload_int, TestClass, default_set_overload, 1, 3, void(TestClass::*)(int, int, int)) -KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE(TestClass_default_set_overload_str, TestClass, default_set_overload, 1, 3, void(TestClass::*)(std::string, std::string, std::string)) - -KAGUYA_TEST_FUNCTION_DEF(member_function_different_type_overload)(kaguya::State& state) -{ +KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE( + TestClass_default_set_overload_int, TestClass, default_set_overload, 1, 3, + void (TestClass::*)(int, int, int)) +KAGUYA_MEMBER_FUNCTION_OVERLOADS_WITH_SIGNATURE( + TestClass_default_set_overload_str, TestClass, default_set_overload, 1, 3, + void (TestClass::*)(std::string, std::string, std::string)) - state["TestClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addOverloadedFunctions("defargfn", TestClass_default_set_overload_int(), TestClass_default_set_overload_str()) - .addFunction("getInt", &TestClass::getInt) - .addFunction("getString", &TestClass::getString) - ); +KAGUYA_TEST_FUNCTION_DEF(member_function_different_type_overload) +(kaguya::State &state) { - state["defargfn"] = kaguya::overload(defargfn_wrapper(), defargfn2_wrapper()); + state["TestClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addOverloadedFunctions("defargfn", + TestClass_default_set_overload_int(), + TestClass_default_set_overload_str()) + .addFunction("getInt", &TestClass::getInt) + .addFunction("getString", &TestClass::getString)); + state["defargfn"] = kaguya::overload(defargfn_wrapper(), defargfn2_wrapper()); - state.dostring("test = TestClass.new()"); + state.dostring("test = TestClass.new()"); - state.dostring("test:defargfn(6) assert(test:getInt() == 12)"); - state.dostring("test:defargfn(6,5) assert(test:getInt() == 30)"); - state.dostring("test:defargfn(2,2,2) assert(test:getInt() == 8)"); + state.dostring("test:defargfn(6) assert(test:getInt() == 12)"); + state.dostring("test:defargfn(6,5) assert(test:getInt() == 30)"); + state.dostring("test:defargfn(2,2,2) assert(test:getInt() == 8)"); - state.dostring("test:defargfn('a') assert(test:getString() == 'abc')"); - state.dostring("test:defargfn('a','a') assert(test:getString() == 'aac')"); - state.dostring("test:defargfn('a','a','a') assert(test:getString() == 'aaa')"); + state.dostring("test:defargfn('a') assert(test:getString() == 'abc')"); + state.dostring("test:defargfn('a','a') assert(test:getString() == 'aac')"); + state.dostring( + "test:defargfn('a','a','a') assert(test:getString() == 'aaa')"); } -std::string defargfn3(const std::string& a, const std::string& b = "b", const std::string& c = "c") -{ - return a + b + c; +std::string defargfn3(const std::string &a, const std::string &b = "b", + const std::string &c = "c") { + return a + b + c; } KAGUYA_FUNCTION_OVERLOADS(defargfn3_wrapper, defargfn3, 1, 3) -KAGUYA_TEST_FUNCTION_DEF(defaultarguments_const_reference)(kaguya::State& state) -{ - state["defargfn"] = kaguya::function(defargfn3_wrapper()); - - state.dostring("assert(defargfn('a') == 'abc')"); - state.dostring("assert(defargfn('a','b') == 'abc')"); - state.dostring("assert(defargfn('a','b','c') == 'abc')"); - state.dostring("assert(defargfn('d','e','f') == 'def')"); -} +KAGUYA_TEST_FUNCTION_DEF(defaultarguments_const_reference) +(kaguya::State &state) { + state["defargfn"] = kaguya::function(defargfn3_wrapper()); + state.dostring("assert(defargfn('a') == 'abc')"); + state.dostring("assert(defargfn('a','b') == 'abc')"); + state.dostring("assert(defargfn('a','b','c') == 'abc')"); + state.dostring("assert(defargfn('d','e','f') == 'def')"); +} -std::string defargfn4(const std::string& a, const char* b = "b", const char* c = "c") -{ - return a + b + c; +std::string defargfn4(const std::string &a, const char *b = "b", + const char *c = "c") { + return a + b + c; } KAGUYA_FUNCTION_OVERLOADS(defargfn4_wrapper, defargfn4, 1, 3) -KAGUYA_TEST_FUNCTION_DEF(defaultarguments_const_char)(kaguya::State& state) -{ - state["defargfn"] = kaguya::function(defargfn4_wrapper()); +KAGUYA_TEST_FUNCTION_DEF(defaultarguments_const_char)(kaguya::State &state) { + state["defargfn"] = kaguya::function(defargfn4_wrapper()); - state.dostring("assert(defargfn('a') == 'abc')"); - state.dostring("assert(defargfn('a','b') == 'abc')"); - state.dostring("assert(defargfn('a','b','c') == 'abc')"); - state.dostring("assert(defargfn('d','e','f') == 'def')"); + state.dostring("assert(defargfn('a') == 'abc')"); + state.dostring("assert(defargfn('a','b') == 'abc')"); + state.dostring("assert(defargfn('a','b','c') == 'abc')"); + state.dostring("assert(defargfn('d','e','f') == 'def')"); } +kaguya::TableData ret_table() { + using namespace kaguya; + kaguya::TableData ret; -kaguya::TableData ret_table() -{ - using namespace kaguya; - kaguya::TableData ret; + ret.elements.push_back(TableDataElement("data", "value")); + ret.elements.push_back(TableDataElement("num", 32)); - ret.elements.push_back(TableDataElement("data", "value")); - ret.elements.push_back(TableDataElement("num", 32)); - - return ret; + return ret; } -kaguya::LuaCodeChunkResult ret_from_luacode() -{ - return kaguya::LuaCodeChunkResult("return 1"); +kaguya::LuaCodeChunkResult ret_from_luacode() { + return kaguya::LuaCodeChunkResult("return 1"); } -KAGUYA_TEST_FUNCTION_DEF(return_value_type)(kaguya::State& state) -{ - state["ret_table"] = &ret_table; - state("assert(ret_table().data == 'value')"); - state("assert(ret_table().num == 32)"); +KAGUYA_TEST_FUNCTION_DEF(return_value_type)(kaguya::State &state) { + state["ret_table"] = &ret_table; + state("assert(ret_table().data == 'value')"); + state("assert(ret_table().num == 32)"); - state["ret_from_luacode"] = &ret_from_luacode; - state("assert(ret_from_luacode() == 1)"); + state["ret_from_luacode"] = &ret_from_luacode; + state("assert(ret_from_luacode() == 1)"); } - -void two_string_fn(std::string a, std::string b) -{ - TEST_EQUAL(a, "test1"); - TEST_EQUAL(b, "test2"); +void two_string_fn(std::string a, std::string b) { + TEST_EQUAL(a, "test1"); + TEST_EQUAL(b, "test2"); } -void two_cr_string_fn(const std::string& a, const std::string& b) -{ - TEST_EQUAL(a, "test1"); - TEST_EQUAL(b, "test2"); +void two_cr_string_fn(const std::string &a, const std::string &b) { + TEST_EQUAL(a, "test1"); + TEST_EQUAL(b, "test2"); } -KAGUYA_TEST_FUNCTION_DEF(none_to_string)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - state["two_string_fn"] = kaguya::function(two_string_fn); - state["two_cr_string_fn"] = kaguya::function(two_cr_string_fn); +KAGUYA_TEST_FUNCTION_DEF(none_to_string)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + state["two_string_fn"] = kaguya::function(two_string_fn); + state["two_cr_string_fn"] = kaguya::function(two_cr_string_fn); - last_error_message = ""; - TEST_CHECK(state.dostring("two_string_fn('test1','test2')")); - TEST_CHECK(last_error_message == ""); + last_error_message = ""; + TEST_CHECK(state.dostring("two_string_fn('test1','test2')")); + TEST_CHECK(last_error_message == ""); - last_error_message = ""; - TEST_CHECK(!state.dostring("two_string_fn('error_test')")); - TEST_CHECK(last_error_message != ""); + last_error_message = ""; + TEST_CHECK(!state.dostring("two_string_fn('error_test')")); + TEST_CHECK(last_error_message != ""); - last_error_message = ""; - TEST_CHECK(state.dostring("two_cr_string_fn('test1','test2')")); - TEST_CHECK(last_error_message == ""); + last_error_message = ""; + TEST_CHECK(state.dostring("two_cr_string_fn('test1','test2')")); + TEST_CHECK(last_error_message == ""); - last_error_message = ""; - TEST_CHECK(!state.dostring("two_cr_string_fn('error_test')")); - TEST_CHECK(last_error_message != ""); + last_error_message = ""; + TEST_CHECK(!state.dostring("two_cr_string_fn('error_test')")); + TEST_CHECK(last_error_message != ""); } KAGUYA_TEST_GROUP_END(test_03_function) diff --git a/test/test_04_lua_function.cpp b/test/test_04_lua_function.cpp index 3871622..b19beff 100644 --- a/test/test_04_lua_function.cpp +++ b/test/test_04_lua_function.cpp @@ -1,573 +1,548 @@ #include "test_util.hpp" #include "kaguya/kaguya.hpp" - KAGUYA_TEST_GROUP_START(test_04_lua_function) using namespace kaguya_test_util; std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; } -KAGUYA_TEST_FUNCTION_DEF(function_call)(kaguya::State& state) -{ - state("testfun = function(a,b,c,d,e) assert(a == 1,a) assert(b == 2,b) assert(c == 4,c) assert(d == 8,d) assert(e == 16,e) end"); - state["testfun"](1,2,4,8,16); - state("testfun2 = function() return 3232 end"); +KAGUYA_TEST_FUNCTION_DEF(function_call)(kaguya::State &state) { + state("testfun = function(a,b,c,d,e) assert(a == 1,a) assert(b == 2,b) " + "assert(c == 4,c) assert(d == 8,d) assert(e == 16,e) end"); + state["testfun"](1, 2, 4, 8, 16); + state("testfun2 = function() return 3232 end"); - TEST_EQUAL(state["testfun2"](), 3232); - state("testfun3 = function() return 'text' end"); - TEST_EQUAL(state["testfun3"](), "text"); + TEST_EQUAL(state["testfun2"](), 3232); + state("testfun3 = function() return 'text' end"); + TEST_EQUAL(state["testfun3"](), "text"); } -KAGUYA_TEST_FUNCTION_DEF(multi_return_function_test)(kaguya::State& state) -{ - state("multresfun =function() return 1,2,4,8,16 end"); - int a, b, c, d, e; - a = b = c = d = e = 0; - kaguya::tie(a, b, c, d, e) = state["multresfun"](); - TEST_EQUAL(a, 1); - TEST_EQUAL(b, 2); - TEST_EQUAL(c, 4); - TEST_EQUAL(d, 8); - TEST_EQUAL(e, 16); - - a = b = c = d = e = 0; - kaguya::tie(a, b, c, d, e) = state["multresfun"].call >(); - TEST_EQUAL(a, 1); - TEST_EQUAL(b, 2); - TEST_EQUAL(c, 4); - TEST_EQUAL(d, 8); - TEST_EQUAL(e, 16); - - using kaguya::standard::get; - kaguya::standard::tuple tuple_res = state["multresfun"].call >(); - TEST_EQUAL(get<0>(tuple_res), 1); - TEST_EQUAL(get<1>(tuple_res), 2); - TEST_EQUAL(get<2>(tuple_res), 4); - TEST_EQUAL(get<3>(tuple_res), 8); - TEST_EQUAL(get<4>(tuple_res), 16); - - state("multireturn_pass_through_to_arg = function(a,b,c,d,e) assert(a == 1,a) assert(b == 2,b) assert(c == 4,c) assert(d == 8,d) assert(e == 16,e) end"); - state["multireturn_pass_through_to_arg"](state["multresfun"].call >()); - state["multireturn_pass_through_to_arg"](state["multresfun"]()); +KAGUYA_TEST_FUNCTION_DEF(multi_return_function_test)(kaguya::State &state) { + state("multresfun =function() return 1,2,4,8,16 end"); + int a, b, c, d, e; + a = b = c = d = e = 0; + kaguya::tie(a, b, c, d, e) = state["multresfun"](); + TEST_EQUAL(a, 1); + TEST_EQUAL(b, 2); + TEST_EQUAL(c, 4); + TEST_EQUAL(d, 8); + TEST_EQUAL(e, 16); + + a = b = c = d = e = 0; + kaguya::tie(a, b, c, d, e) = + state["multresfun"] + .call >(); + TEST_EQUAL(a, 1); + TEST_EQUAL(b, 2); + TEST_EQUAL(c, 4); + TEST_EQUAL(d, 8); + TEST_EQUAL(e, 16); + + using kaguya::standard::get; + kaguya::standard::tuple tuple_res = + state["multresfun"] + .call >(); + TEST_EQUAL(get<0>(tuple_res), 1); + TEST_EQUAL(get<1>(tuple_res), 2); + TEST_EQUAL(get<2>(tuple_res), 4); + TEST_EQUAL(get<3>(tuple_res), 8); + TEST_EQUAL(get<4>(tuple_res), 16); + + state("multireturn_pass_through_to_arg = function(a,b,c,d,e) assert(a == " + "1,a) assert(b == 2,b) assert(c == 4,c) assert(d == 8,d) assert(e == " + "16,e) end"); + state["multireturn_pass_through_to_arg"]( + state["multresfun"] + .call >()); + state["multireturn_pass_through_to_arg"](state["multresfun"]()); } - -KAGUYA_TEST_FUNCTION_DEF(coroutine)(kaguya::State& state) -{ - { - TEST_CHECK(state("cor = coroutine.create( function()" - "coroutine.yield(32) " - "coroutine.yield(53) " - "return 2 " - " end)")); - - kaguya::LuaRef cor = state["cor"]; - int r1 = cor(); - int r2 = cor(); - int r3 = cor(); - - TEST_EQUAL(r1, 32); - TEST_EQUAL(r2, 53); - TEST_EQUAL(r3, 2); - - TEST_CHECK(state("cor3 = coroutine.create( function(arg)" - "coroutine.yield(arg) " - "coroutine.yield(arg*2) " - "coroutine.yield(arg*3) " - "return arg*4 " - " end)")); - - kaguya::LuaThread cor3 = state["cor3"]; - std::vector results; - while (!cor3.isThreadDead()) - { - results.push_back(cor3(3)); - } - - TEST_EQUAL(cor3.costatus(cor3), kaguya::COSTAT_RUNNING); - TEST_EQUAL(results.size(), 4); - TEST_EQUAL(results[0], 3); - TEST_EQUAL(results[1], 6); - TEST_EQUAL(results[2], 9); - TEST_EQUAL(results[3], 12); - } - { - kaguya::LuaThread cor2 = state.newRef(kaguya::NewThread()); - TEST_CHECK(state("corfun = function(arg)" - "coroutine.yield(arg) " - "coroutine.yield(arg*2) " - "coroutine.yield(arg*3) " - "return arg*4 " - " end")); - - kaguya::LuaFunction corfun = state["corfun"]; - int r1 = cor2(corfun, 3); - int r2 = cor2.resume(); - int r3 = cor2.resume(); - int r4 = cor2.resume(); - - TEST_EQUAL(r1, 3); - TEST_EQUAL(r2, 6); - TEST_EQUAL(r3, 9); - TEST_EQUAL(r4, 12); - - - cor2.resume(corfun, 3); - } - { - - state["cor2"] = kaguya::NewThread(); - kaguya::LuaRef cor2 = state["cor2"]; - TEST_CHECK(state("corfun = function(arg)" - "for i = 1,arg do " - "coroutine.yield() " - "end " - "end")); - kaguya::LuaRef corfun = state["corfun"]; - cor2(corfun, 10); - int yieldnum = 0; - while (cor2.threadStatus() == LUA_YIELD) - { - cor2(); - yieldnum++; - } - - - TEST_EQUAL(yieldnum, 10); - } +KAGUYA_TEST_FUNCTION_DEF(coroutine)(kaguya::State &state) { + { + TEST_CHECK(state("cor = coroutine.create( function()" + "coroutine.yield(32) " + "coroutine.yield(53) " + "return 2 " + " end)")); + + kaguya::LuaRef cor = state["cor"]; + int r1 = cor(); + int r2 = cor(); + int r3 = cor(); + + TEST_EQUAL(r1, 32); + TEST_EQUAL(r2, 53); + TEST_EQUAL(r3, 2); + + TEST_CHECK(state("cor3 = coroutine.create( function(arg)" + "coroutine.yield(arg) " + "coroutine.yield(arg*2) " + "coroutine.yield(arg*3) " + "return arg*4 " + " end)")); + + kaguya::LuaThread cor3 = state["cor3"]; + std::vector results; + while (!cor3.isThreadDead()) { + results.push_back(cor3(3)); + } + + TEST_EQUAL(cor3.costatus(cor3), kaguya::COSTAT_RUNNING); + TEST_EQUAL(results.size(), 4); + TEST_EQUAL(results[0], 3); + TEST_EQUAL(results[1], 6); + TEST_EQUAL(results[2], 9); + TEST_EQUAL(results[3], 12); + } + { + kaguya::LuaThread cor2 = state.newRef(kaguya::NewThread()); + TEST_CHECK(state("corfun = function(arg)" + "coroutine.yield(arg) " + "coroutine.yield(arg*2) " + "coroutine.yield(arg*3) " + "return arg*4 " + " end")); + + kaguya::LuaFunction corfun = state["corfun"]; + int r1 = cor2(corfun, 3); + int r2 = cor2.resume(); + int r3 = cor2.resume(); + int r4 = cor2.resume(); + + TEST_EQUAL(r1, 3); + TEST_EQUAL(r2, 6); + TEST_EQUAL(r3, 9); + TEST_EQUAL(r4, 12); + + cor2.resume(corfun, 3); + } + { + + state["cor2"] = kaguya::NewThread(); + kaguya::LuaRef cor2 = state["cor2"]; + TEST_CHECK(state("corfun = function(arg)" + "for i = 1,arg do " + "coroutine.yield() " + "end " + "end")); + kaguya::LuaRef corfun = state["corfun"]; + cor2(corfun, 10); + int yieldnum = 0; + while (cor2.threadStatus() == LUA_YIELD) { + cor2(); + yieldnum++; + } + + TEST_EQUAL(yieldnum, 10); + } } -KAGUYA_TEST_FUNCTION_DEF(coroutine_yield_return)(kaguya::State& state) -{ - { - kaguya::LuaThread cor2 = state.newRef(kaguya::NewThread()); - TEST_CHECK(state("corfun = function(arg)" - "local r = coroutine.yield(arg) " - "r = coroutine.yield(r) " - "r = coroutine.yield(r) " - "return r " - " end")); - - kaguya::LuaFunction corfun = state["corfun"]; - int r1 = cor2(corfun, 3); - int r2 = cor2.resume(4); - int r3 = cor2.resume(5); - int r4 = cor2.resume(6); - - TEST_EQUAL(r1, 3); - TEST_EQUAL(r2, 4); - TEST_EQUAL(r3, 5); - TEST_EQUAL(r4, 6); - } +KAGUYA_TEST_FUNCTION_DEF(coroutine_yield_return)(kaguya::State &state) { + { + kaguya::LuaThread cor2 = state.newRef(kaguya::NewThread()); + TEST_CHECK(state("corfun = function(arg)" + "local r = coroutine.yield(arg) " + "r = coroutine.yield(r) " + "r = coroutine.yield(r) " + "return r " + " end")); + + kaguya::LuaFunction corfun = state["corfun"]; + int r1 = cor2(corfun, 3); + int r2 = cor2.resume(4); + int r3 = cor2.resume(5); + int r4 = cor2.resume(6); + + TEST_EQUAL(r1, 3); + TEST_EQUAL(r2, 4); + TEST_EQUAL(r3, 5); + TEST_EQUAL(r4, 6); + } } -KAGUYA_TEST_FUNCTION_DEF(coroutine_dead)(kaguya::State& state) -{ - kaguya::LuaThread emptycoroutine; - TEST_CHECK(emptycoroutine.isThreadDead()); +KAGUYA_TEST_FUNCTION_DEF(coroutine_dead)(kaguya::State &state) { + kaguya::LuaThread emptycoroutine; + TEST_CHECK(emptycoroutine.isThreadDead()); - TEST_CHECK(state("corfun = function(arg)" - "return 1 " - " end")); - kaguya::LuaThread cor = state.newThread(state["corfun"]); + TEST_CHECK(state("corfun = function(arg)" + "return 1 " + " end")); + kaguya::LuaThread cor = state.newThread(state["corfun"]); - TEST_CHECK(!cor.isThreadDead()); - cor(); - TEST_CHECK(cor.isThreadDead()); + TEST_CHECK(!cor.isThreadDead()); + cor(); + TEST_CHECK(cor.isThreadDead()); } -void corresult_to_main(kaguya::VariadicArgType args) -{ - TEST_EQUAL(args.size(), 9); - TEST_EQUAL(args[0], 1); - TEST_EQUAL(args[1], 2); - TEST_EQUAL(args[2], 3); - TEST_EQUAL(args[3], 4); - TEST_EQUAL(args[4], 5); - TEST_EQUAL(args[5], 6); - TEST_EQUAL(args[6], 7); - TEST_EQUAL(args[7], 8); - TEST_EQUAL(args[8], 9); - int s = std::distance(args.begin(), args.end()); - TEST_EQUAL(s, 9); - - //iterator requirements test - //Forward iterator - kaguya::VariadicArgType::iterator it;//default constructible - it = args.begin();//copy -assignable - kaguya::VariadicArgType::iterator it2 = it;//copy-constructible - kaguya::VariadicArgType::iterator empty_it; - TEST_CHECK(it2 == it);//compare - TEST_CHECK(empty_it != it);//compare - TEST_EQUAL(it->get(), 1)//dereferenced - TEST_EQUAL((*it).get(), 1)//dereferenced - TEST_EQUAL(*it++, 1);//incremented - TEST_EQUAL(*(++it), 3);//incremented - it++; - TEST_EQUAL(*it, 4);//incremented - - //Bidirectional iterator - it--; - TEST_EQUAL(*it--, 3);//decremented - TEST_EQUAL(*(--it), 1);//decremented - - //Random access iterator - it = args.begin(); - - TEST_EQUAL(*(it += 5),6);//compound assignment operations - - TEST_EQUAL(*it, 6); - TEST_EQUAL(*(it - 5), 1); - TEST_EQUAL(*(it - 3), 3); - - TEST_EQUAL(*(it -= 5), 1);//compound assignment operations - - TEST_EQUAL(*it, 1); - TEST_EQUAL(*(it + 5), 6); - TEST_EQUAL(*(it + 3), 4); - TEST_EQUAL(*(5+it), 6); - TEST_CHECK(!((5 + it) < (4 + it))); - TEST_CHECK(!((5 + it) < (5 + it))); - TEST_CHECK(((5 + it) < (6 + it))); - TEST_CHECK(((5 + it) > (4 + it))); - TEST_CHECK(!((5 + it) > (5 + it))); - TEST_CHECK(!((5 + it) > (6 + it))); - TEST_CHECK(!((5 + it) <= (4 + it))); - TEST_CHECK(((5 + it) <= (5 + it))); - TEST_CHECK(((5 + it) <= (6 + it))); - TEST_CHECK(((5 + it) >= (4 + it))); - TEST_CHECK(((5 + it) >= (5 + it))); - TEST_CHECK(!((5 + it) >= (6 + it))); - TEST_CHECK(!((5 + it) <= (4 + it))); - TEST_CHECK(((5 + it) <= (5 + it))); - TEST_CHECK(((5 + it) <= (6 + it))); - - TEST_EQUAL(it[0], 1);//offset dereference operator - TEST_EQUAL(it[6], 7);//offset dereference operator - it += 5; - TEST_EQUAL(it[0], 6);//offset dereference operator - TEST_EQUAL(it[-3], 3);//offset dereference operator - - it = args.begin(); - //use std::advance - std::advance(it,5); - TEST_EQUAL(*it, 6); - std::advance(it, -2); - TEST_EQUAL(*it, 4); +void corresult_to_main(kaguya::VariadicArgType args) { + TEST_EQUAL(args.size(), 9); + TEST_EQUAL(args[0], 1); + TEST_EQUAL(args[1], 2); + TEST_EQUAL(args[2], 3); + TEST_EQUAL(args[3], 4); + TEST_EQUAL(args[4], 5); + TEST_EQUAL(args[5], 6); + TEST_EQUAL(args[6], 7); + TEST_EQUAL(args[7], 8); + TEST_EQUAL(args[8], 9); + int s = std::distance(args.begin(), args.end()); + TEST_EQUAL(s, 9); + + // iterator requirements test + // Forward iterator + kaguya::VariadicArgType::iterator it; // default constructible + it = args.begin(); // copy -assignable + kaguya::VariadicArgType::iterator it2 = it; // copy-constructible + kaguya::VariadicArgType::iterator empty_it; + TEST_CHECK(it2 == it); // compare + TEST_CHECK(empty_it != it); // compare + TEST_EQUAL(it->get(), 1) // dereferenced + TEST_EQUAL((*it).get(), 1) // dereferenced + TEST_EQUAL(*it++, 1); // incremented + TEST_EQUAL(*(++it), 3); // incremented + it++; + TEST_EQUAL(*it, 4); // incremented + + // Bidirectional iterator + it--; + TEST_EQUAL(*it--, 3); // decremented + TEST_EQUAL(*(--it), 1); // decremented + + // Random access iterator + it = args.begin(); + + TEST_EQUAL(*(it += 5), 6); // compound assignment operations + + TEST_EQUAL(*it, 6); + TEST_EQUAL(*(it - 5), 1); + TEST_EQUAL(*(it - 3), 3); + + TEST_EQUAL(*(it -= 5), 1); // compound assignment operations + + TEST_EQUAL(*it, 1); + TEST_EQUAL(*(it + 5), 6); + TEST_EQUAL(*(it + 3), 4); + TEST_EQUAL(*(5 + it), 6); + TEST_CHECK(!((5 + it) < (4 + it))); + TEST_CHECK(!((5 + it) < (5 + it))); + TEST_CHECK(((5 + it) < (6 + it))); + TEST_CHECK(((5 + it) > (4 + it))); + TEST_CHECK(!((5 + it) > (5 + it))); + TEST_CHECK(!((5 + it) > (6 + it))); + TEST_CHECK(!((5 + it) <= (4 + it))); + TEST_CHECK(((5 + it) <= (5 + it))); + TEST_CHECK(((5 + it) <= (6 + it))); + TEST_CHECK(((5 + it) >= (4 + it))); + TEST_CHECK(((5 + it) >= (5 + it))); + TEST_CHECK(!((5 + it) >= (6 + it))); + TEST_CHECK(!((5 + it) <= (4 + it))); + TEST_CHECK(((5 + it) <= (5 + it))); + TEST_CHECK(((5 + it) <= (6 + it))); + + TEST_EQUAL(it[0], 1); // offset dereference operator + TEST_EQUAL(it[6], 7); // offset dereference operator + it += 5; + TEST_EQUAL(it[0], 6); // offset dereference operator + TEST_EQUAL(it[-3], 3); // offset dereference operator + + it = args.begin(); + // use std::advance + std::advance(it, 5); + TEST_EQUAL(*it, 6); + std::advance(it, -2); + TEST_EQUAL(*it, 4); } -void corresult_to_main2(kaguya::VariadicArgType args) -{ - TEST_EQUAL(args.size(), 1); - TEST_EQUAL(args[0], 6); - int s = std::distance(args.begin(), args.end()); - TEST_EQUAL(s,1); +void corresult_to_main2(kaguya::VariadicArgType args) { + TEST_EQUAL(args.size(), 1); + TEST_EQUAL(args[0], 6); + int s = std::distance(args.begin(), args.end()); + TEST_EQUAL(s, 1); } -void corresult_to_main3(kaguya::VariadicArgType args) -{ - TEST_EQUAL(args.size(), 0); - int s = std::distance(args.begin(), args.end()); - TEST_EQUAL(s, 0); +void corresult_to_main3(kaguya::VariadicArgType args) { + TEST_EQUAL(args.size(), 0); + int s = std::distance(args.begin(), args.end()); + TEST_EQUAL(s, 0); } +int coroutine_exec(kaguya::LuaThread cor) { return cor.resume() * 2; } -int coroutine_exec(kaguya::LuaThread cor) -{ - return cor.resume() * 2; -} +KAGUYA_TEST_FUNCTION_DEF(coroutine_on_the_coroutine)(kaguya::State &state) { + TEST_CHECK(state("cor1 = coroutine.create( function()" + "coroutine.yield(32) " + "coroutine.yield(53) " + "return 2 " + " end)")); + + state["coroutine_exec"] = &coroutine_exec; + + TEST_CHECK(state("cor2 = coroutine.wrap( function()" + "coroutine.yield(coroutine_exec(cor1)) " + "coroutine.yield(coroutine_exec(cor1)) " + "return 4 " + " end)")); + + kaguya::LuaRef cor = state["cor2"]; + int r1 = cor(); + int r2 = cor(); + int r3 = cor(); + + TEST_EQUAL(r1, 32 * 2); + TEST_EQUAL(r2, 53 * 2); + TEST_EQUAL(r3, 4); -KAGUYA_TEST_FUNCTION_DEF(coroutine_on_the_coroutine)(kaguya::State& state) -{ - TEST_CHECK(state("cor1 = coroutine.create( function()" - "coroutine.yield(32) " - "coroutine.yield(53) " - "return 2 " - " end)")); - - state["coroutine_exec"] = &coroutine_exec; - - TEST_CHECK(state("cor2 = coroutine.wrap( function()" - "coroutine.yield(coroutine_exec(cor1)) " - "coroutine.yield(coroutine_exec(cor1)) " - "return 4 " - " end)")); - - kaguya::LuaRef cor = state["cor2"]; - int r1 = cor(); - int r2 = cor(); - int r3 = cor(); - - TEST_EQUAL(r1, 32*2); - TEST_EQUAL(r2, 53*2); - TEST_EQUAL(r3, 4); - - kaguya::VariadicArgType vargtest(state.state(),5); - TEST_EQUAL(vargtest.size(), 0); + kaguya::VariadicArgType vargtest(state.state(), 5); + TEST_EQUAL(vargtest.size(), 0); } -int function_exec(kaguya::LuaFunction f, kaguya::LuaStackRef v) -{ - return f.call(v) *2; +int function_exec(kaguya::LuaFunction f, kaguya::LuaStackRef v) { + return f.call(v) * 2; } -KAGUYA_TEST_FUNCTION_DEF(function_on_the_coroutine)(kaguya::State& state) -{ - TEST_CHECK(state("fn = function(a) return a end")); +KAGUYA_TEST_FUNCTION_DEF(function_on_the_coroutine)(kaguya::State &state) { + TEST_CHECK(state("fn = function(a) return a end")); - state["function_exec"] = &function_exec; + state["function_exec"] = &function_exec; - TEST_CHECK(state("cor2 = coroutine.wrap( function()" - "coroutine.yield(function_exec(fn,3)) " - "coroutine.yield(function_exec(fn,4)) " - "return 4 " - " end)")); + TEST_CHECK(state("cor2 = coroutine.wrap( function()" + "coroutine.yield(function_exec(fn,3)) " + "coroutine.yield(function_exec(fn,4)) " + "return 4 " + " end)")); - kaguya::LuaRef cor = state["cor2"]; - int r1 = cor(); - int r2 = cor(); - int r3 = cor(); + kaguya::LuaRef cor = state["cor2"]; + int r1 = cor(); + int r2 = cor(); + int r3 = cor(); - TEST_EQUAL(r1, 3 *2); - TEST_EQUAL(r2, 4 *2); - TEST_EQUAL(r3, 4); + TEST_EQUAL(r1, 3 * 2); + TEST_EQUAL(r2, 4 * 2); + TEST_EQUAL(r3, 4); - kaguya::VariadicArgType vargtest(state.state(), 5); - TEST_EQUAL(vargtest.size(), 0); + kaguya::VariadicArgType vargtest(state.state(), 5); + TEST_EQUAL(vargtest.size(), 0); - TEST_CHECK(cor.typeTest()); - TEST_CHECK(cor.weakTypeTest()); + TEST_CHECK(cor.typeTest()); + TEST_CHECK(cor.weakTypeTest()); } -KAGUYA_TEST_FUNCTION_DEF(move_stack)(kaguya::State& state) -{ - state.pushToStack(1); - kaguya::LuaStackRef ref1(state.state(),-1); - TEST_EQUAL(ref1, 1); - state.pushToStack(2); - kaguya::LuaStackRef ref2(state.state(), -1); - TEST_EQUAL(ref2, 2); - TEST_EQUAL(ref1, 1); - - kaguya::LuaThread cor = state.newThread(); - - TEST_EQUAL(ref1, 1); - ref1.pushStackIndex(cor); - kaguya::LuaStackRef coref1(cor, -1); - TEST_EQUAL(coref1, 1); - ref2.pushStackIndex(cor); - kaguya::LuaStackRef coref2(cor, -1); - TEST_EQUAL(coref2, 2); - - state.popFromStack(); - state.popFromStack(); +KAGUYA_TEST_FUNCTION_DEF(move_stack)(kaguya::State &state) { + state.pushToStack(1); + kaguya::LuaStackRef ref1(state.state(), -1); + TEST_EQUAL(ref1, 1); + state.pushToStack(2); + kaguya::LuaStackRef ref2(state.state(), -1); + TEST_EQUAL(ref2, 2); + TEST_EQUAL(ref1, 1); + + kaguya::LuaThread cor = state.newThread(); + + TEST_EQUAL(ref1, 1); + ref1.pushStackIndex(cor); + kaguya::LuaStackRef coref1(cor, -1); + TEST_EQUAL(coref1, 1); + ref2.pushStackIndex(cor); + kaguya::LuaStackRef coref2(cor, -1); + TEST_EQUAL(coref2, 2); + + state.popFromStack(); + state.popFromStack(); } -KAGUYA_TEST_FUNCTION_DEF(coroutine_stack)(kaguya::State& state) -{ - state["corresult_to_main"] = &corresult_to_main; - state["cor2"] = kaguya::NewThread(); - kaguya::LuaRef cor2 = state["cor2"]; - TEST_CHECK(state("corfun = function(arg)" - "for i = 1,arg do " - "coroutine.yield(1,2,3,4,5,6,7,8,9) " - "end " - "end")); - state["corresult_to_main"](cor2(state["corfun"], 10)); - - - state["corresult_to_main2"] = &corresult_to_main2; - state["corresult_to_main2"](cor2(state["corfun"], 10).result_at(5)); - - state["corresult_to_main3"] = &corresult_to_main3; - state["corresult_to_main3"](); - - TEST_CHECK(state("corfun = function(arg)" - "for i = 1,arg do " - "coroutine.yield({value=323}) " - "end " - "end")); - - - state["cor3"] = kaguya::NewThread(); - state["value"] = state["cor3"](state["corfun"], 10).getField("value"); - TEST_EQUAL(state["value"], 323); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 323)")); - TEST_EQUAL(state["value"], state["cor3"](state["corfun"], 10).getField("value")); +KAGUYA_TEST_FUNCTION_DEF(coroutine_stack)(kaguya::State &state) { + state["corresult_to_main"] = &corresult_to_main; + state["cor2"] = kaguya::NewThread(); + kaguya::LuaRef cor2 = state["cor2"]; + TEST_CHECK(state("corfun = function(arg)" + "for i = 1,arg do " + "coroutine.yield(1,2,3,4,5,6,7,8,9) " + "end " + "end")); + state["corresult_to_main"](cor2(state["corfun"], 10)); + + state["corresult_to_main2"] = &corresult_to_main2; + state["corresult_to_main2"](cor2(state["corfun"], 10).result_at(5)); + + state["corresult_to_main3"] = &corresult_to_main3; + state["corresult_to_main3"](); + + TEST_CHECK(state("corfun = function(arg)" + "for i = 1,arg do " + "coroutine.yield({value=323}) " + "end " + "end")); + + state["cor3"] = kaguya::NewThread(); + state["value"] = state["cor3"](state["corfun"], 10).getField("value"); + TEST_EQUAL(state["value"], 323); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 323)")); + TEST_EQUAL(state["value"], + state["cor3"](state["corfun"], 10).getField("value")); } -void luacallback(const kaguya::standard::function& callback) -{ - int ret = callback(32.f); - TEST_EQUAL(ret,1); +void luacallback(const kaguya::standard::function &callback) { + int ret = callback(32.f); + TEST_EQUAL(ret, 1); } -KAGUYA_TEST_FUNCTION_DEF(bind_to_std_function)(kaguya::State& state) -{ - state["luacallback"] = &luacallback; - state("luacallback(function(v) assert(32 == v) return 1 end)"); +KAGUYA_TEST_FUNCTION_DEF(bind_to_std_function)(kaguya::State &state) { + state["luacallback"] = &luacallback; + state("luacallback(function(v) assert(32 == v) return 1 end)"); } - -KAGUYA_TEST_FUNCTION_DEF(call_error)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - { - last_error_message = ""; - kaguya::LuaFunction nilfn = state["a"]; - nilfn.call(); - TEST_CHECK(last_error_message.find("attempt to call a nil value") != std::string::npos); - } - - - { - last_error_message = ""; - kaguya::LuaFunction nilfn; - nilfn.call(); - } +KAGUYA_TEST_FUNCTION_DEF(call_error)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + { + last_error_message = ""; + kaguya::LuaFunction nilfn = state["a"]; + nilfn.call(); + TEST_CHECK(last_error_message.find("attempt to call a nil value") != + std::string::npos); + } + + { + last_error_message = ""; + kaguya::LuaFunction nilfn; + nilfn.call(); + } } -KAGUYA_TEST_FUNCTION_DEF(coroutine_error)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - { - last_error_message = ""; - kaguya::LuaFunction nilfn = state["a"]; - nilfn.call(); - TEST_CHECK(last_error_message.find("attempt to call a nil value") != std::string::npos); - } - { - - TEST_CHECK(state("corfun = function(arg)" - "assert(false) " - " end")); - kaguya::LuaThread cor = state.newThread(state["corfun"]); - - TEST_CHECK(!cor.isThreadDead()); - cor(); - TEST_CHECK(cor.isThreadDead()); - } +KAGUYA_TEST_FUNCTION_DEF(coroutine_error)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + { + last_error_message = ""; + kaguya::LuaFunction nilfn = state["a"]; + nilfn.call(); + TEST_CHECK(last_error_message.find("attempt to call a nil value") != + std::string::npos); + } + { + + TEST_CHECK(state("corfun = function(arg)" + "assert(false) " + " end")); + kaguya::LuaThread cor = state.newThread(state["corfun"]); + + TEST_CHECK(!cor.isThreadDead()); + cor(); + TEST_CHECK(cor.isThreadDead()); + } } -KAGUYA_TEST_FUNCTION_DEF(function_result_for)(kaguya::State& state) -{ - { - const kaguya::FunctionResults empty; - TEST_EQUAL(empty.result_size(), 0); - std::vector res; - for (kaguya::FunctionResults::iterator it = empty.begin(); it != empty.end(); ++it) - { - res.push_back(*it); - } - TEST_EQUAL(res.size(), 0); - } - - state("fn =function() return 1,2,4,8,16 end"); - { - std::vector res; - kaguya::LuaFunction fn = state["fn"]; - kaguya::FunctionResults result = fn(); - for (kaguya::FunctionResults::iterator it = result.begin();it != result.end();++it) - { - res.push_back(*it); - } - TEST_EQUAL(res.size(), 5); - TEST_EQUAL(res[0], 1); - TEST_EQUAL(res[1], 2); - TEST_EQUAL(res[2], 4); - TEST_EQUAL(res[3], 8); - TEST_EQUAL(res[4], 16); - } - { - std::vector res; - kaguya::LuaFunction fn = state["fn"]; - const kaguya::FunctionResults& result = fn(); - for (kaguya::FunctionResults::const_iterator it = result.begin(); it != result.end(); ++it) - { - res.push_back(*it); - } - TEST_EQUAL(res.size(), 5); - TEST_EQUAL(res[0], 1); - TEST_EQUAL(res[1], 2); - TEST_EQUAL(res[2], 4); - TEST_EQUAL(res[3], 8); - TEST_EQUAL(res[4], 16); - } - { - std::vector res; - kaguya::LuaFunction fn = state["fn"]; - kaguya::FunctionResults result = fn(); - TEST_EQUAL(result.result_size(), 5); - TEST_EQUAL(result.resultStatus(), 0); - for (kaguya::FunctionResults::const_iterator it = result.begin(); it != result.end(); ++it) - { - res.push_back(*it); - } - TEST_EQUAL(res.size(), 5); - TEST_EQUAL(res[0], 1); - TEST_EQUAL(res[1], 2); - TEST_EQUAL(res[2], 4); - TEST_EQUAL(res[3], 8); - TEST_EQUAL(res[4], 16); - } - - state("a={} b={} c={}"); - state("fn =function() return a,b,c end"); - { - kaguya::LuaFunction fn = state["fn"]; - kaguya::FunctionResults result = fn(); - for (kaguya::FunctionResults::iterator it = result.begin(); it != result.end(); ++it) - { - it->setField("value",5); - } - TEST_EQUAL(state["a"]["value"], 5); - TEST_EQUAL(state["b"]["value"], 5); - TEST_EQUAL(state["c"]["value"], 5); - for (kaguya::FunctionResults::iterator it = result.begin(); it != result.end(); ++it) - { - TEST_EQUAL(it->getField("value"), 5); - } - } +KAGUYA_TEST_FUNCTION_DEF(function_result_for)(kaguya::State &state) { + { + const kaguya::FunctionResults empty; + TEST_EQUAL(empty.result_size(), 0); + std::vector res; + for (kaguya::FunctionResults::iterator it = empty.begin(); + it != empty.end(); ++it) { + res.push_back(*it); + } + TEST_EQUAL(res.size(), 0); + } + + state("fn =function() return 1,2,4,8,16 end"); + { + std::vector res; + kaguya::LuaFunction fn = state["fn"]; + kaguya::FunctionResults result = fn(); + for (kaguya::FunctionResults::iterator it = result.begin(); + it != result.end(); ++it) { + res.push_back(*it); + } + TEST_EQUAL(res.size(), 5); + TEST_EQUAL(res[0], 1); + TEST_EQUAL(res[1], 2); + TEST_EQUAL(res[2], 4); + TEST_EQUAL(res[3], 8); + TEST_EQUAL(res[4], 16); + } + { + std::vector res; + kaguya::LuaFunction fn = state["fn"]; + const kaguya::FunctionResults &result = fn(); + for (kaguya::FunctionResults::const_iterator it = result.begin(); + it != result.end(); ++it) { + res.push_back(*it); + } + TEST_EQUAL(res.size(), 5); + TEST_EQUAL(res[0], 1); + TEST_EQUAL(res[1], 2); + TEST_EQUAL(res[2], 4); + TEST_EQUAL(res[3], 8); + TEST_EQUAL(res[4], 16); + } + { + std::vector res; + kaguya::LuaFunction fn = state["fn"]; + kaguya::FunctionResults result = fn(); + TEST_EQUAL(result.result_size(), 5); + TEST_EQUAL(result.resultStatus(), 0); + for (kaguya::FunctionResults::const_iterator it = result.begin(); + it != result.end(); ++it) { + res.push_back(*it); + } + TEST_EQUAL(res.size(), 5); + TEST_EQUAL(res[0], 1); + TEST_EQUAL(res[1], 2); + TEST_EQUAL(res[2], 4); + TEST_EQUAL(res[3], 8); + TEST_EQUAL(res[4], 16); + } + + state("a={} b={} c={}"); + state("fn =function() return a,b,c end"); + { + kaguya::LuaFunction fn = state["fn"]; + kaguya::FunctionResults result = fn(); + for (kaguya::FunctionResults::iterator it = result.begin(); + it != result.end(); ++it) { + it->setField("value", 5); + } + TEST_EQUAL(state["a"]["value"], 5); + TEST_EQUAL(state["b"]["value"], 5); + TEST_EQUAL(state["c"]["value"], 5); + for (kaguya::FunctionResults::iterator it = result.begin(); + it != result.end(); ++it) { + TEST_EQUAL(it->getField("value"), 5); + } + } } +KAGUYA_TEST_FUNCTION_DEF(to_standard_function)(kaguya::State &state) { + state("testfun = function() return 3232 end"); + kaguya::LuaRef testfunref = state["testfun"]; -KAGUYA_TEST_FUNCTION_DEF(to_standard_function)(kaguya::State& state) -{ - state("testfun = function() return 3232 end"); - kaguya::LuaRef testfunref = state["testfun"]; + TEST_CHECK(testfunref); + TEST_CHECK(testfunref.typeTest >()); + TEST_CHECK(testfunref.weakTypeTest >()); + kaguya::standard::function testfun; - TEST_CHECK(testfunref); - TEST_CHECK(testfunref.typeTest >()); - TEST_CHECK(testfunref.weakTypeTest >()); - kaguya::standard::function testfun; + testfun = kaguya::LuaRef().get >(); + TEST_CHECK(!testfun); - testfun = kaguya::LuaRef().get >(); - TEST_CHECK(!testfun); - - testfun = testfunref.get >(); - TEST_EQUAL(testfun(), 3232); - state("testfun3 = function() return 'text' end"); - TEST_EQUAL(state["testfun3"](), "text"); + testfun = testfunref.get >(); + TEST_EQUAL(testfun(), 3232); + state("testfun3 = function() return 'text' end"); + TEST_EQUAL(state["testfun3"](), "text"); } - -KAGUYA_TEST_FUNCTION_DEF(return_luastackref)(kaguya::State& state) -{ - state("testfun = function() return 3232 end"); - kaguya::LuaRef testfunref = state["testfun"]; - - { - kaguya::LuaStackRef ret = testfunref.call(); - TEST_EQUAL(ret, 3232); - } - { - kaguya::LuaStackRef ret = testfunref(); - TEST_EQUAL(ret, 3232); - } +KAGUYA_TEST_FUNCTION_DEF(return_luastackref)(kaguya::State &state) { + state("testfun = function() return 3232 end"); + kaguya::LuaRef testfunref = state["testfun"]; + + { + kaguya::LuaStackRef ret = testfunref.call(); + TEST_EQUAL(ret, 3232); + } + { + kaguya::LuaStackRef ret = testfunref(); + TEST_EQUAL(ret, 3232); + } } KAGUYA_TEST_GROUP_END(test_04_lua_function) diff --git a/test/test_05_lua_ref.cpp b/test/test_05_lua_ref.cpp index 2fc225f..dcfc9ae 100644 --- a/test/test_05_lua_ref.cpp +++ b/test/test_05_lua_ref.cpp @@ -1,717 +1,661 @@ #include "kaguya/kaguya.hpp" #include "test_util.hpp" - KAGUYA_TEST_GROUP_START(test_05_lua_ref) using namespace kaguya_test_util; std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; } +KAGUYA_TEST_FUNCTION_DEF(access)(kaguya::State &state) { + kaguya::LuaRef ref(state.state(), "abc"); + TEST_EQUAL(ref.get(), "abc"); + ref = ref; -KAGUYA_TEST_FUNCTION_DEF(access)(kaguya::State& state) -{ - kaguya::LuaRef ref(state.state(), "abc"); - TEST_EQUAL(ref.get(), "abc"); - ref = ref; - - state("abc={d =1,e=3,f=64,g='sss'}"); - kaguya::LuaRef abctable = state["abc"]; - - TEST_EQUAL(abctable["d"], 1); - TEST_EQUAL(abctable["e"], 3); - TEST_EQUAL(abctable["f"], 64); - TEST_EQUAL(abctable["g"], std::string("sss")); + state("abc={d =1,e=3,f=64,g='sss'}"); + kaguya::LuaRef abctable = state["abc"]; - typedef std::map maptype; - const maptype& map = abctable.map(); - TEST_CHECK(map.size() == 4); + TEST_EQUAL(abctable["d"], 1); + TEST_EQUAL(abctable["e"], 3); + TEST_EQUAL(abctable["f"], 64); + TEST_EQUAL(abctable["g"], std::string("sss")); - std::map strmap = abctable.map(); + typedef std::map maptype; + const maptype &map = abctable.map(); + TEST_CHECK(map.size() == 4); - TEST_EQUAL(strmap["d"], "1"); - TEST_EQUAL(strmap["e"], "3"); - TEST_EQUAL(strmap["f"], "64"); - TEST_EQUAL(strmap["g"], "sss"); - TEST_EQUAL(strmap.size(), 4); + std::map strmap = + abctable.map(); - std::vectorkeys= abctable.keys(); + TEST_EQUAL(strmap["d"], "1"); + TEST_EQUAL(strmap["e"], "3"); + TEST_EQUAL(strmap["f"], "64"); + TEST_EQUAL(strmap["g"], "sss"); + TEST_EQUAL(strmap.size(), 4); - TEST_EQUAL(keys.size(), 4); - TEST_CHECK(std::find(keys.begin(), keys.end(), "d") != keys.end()); - TEST_CHECK(std::find(keys.begin(), keys.end(), "e") != keys.end()); - TEST_CHECK(std::find(keys.begin(), keys.end(), "f") != keys.end()); - TEST_CHECK(std::find(keys.begin(), keys.end(), "g") != keys.end()); + std::vector keys = abctable.keys(); - abctable.setField("a", "test"); - TEST_CHECK(abctable["a"] == std::string("test")); + TEST_EQUAL(keys.size(), 4); + TEST_CHECK(std::find(keys.begin(), keys.end(), "d") != keys.end()); + TEST_CHECK(std::find(keys.begin(), keys.end(), "e") != keys.end()); + TEST_CHECK(std::find(keys.begin(), keys.end(), "f") != keys.end()); + TEST_CHECK(std::find(keys.begin(), keys.end(), "g") != keys.end()); - abctable.setField("a", 22); - TEST_CHECK(abctable["a"] == 22); + abctable.setField("a", "test"); + TEST_CHECK(abctable["a"] == std::string("test")); + abctable.setField("a", 22); + TEST_CHECK(abctable["a"] == 22); - kaguya::LuaTable v = state.newTable(); - TEST_CHECK(v.setRawField("s", 2)); - TEST_CHECK(v.setRawField("s", "a")); - TEST_CHECK(v.setRawField("s", std::string("a"))); - TEST_CHECK(v.setRawField("s", abctable)); - TEST_CHECK(v.setRawField("s", kaguya::NilValue())); - - - kaguya::LuaStackRef a; -} -KAGUYA_TEST_FUNCTION_DEF(refcopy)(kaguya::State& state) -{ - kaguya::LuaRef ref = state.newRef(2); - kaguya::LuaRef ref2; - kaguya::LuaRef ref3; - TEST_CHECK(ref); - TEST_CHECK(!ref2); - - ref2 = ref; - TEST_CHECK(ref2); - ref2 = ref3; - TEST_CHECK(!ref2); + kaguya::LuaTable v = state.newTable(); + TEST_CHECK(v.setRawField("s", 2)); + TEST_CHECK(v.setRawField("s", "a")); + TEST_CHECK(v.setRawField("s", std::string("a"))); + TEST_CHECK(v.setRawField("s", abctable)); + TEST_CHECK(v.setRawField("s", kaguya::NilValue())); + kaguya::LuaStackRef a; } -KAGUYA_TEST_FUNCTION_DEF(newtable)(kaguya::State& state) -{ - kaguya::LuaTable ref = state.newTable(); - TEST_CHECK(kaguya::LuaRef(ref) == ref); - TEST_CHECK(ref == kaguya::LuaRef(ref)); - - ref["tbl"] = kaguya::NewTable(); - kaguya::LuaRef othertable = ref["tbl"]; - TEST_CHECK(othertable != ref); - TEST_CHECK(ref != othertable); - - TEST_CHECK(othertable.map().size() == 0); - TEST_CHECK(othertable.type() == kaguya::LuaRef::TYPE_TABLE); - - othertable["foo"] = 3; - TEST_CHECK(othertable["foo"] == 3); +KAGUYA_TEST_FUNCTION_DEF(refcopy)(kaguya::State &state) { + kaguya::LuaRef ref = state.newRef(2); + kaguya::LuaRef ref2; + kaguya::LuaRef ref3; + TEST_CHECK(ref); + TEST_CHECK(!ref2); + + ref2 = ref; + TEST_CHECK(ref2); + ref2 = ref3; + TEST_CHECK(!ref2); } +KAGUYA_TEST_FUNCTION_DEF(newtable)(kaguya::State &state) { + kaguya::LuaTable ref = state.newTable(); + TEST_CHECK(kaguya::LuaRef(ref) == ref); + TEST_CHECK(ref == kaguya::LuaRef(ref)); -int free_standing_function() -{ - return 12; -} + ref["tbl"] = kaguya::NewTable(); + kaguya::LuaRef othertable = ref["tbl"]; + TEST_CHECK(othertable != ref); + TEST_CHECK(ref != othertable); + + TEST_CHECK(othertable.map().size() == 0); + TEST_CHECK(othertable.type() == kaguya::LuaRef::TYPE_TABLE); -KAGUYA_TEST_FUNCTION_DEF(callfunction)(kaguya::State& state) -{ + othertable["foo"] = 3; + TEST_CHECK(othertable["foo"] == 3); +} - int ret = state["math"]["abs"](-32); - TEST_CHECK(ret == 32); +int free_standing_function() { return 12; } +KAGUYA_TEST_FUNCTION_DEF(callfunction)(kaguya::State &state) { - kaguya::LuaTable globalTable = state.globalTable(); - globalTable["tbl"] = kaguya::NewTable(); - kaguya::LuaRef tbl = globalTable["tbl"]; + int ret = state["math"]["abs"](-32); + TEST_CHECK(ret == 32); - state("tbl.fun=function() return 1 end"); - TEST_CHECK(tbl.map().size() == 1); + kaguya::LuaTable globalTable = state.globalTable(); + globalTable["tbl"] = kaguya::NewTable(); + kaguya::LuaRef tbl = globalTable["tbl"]; - int result = tbl["fun"](); - TEST_CHECK(result == 1); + state("tbl.fun=function() return 1 end"); + TEST_CHECK(tbl.map().size() == 1); - state("tbl.value=6"); - state("tbl.memfun=function(self) return self.value end"); - result = (tbl->*"memfun")();//==tbl["memfun"](tbl) like tbl:memfun() in Lua + int result = tbl["fun"](); + TEST_CHECK(result == 1); - TEST_CHECK(result == 6); + state("tbl.value=6"); + state("tbl.memfun=function(self) return self.value end"); + result = (tbl->*"memfun")(); //==tbl["memfun"](tbl) like tbl:memfun() in Lua - globalTable["free2"] = kaguya::function(&free_standing_function); + TEST_CHECK(result == 6); - TEST_CHECK(state("assert(free2()==12)")); + globalTable["free2"] = kaguya::function(&free_standing_function); + TEST_CHECK(state("assert(free2()==12)")); - state("tbl.sum=function(...) local args = {...};" - "local total=0;" - "for i = 1, #args do " - " total = total + args[i];" - " end " - "return total;" - "end"); - TEST_CHECK(tbl["sum"](1, 2, 3, 4, 5, 6, 7, 8) == 36); - TEST_CHECK(tbl["sum"].call(1, 2, 3, 4, 5, 6, 7, 8) == 36); + state("tbl.sum=function(...) local args = {...};" + "local total=0;" + "for i = 1, #args do " + " total = total + args[i];" + " end " + "return total;" + "end"); + TEST_CHECK(tbl["sum"](1, 2, 3, 4, 5, 6, 7, 8) == 36); + TEST_CHECK(tbl["sum"].call(1, 2, 3, 4, 5, 6, 7, 8) == 36); - //no return compile test - tbl["sum"].call(1, 2, 3, 4, 5, 6, 7, 8); + // no return compile test + tbl["sum"].call(1, 2, 3, 4, 5, 6, 7, 8); - state("tbl.retfun=function(tbl) return tbl.sum end"); - TEST_CHECK((tbl->*"retfun")()(1, 2, 3, 4, 5, 6, 7, 8) == 36) + state("tbl.retfun=function(tbl) return tbl.sum end"); + TEST_CHECK((tbl->*"retfun")()(1, 2, 3, 4, 5, 6, 7, 8) == 36) - //callable check - TEST_CHECK((tbl->*"retfun").call()(1, 2, 3, 4, 5, 6, 7, 8) == 36) - TEST_CHECK((tbl->*"retfun")().call(1, 2, 3, 4, 5, 6, 7, 8) == 36) + // callable check + TEST_CHECK( + (tbl->*"retfun").call()(1, 2, 3, 4, 5, 6, 7, 8) == + 36) + TEST_CHECK((tbl->*"retfun")().call(1, 2, 3, 4, 5, 6, 7, 8) == 36) } -struct ob -{ - operator bool()const { return true; } +struct ob { + operator bool() const { return true; } }; -KAGUYA_TEST_FUNCTION_DEF(test_operator_bool)(kaguya::State& state) -{ - kaguya::LuaRef table1 = state.newTable(); - TEST_CHECK(ob() != table1); - kaguya::LuaTable newTable2 = state.newTable(); - kaguya::LuaTable tabl1_ref_copy = table1; - TEST_CHECK(newTable2 != table1); - TEST_CHECK(ob() != newTable2); - TEST_CHECK(!(newTable2 == table1)); - TEST_CHECK(table1 == tabl1_ref_copy); +KAGUYA_TEST_FUNCTION_DEF(test_operator_bool)(kaguya::State &state) { + kaguya::LuaRef table1 = state.newTable(); + TEST_CHECK(ob() != table1); + kaguya::LuaTable newTable2 = state.newTable(); + kaguya::LuaTable tabl1_ref_copy = table1; + TEST_CHECK(newTable2 != table1); + TEST_CHECK(ob() != newTable2); + TEST_CHECK(!(newTable2 == table1)); + TEST_CHECK(table1 == tabl1_ref_copy); } -KAGUYA_TEST_FUNCTION_DEF(typetest_function)(kaguya::State& state) -{ - kaguya::LuaRef newTable = state.newTable(); - - kaguya::LuaRef function = state.newRef(kaguya::function(&free_standing_function)); - kaguya::LuaRef function2 = function; - TEST_CHECK(function != newTable); - TEST_CHECK(function == function2); +KAGUYA_TEST_FUNCTION_DEF(typetest_function)(kaguya::State &state) { + kaguya::LuaRef newTable = state.newTable(); + + kaguya::LuaRef function = + state.newRef(kaguya::function(&free_standing_function)); + kaguya::LuaRef function2 = function; + TEST_CHECK(function != newTable); + TEST_CHECK(function == function2); } -KAGUYA_TEST_FUNCTION_DEF(operator_equal_test)(kaguya::State& state) -{ - kaguya::LuaTable globalTable = state.globalTable(); - - TEST_CHECK(!(globalTable != state.globalTable())); - TEST_CHECK(globalTable == state.globalTable()); - - kaguya::LuaRef luanum = state.newRef(422); - kaguya::LuaRef luanum2 = state.newRef(42); - kaguya::LuaRef luanum3 = state.newRef(422); - - TEST_COMPARE_EQ(luanum, luanum3); - TEST_COMPARE_NE(luanum, luanum2); - TEST_COMPARE_LT(luanum2, luanum); - TEST_COMPARE_LE(luanum2, luanum); - TEST_COMPARE_GT(luanum, luanum2); - TEST_COMPARE_GE(luanum, luanum2); - - TEST_CHECK(!(luanum != luanum3)); - TEST_CHECK(!(luanum < luanum3)); - TEST_CHECK(luanum <= luanum3); - TEST_CHECK(!(luanum > luanum3)); - TEST_CHECK(luanum >= luanum3); +KAGUYA_TEST_FUNCTION_DEF(operator_equal_test)(kaguya::State &state) { + kaguya::LuaTable globalTable = state.globalTable(); + + TEST_CHECK(!(globalTable != state.globalTable())); + TEST_CHECK(globalTable == state.globalTable()); + + kaguya::LuaRef luanum = state.newRef(422); + kaguya::LuaRef luanum2 = state.newRef(42); + kaguya::LuaRef luanum3 = state.newRef(422); + + TEST_COMPARE_EQ(luanum, luanum3); + TEST_COMPARE_NE(luanum, luanum2); + TEST_COMPARE_LT(luanum2, luanum); + TEST_COMPARE_LE(luanum2, luanum); + TEST_COMPARE_GT(luanum, luanum2); + TEST_COMPARE_GE(luanum, luanum2); + + TEST_CHECK(!(luanum != luanum3)); + TEST_CHECK(!(luanum < luanum3)); + TEST_CHECK(luanum <= luanum3); + TEST_CHECK(!(luanum > luanum3)); + TEST_CHECK(luanum >= luanum3); } -KAGUYA_TEST_FUNCTION_DEF(typetest)(kaguya::State& state) -{ - kaguya::LuaRef luanum = state.newRef(422); - TEST_CHECK(luanum.typeTest()); - TEST_CHECK(!luanum.typeTest()); - TEST_CHECK(!luanum.typeTest()); - - TEST_CHECK(luanum.weakTypeTest()); - TEST_CHECK(!luanum.weakTypeTest()); - - - bool typevalid; - TEST_EQUAL(luanum.get(typevalid), "422"); - TEST_CHECK(typevalid); - TEST_EQUAL(luanum.get(typevalid), 422); - TEST_CHECK(typevalid); - luanum.get(typevalid, false); - TEST_CHECK(!typevalid); - - +KAGUYA_TEST_FUNCTION_DEF(typetest)(kaguya::State &state) { + kaguya::LuaRef luanum = state.newRef(422); + TEST_CHECK(luanum.typeTest()); + TEST_CHECK(!luanum.typeTest()); + TEST_CHECK(!luanum.typeTest()); + + TEST_CHECK(luanum.weakTypeTest()); + TEST_CHECK(!luanum.weakTypeTest()); + + bool typevalid; + TEST_EQUAL(luanum.get(typevalid), "422"); + TEST_CHECK(typevalid); + TEST_EQUAL(luanum.get(typevalid), 422); + TEST_CHECK(typevalid); + luanum.get(typevalid, false); + TEST_CHECK(!typevalid); } - -struct CallbackTest -{ - void callCallback(int x) - { - if (function_) - { - function_(x); - } - } - void setCallback(kaguya::LuaRef fun) - { - function_ = fun; - } - kaguya::LuaRef function_; +struct CallbackTest { + void callCallback(int x) { + if (function_) { + function_(x); + } + } + void setCallback(kaguya::LuaRef fun) { function_ = fun; } + kaguya::LuaRef function_; }; -KAGUYA_TEST_FUNCTION_DEF(luafun_callback)(kaguya::State& state) -{ - - state["CallbackTest"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addFunction("setCallback", &CallbackTest::setCallback) - .addFunction("callCallback", &CallbackTest::callCallback)); - +KAGUYA_TEST_FUNCTION_DEF(luafun_callback)(kaguya::State &state) { - state("callback = CallbackTest.new();" - "receive_data ={};" - "callback:setCallback(function(x) table.insert(receive_data,x) end);" - "callback:callCallback(54)" - "callback:callCallback(24)" - ); + state["CallbackTest"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addFunction("setCallback", &CallbackTest::setCallback) + .addFunction("callCallback", &CallbackTest::callCallback)); - (state["callback"]->*"callCallback")(454); - kaguya::LuaTable callback_data = state["receive_data"]; + state("callback = CallbackTest.new();" + "receive_data ={};" + "callback:setCallback(function(x) table.insert(receive_data,x) end);" + "callback:callCallback(54)" + "callback:callCallback(24)"); - TEST_CHECK(callback_data[1] == 54 - && callback_data[2] == 24 && callback_data[3] == 454) + (state["callback"]->*"callCallback")(454); + kaguya::LuaTable callback_data = state["receive_data"]; + TEST_CHECK(callback_data[1] == 54 && callback_data[2] == 24 && + callback_data[3] == 454) } -struct size_check_struct -{ - char data[22]; +struct size_check_struct { + char data[22]; }; -KAGUYA_TEST_FUNCTION_DEF(lua_ref_size)(kaguya::State& state) -{ -#define TEST_SIZE(IDENTIFIER, VALUE, LEN) \ - state(#IDENTIFIER " = " #VALUE); \ - kaguya::LuaRef IDENTIFIER = state[#IDENTIFIER]; \ - TEST_EQUAL(IDENTIFIER.size() , LEN); +KAGUYA_TEST_FUNCTION_DEF(lua_ref_size)(kaguya::State &state) { +#define TEST_SIZE(IDENTIFIER, VALUE, LEN) \ + state(#IDENTIFIER " = " #VALUE); \ + kaguya::LuaRef IDENTIFIER = state[#IDENTIFIER]; \ + TEST_EQUAL(IDENTIFIER.size(), LEN); - TEST_SIZE(x, 17, 0); - TEST_SIZE(s, 'hello world!', 12); - TEST_SIZE(b, true, 0); - TEST_SIZE(n, nil, 0); - TEST_SIZE(f, function() return 3 end, 0); + TEST_SIZE(x, 17, 0); + TEST_SIZE(s, 'hello world!', 12); + TEST_SIZE(b, true, 0); + TEST_SIZE(n, nil, 0); + TEST_SIZE(f, function() return 3 end, 0); #undef TEST_SIZE - state["d"] = size_check_struct(); - kaguya::LuaRef d = state["d"]; - TEST_CHECK(d.size() >= sizeof(size_check_struct)); // fixme: determine exact size of userdata if possible + state["d"] = size_check_struct(); + kaguya::LuaRef d = state["d"]; + TEST_CHECK(d.size() >= sizeof(size_check_struct)); // fixme: determine exact + // size of userdata if + // possible } -KAGUYA_TEST_FUNCTION_DEF(function_env)(kaguya::State& state) -{ - kaguya::LuaFunction fun = state.loadstring("foo='bar'"); +KAGUYA_TEST_FUNCTION_DEF(function_env)(kaguya::State &state) { + kaguya::LuaFunction fun = state.loadstring("foo='bar'"); - fun.setFunctionEnv(kaguya::NewTable()); - fun(); + fun.setFunctionEnv(kaguya::NewTable()); + fun(); - TEST_CHECK(state("assert(foo == nil)")); - state["functionEnv"] = fun.getFunctionEnv(); - TEST_CHECK(state("assert(functionEnv.foo == 'bar')")); + TEST_CHECK(state("assert(foo == nil)")); + state["functionEnv"] = fun.getFunctionEnv(); + TEST_CHECK(state("assert(functionEnv.foo == 'bar')")); } +KAGUYA_TEST_FUNCTION_DEF(lua_table_get)(kaguya::State &state) { + state("value={out=32,str='gjgj'}"); + state("value['in'] = 'test'"); + kaguya::LuaTable table = state["value"]; -KAGUYA_TEST_FUNCTION_DEF(lua_table_get)(kaguya::State& state) -{ - state("value={out=32,str='gjgj'}"); - state("value['in'] = 'test'"); - kaguya::LuaTable table = state["value"]; + TEST_CHECK(table["str"] == "gjgj" && table["in"] == "test" && + table["out"] == 32); - TEST_CHECK(table["str"] == "gjgj" && table["in"] == "test" && table["out"] == 32); - - TEST_CHECK(!table.isNilref()); + TEST_CHECK(!table.isNilref()); } -KAGUYA_TEST_FUNCTION_DEF(lua_table_set)(kaguya::State& state) -{ - kaguya::LuaTable globalTable = state.globalTable(); - state["value"] = kaguya::NewTable(); - state["value"]["abc"] = kaguya::NewTable(); - state["value"]["abc"]["def"] = 7; - state["value"]["abc"]["bbb"] = "test"; - TEST_CHECK(state("assert(value.abc.def == 7 and value.abc.bbb == 'test')")); +KAGUYA_TEST_FUNCTION_DEF(lua_table_set)(kaguya::State &state) { + kaguya::LuaTable globalTable = state.globalTable(); + state["value"] = kaguya::NewTable(); + state["value"]["abc"] = kaguya::NewTable(); + state["value"]["abc"]["def"] = 7; + state["value"]["abc"]["bbb"] = "test"; + TEST_CHECK(state("assert(value.abc.def == 7 and value.abc.bbb == 'test')")); } -KAGUYA_TEST_FUNCTION_DEF(lua_table_size)(kaguya::State& state) -{ - kaguya::LuaTable table = state.newTable(); - TEST_CHECK(table.size() == 0); - - state("value = {1, 2, 'foo'}"); - kaguya::LuaTable table2 = state["value"]; - TEST_CHECK(table2.size() == 3); - - state("value[3] = nil"); - kaguya::LuaTable table3 = state["value"]; - TEST_CHECK(table3.size() == 2); - - state["value"] = kaguya::NewTable(); - state["value"][1] = "foo"; - state["value"][2] = "bar"; - state["value"][99] = "baz"; - state["value"]["index"] = "foo"; - kaguya::LuaTable table4 = state["value"]; - TEST_CHECK(table4.size() == 2); +KAGUYA_TEST_FUNCTION_DEF(lua_table_size)(kaguya::State &state) { + kaguya::LuaTable table = state.newTable(); + TEST_CHECK(table.size() == 0); + + state("value = {1, 2, 'foo'}"); + kaguya::LuaTable table2 = state["value"]; + TEST_CHECK(table2.size() == 3); + + state("value[3] = nil"); + kaguya::LuaTable table3 = state["value"]; + TEST_CHECK(table3.size() == 2); + + state["value"] = kaguya::NewTable(); + state["value"][1] = "foo"; + state["value"][2] = "bar"; + state["value"][99] = "baz"; + state["value"]["index"] = "foo"; + kaguya::LuaTable table4 = state["value"]; + TEST_CHECK(table4.size() == 2); } -KAGUYA_TEST_FUNCTION_DEF(lua_table_reference)(kaguya::State& state) -{ - kaguya::LuaTable globalTable = state.globalTable(); - state["value"] = kaguya::NewTable(); - state["value"]["abc"] = kaguya::NewTable(); - state["value"]["abc"]["def"] = 7; - TEST_CHECK(state("assert(value.abc.def == 7)")); - state["value"]["abc"]["bbb"] = "test"; - TEST_CHECK(state("assert(value.abc.bbb == 'test')")); - state["value"]["abc"]["ddd"] = state["value"]["abc"]["ccc"] = state["value"]["abc"]["bbb"]; - TEST_CHECK(state("assert(value.abc.ccc == 'test')")); - TEST_CHECK(state("assert(value.abc.ddd == 'test')")); - - TEST_COMPARE_EQ(state["value"]["abc"]["ccc"], state["value"]["abc"]["bbb"]); - TEST_COMPARE_EQ(state["value"]["abc"]["ccc"], "test"); - TEST_CHECK(!(state["value"]["abc"]["ccc"] != state["value"]["abc"]["bbb"])); - TEST_CHECK(!(state["value"]["abc"]["ccc"] != "test")); - TEST_COMPARE_NE(state["value"]["abc"]["ccc"], state["value"]["abc"]["def"]); - TEST_COMPARE_NE(state["value"]["abc"]["ccc"], "tes"); +KAGUYA_TEST_FUNCTION_DEF(lua_table_reference)(kaguya::State &state) { + kaguya::LuaTable globalTable = state.globalTable(); + state["value"] = kaguya::NewTable(); + state["value"]["abc"] = kaguya::NewTable(); + state["value"]["abc"]["def"] = 7; + TEST_CHECK(state("assert(value.abc.def == 7)")); + state["value"]["abc"]["bbb"] = "test"; + TEST_CHECK(state("assert(value.abc.bbb == 'test')")); + state["value"]["abc"]["ddd"] = state["value"]["abc"]["ccc"] = + state["value"]["abc"]["bbb"]; + TEST_CHECK(state("assert(value.abc.ccc == 'test')")); + TEST_CHECK(state("assert(value.abc.ddd == 'test')")); + + TEST_COMPARE_EQ(state["value"]["abc"]["ccc"], state["value"]["abc"]["bbb"]); + TEST_COMPARE_EQ(state["value"]["abc"]["ccc"], "test"); + TEST_CHECK(!(state["value"]["abc"]["ccc"] != state["value"]["abc"]["bbb"])); + TEST_CHECK(!(state["value"]["abc"]["ccc"] != "test")); + TEST_COMPARE_NE(state["value"]["abc"]["ccc"], state["value"]["abc"]["def"]); + TEST_COMPARE_NE(state["value"]["abc"]["ccc"], "tes"); } -KAGUYA_TEST_FUNCTION_DEF(metatable)(kaguya::State& state) -{ - kaguya::LuaTable table = state.newTable(); - kaguya::LuaTable metatable = state.newTable(); - kaguya::LuaTable metatable_index = state.newTable(); - metatable_index["hana"] = "uta"; - metatable["__index"] = metatable_index; - table.setMetatable(metatable); - TEST_EQUAL(table["hana"], "uta"); - TEST_EQUAL(table.getMetatable(), metatable); +KAGUYA_TEST_FUNCTION_DEF(metatable)(kaguya::State &state) { + kaguya::LuaTable table = state.newTable(); + kaguya::LuaTable metatable = state.newTable(); + kaguya::LuaTable metatable_index = state.newTable(); + metatable_index["hana"] = "uta"; + metatable["__index"] = metatable_index; + table.setMetatable(metatable); + TEST_EQUAL(table["hana"], "uta"); + TEST_EQUAL(table.getMetatable(), metatable); } -KAGUYA_TEST_FUNCTION_DEF(stream_out_test)(kaguya::State& state) -{ - kaguya::LuaTable table = state.newTable(); - table[1] = 231; - table[2] = 21; - table[3] = 2; - std::stringstream ss; - std::string text; - ss << table; - text = ss.str(); - TEST_EQUAL(text, "{1=231,2=21,3=2}"); - - ss.str(""); - ss << table[1]; - text = ss.str(); - TEST_EQUAL(text, "231"); - - ss.str(""); - ss << state.newRef(323); - text = ss.str(); - TEST_EQUAL(text, "323"); - - ss.str(""); - ss << state.newRef("test_text"); - text = ss.str(); - TEST_EQUAL(text, "'test_text'"); - - ss.str(""); - ss << state.newRef(true); - text = ss.str(); - TEST_EQUAL(text, "true"); - ss.str(""); - ss << state.newRef(false); - text = ss.str(); - TEST_EQUAL(text, "false"); - ss.str(""); - ss << state.newRef((void*)(0)); - text = ss.str(); - TEST_EQUAL(text, "nil"); - - ss.str(""); - ss << state.newRef(&stream_out_test); - text = ss.str(); - TEST_EQUAL(text, "function"); - - - ss.str(""); - ss << state.loadstring("return {1,2,3,4,5}")(); - text = ss.str(); - TEST_EQUAL(text, "{1=1,2=2,3=3,4=4,5=5}"); - - ss.str(""); - ss << state.loadstring("return {table={1,2,3,4,5}}")(); - text = ss.str(); - TEST_EQUAL(text, "{'table'={...}}"); - - ss.str(""); - ss << state.loadstring("return 2,3")(); - text = ss.str(); - TEST_EQUAL(text, "2,3"); - - ss.str(""); - ss << state.loadstring("return 2,3")().result_at(0); - text = ss.str(); - TEST_EQUAL(text, "2"); - - ss.str(""); - ss << state.newRef(&ss); - text = ss.str(); - TEST_CHECK(text.compare(0, strlen("userdata"), "userdata") == 0); - - bool catch_except = false; - try - { - ss << state.loadstring("return 2,3")().result_at(2); - } - catch (const std::out_of_range&) - { - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(stream_out_test)(kaguya::State &state) { + kaguya::LuaTable table = state.newTable(); + table[1] = 231; + table[2] = 21; + table[3] = 2; + std::stringstream ss; + std::string text; + ss << table; + text = ss.str(); + TEST_EQUAL(text, "{1=231,2=21,3=2}"); + + ss.str(""); + ss << table[1]; + text = ss.str(); + TEST_EQUAL(text, "231"); + + ss.str(""); + ss << state.newRef(323); + text = ss.str(); + TEST_EQUAL(text, "323"); + + ss.str(""); + ss << state.newRef("test_text"); + text = ss.str(); + TEST_EQUAL(text, "'test_text'"); + + ss.str(""); + ss << state.newRef(true); + text = ss.str(); + TEST_EQUAL(text, "true"); + ss.str(""); + ss << state.newRef(false); + text = ss.str(); + TEST_EQUAL(text, "false"); + ss.str(""); + ss << state.newRef((void *)(0)); + text = ss.str(); + TEST_EQUAL(text, "nil"); + + ss.str(""); + ss << state.newRef(&stream_out_test); + text = ss.str(); + TEST_EQUAL(text, "function"); + + ss.str(""); + ss << state.loadstring("return {1,2,3,4,5}")(); + text = ss.str(); + TEST_EQUAL(text, "{1=1,2=2,3=3,4=4,5=5}"); + + ss.str(""); + ss << state.loadstring("return {table={1,2,3,4,5}}")(); + text = ss.str(); + TEST_EQUAL(text, "{'table'={...}}"); + + ss.str(""); + ss << state.loadstring("return 2,3")(); + text = ss.str(); + TEST_EQUAL(text, "2,3"); + + ss.str(""); + ss << state.loadstring("return 2,3")().result_at(0); + text = ss.str(); + TEST_EQUAL(text, "2"); + + ss.str(""); + ss << state.newRef(&ss); + text = ss.str(); + TEST_CHECK(text.compare(0, strlen("userdata"), "userdata") == 0); + + bool catch_except = false; + try { + ss << state.loadstring("return 2,3")().result_at(2); + } catch (const std::out_of_range &) { + catch_except = true; + } + TEST_CHECK(catch_except); } - - -KAGUYA_TEST_FUNCTION_DEF(get_field)(kaguya::State& state) -{ - kaguya::LuaRef table = state.newTable(); - state["testtable"] = table; - table.setField("3", 4); - TEST_CHECK(state("assert(testtable['3'] == 4)")); - table.setField(1, 32); - TEST_CHECK(state("assert(testtable[1] == 32)")); - - TEST_EQUAL(table.getField("3"), 4); - TEST_EQUAL(table[1], 32); - TEST_EQUAL(table.getField(1), 32); - const kaguya::LuaRef& const_table = table; - TEST_EQUAL(const_table.getField("3"), 4); - TEST_EQUAL(const_table[1], 32); - TEST_EQUAL(const_table.getField(1), 32); - TEST_EQUAL(const_table.getField(state.newRef(1)),32); - TEST_EQUAL(const_table.getRawField(1), 32); - TEST_EQUAL(const_table.getRawField(state.newRef(1)), 32); +KAGUYA_TEST_FUNCTION_DEF(get_field)(kaguya::State &state) { + kaguya::LuaRef table = state.newTable(); + state["testtable"] = table; + table.setField("3", 4); + TEST_CHECK(state("assert(testtable['3'] == 4)")); + table.setField(1, 32); + TEST_CHECK(state("assert(testtable[1] == 32)")); + + TEST_EQUAL(table.getField("3"), 4); + TEST_EQUAL(table[1], 32); + TEST_EQUAL(table.getField(1), 32); + const kaguya::LuaRef &const_table = table; + TEST_EQUAL(const_table.getField("3"), 4); + TEST_EQUAL(const_table[1], 32); + TEST_EQUAL(const_table.getField(1), 32); + TEST_EQUAL(const_table.getField(state.newRef(1)), 32); + TEST_EQUAL(const_table.getRawField(1), 32); + TEST_EQUAL(const_table.getRawField(state.newRef(1)), 32); } - -KAGUYA_TEST_FUNCTION_DEF(luafun_loadstring)(kaguya::State& state) -{ - { - kaguya::LuaRef f = kaguya::LuaFunction::loadstring(state.state(), "return function(table, key) return table['other_'..key] end")(); - kaguya::LuaTable table = state.newTable(); - table["x"] = 5; - table["other_x"] = 55; - int v = f(table, "x"); - TEST_EQUAL(v, 55); - } - - { - kaguya::LuaRef f = kaguya::LuaFunction::loadstring(state.state() - , "return function(a) return 22,66 end")(); - - kaguya::LuaRef forwardf = kaguya::LuaFunction::loadstring(state.state() - , "return function(...) return ... end")(); - int a = 0; int b = 0; - kaguya::tie(a, b) = f(); - TEST_EQUAL(a, 22); - TEST_EQUAL(b, 66); - a = 0; b = 0; - kaguya::tie(a, b) = forwardf(f()); - TEST_EQUAL(a, 22); - TEST_EQUAL(b, 66); - } - - +KAGUYA_TEST_FUNCTION_DEF(luafun_loadstring)(kaguya::State &state) { + { + kaguya::LuaRef f = kaguya::LuaFunction::loadstring( + state.state(), + "return function(table, key) return table['other_'..key] end")(); + kaguya::LuaTable table = state.newTable(); + table["x"] = 5; + table["other_x"] = 55; + int v = f(table, "x"); + TEST_EQUAL(v, 55); + } + + { + kaguya::LuaRef f = kaguya::LuaFunction::loadstring( + state.state(), "return function(a) return 22,66 end")(); + + kaguya::LuaRef forwardf = kaguya::LuaFunction::loadstring( + state.state(), "return function(...) return ... end")(); + int a = 0; + int b = 0; + kaguya::tie(a, b) = f(); + TEST_EQUAL(a, 22); + TEST_EQUAL(b, 66); + a = 0; + b = 0; + kaguya::tie(a, b) = forwardf(f()); + TEST_EQUAL(a, 22); + TEST_EQUAL(b, 66); + } } - -KAGUYA_TEST_FUNCTION_DEF(put_multiple)(kaguya::State& state) -{ - kaguya::LuaRef v = state.newRef(kaguya::standard::tuple(32, 22)); - TEST_EQUAL(v, 32); - TEST_CHECK(v); - state["value"] = v; - TEST_EQUAL(state["value"], 32); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 32)")); - - kaguya::LuaRef f = state.loadstring("return 22,66"); - state["value"] = f(); - TEST_EQUAL(state["value"], 22); - TEST_CHECK(state["value"]); - TEST_CHECK(state("assert(value == 22)")); +KAGUYA_TEST_FUNCTION_DEF(put_multiple)(kaguya::State &state) { + kaguya::LuaRef v = state.newRef(kaguya::standard::tuple(32, 22)); + TEST_EQUAL(v, 32); + TEST_CHECK(v); + state["value"] = v; + TEST_EQUAL(state["value"], 32); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 32)")); + + kaguya::LuaRef f = state.loadstring("return 22,66"); + state["value"] = f(); + TEST_EQUAL(state["value"], 22); + TEST_CHECK(state["value"]); + TEST_CHECK(state("assert(value == 22)")); } -struct table_functor -{ - void operator()(int, int) {} +struct table_functor { + void operator()(int, int) {} }; -struct breakable_table_functor -{ - bool operator()(int, int) { - return true; - } +struct breakable_table_functor { + bool operator()(int, int) { return true; } }; -KAGUYA_TEST_FUNCTION_DEF(nostate_ref_error)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - kaguya::LuaRef v; - kaguya::LuaRef thread = state.newThread(); - kaguya::LuaRef table = state.newTable(); - - TEST_CHECK(!v.setMetatable(state.newTable())); - TEST_CHECK(!v.getMetatable()); - - TEST_CHECK(!v.setFunctionEnv(state.newTable())); - TEST_CHECK(!v.getFunctionEnv()); - TEST_CHECK(!v.getField("s")); - TEST_CHECK(!v.setField("s", 2)); - TEST_CHECK(!v.setField("s", "a")); - TEST_CHECK(!v.setField("s", std::string("a"))); - TEST_CHECK(!v.setField("s", table)); - TEST_CHECK(!v.setField("s", kaguya::NilValue())); - TEST_CHECK(!v.setField(kaguya::NilValue(), kaguya::NilValue())); - - - TEST_CHECK(!v.setRawField("s", 2)); - TEST_CHECK(!v.setRawField("s", "a")); - TEST_CHECK(!v.setRawField("s", std::string("a"))); - TEST_CHECK(!v.setRawField("s", table)); - TEST_CHECK(!v.setRawField("s", kaguya::NilValue())); - TEST_CHECK(!v.setRawField(kaguya::NilValue(), kaguya::NilValue())); - - TEST_CHECK(!table.getFunctionEnv()); - TEST_CHECK(!thread.getMetatable()); - - TEST_CHECK(!table.setFunctionEnv(kaguya::NewTable())); - TEST_CHECK(!thread.setMetatable(state.newTable())); - - - const kaguya::LuaRef cv; - const kaguya::LuaRef cthread = state.newThread(); - const kaguya::LuaRef ctable = state.newTable(); - - TEST_CHECK(!cv.getMetatable()); - - TEST_CHECK(!cv.getFunctionEnv()); - TEST_CHECK(!cv.getField("s")); - TEST_CHECK(!cv.getField("s")); - TEST_CHECK(!cv.getField(kaguya::NewTable())); - - - TEST_CHECK(!ctable.getFunctionEnv()); - TEST_CHECK(!cthread.getMetatable()); - - ctable.foreach_table(table_functor()); - ctable.foreach_table_breakable(breakable_table_functor()); - cv.foreach_table(table_functor()); - cv.foreach_table_breakable(breakable_table_functor()); - - last_error_message = ""; - kaguya::LuaRef ref = state.newTable(); - ref.costatus(); - TEST_CHECK(!last_error_message.empty()); - +KAGUYA_TEST_FUNCTION_DEF(nostate_ref_error)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + kaguya::LuaRef v; + kaguya::LuaRef thread = state.newThread(); + kaguya::LuaRef table = state.newTable(); + + TEST_CHECK(!v.setMetatable(state.newTable())); + TEST_CHECK(!v.getMetatable()); + + TEST_CHECK(!v.setFunctionEnv(state.newTable())); + TEST_CHECK(!v.getFunctionEnv()); + TEST_CHECK(!v.getField("s")); + TEST_CHECK(!v.setField("s", 2)); + TEST_CHECK(!v.setField("s", "a")); + TEST_CHECK(!v.setField("s", std::string("a"))); + TEST_CHECK(!v.setField("s", table)); + TEST_CHECK(!v.setField("s", kaguya::NilValue())); + TEST_CHECK(!v.setField(kaguya::NilValue(), kaguya::NilValue())); + + TEST_CHECK(!v.setRawField("s", 2)); + TEST_CHECK(!v.setRawField("s", "a")); + TEST_CHECK(!v.setRawField("s", std::string("a"))); + TEST_CHECK(!v.setRawField("s", table)); + TEST_CHECK(!v.setRawField("s", kaguya::NilValue())); + TEST_CHECK(!v.setRawField(kaguya::NilValue(), kaguya::NilValue())); + + TEST_CHECK(!table.getFunctionEnv()); + TEST_CHECK(!thread.getMetatable()); + + TEST_CHECK(!table.setFunctionEnv(kaguya::NewTable())); + TEST_CHECK(!thread.setMetatable(state.newTable())); + + const kaguya::LuaRef cv; + const kaguya::LuaRef cthread = state.newThread(); + const kaguya::LuaRef ctable = state.newTable(); + + TEST_CHECK(!cv.getMetatable()); + + TEST_CHECK(!cv.getFunctionEnv()); + TEST_CHECK(!cv.getField("s")); + TEST_CHECK(!cv.getField("s")); + TEST_CHECK(!cv.getField(kaguya::NewTable())); + + TEST_CHECK(!ctable.getFunctionEnv()); + TEST_CHECK(!cthread.getMetatable()); + + ctable.foreach_table(table_functor()); + ctable.foreach_table_breakable(breakable_table_functor()); + cv.foreach_table(table_functor()); + cv.foreach_table_breakable(breakable_table_functor()); + + last_error_message = ""; + kaguya::LuaRef ref = state.newTable(); + ref.costatus(); + TEST_CHECK(!last_error_message.empty()); } -struct UserDataTest -{ - UserDataTest(int v) :m(v) {} - int m; +struct UserDataTest { + UserDataTest(int v) : m(v) {} + int m; }; -struct UserDataTest2 -{ - UserDataTest2(int v) :m(v) {} - double m; +struct UserDataTest2 { + UserDataTest2(int v) : m(v) {} + double m; }; -UserDataTest& UserDataTestFunction(UserDataTest& r) -{ - r.m = 5; - return r; -} -void UserDataTestFunction2(int ) -{ +UserDataTest &UserDataTestFunction(UserDataTest &r) { + r.m = 5; + return r; } - - -KAGUYA_TEST_FUNCTION_DEF(typecheck_ref_error)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - { - last_error_message = ""; - kaguya::LuaTable nottable = kaguya::LuaRef(state.newThread()); - TEST_COMPARE_NE(last_error_message, ""); - } - { - last_error_message = ""; - kaguya::LuaUserData notud = kaguya::LuaRef(state.newThread()); - TEST_COMPARE_NE(last_error_message, ""); - } - { - last_error_message = ""; - kaguya::LuaThread notud = kaguya::LuaRef(state.newTable()); - TEST_COMPARE_NE(last_error_message, ""); - } - - { - last_error_message = ""; - kaguya::LuaRef udataref = state.newRef(UserDataTest(2)); - TEST_CHECK(udataref.weakTypeTest()); - TEST_CHECK(udataref.typeTest()); - TEST_CHECK(!udataref.weakTypeTest()); - TEST_CHECK(!udataref.typeTest()); - TEST_CHECK(udataref.typeTest()); - TEST_CHECK(!udataref.typeTest()); - TEST_CHECK(!udataref.typeTest()); - kaguya::LuaUserData udata = udataref; - TEST_EQUAL(last_error_message, ""); - UserDataTest d = udata; - TEST_EQUAL(d.m, 2); - } - { - last_error_message = ""; - kaguya::LuaUserData udata; - TEST_CHECK(!udata); - TEST_EQUAL(last_error_message, ""); - } - { - last_error_message = ""; - kaguya::LuaUserData udata(state.state()); - TEST_CHECK(!udata); - TEST_EQUAL(last_error_message, ""); - } - { - last_error_message = ""; - kaguya::LuaUserData udata(state.state(), UserDataTest(2)); - TEST_CHECK(udata); - TEST_CHECK(udata.typeTest()); - TEST_CHECK(!udata.typeTest()); - UserDataTest d = udata; - TEST_EQUAL(d.m, 2); - TEST_EQUAL(last_error_message, ""); - } - { - last_error_message = ""; - UserDataTest udatan(2); - kaguya::LuaUserData udata(state.state(), &udatan); - TEST_CHECK(udata); - UserDataTest* d = udata;//unsafe - TEST_EQUAL(d->m, 2); - - const UserDataTest& dr = udata;//unsafe - TEST_EQUAL(dr.m, 2); - TEST_EQUAL(last_error_message, ""); - - kaguya::LuaFunction f(state.state(), kaguya::overload(UserDataTestFunction, UserDataTestFunction2)); - f(udata); - TEST_EQUAL(udatan.m, 5); - } - { - last_error_message = ""; - UserDataTest udatan(2); - kaguya::LuaUserData udata(state.state(), kaguya::standard::ref(udatan)); - TEST_CHECK(udata); - UserDataTest* d = udata;//unsafe - TEST_EQUAL(d->m, 2); - - const UserDataTest& dr = udata;//unsafe - TEST_EQUAL(dr.m, 2); - TEST_EQUAL(last_error_message, ""); - - kaguya::LuaFunction f(state.state(), kaguya::overload(UserDataTestFunction, UserDataTestFunction2)); - f(udata); - TEST_EQUAL(udatan.m, 5); - } +void UserDataTestFunction2(int) {} + +KAGUYA_TEST_FUNCTION_DEF(typecheck_ref_error)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + { + last_error_message = ""; + kaguya::LuaTable nottable = kaguya::LuaRef(state.newThread()); + TEST_COMPARE_NE(last_error_message, ""); + } + { + last_error_message = ""; + kaguya::LuaUserData notud = kaguya::LuaRef(state.newThread()); + TEST_COMPARE_NE(last_error_message, ""); + } + { + last_error_message = ""; + kaguya::LuaThread notud = kaguya::LuaRef(state.newTable()); + TEST_COMPARE_NE(last_error_message, ""); + } + + { + last_error_message = ""; + kaguya::LuaRef udataref = state.newRef(UserDataTest(2)); + TEST_CHECK(udataref.weakTypeTest()); + TEST_CHECK(udataref.typeTest()); + TEST_CHECK(!udataref.weakTypeTest()); + TEST_CHECK(!udataref.typeTest()); + TEST_CHECK(udataref.typeTest()); + TEST_CHECK(!udataref.typeTest()); + TEST_CHECK(!udataref.typeTest()); + kaguya::LuaUserData udata = udataref; + TEST_EQUAL(last_error_message, ""); + UserDataTest d = udata; + TEST_EQUAL(d.m, 2); + } + { + last_error_message = ""; + kaguya::LuaUserData udata; + TEST_CHECK(!udata); + TEST_EQUAL(last_error_message, ""); + } + { + last_error_message = ""; + kaguya::LuaUserData udata(state.state()); + TEST_CHECK(!udata); + TEST_EQUAL(last_error_message, ""); + } + { + last_error_message = ""; + kaguya::LuaUserData udata(state.state(), UserDataTest(2)); + TEST_CHECK(udata); + TEST_CHECK(udata.typeTest()); + TEST_CHECK(!udata.typeTest()); + UserDataTest d = udata; + TEST_EQUAL(d.m, 2); + TEST_EQUAL(last_error_message, ""); + } + { + last_error_message = ""; + UserDataTest udatan(2); + kaguya::LuaUserData udata(state.state(), &udatan); + TEST_CHECK(udata); + UserDataTest *d = udata; // unsafe + TEST_EQUAL(d->m, 2); + + const UserDataTest &dr = udata; // unsafe + TEST_EQUAL(dr.m, 2); + TEST_EQUAL(last_error_message, ""); + + kaguya::LuaFunction f( + state.state(), + kaguya::overload(UserDataTestFunction, UserDataTestFunction2)); + f(udata); + TEST_EQUAL(udatan.m, 5); + } + { + last_error_message = ""; + UserDataTest udatan(2); + kaguya::LuaUserData udata(state.state(), kaguya::standard::ref(udatan)); + TEST_CHECK(udata); + UserDataTest *d = udata; // unsafe + TEST_EQUAL(d->m, 2); + + const UserDataTest &dr = udata; // unsafe + TEST_EQUAL(dr.m, 2); + TEST_EQUAL(last_error_message, ""); + + kaguya::LuaFunction f( + state.state(), + kaguya::overload(UserDataTestFunction, UserDataTestFunction2)); + f(udata); + TEST_EQUAL(udatan.m, 5); + } } KAGUYA_TEST_GROUP_END(test_05_lua_ref) diff --git a/test/test_06_state.cpp b/test/test_06_state.cpp index ba63fcb..ff7dd8e 100644 --- a/test/test_06_state.cpp +++ b/test/test_06_state.cpp @@ -5,158 +5,144 @@ KAGUYA_TEST_GROUP_START(test_06_state) using namespace kaguya_test_util; - int error_count = 0; std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; - error_count++; +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; + error_count++; } -KAGUYA_TEST_FUNCTION_DEF(set_error_function)(kaguya::State& state) -{ - error_count = 0; - state.setErrorHandler(ignore_error_fun); - TEST_CHECK(!state("awdorgkwl;gw")); +KAGUYA_TEST_FUNCTION_DEF(set_error_function)(kaguya::State &state) { + error_count = 0; + state.setErrorHandler(ignore_error_fun); + TEST_CHECK(!state("awdorgkwl;gw")); - TEST_CHECK(error_count == 1); - state["yy"]["yy"]["yy"](); - TEST_CHECK(error_count > 0); + TEST_CHECK(error_count == 1); + state["yy"]["yy"]["yy"](); + TEST_CHECK(error_count > 0); } -KAGUYA_TEST_FUNCTION_DEF(function_call_error)(kaguya::State& state) -{ - error_count = 0; - state.setErrorHandler(ignore_error_fun); +KAGUYA_TEST_FUNCTION_DEF(function_call_error)(kaguya::State &state) { + error_count = 0; + state.setErrorHandler(ignore_error_fun); - state["errofun"] = kaguya::function(ignore_error_fun); - state["errofun"](33); + state["errofun"] = kaguya::function(ignore_error_fun); + state["errofun"](33); - TEST_CHECK(error_count == 1); + TEST_CHECK(error_count == 1); - kaguya::LuaRef f; - f.resume(); - f.call(); - TEST_COMPARE_EQ(f.threadStatus(), LUA_ERRRUN); - TEST_COMPARE_EQ(state.newRef(1).threadStatus(), LUA_ERRRUN); + kaguya::LuaRef f; + f.resume(); + f.call(); + TEST_COMPARE_EQ(f.threadStatus(), LUA_ERRRUN); + TEST_COMPARE_EQ(state.newRef(1).threadStatus(), LUA_ERRRUN); } -KAGUYA_TEST_FUNCTION_DEF(other_state)(kaguya::State&) -{ - lua_State* L = luaL_newstate(); +KAGUYA_TEST_FUNCTION_DEF(other_state)(kaguya::State &) { + lua_State *L = luaL_newstate(); - kaguya::State state(L); - kaguya::State state2(L); - kaguya::State state3(L); - kaguya::State state4(L); - kaguya::State state5(L); + kaguya::State state(L); + kaguya::State state2(L); + kaguya::State state3(L); + kaguya::State state4(L); + kaguya::State state5(L); - state5["value"] = 1; - TEST_EQUAL(state["value"], 1); - TEST_EQUAL(state5["value"], state2["value"]); + state5["value"] = 1; + TEST_EQUAL(state["value"], 1); + TEST_EQUAL(state5["value"], state2["value"]); - lua_close(L); + lua_close(L); } -KAGUYA_TEST_FUNCTION_DEF(load_string)(kaguya::State& state) -{ - kaguya::LuaRef luafun = state.loadstring("assert(11 == 11);return true"); - TEST_CHECK(luafun() != false); - state.setErrorHandler(ignore_error_fun); - kaguya::LuaRef errorref = state.loadstring("function() e");//syntax error - TEST_CHECK(!errorref); +KAGUYA_TEST_FUNCTION_DEF(load_string)(kaguya::State &state) { + kaguya::LuaRef luafun = state.loadstring("assert(11 == 11);return true"); + TEST_CHECK(luafun() != false); + state.setErrorHandler(ignore_error_fun); + kaguya::LuaRef errorref = state.loadstring("function() e"); // syntax error + TEST_CHECK(!errorref); } +KAGUYA_TEST_FUNCTION_DEF(load_with_other_env)(kaguya::State &state) { + state.dostring("foo = 'bar'"); -KAGUYA_TEST_FUNCTION_DEF(load_with_other_env)(kaguya::State& state) -{ - state.dostring("foo = 'bar'"); - - state["otherEnv"] = kaguya::NewTable(); + state["otherEnv"] = kaguya::NewTable(); - state.dostring("foo = 'dar'", state["otherEnv"]); + state.dostring("foo = 'dar'", state["otherEnv"]); - TEST_CHECK(state("assert(foo == 'bar')")); + TEST_CHECK(state("assert(foo == 'bar')")); - TEST_CHECK(state("assert(otherEnv.foo == 'dar')")); + TEST_CHECK(state("assert(otherEnv.foo == 'dar')")); - - std::stringstream sstream; - sstream << "foo = 'beer'"; - TEST_CHECK(state.dostream(sstream, "streamchunk", state["otherEnv"])); - TEST_CHECK(state("assert(foo == 'bar')")); - TEST_CHECK(state("assert(otherEnv.foo == 'beer')")); + std::stringstream sstream; + sstream << "foo = 'beer'"; + TEST_CHECK(state.dostream(sstream, "streamchunk", state["otherEnv"])); + TEST_CHECK(state("assert(foo == 'bar')")); + TEST_CHECK(state("assert(otherEnv.foo == 'beer')")); } -KAGUYA_TEST_FUNCTION_DEF(no_standard_lib)(kaguya::State&) -{ - kaguya::State state(kaguya::NoLoadLib()); - state.setErrorHandler(ignore_error_fun); - TEST_CHECK(!state("assert(true)"));//can not call assert +KAGUYA_TEST_FUNCTION_DEF(no_standard_lib)(kaguya::State &) { + kaguya::State state(kaguya::NoLoadLib()); + state.setErrorHandler(ignore_error_fun); + TEST_CHECK(!state("assert(true)")); // can not call assert } -KAGUYA_TEST_FUNCTION_DEF(load_all_library)(kaguya::State&) -{ - kaguya::State state(kaguya::NoLoadLib()); - state.openlibs(); - - TEST_CHECK(state("assert(true)"));// - TEST_CHECK(state("assert(load)"));// - TEST_CHECK(state("assert(coroutine)")); - TEST_CHECK(state("assert(debug)"));// - TEST_CHECK(state("assert(io)"));// - TEST_CHECK(state("assert(math)"));// - TEST_CHECK(state("assert(os)"));// - TEST_CHECK(state("assert(package)"));// - TEST_CHECK(state("assert(string)"));// - TEST_CHECK(state("assert(table)"));// +KAGUYA_TEST_FUNCTION_DEF(load_all_library)(kaguya::State &) { + kaguya::State state(kaguya::NoLoadLib()); + state.openlibs(); + + TEST_CHECK(state("assert(true)")); // + TEST_CHECK(state("assert(load)")); // + TEST_CHECK(state("assert(coroutine)")); + TEST_CHECK(state("assert(debug)")); // + TEST_CHECK(state("assert(io)")); // + TEST_CHECK(state("assert(math)")); // + TEST_CHECK(state("assert(os)")); // + TEST_CHECK(state("assert(package)")); // + TEST_CHECK(state("assert(string)")); // + TEST_CHECK(state("assert(table)")); // } -int lua_mylibf(lua_State* L) -{ - kaguya::State state(L); - kaguya::LuaTable t = state.newTable(); - t["value"] = 111; - return t.push(); +int lua_mylibf(lua_State *L) { + kaguya::State state(L); + kaguya::LuaTable t = state.newTable(); + t["value"] = 111; + return t.push(); } -KAGUYA_TEST_FUNCTION_DEF(load_my_library)(kaguya::State& state) -{ - state.openlib(kaguya::LoadLib("mylib",lua_mylibf)); - TEST_CHECK(state("assert(mylib.value == 111)")); +KAGUYA_TEST_FUNCTION_DEF(load_my_library)(kaguya::State &state) { + state.openlib(kaguya::LoadLib("mylib", lua_mylibf)); + TEST_CHECK(state("assert(mylib.value == 111)")); } -KAGUYA_TEST_FUNCTION_DEF(load_lib_constructor)(kaguya::State&) -{ - { - kaguya::LoadLibs libs; - libs.push_back(kaguya::LoadLib("_G", luaopen_base)); - libs.push_back(kaguya::LoadLib(LUA_MATHLIBNAME, luaopen_math)); - - kaguya::State state(libs); - TEST_CHECK(state("assert(true)")); - TEST_CHECK(state("assert(math.abs(-2) == 2)")); - TEST_CHECK(lua_gettop(state.state()) == 0);//leak check - } -#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER>=1800) - {//use c++11 initializer list - kaguya::State state({ { "_G", luaopen_base },{ LUA_MATHLIBNAME, luaopen_math } }); - TEST_CHECK(state("assert(true)")); - TEST_CHECK(state("assert(math.abs(-2) == 2)")); - - TEST_CHECK(lua_gettop(state.state()) == 0);//leak check - } +KAGUYA_TEST_FUNCTION_DEF(load_lib_constructor)(kaguya::State &) { + { + kaguya::LoadLibs libs; + libs.push_back(kaguya::LoadLib("_G", luaopen_base)); + libs.push_back(kaguya::LoadLib(LUA_MATHLIBNAME, luaopen_math)); + + kaguya::State state(libs); + TEST_CHECK(state("assert(true)")); + TEST_CHECK(state("assert(math.abs(-2) == 2)")); + TEST_CHECK(lua_gettop(state.state()) == 0); // leak check + } +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) + { // use c++11 initializer list + kaguya::State state( + {{"_G", luaopen_base}, {LUA_MATHLIBNAME, luaopen_math}}); + TEST_CHECK(state("assert(true)")); + TEST_CHECK(state("assert(math.abs(-2) == 2)")); + + TEST_CHECK(lua_gettop(state.state()) == 0); // leak check + } #endif } bool errorOccurred = false; std::string lastMsg; -void registerError(int status, const char* message) -{ - KAGUYA_UNUSED(status); - if (errorOccurred) - throw std::runtime_error("Should have reset errorOccurred"); - errorOccurred = true; - lastMsg = message; +void registerError(int status, const char *message) { + KAGUYA_UNUSED(status); + if (errorOccurred) + throw std::runtime_error("Should have reset errorOccurred"); + errorOccurred = true; + lastMsg = message; } struct Foo {}; @@ -166,433 +152,380 @@ void foobar2(int, int) {} void foobar3(int, Foo, int) {} void foobar4(std::string) { throw 3; } -KAGUYA_TEST_FUNCTION_DEF(errorThrowing)(kaguya::State& state) -{ - using kaguya::util::pretty_name; - state["foobar"] = kaguya::overload(foobar1, foobar2, foobar3, foobar4); - state["Foo"].setClass(kaguya::UserdataMetatable().setConstructors()); - state.setErrorHandler(registerError); - TEST_CHECK(!state("foobar()")); - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("candidate is:") != std::string::npos); - lastMsg = lastMsg.substr(lastMsg.find("candidate is:\n")); - lastMsg = lastMsg.substr(0, lastMsg.find("stack ")); - std::vector parts = remove_empty(split(lastMsg, '\n')); - TEST_EQUAL(parts.size(), 5); - std::string intName = pretty_name(typeid(int)); - TEST_CHECK(parts[1].find(intName) != std::string::npos); - TEST_CHECK(parts[2].find(intName + "," + intName) != std::string::npos); - TEST_CHECK(parts[3].find(intName + "," + pretty_name(typeid(Foo)) + "," + intName) != std::string::npos); - TEST_CHECK(parts[4].find(pretty_name(typeid(std::string))) != std::string::npos); - - errorOccurred = false; - TEST_CHECK(!state("foobar(Foo.new(), 1, 1)")); - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("candidate is:") != std::string::npos); - - errorOccurred = false; - TEST_CHECK(!state("foobar(1)")); - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("MyRuntimeError") != std::string::npos); - - - errorOccurred = false; - TEST_CHECK(!state("foobar('test')")); - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("Unknown") != std::string::npos); - - { - std::stringstream sstream; - sstream << "foobar(1)"; - errorOccurred = false; - TEST_CHECK(!state.dostream(sstream, "streamchunk")); - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("MyRuntimeError") != std::string::npos); - } +KAGUYA_TEST_FUNCTION_DEF(errorThrowing)(kaguya::State &state) { + using kaguya::util::pretty_name; + state["foobar"] = kaguya::overload(foobar1, foobar2, foobar3, foobar4); + state["Foo"].setClass( + kaguya::UserdataMetatable().setConstructors()); + state.setErrorHandler(registerError); + TEST_CHECK(!state("foobar()")); + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("candidate is:") != std::string::npos); + lastMsg = lastMsg.substr(lastMsg.find("candidate is:\n")); + lastMsg = lastMsg.substr(0, lastMsg.find("stack ")); + std::vector parts = remove_empty(split(lastMsg, '\n')); + TEST_EQUAL(parts.size(), 5); + std::string intName = pretty_name(typeid(int)); + TEST_CHECK(parts[1].find(intName) != std::string::npos); + TEST_CHECK(parts[2].find(intName + "," + intName) != std::string::npos); + TEST_CHECK(parts[3].find(intName + "," + pretty_name(typeid(Foo)) + "," + + intName) != std::string::npos); + TEST_CHECK(parts[4].find(pretty_name(typeid(std::string))) != + std::string::npos); + + errorOccurred = false; + TEST_CHECK(!state("foobar(Foo.new(), 1, 1)")); + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("candidate is:") != std::string::npos); + + errorOccurred = false; + TEST_CHECK(!state("foobar(1)")); + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("MyRuntimeError") != std::string::npos); + + errorOccurred = false; + TEST_CHECK(!state("foobar('test')")); + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("Unknown") != std::string::npos); + + { + std::stringstream sstream; + sstream << "foobar(1)"; + errorOccurred = false; + TEST_CHECK(!state.dostream(sstream, "streamchunk")); + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("MyRuntimeError") != std::string::npos); + } #ifndef KAGUYA_NO_STD_MAP_TO_TABLE - errorOccurred = false; - state["noTable"] = 5; - std::map map = state["noTable"]; - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("type mismatch") != std::string::npos); - - errorOccurred = false; - state["noTable"] = 5; - std::vector vec = state["noTable"]; - TEST_EQUAL(errorOccurred, true); - TEST_CHECK(lastMsg.find("type mismatch") != std::string::npos); + errorOccurred = false; + state["noTable"] = 5; + std::map map = state["noTable"]; + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("type mismatch") != std::string::npos); + + errorOccurred = false; + state["noTable"] = 5; + std::vector vec = state["noTable"]; + TEST_EQUAL(errorOccurred, true); + TEST_CHECK(lastMsg.find("type mismatch") != std::string::npos); #endif } - -KAGUYA_TEST_FUNCTION_DEF(load_from_stream)(kaguya::State& state) -{ - state("value=nil"); - { - std::stringstream sstream; - sstream << "value=true"; - TEST_CHECK(state.dostream(sstream, "streamchunk")); - TEST_EQUAL(state["value"], true); - } - - state("value=nil"); - {//BOM - std::stringstream sstream; - sstream << "\xEF\xBB\xBFvalue=true"; - TEST_CHECK(state.dostream(sstream, "streamchunk")); - TEST_EQUAL(state["value"], true); - } - - - state("value=nil"); - {//comment - std::stringstream sstream; - sstream << "#/bin/lua\n" - "value=true"; - TEST_CHECK(state.dostream(sstream, "streamchunk")); - TEST_EQUAL(state["value"], true); - } - - state("value=nil"); - {//short comment - std::stringstream sstream; - sstream << "#\n" - "value=true"; - TEST_CHECK(state.dostream(sstream, "streamchunk")); - TEST_EQUAL(state["value"], true); - } - state("value=nil"); - { - std::stringstream sstream; - sstream << "value=true"; - TEST_CHECK(state.dostream(sstream)); - TEST_EQUAL(state["value"], true); - } - state("value=nil"); - { - std::stringstream sstream; - sstream << "value=true"; - state.loadstream(sstream)();//loadstream and execute - TEST_EQUAL(state["value"], true); - } - state("value=nil"); - { - std::stringstream sstream; - sstream << "value=true"; - state.loadstream(sstream, "streamchunk")();//loadstream and execute with chunkname - TEST_EQUAL(state["value"], true); - } - state("value=nil"); - { - kaguya::LuaTable env = state.newTable(); - std::stringstream sstream; - sstream << "value=true"; - TEST_CHECK(state.dostream(sstream, "streamchunk", env));//dostream with chunkname and function env - TEST_CHECK(!state["value"]); - TEST_EQUAL(env["value"], true); - } +KAGUYA_TEST_FUNCTION_DEF(load_from_stream)(kaguya::State &state) { + state("value=nil"); + { + std::stringstream sstream; + sstream << "value=true"; + TEST_CHECK(state.dostream(sstream, "streamchunk")); + TEST_EQUAL(state["value"], true); + } + + state("value=nil"); + { // BOM + std::stringstream sstream; + sstream << "\xEF\xBB\xBFvalue=true"; + TEST_CHECK(state.dostream(sstream, "streamchunk")); + TEST_EQUAL(state["value"], true); + } + + state("value=nil"); + { // comment + std::stringstream sstream; + sstream << "#/bin/lua\n" + "value=true"; + TEST_CHECK(state.dostream(sstream, "streamchunk")); + TEST_EQUAL(state["value"], true); + } + + state("value=nil"); + { // short comment + std::stringstream sstream; + sstream << "#\n" + "value=true"; + TEST_CHECK(state.dostream(sstream, "streamchunk")); + TEST_EQUAL(state["value"], true); + } + state("value=nil"); + { + std::stringstream sstream; + sstream << "value=true"; + TEST_CHECK(state.dostream(sstream)); + TEST_EQUAL(state["value"], true); + } + state("value=nil"); + { + std::stringstream sstream; + sstream << "value=true"; + state.loadstream(sstream)(); // loadstream and execute + TEST_EQUAL(state["value"], true); + } + state("value=nil"); + { + std::stringstream sstream; + sstream << "value=true"; + state.loadstream(sstream, + "streamchunk")(); // loadstream and execute with chunkname + TEST_EQUAL(state["value"], true); + } + state("value=nil"); + { + kaguya::LuaTable env = state.newTable(); + std::stringstream sstream; + sstream << "value=true"; + TEST_CHECK(state.dostream(sstream, "streamchunk", + env)); // dostream with chunkname and function env + TEST_CHECK(!state["value"]); + TEST_EQUAL(env["value"], true); + } } +struct CountLimitAllocator { + typedef void *pointer; + typedef size_t size_type; + size_type allocated_count; + size_type allocate_limit; + size_type allocate_block_max_size; + CountLimitAllocator() + : allocated_count(0), allocate_limit(0), allocate_block_max_size(0) {} + CountLimitAllocator(size_type limit) + : allocated_count(0), allocate_limit(limit), allocate_block_max_size(0) {} + CountLimitAllocator(size_type limit, size_type blockmax) + : allocated_count(0), allocate_limit(limit), + allocate_block_max_size(blockmax) {} + pointer allocate(size_type n) { + if (allocate_limit != 0 && allocate_limit < allocated_count) { + return 0; + } + if (allocate_block_max_size != 0 && allocate_block_max_size < n) { + return 0; + } + allocated_count++; + return std::malloc(n); + } + pointer reallocate(pointer p, size_type n) { + if (allocate_block_max_size != 0 && allocate_block_max_size < n) { + return 0; + } + return std::realloc(p, n); + } + void deallocate(pointer p, size_type n) { + KAGUYA_UNUSED(n); + if (p) { + allocated_count--; + } + std::free(p); + } +}; - -struct CountLimitAllocator -{ - typedef void* pointer; - typedef size_t size_type; - size_type allocated_count; - size_type allocate_limit; - size_type allocate_block_max_size; - CountLimitAllocator() :allocated_count(0), allocate_limit(0), allocate_block_max_size(0) {} - CountLimitAllocator(size_type limit) :allocated_count(0), allocate_limit(limit), allocate_block_max_size(0) {} - CountLimitAllocator(size_type limit, size_type blockmax) :allocated_count(0), allocate_limit(limit), allocate_block_max_size(blockmax) {} - pointer allocate(size_type n) - { - if (allocate_limit != 0 && allocate_limit < allocated_count) - { - return 0; - } - if (allocate_block_max_size != 0 && allocate_block_max_size < n) - { - return 0; - } - allocated_count++; - return std::malloc(n); - } - pointer reallocate(pointer p, size_type n) - { - if (allocate_block_max_size != 0 && allocate_block_max_size < n) - { - return 0; - } - return std::realloc(p, n); - } - void deallocate(pointer p, size_type n) - { - KAGUYA_UNUSED(n); - if (p) - { - allocated_count--; - } - std::free(p); - } +struct alloctest { + int data; }; -struct alloctest { int data; }; - -KAGUYA_TEST_FUNCTION_DEF(allocator_test)(kaguya::State&) -{ - kaguya::standard::shared_ptr allocator(new CountLimitAllocator); - { - kaguya::State state(allocator); - if (!state.state()) - { //can not use allocator e.g. using luajit - return; - } - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - state("a='abc'"); - state["data"] = alloctest(); - TEST_CHECK(allocator->allocated_count > 0); - } - - TEST_CHECK(allocator->allocated_count == 0); +KAGUYA_TEST_FUNCTION_DEF(allocator_test)(kaguya::State &) { + kaguya::standard::shared_ptr allocator( + new CountLimitAllocator); + { + kaguya::State state(allocator); + if (!state.state()) { // can not use allocator e.g. using luajit + return; + } + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + state("a='abc'"); + state["data"] = alloctest(); + TEST_CHECK(allocator->allocated_count > 0); + } + + TEST_CHECK(allocator->allocated_count == 0); } - -KAGUYA_TEST_FUNCTION_DEF(allocation_error_test)(kaguya::State&) -{ - for (size_t alloclimit = 32; alloclimit < 512; ++alloclimit) - { - kaguya::standard::shared_ptr allocator(new CountLimitAllocator(alloclimit)); - kaguya::State state(allocator); - if (!state.state()) - { //can not use allocator e.g. using luajit - continue; - } - try - { - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - - state["Foo"].setClass(kaguya::UserdataMetatable().setConstructors()); - - state["data"] = kaguya::NewTable(); - Foo foodata; - for (size_t i = 0; i < alloclimit; ++i) - { - state("data[" + to_string(i) + "] ='abc'"); - state["data"][i + alloclimit * 2] = alloctest(); - state["data"][i + alloclimit * 3] = 1; - state["data"][i + alloclimit * 4] = "str"; - state["data"][i + alloclimit * 5] = foodata;//copy - state["data"][i + alloclimit * 6] = &foodata;//ptr - } - } - catch (const kaguya::LuaMemoryError&) - { - continue; - } - TEST_CHECK(false); - } +KAGUYA_TEST_FUNCTION_DEF(allocation_error_test)(kaguya::State &) { + for (size_t alloclimit = 32; alloclimit < 512; ++alloclimit) { + kaguya::standard::shared_ptr allocator( + new CountLimitAllocator(alloclimit)); + kaguya::State state(allocator); + if (!state.state()) { // can not use allocator e.g. using luajit + continue; + } + try { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + + state["Foo"].setClass( + kaguya::UserdataMetatable().setConstructors()); + + state["data"] = kaguya::NewTable(); + Foo foodata; + for (size_t i = 0; i < alloclimit; ++i) { + state("data[" + to_string(i) + "] ='abc'"); + state["data"][i + alloclimit * 2] = alloctest(); + state["data"][i + alloclimit * 3] = 1; + state["data"][i + alloclimit * 4] = "str"; + state["data"][i + alloclimit * 5] = foodata; // copy + state["data"][i + alloclimit * 6] = &foodata; // ptr + } + } catch (const kaguya::LuaMemoryError &) { + continue; + } + TEST_CHECK(false); + } } - - -KAGUYA_TEST_FUNCTION_DEF(syntax_error_throw_test)(kaguya::State& state) -{ - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - bool catch_except = false; - try - { - state("tes terror");//syntax_error - } - catch (const kaguya::LuaSyntaxError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("terror") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - - catch_except = false; - try - { - std::stringstream sstream; - sstream << "tes terror"; - state.loadstream(sstream)();//syntax_error - } - catch (const kaguya::LuaSyntaxError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("terror") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(syntax_error_throw_test)(kaguya::State &state) { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + bool catch_except = false; + try { + state("tes terror"); // syntax_error + } catch (const kaguya::LuaSyntaxError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("terror") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + + catch_except = false; + try { + std::stringstream sstream; + sstream << "tes terror"; + state.loadstream(sstream)(); // syntax_error + } catch (const kaguya::LuaSyntaxError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("terror") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } -KAGUYA_TEST_FUNCTION_DEF(running_error_throw_test)(kaguya::State& state) -{ - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - bool catch_except = false; - try - { - state("error('error message')");//error - } - catch (const kaguya::LuaRuntimeError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("error message") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(running_error_throw_test)(kaguya::State &state) { + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + bool catch_except = false; + try { + state("error('error message')"); // error + } catch (const kaguya::LuaRuntimeError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("error message") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } -void throwUnknownError(int status, const char* message) -{ - KAGUYA_UNUSED(status); - KAGUYA_UNUSED(message); - kaguya::ErrorHandler::throwDefaultError(32323232, "unknown error"); +void throwUnknownError(int status, const char *message) { + KAGUYA_UNUSED(status); + KAGUYA_UNUSED(message); + kaguya::ErrorHandler::throwDefaultError(32323232, "unknown error"); } -KAGUYA_TEST_FUNCTION_DEF(unknown_error_throw_test)(kaguya::State& state) -{ - state.setErrorHandler(throwUnknownError); - bool catch_except = false; - try - { - state("error('')");//error - } - catch (const kaguya::LuaUnknownError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("unknown error") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(unknown_error_throw_test)(kaguya::State &state) { + state.setErrorHandler(throwUnknownError); + bool catch_except = false; + try { + state("error('')"); // error + } catch (const kaguya::LuaUnknownError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("unknown error") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } -void throwErrorRunningError(int status, const char* message) -{ - KAGUYA_UNUSED(status); - KAGUYA_UNUSED(message); - throw kaguya::LuaErrorRunningError(LUA_ERRERR, "error handler error"); +void throwErrorRunningError(int status, const char *message) { + KAGUYA_UNUSED(status); + KAGUYA_UNUSED(message); + throw kaguya::LuaErrorRunningError(LUA_ERRERR, "error handler error"); } -void throwErrorRunningError2(int status, const char* message) -{ - KAGUYA_UNUSED(status); - KAGUYA_UNUSED(message); - throw kaguya::LuaErrorRunningError(LUA_ERRERR, std::string("error handler error")); +void throwErrorRunningError2(int status, const char *message) { + KAGUYA_UNUSED(status); + KAGUYA_UNUSED(message); + throw kaguya::LuaErrorRunningError(LUA_ERRERR, + std::string("error handler error")); } -KAGUYA_TEST_FUNCTION_DEF(errorrunning_error_throw_test)(kaguya::State& state) -{ - state.setErrorHandler(throwErrorRunningError); - bool catch_except = false; - try - { - state("error('')");//error - } - catch (const kaguya::LuaErrorRunningError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("error handler error") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); - - state.setErrorHandler(throwErrorRunningError2); - catch_except = false; - try - { - state("error('')");//error - } - catch (const kaguya::LuaErrorRunningError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("error handler error") != std::string::npos); - catch_except = true; - } +KAGUYA_TEST_FUNCTION_DEF(errorrunning_error_throw_test)(kaguya::State &state) { + state.setErrorHandler(throwErrorRunningError); + bool catch_except = false; + try { + state("error('')"); // error + } catch (const kaguya::LuaErrorRunningError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("error handler error") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); + + state.setErrorHandler(throwErrorRunningError2); + catch_except = false; + try { + state("error('')"); // error + } catch (const kaguya::LuaErrorRunningError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("error handler error") != std::string::npos); + catch_except = true; + } } +KAGUYA_TEST_FUNCTION_DEF(this_typemismatch_error_test)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); - -KAGUYA_TEST_FUNCTION_DEF(this_typemismatch_error_test)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - { - last_error_message = ""; - std::stringstream sstream; - sstream << "=true"; - TEST_CHECK(!state.dostream(sstream, "streamchunk")); - TEST_CHECK(last_error_message.find("streamchunk") != std::string::npos); - } + { + last_error_message = ""; + std::stringstream sstream; + sstream << "=true"; + TEST_CHECK(!state.dostream(sstream, "streamchunk")); + TEST_CHECK(last_error_message.find("streamchunk") != std::string::npos); + } } - - #if LUA_VERSION_NUM >= 502 -KAGUYA_TEST_FUNCTION_DEF(gc_error_throw_test)(kaguya::State&) -{ - bool catch_except = false; - try - { - kaguya::State state; - state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); - - state("testtable ={}" - "meta ={__gc=function() error('gc error') end}" - "setmetatable(testtable,meta)" - "testtable={}" - ); - state.gc().collect(); - } - catch (const kaguya::LuaGCError& e) - { - std::string errormessage(e.what()); - TEST_CHECK(errormessage.find("gc error") != std::string::npos); - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(gc_error_throw_test)(kaguya::State &) { + bool catch_except = false; + try { + kaguya::State state; + state.setErrorHandler(kaguya::ErrorHandler::throwDefaultError); + + state("testtable ={}" + "meta ={__gc=function() error('gc error') end}" + "setmetatable(testtable,meta)" + "testtable={}"); + state.gc().collect(); + } catch (const kaguya::LuaGCError &e) { + std::string errormessage(e.what()); + TEST_CHECK(errormessage.find("gc error") != std::string::npos); + catch_except = true; + } + TEST_CHECK(catch_except); } #endif - -KAGUYA_TEST_FUNCTION_DEF(full_gc_test)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - int used = state.gc().count(); - int first = used; - state.gc().disable(); - for (int i = 0; i < 1000; i++) - { - state["a"] = kaguya::NewTable(i, i); - TEST_COMPARE_LE(used, state.gc().count()); - used = state.gc().count(); - } - state.gc().enable(); - state["a"] = kaguya::NilValue(); - state.gc().collect(); - int current = state.gc().count(); - TEST_COMPARE_GT(used, current); - TEST_COMPARE_GE(first, current); +KAGUYA_TEST_FUNCTION_DEF(full_gc_test)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + int used = state.gc().count(); + int first = used; + state.gc().disable(); + for (int i = 0; i < 1000; i++) { + state["a"] = kaguya::NewTable(i, i); + TEST_COMPARE_LE(used, state.gc().count()); + used = state.gc().count(); + } + state.gc().enable(); + state["a"] = kaguya::NilValue(); + state.gc().collect(); + int current = state.gc().count(); + TEST_COMPARE_GT(used, current); + TEST_COMPARE_GE(first, current); } -KAGUYA_TEST_FUNCTION_DEF(inc_gc_test)(kaguya::State& state) -{ - state.setErrorHandler(ignore_error_fun); - - int used = state.gc().count(); - int peak = 0; - for (int i = 0; i < 1000; i++) - { - state["a"] = kaguya::NewTable(i, i); - used = state.gc().count(); - peak = std::max(peak, used); - } - TEST_COMPARE_LT(peak, 1500); +KAGUYA_TEST_FUNCTION_DEF(inc_gc_test)(kaguya::State &state) { + state.setErrorHandler(ignore_error_fun); + + int used = state.gc().count(); + int peak = 0; + for (int i = 0; i < 1000; i++) { + state["a"] = kaguya::NewTable(i, i); + used = state.gc().count(); + peak = std::max(peak, used); + } + TEST_COMPARE_LT(peak, 1500); } -KAGUYA_TEST_FUNCTION_DEF(defailt_error_handler)(kaguya::State&) -{ - kaguya::State state; - state("a"); +KAGUYA_TEST_FUNCTION_DEF(defailt_error_handler)(kaguya::State &) { + kaguya::State state; + state("a"); } KAGUYA_TEST_GROUP_END(test_06_state) diff --git a/test/test_07_vector_map_to_luatable.cpp b/test/test_07_vector_map_to_luatable.cpp index 54b661f..f12aa61 100644 --- a/test/test_07_vector_map_to_luatable.cpp +++ b/test/test_07_vector_map_to_luatable.cpp @@ -3,148 +3,143 @@ KAGUYA_TEST_GROUP_START(test_07_vector_map_to_luatable) - #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE -KAGUYA_TEST_FUNCTION_DEF(vector_from_table)(kaguya::State& state) -{ - state("arraytablefn =function() return {32,1,2,4,8,16} end"); - std::vector b = state["arraytablefn"](); - TEST_EQUAL(b.size(), 6); - TEST_EQUAL(b[0], 32); - TEST_EQUAL(b[1], 1); - TEST_EQUAL(b[2], 2); - TEST_EQUAL(b[3], 4); - TEST_EQUAL(b[4], 8); - TEST_EQUAL(b[5], 16); - TEST_CHECK(state["arraytablefn"]().typeTest >()); +KAGUYA_TEST_FUNCTION_DEF(vector_from_table)(kaguya::State &state) { + state("arraytablefn =function() return {32,1,2,4,8,16} end"); + std::vector b = state["arraytablefn"](); + TEST_EQUAL(b.size(), 6); + TEST_EQUAL(b[0], 32); + TEST_EQUAL(b[1], 1); + TEST_EQUAL(b[2], 2); + TEST_EQUAL(b[3], 4); + TEST_EQUAL(b[4], 8); + TEST_EQUAL(b[5], 16); + TEST_CHECK(state["arraytablefn"]().typeTest >()); } -KAGUYA_TEST_FUNCTION_DEF(vector_to_table)(kaguya::State& state) -{ - std::vector v; v.push_back(3); v.push_back(13); v.push_back(2); v.push_back(99); - state["v"] = v; - TEST_CHECK(state("assert(v[1] == 3 and v[2] == 13 and v[3] == 2 and v[4] == 99)")); +KAGUYA_TEST_FUNCTION_DEF(vector_to_table)(kaguya::State &state) { + std::vector v; + v.push_back(3); + v.push_back(13); + v.push_back(2); + v.push_back(99); + state["v"] = v; + TEST_CHECK( + state("assert(v[1] == 3 and v[2] == 13 and v[3] == 2 and v[4] == 99)")); } -KAGUYA_TEST_FUNCTION_DEF(vector_bool_from_table)(kaguya::State& state) -{ - state("arraytablefn =function() return {true,false,false,true,false,true} end"); - std::vector b = state["arraytablefn"](); - TEST_EQUAL(b.size(), 6); - TEST_EQUAL(b[0], true); - TEST_EQUAL(b[1], false); - TEST_EQUAL(b[2], false); - TEST_EQUAL(b[3], true); - TEST_EQUAL(b[4], false); - TEST_EQUAL(b[5], true); - TEST_CHECK(state["arraytablefn"]().typeTest >()); +KAGUYA_TEST_FUNCTION_DEF(vector_bool_from_table)(kaguya::State &state) { + state( + "arraytablefn =function() return {true,false,false,true,false,true} end"); + std::vector b = state["arraytablefn"](); + TEST_EQUAL(b.size(), 6); + TEST_EQUAL(b[0], true); + TEST_EQUAL(b[1], false); + TEST_EQUAL(b[2], false); + TEST_EQUAL(b[3], true); + TEST_EQUAL(b[4], false); + TEST_EQUAL(b[5], true); + TEST_CHECK(state["arraytablefn"]().typeTest >()); } -KAGUYA_TEST_FUNCTION_DEF(vector_bool_to_table)(kaguya::State& state) -{ - std::vector v; v.push_back(true); v.push_back(false); v.push_back(false); v.push_back(true); - state["v"] = v; - TEST_CHECK(state("assert(v[1] == true and v[2] == false and v[3] == false and v[4] == true)")); +KAGUYA_TEST_FUNCTION_DEF(vector_bool_to_table)(kaguya::State &state) { + std::vector v; + v.push_back(true); + v.push_back(false); + v.push_back(false); + v.push_back(true); + state["v"] = v; + TEST_CHECK(state("assert(v[1] == true and v[2] == false and v[3] == false " + "and v[4] == true)")); } #endif #ifndef KAGUYA_NO_STD_MAP_TO_TABLE - -KAGUYA_TEST_FUNCTION_DEF(map_from_table)(kaguya::State& state) -{ - state("tablefn =function() return {a=32,b=1,c=2} end"); - std::map m = state["tablefn"](); - - TEST_EQUAL(m["a"], 32); - TEST_EQUAL(m["b"], 1); - TEST_EQUAL(m["c"], 2); - - kaguya::LuaRef t = state["tablefn"](); - TEST_CHECK(!t.isType >()); - bool r = t.isType >(); - TEST_CHECK(r); - r = t.isType >(); - TEST_CHECK(r); - r = t.isConvertible >(); - TEST_CHECK(r); +KAGUYA_TEST_FUNCTION_DEF(map_from_table)(kaguya::State &state) { + state("tablefn =function() return {a=32,b=1,c=2} end"); + std::map m = state["tablefn"](); + + TEST_EQUAL(m["a"], 32); + TEST_EQUAL(m["b"], 1); + TEST_EQUAL(m["c"], 2); + + kaguya::LuaRef t = state["tablefn"](); + TEST_CHECK(!t.isType >()); + bool r = t.isType >(); + TEST_CHECK(r); + r = t.isType >(); + TEST_CHECK(r); + r = t.isConvertible >(); + TEST_CHECK(r); } -KAGUYA_TEST_FUNCTION_DEF(map_to_table)(kaguya::State& state) -{ - std::map m; m["a"] = 4; m["b"] = 32; m["c"] = 24; - state["m"] = m; - TEST_CHECK(state("assert(m['a'] == 4 and m['b'] == 32 and m['c'] == 24)")); - +KAGUYA_TEST_FUNCTION_DEF(map_to_table)(kaguya::State &state) { + std::map m; + m["a"] = 4; + m["b"] = 32; + m["c"] = 24; + state["m"] = m; + TEST_CHECK(state("assert(m['a'] == 4 and m['b'] == 32 and m['c'] == 24)")); } std::map myMap; int myVal; class FooClass { public: - void mapCallback(const std::map& map) - { - myMap = map; - } - void mapOverload() - { - myMap.clear(); - } - void mapOverload(const std::map& map) - { - myMap = map; - } - void mapOverload(const std::map& map, int val) - { - myMap = map; - myVal = val; - } + void mapCallback(const std::map &map) { myMap = map; } + void mapOverload() { myMap.clear(); } + void mapOverload(const std::map &map) { myMap = map; } + void mapOverload(const std::map &map, int val) { + myMap = map; + myVal = val; + } }; -KAGUYA_TEST_FUNCTION_DEF(testWrongClassUseWihMap)(kaguya::State& state) -{ - state["testMap"].setClass(kaguya::UserdataMetatable() - .addFunction("testMap", &FooClass::mapCallback) - .addOverloadedFunctions("mapOverload" - , static_cast(&FooClass::mapOverload) - , static_cast&)>(&FooClass::mapOverload) - , static_cast&, int)>(&FooClass::mapOverload)) - ); - state["foo"] = FooClass(); - state("myMap = {[1] = 2, [3] = 4, [5] = 6}"); - try { - // This uses an invalid function call which should throw an error - state("foo.testMap(myMap)"); - TEST_CHECK(false); - } - catch (std::runtime_error&) - { - } - TEST_CHECK(myMap.empty()); - // This is the correct call - state("foo:testMap(myMap)"); - TEST_EQUAL(myMap[1], 2); - TEST_EQUAL(myMap[3], 4); - TEST_EQUAL(myMap[5], 6); - state("foo:mapOverload()"); - TEST_CHECK(myMap.empty()); - try { - // This uses an invalid function call which should throw an error - state("foo.mapOverload(myMap)"); - TEST_CHECK(false); - } - catch (std::runtime_error&) - { - } - state("foo:mapOverload(myMap)"); - TEST_EQUAL(myMap[1], 2); - TEST_EQUAL(myMap[3], 4); - TEST_EQUAL(myMap[5], 6); - myMap.clear(); - state("foo:mapOverload(myMap, 42)"); - TEST_EQUAL(myMap[1], 2); - TEST_EQUAL(myMap[3], 4); - TEST_EQUAL(myMap[5], 6); - TEST_EQUAL(myVal, 42); +KAGUYA_TEST_FUNCTION_DEF(testWrongClassUseWihMap)(kaguya::State &state) { + state["testMap"].setClass( + kaguya::UserdataMetatable() + .addFunction("testMap", &FooClass::mapCallback) + .addOverloadedFunctions( + "mapOverload", + static_cast(&FooClass::mapOverload), + static_cast &)>( + &FooClass::mapOverload), + static_cast &, int)>( + &FooClass::mapOverload))); + state["foo"] = FooClass(); + state("myMap = {[1] = 2, [3] = 4, [5] = 6}"); + try { + // This uses an invalid function call which should throw an error + state("foo.testMap(myMap)"); + TEST_CHECK(false); + } catch (std::runtime_error &) { + } + TEST_CHECK(myMap.empty()); + // This is the correct call + state("foo:testMap(myMap)"); + TEST_EQUAL(myMap[1], 2); + TEST_EQUAL(myMap[3], 4); + TEST_EQUAL(myMap[5], 6); + state("foo:mapOverload()"); + TEST_CHECK(myMap.empty()); + try { + // This uses an invalid function call which should throw an error + state("foo.mapOverload(myMap)"); + TEST_CHECK(false); + } catch (std::runtime_error &) { + } + state("foo:mapOverload(myMap)"); + TEST_EQUAL(myMap[1], 2); + TEST_EQUAL(myMap[3], 4); + TEST_EQUAL(myMap[5], 6); + myMap.clear(); + state("foo:mapOverload(myMap, 42)"); + TEST_EQUAL(myMap[1], 2); + TEST_EQUAL(myMap[3], 4); + TEST_EQUAL(myMap[5], 6); + TEST_EQUAL(myVal, 42); } #endif diff --git a/test/test_08_optional.cpp b/test/test_08_optional.cpp index c877f3c..18a3d6b 100644 --- a/test/test_08_optional.cpp +++ b/test/test_08_optional.cpp @@ -4,294 +4,257 @@ KAGUYA_TEST_GROUP_START(test_08_optional) using namespace kaguya_test_util; -KAGUYA_TEST_FUNCTION_DEF(optional_construct)(kaguya::State&) -{ - kaguya::optional opt1 = 1; - TEST_EQUAL(1, *opt1); +KAGUYA_TEST_FUNCTION_DEF(optional_construct)(kaguya::State &) { + kaguya::optional opt1 = 1; + TEST_EQUAL(1, *opt1); - kaguya::optional opt2 = std::string("abc"); - TEST_EQUAL("abc", *opt2); + kaguya::optional opt2 = std::string("abc"); + TEST_EQUAL("abc", *opt2); - TEST_EQUAL(std::string("abc"), opt2.value_or("def")); + TEST_EQUAL(std::string("abc"), opt2.value_or("def")); - const kaguya::optional opt3 = opt2; - TEST_EQUAL("abc", *opt2); - TEST_EQUAL("abc", *opt3); - std::string value("data"); - TEST_CHECK(opt2 = value); + const kaguya::optional opt3 = opt2; + TEST_EQUAL("abc", *opt2); + TEST_EQUAL("abc", *opt3); + std::string value("data"); + TEST_CHECK(opt2 = value); } -KAGUYA_TEST_FUNCTION_DEF(optional_copy)(kaguya::State&) -{ - kaguya::optional s1 = "abc", s2; // constructor +KAGUYA_TEST_FUNCTION_DEF(optional_copy)(kaguya::State &) { + kaguya::optional s1 = "abc", s2; // constructor - TEST_EQUAL(std::string("def"), s2.value_or("def")); - TEST_CHECK((s2 = s1)); - TEST_CHECK((s1 = "def")); + TEST_EQUAL(std::string("def"), s2.value_or("def")); + TEST_CHECK((s2 = s1)); + TEST_CHECK((s1 = "def")); - TEST_EQUAL(std::string("def"), s1.value_or("abc")); - TEST_EQUAL(std::string("abc"), s2.value_or("def")); - TEST_CHECK(s1); - TEST_CHECK(s2); - TEST_EQUAL(std::string("abc"), *s2); - TEST_EQUAL(std::string("def"), *s1); + TEST_EQUAL(std::string("def"), s1.value_or("abc")); + TEST_EQUAL(std::string("abc"), s2.value_or("def")); + TEST_CHECK(s1); + TEST_CHECK(s2); + TEST_EQUAL(std::string("abc"), *s2); + TEST_EQUAL(std::string("def"), *s1); - TEST_CHECK(!(s2 = kaguya::optional())); - TEST_CHECK(!s2); + TEST_CHECK(!(s2 = kaguya::optional())); + TEST_CHECK(!s2); - TEST_CHECK(s2 = s1); - TEST_EQUAL(std::string("def"), *s2); - TEST_CHECK(s2 = "data"); - TEST_EQUAL(std::string("data"), *s2); + TEST_CHECK(s2 = s1); + TEST_EQUAL(std::string("def"), *s2); + TEST_CHECK(s2 = "data"); + TEST_EQUAL(std::string("data"), *s2); + kaguya::optional csnullopt; + TEST_CHECK(!(s2 = csnullopt)); + TEST_CHECK(!(s2 = csnullopt)); + TEST_CHECK(!s2); - kaguya::optional csnullopt; - TEST_CHECK(!(s2 = csnullopt)); - TEST_CHECK(!(s2 = csnullopt)); - TEST_CHECK(!s2); - - - kaguya::nullopt_t nullopt; - TEST_CHECK(!(s2 = nullopt)); - TEST_CHECK(!s2); + kaguya::nullopt_t nullopt; + TEST_CHECK(!(s2 = nullopt)); + TEST_CHECK(!s2); } -KAGUYA_TEST_FUNCTION_DEF(optional_ref)(kaguya::State&) -{ - const std::string& str = "abc"; - kaguya::optional s1 = str; // constructor - TEST_EQUAL(std::string("abc"), *s1); - - TEST_EQUAL(std::string("abc"), s1.value_or("def")); +KAGUYA_TEST_FUNCTION_DEF(optional_ref)(kaguya::State &) { + const std::string &str = "abc"; + kaguya::optional s1 = str; // constructor + TEST_EQUAL(std::string("abc"), *s1); - const kaguya::optional s2 = str; // constructor - TEST_CHECK(s2); - TEST_EQUAL(std::string("abc"), *s2); - TEST_EQUAL(std::string("abc"), s1.value_or("def")); + TEST_EQUAL(std::string("abc"), s1.value_or("def")); + const kaguya::optional s2 = str; // constructor + TEST_CHECK(s2); + TEST_EQUAL(std::string("abc"), *s2); + TEST_EQUAL(std::string("abc"), s1.value_or("def")); - kaguya::optional csnullopt; - TEST_CHECK(!(s1 = csnullopt)); - TEST_CHECK(!s1); + kaguya::optional csnullopt; + TEST_CHECK(!(s1 = csnullopt)); + TEST_CHECK(!s1); - TEST_CHECK(s1 = str); - TEST_CHECK(s1); + TEST_CHECK(s1 = str); + TEST_CHECK(s1); - kaguya::nullopt_t nullopt; - TEST_CHECK(!(s1 = nullopt)); - TEST_CHECK(!s1); + kaguya::nullopt_t nullopt; + TEST_CHECK(!(s1 = nullopt)); + TEST_CHECK(!s1); } - -KAGUYA_TEST_FUNCTION_DEF(optional_value_error)(kaguya::State&) -{ - kaguya::optional s1; - - TEST_CHECK(!s1); - TEST_EQUAL(std::string("def"), s1.value_or("def")); - try - { - s1.value(); - } - catch (const kaguya::bad_optional_access&) - { - return; - } - TEST_CHECK(false); +KAGUYA_TEST_FUNCTION_DEF(optional_value_error)(kaguya::State &) { + kaguya::optional s1; + + TEST_CHECK(!s1); + TEST_EQUAL(std::string("def"), s1.value_or("def")); + try { + s1.value(); + } catch (const kaguya::bad_optional_access &) { + return; + } + TEST_CHECK(false); } -KAGUYA_TEST_FUNCTION_DEF(optional_value_error2)(kaguya::State&) -{ - kaguya::optional s1; - - TEST_CHECK(!s1); - TEST_EQUAL(std::string("def"), s1.value_or("def")); - try - { - s1.value(); - } - catch (const kaguya::bad_optional_access&) - { - return; - } - TEST_CHECK(false); +KAGUYA_TEST_FUNCTION_DEF(optional_value_error2)(kaguya::State &) { + kaguya::optional s1; + + TEST_CHECK(!s1); + TEST_EQUAL(std::string("def"), s1.value_or("def")); + try { + s1.value(); + } catch (const kaguya::bad_optional_access &) { + return; + } + TEST_CHECK(false); } -KAGUYA_TEST_FUNCTION_DEF(optional_value_error3)(kaguya::State&) -{ - const kaguya::optional s1; - - TEST_CHECK(!s1); - TEST_EQUAL(std::string("def"), s1.value_or("def")); - - bool catch_except = false; - try - { - s1.value(); - } - catch (const kaguya::bad_optional_access&) - { - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(optional_value_error3)(kaguya::State &) { + const kaguya::optional s1; + + TEST_CHECK(!s1); + TEST_EQUAL(std::string("def"), s1.value_or("def")); + + bool catch_except = false; + try { + s1.value(); + } catch (const kaguya::bad_optional_access &) { + catch_except = true; + } + TEST_CHECK(catch_except); } -KAGUYA_TEST_FUNCTION_DEF(optional_value_error4)(kaguya::State&) -{ - const kaguya::optional s1; - - TEST_CHECK(!s1); - TEST_EQUAL(std::string("def"), s1.value_or("def")); - bool catch_except = false; - try - { - s1.value(); - } - catch (const kaguya::bad_optional_access&) - { - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(optional_value_error4)(kaguya::State &) { + const kaguya::optional s1; + + TEST_CHECK(!s1); + TEST_EQUAL(std::string("def"), s1.value_or("def")); + bool catch_except = false; + try { + s1.value(); + } catch (const kaguya::bad_optional_access &) { + catch_except = true; + } + TEST_CHECK(catch_except); } #if KAGUYA_USE_CPP11 -struct MoveOnlyClass -{ - MoveOnlyClass(int i) :member(i) {} - int member; - - MoveOnlyClass(MoveOnlyClass&& src) :member(src.member) {} - MoveOnlyClass& operator=(MoveOnlyClass&& src) { - member = src.member; - return *this; - } +struct MoveOnlyClass { + MoveOnlyClass(int i) : member(i) {} + int member; + + MoveOnlyClass(MoveOnlyClass &&src) : member(src.member) {} + MoveOnlyClass &operator=(MoveOnlyClass &&src) { + member = src.member; + return *this; + } + private: - MoveOnlyClass(); - MoveOnlyClass(const MoveOnlyClass&); - MoveOnlyClass& operator=(const MoveOnlyClass&); + MoveOnlyClass(); + MoveOnlyClass(const MoveOnlyClass &); + MoveOnlyClass &operator=(const MoveOnlyClass &); }; -KAGUYA_TEST_FUNCTION_DEF(optional_move)(kaguya::State&) -{ - kaguya::optional s1 = MoveOnlyClass(43); - kaguya::optional s2; // constructor - s2 = std::move(s1); - s1 = MoveOnlyClass(12); - TEST_EQUAL(43, s2->member); - TEST_EQUAL(12, s1->member); +KAGUYA_TEST_FUNCTION_DEF(optional_move)(kaguya::State &) { + kaguya::optional s1 = MoveOnlyClass(43); + kaguya::optional s2; // constructor + s2 = std::move(s1); + s1 = MoveOnlyClass(12); + TEST_EQUAL(43, s2->member); + TEST_EQUAL(12, s1->member); } #endif - - -template -void optional_type_test(const typename kaguya::traits::decay::type& init_value, const typename kaguya::traits::decay::type& other_value) -{ - typedef kaguya::optional test_type; - - test_type init_v_opt(init_value); - test_type other_v_opt(other_value); - test_type nullopt_v_opt; - - - TEST_EQUAL(init_v_opt == other_v_opt, init_value == other_value); - TEST_EQUAL(init_v_opt != other_v_opt, init_value != other_value); - TEST_EQUAL(init_v_opt < other_v_opt, init_value < other_value); - TEST_EQUAL(init_v_opt > other_v_opt, init_value > other_value); - TEST_EQUAL(init_v_opt <= other_v_opt, init_value <= other_value); - TEST_EQUAL(init_v_opt >= other_v_opt, init_value >= other_value); - - TEST_EQUAL(init_v_opt == nullopt_v_opt, false); - TEST_EQUAL(init_v_opt != nullopt_v_opt, true); - TEST_EQUAL(init_v_opt < nullopt_v_opt, false); - TEST_EQUAL(init_v_opt > nullopt_v_opt, true); - TEST_EQUAL(init_v_opt <= nullopt_v_opt, false); - TEST_EQUAL(init_v_opt >= nullopt_v_opt, true); - - TEST_EQUAL(nullopt_v_opt == nullopt_v_opt, true); - TEST_EQUAL(nullopt_v_opt != nullopt_v_opt, false); - TEST_EQUAL(nullopt_v_opt < nullopt_v_opt, false); - TEST_EQUAL(nullopt_v_opt > nullopt_v_opt, false); - TEST_EQUAL(nullopt_v_opt <= nullopt_v_opt, true); - TEST_EQUAL(nullopt_v_opt >= nullopt_v_opt, true); - - test_type opt1 = init_value; - TEST_EQUAL(init_value, opt1.value()); - TEST_EQUAL(init_value, *opt1); - TEST_EQUAL(init_value, opt1.value_or(other_value)); - TEST_CHECK(!(opt1 = nullopt_v_opt)); - TEST_EQUAL(other_value, opt1.value_or(other_value)); - TEST_CHECK(!(opt1 = nullopt_v_opt)); - - opt1 = init_value; - TEST_EQUAL(init_value, opt1.value()); - TEST_EQUAL(init_value, *opt1); - TEST_EQUAL(init_value, opt1.value_or(T(other_value))); - TEST_CHECK(!(opt1 = nullopt_v_opt)); - TEST_EQUAL(other_value, opt1.value_or(T(other_value))); - TEST_CHECK(!(opt1 = nullopt_v_opt)); - - bool except_catch = false; - try - { - opt1.value(); - } - catch (const kaguya::bad_optional_access&) - { - except_catch = true; - } - TEST_CHECK(except_catch); - - TEST_CHECK(opt1 = test_type(init_value)); - TEST_EQUAL(init_value, *opt1); - TEST_CHECK(opt1 = test_type(other_value)); - TEST_EQUAL(other_value, *opt1); - - TEST_CHECK(opt1 = test_type(T(init_value))); - TEST_EQUAL(init_value, *opt1); - TEST_CHECK(opt1 = T(init_value)); - TEST_EQUAL(init_value, *opt1); - - TEST_CHECK(opt1 = init_v_opt); - TEST_EQUAL(init_value, *opt1); - TEST_CHECK(opt1 = other_v_opt); - TEST_EQUAL(other_value, *opt1); - - - TEST_CHECK(opt1 = init_value); - TEST_EQUAL(init_value, *opt1); - TEST_CHECK(opt1 = other_value); - TEST_EQUAL(other_value, *opt1); - - const test_type copt1 = init_value; - TEST_CHECK(copt1); - TEST_EQUAL(init_value, *copt1); - - TEST_EQUAL(init_value, copt1.value_or(other_value)); - - const test_type copt2; - TEST_CHECK(!copt2); - except_catch = false; - try - { - copt2.value(); - } - catch (const kaguya::bad_optional_access&) - { - except_catch = true; - } - TEST_CHECK(except_catch); +template +void optional_type_test( + const typename kaguya::traits::decay::type &init_value, + const typename kaguya::traits::decay::type &other_value) { + typedef kaguya::optional test_type; + + test_type init_v_opt(init_value); + test_type other_v_opt(other_value); + test_type nullopt_v_opt; + + TEST_EQUAL(init_v_opt == other_v_opt, init_value == other_value); + TEST_EQUAL(init_v_opt != other_v_opt, init_value != other_value); + TEST_EQUAL(init_v_opt < other_v_opt, init_value < other_value); + TEST_EQUAL(init_v_opt > other_v_opt, init_value > other_value); + TEST_EQUAL(init_v_opt <= other_v_opt, init_value <= other_value); + TEST_EQUAL(init_v_opt >= other_v_opt, init_value >= other_value); + + TEST_EQUAL(init_v_opt == nullopt_v_opt, false); + TEST_EQUAL(init_v_opt != nullopt_v_opt, true); + TEST_EQUAL(init_v_opt < nullopt_v_opt, false); + TEST_EQUAL(init_v_opt > nullopt_v_opt, true); + TEST_EQUAL(init_v_opt <= nullopt_v_opt, false); + TEST_EQUAL(init_v_opt >= nullopt_v_opt, true); + + TEST_EQUAL(nullopt_v_opt == nullopt_v_opt, true); + TEST_EQUAL(nullopt_v_opt != nullopt_v_opt, false); + TEST_EQUAL(nullopt_v_opt < nullopt_v_opt, false); + TEST_EQUAL(nullopt_v_opt > nullopt_v_opt, false); + TEST_EQUAL(nullopt_v_opt <= nullopt_v_opt, true); + TEST_EQUAL(nullopt_v_opt >= nullopt_v_opt, true); + + test_type opt1 = init_value; + TEST_EQUAL(init_value, opt1.value()); + TEST_EQUAL(init_value, *opt1); + TEST_EQUAL(init_value, opt1.value_or(other_value)); + TEST_CHECK(!(opt1 = nullopt_v_opt)); + TEST_EQUAL(other_value, opt1.value_or(other_value)); + TEST_CHECK(!(opt1 = nullopt_v_opt)); + + opt1 = init_value; + TEST_EQUAL(init_value, opt1.value()); + TEST_EQUAL(init_value, *opt1); + TEST_EQUAL(init_value, opt1.value_or(T(other_value))); + TEST_CHECK(!(opt1 = nullopt_v_opt)); + TEST_EQUAL(other_value, opt1.value_or(T(other_value))); + TEST_CHECK(!(opt1 = nullopt_v_opt)); + + bool except_catch = false; + try { + opt1.value(); + } catch (const kaguya::bad_optional_access &) { + except_catch = true; + } + TEST_CHECK(except_catch); + + TEST_CHECK(opt1 = test_type(init_value)); + TEST_EQUAL(init_value, *opt1); + TEST_CHECK(opt1 = test_type(other_value)); + TEST_EQUAL(other_value, *opt1); + + TEST_CHECK(opt1 = test_type(T(init_value))); + TEST_EQUAL(init_value, *opt1); + TEST_CHECK(opt1 = T(init_value)); + TEST_EQUAL(init_value, *opt1); + + TEST_CHECK(opt1 = init_v_opt); + TEST_EQUAL(init_value, *opt1); + TEST_CHECK(opt1 = other_v_opt); + TEST_EQUAL(other_value, *opt1); + + TEST_CHECK(opt1 = init_value); + TEST_EQUAL(init_value, *opt1); + TEST_CHECK(opt1 = other_value); + TEST_EQUAL(other_value, *opt1); + + const test_type copt1 = init_value; + TEST_CHECK(copt1); + TEST_EQUAL(init_value, *copt1); + + TEST_EQUAL(init_value, copt1.value_or(other_value)); + + const test_type copt2; + TEST_CHECK(!copt2); + except_catch = false; + try { + copt2.value(); + } catch (const kaguya::bad_optional_access &) { + except_catch = true; + } + TEST_CHECK(except_catch); } - -KAGUYA_TEST_FUNCTION_DEF(optional_type)(kaguya::State&) -{ - optional_type_test(1, 4); - optional_type_test(1, 4); - optional_type_test(1, 4); - optional_type_test(1, 4); - optional_type_test("abc", "def"); - optional_type_test("abc", "def"); - optional_type_test("abc", "def"); +KAGUYA_TEST_FUNCTION_DEF(optional_type)(kaguya::State &) { + optional_type_test(1, 4); + optional_type_test(1, 4); + optional_type_test(1, 4); + optional_type_test(1, 4); + optional_type_test("abc", "def"); + optional_type_test("abc", "def"); + optional_type_test("abc", "def"); } - - KAGUYA_TEST_GROUP_END(test_08_optional) diff --git a/test/test_09_utility.cpp b/test/test_09_utility.cpp index a5cb345..8ed1d45 100644 --- a/test/test_09_utility.cpp +++ b/test/test_09_utility.cpp @@ -1,274 +1,240 @@ #include "kaguya/kaguya.hpp" #include "test_util.hpp" - -namespace -{ - struct ProxyClassTest - { - ProxyClassTest(const std::string& v) :str(v), num(0), object(0), vec_ptr(0) {} - ProxyClassTest(const int& v) :str(), num(v), object(0), vec_ptr(0) {} - - ProxyClassTest(kaguya_test_util::TestClass* v) :str(), num(0), object(v), vec_ptr(0) {} - - ProxyClassTest(const std::vector& v) :str(), num(0), object(0), vec_ptr(&v){} - - - std::string str; - int num; - kaguya_test_util::TestClass* object; - const std::vector* vec_ptr; - }; +namespace { +struct ProxyClassTest { + ProxyClassTest(const std::string &v) + : str(v), num(0), object(0), vec_ptr(0) {} + ProxyClassTest(const int &v) : str(), num(v), object(0), vec_ptr(0) {} + + ProxyClassTest(kaguya_test_util::TestClass *v) + : str(), num(0), object(v), vec_ptr(0) {} + + ProxyClassTest(const std::vector &v) + : str(), num(0), object(0), vec_ptr(&v) {} + + std::string str; + int num; + kaguya_test_util::TestClass *object; + const std::vector *vec_ptr; +}; } -namespace kaguya -{ - template<> - struct lua_type_traits - : util::ConvertibleRegisterHelper, int, std::string, kaguya_test_util::TestClass*,const std::vector&> - { - }; +namespace kaguya { +template <> +struct lua_type_traits + : util::ConvertibleRegisterHelper< + util::ConvertibleRegisterHelperProxy, int, + std::string, kaguya_test_util::TestClass *, + const std::vector &> {}; } - KAGUYA_TEST_GROUP_START(test_09_utility) using namespace kaguya_test_util; std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; } -KAGUYA_TEST_FUNCTION_DEF(lua_resume_test)(kaguya::State& s) -{ - using namespace kaguya; - +KAGUYA_TEST_FUNCTION_DEF(lua_resume_test)(kaguya::State &s) { + using namespace kaguya; - LuaThread t = s.newThread(s.loadstring("v={...}")); + LuaThread t = s.newThread(s.loadstring("v={...}")); - lua_State* co = t; - lua_pushnumber(co, 2); - lua_pushnumber(co, 3); + lua_State *co = t; + lua_pushnumber(co, 2); + lua_pushnumber(co, 3); - lua_resume(co, s.state(), 2); + lua_resume(co, s.state(), 2); - TEST_EQUAL(s["v"][1], 2); - TEST_EQUAL(s["v"][2], 3); -} -KAGUYA_TEST_FUNCTION_DEF(lua_compare_test)(kaguya::State& s) -{ - using namespace kaguya; - - s.pushToStack(2); - s.pushToStack(2); - TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPEQ)); - TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPLE)); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLT)); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE + 2));//invalid option - s.popFromStack(); - s.popFromStack(); - - s.pushToStack(4); - s.pushToStack(2); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPEQ)); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE)); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLT)); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE + 2));//invalid option - s.popFromStack(); - s.popFromStack(); - - s.pushToStack(2); - s.pushToStack(4); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPEQ)); - TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPLE)); - TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPLT)); - TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE + 2));//invalid option - s.popFromStack(); - s.popFromStack(); + TEST_EQUAL(s["v"][1], 2); + TEST_EQUAL(s["v"][2], 3); } +KAGUYA_TEST_FUNCTION_DEF(lua_compare_test)(kaguya::State &s) { + using namespace kaguya; + + s.pushToStack(2); + s.pushToStack(2); + TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPEQ)); + TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPLE)); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLT)); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE + 2)); // invalid option + s.popFromStack(); + s.popFromStack(); + + s.pushToStack(4); + s.pushToStack(2); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPEQ)); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE)); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLT)); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE + 2)); // invalid option + s.popFromStack(); + s.popFromStack(); + s.pushToStack(2); + s.pushToStack(4); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPEQ)); + TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPLE)); + TEST_CHECK(lua_compare(s.state(), -2, -1, LUA_OPLT)); + TEST_CHECK(!lua_compare(s.state(), -2, -1, LUA_OPLE + 2)); // invalid option + s.popFromStack(); + s.popFromStack(); +} -int lua_mylibf(lua_State* L) -{ - kaguya::State state(L); - kaguya::LuaTable t = state.newTable(); - t["value"] = 111; - return t.push(); +int lua_mylibf(lua_State *L) { + kaguya::State state(L); + kaguya::LuaTable t = state.newTable(); + t["value"] = 111; + return t.push(); } -KAGUYA_TEST_FUNCTION_DEF(luaL_requiref_test)(kaguya::State& s) -{ - using namespace kaguya; +KAGUYA_TEST_FUNCTION_DEF(luaL_requiref_test)(kaguya::State &s) { + using namespace kaguya; - luaL_requiref(s.state(), "mylib", lua_mylibf, false); - kaguya::LuaStackRef ref(s.state(), -1, true); - TEST_EQUAL(ref["value"], 111); - TEST_CHECK(s("assert(mylib == nil)")); + luaL_requiref(s.state(), "mylib", lua_mylibf, false); + kaguya::LuaStackRef ref(s.state(), -1, true); + TEST_EQUAL(ref["value"], 111); + TEST_CHECK(s("assert(mylib == nil)")); } -KAGUYA_TEST_FUNCTION_DEF(stackValueDump)(kaguya::State& s) -{ - using namespace kaguya; - util::stackValueDump(std::cout, s.state(), 4, 2); +KAGUYA_TEST_FUNCTION_DEF(stackValueDump)(kaguya::State &s) { + using namespace kaguya; + util::stackValueDump(std::cout, s.state(), 4, 2); } -struct A -{ - int a[4]; +struct A { + int a[4]; }; -KAGUYA_TEST_FUNCTION_DEF(lua_rawlen_test)(kaguya::State& s) -{ - using namespace kaguya; +KAGUYA_TEST_FUNCTION_DEF(lua_rawlen_test)(kaguya::State &s) { + using namespace kaguya; - s.pushToStack("string"); - TEST_EQUAL(lua_rawlen(s.state(), -1), 6); + s.pushToStack("string"); + TEST_EQUAL(lua_rawlen(s.state(), -1), 6); - LuaTable tbl = s.newTable(); - tbl["2"] = 3; tbl["1"] = 3; - s.pushToStack(tbl); - TEST_EQUAL(lua_rawlen(s.state(), -1), 0); + LuaTable tbl = s.newTable(); + tbl["2"] = 3; + tbl["1"] = 3; + s.pushToStack(tbl); + TEST_EQUAL(lua_rawlen(s.state(), -1), 0); - s.pushToStack(A()); - TEST_COMPARE_GE(lua_rawlen(s.state(), -1), sizeof(A)); + s.pushToStack(A()); + TEST_COMPARE_GE(lua_rawlen(s.state(), -1), sizeof(A)); - A a; - s.pushToStack(&a); - TEST_EQUAL(lua_type(s.state(), -1), LUA_TLIGHTUSERDATA); - TEST_COMPARE_EQ(lua_rawlen(s.state(), -1), 0); + A a; + s.pushToStack(&a); + TEST_EQUAL(lua_type(s.state(), -1), LUA_TLIGHTUSERDATA); + TEST_COMPARE_EQ(lua_rawlen(s.state(), -1), 0); - s.pushToStack(2); - TEST_EQUAL(lua_rawlen(s.state(), -1), 0); + s.pushToStack(2); + TEST_EQUAL(lua_rawlen(s.state(), -1), 0); - lua_settop(s.state(), 0); + lua_settop(s.state(), 0); } +void checkf() {} -void checkf() -{ +template void function_argcount_check(F, size_t count) { + TEST_EQUAL(kaguya::util::FunctionSignature::type::argument_count, count); } -templatevoid function_argcount_check(F , size_t count) -{ - TEST_EQUAL(kaguya::util::FunctionSignature::type::argument_count, count); +template void function_return_type_check(F) { + bool ret = kaguya::standard::is_same< + typename kaguya::util::FunctionSignature::type::result_type, + RET>::value; + TEST_CHECK(ret); } +KAGUYA_TEST_FUNCTION_DEF(check_function_signature)(kaguya::State &s) { + using namespace kaguya; -templatevoid function_return_type_check(F) -{ - bool ret = kaguya::standard::is_same< - typename kaguya::util::FunctionSignature::type::result_type - , RET>::value; - TEST_CHECK(ret); -} -KAGUYA_TEST_FUNCTION_DEF(check_function_signature)(kaguya::State& s) -{ - using namespace kaguya; - - standard::function stdfn(checkf); - - TEST_CHECK(nativefunction::checkArgTypes(s.state(), checkf)); - TEST_CHECK(nativefunction::strictCheckArgTypes(s.state(), checkf)); - TEST_EQUAL(nativefunction::argTypesName(checkf), std::string("")); - TEST_EQUAL(nativefunction::minArgCount(checkf), 0); - TEST_EQUAL(nativefunction::maxArgCount(checkf), 0); - - TEST_CHECK(nativefunction::checkArgTypes(s.state(), &checkf)); - TEST_CHECK(nativefunction::strictCheckArgTypes(s.state(), &checkf)); - TEST_EQUAL(nativefunction::argTypesName(&checkf), std::string("")); - TEST_EQUAL(nativefunction::minArgCount(&checkf), 0); - TEST_EQUAL(nativefunction::maxArgCount(&checkf), 0); - - TEST_CHECK(nativefunction::checkArgTypes(s.state(), stdfn)); - TEST_CHECK(nativefunction::strictCheckArgTypes(s.state(), stdfn)); - TEST_EQUAL(nativefunction::argTypesName(stdfn), std::string("")); - TEST_EQUAL(nativefunction::minArgCount(stdfn), 0); - TEST_EQUAL(nativefunction::maxArgCount(stdfn), 0); - - bool ret = traits::is_same::value; - TEST_CHECK(ret); - ret = traits::is_same::type>::value; - TEST_CHECK(ret); - ret = traits::is_same ::type>::value; - TEST_CHECK(ret); - - - function_argcount_check(checkf, 0); - function_argcount_check(&TestClass::default_arg, 4); - function_argcount_check(stdfn, 0); - - function_return_type_check(checkf); - function_return_type_check(&TestClass::default_arg); - function_return_type_check(stdfn); -} + standard::function stdfn(checkf); + TEST_CHECK(nativefunction::checkArgTypes(s.state(), checkf)); + TEST_CHECK(nativefunction::strictCheckArgTypes(s.state(), checkf)); + TEST_EQUAL(nativefunction::argTypesName(checkf), std::string("")); + TEST_EQUAL(nativefunction::minArgCount(checkf), 0); + TEST_EQUAL(nativefunction::maxArgCount(checkf), 0); -KAGUYA_TEST_FUNCTION_DEF(preprocessor)(kaguya::State& ) -{ - TEST_EQUAL(KAGUYA_PP_INC(1), 2); - TEST_EQUAL(KAGUYA_PP_INC(2), 3); - TEST_EQUAL(KAGUYA_PP_ADD(1, 2), 3); - TEST_EQUAL(KAGUYA_PP_SUB(3, 2), 1); - TEST_EQUAL(KAGUYA_PP_SUB(3, 3), 0); - TEST_EQUAL(KAGUYA_PP_SUB(3, 0), 3); -} -KAGUYA_TEST_FUNCTION_DEF(pretty_type_name)(kaguya::State&) -{ - using kaguya::util::pretty_name; + TEST_CHECK(nativefunction::checkArgTypes(s.state(), &checkf)); + TEST_CHECK(nativefunction::strictCheckArgTypes(s.state(), &checkf)); + TEST_EQUAL(nativefunction::argTypesName(&checkf), std::string("")); + TEST_EQUAL(nativefunction::minArgCount(&checkf), 0); + TEST_EQUAL(nativefunction::maxArgCount(&checkf), 0); - TEST_EQUAL(pretty_name(typeid(int)), "int"); - TEST_EQUAL(pretty_name(typeid(long)), "long"); + TEST_CHECK(nativefunction::checkArgTypes(s.state(), stdfn)); + TEST_CHECK(nativefunction::strictCheckArgTypes(s.state(), stdfn)); + TEST_EQUAL(nativefunction::argTypesName(stdfn), std::string("")); + TEST_EQUAL(nativefunction::minArgCount(stdfn), 0); + TEST_EQUAL(nativefunction::maxArgCount(stdfn), 0); -} + bool ret = traits::is_same::value; + TEST_CHECK(ret); + ret = + traits::is_same::type>::value; + TEST_CHECK(ret); + ret = traits::is_same< + std::string, util::ArgumentType<1, void(int, std::string)>::type>::value; + TEST_CHECK(ret); + function_argcount_check(checkf, 0); + function_argcount_check(&TestClass::default_arg, 4); + function_argcount_check(stdfn, 0); + function_return_type_check(checkf); + function_return_type_check(&TestClass::default_arg); + function_return_type_check(stdfn); +} -void proxy_class_test_func(ProxyClassTest t) -{ - TEST_EQUAL(t.str, "test"); +KAGUYA_TEST_FUNCTION_DEF(preprocessor)(kaguya::State &) { + TEST_EQUAL(KAGUYA_PP_INC(1), 2); + TEST_EQUAL(KAGUYA_PP_INC(2), 3); + TEST_EQUAL(KAGUYA_PP_ADD(1, 2), 3); + TEST_EQUAL(KAGUYA_PP_SUB(3, 2), 1); + TEST_EQUAL(KAGUYA_PP_SUB(3, 3), 0); + TEST_EQUAL(KAGUYA_PP_SUB(3, 0), 3); } -void proxy_class_test_func2(const ProxyClassTest& t) -{ - TEST_EQUAL(t.num, 5); +KAGUYA_TEST_FUNCTION_DEF(pretty_type_name)(kaguya::State &) { + using kaguya::util::pretty_name; + + TEST_EQUAL(pretty_name(typeid(int)), "int"); + TEST_EQUAL(pretty_name(typeid(long)), "long"); } -void proxy_class_test_func3(const ProxyClassTest& t) -{ - TEST_EQUAL(t.object->stringmember, "test"); + +void proxy_class_test_func(ProxyClassTest t) { TEST_EQUAL(t.str, "test"); } +void proxy_class_test_func2(const ProxyClassTest &t) { TEST_EQUAL(t.num, 5); } +void proxy_class_test_func3(const ProxyClassTest &t) { + TEST_EQUAL(t.object->stringmember, "test"); } -void proxy_class_test_func_array(const ProxyClassTest& t) -{ - std::vector v; - v.push_back(0); - v.push_back(1); - v.push_back(2); - v.push_back(3); - TEST_CHECK(*t.vec_ptr == v); +void proxy_class_test_func_array(const ProxyClassTest &t) { + std::vector v; + v.push_back(0); + v.push_back(1); + v.push_back(2); + v.push_back(3); + TEST_CHECK(*t.vec_ptr == v); } -KAGUYA_TEST_FUNCTION_DEF(proxy_class_test)(kaguya::State& state) -{ - state["testf"] = &proxy_class_test_func; - TEST_CHECK(state("testf('test')")); - state["testf2"] = &proxy_class_test_func2; - TEST_CHECK(state("testf2(5)")); +KAGUYA_TEST_FUNCTION_DEF(proxy_class_test)(kaguya::State &state) { + state["testf"] = &proxy_class_test_func; + TEST_CHECK(state("testf('test')")); + state["testf2"] = &proxy_class_test_func2; + TEST_CHECK(state("testf2(5)")); + + state.setErrorHandler(ignore_error_fun); + TEST_CHECK(!state("testf2()")); - state.setErrorHandler(ignore_error_fun); - TEST_CHECK(!state("testf2()")); - - state["TestClass"].setClass(kaguya::UserdataMetatable() - .setConstructors < TestClass(std::string) > () - ); - state["testf3"] = &proxy_class_test_func3; + state["TestClass"].setClass(kaguya::UserdataMetatable() + .setConstructors()); + state["testf3"] = &proxy_class_test_func3; - TEST_CHECK(state("testf3(TestClass.new('test'))")); + TEST_CHECK(state("testf3(TestClass.new('test'))")); #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE - state["testf4"] = &proxy_class_test_func_array; - TEST_CHECK(state("testf4({0,1,2,3})")); + state["testf4"] = &proxy_class_test_func_array; + TEST_CHECK(state("testf4({0,1,2,3})")); #endif } - - KAGUYA_TEST_GROUP_END(test_09_utility) diff --git a/test/test_10_loadfile.cpp b/test/test_10_loadfile.cpp index 09bce05..5824f18 100644 --- a/test/test_10_loadfile.cpp +++ b/test/test_10_loadfile.cpp @@ -5,48 +5,41 @@ KAGUYA_TEST_GROUP_START(test_10_loadfile) using namespace kaguya_test_util; std::string last_error_message; -void ignore_error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : ""; +void ignore_error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : ""; } - -KAGUYA_TEST_FUNCTION_DEF(load_return_number)(kaguya::State& state) -{ - TEST_CHECK(state.dofile("lua/return_number.lua")); - TEST_CHECK(state.loadfile("lua/return_number.lua")); +KAGUYA_TEST_FUNCTION_DEF(load_return_number)(kaguya::State &state) { + TEST_CHECK(state.dofile("lua/return_number.lua")); + TEST_CHECK(state.loadfile("lua/return_number.lua")); } - -KAGUYA_TEST_FUNCTION_DEF(load_assign_value)(kaguya::State& state) -{ - TEST_CHECK(state.dofile("lua/assign_value.lua")); - TEST_EQUAL(state["value"],1); - state["value"] = 5; - kaguya::LuaTable env = state.newTable(); - TEST_CHECK(state.dofile("lua/assign_value.lua", env)); - TEST_CHECK(state.loadfile("lua/assign_value.lua")); - TEST_EQUAL(env["value"], 1); +KAGUYA_TEST_FUNCTION_DEF(load_assign_value)(kaguya::State &state) { + TEST_CHECK(state.dofile("lua/assign_value.lua")); + TEST_EQUAL(state["value"], 1); + state["value"] = 5; + kaguya::LuaTable env = state.newTable(); + TEST_CHECK(state.dofile("lua/assign_value.lua", env)); + TEST_CHECK(state.loadfile("lua/assign_value.lua")); + TEST_EQUAL(env["value"], 1); } -KAGUYA_TEST_FUNCTION_DEF(load_syntax_error_script)(kaguya::State& state) -{ - last_error_message = ""; - state.setErrorHandler(ignore_error_fun); +KAGUYA_TEST_FUNCTION_DEF(load_syntax_error_script)(kaguya::State &state) { + last_error_message = ""; + state.setErrorHandler(ignore_error_fun); - TEST_CHECK(!state.loadfile("lua/syntax_error.lua")); - TEST_CHECK(!state.dofile("lua/syntax_error.lua")); - TEST_COMPARE_NE(last_error_message, ""); + TEST_CHECK(!state.loadfile("lua/syntax_error.lua")); + TEST_CHECK(!state.dofile("lua/syntax_error.lua")); + TEST_COMPARE_NE(last_error_message, ""); } -KAGUYA_TEST_FUNCTION_DEF(runtime_error_script)(kaguya::State& state) -{ - last_error_message = ""; - state.setErrorHandler(ignore_error_fun); +KAGUYA_TEST_FUNCTION_DEF(runtime_error_script)(kaguya::State &state) { + last_error_message = ""; + state.setErrorHandler(ignore_error_fun); - TEST_CHECK(!state.dofile("lua/runtime_error.lua")); - TEST_COMPARE_NE(last_error_message, ""); + TEST_CHECK(!state.dofile("lua/runtime_error.lua")); + TEST_COMPARE_NE(last_error_message, ""); } KAGUYA_TEST_GROUP_END(test_10_loadfile) diff --git a/test/test_11_cxx11_feature.cpp b/test/test_11_cxx11_feature.cpp index b6f9134..f496a68 100644 --- a/test/test_11_cxx11_feature.cpp +++ b/test/test_11_cxx11_feature.cpp @@ -1,8 +1,6 @@ #include "kaguya/kaguya.hpp" #include "test_util.hpp" - - #if KAGUYA_USE_CPP11 #include @@ -10,349 +8,310 @@ KAGUYA_TEST_GROUP_START(test_11_cxx11_feature) using namespace kaguya_test_util; -enum class testenumclass -{ - Foo = 0, - Bar = 1, +enum class testenumclass { + Foo = 0, + Bar = 1, }; - -KAGUYA_TEST_FUNCTION_DEF(enum_class_set)(kaguya::State& state) -{ - state["value"] = testenumclass::Foo; - TEST_CHECK(state("assert(value == 0)")); +KAGUYA_TEST_FUNCTION_DEF(enum_class_set)(kaguya::State &state) { + state["value"] = testenumclass::Foo; + TEST_CHECK(state("assert(value == 0)")); } -KAGUYA_TEST_FUNCTION_DEF(enum_class_get)(kaguya::State& state) -{ - state("value = 1"); - TEST_CHECK(state["value"] == testenumclass::Bar); +KAGUYA_TEST_FUNCTION_DEF(enum_class_get)(kaguya::State &state) { + state("value = 1"); + TEST_CHECK(state["value"] == testenumclass::Bar); } +struct MoveOnlyClass { + MoveOnlyClass(int i) : member(i) {} + int member; + MoveOnlyClass(MoveOnlyClass &&src) : member(src.member) {} -struct MoveOnlyClass -{ - MoveOnlyClass(int i) :member(i) {} - int member; - - MoveOnlyClass(MoveOnlyClass&& src) :member(src.member) {} private: - MoveOnlyClass(); - MoveOnlyClass(const MoveOnlyClass&); - MoveOnlyClass& operator=(const MoveOnlyClass&); + MoveOnlyClass(); + MoveOnlyClass(const MoveOnlyClass &); + MoveOnlyClass &operator=(const MoveOnlyClass &); }; -KAGUYA_TEST_FUNCTION_DEF(movable_class_test)(kaguya::State& state) -{ - state["MoveOnlyClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("member", &MoveOnlyClass::member) - ); +KAGUYA_TEST_FUNCTION_DEF(movable_class_test)(kaguya::State &state) { + state["MoveOnlyClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addProperty("member", &MoveOnlyClass::member)); - state["moveonly"] = MoveOnlyClass(2); + state["moveonly"] = MoveOnlyClass(2); - const MoveOnlyClass* ref = state["moveonly"]; - TEST_CHECK(ref); - TEST_CHECK(ref->member == 2); + const MoveOnlyClass *ref = state["moveonly"]; + TEST_CHECK(ref); + TEST_CHECK(ref->member == 2); - state("func =function(arg) return assert(arg.member == 5) end"); - state["func"](MoveOnlyClass(5)); + state("func =function(arg) return assert(arg.member == 5) end"); + state["func"](MoveOnlyClass(5)); - state.newRef(MoveOnlyClass(5)); + state.newRef(MoveOnlyClass(5)); } -KAGUYA_TEST_FUNCTION_DEF(lambdafun)(kaguya::State& state) -{ - state["ABC"] = kaguya::function([](int a) {return a * 2; }); - int a = state["ABC"](54); - TEST_EQUAL(a, 108); - - state["free2"] = kaguya::function([]() {return 12; }); - TEST_EQUAL(state["free2"](), 12.0); - - - state["sum"] = kaguya::function([](kaguya::VariadicArgType args) { - int sum = 0; - for (int arg : args) - { - sum += arg; - } - - TEST_EQUAL(args.size(), 10); - TEST_EQUAL(args[0], 1); - TEST_EQUAL(args[1], 2); - TEST_EQUAL(args[2], 3); - TEST_EQUAL(args[3], 4); - TEST_EQUAL(args[4], 5); - TEST_EQUAL(args[5], 6); - TEST_EQUAL(args[6], 7); - TEST_EQUAL(args[7], 8); - TEST_EQUAL(args[8], 9); - TEST_EQUAL(args[9], 10); - return sum; - }); - TEST_EQUAL(state["sum"](1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 55); - - - - state["ssum"] = kaguya::function([](kaguya::VariadicArgType args) { - std::string sum; - for (std::string arg : args) - { - sum += arg; - } - return sum; - }); - TEST_EQUAL(state["ssum"](1, 2, 3, 4, 5, 6, 7, 8, 9, 10), "12345678910"); - - - state["overload"] = kaguya::overload([](int) {return 1; }, - [](const std::string&) {return 2; }, - []() {return 3; } - ); - state("assert(overload(2) == 1)");//int version - state("assert(overload('2') == 2)");//string version - state("assert(overload() == 3)");//no argument version - - state["lamda2"] = kaguya::function([]()mutable {return 12; });//mutable functor - state("assert(lamda2() == 12)"); +KAGUYA_TEST_FUNCTION_DEF(lambdafun)(kaguya::State &state) { + state["ABC"] = kaguya::function([](int a) { return a * 2; }); + int a = state["ABC"](54); + TEST_EQUAL(a, 108); + + state["free2"] = kaguya::function([]() { return 12; }); + TEST_EQUAL(state["free2"](), 12.0); + + state["sum"] = kaguya::function([](kaguya::VariadicArgType args) { + int sum = 0; + for (int arg : args) { + sum += arg; + } + + TEST_EQUAL(args.size(), 10); + TEST_EQUAL(args[0], 1); + TEST_EQUAL(args[1], 2); + TEST_EQUAL(args[2], 3); + TEST_EQUAL(args[3], 4); + TEST_EQUAL(args[4], 5); + TEST_EQUAL(args[5], 6); + TEST_EQUAL(args[6], 7); + TEST_EQUAL(args[7], 8); + TEST_EQUAL(args[8], 9); + TEST_EQUAL(args[9], 10); + return sum; + }); + TEST_EQUAL(state["sum"](1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 55); + + state["ssum"] = kaguya::function([](kaguya::VariadicArgType args) { + std::string sum; + for (std::string arg : args) { + sum += arg; + } + return sum; + }); + TEST_EQUAL(state["ssum"](1, 2, 3, 4, 5, 6, 7, 8, 9, 10), "12345678910"); + + state["overload"] = kaguya::overload([](int) { return 1; }, + [](const std::string &) { return 2; }, + []() { return 3; }); + state("assert(overload(2) == 1)"); // int version + state("assert(overload('2') == 2)"); // string version + state("assert(overload() == 3)"); // no argument version + + state["lamda2"] = + kaguya::function([]() mutable { return 12; }); // mutable functor + state("assert(lamda2() == 12)"); } -KAGUYA_TEST_FUNCTION_DEF(put_unique_ptr)(kaguya::State& state) -{ - state["MoveOnlyClass"].setClass(kaguya::UserdataMetatable() - .setConstructors() - .addProperty("member", &MoveOnlyClass::member) - ); - - state["uniqueptr"] = std::unique_ptr(new MoveOnlyClass(2)); - - const MoveOnlyClass* ref = state["uniqueptr"]; - TEST_CHECK(ref); - TEST_EQUAL(ref->member, 2); - - state["uniqueptr"].typeTest&>(); - const std::unique_ptr& cuptr = state["uniqueptr"].get&>(); - TEST_CHECK(cuptr); - TEST_EQUAL(cuptr->member, 2); - - std::unique_ptr& uptr = state["uniqueptr"].get&>(); - TEST_CHECK(uptr); - TEST_EQUAL(uptr->member, 2); - uptr.reset(); - - state("func =function(arg) return assert(arg.member == 5) end"); - TEST_CHECK(state["func"](std::unique_ptr(new MoveOnlyClass(5))) == true); - - - bool catch_except = false; - try - { - std::unique_ptr& uptr = state["nil"].get&>(); - TEST_CHECK(uptr); - TEST_EQUAL(uptr->member, 2); - } - catch (const kaguya::LuaTypeMismatch&) - { - catch_except = true; - } - TEST_CHECK(catch_except); +KAGUYA_TEST_FUNCTION_DEF(put_unique_ptr)(kaguya::State &state) { + state["MoveOnlyClass"].setClass( + kaguya::UserdataMetatable() + .setConstructors() + .addProperty("member", &MoveOnlyClass::member)); + + state["uniqueptr"] = std::unique_ptr(new MoveOnlyClass(2)); + + const MoveOnlyClass *ref = state["uniqueptr"]; + TEST_CHECK(ref); + TEST_EQUAL(ref->member, 2); + + state["uniqueptr"].typeTest &>(); + const std::unique_ptr &cuptr = + state["uniqueptr"].get &>(); + TEST_CHECK(cuptr); + TEST_EQUAL(cuptr->member, 2); + + std::unique_ptr &uptr = + state["uniqueptr"].get &>(); + TEST_CHECK(uptr); + TEST_EQUAL(uptr->member, 2); + uptr.reset(); + + state("func =function(arg) return assert(arg.member == 5) end"); + TEST_CHECK(state["func"]( + std::unique_ptr(new MoveOnlyClass(5))) == true); + + bool catch_except = false; + try { + std::unique_ptr &uptr = + state["nil"].get &>(); + TEST_CHECK(uptr); + TEST_EQUAL(uptr->member, 2); + } catch (const kaguya::LuaTypeMismatch &) { + catch_except = true; + } + TEST_CHECK(catch_except); } -KAGUYA_TEST_FUNCTION_DEF(compare_null_ptr)(kaguya::State& state) -{ - { - kaguya::LuaRef nullref = state.newRef(nullptr); - TEST_CHECK(nullref.typeTest()); - TEST_CHECK(nullref.weakTypeTest()); - TEST_CHECK(nullref == nullptr); - void* ptr = nullref.get(); - TEST_CHECK(!ptr); - } - { - kaguya::LuaRef ref = state.newRef(1); - TEST_CHECK(!(ref.typeTest())); - TEST_CHECK(!(ref.weakTypeTest())); - TEST_CHECK(ref != nullptr); - bool catch_except = false; - try - { - ref.get(); - } - catch (const kaguya::LuaTypeMismatch&) - { - catch_except = true; - } - TEST_CHECK(catch_except); - } +KAGUYA_TEST_FUNCTION_DEF(compare_null_ptr)(kaguya::State &state) { + { + kaguya::LuaRef nullref = state.newRef(nullptr); + TEST_CHECK(nullref.typeTest()); + TEST_CHECK(nullref.weakTypeTest()); + TEST_CHECK(nullref == nullptr); + void *ptr = nullref.get(); + TEST_CHECK(!ptr); + } + { + kaguya::LuaRef ref = state.newRef(1); + TEST_CHECK(!(ref.typeTest())); + TEST_CHECK(!(ref.weakTypeTest())); + TEST_CHECK(ref != nullptr); + bool catch_except = false; + try { + ref.get(); + } catch (const kaguya::LuaTypeMismatch &) { + catch_except = true; + } + TEST_CHECK(catch_except); + } } -KAGUYA_TEST_FUNCTION_DEF(nullptr_set)(kaguya::State& state) -{ - state["value"] = nullptr; - TEST_CHECK(state["value"] == nullptr); - TEST_CHECK(!state["value"]); - TEST_CHECK(state("assert(value == nil)")); +KAGUYA_TEST_FUNCTION_DEF(nullptr_set)(kaguya::State &state) { + state["value"] = nullptr; + TEST_CHECK(state["value"] == nullptr); + TEST_CHECK(!state["value"]); + TEST_CHECK(state("assert(value == nil)")); } +KAGUYA_TEST_FUNCTION_DEF(null_unique_ptr)(kaguya::State &state) { + state["Base"].setClass(kaguya::UserdataMetatable()); -KAGUYA_TEST_FUNCTION_DEF(null_unique_ptr)(kaguya::State& state) -{ - state["Base"].setClass(kaguya::UserdataMetatable()); - - state["test"] = std::unique_ptr(); - TEST_CHECK(state("assert(test==nil)")); + state["test"] = std::unique_ptr(); + TEST_CHECK(state("assert(test==nil)")); } - -KAGUYA_TEST_FUNCTION_DEF(result_range_based_for)(kaguya::State& state) -{ - state("fn =function() return 1,2,4,8,16 end"); - { - std::vector res; - kaguya::LuaFunction fn = state["fn"]; - auto result = fn(); - for (int v : result) - { - res.push_back(v); - } - TEST_EQUAL(res.size(), 5); - TEST_EQUAL(res[0], 1); - TEST_EQUAL(res[1], 2); - TEST_EQUAL(res[2], 4); - TEST_EQUAL(res[3], 8); - TEST_EQUAL(res[4], 16); - } - { - std::vector res; - kaguya::LuaFunction fn = state["fn"]; - const auto result = fn(); - for (int v : result) - { - res.push_back(v); - } - TEST_EQUAL(res.size(), 5); - TEST_EQUAL(res[0], 1); - TEST_EQUAL(res[1], 2); - TEST_EQUAL(res[2], 4); - TEST_EQUAL(res[3], 8); - TEST_EQUAL(res[4], 16); - } - +KAGUYA_TEST_FUNCTION_DEF(result_range_based_for)(kaguya::State &state) { + state("fn =function() return 1,2,4,8,16 end"); + { + std::vector res; + kaguya::LuaFunction fn = state["fn"]; + auto result = fn(); + for (int v : result) { + res.push_back(v); + } + TEST_EQUAL(res.size(), 5); + TEST_EQUAL(res[0], 1); + TEST_EQUAL(res[1], 2); + TEST_EQUAL(res[2], 4); + TEST_EQUAL(res[3], 8); + TEST_EQUAL(res[4], 16); + } + { + std::vector res; + kaguya::LuaFunction fn = state["fn"]; + const auto result = fn(); + for (int v : result) { + res.push_back(v); + } + TEST_EQUAL(res.size(), 5); + TEST_EQUAL(res[0], 1); + TEST_EQUAL(res[1], 2); + TEST_EQUAL(res[2], 4); + TEST_EQUAL(res[3], 8); + TEST_EQUAL(res[4], 16); + } } -KAGUYA_TEST_FUNCTION_DEF(initializer_list)(kaguya::State& state) -{ - state["table"] = kaguya::TableData{ 23,"test",{"key","value"}, - { "childtable",kaguya::TableData{3} } }; - kaguya::LuaTable tbl = state["table"]; - +KAGUYA_TEST_FUNCTION_DEF(initializer_list)(kaguya::State &state) { + state["table"] = kaguya::TableData{ + 23, "test", {"key", "value"}, {"childtable", kaguya::TableData{3}}}; + kaguya::LuaTable tbl = state["table"]; - state("assert(table[1] == 23)"); - state("assert(table[2] == 'test')"); - state("assert(table['key'] == 'value')"); + state("assert(table[1] == 23)"); + state("assert(table[2] == 'test')"); + state("assert(table['key'] == 'value')"); - TEST_EQUAL(tbl[1], 23); - TEST_EQUAL(tbl[2], "test"); - TEST_EQUAL(tbl["key"], "value"); - TEST_EQUAL(tbl["childtable"][1], 3); + TEST_EQUAL(tbl[1], 23); + TEST_EQUAL(tbl[2], "test"); + TEST_EQUAL(tbl["key"], "value"); + TEST_EQUAL(tbl["childtable"][1], 3); } -KAGUYA_TEST_FUNCTION_DEF(std_array)(kaguya::State& state) -{ - std::array arr{{ 2,3,4 }}; - state["value"] = arr; - - - state("assert(value[1] == 2)"); - state("assert(value[2] == 3)"); - state("assert(value[3] == 4)"); - std::array get = state["value"]; - TEST_EQUAL(get[0], 2); - TEST_EQUAL(get[1], 3); - TEST_EQUAL(get[2], 4); - bool v = state["value"].weakTypeTest >(); - TEST_CHECK(v); +KAGUYA_TEST_FUNCTION_DEF(std_array)(kaguya::State &state) { + std::array arr{{2, 3, 4}}; + state["value"] = arr; + + state("assert(value[1] == 2)"); + state("assert(value[2] == 3)"); + state("assert(value[3] == 4)"); + std::array get = state["value"]; + TEST_EQUAL(get[0], 2); + TEST_EQUAL(get[1], 3); + TEST_EQUAL(get[2], 4); + bool v = state["value"].weakTypeTest >(); + TEST_CHECK(v); } - int self_refcounted_object_count = 0; -struct self_refcounted_object -{ - self_refcounted_object() :refcount(0) - { - self_refcounted_object_count++; - } - virtual ~self_refcounted_object() { self_refcounted_object_count--; } +struct self_refcounted_object { + self_refcounted_object() : refcount(0) { self_refcounted_object_count++; } + virtual ~self_refcounted_object() { self_refcounted_object_count--; } + + int get_ref_count() const { return refcount; } - int get_ref_count()const { return refcount; } + int refcount; - int refcount; private: - self_refcounted_object(const self_refcounted_object&) = delete; - self_refcounted_object& operator=(const self_refcounted_object&) = delete; + self_refcounted_object(const self_refcounted_object &) = delete; + self_refcounted_object &operator=(const self_refcounted_object &) = delete; }; -struct self_refcounted_object_deleter -{ - void operator()(self_refcounted_object* d) - { - d->refcount--; - if (d->refcount <= 0) - { - delete d; - } - } +struct self_refcounted_object_deleter { + void operator()(self_refcounted_object *d) { + d->refcount--; + if (d->refcount <= 0) { + delete d; + } + } }; -std::unique_ptr self_refcounted_object_construct() -{ - self_refcounted_object* ptr = new self_refcounted_object(); - ptr->refcount++; - return std::unique_ptr(ptr); +std::unique_ptr +self_refcounted_object_construct() { + self_refcounted_object *ptr = new self_refcounted_object(); + ptr->refcount++; + return std::unique_ptr(ptr); } -KAGUYA_TEST_FUNCTION_DEF(self_refcount_object)(kaguya::State&) -{ - TEST_EQUAL(self_refcounted_object_count, 0); - { - kaguya::State state; - state["self_refcount_object"].setClass(kaguya::UserdataMetatable() - .addStaticFunction("new", &self_refcounted_object_construct) - .addProperty("ref_count", &self_refcounted_object::get_ref_count) - ); +KAGUYA_TEST_FUNCTION_DEF(self_refcount_object)(kaguya::State &) { + TEST_EQUAL(self_refcounted_object_count, 0); + { + kaguya::State state; + state["self_refcount_object"].setClass( + kaguya::UserdataMetatable() + .addStaticFunction("new", &self_refcounted_object_construct) + .addProperty("ref_count", &self_refcounted_object::get_ref_count)); - TEST_CHECK(state.dostring("a = self_refcount_object.new();assert(a.ref_count == 1)")); + TEST_CHECK(state.dostring( + "a = self_refcount_object.new();assert(a.ref_count == 1)")); - TEST_EQUAL(self_refcounted_object_count, 1);//available 1 object - } + TEST_EQUAL(self_refcounted_object_count, 1); // available 1 object + } - TEST_EQUAL(self_refcounted_object_count, 0);//destructed + TEST_EQUAL(self_refcounted_object_count, 0); // destructed } +KAGUYA_TEST_FUNCTION_DEF(invoke_test)(kaguya::State &) { + TestClass c(2); + TEST_EQUAL(c.getInt(), 2); + kaguya::util::invoke(&TestClass::setInt, c, 4); + TEST_EQUAL(c.getInt(), 4); + int a = kaguya::util::invoke(&TestClass::getInt, c); - -KAGUYA_TEST_FUNCTION_DEF(invoke_test)(kaguya::State&) -{ - TestClass c(2); - TEST_EQUAL(c.getInt(), 2); - kaguya::util::invoke(&TestClass::setInt, c, 4); - TEST_EQUAL(c.getInt(), 4); - int a = kaguya::util::invoke(&TestClass::getInt, c); - - TEST_EQUAL(a, 4); + TEST_EQUAL(a, 4); } - - #ifndef KAGUYA_NO_STD_VECTOR_TO_TABLE -KAGUYA_TEST_FUNCTION_DEF(vector_to_table_with_move)(kaguya::State& state) -{ - std::vector v; v.push_back(3); v.push_back(13); v.push_back(2); v.push_back(99); - state["v"] = std::move(v); - TEST_CHECK(state("assert(v[1] == 3 and v[2] == 13 and v[3] == 2 and v[4] == 99)")); +KAGUYA_TEST_FUNCTION_DEF(vector_to_table_with_move)(kaguya::State &state) { + std::vector v; + v.push_back(3); + v.push_back(13); + v.push_back(2); + v.push_back(99); + state["v"] = std::move(v); + TEST_CHECK( + state("assert(v[1] == 3 and v[2] == 13 and v[3] == 2 and v[4] == 99)")); } #endif KAGUYA_TEST_GROUP_END(test_11_cxx11_feature) - #endif diff --git a/test/test_12_push_any.cpp b/test/test_12_push_any.cpp index 054aed7..1ffe208 100644 --- a/test/test_12_push_any.cpp +++ b/test/test_12_push_any.cpp @@ -4,41 +4,37 @@ KAGUYA_TEST_GROUP_START(test_12_push_any) using namespace kaguya_test_util; -KAGUYA_TEST_FUNCTION_DEF(push_any_type)(kaguya::State& state) -{ - using namespace kaguya; - - std::vector data; - data.push_back(3); - data.push_back("data"); - data.push_back("abc"); - data.push_back(std::string("abc")); - - - TEST_COMPARE_EQ(state.newRef(AnyDataPusher(3)), 3); - TEST_COMPARE_EQ(state.newRef(AnyDataPusher("data")), "data"); - TEST_COMPARE_EQ(state.newRef(AnyDataPusher(std::string("abc"))), std::string("abc")); - - AnyDataPusher a("d"); - AnyDataPusher b(4); - a = b; - a = a; - AnyDataPusher c; - TEST_COMPARE_EQ(state.newRef(a), 4); - TEST_COMPARE_EQ(state.newRef(b), 4); - TEST_CHECK(!state.newRef(c)); +KAGUYA_TEST_FUNCTION_DEF(push_any_type)(kaguya::State &state) { + using namespace kaguya; + + std::vector data; + data.push_back(3); + data.push_back("data"); + data.push_back("abc"); + data.push_back(std::string("abc")); + + TEST_COMPARE_EQ(state.newRef(AnyDataPusher(3)), 3); + TEST_COMPARE_EQ(state.newRef(AnyDataPusher("data")), "data"); + TEST_COMPARE_EQ(state.newRef(AnyDataPusher(std::string("abc"))), + std::string("abc")); + + AnyDataPusher a("d"); + AnyDataPusher b(4); + a = b; + a = a; + AnyDataPusher c; + TEST_COMPARE_EQ(state.newRef(a), 4); + TEST_COMPARE_EQ(state.newRef(b), 4); + TEST_CHECK(!state.newRef(c)); } +KAGUYA_TEST_FUNCTION_DEF(push_const_shared_ptr_type)(kaguya::State &state) { + using namespace kaguya; + using namespace kaguya::standard; + shared_ptr s(new int(4)); + LuaRef ref = state.newRef(s); + shared_ptr other = ref; - -KAGUYA_TEST_FUNCTION_DEF(push_const_shared_ptr_type)(kaguya::State& state) -{ - using namespace kaguya; - using namespace kaguya::standard; - shared_ptr s(new int(4)); - LuaRef ref = state.newRef(s); - shared_ptr other = ref; - - TEST_CHECK(!other); + TEST_CHECK(!other); } KAGUYA_TEST_GROUP_END(test_12_push_any) diff --git a/test/test_13_another_binding_api.cpp b/test/test_13_another_binding_api.cpp index 5c6a285..eae5879 100644 --- a/test/test_13_another_binding_api.cpp +++ b/test/test_13_another_binding_api.cpp @@ -8,50 +8,41 @@ using namespace kaguya; int squared(int a) { return a * a; } -enum ENUM_TEST_TYPE -{ - ENUM_TEST_A = 2, - ENUM_TEST_B = 4 -}; - -KAGUYA_BINDINGS(test_bind){ - class_("TestClass") - .constructor() - .def("getInt", &TestClass::getInt); - - { - scope newscope("submodule"); - def("squared", &squared); - { - scope newscope("submodule"); - def("squared3", &squared); - } - } - function("squared", &squared); - scope().attr("x") = 1; - - enum_("ENUM_TEST_TYPE") - .value("ENUM_TEST_A", ENUM_TEST_A) - .value("ENUM_TEST_B", ENUM_TEST_B); +enum ENUM_TEST_TYPE { ENUM_TEST_A = 2, ENUM_TEST_B = 4 }; + +KAGUYA_BINDINGS(test_bind) { + class_("TestClass") + .constructor() + .def("getInt", &TestClass::getInt); + + { + scope newscope("submodule"); + def("squared", &squared); + { + scope newscope("submodule"); + def("squared3", &squared); + } + } + function("squared", &squared); + scope().attr("x") = 1; + + enum_("ENUM_TEST_TYPE") + .value("ENUM_TEST_A", ENUM_TEST_A) + .value("ENUM_TEST_B", ENUM_TEST_B); } -KAGUYA_TEST_FUNCTION_DEF(int_constructor)(kaguya::State& state) -{ - state.openlib("test_bind", &luaopen_test_bind); +KAGUYA_TEST_FUNCTION_DEF(int_constructor)(kaguya::State &state) { + state.openlib("test_bind", &luaopen_test_bind); - TEST_CHECK(state("value = assert(test_bind.TestClass.new(32))")); - TEST_CHECK(state("assert(value:getInt() == 32)")); - TEST_CHECK(state("assert(test_bind.squared(3) == 9)")); - TEST_CHECK(state("assert(test_bind.submodule.squared(6) == 36)")); - TEST_CHECK(state("assert(test_bind.submodule.submodule.squared3(6) == 36)")); + TEST_CHECK(state("value = assert(test_bind.TestClass.new(32))")); + TEST_CHECK(state("assert(value:getInt() == 32)")); + TEST_CHECK(state("assert(test_bind.squared(3) == 9)")); + TEST_CHECK(state("assert(test_bind.submodule.squared(6) == 36)")); + TEST_CHECK(state("assert(test_bind.submodule.submodule.squared3(6) == 36)")); - - TEST_CHECK(state("assert(test_bind.x == 1)")) - TEST_CHECK(state("assert(test_bind.ENUM_TEST_TYPE.ENUM_TEST_A == 2)")); - TEST_CHECK(state("assert(test_bind.ENUM_TEST_TYPE.ENUM_TEST_B == 4)")); + TEST_CHECK(state("assert(test_bind.x == 1)")) + TEST_CHECK(state("assert(test_bind.ENUM_TEST_TYPE.ENUM_TEST_A == 2)")); + TEST_CHECK(state("assert(test_bind.ENUM_TEST_TYPE.ENUM_TEST_B == 4)")); } - - - KAGUYA_TEST_GROUP_END(test_13_predefined_binding_api) diff --git a/test/test_14_error_message.cpp b/test/test_14_error_message.cpp index acef2d1..ab3f36f 100644 --- a/test/test_14_error_message.cpp +++ b/test/test_14_error_message.cpp @@ -3,53 +3,46 @@ KAGUYA_TEST_GROUP_START(test_14_error_message) using namespace kaguya_test_util; - using namespace kaguya; - std::string last_error_message; -void error_fun(int status, const char* message) -{ - KAGUYA_UNUSED(status); - last_error_message = message ? message : "unknown error"; +void error_fun(int status, const char *message) { + KAGUYA_UNUSED(status); + last_error_message = message ? message : "unknown error"; } - - -void defargfn(int a = 3, int b = 2, int c = 1) -{ - TEST_EQUAL(a, 3); - TEST_EQUAL(b, 2); - TEST_EQUAL(c, 1); +void defargfn(int a = 3, int b = 2, int c = 1) { + TEST_EQUAL(a, 3); + TEST_EQUAL(b, 2); + TEST_EQUAL(c, 1); } -void defargfn2(int a, int b, int c = 1) -{ - TEST_EQUAL(a, 3); - TEST_EQUAL(b, 2); - TEST_EQUAL(c, 1); +void defargfn2(int a, int b, int c = 1) { + TEST_EQUAL(a, 3); + TEST_EQUAL(b, 2); + TEST_EQUAL(c, 1); } KAGUYA_FUNCTION_OVERLOADS(defargfn_wrapper, defargfn, 0, 3) KAGUYA_FUNCTION_OVERLOADS(defargfn_wrapper2, defargfn2, 2, 3) -KAGUYA_TEST_FUNCTION_DEF(defaultarguments)(kaguya::State& state) -{ - state.setErrorHandler(error_fun); - state["defargfn"] = kaguya::function(defargfn_wrapper()); - state["defargfn2"] = kaguya::function(defargfn_wrapper2()); - - std::string intname = kaguya::util::pretty_name(typeid(int)); - - if (intname == "int") - { - state.dostring("defargfn('abc')"); - TEST_CHECK_M(last_error_message.find("[OPT]int,[OPT]int,[OPT]int") != std::string::npos, last_error_message); - state.dostring("defargfn2('abc',3)"); - TEST_CHECK_M(last_error_message.find("int,int,[OPT]int") != std::string::npos, last_error_message); - } +KAGUYA_TEST_FUNCTION_DEF(defaultarguments)(kaguya::State &state) { + state.setErrorHandler(error_fun); + state["defargfn"] = kaguya::function(defargfn_wrapper()); + state["defargfn2"] = kaguya::function(defargfn_wrapper2()); + + std::string intname = kaguya::util::pretty_name(typeid(int)); + + if (intname == "int") { + state.dostring("defargfn('abc')"); + TEST_CHECK_M(last_error_message.find("[OPT]int,[OPT]int,[OPT]int") != + std::string::npos, + last_error_message); + state.dostring("defargfn2('abc',3)"); + TEST_CHECK_M(last_error_message.find("int,int,[OPT]int") != + std::string::npos, + last_error_message); + } } - - KAGUYA_TEST_GROUP_END(test_14_error_message) diff --git a/test/test_20_max_arg_20.cpp b/test/test_20_max_arg_20.cpp index b81dd51..7aa3ae4 100644 --- a/test/test_20_max_arg_20.cpp +++ b/test/test_20_max_arg_20.cpp @@ -5,68 +5,66 @@ KAGUYA_TEST_GROUP_START(test_20_max_arg_20) using namespace kaguya_test_util; - using namespace kaguya; - -void defargfn(int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8,int a9,int a10=10,int a11=11,int a12=12,int a13=13,int a14=14,int a15=15,int a16=16,int a17=17,int a18=18,int a19 = 19,int a20 = 20) -{ - TEST_EQUAL(a1, 1); - TEST_EQUAL(a2, 2); - TEST_EQUAL(a3, 3); - TEST_EQUAL(a4, 4); - TEST_EQUAL(a5, 5); - TEST_EQUAL(a6, 6); - TEST_EQUAL(a7, 7); - TEST_EQUAL(a8, 8); - TEST_EQUAL(a9, 9); - TEST_EQUAL(a10, 10); - TEST_EQUAL(a11, 11); - TEST_EQUAL(a12, 12); - TEST_EQUAL(a13, 13); - TEST_EQUAL(a14, 14); - TEST_EQUAL(a15, 15); - TEST_EQUAL(a16, 16); - TEST_EQUAL(a17, 17); - TEST_EQUAL(a18, 18); - TEST_EQUAL(a19, 19); - TEST_EQUAL(a20, 20); +void defargfn(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, + int a9, int a10 = 10, int a11 = 11, int a12 = 12, int a13 = 13, + int a14 = 14, int a15 = 15, int a16 = 16, int a17 = 17, + int a18 = 18, int a19 = 19, int a20 = 20) { + TEST_EQUAL(a1, 1); + TEST_EQUAL(a2, 2); + TEST_EQUAL(a3, 3); + TEST_EQUAL(a4, 4); + TEST_EQUAL(a5, 5); + TEST_EQUAL(a6, 6); + TEST_EQUAL(a7, 7); + TEST_EQUAL(a8, 8); + TEST_EQUAL(a9, 9); + TEST_EQUAL(a10, 10); + TEST_EQUAL(a11, 11); + TEST_EQUAL(a12, 12); + TEST_EQUAL(a13, 13); + TEST_EQUAL(a14, 14); + TEST_EQUAL(a15, 15); + TEST_EQUAL(a16, 16); + TEST_EQUAL(a17, 17); + TEST_EQUAL(a18, 18); + TEST_EQUAL(a19, 19); + TEST_EQUAL(a20, 20); } -KAGUYA_TEST_FUNCTION_DEF(many_arg_fn)(kaguya::State& state) -{ - state["f"] = kaguya::function(&defargfn); - state.dostring("f(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)"); +KAGUYA_TEST_FUNCTION_DEF(many_arg_fn)(kaguya::State &state) { + state["f"] = kaguya::function(&defargfn); + state.dostring("f(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)"); } KAGUYA_FUNCTION_OVERLOADS(defargfn_wrapper, defargfn, 10, 20) -KAGUYA_TEST_FUNCTION_DEF(defaultarguments)(kaguya::State& state) -{ - state["defargfn"] = kaguya::function(defargfn_wrapper()); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)"); - state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)"); +KAGUYA_TEST_FUNCTION_DEF(defaultarguments)(kaguya::State &state) { + state["defargfn"] = kaguya::function(defargfn_wrapper()); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)"); + state.dostring("defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)"); + state.dostring( + "defargfn(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)"); } - -KAGUYA_TEST_FUNCTION_DEF(many_overloads)(kaguya::State& state) -{ - state["defargfn"] = kaguya::UserdataMetatable() - .setConstructors < - TestClass(), TestClass(), TestClass(), TestClass(), TestClass() - , TestClass(), TestClass(), TestClass(), TestClass(), TestClass() - , TestClass(), TestClass(), TestClass(), TestClass(), TestClass() - , TestClass(), TestClass(), TestClass(), TestClass(), TestClass() - , TestClass(), TestClass(), TestClass(), TestClass(), TestClass() - > (); +KAGUYA_TEST_FUNCTION_DEF(many_overloads)(kaguya::State &state) { + state["defargfn"] = + kaguya::UserdataMetatable() + .setConstructors(); } KAGUYA_TEST_GROUP_END(test_20_max_arg_20) diff --git a/test/test_main.cpp b/test/test_main.cpp index ec0771e..4a3275c 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -1,29 +1,25 @@ -#include -#include -#include +#include +#include +#include #include "test_util.hpp" -int main(int argc,const char* argv[]) -{ - std::vector test_set; +int main(int argc, const char *argv[]) { + std::vector test_set; - const std::string run_test_opt = "--run_test="; - for (int i = 1; i < argc; ++i) - { - if (strncmp(argv[i], run_test_opt.c_str(), run_test_opt.size()) == 0) - { - std::stringstream opt(argv[i] + run_test_opt.size()); - while (opt.good()) - { - std::string testname; - getline(opt, testname, ','); - test_set.push_back(testname); - } - } - } - kaguya_test_util::TestRunner::instance().set_test_set(test_set); + const std::string run_test_opt = "--run_test="; + for (int i = 1; i < argc; ++i) { + if (strncmp(argv[i], run_test_opt.c_str(), run_test_opt.size()) == 0) { + std::stringstream opt(argv[i] + run_test_opt.size()); + while (opt.good()) { + std::string testname; + getline(opt, testname, ','); + test_set.push_back(testname); + } + } + } + kaguya_test_util::TestRunner::instance().set_test_set(test_set); - bool test_result = kaguya_test_util::TestRunner::instance().execute(); - return test_result ? 0 : -1; + bool test_result = kaguya_test_util::TestRunner::instance().execute(); + return test_result ? 0 : -1; } diff --git a/test/test_util.hpp b/test/test_util.hpp index 44eeb33..a3893ed 100644 --- a/test/test_util.hpp +++ b/test/test_util.hpp @@ -6,305 +6,275 @@ #include #include "kaguya/kaguya.hpp" -namespace kaguya_test_util -{ - inline std::string to_string(int v) - { - char buffer[64] = {}; +namespace kaguya_test_util { +inline std::string to_string(int v) { + char buffer[64] = {}; #if (defined(_MSC_VER) && _MSC_VER < 1900) - sprintf_s(buffer, "%d", v); + sprintf_s(buffer, "%d", v); #else - snprintf(buffer, 64, "%d", v); + snprintf(buffer, 64, "%d", v); #endif - return buffer; - } - inline std::string to_string(size_t v) - { - return to_string(int(v)); - } - - inline std::vector split(std::string s, const char delim) - { - std::vector result; - std::size_t pos; - while ((pos = s.find(delim)) != std::string::npos) - { - result.push_back(s.substr(0, pos)); - s = s.substr(pos + 1); - } - result.push_back(s); - return result; - } - inline std::vector remove_empty(const std::vector& src) - { - std::vector result; - result.reserve(src.size()); - for (std::vector::const_iterator i = src.begin(); i != src.end(); ++i) - { - if (!i->empty()) - { - result.push_back(*i); - } - } - return result; - } - - - typedef void(*TestFunctionType)(kaguya::State&); - - class TestRunner - { - TestRunner() {} - TestRunner(const TestRunner&); - TestRunner& operator=(const TestRunner&); - - - typedef std::map TestFunctionMapType; - - TestFunctionMapType test_functions_; - - std::vector test_set_; - public: - void set_test_set(std::vector container) - { - test_set_ = container; - } - static TestRunner& instance() - { - static TestRunner ins; - return ins; - } - static void test_error_handler(int , const char* message) - { - throw std::runtime_error(std::string(message)); - } - bool is_name_execute(const std::string& name)const - { - if (test_set_.empty()) { return true; } - for (std::vector::const_iterator it = test_set_.begin(); it != test_set_.end(); ++it) - { - if (name.find(*it) != std::string::npos) - { - return true; - } - } - - return false; - } - TestFunctionMapType tests() - { - TestFunctionMapType tests; - for (TestFunctionMapType::const_iterator it = test_functions_.begin(); it != test_functions_.end(); ++it) - { - if (!is_name_execute(it->first)) { continue; } - tests.insert(*it); - } - return tests; - } - - void addTest(const std::string& name, TestFunctionType function) - { - test_functions_[name] = function; - } - - bool execute() - { - TestFunctionMapType test_function = tests(); - bool fail = false; - size_t testcount = test_function.size(); - size_t testindex = 1; - - std::vector pass_tests; - std::vector fail_tests; - for (TestFunctionMapType::const_iterator it = test_function.begin(); it != test_function.end(); ++it, ++testindex) - { - const std::string& test_name = it->first; - - kaguya::State state; - - state.setErrorHandler(test_error_handler); - - - std::cout << test_name << " (" << testindex << "/" << testcount << ") ..."; - - std::string error_message = ""; - std::cout << std::flush; - bool result = false; - try - { - it->second(state); - result = true; - } - catch (std::exception& e) - { - result = false; - std::cout << e.what() << std::endl; - error_message = e.what(); - } - catch (...) - { - result = false; - std::cout << "unknown exception" << std::endl; - error_message = "unknown exception"; - } - - if (result) - { - //test pass - int stack_leak = lua_gettop(state.state()); - if (stack_leak == 0) - { - std::cout << "pass" << std::endl; - pass_tests.push_back(test_name); - } - else - { - std::cout << "pass. but stack leaked, count=" << stack_leak << std::endl; - fail = true; - error_message = "stack leaked, count =" + to_string(stack_leak); - fail_tests.push_back(test_name + " msg: " + error_message); - } - } - else - { - //test failure - std::cout << "Failed" << std::endl; - fail = true; - fail_tests.push_back(test_name + "\n\t error msg: " + error_message); - } - } - std::cout << std::endl; - int percent = int(pass_tests.size() * 100 / test_function.size()); - std::cout << percent << "% tests passed." << std::endl; - if (!fail_tests.empty()) - { - std::cout << "The following tests FAILED:" << std::endl; - - for (size_t i = 0; i < fail_tests.size(); ++i) - { - std::cout << fail_tests[i] << std::endl; - } - - std::cout << std::endl; - - } - return !fail; - } - - }; - - //test target class - struct TestClass - { - int intmember; - std::string stringmember; - TestClass() :intmember(0) {} - TestClass(int a) :intmember(a) { } - TestClass(const char* a) :intmember(0), stringmember(a) { } - TestClass(std::string a) :intmember(0), stringmember(a) { } - TestClass(int intmem, const std::string& strmem) :intmember(intmem), stringmember(strmem) { } - TestClass(const std::string& strmem, int intmem) :intmember(intmem), stringmember(strmem) { } - TestClass(const TestClass&src) :intmember(src.intmember), stringmember(src.stringmember) {} - - bool operator ==(const TestClass& rhs)const { - return intmember == rhs.intmember && stringmember == rhs.stringmember; - } - bool operator <(const TestClass& rhs)const { - return intmember < rhs.intmember || (intmember == rhs.intmember && stringmember < rhs.stringmember); - } - bool operator !=(const TestClass& rhs)const { - return !(*this == rhs); - } - bool operator >(const TestClass& rhs)const { - return (rhs < *this); - } - bool operator >=(const TestClass& rhs)const { - return !(*this < rhs); - } - bool operator <=(const TestClass& rhs)const { - return !(*this > rhs); - } - int getInt() const { - return intmember; - } - void setInt(const int& n) { - intmember = n; - } - std::string getString()const { - return stringmember; - } - void setString(std::string str) { stringmember = str; } - - int default_arg(int a = 3, int b = 2, int c = 1) - { - return a*b*c; - } - void default_set(int a = 3, int b = 2, int c = 1) - { - setInt(a*b*c); - } - void default_set_overload(int a, int b = 2, int c = 1) - { - setInt(a*b*c); - } - void default_set_overload(std::string a, std::string b = "b", std::string c = "c") - { - setString(a+b+c); - } - - TestClass copy()const { return *this; } - const TestClass& references()const { return *this; } - const TestClass& const_references()const { return *this; } - TestClass& references() { return *this; } - TestClass* pointer() { return this; } - const TestClass* const_pointer()const { return this; } - kaguya::standard::shared_ptr shared_copy() { return kaguya::standard::shared_ptr(new TestClass(*this)); } - }; - - + return buffer; +} +inline std::string to_string(size_t v) { return to_string(int(v)); } + +inline std::vector split(std::string s, const char delim) { + std::vector result; + std::size_t pos; + while ((pos = s.find(delim)) != std::string::npos) { + result.push_back(s.substr(0, pos)); + s = s.substr(pos + 1); + } + result.push_back(s); + return result; +} +inline std::vector +remove_empty(const std::vector &src) { + std::vector result; + result.reserve(src.size()); + for (std::vector::const_iterator i = src.begin(); i != src.end(); + ++i) { + if (!i->empty()) { + result.push_back(*i); + } + } + return result; +} +typedef void (*TestFunctionType)(kaguya::State &); + +class TestRunner { + TestRunner() {} + TestRunner(const TestRunner &); + TestRunner &operator=(const TestRunner &); + + typedef std::map TestFunctionMapType; + + TestFunctionMapType test_functions_; + + std::vector test_set_; + +public: + void set_test_set(std::vector container) { + test_set_ = container; + } + static TestRunner &instance() { + static TestRunner ins; + return ins; + } + static void test_error_handler(int, const char *message) { + throw std::runtime_error(std::string(message)); + } + bool is_name_execute(const std::string &name) const { + if (test_set_.empty()) { + return true; + } + for (std::vector::const_iterator it = test_set_.begin(); + it != test_set_.end(); ++it) { + if (name.find(*it) != std::string::npos) { + return true; + } + } + + return false; + } + TestFunctionMapType tests() { + TestFunctionMapType tests; + for (TestFunctionMapType::const_iterator it = test_functions_.begin(); + it != test_functions_.end(); ++it) { + if (!is_name_execute(it->first)) { + continue; + } + tests.insert(*it); + } + return tests; + } + + void addTest(const std::string &name, TestFunctionType function) { + test_functions_[name] = function; + } + + bool execute() { + TestFunctionMapType test_function = tests(); + bool fail = false; + size_t testcount = test_function.size(); + size_t testindex = 1; + + std::vector pass_tests; + std::vector fail_tests; + for (TestFunctionMapType::const_iterator it = test_function.begin(); + it != test_function.end(); ++it, ++testindex) { + const std::string &test_name = it->first; + + kaguya::State state; + + state.setErrorHandler(test_error_handler); + + std::cout << test_name << " (" << testindex << "/" << testcount + << ") ..."; + + std::string error_message = ""; + std::cout << std::flush; + bool result = false; + try { + it->second(state); + result = true; + } catch (std::exception &e) { + result = false; + std::cout << e.what() << std::endl; + error_message = e.what(); + } catch (...) { + result = false; + std::cout << "unknown exception" << std::endl; + error_message = "unknown exception"; + } + + if (result) { + // test pass + int stack_leak = lua_gettop(state.state()); + if (stack_leak == 0) { + std::cout << "pass" << std::endl; + pass_tests.push_back(test_name); + } else { + std::cout << "pass. but stack leaked, count=" << stack_leak + << std::endl; + fail = true; + error_message = "stack leaked, count =" + to_string(stack_leak); + fail_tests.push_back(test_name + " msg: " + error_message); + } + } else { + // test failure + std::cout << "Failed" << std::endl; + fail = true; + fail_tests.push_back(test_name + "\n\t error msg: " + error_message); + } + } + std::cout << std::endl; + int percent = int(pass_tests.size() * 100 / test_function.size()); + std::cout << percent << "% tests passed." << std::endl; + if (!fail_tests.empty()) { + std::cout << "The following tests FAILED:" << std::endl; + + for (size_t i = 0; i < fail_tests.size(); ++i) { + std::cout << fail_tests[i] << std::endl; + } + + std::cout << std::endl; + } + return !fail; + } +}; + +// test target class +struct TestClass { + int intmember; + std::string stringmember; + TestClass() : intmember(0) {} + TestClass(int a) : intmember(a) {} + TestClass(const char *a) : intmember(0), stringmember(a) {} + TestClass(std::string a) : intmember(0), stringmember(a) {} + TestClass(int intmem, const std::string &strmem) + : intmember(intmem), stringmember(strmem) {} + TestClass(const std::string &strmem, int intmem) + : intmember(intmem), stringmember(strmem) {} + TestClass(const TestClass &src) + : intmember(src.intmember), stringmember(src.stringmember) {} + + bool operator==(const TestClass &rhs) const { + return intmember == rhs.intmember && stringmember == rhs.stringmember; + } + bool operator<(const TestClass &rhs) const { + return intmember < rhs.intmember || + (intmember == rhs.intmember && stringmember < rhs.stringmember); + } + bool operator!=(const TestClass &rhs) const { return !(*this == rhs); } + bool operator>(const TestClass &rhs) const { return (rhs < *this); } + bool operator>=(const TestClass &rhs) const { return !(*this < rhs); } + bool operator<=(const TestClass &rhs) const { return !(*this > rhs); } + int getInt() const { return intmember; } + void setInt(const int &n) { intmember = n; } + std::string getString() const { return stringmember; } + void setString(std::string str) { stringmember = str; } + + int default_arg(int a = 3, int b = 2, int c = 1) { return a * b * c; } + void default_set(int a = 3, int b = 2, int c = 1) { setInt(a * b * c); } + void default_set_overload(int a, int b = 2, int c = 1) { setInt(a * b * c); } + void default_set_overload(std::string a, std::string b = "b", + std::string c = "c") { + setString(a + b + c); + } + + TestClass copy() const { return *this; } + const TestClass &references() const { return *this; } + const TestClass &const_references() const { return *this; } + TestClass &references() { return *this; } + TestClass *pointer() { return this; } + const TestClass *const_pointer() const { return this; } + kaguya::standard::shared_ptr shared_copy() { + return kaguya::standard::shared_ptr(new TestClass(*this)); + } +}; } #if KAGUYA_USE_CPP11 -inline std::ostream& operator << (std::ostream& os, std::nullptr_t) -{ - return os << "nullptr"; +inline std::ostream &operator<<(std::ostream &os, std::nullptr_t) { + return os << "nullptr"; } #endif -#define TEST_CHECK(B) if(!(B)) throw std::runtime_error( std::string("failed.\nfunction:") +__FUNCTION__ + std::string("\nline:") + kaguya_test_util::to_string(__LINE__) + "\nCHECKCODE:" #B ); - -#define TEST_CHECK_M(B,M) if(!(B)) throw std::runtime_error(M + std::string("\nfunction:") +__FUNCTION__ + std::string("\nline:") + kaguya_test_util::to_string(__LINE__) + "\nCHECKCODE:" #B ); - -#define TEST_COMPARE(A,B,OP) if(!((A) OP (B)))\ -{\ -std::stringstream ss;\ -ss << "failed.\nfunction:" << __FUNCTION__ << std::endl \ -<< " line:" << __LINE__<< std::endl \ -<< " CHECKCODE:"#A #OP #B << std::endl \ -<< " left:" << (A) << std::endl \ -<< " right:" << (B) << std::endl; \ - throw std::runtime_error(ss.str());\ +#define TEST_CHECK(B) \ + if (!(B)) \ + throw std::runtime_error(std::string("failed.\nfunction:") + \ + __FUNCTION__ + std::string("\nline:") + \ + kaguya_test_util::to_string(__LINE__) + \ + "\nCHECKCODE:" #B); + +#define TEST_CHECK_M(B, M) \ + if (!(B)) \ + throw std::runtime_error(M + std::string("\nfunction:") + __FUNCTION__ + \ + std::string("\nline:") + \ + kaguya_test_util::to_string(__LINE__) + \ + "\nCHECKCODE:" #B); + +#define TEST_COMPARE(A, B, OP) \ + if (!((A)OP(B))) \ +{ \ + \ +std::stringstream ss; \ + \ +ss << "failed.\nfunction:" \ + << __FUNCTION__ << std::endl \ + \ +<< " line:" << __LINE__ << std::endl \ + \ +<< " CHECKCODE:" #A #OP #B << std::endl \ + \ +<< " left:" << (A) << std::endl \ + \ +<< " right:" << (B) << std::endl; \ + throw std::runtime_error(ss.str()); \ + \ } -#define TEST_EQUAL(A,B) TEST_COMPARE(A,B,==) -#define TEST_COMPARE_EQ(A,B) TEST_COMPARE(A,B,==) -#define TEST_COMPARE_NE(A,B) TEST_COMPARE(A,B,!=) -#define TEST_COMPARE_LT(A,B) TEST_COMPARE(A,B,<) -#define TEST_COMPARE_LE(A,B) TEST_COMPARE(A,B,<=) -#define TEST_COMPARE_GT(A,B) TEST_COMPARE(A,B,>) -#define TEST_COMPARE_GE(A,B) TEST_COMPARE(A,B,>=) - - -#define KAGUYA_TEST_GROUP_START(TEST_GROUP) namespace TEST_GROUP{ static const char* kaguya_test_group_name= #TEST_GROUP; +#define TEST_EQUAL(A, B) TEST_COMPARE(A, B, ==) +#define TEST_COMPARE_EQ(A, B) TEST_COMPARE(A, B, ==) +#define TEST_COMPARE_NE(A, B) TEST_COMPARE(A, B, !=) +#define TEST_COMPARE_LT(A, B) TEST_COMPARE(A, B, <) +#define TEST_COMPARE_LE(A, B) TEST_COMPARE(A, B, <=) +#define TEST_COMPARE_GT(A, B) TEST_COMPARE(A, B, >) +#define TEST_COMPARE_GE(A, B) TEST_COMPARE(A, B, >=) + +#define KAGUYA_TEST_GROUP_START(TEST_GROUP) \ + namespace TEST_GROUP { \ + static const char *kaguya_test_group_name = #TEST_GROUP; #define KAGUYA_TEST_GROUP_END(TEST_GROUP) } - -#define KAGUYA_TEST_FUNCTION_DEF(TEST_NAME) void TEST_NAME(kaguya::State&);\ - struct TEST_NAME##_register\ - {\ - TEST_NAME##_register()\ - {\ - kaguya_test_util::TestRunner::instance().addTest(std::string(kaguya_test_group_name) + "::" + #TEST_NAME, &TEST_NAME);\ - }\ - } TEST_NAME##_register;\ - void TEST_NAME +#define KAGUYA_TEST_FUNCTION_DEF(TEST_NAME) \ + void TEST_NAME(kaguya::State &); \ + struct TEST_NAME##_register { \ + TEST_NAME##_register() { \ + kaguya_test_util::TestRunner::instance().addTest( \ + std::string(kaguya_test_group_name) + "::" + #TEST_NAME, \ + &TEST_NAME); \ + } \ + } TEST_NAME##_register; \ + void TEST_NAME