// The MIT License (MIT) // Copyright (c) 2013-2016 Rapptz, ThePhD and contributors // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef SOL_STACK_FIELD_HPP #define SOL_STACK_FIELD_HPP #include "stack_core.hpp" #include "stack_push.hpp" #include "stack_get.hpp" #include "stack_check_get.hpp" namespace sol { namespace stack { template struct field_getter { template void get(lua_State* L, Key&& key, int tableindex = -2) { push( L, std::forward( key ) ); lua_gettable( L, tableindex ); } }; template struct field_getter { void get(lua_State* L, metatable_key_t, int tableindex = -1) { if (lua_getmetatable(L, tableindex) == 0) push(L, nil); } }; template struct field_getter::value>> { template void get(lua_State* L, Key&& key, int = -1) { lua_getglobal(L, &key[0]); } }; template struct field_getter::value>> { template void get(lua_State* L, Key&& key, int tableindex = -1) { lua_getfield(L, tableindex, &key[0]); } }; #if SOL_LUA_VERSION >= 503 template struct field_getter::value>> { template void get(lua_State* L, Key&& key, int tableindex = -1) { lua_geti(L, tableindex, static_cast(key)); } }; #endif // Lua 5.3.x #if SOL_LUA_VERSION >= 502 template struct field_getter { void get(lua_State* L, void* key, int tableindex = -1) { lua_rawgetp(L, tableindex, key); } }; #endif // Lua 5.3.x template struct field_getter::value>> { template void get(lua_State* L, Key&& key, int tableindex = -1) { lua_rawgeti(L, tableindex, static_cast(key)); } }; template struct field_getter, b, raw, C> { template void apply(std::index_sequence<0, I...>, lua_State* L, Keys&& keys, int tableindex) { get_field(L, detail::forward_get<0>(keys), tableindex); void(detail::swallow{ (get_field(L, detail::forward_get(keys)), 0)... }); reference saved(L, -1); lua_pop(L, static_cast(sizeof...(I))); saved.push(); } template void get(lua_State* L, Keys&& keys) { apply(std::make_index_sequence(), L, std::forward(keys), lua_absindex(L, -1)); } template void get(lua_State* L, Keys&& keys, int tableindex) { apply(std::make_index_sequence(), L, std::forward(keys), tableindex); } }; template struct field_getter, b, raw, C> { template void get(lua_State* L, Keys&& keys, int tableindex) { get_field(L, detail::forward_get<0>(keys), tableindex); get_field(L, detail::forward_get<1>(keys)); reference saved(L, -1); lua_pop(L, static_cast(2)); saved.push(); } template void get(lua_State* L, Keys&& keys) { get_field(L, detail::forward_get<0>(keys)); get_field(L, detail::forward_get<1>(keys)); reference saved(L, -1); lua_pop(L, static_cast(2)); saved.push(); } }; template struct field_setter { template void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) { push(L, std::forward(key)); push(L, std::forward(value)); lua_settable(L, tableindex); } }; template struct field_setter { template void set(lua_State* L, Key&& key, Value&& value, int tableindex = -3) { push(L, std::forward(key)); push(L, std::forward(value)); lua_rawset(L, tableindex); } }; template struct field_setter { template void set(lua_State* L, metatable_key_t, Value&& value, int tableindex = -2) { push(L, std::forward(value)); lua_setmetatable(L, tableindex); } }; template struct field_setter::value>> { template void set(lua_State* L, Key&& key, Value&& value, int = -2) { push(L, std::forward(value)); lua_setglobal(L, &key[0]); } }; template struct field_setter::value>> { template void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) { push(L, std::forward(value)); lua_setfield(L, tableindex, &key[0]); } }; #if SOL_LUA_VERSION >= 503 template struct field_setter::value>> { template void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) { push(L, std::forward(value)); lua_seti(L, tableindex, static_cast(key)); } }; #endif // Lua 5.3.x template struct field_setter::value>> { template void set(lua_State* L, Key&& key, Value&& value, int tableindex = -2) { push(L, std::forward(value)); lua_rawseti(L, tableindex, static_cast(key)); } }; #if SOL_LUA_VERSION >= 502 template struct field_setter { template void set(lua_State* L, void* key, Value&& value, int tableindex = -2) { push(L, std::forward(value)); lua_rawsetp(L, tableindex, key); } }; #endif // Lua 5.2.x template struct field_setter, b, raw, C> { template void apply(std::index_sequence, lua_State* L, Key&& keys, Value&& value, int tableindex) { I < 1 ? set_field(L, detail::forward_get(keys), std::forward(value), tableindex) : set_field(L, detail::forward_get(keys), std::forward(value)); } template void apply(std::index_sequence, lua_State* L, Keys&& keys, Value&& value, int tableindex) { I0 < 1 ? get_field(L, detail::forward_get(keys), tableindex) : get_field(L, detail::forward_get(keys), -1); apply(std::index_sequence(), L, std::forward(keys), std::forward(value), -1); } template void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -3) { apply(std::make_index_sequence(), L, std::forward(keys), std::forward(value), tableindex); } }; template struct field_setter, b, raw, C> { template void set(lua_State* L, Keys&& keys, Value&& value, int tableindex = -1) { get_field(L, detail::forward_get<0>(keys), tableindex); set_field(L, detail::forward_get<1>(keys), std::forward(value)); } }; } // stack } // sol #endif // SOL_STACK_FIELD_HPP