mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Mmn. Always making lots and lots of small changes.
This commit is contained in:
parent
2ac711b7f8
commit
85329ca183
|
@ -61,7 +61,7 @@ author = 'ThePhD'
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '2.14'
|
version = '2.14'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '2.14.10'
|
release = '2.14.12'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|
|
@ -18,6 +18,11 @@ When you need to hit the ground running with Lua and C++, `Sol`_ is the go-to fr
|
||||||
:target: https://travis-ci.org/ThePhD/sol2
|
:target: https://travis-ci.org/ThePhD/sol2
|
||||||
:alt: build status
|
:alt: build status
|
||||||
|
|
||||||
|
.. image:: https://badges.gitter.im/chat-sol2/Lobby.svg
|
||||||
|
target: https://gitter.im/chat-sol2/Lobby
|
||||||
|
:alt: chat about sol2 on gitter
|
||||||
|
|
||||||
|
|
||||||
get going:
|
get going:
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -28,6 +33,7 @@ get going:
|
||||||
tutorial/all-the-things
|
tutorial/all-the-things
|
||||||
tutorial/tutorial-top
|
tutorial/tutorial-top
|
||||||
features
|
features
|
||||||
|
usertypes
|
||||||
api/api-top
|
api/api-top
|
||||||
mentions
|
mentions
|
||||||
benchmarks
|
benchmarks
|
||||||
|
@ -43,7 +49,7 @@ get going:
|
||||||
|
|
||||||
"I need feature X, maybe you have it?"
|
"I need feature X, maybe you have it?"
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the :doc:`api<api/api-top>` or ease in with the :doc:`tutorials<tutorial/tutorial-top>`. To know how function arguments are handled, see :ref:`this note<function-argument-handling>`. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
|
Take a look at the :doc:`Features<features>` page: it links to much of the API. You can also just straight up browse the :doc:`api<api/api-top>` or ease in with the :doc:`tutorials<tutorial/tutorial-top>`. To know more about the implementation for usertypes, see :doc:`here<usertypes>` To know how function arguments are handled, see :ref:`this note<function-argument-handling>`. Don't see a feature you want? Send inquiries for support for a particular abstraction to the `issues`_ tracker.
|
||||||
|
|
||||||
|
|
||||||
the basics:
|
the basics:
|
||||||
|
|
|
@ -108,6 +108,9 @@ A few things of note about the implementation: First, there's an auxiliary param
|
||||||
|
|
||||||
You can make something pushable into Lua, but not get-able in the same way if you only specialize one part of the system. If you need to retrieve it (as a return using one or multiple values from Lua), you should specialize the ``sol::stack::getter`` template class and the ``sol::stack::checker`` template class. If you need to push it into Lua at some point, then you'll want to specialize the ``sol::stack::pusher`` template class. The ``sol::lua_size`` template class trait needs to be specialized for both cases, unless it only pushes 1 item, in which case the default implementation will assume 1.
|
You can make something pushable into Lua, but not get-able in the same way if you only specialize one part of the system. If you need to retrieve it (as a return using one or multiple values from Lua), you should specialize the ``sol::stack::getter`` template class and the ``sol::stack::checker`` template class. If you need to push it into Lua at some point, then you'll want to specialize the ``sol::stack::pusher`` template class. The ``sol::lua_size`` template class trait needs to be specialized for both cases, unless it only pushes 1 item, in which case the default implementation will assume 1.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
It is important to note here that the ``getter``, ``pusher`` and ``checker`` differentiate between a type ``T`` and a pointer to a type ``T*``. This means that if you want to work purely with, say, a ``T*`` handle that does not have the same semantics as just ``T``, you may need to specify checkers/getters/pushers for both ``T*`` and ``T``. The checkers for ``T*`` forward to the checkers for ``T``, but the getter for ``T*`` does not forward to the getter for ``T`` (e.g., because of ``int*`` not being quite the same as ``int``).
|
||||||
|
|
||||||
In general, this is fine since most getters/checkers only use 1 stack point. But, if you're doing more complex nested classes, it would be useful to use ``tracking.last`` to understand how many stack indices the last getter/checker operation did and increment it by ``index + tracking.last`` after using a ``stack::check<..>( L, index, tracking)`` call.
|
In general, this is fine since most getters/checkers only use 1 stack point. But, if you're doing more complex nested classes, it would be useful to use ``tracking.last`` to understand how many stack indices the last getter/checker operation did and increment it by ``index + tracking.last`` after using a ``stack::check<..>( L, index, tracking)`` call.
|
||||||
|
|
||||||
|
|
25
docs/source/usertypes.rst
Normal file
25
docs/source/usertypes.rst
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
usertypes
|
||||||
|
=========
|
||||||
|
|
||||||
|
Perhaps the most powerful feature of sol2, ``usertypes`` are the way sol2 and C++ communicate your classes to the Lua runtime and bind things between both tables and to specific blocks of C++ memory, allowing you to treat Lua userdata and other things like classes.
|
||||||
|
|
||||||
|
To learn more about usertypes, visit:
|
||||||
|
|
||||||
|
* :doc:`tutorial<tutorial/cxx-in-lua>`
|
||||||
|
* :doc:`customization point tutorial<tutorial/customization>`
|
||||||
|
* :doc:`api documentation<api/usertype>`
|
||||||
|
* :doc:`memory documentation<api/usertype_memory>`
|
||||||
|
|
||||||
|
There are also some notes about guarantees you can find about usertypes, and their associated userdata, below:
|
||||||
|
|
||||||
|
* You can push types classified as userdata before you register a usertype.
|
||||||
|
- You can register a usertype with the Lua runtime at any time sol2
|
||||||
|
- You can retrieve them from the Lua runtime as well through sol2
|
||||||
|
- Methods and properties will be added to the type only after you register it in the Lua runtime
|
||||||
|
* Types either copy once or move once into the memory location, if it is a value type. If it is a pointer, we store only the reference.
|
||||||
|
- This means take arguments of class types (not primitive types like strings or integers) by ``T&`` or ``T*`` to modify the data in Lua directly, or by plain ``T`` to get a copy
|
||||||
|
- Return types and passing arguments to ``sol::function`` use perfect forwarding and reference semantics, which means no copies happen unless you specify a value explicitly. See :ref:`this note for details<function-argument-handling>`.
|
||||||
|
* The first ``sizeof( void* )`` bytes is always a pointer to the typed C++ memory. What comes after is based on what you've pushed into the system according to :doc:`the memory specification for usertypes<api/usertype_memory>`. This is compatible with a number of systems.
|
||||||
|
* Member methods, properties, variables and functions taking ``self&`` arguments modify data directly
|
||||||
|
- Work on a copy by taking or returning a copy by value.
|
||||||
|
* The actual metatable associated with the usertype has a long name and is defined to be opaque by the Sol implementation.
|
|
@ -20,8 +20,8 @@
|
||||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
// This file was generated with a script.
|
// This file was generated with a script.
|
||||||
// Generated 2016-10-21 21:30:36.718233 UTC
|
// Generated 2016-10-23 21:02:40.993304 UTC
|
||||||
// This header was generated with sol v2.14.11 (revision 8c3ae42)
|
// This header was generated with sol v2.14.12 (revision 2ac711b)
|
||||||
// https://github.com/ThePhD/sol2
|
// https://github.com/ThePhD/sol2
|
||||||
|
|
||||||
#ifndef SOL_SINGLE_INCLUDE_HPP
|
#ifndef SOL_SINGLE_INCLUDE_HPP
|
||||||
|
@ -5063,7 +5063,7 @@ namespace sol {
|
||||||
template<typename T, typename>
|
template<typename T, typename>
|
||||||
struct getter {
|
struct getter {
|
||||||
static T& get(lua_State* L, int index, record& tracking) {
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
return getter<T&>{}.get(L, index, tracking);
|
return getter<sol::detail::as_value_tag<T>>{}.get(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5459,7 +5459,7 @@ namespace sol {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct getter<T*> {
|
struct getter<detail::as_value_tag<T>> {
|
||||||
static T* get_no_nil(lua_State* L, int index, record& tracking) {
|
static T* get_no_nil(lua_State* L, int index, record& tracking) {
|
||||||
tracking.use(1);
|
tracking.use(1);
|
||||||
void** pudata = static_cast<void**>(lua_touserdata(L, index));
|
void** pudata = static_cast<void**>(lua_touserdata(L, index));
|
||||||
|
@ -5478,28 +5478,49 @@ namespace sol {
|
||||||
T* obj = static_cast<T*>(udata);
|
T* obj = static_cast<T*>(udata);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
|
return *get_no_nil(L, index, tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct getter<detail::as_pointer_tag<T>> {
|
||||||
static T* get(lua_State* L, int index, record& tracking) {
|
static T* get(lua_State* L, int index, record& tracking) {
|
||||||
type t = type_of(L, index);
|
type t = type_of(L, index);
|
||||||
if (t == type::nil) {
|
if (t == type::nil) {
|
||||||
tracking.use(1);
|
tracking.use(1);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return get_no_nil(L, index, tracking);
|
return getter<detail::as_value_tag<T>>::get_no_nil(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct getter<non_null<T*>> {
|
struct getter<non_null<T*>> {
|
||||||
static T* get(lua_State* L, int index, record& tracking) {
|
static T* get(lua_State* L, int index, record& tracking) {
|
||||||
return getter<T*>::get_no_nil(L, index, tracking);
|
return getter<detail::as_value_tag<T>>::get_no_nil(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct getter<T&> {
|
struct getter<T&> {
|
||||||
static T& get(lua_State* L, int index, record& tracking) {
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
return *getter<T*>::get_no_nil(L, index, tracking);
|
return getter<detail::as_value_tag<T>>::get(L, index, tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct getter<std::reference_wrapper<T>> {
|
||||||
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
|
return getter<T>{}.get(L, index, tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct getter<T*> {
|
||||||
|
static T* get(lua_State* L, int index, record& tracking) {
|
||||||
|
return getter<detail::as_pointer_tag<T>>::get(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5517,13 +5538,6 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct getter<std::reference_wrapper<T>> {
|
|
||||||
static T& get(lua_State* L, int index, record& tracking) {
|
|
||||||
return getter<T&>{}.get(L, index, tracking);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct getter<std::tuple<Args...>> {
|
struct getter<std::tuple<Args...>> {
|
||||||
typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
|
typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
|
||||||
|
@ -7427,11 +7441,50 @@ namespace sol {
|
||||||
}
|
}
|
||||||
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <std::size_t... M, typename Match, typename... Args>
|
||||||
|
inline int overload_match_arity_single(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
||||||
|
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
|
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
||||||
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
|
typedef typename traits::free_args_list args_list;
|
||||||
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
|
||||||
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
if (traits::free_arity != fxarity) {
|
||||||
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||||
|
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
|
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
||||||
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
|
typedef typename traits::free_args_list args_list;
|
||||||
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
|
||||||
|
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
if (traits::free_arity != fxarity) {
|
||||||
|
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
stack::record tracking{};
|
||||||
|
if (!stack::stack_detail::check_types<true>{}.check(args_list(), L, start, no_panic, tracking)) {
|
||||||
|
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
} // overload_detail
|
} // overload_detail
|
||||||
|
|
||||||
template <typename... Functions, typename Match, typename... Args>
|
template <typename... Functions, typename Match, typename... Args>
|
||||||
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
return overload_detail::overload_match_arity(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
return overload_detail::overload_match_arity_single(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Functions, typename Match, typename... Args>
|
template <typename... Functions, typename Match, typename... Args>
|
||||||
|
|
43
sol/call.hpp
43
sol/call.hpp
|
@ -57,7 +57,7 @@ namespace sol {
|
||||||
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
template <typename Fx, std::size_t I, typename... R, typename... Args>
|
||||||
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
int operator()(types<Fx>, index_value<I>, types<R...> r, types<Args...> a, lua_State* L, int, int start) const {
|
||||||
detail::default_construct func{};
|
detail::default_construct func{};
|
||||||
return stack::call_into_lua<false>(r, a, L, start, func, obj);
|
return stack::call_into_lua<stack::stack_detail::default_check_arguments>(r, a, L, start, func, obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,11 +85,50 @@ namespace sol {
|
||||||
}
|
}
|
||||||
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <std::size_t... M, typename Match, typename... Args>
|
||||||
|
inline int overload_match_arity_single(types<>, std::index_sequence<>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fx, std::size_t I, std::size_t... M, typename Match, typename... Args>
|
||||||
|
inline int overload_match_arity_single(types<Fx>, std::index_sequence<I>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
|
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
||||||
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
|
typedef typename traits::free_args_list args_list;
|
||||||
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
|
||||||
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
if (traits::free_arity != fxarity) {
|
||||||
|
return overload_match_arity(types<>(), std::index_sequence<>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Fx, typename Fx1, typename... Fxs, std::size_t I, std::size_t I1, std::size_t... In, std::size_t... M, typename Match, typename... Args>
|
||||||
|
inline int overload_match_arity_single(types<Fx, Fx1, Fxs...>, std::index_sequence<I, I1, In...>, std::index_sequence<M...>, Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
|
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
|
||||||
|
typedef meta::tuple_types<typename traits::return_type> return_types;
|
||||||
|
typedef typename traits::free_args_list args_list;
|
||||||
|
// compile-time eliminate any functions that we know ahead of time are of improper arity
|
||||||
|
if (meta::find_in_pack_v<index_value<traits::free_arity>, index_value<M>...>::value) {
|
||||||
|
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
if (traits::free_arity != fxarity) {
|
||||||
|
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<traits::free_arity, M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
stack::record tracking{};
|
||||||
|
if (!stack::stack_detail::check_types<true>{}.check(args_list(), L, start, no_panic, tracking)) {
|
||||||
|
return overload_match_arity(types<Fx1, Fxs...>(), std::index_sequence<I1, In...>(), std::index_sequence<M...>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
return matchfx(types<Fx>(), index_value<I>(), return_types(), args_list(), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
} // overload_detail
|
} // overload_detail
|
||||||
|
|
||||||
template <typename... Functions, typename Match, typename... Args>
|
template <typename... Functions, typename Match, typename... Args>
|
||||||
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
inline int overload_match_arity(Match&& matchfx, lua_State* L, int fxarity, int start, Args&&... args) {
|
||||||
return overload_detail::overload_match_arity(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
return overload_detail::overload_match_arity_single(types<Functions...>(), std::make_index_sequence<sizeof...(Functions)>(), std::index_sequence<>(), std::forward<Match>(matchfx), L, fxarity, start, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Functions, typename Match, typename... Args>
|
template <typename... Functions, typename Match, typename... Args>
|
||||||
|
|
|
@ -267,21 +267,7 @@ namespace sol {
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename C>
|
template <typename T, typename C>
|
||||||
struct checker<T*, type::userdata, C> {
|
struct checker<detail::as_value_tag<T>, type::userdata, C> {
|
||||||
template <typename Handler>
|
|
||||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
|
||||||
const type indextype = type_of(L, index);
|
|
||||||
// Allow nil to be transformed to nullptr
|
|
||||||
if (indextype == type::nil) {
|
|
||||||
tracking.use(1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return checker<meta::unqualified_t<T>, type::userdata, C>{}.check(types<meta::unqualified_t<T>>(), L, indextype, index, std::forward<Handler>(handler), tracking);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename C>
|
|
||||||
struct checker<T, type::userdata, C> {
|
|
||||||
template <typename U, typename Handler>
|
template <typename U, typename Handler>
|
||||||
static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
|
static bool check(types<U>, lua_State* L, type indextype, int index, Handler&& handler, record& tracking) {
|
||||||
tracking.use(1);
|
tracking.use(1);
|
||||||
|
@ -320,11 +306,28 @@ namespace sol {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename C>
|
||||||
|
struct checker<T, type::userdata, C> {
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||||
const type indextype = type_of(L, index);
|
const type indextype = type_of(L, index);
|
||||||
return check(types<T>(), L, indextype, index, std::forward<Handler>(handler), tracking);
|
return checker<detail::as_value_tag<T>, type::userdata, C>{}.check(types<T>(), L, indextype, index, std::forward<Handler>(handler), tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename C>
|
||||||
|
struct checker<T*, type::userdata, C> {
|
||||||
|
template <typename Handler>
|
||||||
|
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {
|
||||||
|
const type indextype = type_of(L, index);
|
||||||
|
// Allow nil to be transformed to nullptr
|
||||||
|
if (indextype == type::nil) {
|
||||||
|
tracking.use(1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return checker<meta::unqualified_t<T>, type::userdata, C>{}.check(L, index, std::forward<Handler>(handler), tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace sol {
|
||||||
template<typename T, typename>
|
template<typename T, typename>
|
||||||
struct getter {
|
struct getter {
|
||||||
static T& get(lua_State* L, int index, record& tracking) {
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
return getter<T&>{}.get(L, index, tracking);
|
return getter<sol::detail::as_value_tag<T>>{}.get(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ namespace sol {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct getter<T*> {
|
struct getter<detail::as_value_tag<T>> {
|
||||||
static T* get_no_nil(lua_State* L, int index, record& tracking) {
|
static T* get_no_nil(lua_State* L, int index, record& tracking) {
|
||||||
tracking.use(1);
|
tracking.use(1);
|
||||||
void** pudata = static_cast<void**>(lua_touserdata(L, index));
|
void** pudata = static_cast<void**>(lua_touserdata(L, index));
|
||||||
|
@ -456,28 +456,49 @@ namespace sol {
|
||||||
T* obj = static_cast<T*>(udata);
|
T* obj = static_cast<T*>(udata);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
|
return *get_no_nil(L, index, tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct getter<detail::as_pointer_tag<T>> {
|
||||||
static T* get(lua_State* L, int index, record& tracking) {
|
static T* get(lua_State* L, int index, record& tracking) {
|
||||||
type t = type_of(L, index);
|
type t = type_of(L, index);
|
||||||
if (t == type::nil) {
|
if (t == type::nil) {
|
||||||
tracking.use(1);
|
tracking.use(1);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return get_no_nil(L, index, tracking);
|
return getter<detail::as_value_tag<T>>::get_no_nil(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct getter<non_null<T*>> {
|
struct getter<non_null<T*>> {
|
||||||
static T* get(lua_State* L, int index, record& tracking) {
|
static T* get(lua_State* L, int index, record& tracking) {
|
||||||
return getter<T*>::get_no_nil(L, index, tracking);
|
return getter<detail::as_value_tag<T>>::get_no_nil(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct getter<T&> {
|
struct getter<T&> {
|
||||||
static T& get(lua_State* L, int index, record& tracking) {
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
return *getter<T*>::get_no_nil(L, index, tracking);
|
return getter<detail::as_value_tag<T>>::get(L, index, tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct getter<std::reference_wrapper<T>> {
|
||||||
|
static T& get(lua_State* L, int index, record& tracking) {
|
||||||
|
return getter<T&>{}.get(L, index, tracking);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct getter<T*> {
|
||||||
|
static T* get(lua_State* L, int index, record& tracking) {
|
||||||
|
return getter<detail::as_pointer_tag<T>>::get(L, index, tracking);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -495,13 +516,6 @@ namespace sol {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct getter<std::reference_wrapper<T>> {
|
|
||||||
static T& get(lua_State* L, int index, record& tracking) {
|
|
||||||
return getter<T&>{}.get(L, index, tracking);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct getter<std::tuple<Args...>> {
|
struct getter<std::tuple<Args...>> {
|
||||||
typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
|
typedef std::tuple<decltype(stack::get<Args>(nullptr, 0))...> R;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user