// sol2 // The MIT License (MIT) // Copyright (c) 2013-2022 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_USERTYPE_HPP #define SOL_USERTYPE_HPP #include #include #include #include #include namespace sol { template class basic_usertype : private basic_metatable { private: using base_t = basic_metatable; using table_base_t = basic_table; template friend class basic_metatable; template friend class basic_table_core; template void tuple_set(std::index_sequence, std::tuple&& args) { (void)args; (void)detail::swallow { 0, (this->set(std::get(std::move(args)), std::get(std::move(args))), 0)... }; } template > void set_fx(types, Key&& key, Fx&& fx) { set_resolved_function(std::forward(key), std::forward(fx)); } template , overload_set>> = meta::enabler> void set_fx(types<>, Key&& key, Fx&& fx) { set(std::forward(key), std::forward(fx)); } template , overload_set>> = meta::enabler> void set_fx(types<>, Key&& key, Fx&& fx, Args&&... args) { set(std::forward(key), as_function_reference(std::forward(fx), std::forward(args)...)); } template void set_resolved_function(Key&& key, Args&&... args) { set(std::forward(key), as_function_reference>(std::forward(args)...)); } public: using base_t::base_t; using base_t::get; using base_t::lua_state; using base_t::pop; using base_t::push; using base_t::traverse_get; using base_t::traverse_set; using base_t::unregister; template basic_usertype& set(Key&& key, Value&& value) { optional&> maybe_uts = u_detail::maybe_get_usertype_storage(this->lua_state()); if (maybe_uts) { u_detail::usertype_storage& uts = *maybe_uts; uts.set(this->lua_state(), std::forward(key), std::forward(value)); } else { using ValueU = meta::unqualified_t; // cannot get metatable: try regular table set? if constexpr (detail::is_non_factory_constructor_v || detail::is_policy_v) { // tag constructors so we don't get destroyed by lack of info table_base_t::set(std::forward(key), detail::tagged(std::forward(value))); } else { table_base_t::set(std::forward(key), std::forward(value)); } } return *this; } template basic_usertype& set_function(Key&& key, Args&&... args) { set_fx(types(), std::forward(key), std::forward(args)...); return *this; } template basic_usertype& set_function(Key&& key, Args&&... args) { set_fx(types<>(), std::forward(key), std::forward(args)...); return *this; } template usertype_proxy> operator[](Key&& key) { return usertype_proxy>(*this, std::forward(key)); } template usertype_proxy> operator[](Key&& key) const { return usertype_proxy>(*this, std::forward(key)); } }; } // namespace sol #endif // SOL_USERTYPE_HPP