// The MIT License (MIT) // Copyright (c) 2013-2015 Danny Y., Rapptz // 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_TABLE_HPP #define SOL_TABLE_HPP #include "proxy.hpp" #include "stack.hpp" #include "function_types.hpp" #include "usertype.hpp" namespace sol { class table : public reference { friend class state; template typename stack::get_return::type single_get(U&& key) const { push(); stack::push(state(), std::forward(key)); lua_gettable(state(), -2); type_assert(state(), -1, type_of()); auto&& result = stack::pop(state()); lua_pop(state(), 1); return result; } template typename return_type::type...>::type tuple_get(types, indices, Keys&& keys) const { return std::make_tuple(single_get(std::get(keys))...); } template typename stack::get_return::type tuple_get(types, indices<0>, Keys&& keys) const { return single_get(std::get<0>(keys)); } public: table() noexcept : reference() {} table(lua_State* L, int index = -1) : reference(L, index) { type_assert(L, index, type::table); } template typename return_type::type...>::type get(Keys&&... keys) const { types tr; return tuple_get(tr, tr, std::make_tuple(std::forward(keys)...)); } template table& set(T&& key, U&& value) { push(); stack::push(state(), std::forward(key)); stack::push(state(), std::forward(value)); lua_settable(state(), -3); lua_pop(state(), 1); return *this; } template SOL_DEPRECATED table& set_userdata(usertype& user) { return set_usertype(user); } template SOL_DEPRECATED table& set_userdata(Key&& key, usertype& user) { return set_usertype(std::forward(key), user); } template table& set_usertype(usertype& user) { return set_usertype(usertype_traits::name, user); } template table& set_usertype(Key&& key, usertype& user) { push(); stack::push(state(), std::forward(key)); stack::push(state(), user); lua_settable(state(), -3); lua_pop(state(), 1); return *this; } template void for_each(Fx&& fx) const { push(); stack::push(state(), nil); while (lua_next(this->state(), -2)) { sol::object key(state(), -2); sol::object value(state(), -1); fx(key, value); lua_pop(state(), 1); } pop(); } size_t size() const { push(); size_t result = lua_rawlen(state(), -1); pop(); return result; } template proxy operator[](T&& key) { return proxy(*this, std::forward(key)); } template proxy operator[](T&& key) const { return proxy(*this, std::forward(key)); } void pop(int n = 1) const noexcept { lua_pop(state(), n); } template table& set_function(Key&& key, R fun_ptr(Args...)){ set_resolved_function(std::forward(key), fun_ptr); return *this; } template table& set_function(Key&& key, Sig* fun_ptr){ set_resolved_function(std::forward(key), fun_ptr); return *this; } template table& set_function(Key&& key, R (C::*mem_ptr)(Args...), T&& obj) { set_resolved_function(std::forward(key), mem_ptr, std::forward(obj)); return *this; } template table& set_function(Key&& key, Sig C::* mem_ptr, T&& obj) { set_resolved_function(std::forward(key), mem_ptr, std::forward(obj)); return *this; } template table& set_function(Key&& key, Fx&& fx) { set_fx(types(), std::forward(key), std::forward(fx)); return *this; } private: template::type> void set_fx(types, Key&& key, Fx&& fx) { set_resolved_function(std::forward(key), std::forward(fx)); } template void set_fx(types<>, Key&& key, Fx&& fx) { typedef Unqualified> fx_t; typedef decltype(&fx_t::operator()) Sig; set_fx(types>(), std::forward(key), std::forward(fx)); } template void set_resolved_function(Key&& key, Args&&... args) { std::string fkey(std::forward(key)); push(); int tabletarget = lua_gettop(state()); stack::push>(state(), std::forward(args)...); lua_setfield(state(), tabletarget, fkey.c_str()); pop(); } }; } // sol #endif // SOL_TABLE_HPP