From dc2493e7525bb7633f697ef10f72b72b46222249 Mon Sep 17 00:00:00 2001 From: Andy Belle-Isle Date: Fri, 30 Aug 2019 00:45:36 -0400 Subject: Forget what I said, I just need to change git attributes to mark for vendor --- lib/sol2/include/sol/proxy.hpp | 324 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 lib/sol2/include/sol/proxy.hpp (limited to 'lib/sol2/include/sol/proxy.hpp') diff --git a/lib/sol2/include/sol/proxy.hpp b/lib/sol2/include/sol/proxy.hpp new file mode 100644 index 0000000..9993ca2 --- /dev/null +++ b/lib/sol2/include/sol/proxy.hpp @@ -0,0 +1,324 @@ +// sol3 + +// The MIT License (MIT) + +// Copyright (c) 2013-2019 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_PROXY_HPP +#define SOL_PROXY_HPP + +#include "traits.hpp" +#include "function.hpp" +#include "protected_function.hpp" +#include "proxy_base.hpp" + +namespace sol { + + template + struct proxy : public proxy_base> { + private: + using key_type = detail::proxy_key_t; + + template + decltype(auto) tuple_get(std::index_sequence) const & { + return tbl.template traverse_get(std::get(key)...); + } + + template + decltype(auto) tuple_get(std::index_sequence) && { + return tbl.template traverse_get(std::get(std::move(key))...); + } + + template + void tuple_set(std::index_sequence, T&& value) & { + tbl.traverse_set(std::get(key)..., std::forward(value)); + } + + template + void tuple_set(std::index_sequence, T&& value) && { + tbl.traverse_set(std::get(std::move(key))..., std::forward(value)); + } + + auto setup_table(std::true_type) { + auto p = stack::probe_get_field, global_table>>(lua_state(), key, tbl.stack_index()); + lua_pop(lua_state(), p.levels); + return p; + } + + bool is_valid(std::false_type) { + auto pp = stack::push_pop(tbl); + auto p = stack::probe_get_field, global_table>>(lua_state(), key, lua_gettop(lua_state())); + lua_pop(lua_state(), p.levels); + return p; + } + + public: + Table tbl; + key_type key; + + template + proxy(Table table, T&& k) + : tbl(table), key(std::forward(k)) { + } + + template + proxy& set(T&& item) & { + tuple_set(std::make_index_sequence>>(), std::forward(item)); + return *this; + } + + template + proxy&& set(T&& item) && { + tuple_set(std::make_index_sequence>>(), std::forward(item)); + return std::move(*this); + } + + template + proxy& set_function(Args&&... args) & { + tbl.set_function(key, std::forward(args)...); + return *this; + } + + template + proxy&& set_function(Args&&... args) && { + tbl.set_function(std::move(key), std::forward(args)...); + return std::move(*this); + } + + template + proxy& operator=(T&& other) & { + using Tu = meta::unwrap_unqualified_t; + if constexpr (!is_lua_reference_or_proxy_v && meta::is_callable_v) { + return set_function(std::forward(other)); + } + else { + return set(std::forward(other)); + } + } + + template + proxy&& operator=(T&& other) && { + using Tu = meta::unwrap_unqualified_t; + if constexpr (!is_lua_reference_or_proxy_v && meta::is_callable_v) { + return std::move(*this).set_function(std::forward(other)); + } + else { + return std::move(*this).set(std::forward(other)); + } + } + + template + proxy& operator=(std::initializer_list other) & { + return set(std::move(other)); + } + + template + proxy&& operator=(std::initializer_list other) && { + return std::move(*this).set(std::move(other)); + } + + template + decltype(auto) get() const & { + using idx_seq = std::make_index_sequence>>; + return tuple_get(idx_seq()); + } + + template + decltype(auto) get() && { + using idx_seq = std::make_index_sequence>>; + return std::move(*this).template tuple_get(idx_seq()); + } + + template + decltype(auto) get_or(T&& otherwise) const { + typedef decltype(get()) U; + optional option = get>(); + if (option) { + return static_cast(option.value()); + } + return static_cast(std::forward(otherwise)); + } + + template + decltype(auto) get_or(D&& otherwise) const { + optional option = get>(); + if (option) { + return static_cast(option.value()); + } + return static_cast(std::forward(otherwise)); + } + + + template + decltype(auto) get_or_create() { + return get_or_create(new_table()); + } + + template + decltype(auto) get_or_create(Otherwise&& other) { + if (!this->valid()) { + this->set(std::forward(other)); + } + return get(); + } + + template + decltype(auto) operator[](K&& k) const& { + auto keys = meta::tuplefy(key, std::forward(k)); + return proxy(tbl, std::move(keys)); + } + + template + decltype(auto) operator[](K&& k) & { + auto keys = meta::tuplefy(key, std::forward(k)); + return proxy(tbl, std::move(keys)); + } + + template + decltype(auto) operator[](K&& k) && { + auto keys = meta::tuplefy(std::move(key), std::forward(k)); + return proxy(tbl, std::move(keys)); + } + + template + decltype(auto) call(Args&&... args) { +#if !defined(__clang__) && defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 191200000 + // MSVC is ass sometimes + return get().call(std::forward(args)...); +#else + return get().template call(std::forward(args)...); +#endif + } + + template + decltype(auto) operator()(Args&&... args) { + return call<>(std::forward(args)...); + } + + bool valid() const { + auto pp = stack::push_pop(tbl); + auto p = stack::probe_get_field, global_table>::value>(lua_state(), key, lua_gettop(lua_state())); + lua_pop(lua_state(), p.levels); + return p; + } + + int push() const noexcept { + return push(this->lua_state()); + } + + int push(lua_State* L) const noexcept { + return get().push(L); + } + + type get_type() const { + type t = type::none; + auto pp = stack::push_pop(tbl); + auto p = stack::probe_get_field, global_table>::value>(lua_state(), key, lua_gettop(lua_state())); + if (p) { + t = type_of(lua_state(), -1); + } + lua_pop(lua_state(), p.levels); + return t; + } + + lua_State* lua_state() const { + return tbl.lua_state(); + } + + proxy& force() { + if (!this->valid()) { + this->set(new_table()); + } + return *this; + } + }; + + template + inline bool operator==(T&& left, const proxy& right) { + using G = decltype(stack::get(nullptr, 0)); + return right.template get>() == left; + } + + template + inline bool operator==(const proxy& right, T&& left) { + using G = decltype(stack::get(nullptr, 0)); + return right.template get>() == left; + } + + template + inline bool operator!=(T&& left, const proxy& right) { + using G = decltype(stack::get(nullptr, 0)); + return right.template get>() != left; + } + + template + inline bool operator!=(const proxy& right, T&& left) { + using G = decltype(stack::get(nullptr, 0)); + return right.template get>() != left; + } + + template + inline bool operator==(lua_nil_t, const proxy& right) { + return !right.valid(); + } + + template + inline bool operator==(const proxy& right, lua_nil_t) { + return !right.valid(); + } + + template + inline bool operator!=(lua_nil_t, const proxy& right) { + return right.valid(); + } + + template + inline bool operator!=(const proxy& right, lua_nil_t) { + return right.valid(); + } + + template + template + basic_reference& basic_reference::operator=(proxy_base&& r) { + basic_reference v = r; + this->operator=(std::move(v)); + return *this; + } + + template + template + basic_reference& basic_reference::operator=(const proxy_base& r) { + basic_reference v = r; + this->operator=(std::move(v)); + return *this; + } + + namespace stack { + template + struct unqualified_pusher> { + static int push(lua_State* L, const proxy& p) { + reference r = p; + return r.push(L); + } + }; + } // namespace stack +} // namespace sol + +#endif // SOL_PROXY_HPP -- cgit v1.2.3