1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-07 21:34:33 +00:00

Merge branch 'solarpowered' into 'master'

Update sol

Closes #8591 and #8614

See merge request OpenMW/openmw!4745
This commit is contained in:
Alexei Kotov 2025-07-27 11:38:16 +03:00
commit 1896375380
118 changed files with 6291 additions and 5557 deletions

View file

@ -1,5 +1,8 @@
The code in this directory is copied from https://github.com/ThePhD/sol2.git (64096348465b980e2f1d0e5ba9cbeea8782e8f27) The code in this directory is copied from https://github.com/ThePhD/sol2.git (c1f95a773c6f8f4fde8ca3efe872e7286afe4444) and has been patched to include
Additional changes include cherry-picking upstream commit d805d027e0a0a7222e936926139f06e23828ce9f to fix compilation under Clang 19. https://github.com/ThePhD/sol2/pull/1674 (71d85143ad69164f5f52c3bdab91fb503c676eb4)
https://github.com/ThePhD/sol2/pull/1676 (a6872ef46b08704b9069ebf83161f4637459ce63)
https://github.com/ThePhD/sol2/pull/1716 (5b6881ed94c795298eae72b6848308e9a37e42c5)
https://github.com/ThePhD/sol2/pull/1722 (ab874eb0e8ef8aea4c10074a89efa25f62a29d9a)
License: MIT License: MIT

47
extern/sol3/sol/abort.hpp vendored Normal file
View file

@ -0,0 +1,47 @@
// 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_ABORT_HPP
#define SOL_ABORT_HPP
#include <sol/version.hpp>
#include <sol/base_traits.hpp>
#include <cstdlib>
// clang-format off
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_DEBUG_ABORT() \
if (true) { ::std::abort(); } \
static_assert(true, "")
#else
#define SOL_DEBUG_ABORT() ::std::abort()
#endif
#else
#define SOL_DEBUG_ABORT() static_assert(true, "")
#endif
// clang-format on
#endif // SOL_ABORT_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -1,99 +1,99 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#ifndef SOL_ASSERT_HPP #ifndef SOL_ASSERT_HPP
#define SOL_ASSERT_HPP #define SOL_ASSERT_HPP
#include <sol/forward.hpp> #include <sol/forward.hpp>
#if SOL_IS_ON(SOL2_CI_I_) #if SOL_IS_ON(SOL2_CI)
struct pre_main { struct pre_main {
pre_main() { pre_main() {
#ifdef _MSC_VER #ifdef _MSC_VER
_set_abort_behavior(0, _WRITE_ABORT_MSG); _set_abort_behavior(0, _WRITE_ABORT_MSG);
#endif #endif
} }
} inline sol2_ci_dont_lock_ci_please = {}; } inline sol2_ci_dont_lock_ci_please = {};
#endif // Prevent lockup when doing Continuous Integration #endif // Prevent lockup when doing Continuous Integration
// clang-format off // clang-format off
#if SOL_IS_ON(SOL_USER_C_ASSERT_I_) #if SOL_IS_ON(SOL_USER_ASSERT)
#define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__) #define SOL_ASSERT(...) SOL_C_ASSERT(__VA_ARGS__)
#else #else
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_) #if SOL_IS_ON(SOL_DEBUG_BUILD)
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#define sol_c_assert(...) \ #define SOL_ASSERT(...) \
do { \ do { \
if (!(__VA_ARGS__)) { \ if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \ std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \
std::terminate(); \ std::terminate(); \
} \ } \
} while (false) } while (false)
#else #else
#define sol_c_assert(...) \ #define SOL_ASSERT(...) \
do { \ do { \
if (false) { \ if (false) { \
(void)(__VA_ARGS__); \ (void)(__VA_ARGS__); \
} \ } \
} while (false) } while (false)
#endif #endif
#endif #endif
#if SOL_IS_ON(SOL_USER_M_ASSERT_I_) #if SOL_IS_ON(SOL_USER_ASSERT_MSG)
#define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__) #define SOL_ASSERT_MSG(message, ...) SOL_ASSERT_MSG(message, __VA_ARGS__)
#else #else
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_) #if SOL_IS_ON(SOL_DEBUG_BUILD)
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
#define sol_m_assert(message, ...) \ #define SOL_ASSERT_MSG(message, ...) \
do { \ do { \
if (!(__VA_ARGS__)) { \ if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \ std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
std::terminate(); \ std::terminate(); \
} \ } \
} while (false) } while (false)
#else #else
#define sol_m_assert(message, ...) \ #define SOL_ASSERT_MSG(message, ...) \
do { \ do { \
if (false) { \ if (false) { \
(void)(__VA_ARGS__); \ (void)(__VA_ARGS__); \
(void)sizeof(message); \ (void)sizeof(message); \
} \ } \
} while (false) } while (false)
#endif #endif
#endif #endif
// clang-format on // clang-format on
#endif // SOL_ASSERT_HPP #endif // SOL_ASSERT_HPP

View file

@ -1,123 +1,156 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_BASE_TRAITS_HPP #ifndef SOL_BASE_TRAITS_HPP
#define SOL_BASE_TRAITS_HPP #define SOL_BASE_TRAITS_HPP
#include <type_traits> #include <type_traits>
namespace sol { namespace sol {
namespace detail { namespace detail {
struct unchecked_t { }; struct unchecked_t { };
const unchecked_t unchecked = unchecked_t {}; const unchecked_t unchecked = unchecked_t {};
} // namespace detail } // namespace detail
namespace meta { namespace meta {
using sfinae_yes_t = std::true_type; using sfinae_yes_t = std::true_type;
using sfinae_no_t = std::false_type; using sfinae_no_t = std::false_type;
template <typename...> template <typename...>
using void_t = void; using void_t = void;
template <typename T> template <typename T>
using unqualified = std::remove_cv<std::remove_reference_t<T>>; using unqualified = std::remove_cv<std::remove_reference_t<T>>;
template <typename T> template <typename T>
using unqualified_t = typename unqualified<T>::type; using unqualified_t = typename unqualified<T>::type;
namespace meta_detail { namespace meta_detail {
template <typename T> template <typename T>
struct unqualified_non_alias : unqualified<T> { }; struct unqualified_non_alias : unqualified<T> { };
template <template <class...> class Test, class, class... Args> template <template <class...> class Test, class, class... Args>
struct is_detected : std::false_type { }; struct is_detected : std::false_type { };
template <template <class...> class Test, class... Args> template <template <class...> class Test, class... Args>
struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type { }; struct is_detected<Test, void_t<Test<Args...>>, Args...> : std::true_type { };
} // namespace meta_detail } // namespace meta_detail
template <template <class...> class Trait, class... Args> template <template <class...> class Trait, class... Args>
using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type; using is_detected = typename meta_detail::is_detected<Trait, void, Args...>::type;
template <template <class...> class Trait, class... Args> template <template <class...> class Trait, class... Args>
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value; constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
template <std::size_t I> template <typename _Default, typename _Void, template <typename...> typename _Op, typename... _Args>
using index_value = std::integral_constant<std::size_t, I>; class detector {
public:
template <bool> using value_t = ::std::false_type;
struct conditional { using type = _Default;
template <typename T, typename U> };
using type = T;
}; template <typename _Default, template <typename...> typename _Op, typename... _Args>
class detector<_Default, void_t<_Op<_Args...>>, _Op, _Args...> {
template <> public:
struct conditional<false> { using value_t = ::std::true_type;
template <typename T, typename U> using type = _Op<_Args...>;
using type = U; };
};
class nonesuch {
template <bool B, typename T, typename U> public:
using conditional_t = typename conditional<B>::template type<T, U>; ~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
namespace meta_detail { nonesuch& operator=(nonesuch const&) = delete;
template <typename T, template <typename...> class Templ> };
struct is_specialization_of : std::false_type { };
template <typename... T, template <typename...> class Templ> template <template <typename...> typename _Op, typename... _Args>
struct is_specialization_of<Templ<T...>, Templ> : std::true_type { }; using detected_t = typename detector<nonesuch, void, _Op, _Args...>::type;
} // namespace meta_detail
template <typename _Default, template <typename...> typename _Op, typename... _Args>
template <typename T, template <typename...> class Templ> using detected_or = detector<_Default, void, _Op, _Args...>;
using is_specialization_of = meta_detail::is_specialization_of<std::remove_cv_t<T>, Templ>;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
template <typename T, template <typename...> class Templ> using detected_or_t = typename detector<_Default, void, _Op, _Args...>::type;
inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
template <typename T> constexpr inline bool detected_or_v = detector<_Default, void, _Op, _Args...>::value;
struct identity {
typedef T type; template <std::size_t I>
}; using index_value = std::integral_constant<std::size_t, I>;
template <typename T> template <bool>
using identity_t = typename identity<T>::type; struct conditional {
template <typename T, typename U>
template <typename T> using type = T;
using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>; };
namespace meta_detail { template <>
template <typename T, typename = void> struct conditional<false> {
struct has_internal_marker_impl : std::false_type { }; template <typename T, typename U>
template <typename T> using type = U;
struct has_internal_marker_impl<T, void_t<typename T::SOL_INTERNAL_UNSPECIALIZED_MARKER_>> : std::true_type { }; };
template <typename T> template <bool B, typename T, typename U>
using has_internal_marker = has_internal_marker_impl<T>; using conditional_t = typename conditional<B>::template type<T, U>;
template <typename T> namespace meta_detail {
constexpr inline bool has_internal_marker_v = has_internal_marker<T>::value; template <typename T, template <typename...> class Templ>
} // namespace meta_detail struct is_specialization_of : std::false_type { };
template <typename... T, template <typename...> class Templ>
} // namespace meta struct is_specialization_of<Templ<T...>, Templ> : std::true_type { };
} // namespace sol } // namespace meta_detail
#endif // SOL_BASE_TRAITS_HPP template <typename T, template <typename...> class Templ>
using is_specialization_of = meta_detail::is_specialization_of<std::remove_cv_t<T>, Templ>;
template <typename T, template <typename...> class Templ>
inline constexpr bool is_specialization_of_v = is_specialization_of<std::remove_cv_t<T>, Templ>::value;
template <typename T>
struct identity {
typedef T type;
};
template <typename T>
using identity_t = typename identity<T>::type;
template <typename T>
using is_builtin_type = std::integral_constant<bool, std::is_arithmetic<T>::value || std::is_pointer<T>::value || std::is_array<T>::value>;
namespace meta_detail {
template <typename T, typename = void>
struct has_internal_marker_impl : std::false_type { };
template <typename T>
struct has_internal_marker_impl<T, void_t<typename T::SOL_INTERNAL_UNSPECIALIZED_MARKER_>> : std::true_type { };
template <typename T>
using has_internal_marker = has_internal_marker_impl<T>;
template <typename T>
constexpr inline bool has_internal_marker_v = has_internal_marker<T>::value;
} // namespace meta_detail
} // namespace meta
} // namespace sol
#endif // SOL_BASE_TRAITS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -31,7 +31,7 @@
namespace sol { namespace meta { namespace sol { namespace meta {
namespace meta_detail { namespace meta_detail {
template <typename F> template <typename F>
using detect_deducible_signature = decltype(&F::operator(), void()); using detect_deducible_signature = decltype(&F::operator());
} // namespace meta_detail } // namespace meta_detail
template <typename F> template <typename F>
@ -196,7 +196,7 @@ namespace sol { namespace meta {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&; typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
}; };
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <typename R, typename... Args> template <typename R, typename... Args>
struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> { struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
@ -311,7 +311,7 @@ namespace sol { namespace meta {
#endif // noexcept is part of a function's type #endif // noexcept is part of a function's type
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && SOL_IS_ON(SOL_PLATFORM_X86_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX) && SOL_IS_ON(SOL_PLATFORM_X86)
template <typename R, typename... Args> template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> { struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...); typedef R(__stdcall* function_pointer_type)(Args...);
@ -369,7 +369,7 @@ namespace sol { namespace meta {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&; typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
}; };
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <typename R, typename... Args> template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> { struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {

View file

@ -1,121 +1,121 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_BYTECODE_HPP #ifndef SOL_BYTECODE_HPP
#define SOL_BYTECODE_HPP #define SOL_BYTECODE_HPP
#include <sol/compatibility.hpp> #include <sol/compatibility.hpp>
#include <sol/string_view.hpp> #include <sol/string_view.hpp>
#include <vector> #include <vector>
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
namespace sol { namespace sol {
template <typename Allocator = std::allocator<std::byte>> template <typename Allocator = std::allocator<std::byte>>
class basic_bytecode : private std::vector<std::byte, Allocator> { class basic_bytecode : private std::vector<std::byte, Allocator> {
private: private:
using base_t = std::vector<std::byte, Allocator>; using base_t = std::vector<std::byte, Allocator>;
public: public:
using typename base_t::allocator_type; using typename base_t::allocator_type;
using typename base_t::const_iterator; using typename base_t::const_iterator;
using typename base_t::const_pointer; using typename base_t::const_pointer;
using typename base_t::const_reference; using typename base_t::const_reference;
using typename base_t::const_reverse_iterator; using typename base_t::const_reverse_iterator;
using typename base_t::difference_type; using typename base_t::difference_type;
using typename base_t::iterator; using typename base_t::iterator;
using typename base_t::pointer; using typename base_t::pointer;
using typename base_t::reference; using typename base_t::reference;
using typename base_t::reverse_iterator; using typename base_t::reverse_iterator;
using typename base_t::size_type; using typename base_t::size_type;
using typename base_t::value_type; using typename base_t::value_type;
using base_t::base_t; using base_t::base_t;
using base_t::operator=; using base_t::operator=;
using base_t::data; using base_t::data;
using base_t::empty; using base_t::empty;
using base_t::max_size; using base_t::max_size;
using base_t::size; using base_t::size;
using base_t::at; using base_t::at;
using base_t::operator[]; using base_t::operator[];
using base_t::back; using base_t::back;
using base_t::front; using base_t::front;
using base_t::begin; using base_t::begin;
using base_t::cbegin; using base_t::cbegin;
using base_t::cend; using base_t::cend;
using base_t::end; using base_t::end;
using base_t::crbegin; using base_t::crbegin;
using base_t::crend; using base_t::crend;
using base_t::rbegin; using base_t::rbegin;
using base_t::rend; using base_t::rend;
using base_t::get_allocator; using base_t::get_allocator;
using base_t::swap; using base_t::swap;
using base_t::clear; using base_t::clear;
using base_t::emplace; using base_t::emplace;
using base_t::emplace_back; using base_t::emplace_back;
using base_t::erase; using base_t::erase;
using base_t::insert; using base_t::insert;
using base_t::pop_back; using base_t::pop_back;
using base_t::push_back; using base_t::push_back;
using base_t::reserve; using base_t::reserve;
using base_t::resize; using base_t::resize;
using base_t::shrink_to_fit; using base_t::shrink_to_fit;
string_view as_string_view() const { string_view as_string_view() const {
return string_view(reinterpret_cast<const char*>(this->data()), this->size()); return string_view(reinterpret_cast<const char*>(this->data()), this->size());
} }
}; };
template <typename Container> template <typename Container>
inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata_pointer) { inline int basic_insert_dump_writer(lua_State*, const void* memory, size_t memory_size, void* userdata_pointer) {
using storage_t = Container; using storage_t = Container;
const std::byte* p_code = static_cast<const std::byte*>(memory); const std::byte* p_code = static_cast<const std::byte*>(memory);
storage_t& bc = *static_cast<storage_t*>(userdata_pointer); storage_t& bc = *static_cast<storage_t*>(userdata_pointer);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
bc.insert(bc.cend(), p_code, p_code + memory_size); bc.insert(bc.cend(), p_code, p_code + memory_size);
#else #else
try { try {
bc.insert(bc.cend(), p_code, p_code + memory_size); bc.insert(bc.cend(), p_code, p_code + memory_size);
} }
catch (...) { catch (...) {
return -1; return -1;
} }
#endif #endif
return 0; return 0;
} }
using bytecode = basic_bytecode<>; using bytecode = basic_bytecode<>;
constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>; constexpr inline auto bytecode_dump_writer = &basic_insert_dump_writer<bytecode>;
} // namespace sol } // namespace sol
#endif // SOL_BYTECODE_HPP #endif // SOL_BYTECODE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -54,7 +54,7 @@ namespace sol {
lua_createtable(L, static_cast<int>(sizeof...(In)), 0); lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
stack_reference deps(L, -1); stack_reference deps(L, -1);
auto per_dep = [&L, &deps](int i) { auto per_dep = [&L, &deps](int i) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L, i); lua_pushvalue(L, i);
@ -79,7 +79,7 @@ namespace sol {
} }
lua_createtable(L, static_cast<int>(sdeps.size()), 0); lua_createtable(L, static_cast<int>(sdeps.size()), 0);
stack_reference deps(L, -1); stack_reference deps(L, -1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic); luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
for (std::size_t i = 0; i < sdeps.size(); ++i) { for (std::size_t i = 0; i < sdeps.size(); ++i) {
@ -429,7 +429,7 @@ namespace sol {
} }
}; };
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C> template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> { struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
static int call(lua_State* L, detail::lua_CFunction_noexcept f) { static int call(lua_State* L, detail::lua_CFunction_noexcept f) {
@ -478,12 +478,13 @@ namespace sol {
using object_type = typename wrap::object_type; using object_type = typename wrap::object_type;
if constexpr (sizeof...(Args) < 1) { if constexpr (sizeof...(Args) < 1) {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>; using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
static_assert(std::is_base_of_v<object_type, Ta>, static_assert(std::is_same_v<object_type, Ta> || std::is_base_of_v<object_type, Ta>,
"It seems like you might have accidentally bound a class type with a member function method that does not correspond to the " "It seems like you might have accidentally bound a class type with a member function method that does not correspond to the "
"class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" " "class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" "
"but then bind member methods from a complete unrelated class. Check things over!"); "but then bind member methods from a complete unrelated class. Check things over!");
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_) #if SOL_IS_ON(SOL_SAFE_USERTYPE)
auto maybeo = stack::check_get<Ta*>(L, 1); stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) { if (!maybeo || maybeo.value() == nullptr) {
return luaL_error(L, return luaL_error(L,
"sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are " "sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
@ -511,12 +512,13 @@ namespace sol {
if constexpr (is_index) { if constexpr (is_index) {
if constexpr (sizeof...(Args) < 1) { if constexpr (sizeof...(Args) < 1) {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>; using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
static_assert(std::is_base_of_v<object_type, Ta>, static_assert(std::is_same_v<object_type, Ta> || std::is_base_of_v<object_type, Ta>,
"It seems like you might have accidentally bound a class type with a member function method that does not correspond " "It seems like you might have accidentally bound a class type with a member function method that does not correspond "
"to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one " "to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one "
"class \"T\" but then bind member methods from a complete unrelated class. Check things over!"); "class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_) #if SOL_IS_ON(SOL_SAFE_USERTYPE)
auto maybeo = stack::check_get<Ta*>(L, 1); stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) { if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) { if (is_variable) {
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)"); return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
@ -573,8 +575,9 @@ namespace sol {
} }
else { else {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>; using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_) #if SOL_IS_ON(SOL_SAFE_USERTYPE)
auto maybeo = stack::check_get<Ta*>(L, 1); stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) { if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) { if (is_variable) {
return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)"); return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
@ -811,8 +814,9 @@ namespace sol {
using args_list = meta::pop_front_type_t<typename traits_type::free_args_list>; using args_list = meta::pop_front_type_t<typename traits_type::free_args_list>;
using Ta = T; using Ta = T;
using Oa = std::remove_pointer_t<object_type>; using Oa = std::remove_pointer_t<object_type>;
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_) #if SOL_IS_ON(SOL_SAFE_USERTYPE)
auto maybeo = stack::check_get<Ta*>(L, 1); stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) { if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) { if (is_variable) {
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)"); return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -32,20 +32,20 @@
#include <sol/version.hpp> #include <sol/version.hpp>
#include <sol/compatibility/lua_version.hpp> #include <sol/compatibility/lua_version.hpp>
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER_I_) #if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) // clang-format off
#ifndef COMPAT53_LUA_CPP #if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define COMPAT53_LUA_CPP 1 #ifndef COMPAT53_LUA_CPP
#endif // Build Lua Compat layer as C++ #define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
#endif #endif
#ifndef COMPAT53_INCLUDE_SOURCE #ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1 #define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline #endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.3.h> #include <sol/compatibility/compat-5.4.h>
#include <sol/compatibility/compat-5.4.h>
#endif #endif
// clang-format on
#endif // SOL_COMPATIBILITY_HPP #endif // SOL_COMPATIBILITY_HPP

File diff suppressed because it is too large Load diff

View file

@ -1,424 +1,430 @@
#ifndef KEPLER_PROJECT_COMPAT53_H_ #ifndef KEPLER_PROJECT_COMPAT53_H_
#define KEPLER_PROJECT_COMPAT53_H_ #define KEPLER_PROJECT_COMPAT53_H_
#include <stddef.h> #include <stddef.h>
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" { extern "C" {
#endif #endif
#include <lua.h> #if __has_include(<lua/lua.h>)
#include <lauxlib.h> #include <lua/lua.h>
#include <lualib.h> #include <lua/lauxlib.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) #include <lua/lualib.h>
} #else
#endif #include <lua.h>
#include <lauxlib.h>
#ifndef COMPAT53_PREFIX #include <lualib.h>
/* we chose this name because many other lua bindings / libs have #endif
* their own compatibility layer, and that use the compat53 declaration #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
* frequently, causing all kinds of linker / compiler issues }
*/ #endif
# define COMPAT53_PREFIX kp_compat53
#endif // COMPAT53_PREFIX #ifndef COMPAT53_PREFIX
/* we chose this name because many other lua bindings / libs have
#ifndef COMPAT53_API * their own compatibility layer, and that use the compat53 declaration
# if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE * frequently, causing all kinds of linker / compiler issues
# if defined(__GNUC__) || defined(__clang__) */
# define COMPAT53_API __attribute__((__unused__)) static inline # define COMPAT53_PREFIX kp_compat53
# else #endif // COMPAT53_PREFIX
# define COMPAT53_API static inline
# endif /* Clang/GCC */ #ifndef COMPAT53_API
# else /* COMPAT53_INCLUDE_SOURCE */ # if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE
/* we are not including source, so everything is extern */ # if defined(__GNUC__) || defined(__clang__)
# define COMPAT53_API extern # define COMPAT53_API __attribute__((__unused__)) static inline
# endif /* COMPAT53_INCLUDE_SOURCE */ # else
#endif /* COMPAT53_PREFIX */ # define COMPAT53_API static inline
# endif /* Clang/GCC */
# else /* COMPAT53_INCLUDE_SOURCE */
#define COMPAT53_CONCAT_HELPER(a, b) a##b /* we are not including source, so everything is extern */
#define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b) # define COMPAT53_API extern
# endif /* COMPAT53_INCLUDE_SOURCE */
#endif /* COMPAT53_PREFIX */
/* declarations for Lua 5.1 */
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 #define COMPAT53_CONCAT_HELPER(a, b) a##b
#define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b)
/* XXX not implemented:
* lua_arith (new operators)
* lua_upvalueid
* lua_upvaluejoin /* declarations for Lua 5.1 */
* lua_version #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
* lua_yieldk
*/ /* XXX not implemented:
* lua_arith (new operators)
#ifndef LUA_OK * lua_upvalueid
# define LUA_OK 0 * lua_upvaluejoin
#endif * lua_version
#ifndef LUA_OPADD * lua_yieldk
# define LUA_OPADD 0 */
#endif
#ifndef LUA_OPSUB #ifndef LUA_OK
# define LUA_OPSUB 1 # define LUA_OK 0
#endif #endif
#ifndef LUA_OPMUL #ifndef LUA_OPADD
# define LUA_OPMUL 2 # define LUA_OPADD 0
#endif #endif
#ifndef LUA_OPDIV #ifndef LUA_OPSUB
# define LUA_OPDIV 3 # define LUA_OPSUB 1
#endif #endif
#ifndef LUA_OPMOD #ifndef LUA_OPMUL
# define LUA_OPMOD 4 # define LUA_OPMUL 2
#endif #endif
#ifndef LUA_OPPOW #ifndef LUA_OPDIV
# define LUA_OPPOW 5 # define LUA_OPDIV 3
#endif #endif
#ifndef LUA_OPUNM #ifndef LUA_OPMOD
# define LUA_OPUNM 6 # define LUA_OPMOD 4
#endif #endif
#ifndef LUA_OPEQ #ifndef LUA_OPPOW
# define LUA_OPEQ 0 # define LUA_OPPOW 5
#endif #endif
#ifndef LUA_OPLT #ifndef LUA_OPUNM
# define LUA_OPLT 1 # define LUA_OPUNM 6
#endif #endif
#ifndef LUA_OPLE #ifndef LUA_OPEQ
# define LUA_OPLE 2 # define LUA_OPEQ 0
#endif #endif
#ifndef LUA_OPLT
/* LuaJIT/Lua 5.1 does not have the updated # define LUA_OPLT 1
* error codes for thread status/function returns (but some patched versions do) #endif
* define it only if it's not found #ifndef LUA_OPLE
*/ # define LUA_OPLE 2
#if !defined(LUA_ERRGCMM) #endif
/* Use + 2 because in some versions of Lua (Lua 5.1)
* LUA_ERRFILE is defined as (LUA_ERRERR+1) /* LuaJIT/Lua 5.1 does not have the updated
* so we need to avoid it (LuaJIT might have something at this * error codes for thread status/function returns (but some patched versions do)
* integer value too) * define it only if it's not found
*/ */
# define LUA_ERRGCMM (LUA_ERRERR + 2) #if !defined(LUA_ERRGCMM)
#endif /* LUA_ERRGCMM define */ /* Use + 2 because in some versions of Lua (Lua 5.1)
* LUA_ERRFILE is defined as (LUA_ERRERR+1)
#if !defined(MOONJIT_VERSION) * so we need to avoid it (LuaJIT might have something at this
typedef size_t lua_Unsigned; * integer value too)
#endif */
# define LUA_ERRGCMM (LUA_ERRERR + 2)
typedef struct luaL_Buffer_53 { #endif /* LUA_ERRGCMM define */
luaL_Buffer b; /* make incorrect code crash! */
char *ptr; #if !defined(MOONJIT_VERSION)
size_t nelems; typedef size_t lua_Unsigned;
size_t capacity; #endif
lua_State *L2;
} luaL_Buffer_53; typedef struct luaL_Buffer_53 {
#define luaL_Buffer luaL_Buffer_53 luaL_Buffer b; /* make incorrect code crash! */
char *ptr;
/* In PUC-Rio 5.1, userdata is a simple FILE* size_t nelems;
* In LuaJIT, it's a struct where the first member is a FILE* size_t capacity;
* We can't support the `closef` member lua_State *L2;
*/ } luaL_Buffer_53;
typedef struct luaL_Stream { #define luaL_Buffer luaL_Buffer_53
FILE *f;
} luaL_Stream; /* In PUC-Rio 5.1, userdata is a simple FILE*
* In LuaJIT, it's a struct where the first member is a FILE*
#define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) * We can't support the `closef` member
COMPAT53_API int lua_absindex(lua_State *L, int i); */
typedef struct luaL_Stream {
#define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith) FILE *f;
COMPAT53_API void lua_arith(lua_State *L, int op); } luaL_Stream;
#define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare) #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex)
COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op); COMPAT53_API int lua_absindex(lua_State *L, int i);
#define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy) #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith)
COMPAT53_API void lua_copy(lua_State *L, int from, int to); COMPAT53_API void lua_arith(lua_State *L, int op);
#define lua_getuservalue(L, i) \ #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare)
(lua_getfenv((L), (i)), lua_type((L), -1)) COMPAT53_API int lua_compare(lua_State *L, int idx1, int idx2, int op);
#define lua_setuservalue(L, i) \
(luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i))) #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy)
COMPAT53_API void lua_copy(lua_State *L, int from, int to);
#define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
COMPAT53_API void lua_len(lua_State *L, int i); #define lua_getuservalue(L, i) \
(lua_getfenv((L), (i)), lua_type((L), -1))
#define lua_pushstring(L, s) \ #define lua_setuservalue(L, i) \
(lua_pushstring((L), (s)), lua_tostring((L), -1)) (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i)))
#define lua_pushlstring(L, s, len) \ #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len)
((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1)) COMPAT53_API void lua_len(lua_State *L, int i);
#ifndef luaL_newlibtable #define lua_pushstring(L, s) \
# define luaL_newlibtable(L, l) \ (lua_pushstring((L), (s)), lua_tostring((L), -1))
(lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
#endif #define lua_pushlstring(L, s, len) \
#ifndef luaL_newlib ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1))
# define luaL_newlib(L, l) \
(luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l))) #ifndef luaL_newlibtable
#endif # define luaL_newlibtable(L, l) \
(lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1))
#ifndef lua_pushglobaltable #endif
# define lua_pushglobaltable(L) \ #ifndef luaL_newlib
lua_pushvalue((L), LUA_GLOBALSINDEX) # define luaL_newlib(L, l) \
#endif (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l)))
#define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp) #endif
COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
#ifndef lua_pushglobaltable
#define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp) # define lua_pushglobaltable(L) \
COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p); lua_pushvalue((L), LUA_GLOBALSINDEX)
#endif
#define lua_rawlen(L, i) lua_objlen((L), (i)) #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp)
COMPAT53_API int lua_rawgetp(lua_State *L, int i, const void *p);
#define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
#define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp)
#define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx) COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p);
COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
#define lua_rawlen(L, i) lua_objlen((L), (i))
#define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
COMPAT53_API void luaL_checkversion(lua_State *L); #define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL)
#define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53) #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx)
COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode); COMPAT53_API lua_Number lua_tonumberx(lua_State *L, int i, int *isnum);
#define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex) #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion)
COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode); COMPAT53_API void luaL_checkversion(lua_State *L);
#define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx) #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53)
COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); COMPAT53_API int lua_load(lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode);
#define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53) #define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex)
COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg); COMPAT53_API int luaL_loadfilex(lua_State *L, const char *filename, const char *mode);
#define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable) #define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx)
COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name); COMPAT53_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
#define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len) #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53)
COMPAT53_API lua_Integer luaL_len(lua_State *L, int i); COMPAT53_API void luaL_checkstack(lua_State *L, int sp, const char *msg);
#define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs) #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable)
COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup); COMPAT53_API int luaL_getsubtable(lua_State* L, int i, const char *name);
#define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable) #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len)
COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname); COMPAT53_API lua_Integer luaL_len(lua_State *L, int i);
#define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata) #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs)
COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname); COMPAT53_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
#define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback) #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable)
COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level); COMPAT53_API void luaL_setmetatable(lua_State *L, const char *tname);
#define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult) #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata)
COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname); COMPAT53_API void *luaL_testudata(lua_State *L, int i, const char *tname);
#define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult) #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback)
COMPAT53_API int luaL_execresult(lua_State *L, int stat); COMPAT53_API void luaL_traceback(lua_State *L, lua_State *L1, const char *msg, int level);
#define lua_callk(L, na, nr, ctx, cont) \ #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult)
((void)(ctx), (void)(cont), lua_call((L), (na), (nr))) COMPAT53_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
#define lua_pcallk(L, na, nr, err, ctx, cont) \
((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err))) #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult)
COMPAT53_API int luaL_execresult(lua_State *L, int stat);
#define lua_resume(L, from, nargs) \
((void)(from), lua_resume((L), (nargs))) #define lua_callk(L, na, nr, ctx, cont) \
((void)(ctx), (void)(cont), lua_call((L), (na), (nr)))
#define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53) #define lua_pcallk(L, na, nr, err, ctx, cont) \
COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B); ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err)))
#define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53) #define lua_resume(L, from, nargs) \
COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s); ((void)(from), lua_resume((L), (nargs)))
#define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53) #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53)
COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l); COMPAT53_API void luaL_buffinit(lua_State *L, luaL_Buffer_53 *B);
#define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53) #define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53)
COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B); COMPAT53_API char *luaL_prepbuffsize(luaL_Buffer_53 *B, size_t s);
#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53) #define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53)
COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B); COMPAT53_API void luaL_addlstring(luaL_Buffer_53 *B, const char *s, size_t l);
#undef luaL_buffinitsize #define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53)
#define luaL_buffinitsize(L, B, s) \ COMPAT53_API void luaL_addvalue(luaL_Buffer_53 *B);
(luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
#define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53)
#undef luaL_prepbuffer COMPAT53_API void luaL_pushresult(luaL_Buffer_53 *B);
#define luaL_prepbuffer(B) \
luaL_prepbuffsize((B), LUAL_BUFFERSIZE) #undef luaL_buffinitsize
#define luaL_buffinitsize(L, B, s) \
#undef luaL_addchar (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s)))
#define luaL_addchar(B, c) \
((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \ #undef luaL_prepbuffer
((B)->ptr[(B)->nelems++] = (c))) #define luaL_prepbuffer(B) \
luaL_prepbuffsize((B), LUAL_BUFFERSIZE)
#undef luaL_addsize
#define luaL_addsize(B, s) \ #undef luaL_addchar
((B)->nelems += (s)) #define luaL_addchar(B, c) \
((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \
#undef luaL_addstring ((B)->ptr[(B)->nelems++] = (c)))
#define luaL_addstring(B, s) \
luaL_addlstring((B), (s), strlen((s))) #undef luaL_addsize
#define luaL_addsize(B, s) \
#undef luaL_pushresultsize ((B)->nelems += (s))
#define luaL_pushresultsize(B, s) \
(luaL_addsize((B), (s)), luaL_pushresult((B))) #undef luaL_addstring
#define luaL_addstring(B, s) \
#if defined(LUA_COMPAT_APIINTCASTS) luaL_addlstring((B), (s), strlen((s)))
#define lua_pushunsigned(L, n) \
lua_pushinteger((L), (lua_Integer)(n)) #undef luaL_pushresultsize
#define lua_tounsignedx(L, i, is) \ #define luaL_pushresultsize(B, s) \
((lua_Unsigned)lua_tointegerx((L), (i), (is))) (luaL_addsize((B), (s)), luaL_pushresult((B)))
#define lua_tounsigned(L, i) \
lua_tounsignedx((L), (i), NULL) #if defined(LUA_COMPAT_APIINTCASTS)
#define luaL_checkunsigned(L, a) \ #define lua_pushunsigned(L, n) \
((lua_Unsigned)luaL_checkinteger((L), (a))) lua_pushinteger((L), (lua_Integer)(n))
#define luaL_optunsigned(L, a, d) \ #define lua_tounsignedx(L, i, is) \
((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d))) ((lua_Unsigned)lua_tointegerx((L), (i), (is)))
#endif #define lua_tounsigned(L, i) \
lua_tounsignedx((L), (i), NULL)
#endif /* Lua 5.1 only */ #define luaL_checkunsigned(L, a) \
((lua_Unsigned)luaL_checkinteger((L), (a)))
#define luaL_optunsigned(L, a, d) \
((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d)))
/* declarations for Lua 5.1 and 5.2 */ #endif
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
#endif /* Lua 5.1 only */
typedef int lua_KContext;
typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
/* declarations for Lua 5.1 and 5.2 */
#define lua_dump(L, w, d, s) \ #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502
((void)(s), lua_dump((L), (w), (d)))
typedef int lua_KContext;
#define lua_getfield(L, i, k) \
(lua_getfield((L), (i), (k)), lua_type((L), -1)) typedef int(*lua_KFunction)(lua_State *L, int status, lua_KContext ctx);
#define lua_gettable(L, i) \ #define lua_dump(L, w, d, s) \
(lua_gettable((L), (i)), lua_type((L), -1)) ((void)(s), lua_dump((L), (w), (d)))
#define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) #define lua_getfield(L, i, k) \
COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i); (lua_getfield((L), (i), (k)), lua_type((L), -1))
#define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) #define lua_gettable(L, i) \
COMPAT53_API int lua_isinteger(lua_State *L, int index); (lua_gettable((L), (i)), lua_type((L), -1))
#define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53) #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti)
COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum); COMPAT53_API int lua_geti(lua_State *L, int index, lua_Integer i);
#define lua_numbertointeger(n, p) \ #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger)
((*(p) = (lua_Integer)(n)), 1) COMPAT53_API int lua_isinteger(lua_State *L, int index);
#define lua_rawget(L, i) \ #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53)
(lua_rawget((L), (i)), lua_type((L), -1)) COMPAT53_API lua_Integer lua_tointegerx(lua_State *L, int i, int *isnum);
#define lua_rawgeti(L, i, n) \ #define lua_numbertointeger(n, p) \
(lua_rawgeti((L), (i), (n)), lua_type((L), -1)) ((*(p) = (lua_Integer)(n)), 1)
#define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate) #define lua_rawget(L, i) \
COMPAT53_API void lua_rotate(lua_State *L, int idx, int n); (lua_rawget((L), (i)), lua_type((L), -1))
#define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti) #define lua_rawgeti(L, i, n) \
COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i); (lua_rawgeti((L), (i), (n)), lua_type((L), -1))
#define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber) #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate)
COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s); COMPAT53_API void lua_rotate(lua_State *L, int idx, int n);
#define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring) #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti)
COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len); COMPAT53_API void lua_seti(lua_State *L, int index, lua_Integer i);
#define luaL_getmetafield(L, o, e) \ #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber)
(luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL) COMPAT53_API size_t lua_stringtonumber(lua_State *L, const char *s);
#define luaL_newmetatable(L, tn) \ #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring)
(luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0) COMPAT53_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len);
#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53) #define luaL_getmetafield(L, o, e) \
COMPAT53_API void luaL_requiref(lua_State *L, const char *modname, (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL)
lua_CFunction openf, int glb);
#define luaL_newmetatable(L, tn) \
#endif /* Lua 5.1 and Lua 5.2 */ (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0)
#define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53)
COMPAT53_API void luaL_requiref(lua_State *L, const char *modname,
/* declarations for Lua 5.2 */ lua_CFunction openf, int glb);
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
#endif /* Lua 5.1 and Lua 5.2 */
/* XXX not implemented:
* lua_isyieldable
* lua_getextraspace
* lua_arith (new operators) /* declarations for Lua 5.2 */
* lua_pushfstring (new formats) #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502
*/
/* XXX not implemented:
#define lua_getglobal(L, n) \ * lua_isyieldable
(lua_getglobal((L), (n)), lua_type((L), -1)) * lua_getextraspace
* lua_arith (new operators)
#define lua_getuservalue(L, i) \ * lua_pushfstring (new formats)
(lua_getuservalue((L), (i)), lua_type((L), -1)) */
#define lua_pushlstring(L, s, len) \ #define lua_getglobal(L, n) \
(((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))) (lua_getglobal((L), (n)), lua_type((L), -1))
#define lua_rawgetp(L, i, p) \ #define lua_getuservalue(L, i) \
(lua_rawgetp((L), (i), (p)), lua_type((L), -1)) (lua_getuservalue((L), (i)), lua_type((L), -1))
#define LUA_KFUNCTION(_name) \ #define lua_pushlstring(L, s, len) \
static int (_name)(lua_State *L, int status, lua_KContext ctx); \ (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len)))
static int (_name ## _52)(lua_State *L) { \
lua_KContext ctx; \ #define lua_rawgetp(L, i, p) \
int status = lua_getctx(L, &ctx); \ (lua_rawgetp((L), (i), (p)), lua_type((L), -1))
return (_name)(L, status, ctx); \
} \ #define LUA_KFUNCTION(_name) \
static int (_name)(lua_State *L, int status, lua_KContext ctx) static int (_name)(lua_State *L, int status, lua_KContext ctx); \
static int (_name ## _52)(lua_State *L) { \
#define lua_pcallk(L, na, nr, err, ctx, cont) \ lua_KContext ctx; \
lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52) int status = lua_getctx(L, &ctx); \
return (_name)(L, status, ctx); \
#define lua_callk(L, na, nr, ctx, cont) \ } \
lua_callk((L), (na), (nr), (ctx), cont ## _52) static int (_name)(lua_State *L, int status, lua_KContext ctx)
#define lua_yieldk(L, nr, ctx, cont) \ #define lua_pcallk(L, na, nr, err, ctx, cont) \
lua_yieldk((L), (nr), (ctx), cont ## _52) lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52)
#ifdef lua_call #define lua_callk(L, na, nr, ctx, cont) \
# undef lua_call lua_callk((L), (na), (nr), (ctx), cont ## _52)
# define lua_call(L, na, nr) \
(lua_callk)((L), (na), (nr), 0, NULL) #define lua_yieldk(L, nr, ctx, cont) \
#endif lua_yieldk((L), (nr), (ctx), cont ## _52)
#ifdef lua_pcall #ifdef lua_call
# undef lua_pcall # undef lua_call
# define lua_pcall(L, na, nr, err) \ # define lua_call(L, na, nr) \
(lua_pcallk)((L), (na), (nr), (err), 0, NULL) (lua_callk)((L), (na), (nr), 0, NULL)
#endif #endif
#ifdef lua_yield #ifdef lua_pcall
# undef lua_yield # undef lua_pcall
# define lua_yield(L, nr) \ # define lua_pcall(L, na, nr, err) \
(lua_yieldk)((L), (nr), 0, NULL) (lua_pcallk)((L), (na), (nr), (err), 0, NULL)
#endif #endif
#endif /* Lua 5.2 only */ #ifdef lua_yield
# undef lua_yield
# define lua_yield(L, nr) \
(lua_yieldk)((L), (nr), 0, NULL)
/* other Lua versions */ #endif
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
#endif /* Lua 5.2 only */
# error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
#endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
/* other Lua versions */
#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504
/* helper macro for defining continuation functions (for every version # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)"
* *except* Lua 5.2) */
#ifndef LUA_KFUNCTION #endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */
#define LUA_KFUNCTION(_name) \
static int (_name)(lua_State *L, int status, lua_KContext ctx)
#endif
/* helper macro for defining continuation functions (for every version
* *except* Lua 5.2) */
#if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1 #ifndef LUA_KFUNCTION
# include "compat-5.3.c.h" #define LUA_KFUNCTION(_name) \
#endif static int (_name)(lua_State *L, int status, lua_KContext ctx)
#endif
#endif /* KEPLER_PROJECT_COMPAT53_H_ */
#if defined(COMPAT53_INCLUDE_SOURCE) && COMPAT53_INCLUDE_SOURCE == 1
# include "compat-5.3.c.h"
#endif
#endif /* KEPLER_PROJECT_COMPAT53_H_ */

View file

@ -1,25 +1,31 @@
#ifndef NOT_KEPLER_PROJECT_COMPAT54_H_ #ifndef NOT_KEPLER_PROJECT_COMPAT54_H_
#define NOT_KEPLER_PROJECT_COMPAT54_H_ #define NOT_KEPLER_PROJECT_COMPAT54_H_
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" { extern "C" {
#endif #endif
#include <lua.h> #if __has_include(<lua/lua.h>)
#include <lauxlib.h> #include <lua/lua.h>
#include <lualib.h> #include <lua/lauxlib.h>
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) #include <lua/lualib.h>
} #else
#endif #include <lua.h>
#include <lauxlib.h>
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504 #include <lualib.h>
#endif
#if !defined(LUA_ERRGCMM) #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
/* So Lua 5.4 actually removes this, which breaks sol2... }
man, this API is quite unstable...! #endif
*/
# define LUA_ERRGCMM (LUA_ERRERR + 2) #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 504
#endif /* LUA_ERRGCMM define */
#if !defined(LUA_ERRGCMM)
#endif // Lua 5.4 only /* So Lua 5.4 actually removes this, which breaks sol2...
man, this API is quite unstable...!
*/
# define LUA_ERRGCMM (LUA_ERRERR + 2)
#endif /* LUA_ERRGCMM define */
#endif // Lua 5.4 only
#endif // NOT_KEPLER_PROJECT_COMPAT54_H_ #endif // NOT_KEPLER_PROJECT_COMPAT54_H_

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -21,24 +21,40 @@
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_COMPATIBILITY_VERSION_HPP #ifndef SOL_COMPATIBILITY_LUA_VERSION_HPP
#define SOL_COMPATIBILITY_VERSION_HPP #define SOL_COMPATIBILITY_LUA_VERSION_HPP
#include <sol/version.hpp> #include <sol/version.hpp>
// clang-format off // clang-format off
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) #if SOL_IS_ON(SOL_USING_CXX_LUA)
#include <lua.h> #if __has_include(<lua/lua.h>)
#include <lualib.h> #include <lua/lua.h>
#include <lauxlib.h> #include <lua/lauxlib.h>
#elif SOL_IS_ON(SOL_USE_LUA_HPP_I_) #include <lua/lualib.h>
#include <lua.hpp> #else
#else
extern "C" {
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
#include <lualib.h> #include <lualib.h>
#endif
#elif SOL_IS_ON(SOL_USE_LUA_HPP)
#if __has_include(<lua/lua.hpp>)
#include <lua/lua.hpp>
#else
#include <lua.hpp>
#endif
#else
extern "C" {
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
} }
#endif // C++ Mangling for Lua vs. Not #endif // C++ Mangling for Lua vs. Not
@ -50,13 +66,15 @@
#endif #endif
#elif defined(LUAJIT_VERSION) #elif defined(LUAJIT_VERSION)
#define SOL_USE_LUAJIT_I_ SOL_ON #define SOL_USE_LUAJIT_I_ SOL_ON
#elif SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_USE_LUAJIT_I_ SOL_ON
#else #else
#define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF #define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
#endif // luajit #endif // luajit
#if SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) #if SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#include <luajit.h> #include <luajit.h>
#elif SOL_IS_ON(SOL_USE_LUAJIT_I_) #elif SOL_IS_ON(SOL_USE_LUAJIT)
extern "C" { extern "C" {
#include <luajit.h> #include <luajit.h>
} }
@ -64,7 +82,7 @@
#if defined(SOL_LUAJIT_VERSION) #if defined(SOL_LUAJIT_VERSION)
#define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION #define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION
#elif SOL_IS_ON(SOL_USE_LUAJIT_I_) #elif SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM #define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM
#else #else
#define SOL_LUAJIT_VERSION_I_ 0 #define SOL_LUAJIT_VERSION_I_ 0
@ -118,21 +136,25 @@
#else #else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
#endif #endif
#elif SOL_LUAJIT_VERSION_I_ >= 20100
// LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#elif SOL_LUAJIT_VERSION_I_ >= 20000
// LuaJIT 2.0.x have exception support only on x64 builds
#if SOL_IS_ON(SOL_PLATFORM_X64_I_)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
#endif
#else #else
// otherwise, there is no exception safety for #if SOL_IS_ON(SOL_USE_LUAJIT)
// shoving exceptions through Lua and errors should #if SOL_USE(SOL_LUAJIT_VERSION) >= 20100
// always be serialized // LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF #define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#elif SOL_USE(SOL_LUAJIT_VERSION) >= 20000
// LuaJIT 2.0.x have exception support only on x64 builds
#if SOL_IS_ON(SOL_PLATFORM_X64)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif
#endif
#else
// otherwise, there is no exception safety for
// shoving exceptions through Lua and errors should
// always be serialized
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif
#endif #endif
// Some configurations work with exceptions, // Some configurations work with exceptions,
@ -144,13 +166,14 @@
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF
#endif #endif
#else #else
#if SOL_IS_ON(SOL_USE_LUAJIT_I_) #if SOL_IS_ON(SOL_USE_LUAJIT) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) #elif SOL_IS_ON(SOL_USING_CXX_LUA)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF // C++ builds of Lua will throw an exception to implement its `yield` behavior;
#elif SOL_IS_ON(SOL_USE_CXX_LUA_I_) // it is irresponsible to "catch all" on this setting.
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#else #else
// Otherwise, by default, everyhting should be caught.
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON #define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
#endif #endif
#endif #endif
@ -162,7 +185,7 @@
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF
#endif #endif
#else #else
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) && SOL_IS_ON(SOL_USE_LUAJIT_I_) #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS) && SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
#else #else
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF #define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF
@ -176,7 +199,7 @@
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF
#endif #endif
#else #else
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_) && (SOL_LUA_VERSION > 501) #if SOL_IS_OFF(SOL_USE_LUAJIT) && (SOL_LUA_VERSION > 501)
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
#else #else
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF #define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF
@ -192,7 +215,11 @@
#else #else
// Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags) // Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
// Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it) // Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
#if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0))) #if (SOL_LUA_VERSION_I_ == 502)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif defined(LUA_COMPAT_BITLIB)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (SOL_LUA_VERSION_I_ < 504 && defined(LUA_COMPAT_5_2))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON #define SOL_LUA_BIT32_LIB_I_ SOL_ON
#else #else
#define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF #define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF
@ -215,4 +242,4 @@
// clang-format on // clang-format on
#endif // SOL_COMPATIBILITY_VERSION_HPP #endif // SOL_COMPATIBILITY_LUA_VERSION_HPP

50
extern/sol3/sol/config.hpp vendored Normal file
View file

@ -0,0 +1,50 @@
// 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_CONFIG_HPP
#define SOL_CONFIG_HPP
/* Base, empty configuration file!
To override, place a file in your include paths of the form:
. (your include path here)
| sol (directory, or equivalent)
| config.hpp (your config.hpp file)
So that when sol2 includes the file
#include <sol/config.hpp>
it gives you the configuration values you desire. Configuration values can be
seen in the safety.rst of the doc/src, or at
https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through
the build system, or the command line options of your compiler.
*/
#endif // SOL_CONFIG_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -94,7 +94,7 @@ namespace sol {
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(T&& r) noexcept basic_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) { : base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) { if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
@ -157,7 +157,7 @@ namespace sol {
} }
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) { basic_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_coroutine>(lua_state(), -1, handler); stack::check<basic_coroutine>(lua_state(), -1, handler);
@ -180,7 +180,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_coroutine>(L, index, handler); stack::check<basic_coroutine>(L, index, handler);
#endif // Safety #endif // Safety
@ -189,7 +189,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_coroutine>(L, index, handler); stack::check<basic_coroutine>(L, index, handler);
#endif // Safety #endif // Safety
@ -198,7 +198,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_coroutine>(lua_state(), -1, handler); stack::check<basic_coroutine>(lua_state(), -1, handler);

View file

@ -1,52 +1,63 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEBUG_HPP #ifndef SOL_DEBUG_HPP
#define SOL_DEBUG_HPP #define SOL_DEBUG_HPP
#include <sol/stack.hpp> #include <sol/stack.hpp>
#include <iostream> #include <iostream>
namespace sol { namespace detail { namespace debug { namespace sol { namespace detail { namespace debug {
inline std::string dump_types(lua_State* L) { inline std::string dump_types(lua_State* L) {
std::string visual; std::string visual;
std::size_t size = lua_gettop(L) + 1; std::size_t size = lua_gettop(L) + 1;
for (std::size_t i = 1; i < size; ++i) { for (std::size_t i = 1; i < size; ++i) {
if (i != 1) { if (i != 1) {
visual += " | "; visual += " | ";
} }
visual += type_name(L, stack::get<type>(L, static_cast<int>(i))); visual += type_name(L, stack::get<type>(L, static_cast<int>(i)));
} }
return visual; return visual;
} }
inline void print_stack(lua_State* L) { inline void print_stack(lua_State* L) {
std::cout << dump_types(L) << std::endl; std::cout << dump_types(L) << std::endl;
} }
inline void print_section(const std::string& message, lua_State* L) { inline void print_section(const std::string& message, lua_State* L) {
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl; std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
} }
}}} // namespace sol::detail::debug
inline void print_lua_information(lua_State* L) {
#endif // SOL_DEBUG_HPP std::cout << "Lua Version: " << SOL_USE(SOL_LUA_VERSION) << std::endl;
std::cout << "Lua (C++): " << SOL_IS_ON(SOL_USING_CXX_LUA) << std::endl;
std::cout << "Trampoline Propagate Exceptions?: " << SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS) << std::endl;
std::cout << "Catch-all Exceptions?: " << SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL) << std::endl;
std::cout << "LuaJIT: " << SOL_IS_ON(SOL_USE_LUAJIT) << std::endl;
std::cout << "LuaJIT Version: " << SOL_USE(SOL_LUAJIT_VERSION) << std::endl;
std::cout << "LuaJIT (C++): " << SOL_IS_ON(SOL_USING_CXX_LUAJIT) << std::endl;
std::cout << "LuaJIT Exception Trampoline: " << SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE) << std::endl;
}
}}} // namespace sol::detail::debug
#endif // SOL_DEBUG_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -28,7 +28,7 @@
#include <string> #include <string>
#include <array> #include <array>
#include <cctype> #include <cctype>
#if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED_I_) #if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED)
extern "C" { extern "C" {
#include <ctype.h> #include <ctype.h>
} }
@ -47,7 +47,7 @@ namespace sol { namespace detail {
"`anonymous namespace'" } }; "`anonymous namespace'" } };
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
inline std::string ctti_get_type_name_from_sig(std::string name) { inline std::string ctti_get_type_name_from_sig(std::string name) {
// cardinal sins from MINGW // cardinal sins from MINGW
using namespace std; using namespace std;
@ -85,7 +85,7 @@ namespace sol { namespace detail {
inline std::string ctti_get_type_name() { inline std::string ctti_get_type_name() {
return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__); return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
} }
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) #elif SOL_IS_ON(SOL_COMPILER_VCXX)
inline std::string ctti_get_type_name_from_sig(std::string name) { inline std::string ctti_get_type_name_from_sig(std::string name) {
std::size_t start = name.find("get_type_name"); std::size_t start = name.find("get_type_name");
if (start == std::string::npos) if (start == std::string::npos)

View file

@ -1,44 +1,44 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DEPRECATE_HPP #ifndef SOL_DEPRECATE_HPP
#define SOL_DEPRECATE_HPP #define SOL_DEPRECATE_HPP
#ifndef SOL_DEPRECATED #ifndef SOL_DEPRECATED
#ifdef _MSC_VER #ifdef _MSC_VER
#define SOL_DEPRECATED __declspec(deprecated) #define SOL_DEPRECATED __declspec(deprecated)
#elif __GNUC__ #elif __GNUC__
#define SOL_DEPRECATED __attribute__((deprecated)) #define SOL_DEPRECATED __attribute__((deprecated))
#else #else
#define SOL_DEPRECATED [[deprecated]] #define SOL_DEPRECATED [[deprecated]]
#endif // compilers #endif // compilers
#endif // SOL_DEPRECATED #endif // SOL_DEPRECATED
namespace sol { namespace detail { namespace sol { namespace detail {
template <typename T> template <typename T>
struct SOL_DEPRECATED deprecate_type { struct SOL_DEPRECATED deprecate_type {
using type = T; using type = T;
}; };
}} // namespace sol::detail }} // namespace sol::detail
#endif // SOL_DEPRECATE_HPP #endif // SOL_DEPRECATE_HPP

View file

@ -1,232 +1,232 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#ifndef SOL_DETAIL_BUILD_VERSION_HPP #ifndef SOL_DETAIL_BUILD_VERSION_HPP
#define SOL_DETAIL_BUILD_VERSION_HPP #define SOL_DETAIL_BUILD_VERSION_HPP
#include <sol/version.hpp> #include <sol/version.hpp>
// clang-format off // clang-format off
#if defined(SOL_DLL) #if defined(SOL_DLL)
#if (SOL_DLL != 0) #if (SOL_DLL != 0)
#define SOL_DLL_I_ SOL_ON #define SOL_DLL_I_ SOL_ON
#else #else
#define SOL_DLL_I_ SOL_OFF #define SOL_DLL_I_ SOL_OFF
#endif #endif
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(DLL_) || defined(_DLL)) #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL))
#define SOL_DLL_I_ SOL_DEFAULT_ON #define SOL_DLL_I_ SOL_DEFAULT_ON
#else #else
#define SOL_DLL_I_ SOL_DEFAULT_OFF #define SOL_DLL_I_ SOL_DEFAULT_OFF
#endif // DLL definition #endif // DLL definition
#if defined(SOL_HEADER_ONLY) #if defined(SOL_HEADER_ONLY)
#if (SOL_HEADER_ONLY != 0) #if (SOL_HEADER_ONLY != 0)
#define SOL_HEADER_ONLY_I_ SOL_ON #define SOL_HEADER_ONLY_I_ SOL_ON
#else #else
#define SOL_HEADER_ONLY_I_ SOL_OFF #define SOL_HEADER_ONLY_I_ SOL_OFF
#endif #endif
#else #else
#define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF #define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF
#endif // Header only library #endif // Header only library
#if defined(SOL_BUILD) #if defined(SOL_BUILD)
#if (SOL_BUILD != 0) #if (SOL_BUILD != 0)
#define SOL_BUILD_I_ SOL_ON #define SOL_BUILD_I_ SOL_ON
#else #else
#define SOL_BUILD_I_ SOL_OFF #define SOL_BUILD_I_ SOL_OFF
#endif #endif
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_) #elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_BUILD_I_ SOL_DEFAULT_OFF #define SOL_BUILD_I_ SOL_DEFAULT_OFF
#else #else
#define SOL_BUILD_I_ SOL_DEFAULT_ON #define SOL_BUILD_I_ SOL_DEFAULT_ON
#endif #endif
#if defined(SOL_UNITY_BUILD) #if defined(SOL_UNITY_BUILD)
#if (SOL_UNITY_BUILD != 0) #if (SOL_UNITY_BUILD != 0)
#define SOL_UNITY_BUILD_I_ SOL_ON #define SOL_UNITY_BUILD_I_ SOL_ON
#else #else
#define SOL_UNITY_BUILD_I_ SOL_OFF #define SOL_UNITY_BUILD_I_ SOL_OFF
#endif #endif
#else #else
#define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF #define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF
#endif // Header only library #endif // Header only library
#if defined(SOL_C_FUNCTION_LINKAGE) #if defined(SOL_C_FUNCTION_LINKAGE)
#define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE #define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE
#else #else
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_) #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
// C++ // C++
#define SOL_C_FUNCTION_LINKAGE_I_ extern "C" #define SOL_C_FUNCTION_LINKAGE_I_ extern "C"
#else #else
// normal // normal
#define SOL_C_FUNCTION_LINKAGE_I_ #define SOL_C_FUNCTION_LINKAGE_I_
#endif // C++ or not #endif // C++ or not
#endif // Linkage specification for C functions #endif // Linkage specification for C functions
#if defined(SOL_API_LINKAGE) #if defined(SOL_API_LINKAGE)
#define SOL_API_LINKAGE_I_ SOL_API_LINKAGE #define SOL_API_LINKAGE_I_ SOL_API_LINKAGE
#else #else
#if SOL_IS_ON(SOL_DLL_I_) #if SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) || SOL_IS_ON(SOL_PLATFORM_WINDOWS_I_) || SOL_IS_ON(SOL_PLATFORM_CYGWIN_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN)
// MSVC Compiler; or, Windows, or Cygwin platforms // MSVC Compiler; or, Windows, or Cygwin platforms
#if SOL_IS_ON(SOL_BUILD_I_) #if SOL_IS_ON(SOL_BUILD)
// Building the library // Building the library
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) #if SOL_IS_ON(SOL_COMPILER_GCC)
// Using GCC // Using GCC
#define SOL_API_LINKAGE_I_ __attribute__((dllexport)) #define SOL_API_LINKAGE_I_ __attribute__((dllexport))
#else #else
// Using Clang, MSVC, etc... // Using Clang, MSVC, etc...
#define SOL_API_LINKAGE_I_ __declspec(dllexport) #define SOL_API_LINKAGE_I_ __declspec(dllexport)
#endif #endif
#else #else
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) #if SOL_IS_ON(SOL_COMPILER_GCC)
#define SOL_API_LINKAGE_I_ __attribute__((dllimport)) #define SOL_API_LINKAGE_I_ __attribute__((dllimport))
#else #else
#define SOL_API_LINKAGE_I_ __declspec(dllimport) #define SOL_API_LINKAGE_I_ __declspec(dllimport)
#endif #endif
#endif #endif
#else #else
// extern if building normally on non-MSVC // extern if building normally on non-MSVC
#define SOL_API_LINKAGE_I_ extern #define SOL_API_LINKAGE_I_ extern
#endif #endif
#elif SOL_IS_ON(SOL_UNITY_BUILD_I_) #elif SOL_IS_ON(SOL_UNITY_BUILD)
// Built-in library, like how stb typical works // Built-in library, like how stb typical works
#if SOL_IS_ON(SOL_HEADER_ONLY_I_) #if SOL_IS_ON(SOL_HEADER_ONLY)
// Header only, so functions are defined "inline" // Header only, so functions are defined "inline"
#define SOL_API_LINKAGE_I_ inline #define SOL_API_LINKAGE_I_ inline
#else #else
// Not header only, so seperately compiled files // Not header only, so seperately compiled files
#define SOL_API_LINKAGE_I_ extern #define SOL_API_LINKAGE_I_ extern
#endif #endif
#else #else
// Normal static library // Normal static library
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_) #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#define SOL_API_LINKAGE_I_ #define SOL_API_LINKAGE_I_
#else #else
#define SOL_API_LINKAGE_I_ extern #define SOL_API_LINKAGE_I_ extern
#endif #endif
#endif // DLL or not #endif // DLL or not
#endif // Build definitions #endif // Build definitions
#if defined(SOL_PUBLIC_FUNC_DECL) #if defined(SOL_PUBLIC_FUNC_DECL)
#define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL #define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL
#else #else
#define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_ #define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_
#endif #endif
#if defined(SOL_INTERNAL_FUNC_DECL_) #if defined(SOL_INTERNAL_FUNC_DECL_)
#define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_ #define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_
#else #else
#define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_ #define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_
#endif #endif
#if defined(SOL_PUBLIC_FUNC_DEF) #if defined(SOL_PUBLIC_FUNC_DEF)
#define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF #define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF
#else #else
#define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_ #define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_
#endif #endif
#if defined(SOL_INTERNAL_FUNC_DEF) #if defined(SOL_INTERNAL_FUNC_DEF)
#define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF #define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF
#else #else
#define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_ #define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_
#endif #endif
#if defined(SOL_FUNC_DECL) #if defined(SOL_FUNC_DECL)
#define SOL_FUNC_DECL_I_ SOL_FUNC_DECL #define SOL_FUNC_DECL_I_ SOL_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_) #elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_FUNC_DECL_I_ #define SOL_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL_I_) #elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD_I_) #if SOL_IS_ON(SOL_BUILD)
#define SOL_FUNC_DECL_I_ extern __declspec(dllexport) #define SOL_FUNC_DECL_I_ extern __declspec(dllexport)
#else #else
#define SOL_FUNC_DECL_I_ extern __declspec(dllimport) #define SOL_FUNC_DECL_I_ extern __declspec(dllimport)
#endif #endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default"))) #define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default")))
#else #else
#define SOL_FUNC_DECL_I_ extern #define SOL_FUNC_DECL_I_ extern
#endif #endif
#endif #endif
#if defined(SOL_FUNC_DEFN) #if defined(SOL_FUNC_DEFN)
#define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN #define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_) #elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_FUNC_DEFN_I_ inline #define SOL_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL_I_) #elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD_I_) #if SOL_IS_ON(SOL_BUILD)
#define SOL_FUNC_DEFN_I_ __declspec(dllexport) #define SOL_FUNC_DEFN_I_ __declspec(dllexport)
#else #else
#define SOL_FUNC_DEFN_I_ __declspec(dllimport) #define SOL_FUNC_DEFN_I_ __declspec(dllimport)
#endif #endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_FUNC_DEFN_I_ __attribute__((visibility("default"))) #define SOL_FUNC_DEFN_I_ __attribute__((visibility("default")))
#else #else
#define SOL_FUNC_DEFN_I_ #define SOL_FUNC_DEFN_I_
#endif #endif
#endif #endif
#if defined(SOL_HIDDEN_FUNC_DECL) #if defined(SOL_HIDDEN_FUNC_DECL)
#define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL #define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_) #elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_HIDDEN_FUNC_DECL_I_ #define SOL_HIDDEN_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL_I_) #elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD_I_) #if SOL_IS_ON(SOL_BUILD)
#define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport) #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport)
#else #else
#define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport) #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport)
#endif #endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default"))) #define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default")))
#else #else
#define SOL_HIDDEN_FUNC_DECL_I_ extern #define SOL_HIDDEN_FUNC_DECL_I_ extern
#endif #endif
#endif #endif
#if defined(SOL_HIDDEN_FUNC_DEFN) #if defined(SOL_HIDDEN_FUNC_DEFN)
#define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN #define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_) #elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_HIDDEN_FUNC_DEFN_I_ inline #define SOL_HIDDEN_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL_I_) #elif SOL_IS_ON(SOL_DLL)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
#if SOL_IS_ON(SOL_BUILD_I_) #if SOL_IS_ON(SOL_BUILD)
#define SOL_HIDDEN_FUNC_DEFN_I_ #define SOL_HIDDEN_FUNC_DEFN_I_
#else #else
#define SOL_HIDDEN_FUNC_DEFN_I_ #define SOL_HIDDEN_FUNC_DEFN_I_
#endif #endif
#elif SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden"))) #define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden")))
#else #else
#define SOL_HIDDEN_FUNC_DEFN_I_ #define SOL_HIDDEN_FUNC_DEFN_I_
#endif #endif
#endif #endif
// clang-format on // clang-format on
#endif // SOL_DETAIL_BUILD_VERSION_HPP #endif // SOL_DETAIL_BUILD_VERSION_HPP

View file

@ -1,77 +1,77 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DUMP_HANDLER_HPP #ifndef SOL_DUMP_HANDLER_HPP
#define SOL_DUMP_HANDLER_HPP #define SOL_DUMP_HANDLER_HPP
#include <sol/compatibility.hpp> #include <sol/compatibility.hpp>
#include <cstdint> #include <cstdint>
#include <exception> #include <exception>
namespace sol { namespace sol {
class dump_error : public error { class dump_error : public error {
private: private:
int m_ec; int m_ec;
public: public:
dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), m_ec(error_code_) { dump_error(int error_code_) : error("dump returned non-zero error of " + std::to_string(error_code_)), m_ec(error_code_) {
} }
int error_code() const { int error_code() const {
return m_ec; return m_ec;
} }
}; };
inline int dump_pass_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) { inline int dump_pass_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
(void)L_; (void)L_;
(void)writer_function; (void)writer_function;
(void)userdata_pointer_; (void)userdata_pointer_;
(void)strip; (void)strip;
return result_code; return result_code;
} }
inline int dump_panic_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) { inline int dump_panic_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
(void)L_; (void)L_;
(void)writer_function; (void)writer_function;
(void)userdata_pointer_; (void)userdata_pointer_;
(void)strip; (void)strip;
return luaL_error(L_, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code); return luaL_error(L_, "a non-zero error code (%d) was returned by the lua_Writer for the dump function", result_code);
} }
inline int dump_throw_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) { inline int dump_throw_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
return dump_panic_on_error(L_, result_code, writer_function, userdata_pointer_, strip); return dump_panic_on_error(L_, result_code, writer_function, userdata_pointer_, strip);
#else #else
(void)L_; (void)L_;
(void)writer_function; (void)writer_function;
(void)userdata_pointer_; (void)userdata_pointer_;
(void)strip; (void)strip;
throw dump_error(result_code); throw dump_error(result_code);
#endif // no exceptions stuff #endif // no exceptions stuff
} }
} // namespace sol } // namespace sol
#endif // SOL_DUMP_HANDLER_HPP #endif // SOL_DUMP_HANDLER_HPP

View file

@ -1,160 +1,161 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_EBCO_HPP #ifndef SOL_EBCO_HPP
#define SOL_EBCO_HPP #define SOL_EBCO_HPP
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include <memory>
namespace sol { namespace detail {
namespace sol { namespace detail {
template <typename T, std::size_t tag = 0, typename = void>
struct ebco { template <typename T, std::size_t tag = 0, typename = void>
T m_value; struct ebco {
T m_value;
ebco() = default;
ebco(const ebco&) = default; ebco() = default;
ebco(ebco&&) = default; ebco(const ebco&) = default;
ebco& operator=(const ebco&) = default; ebco(ebco&&) = default;
ebco& operator=(ebco&&) = default; ebco& operator=(const ebco&) = default;
ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : m_value(v) {}; ebco& operator=(ebco&&) = default;
ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : m_value(std::move(v)) {}; ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : m_value(v) {};
ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) { ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : m_value(std::move(v)) {};
m_value = v; ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
return *this; m_value = v;
} return *this;
ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) { }
m_value = std::move(v); ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
return *this; m_value = std::move(v);
}; return *this;
template <typename Arg, typename... Args, };
typename = std::enable_if_t< template <typename Arg, typename... Args,
!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, typename = std::enable_if_t<
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>> !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
: m_value(std::forward<Arg>(arg), std::forward<Args>(args)...) { ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>)
} : m_value(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
T& value() & noexcept {
return m_value; T& value() & noexcept {
} return m_value;
}
T const& value() const& noexcept {
return m_value; T const& value() const& noexcept {
} return m_value;
}
T&& value() && noexcept {
return std::move(m_value); T&& value() && noexcept {
} return std::move(m_value);
}; }
};
template <typename T, std::size_t tag>
struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T { template <typename T, std::size_t tag>
ebco() = default; struct ebco<T, tag, std::enable_if_t<!std::is_reference_v<T> && std::is_class_v<T> && !std::is_final_v<T>>> : T {
ebco(const ebco&) = default; ebco() = default;
ebco(ebco&&) = default; ebco(const ebco&) = default;
ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : T(v) {}; ebco(ebco&&) = default;
ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : T(std::move(v)) {}; ebco(const T& v) noexcept(std::is_nothrow_copy_constructible_v<T>) : T(v) {};
template <typename Arg, typename... Args, ebco(T&& v) noexcept(std::is_nothrow_move_constructible_v<T>) : T(std::move(v)) {};
typename = std::enable_if_t< template <typename Arg, typename... Args,
!std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, typename = std::enable_if_t<
ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>> !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>,
ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) { ebco> && !std::is_same_v<std::remove_reference_t<std::remove_cv_t<Arg>>, T> && (sizeof...(Args) > 0 || !std::is_convertible_v<Arg, T>)>>
} ebco(Arg&& arg, Args&&... args) noexcept(std::is_nothrow_constructible_v<T, Arg, Args...>) : T(std::forward<Arg>(arg), std::forward<Args>(args)...) {
}
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default; ebco& operator=(const ebco&) = default;
ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) { ebco& operator=(ebco&&) = default;
static_cast<T&>(*this) = v; ebco& operator=(const T& v) noexcept(std::is_nothrow_copy_assignable_v<T>) {
return *this; static_cast<T&>(*this) = v;
} return *this;
ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) { }
static_cast<T&>(*this) = std::move(v); ebco& operator=(T&& v) noexcept(std::is_nothrow_move_assignable_v<T>) {
return *this; static_cast<T&>(*this) = std::move(v);
}; return *this;
};
T& value() & noexcept {
return static_cast<T&>(*this); T& value() & noexcept {
} return static_cast<T&>(*this);
}
T const& value() const& noexcept {
return static_cast<T const&>(*this); T const& value() const& noexcept {
} return static_cast<T const&>(*this);
}
T&& value() && noexcept {
return std::move(static_cast<T&>(*this)); T&& value() && noexcept {
} return std::move(static_cast<T&>(*this));
}; }
};
template <typename T, std::size_t tag>
struct ebco<T&, tag> { template <typename T, std::size_t tag>
private: struct ebco<T&, tag> {
T* m_ref; private:
T* m_ref;
public:
ebco() = default; public:
ebco(const ebco&) = default; ebco() = default;
ebco(ebco&&) = default; ebco(const ebco&) = default;
ebco(T& v) noexcept : m_ref(std::addressof(v)) {}; ebco(ebco&&) = default;
ebco(T& v) noexcept : m_ref(std::addressof(v)) {};
ebco& operator=(const ebco&) = default;
ebco& operator=(ebco&&) = default; ebco& operator=(const ebco&) = default;
ebco& operator=(T& v) noexcept { ebco& operator=(ebco&&) = default;
m_ref = std::addressof(v); ebco& operator=(T& v) noexcept {
return *this; m_ref = std::addressof(v);
} return *this;
}
T& value() const noexcept {
return *(const_cast<ebco<T&, tag>&>(*this).m_ref); T& value() const noexcept {
} return *(const_cast<ebco<T&, tag>&>(*this).m_ref);
}; }
};
template <typename T, std::size_t tag>
struct ebco<T&&, tag> { template <typename T, std::size_t tag>
T&& ref; struct ebco<T&&, tag> {
T&& ref;
ebco() = default;
ebco(const ebco&) = delete; ebco() = default;
ebco(ebco&&) = default; ebco(const ebco&) = delete;
ebco(T&& v) noexcept : ref(v) {}; ebco(ebco&&) = default;
ebco(T&& v) noexcept : ref(v) {};
ebco& operator=(const ebco&) = delete;
ebco& operator=(ebco&&) = delete; ebco& operator=(const ebco&) = delete;
ebco& operator=(ebco&&) = delete;
T& value() & noexcept {
return ref; T& value() & noexcept {
} return ref;
}
const T& value() const& noexcept {
return ref; const T& value() const& noexcept {
} return ref;
}
T&& value() && noexcept {
return std::move(ref); T&& value() && noexcept {
} return std::move(ref);
}; }
};
}} // namespace sol::detail
}} // namespace sol::detail
#endif // SOL_EBCO_HPP
#endif // SOL_EBCO_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -58,29 +58,29 @@ namespace sol {
basic_environment(env_key_t, const stack_reference& extraction_target) basic_environment(env_key_t, const stack_reference& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) { : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<env_key_t>(this->lua_state(), -1, handler); stack::check<env_key_t>(this->lua_state(), -1, handler);
#endif // Safety #endif // Safety
lua_pop(this->lua_state(), 2); lua_pop(this->lua_state(), 1);
} }
template <bool b> template <bool b>
basic_environment(env_key_t, const basic_reference<b>& extraction_target) basic_environment(env_key_t, const basic_reference<b>& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) { : base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<env_key_t>(this->lua_state(), -1, handler); stack::check<env_key_t>(this->lua_state(), -1, handler);
#endif // Safety #endif // Safety
lua_pop(this->lua_state(), 2); lua_pop(this->lua_state(), 1);
} }
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) { basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_environment>(L, index, handler); stack::check<basic_environment>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) { basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_environment>(L, -1, handler); stack::check<basic_environment>(L, -1, handler);
@ -90,7 +90,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward<T>(r)) { basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_environment<meta::unqualified_t<T>>::value) { if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
@ -103,7 +103,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(lua_State* L, T&& r) noexcept : base_t(detail::no_safety, L, std::forward<T>(r)) { basic_environment(lua_State* L, T&& r) noexcept : base_t(detail::no_safety, L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_environment<meta::unqualified_t<T>>::value) { if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
@ -136,11 +136,13 @@ namespace sol {
const char* success = lua_setupvalue(L, target_index, 1); const char* success = lua_setupvalue(L, target_index, 1);
if (success == nullptr) { if (success == nullptr) {
// left things alone on the stack, pop them off // left things alone on the stack, pop them off
lua_pop(L, 1); lua_pop(L, 2);
return false; return false;
} }
lua_pop(L, 1);
return true; return true;
} }
lua_pop(L, 1);
return false; return false;
} }
else { else {
@ -152,6 +154,7 @@ namespace sol {
} }
string_view upvalue_name(maybe_upvalue_name); string_view upvalue_name(maybe_upvalue_name);
if (upvalue_name == "_ENV") { if (upvalue_name == "_ENV") {
lua_pop(L, 1);
this->push(); this->push();
const char* success = lua_setupvalue(L, target_index, upvalue_index); const char* success = lua_setupvalue(L, target_index, upvalue_index);
if (success == nullptr) { if (success == nullptr) {

View file

@ -1,39 +1,39 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
// clang-format off // clang-format off
#if !defined(SOL_PROLOGUE_I_) #if !defined(SOL_PROLOGUE_I_)
#error "[sol2] Library Prologue is missing from this translation unit." #error "[sol2] Library Prologue is missing from this translation unit."
#else #else
#undef SOL_PROLOGUE_I_ #undef SOL_PROLOGUE_I_
#endif #endif
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_) #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#undef _FWD #undef _FWD
#undef _MOVE #undef _MOVE
#endif #endif
// clang-format on // clang-format on

View file

@ -1,89 +1,102 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_ERROR_HPP #ifndef SOL_ERROR_HPP
#define SOL_ERROR_HPP #define SOL_ERROR_HPP
#include <sol/compatibility.hpp> #include <sol/compatibility.hpp>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <array> #include <array>
namespace sol { namespace sol {
namespace detail { namespace detail {
struct direct_error_tag { }; struct direct_error_tag { };
const auto direct_error = direct_error_tag {}; const auto direct_error = direct_error_tag {};
struct error_result { struct error_result {
int results; int results;
const char* format_string; const char* format_string;
std::array<const char*, 4> argument_strings; std::array<const char*, 4> argument_strings;
error_result() : results(0), format_string(nullptr) { error_result() : results(0), format_string(nullptr) {
} }
error_result(int results_) : results(results_), format_string(nullptr) { error_result(int results_) : results(results_), format_string(nullptr) {
} }
error_result(const char* format_string_, const char* first_message_) : results(0), format_string(format_string_), argument_strings() { error_result(const char* format_string_, const char* first_message_) : results(0), format_string(format_string_), argument_strings() {
argument_strings[0] = first_message_; argument_strings[0] = first_message_;
} }
}; };
inline int handle_errors(lua_State* L, const error_result& er) { inline int handle_errors(lua_State* L, const error_result& er) {
if (er.format_string == nullptr) { if (er.format_string == nullptr) {
return er.results; return er.results;
} }
return luaL_error(L, er.format_string, er.argument_strings[0], er.argument_strings[1], er.argument_strings[2], er.argument_strings[3]); return luaL_error(L, er.format_string, er.argument_strings[0], er.argument_strings[1], er.argument_strings[2], er.argument_strings[3]);
} }
} // namespace detail
class error_exception : public std::runtime_error {
class error : public std::runtime_error { public:
private: error_exception(const std::string& str) : error_exception(detail::direct_error, "lua: error: " + str) {
// Because VC++ is upsetting, most of the time! }
std::string what_reason; error_exception(std::string&& str) : error_exception(detail::direct_error, "lua: error: " + std::move(str)) {
}
public: error_exception(detail::direct_error_tag, const std::string& str) : std::runtime_error(str) {
error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) { }
} error_exception(detail::direct_error_tag, std::string&& str) : std::runtime_error(str) {
error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) { }
}
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), what_reason(str) { error_exception(const error_exception& e) = default;
} error_exception(error_exception&& e) = default;
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), what_reason(std::move(str)) { error_exception& operator=(const error_exception& e) = default;
} error_exception& operator=(error_exception&& e) = default;
};
error(const error& e) = default; } // namespace detail
error(error&& e) = default;
error& operator=(const error& e) = default; class error : public std::runtime_error {
error& operator=(error&& e) = default; private:
// Because VC++ is upsetting, most of the time!
virtual const char* what() const noexcept override { std::string what_reason;
return what_reason.c_str();
} public:
}; error(const std::string& str) : error(detail::direct_error, "lua: error: " + str) {
}
} // namespace sol error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
}
#endif // SOL_ERROR_HPP error(detail::direct_error_tag, const std::string& str) : std::runtime_error(str) {
}
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(str) {
}
error(const error& e) = default;
error(error&& e) = default;
error& operator=(const error& e) = default;
error& operator=(error&& e) = default;
};
} // namespace sol
#endif // SOL_ERROR_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -24,6 +24,7 @@
#ifndef SOL_ERROR_HANDLER_HPP #ifndef SOL_ERROR_HANDLER_HPP
#define SOL_ERROR_HANDLER_HPP #define SOL_ERROR_HANDLER_HPP
#include <sol/config.hpp>
#include <sol/types.hpp> #include <sol/types.hpp>
#include <sol/demangle.hpp> #include <sol/demangle.hpp>
@ -62,7 +63,7 @@ namespace sol {
case type::poly: case type::poly:
return "anything"; return "anything";
case type::userdata: { case type::userdata: {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 2, "not enough space to push get the type name"); luaL_checkstack(L, 2, "not enough space to push get the type name");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
if (lua_getmetatable(L, index) == 0) { if (lua_getmetatable(L, index) == 0) {
@ -84,7 +85,7 @@ namespace sol {
inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept { inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept {
const char* err = message.size() == 0 const char* err = message.size() == 0
? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s") ? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s%s")
: "stack index %d, expected %s, received %s: %s %s"; : "stack index %d, expected %s, received %s: %s %s";
const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected)); const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected));
{ {
@ -96,12 +97,16 @@ namespace sol {
inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) { inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, ""); push_type_panic_string(L, index, expected, actual, message, "");
return lua_error(L); size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
} }
inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) { inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, ""); push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, "");
return lua_error(L); size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
} }
struct type_panic_t { struct type_panic_t {
@ -118,7 +123,9 @@ namespace sol {
struct constructor_handler { struct constructor_handler {
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) { int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)"); push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)");
return lua_error(L); size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
} }
}; };
@ -126,7 +133,9 @@ namespace sol {
struct argument_handler { struct argument_handler {
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) { int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)"); push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)");
return lua_error(L); size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
} }
}; };
@ -142,7 +151,9 @@ namespace sol {
aux_message += ")')"; aux_message += ")')";
push_type_panic_string(L, index, expected, actual, message, aux_message); push_type_panic_string(L, index, expected, actual, message, aux_message);
} }
return lua_error(L); size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
} }
}; };

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -30,7 +30,7 @@
#include <type_traits> #include <type_traits>
#include <string_view> #include <string_view>
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) #if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
struct lua_State; struct lua_State;
#else #else
extern "C" { extern "C" {
@ -117,7 +117,7 @@ namespace sol {
using main_protected_function = main_safe_function; using main_protected_function = main_safe_function;
using stack_protected_function = stack_safe_function; using stack_protected_function = stack_safe_function;
using stack_aligned_protected_function = stack_aligned_safe_function; using stack_aligned_protected_function = stack_aligned_safe_function;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
using function = protected_function; using function = protected_function;
using main_function = main_protected_function; using main_function = main_protected_function;
using stack_function = stack_protected_function; using stack_function = stack_protected_function;
@ -133,7 +133,7 @@ namespace sol {
struct unsafe_function_result; struct unsafe_function_result;
struct protected_function_result; struct protected_function_result;
using safe_function_result = protected_function_result; using safe_function_result = protected_function_result;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
using function_result = safe_function_result; using function_result = safe_function_result;
#else #else
using function_result = unsafe_function_result; using function_result = unsafe_function_result;
@ -234,7 +234,7 @@ namespace sol {
struct record; struct record;
} }
#if SOL_IS_OFF(SOL_USE_BOOST_I_) #if SOL_IS_OFF(SOL_USE_BOOST)
template <class T> template <class T>
class optional; class optional;
@ -253,7 +253,7 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \ typedef ::sol::types<__VA_ARGS__> type; \
}; \ }; \
} \ } \
void a_sol3_detail_function_decl_please_no_collide() static_assert(true, "")
#define SOL_DERIVED_CLASSES(T, ...) \ #define SOL_DERIVED_CLASSES(T, ...) \
namespace sol { \ namespace sol { \
template <> \ template <> \
@ -261,6 +261,6 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \ typedef ::sol::types<__VA_ARGS__> type; \
}; \ }; \
} \ } \
void a_sol3_detail_function_decl_please_no_collide() static_assert(true, "")
#endif // SOL_FORWARD_HPP #endif // SOL_FORWARD_HPP

44
extern/sol3/sol/forward_as.hpp vendored Normal file
View file

@ -0,0 +1,44 @@
// 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_FORWARD_AS_HPP
#define SOL_FORWARD_AS_HPP
#include <sol/version.hpp>
#include <utility>
#include <type_traits>
namespace sol {
template <typename T, typename U>
constexpr decltype(auto) forward_as(U&& value) noexcept {
if constexpr (::std::is_lvalue_reference_v<T>) {
return value;
}
else {
return ::std::move(value);
}
}
}
#endif // SOL_FORWARD_AS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -32,7 +32,7 @@
namespace sol { namespace sol {
namespace detail { namespace detail {
const bool default_safe_function_calls = const bool default_safe_function_calls =
#if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS_I_) #if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS)
true; true;
#else #else
false; false;

View file

@ -1,142 +1,142 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_FUNCTION_HPP #ifndef SOL_FUNCTION_HPP
#define SOL_FUNCTION_HPP #define SOL_FUNCTION_HPP
#include <sol/stack.hpp> #include <sol/stack.hpp>
#include <sol/unsafe_function.hpp> #include <sol/unsafe_function.hpp>
#include <sol/protected_function.hpp> #include <sol/protected_function.hpp>
#include <sol/bytecode.hpp> #include <sol/bytecode.hpp>
#include <functional> #include <functional>
namespace sol { namespace sol {
template <typename... Ret, typename... Args> template <typename... Ret, typename... Args>
decltype(auto) stack_proxy::call(Args&&... args) { decltype(auto) stack_proxy::call(Args&&... args) {
stack_function sf(this->lua_state(), this->stack_index()); stack_function sf(this->lua_state(), this->stack_index());
return sf.template call<Ret...>(std::forward<Args>(args)...); return sf.template call<Ret...>(std::forward<Args>(args)...);
} }
inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept inline protected_function_result::protected_function_result(unsafe_function_result&& o) noexcept
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) { : L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()), popcount(o.return_count()), err(o.status()) {
// Must be manual, otherwise destructor will screw us // Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean // return count being 0 is enough to keep things clean
// but we will be thorough // but we will be thorough
o.abandon(); o.abandon();
} }
inline protected_function_result& protected_function_result::operator=(unsafe_function_result&& o) noexcept { inline protected_function_result& protected_function_result::operator=(unsafe_function_result&& o) noexcept {
L = o.lua_state(); L = o.lua_state();
index = o.stack_index(); index = o.stack_index();
returncount = o.return_count(); returncount = o.return_count();
popcount = o.return_count(); popcount = o.return_count();
err = o.status(); err = o.status();
// Must be manual, otherwise destructor will screw us // Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean // return count being 0 is enough to keep things clean
// but we will be thorough // but we will be thorough
o.abandon(); o.abandon();
return *this; return *this;
} }
inline unsafe_function_result::unsafe_function_result(protected_function_result&& o) noexcept inline unsafe_function_result::unsafe_function_result(protected_function_result&& o) noexcept
: L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) { : L(o.lua_state()), index(o.stack_index()), returncount(o.return_count()) {
// Must be manual, otherwise destructor will screw us // Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean // return count being 0 is enough to keep things clean
// but we will be thorough // but we will be thorough
o.abandon(); o.abandon();
} }
inline unsafe_function_result& unsafe_function_result::operator=(protected_function_result&& o) noexcept { inline unsafe_function_result& unsafe_function_result::operator=(protected_function_result&& o) noexcept {
L = o.lua_state(); L = o.lua_state();
index = o.stack_index(); index = o.stack_index();
returncount = o.return_count(); returncount = o.return_count();
// Must be manual, otherwise destructor will screw us // Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean // return count being 0 is enough to keep things clean
// but we will be thorough // but we will be thorough
o.abandon(); o.abandon();
return *this; return *this;
} }
namespace detail { namespace detail {
template <typename... R> template <typename... R>
struct std_shim { struct std_shim {
unsafe_function lua_func_; unsafe_function lua_func_;
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) { std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
} }
template <typename... Args> template <typename... Args>
meta::return_type_t<R...> operator()(Args&&... args) { meta::return_type_t<R...> operator()(Args&&... args) {
return lua_func_.call<R...>(std::forward<Args>(args)...); return lua_func_.call<R...>(std::forward<Args>(args)...);
} }
}; };
template <> template <>
struct std_shim<void> { struct std_shim<void> {
unsafe_function lua_func_; unsafe_function lua_func_;
std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) { std_shim(unsafe_function lua_func) : lua_func_(std::move(lua_func)) {
} }
template <typename... Args> template <typename... Args>
void operator()(Args&&... args) { void operator()(Args&&... args) {
lua_func_.call<void>(std::forward<Args>(args)...); lua_func_.call<void>(std::forward<Args>(args)...);
} }
}; };
} // namespace detail } // namespace detail
namespace stack { namespace stack {
template <typename Signature> template <typename Signature>
struct unqualified_getter<std::function<Signature>> { struct unqualified_getter<std::function<Signature>> {
typedef meta::bind_traits<Signature> fx_t; typedef meta::bind_traits<Signature> fx_t;
typedef typename fx_t::args_list args_lists; typedef typename fx_t::args_list args_lists;
typedef meta::tuple_types<typename fx_t::return_type> return_types; typedef meta::tuple_types<typename fx_t::return_type> return_types;
template <typename... R> template <typename... R>
static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) { static std::function<Signature> get_std_func(types<R...>, lua_State* L, int index) {
detail::std_shim<R...> fx(unsafe_function(L, index)); detail::std_shim<R...> fx(unsafe_function(L, index));
return fx; return fx;
} }
static std::function<Signature> get(lua_State* L, int index, record& tracking) { static std::function<Signature> get(lua_State* L, int index, record& tracking) {
tracking.use(1); tracking.use(1);
type t = type_of(L, index); type t = type_of(L, index);
if (t == type::none || t == type::lua_nil) { if (t == type::none || t == type::lua_nil) {
return nullptr; return nullptr;
} }
return get_std_func(return_types(), L, index); return get_std_func(return_types(), L, index);
} }
}; };
template <typename Allocator> template <typename Allocator>
struct unqualified_getter<basic_bytecode<Allocator>> { struct unqualified_getter<basic_bytecode<Allocator>> {
static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) { static basic_bytecode<Allocator> get(lua_State* L, int index, record& tracking) {
tracking.use(1); tracking.use(1);
stack_function sf(L, index); stack_function sf(L, index);
return sf.dump(&dump_panic_on_error); return sf.dump(&dump_panic_on_error);
} }
}; };
} // namespace stack } // namespace stack
} // namespace sol } // namespace sol
#endif // SOL_FUNCTION_HPP #endif // SOL_FUNCTION_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -217,7 +217,7 @@ namespace sol {
int upvalues = 0; int upvalues = 0;
upvalues += stack::push(L, nullptr); upvalues += stack::push(L, nullptr);
upvalues += stack::push(L, std::forward<Fx>(fx)); upvalues += stack::push(L, std::forward<Fx>(fx));
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) { if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<true>; detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<true>;
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues); lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
@ -237,7 +237,7 @@ namespace sol {
int upvalues = 0; int upvalues = 0;
upvalues += stack::push(L, nullptr); upvalues += stack::push(L, nullptr);
upvalues += stack::push(L, std::forward<Fx>(fx)); upvalues += stack::push(L, std::forward<Fx>(fx));
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) { if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>; detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>;
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues); lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
@ -398,7 +398,7 @@ namespace sol {
struct unqualified_pusher<Signature, struct unqualified_pusher<Signature,
std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>, std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>> meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
, ,
meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>, meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>> meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
@ -711,7 +711,7 @@ namespace sol {
namespace stack_detail { namespace stack_detail {
template <typename Function, typename Handler> template <typename Function, typename Handler>
bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept { bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
tracking.use(1); tracking.use(1);
bool success = lua_iscfunction(L, index) == 1; bool success = lua_iscfunction(L, index) == 1;
if (success) { if (success) {
@ -737,7 +737,7 @@ namespace sol {
template <typename Function> template <typename Function>
Function* get_function_pointer(lua_State* L, int index, record& tracking) noexcept { Function* get_function_pointer(lua_State* L, int index, record& tracking) noexcept {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
tracking.use(1); tracking.use(1);
auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L, index); auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L, index);
Function* fx = udata.first; Function* fx = udata.first;
@ -747,7 +747,7 @@ namespace sol {
(void)index; (void)index;
(void)tracking; (void)tracking;
static_assert(meta::meta_detail::always_true<Function>::value, static_assert(meta::meta_detail::always_true<Function>::value,
#if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE)
"You are attempting to retrieve a function pointer type. " "You are attempting to retrieve a function pointer type. "
"This is inherently unsafe in sol2. In order to do this, you must turn on the " "This is inherently unsafe in sol2. In order to do this, you must turn on the "
"SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. " "SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. "

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -62,4 +62,4 @@ namespace sol { namespace function_detail {
}; };
}} // namespace sol::function_detail }} // namespace sol::function_detail
#endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP #endif // SOL_FUNCTION_TYPES_OVERLOAD_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -74,7 +74,7 @@ namespace sol { namespace function_detail {
} }
static int call(lua_State* L, member_function& self) static int call(lua_State* L, member_function& self)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -90,7 +90,7 @@ namespace sol { namespace function_detail {
} }
int operator()(lua_State* L) int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -35,7 +35,7 @@ namespace sol { namespace function_detail {
using traits_type = meta::bind_traits<function_type>; using traits_type = meta::bind_traits<function_type>;
static int real_call(lua_State* L) static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -70,7 +70,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -88,7 +88,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline> template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -110,7 +110,7 @@ namespace sol { namespace function_detail {
} }
int operator()(lua_State* L) int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -126,7 +126,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -153,7 +153,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline> template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -175,7 +175,7 @@ namespace sol { namespace function_detail {
} }
int operator()(lua_State* L) int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -191,7 +191,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -216,7 +216,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline> template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -238,7 +238,7 @@ namespace sol { namespace function_detail {
} }
int operator()(lua_State* L) int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -254,7 +254,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type; typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L) static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -268,7 +268,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline> template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -290,7 +290,7 @@ namespace sol { namespace function_detail {
} }
int operator()(lua_State* L) int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) #if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise... // MSVC is broken, what a surprise...
#else #else
noexcept(traits_type::is_noexcept) noexcept(traits_type::is_noexcept)
@ -320,7 +320,13 @@ namespace sol { namespace function_detail {
} }
template <bool is_yielding, bool no_trampoline> template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_CLANG)
// apparent regression in clang 18 - llvm/llvm-project#91362
#else
noexcept(std::is_nothrow_copy_assignable_v<T>)
#endif
{
int nr; int nr;
if constexpr (no_trampoline) { if constexpr (no_trampoline) {
nr = real_call(L); nr = real_call(L);
@ -360,7 +366,13 @@ namespace sol { namespace function_detail {
} }
template <bool is_yielding, bool no_trampoline> template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) { static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_CLANG)
// apparent regression in clang 18 - llvm/llvm-project#91362
#else
noexcept(std::is_nothrow_copy_assignable_v<T>)
#endif
{
int nr; int nr;
if constexpr (no_trampoline) { if constexpr (no_trampoline) {
nr = real_call(L); nr = real_call(L);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -121,7 +121,7 @@ namespace sol {
typedef meta::unqualified_t<F> Fu; typedef meta::unqualified_t<F> Fu;
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
std::is_same<Fu, lua_CFunction>::value std::is_same<Fu, lua_CFunction>::value
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
|| std::is_same<Fu, detail::lua_CFunction_noexcept>::value || std::is_same<Fu, detail::lua_CFunction_noexcept>::value
#endif #endif
> >

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -1,195 +1,195 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_INHERITANCE_HPP #ifndef SOL_INHERITANCE_HPP
#define SOL_INHERITANCE_HPP #define SOL_INHERITANCE_HPP
#include <sol/types.hpp> #include <sol/types.hpp>
#include <sol/usertype_traits.hpp> #include <sol/usertype_traits.hpp>
#include <sol/unique_usertype_traits.hpp> #include <sol/unique_usertype_traits.hpp>
namespace sol { namespace sol {
template <typename... Args> template <typename... Args>
struct base_list { }; struct base_list { };
template <typename... Args> template <typename... Args>
using bases = base_list<Args...>; using bases = base_list<Args...>;
typedef bases<> base_classes_tag; typedef bases<> base_classes_tag;
const auto base_classes = base_classes_tag(); const auto base_classes = base_classes_tag();
template <typename... Args> template <typename... Args>
struct is_to_stringable<base_list<Args...>> : std::false_type { }; struct is_to_stringable<base_list<Args...>> : std::false_type { };
namespace detail { namespace detail {
inline decltype(auto) base_class_check_key() { inline decltype(auto) base_class_check_key() {
static const auto& key = "class_check"; static const auto& key = "class_check";
return key; return key;
} }
inline decltype(auto) base_class_cast_key() { inline decltype(auto) base_class_cast_key() {
static const auto& key = "class_cast"; static const auto& key = "class_cast";
return key; return key;
} }
inline decltype(auto) base_class_index_propogation_key() { inline decltype(auto) base_class_index_propogation_key() {
static const auto& key = u8"\xF0\x9F\x8C\xB2.index"; static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
return key; return key;
} }
inline decltype(auto) base_class_new_index_propogation_key() { inline decltype(auto) base_class_new_index_propogation_key() {
static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index"; static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
return key; return key;
} }
template <typename T> template <typename T>
struct inheritance { struct inheritance {
typedef typename base<T>::type bases_t; typedef typename base<T>::type bases_t;
static bool type_check_bases(types<>, const string_view&) { static bool type_check_bases(types<>, const string_view&) {
return false; return false;
} }
template <typename Base, typename... Args> template <typename Base, typename... Args>
static bool type_check_bases(types<Base, Args...>, const string_view& ti) { static bool type_check_bases(types<Base, Args...>, const string_view& ti) {
return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti); return ti == usertype_traits<Base>::qualified_name() || type_check_bases(types<Args...>(), ti);
} }
static bool type_check(const string_view& ti) { static bool type_check(const string_view& ti) {
return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti); return ti == usertype_traits<T>::qualified_name() || type_check_bases(bases_t(), ti);
} }
template <typename... Bases> template <typename... Bases>
static bool type_check_with(const string_view& ti) { static bool type_check_with(const string_view& ti) {
return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti); return ti == usertype_traits<T>::qualified_name() || type_check_bases(types<Bases...>(), ti);
} }
static void* type_cast_bases(types<>, T*, const string_view&) { static void* type_cast_bases(types<>, T*, const string_view&) {
return nullptr; return nullptr;
} }
template <typename Base, typename... Args> template <typename Base, typename... Args>
static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) { static void* type_cast_bases(types<Base, Args...>, T* data, const string_view& ti) {
// Make sure to convert to T first, and then dynamic cast to the proper type // Make sure to convert to T first, and then dynamic cast to the proper type
return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti) return ti != usertype_traits<Base>::qualified_name() ? type_cast_bases(types<Args...>(), data, ti)
: static_cast<void*>(static_cast<Base*>(data)); : static_cast<void*>(static_cast<Base*>(data));
} }
static void* type_cast(void* voiddata, const string_view& ti) { static void* type_cast(void* voiddata, const string_view& ti) {
T* data = static_cast<T*>(voiddata); T* data = static_cast<T*>(voiddata);
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data); return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(bases_t(), data, ti) : data);
} }
template <typename... Bases> template <typename... Bases>
static void* type_cast_with(void* voiddata, const string_view& ti) { static void* type_cast_with(void* voiddata, const string_view& ti) {
T* data = static_cast<T*>(voiddata); T* data = static_cast<T*>(voiddata);
return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data); return static_cast<void*>(ti != usertype_traits<T>::qualified_name() ? type_cast_bases(types<Bases...>(), data, ti) : data);
} }
template <typename U> template <typename U>
static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) { static bool type_unique_cast_bases(types<>, void*, void*, const string_view&) {
return 0; return 0;
} }
template <typename U, typename Base, typename... Args> template <typename U, typename Base, typename... Args>
static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) { static int type_unique_cast_bases(types<Base, Args...>, void* source_data, void* target_data, const string_view& ti) {
using uu_traits = unique_usertype_traits<U>; using uu_traits = unique_usertype_traits<U>;
using base_ptr = typename uu_traits::template rebind_actual_type<Base>; using base_ptr = typename uu_traits::template rebind_actual_type<Base>;
string_view base_ti = usertype_traits<Base>::qualified_name(); string_view base_ti = usertype_traits<Base>::qualified_name();
if (base_ti == ti) { if (base_ti == ti) {
if (target_data != nullptr) { if (target_data != nullptr) {
U* source = static_cast<U*>(source_data); U* source = static_cast<U*>(source_data);
base_ptr* target = static_cast<base_ptr*>(target_data); base_ptr* target = static_cast<base_ptr*>(target_data);
// perform proper derived -> base conversion // perform proper derived -> base conversion
*target = *source; *target = *source;
} }
return 2; return 2;
} }
return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti); return type_unique_cast_bases<U>(types<Args...>(), source_data, target_data, ti);
} }
template <typename U> template <typename U>
static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) { static int type_unique_cast(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
if constexpr (is_actual_type_rebindable_for_v<U>) { if constexpr (is_actual_type_rebindable_for_v<U>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<U>; using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
using maybe_bases_or_empty = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, bases_t>; using maybe_bases_or_empty = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, bases_t>;
string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name(); string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
if (rebind_ti != this_rebind_ti) { if (rebind_ti != this_rebind_ti) {
// this is not even of the same unique type // this is not even of the same unique type
return 0; return 0;
} }
string_view this_ti = usertype_traits<T>::qualified_name(); string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) { if (ti == this_ti) {
// direct match, return 1 // direct match, return 1
return 1; return 1;
} }
return type_unique_cast_bases<U>(maybe_bases_or_empty(), source_data, target_data, ti); return type_unique_cast_bases<U>(maybe_bases_or_empty(), source_data, target_data, ti);
} }
else { else {
(void)rebind_ti; (void)rebind_ti;
string_view this_ti = usertype_traits<T>::qualified_name(); string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) { if (ti == this_ti) {
// direct match, return 1 // direct match, return 1
return 1; return 1;
} }
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti); return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
} }
} }
template <typename U, typename... Bases> template <typename U, typename... Bases>
static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) { static int type_unique_cast_with(void* source_data, void* target_data, const string_view& ti, const string_view& rebind_ti) {
using uc_bases_t = types<Bases...>; using uc_bases_t = types<Bases...>;
if constexpr (is_actual_type_rebindable_for_v<U>) { if constexpr (is_actual_type_rebindable_for_v<U>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<U>; using rebound_actual_type = unique_usertype_rebind_actual_t<U>;
using cond_bases_t = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, uc_bases_t>; using cond_bases_t = meta::conditional_t<std::is_void_v<rebound_actual_type>, types<>, uc_bases_t>;
string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name(); string_view this_rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
if (rebind_ti != this_rebind_ti) { if (rebind_ti != this_rebind_ti) {
// this is not even of the same unique type // this is not even of the same unique type
return 0; return 0;
} }
string_view this_ti = usertype_traits<T>::qualified_name(); string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) { if (ti == this_ti) {
// direct match, return 1 // direct match, return 1
return 1; return 1;
} }
return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti); return type_unique_cast_bases<U>(cond_bases_t(), source_data, target_data, ti);
} }
else { else {
(void)rebind_ti; (void)rebind_ti;
string_view this_ti = usertype_traits<T>::qualified_name(); string_view this_ti = usertype_traits<T>::qualified_name();
if (ti == this_ti) { if (ti == this_ti) {
// direct match, return 1 // direct match, return 1
return 1; return 1;
} }
return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti); return type_unique_cast_bases<U>(types<>(), source_data, target_data, ti);
} }
} }
}; };
using inheritance_check_function = decltype(&inheritance<void>::type_check); using inheritance_check_function = decltype(&inheritance<void>::type_check);
using inheritance_cast_function = decltype(&inheritance<void>::type_cast); using inheritance_cast_function = decltype(&inheritance<void>::type_cast);
using inheritance_unique_cast_function = decltype(&inheritance<void>::type_unique_cast<void>); using inheritance_unique_cast_function = decltype(&inheritance<void>::type_unique_cast<void>);
} // namespace detail } // namespace detail
} // namespace sol } // namespace sol
#endif // SOL_INHERITANCE_HPP #endif // SOL_INHERITANCE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -39,7 +39,7 @@ namespace sol {
load_status err; load_status err;
public: public:
load_result() noexcept = default; load_result() noexcept : load_result(nullptr) {}
load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept
: L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) { : L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
} }
@ -95,7 +95,7 @@ namespace sol {
if (valid()) { if (valid()) {
return UT(nullopt); return UT(nullopt);
} }
return error(detail::direct_error, stack::get<std::string>(L, index)); return stack::stack_detail::get_error(L, index);
} }
else { else {
if (!valid()) { if (!valid()) {
@ -106,15 +106,15 @@ namespace sol {
} }
else { else {
if constexpr (std::is_same_v<T, error>) { if constexpr (std::is_same_v<T, error>) {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_) #if SOL_IS_ON(SOL_SAFE_PROXIES)
if (valid()) { if (valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)"); type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
} }
#endif // Check proxy type's safety #endif // Check proxy type's safety
return error(detail::direct_error, stack::get<std::string>(L, index)); return stack::stack_detail::get_error(L, index);
} }
else { else {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_) #if SOL_IS_ON(SOL_SAFE_PROXIES)
if (!valid()) { if (!valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none); type_panic_c_str(L, index, type_of(L, index), type::none);
} }
@ -142,7 +142,9 @@ namespace sol {
}; };
~load_result() { ~load_result() {
stack::remove(L, index, popcount); if (L != nullptr) {
stack::remove(L, index, popcount);
}
} }
}; };
} // namespace sol } // namespace sol

View file

@ -1,95 +1,95 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_LUA_TABLE_HPP #ifndef SOL_LUA_TABLE_HPP
#define SOL_LUA_TABLE_HPP #define SOL_LUA_TABLE_HPP
#include <sol/table_core.hpp> #include <sol/table_core.hpp>
namespace sol { namespace sol {
template <typename ref_t> template <typename ref_t>
struct basic_lua_table : basic_table_core<false, ref_t> { struct basic_lua_table : basic_table_core<false, ref_t> {
private: private:
using base_t = basic_table_core<false, ref_t>; using base_t = basic_table_core<false, ref_t>;
friend class state; friend class state;
friend class state_view; friend class state_view;
public: public:
using base_t::lua_state; using base_t::lua_state;
basic_lua_table() noexcept = default; basic_lua_table() noexcept = default;
basic_lua_table(const basic_lua_table&) = default; basic_lua_table(const basic_lua_table&) = default;
basic_lua_table(basic_lua_table&&) = default; basic_lua_table(basic_lua_table&&) = default;
basic_lua_table& operator=(const basic_lua_table&) = default; basic_lua_table& operator=(const basic_lua_table&) = default;
basic_lua_table& operator=(basic_lua_table&&) = default; basic_lua_table& operator=(basic_lua_table&&) = default;
basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) { basic_lua_table(const stack_reference& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
} }
basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) { basic_lua_table(stack_reference&& r) : basic_lua_table(r.lua_state(), r.stack_index()) {
} }
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) { basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler); stack::check<basic_lua_table>(lua_state(), -1, handler);
#endif // Safety #endif // Safety
} }
basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) { basic_lua_table(lua_State* L, const new_table& nt) : base_t(L, nt) {
if (!is_stack_based<meta::unqualified_t<ref_t>>::value) { if (!is_stack_based<meta::unqualified_t<ref_t>>::value) {
lua_pop(L, 1); lua_pop(L, 1);
} }
} }
basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) { basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_lua_table>(L, index, handler); stack::check<basic_lua_table>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) { basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler); stack::check<basic_lua_table>(lua_state(), -1, handler);
#endif // Safety #endif // Safety
} }
template <typename T, template <typename T,
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) { basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) { if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler); stack::check<basic_lua_table>(lua_state(), -1, handler);
} }
#endif // Safety #endif // Safety
} }
basic_lua_table(lua_nil_t r) noexcept : basic_lua_table(detail::no_safety, r) { basic_lua_table(lua_nil_t r) noexcept : basic_lua_table(detail::no_safety, r) {
} }
}; };
} // namespace sol } // namespace sol
#endif // SOL_LUA_TABLE_HPP #endif // SOL_LUA_TABLE_HPP

View file

@ -1,162 +1,162 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_LUA_VALUE_HPP #ifndef SOL_LUA_VALUE_HPP
#define SOL_LUA_VALUE_HPP #define SOL_LUA_VALUE_HPP
#include <sol/stack.hpp> #include <sol/stack.hpp>
#include <sol/reference.hpp> #include <sol/reference.hpp>
#include <sol/make_reference.hpp> #include <sol/make_reference.hpp>
namespace sol { namespace sol {
struct lua_value { struct lua_value {
public: public:
struct arr : detail::ebco<std::initializer_list<lua_value>> { struct arr : detail::ebco<std::initializer_list<lua_value>> {
private: private:
using base_t = detail::ebco<std::initializer_list<lua_value>>; using base_t = detail::ebco<std::initializer_list<lua_value>>;
public: public:
using base_t::base_t; using base_t::base_t;
}; };
private: private:
template <typename T> template <typename T>
using is_reference_or_lua_value_init_list using is_reference_or_lua_value_init_list
= meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>; = meta::any<meta::is_specialization_of<T, std::initializer_list>, std::is_same<T, reference>, std::is_same<T, arr>>;
template <typename T> template <typename T>
using is_lua_value_single_constructible = meta::any<std::is_same<T, lua_value>, is_reference_or_lua_value_init_list<T>>; using is_lua_value_single_constructible = meta::any<std::is_same<T, lua_value>, is_reference_or_lua_value_init_list<T>>;
static lua_State*& thread_local_lua_state() { static lua_State*& thread_local_lua_state() {
#if SOL_IS_ON(SOL_USE_THREAD_LOCAL_I_) #if SOL_IS_ON(SOL_USE_THREAD_LOCAL)
static thread_local lua_State* L = nullptr; static thread_local lua_State* L = nullptr;
#else #else
static lua_State* L = nullptr; static lua_State* L = nullptr;
#endif #endif
return L; return L;
} }
reference ref_value; reference ref_value;
public: public:
static void set_lua_state(lua_State* L) { static void set_lua_state(lua_State* L) {
thread_local_lua_state() = L; thread_local_lua_state() = L;
} }
template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::disable<is_reference_or_lua_value_init_list<meta::unqualified_t<T>>> = meta::enabler>
lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) { lua_value(lua_State* L_, T&& value) : lua_value(((set_lua_state(L_)), std::forward<T>(value))) {
} }
template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::disable<is_lua_value_single_constructible<meta::unqualified_t<T>>> = meta::enabler>
lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) { lua_value(T&& value) : ref_value(make_reference(thread_local_lua_state(), std::forward<T>(value))) {
} }
lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il) lua_value(lua_State* L_, std::initializer_list<std::pair<lua_value, lua_value>> il)
: lua_value([&L_, &il]() { : lua_value([&L_, &il]() {
set_lua_state(L_); set_lua_state(L_);
return std::move(il); return std::move(il);
}()) { }()) {
} }
lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) { lua_value(std::initializer_list<std::pair<lua_value, lua_value>> il) : ref_value(make_reference(thread_local_lua_state(), std::move(il))) {
} }
lua_value(lua_State* L_, arr il) lua_value(lua_State* L_, arr il)
: lua_value([&L_, &il]() { : lua_value([&L_, &il]() {
set_lua_state(L_); set_lua_state(L_);
return std::move(il); return std::move(il);
}()) { }()) {
} }
lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) { lua_value(arr il) : ref_value(make_reference(thread_local_lua_state(), std::move(il.value()))) {
} }
lua_value(lua_State* L_, reference r) lua_value(lua_State* L_, reference r)
: lua_value([&L_, &r]() { : lua_value([&L_, &r]() {
set_lua_state(L_); set_lua_state(L_);
return std::move(r); return std::move(r);
}()) { }()) {
} }
lua_value(reference r) : ref_value(std::move(r)) { lua_value(reference r) : ref_value(std::move(r)) {
} }
lua_value(const lua_value&) noexcept = default; lua_value(const lua_value&) noexcept = default;
lua_value(lua_value&&) = default; lua_value(lua_value&&) = default;
lua_value& operator=(const lua_value&) = default; lua_value& operator=(const lua_value&) = default;
lua_value& operator=(lua_value&&) = default; lua_value& operator=(lua_value&&) = default;
const reference& value() const& { const reference& value() const& {
return ref_value; return ref_value;
} }
reference& value() & { reference& value() & {
return ref_value; return ref_value;
} }
reference&& value() && { reference&& value() && {
return std::move(ref_value); return std::move(ref_value);
} }
template <typename T> template <typename T>
decltype(auto) as() const { decltype(auto) as() const {
ref_value.push(); ref_value.push();
return stack::pop<T>(ref_value.lua_state()); return stack::pop<T>(ref_value.lua_state());
} }
template <typename T> template <typename T>
bool is() const { bool is() const {
int r = ref_value.registry_index(); int r = ref_value.registry_index();
if (r == LUA_REFNIL) if (r == LUA_REFNIL)
return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false; return meta::any_same<meta::unqualified_t<T>, lua_nil_t, nullopt_t, std::nullptr_t>::value ? true : false;
if (r == LUA_NOREF) if (r == LUA_NOREF)
return false; return false;
auto pp = stack::push_pop(ref_value); auto pp = stack::push_pop(ref_value);
return stack::check<T>(ref_value.lua_state(), -1, &no_panic); return stack::check<T>(ref_value.lua_state(), -1, &no_panic);
} }
}; };
using array_value = typename lua_value::arr; using array_value = typename lua_value::arr;
namespace stack { namespace stack {
template <> template <>
struct unqualified_pusher<lua_value> { struct unqualified_pusher<lua_value> {
static int push(lua_State* L, const lua_value& lv) { static int push(lua_State* L, const lua_value& lv) {
return stack::push(L, lv.value()); return stack::push(L, lv.value());
} }
static int push(lua_State* L, lua_value&& lv) { static int push(lua_State* L, lua_value&& lv) {
return stack::push(L, std::move(lv).value()); return stack::push(L, std::move(lv).value());
} }
}; };
template <> template <>
struct unqualified_getter<lua_value> { struct unqualified_getter<lua_value> {
static lua_value get(lua_State* L, int index, record& tracking) { static lua_value get(lua_State* L, int index, record& tracking) {
return lua_value(L, stack::get<reference>(L, index, tracking)); return lua_value(L, stack::get<reference>(L, index, tracking));
} }
}; };
} // namespace stack } // namespace stack
} // namespace sol } // namespace sol
#endif // SOL_LUA_VALUE_HPP #endif // SOL_LUA_VALUE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -86,20 +86,20 @@ namespace sol {
} }
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) { basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_metatable>(lua_state(), -1, handler); stack::check<basic_metatable>(lua_state(), -1, handler);
#endif // Safety #endif // Safety
} }
basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) { basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_metatable>(L, index, handler); stack::check<basic_metatable>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) { basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_metatable>(lua_state(), -1, handler); stack::check<basic_metatable>(lua_state(), -1, handler);
@ -109,7 +109,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) { basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) { if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -27,7 +27,7 @@
#include <sol/forward.hpp> #include <sol/forward.hpp>
#include <sol/in_place.hpp> #include <sol/in_place.hpp>
#include <sol/traits.hpp> #include <sol/traits.hpp>
#if SOL_IS_ON(SOL_USE_BOOST_I_) #if SOL_IS_ON(SOL_USE_BOOST)
#include <boost/optional.hpp> #include <boost/optional.hpp>
#else #else
#include <sol/optional_implementation.hpp> #include <sol/optional_implementation.hpp>
@ -38,7 +38,7 @@
namespace sol { namespace sol {
#if SOL_IS_ON(SOL_USE_BOOST_I_) #if SOL_IS_ON(SOL_USE_BOOST)
template <typename T> template <typename T>
using optional = boost::optional<T>; using optional = boost::optional<T>;
using nullopt_t = boost::none_t; using nullopt_t = boost::none_t;
@ -59,14 +59,14 @@ namespace sol {
inline static constexpr std::nullopt_t value = std::nullopt; inline static constexpr std::nullopt_t value = std::nullopt;
}; };
#if SOL_IS_ON(SOL_USE_BOOST_I_) #if SOL_IS_ON(SOL_USE_BOOST)
template <typename T> template <typename T>
struct associated_nullopt<boost::optional<T>> { struct associated_nullopt<boost::optional<T>> {
inline static SOL_BOOST_NONE_CONSTEXPR_I_ boost::none_t value = boost::none; inline static SOL_BOOST_NONE_CONSTEXPR_I_ boost::none_t value = boost::none;
}; };
#endif // Boost nullopt #endif // Boost nullopt
#if SOL_IS_ON(SOL_USE_BOOST_I_) #if SOL_IS_ON(SOL_USE_BOOST)
template <typename T> template <typename T>
inline SOL_BOOST_NONE_CONSTEXPR_I_ auto associated_nullopt_v = associated_nullopt<T>::value; inline SOL_BOOST_NONE_CONSTEXPR_I_ auto associated_nullopt_v = associated_nullopt<T>::value;
#else #else
@ -76,7 +76,7 @@ namespace sol {
} // namespace detail } // namespace detail
} // namespace sol } // namespace sol
#if SOL_IS_ON(SOL_USE_BOOST_I_) #if SOL_IS_ON(SOL_USE_BOOST)
#undef SOL_BOOST_NONE_CONSTEXPR_I_ #undef SOL_BOOST_NONE_CONSTEXPR_I_
#endif #endif

View file

@ -1,6 +1,6 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -1375,7 +1375,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T& value() & { SOL_TL_OPTIONAL_11_CONSTEXPR T& value() & {
if (has_value()) if (has_value())
return this->m_value; return this->m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort(); std::abort();
#else #else
throw bad_optional_access(); throw bad_optional_access();
@ -1386,7 +1386,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const& { SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const& {
if (has_value()) if (has_value())
return this->m_value; return this->m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort(); std::abort();
#else #else
throw bad_optional_access(); throw bad_optional_access();
@ -1396,7 +1396,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T&& value() && { SOL_TL_OPTIONAL_11_CONSTEXPR T&& value() && {
if (has_value()) if (has_value())
return std::move(this->m_value); return std::move(this->m_value);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort(); std::abort();
#else #else
throw bad_optional_access(); throw bad_optional_access();
@ -1408,7 +1408,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& { SOL_TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& {
if (has_value()) if (has_value())
return std::move(this->m_value); return std::move(this->m_value);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort(); std::abort();
#else #else
throw bad_optional_access(); throw bad_optional_access();
@ -2186,12 +2186,9 @@ namespace sol {
/// one. /// one.
/// ///
/// \group emplace /// \group emplace
template <class... Args> T& emplace(T& arg) noexcept {
T& emplace(Args&&... args) noexcept {
static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
*this = nullopt; *this = nullopt;
new (static_cast<void*>(this)) optional(std::in_place, std::forward<Args>(args)...); m_value = &arg;
return **this; return **this;
} }
@ -2251,7 +2248,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T& value() { SOL_TL_OPTIONAL_11_CONSTEXPR T& value() {
if (has_value()) if (has_value())
return *m_value; return *m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort(); std::abort();
#else #else
throw bad_optional_access(); throw bad_optional_access();
@ -2262,7 +2259,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const { SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const {
if (has_value()) if (has_value())
return *m_value; return *m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort(); std::abort();
#else #else
throw bad_optional_access(); throw bad_optional_access();

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -46,4 +46,4 @@ namespace sol {
} }
} // namespace sol } // namespace sol
#endif // SOL_OVERLOAD_HPP #endif // SOL_OVERLOAD_HPP

View file

@ -1,262 +1,262 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_PACKAGED_COROUTINE_HPP #ifndef SOL_PACKAGED_COROUTINE_HPP
#define SOL_PACKAGED_COROUTINE_HPP #define SOL_PACKAGED_COROUTINE_HPP
#include <sol/reference.hpp> #include <sol/reference.hpp>
#include <sol/object.hpp> #include <sol/object.hpp>
#include <sol/stack.hpp> #include <sol/stack.hpp>
#include <sol/function_result.hpp> #include <sol/function_result.hpp>
#include <sol/thread.hpp> #include <sol/thread.hpp>
#include <sol/protected_handler.hpp> #include <sol/protected_handler.hpp>
#include <sol/coroutine.hpp> #include <sol/coroutine.hpp>
namespace sol { namespace sol {
#if 0 #if 0
class packaged_coroutine { class packaged_coroutine {
private: private:
lua_State* m_L; lua_State* m_L;
sol::stateless_reference m_coroutine_reference; sol::stateless_reference m_coroutine_reference;
sol::stateless_reference m_error_handler; sol::stateless_reference m_error_handler;
sol::thread m_thread_reference; sol::thread m_thread_reference;
void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) { void luacall(std::ptrdiff_t argcount, std::ptrdiff_t) {
#if SOL_LUA_VERSION_I_ >= 504 #if SOL_LUA_VERSION_I_ >= 504
int nresults; int nresults;
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults)); stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount), &nresults));
#else #else
stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount))); stats = static_cast<call_status>(lua_resume(lua_state(), nullptr, static_cast<int>(argcount)));
#endif #endif
} }
template <std::size_t... I, typename... Ret> template <std::size_t... I, typename... Ret>
auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) { auto invoke(types<Ret...>, std::index_sequence<I...>, std::ptrdiff_t n) {
luacall(n, sizeof...(Ret)); luacall(n, sizeof...(Ret));
return stack::pop<std::tuple<Ret...>>(lua_state()); return stack::pop<std::tuple<Ret...>>(lua_state());
} }
template <std::size_t I, typename Ret> template <std::size_t I, typename Ret>
Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) { Ret invoke(types<Ret>, std::index_sequence<I>, std::ptrdiff_t n) {
luacall(n, 1); luacall(n, 1);
return stack::pop<Ret>(lua_state()); return stack::pop<Ret>(lua_state());
} }
template <std::size_t I> template <std::size_t I>
void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) { void invoke(types<void>, std::index_sequence<I>, std::ptrdiff_t n) {
luacall(n, 0); luacall(n, 0);
} }
protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) { protected_function_result invoke(types<>, std::index_sequence<>, std::ptrdiff_t n) {
int firstreturn = 1; int firstreturn = 1;
luacall(n, LUA_MULTRET); luacall(n, LUA_MULTRET);
int poststacksize = lua_gettop(this->lua_state()); int poststacksize = lua_gettop(this->lua_state());
int returncount = poststacksize - (firstreturn - 1); int returncount = poststacksize - (firstreturn - 1);
if (error()) { if (error()) {
if (m_error_handler.valid()) { if (m_error_handler.valid()) {
string_view err = stack::get<string_view>(this->lua_state(), poststacksize); string_view err = stack::get<string_view>(this->lua_state(), poststacksize);
m_error_handler.push(); m_error_handler.push();
stack::push(this->lua_state(), err); stack::push(this->lua_state(), err);
lua_call(lua_state(), 1, 1); lua_call(lua_state(), 1, 1);
} }
return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status()); return protected_function_result(this->lua_state(), lua_absindex(this->lua_state(), -1), 1, returncount, status());
} }
return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status()); return protected_function_result(this->lua_state(), firstreturn, returncount, returncount, status());
} }
public: public:
using base_t::lua_state; using base_t::lua_state;
basic_packaged_coroutine() = default; basic_packaged_coroutine() = default;
template <typename T, template <typename T,
meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_packaged_coroutine>>, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_packaged_coroutine>>,
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(T&& r) noexcept basic_packaged_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) { : base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) { if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler); stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
} }
#endif // Safety #endif // Safety
} }
basic_packaged_coroutine(const basic_packaged_coroutine& other) = default; basic_packaged_coroutine(const basic_packaged_coroutine& other) = default;
basic_packaged_coroutine& operator=(const basic_packaged_coroutine&) = default; basic_packaged_coroutine& operator=(const basic_packaged_coroutine&) = default;
basic_packaged_coroutine(basic_packaged_coroutine&& other) noexcept basic_packaged_coroutine(basic_packaged_coroutine&& other) noexcept
: base_t(std::move(other)), m_error_handler(this->lua_state(), std::move(other.m_error_handler)) { : base_t(std::move(other)), m_error_handler(this->lua_state(), std::move(other.m_error_handler)) {
} }
basic_packaged_coroutine& operator=(basic_packaged_coroutine&& other) noexcept { basic_packaged_coroutine& operator=(basic_packaged_coroutine&& other) noexcept {
base_t::operator=(std::move(other)); base_t::operator=(std::move(other));
// must change the state, since it could change on the coroutine type // must change the state, since it could change on the coroutine type
m_error_handler.abandon(); m_error_handler.abandon();
m_error_handler = handler_t(this->lua_state(), std::move(other.m_error_handler)); m_error_handler = handler_t(this->lua_state(), std::move(other.m_error_handler));
return *this; return *this;
} }
basic_packaged_coroutine(const basic_function<base_t>& b) noexcept basic_packaged_coroutine(const basic_function<base_t>& b) noexcept
: basic_packaged_coroutine(b, detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) { : basic_packaged_coroutine(b, detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) {
} }
basic_packaged_coroutine(basic_function<base_t>&& b) noexcept basic_packaged_coroutine(basic_function<base_t>&& b) noexcept
: basic_packaged_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) { : basic_packaged_coroutine(std::move(b), detail::get_default_handler<reference, is_main_threaded_v<base_t>>(b.lua_state())) {
} }
basic_packaged_coroutine(const basic_function<base_t>& b, handler_t eh) noexcept : base_t(b), m_error_handler(std::move(eh)) { basic_packaged_coroutine(const basic_function<base_t>& b, handler_t eh) noexcept : base_t(b), m_error_handler(std::move(eh)) {
} }
basic_packaged_coroutine(basic_function<base_t>&& b, handler_t eh) noexcept : base_t(std::move(b)), m_error_handler(std::move(eh)) { basic_packaged_coroutine(basic_function<base_t>&& b, handler_t eh) noexcept : base_t(std::move(b)), m_error_handler(std::move(eh)) {
} }
basic_packaged_coroutine(const stack_reference& r) noexcept basic_packaged_coroutine(const stack_reference& r) noexcept
: basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) { : basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
} }
basic_packaged_coroutine(stack_reference&& r) noexcept basic_packaged_coroutine(stack_reference&& r) noexcept
: basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) { : basic_packaged_coroutine(r.lua_state(), r.stack_index(), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
} }
basic_packaged_coroutine(const stack_reference& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { basic_packaged_coroutine(const stack_reference& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
} }
basic_packaged_coroutine(stack_reference&& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) { basic_packaged_coroutine(stack_reference&& r, handler_t eh) noexcept : basic_packaged_coroutine(r.lua_state(), r.stack_index(), std::move(eh)) {
} }
template <typename Super> template <typename Super>
basic_packaged_coroutine(const proxy_base<Super>& p) basic_packaged_coroutine(const proxy_base<Super>& p)
: basic_packaged_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) { : basic_packaged_coroutine(p, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
} }
template <typename Super> template <typename Super>
basic_packaged_coroutine(proxy_base<Super>&& p) basic_packaged_coroutine(proxy_base<Super>&& p)
: basic_packaged_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) { : basic_packaged_coroutine(std::move(p), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(p.lua_state())) {
} }
template <typename Proxy, typename HandlerReference, template <typename Proxy, typename HandlerReference,
meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<HandlerReference>>>> = meta::enabler> meta::enable<std::is_base_of<proxy_base_tag, meta::unqualified_t<Proxy>>, meta::neg<is_lua_index<meta::unqualified_t<HandlerReference>>>> = meta::enabler>
basic_packaged_coroutine(Proxy&& p, HandlerReference&& eh) : basic_packaged_coroutine(detail::force_cast<base_t>(p), std::forward<HandlerReference>(eh)) { basic_packaged_coroutine(Proxy&& p, HandlerReference&& eh) : basic_packaged_coroutine(detail::force_cast<base_t>(p), std::forward<HandlerReference>(eh)) {
} }
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r) noexcept basic_packaged_coroutine(lua_State* L, T&& r) noexcept
: basic_packaged_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_packaged_coroutine(L, std::forward<T>(r), detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) { basic_packaged_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler); stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
#endif // Safety #endif // Safety
} }
basic_packaged_coroutine(lua_nil_t n) : base_t(n), m_error_handler(n) { basic_packaged_coroutine(lua_nil_t n) : base_t(n), m_error_handler(n) {
} }
basic_packaged_coroutine(lua_State* L, int index = -1) basic_packaged_coroutine(lua_State* L, int index = -1)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_packaged_coroutine(lua_State* L, int index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_packaged_coroutine(lua_State* L, int index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#ifdef SOL_SAFE_REFERENCES #ifdef SOL_SAFE_REFERENCES
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler); stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_packaged_coroutine(lua_State* L, absolute_index index) basic_packaged_coroutine(lua_State* L, absolute_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_packaged_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_packaged_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler); stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_packaged_coroutine(lua_State* L, raw_index index) basic_packaged_coroutine(lua_State* L, raw_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_packaged_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_packaged_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler); stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_packaged_coroutine(lua_State* L, ref_index index) basic_packaged_coroutine(lua_State* L, ref_index index)
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) { : basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
} }
basic_packaged_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) { basic_packaged_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler); stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
#endif // Safety #endif // Safety
} }
call_status status() const noexcept { call_status status() const noexcept {
return stats; return stats;
} }
bool error() const noexcept { bool error() const noexcept {
call_status cs = status(); call_status cs = status();
return cs != call_status::ok && cs != call_status::yielded; return cs != call_status::ok && cs != call_status::yielded;
} }
bool runnable() const noexcept { bool runnable() const noexcept {
return base_t::valid() && (status() == call_status::yielded); return base_t::valid() && (status() == call_status::yielded);
} }
reference error_handler() const noexcept { reference error_handler() const noexcept {
return reference(m_L, registry_index(m_error_handler.index)); return reference(m_L, registry_index(m_error_handler.index));
} }
set_error_handler(reference new_error_handler) noexcept { set_error_handler(reference new_error_handler) noexcept {
this->m_error_handler = stateless_reference(this->m_L, std::move(new_error_handler)); this->m_error_handler = stateless_reference(this->m_L, std::move(new_error_handler));
} }
explicit operator bool() const noexcept { explicit operator bool() const noexcept {
return runnable(); return runnable();
} }
template <typename... Args> template <typename... Args>
protected_function_result operator()(Args&&... args) { protected_function_result operator()(Args&&... args) {
return call<>(std::forward<Args>(args)...); return call<>(std::forward<Args>(args)...);
} }
template <typename... Ret, typename... Args> template <typename... Ret, typename... Args>
decltype(auto) operator()(types<Ret...>, Args&&... args) { decltype(auto) operator()(types<Ret...>, Args&&... args) {
return call<Ret...>(std::forward<Args>(args)...); return call<Ret...>(std::forward<Args>(args)...);
} }
template <typename... Ret, typename... Args> template <typename... Ret, typename... Args>
decltype(auto) call(Args&&... args) { decltype(auto) call(Args&&... args) {
// some users screw up coroutine.create // some users screw up coroutine.create
// and try to use it with sol::coroutine without ever calling the first resume in Lua // and try to use it with sol::coroutine without ever calling the first resume in Lua
// this makes the stack incompatible with other kinds of stacks: protect against this // this makes the stack incompatible with other kinds of stacks: protect against this
// make sure coroutines don't screw us over // make sure coroutines don't screw us over
base_t::push(); base_t::push();
int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...); int pushcount = stack::multi_push_reference(lua_state(), std::forward<Args>(args)...);
return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount); return invoke(types<Ret...>(), std::make_index_sequence<sizeof...(Ret)>(), pushcount);
} }
}; };
#endif #endif
} // namespace sol } // namespace sol
#endif // SOL_PACKAGED_COROUTINE_HPP #endif // SOL_PACKAGED_COROUTINE_HPP

View file

@ -1,275 +1,275 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_PAIRS_ITERATOR_HPP #ifndef SOL_PAIRS_ITERATOR_HPP
#define SOL_PAIRS_ITERATOR_HPP #define SOL_PAIRS_ITERATOR_HPP
#include <sol/version.hpp> #include <sol/version.hpp>
#include <sol/reference.hpp> #include <sol/reference.hpp>
#include <sol/stack_reference.hpp> #include <sol/stack_reference.hpp>
#include <sol/table_iterator.hpp> #include <sol/table_iterator.hpp>
#include <sol/protected_function.hpp> #include <sol/protected_function.hpp>
#include <sol/stack/detail/pairs.hpp> #include <sol/stack/detail/pairs.hpp>
namespace sol { namespace sol {
struct pairs_sentinel { }; struct pairs_sentinel { };
class pairs_iterator { class pairs_iterator {
private: private:
inline static constexpr int empty_key_index = -1; inline static constexpr int empty_key_index = -1;
public: public:
using key_type = object; using key_type = object;
using mapped_type = object; using mapped_type = object;
using value_type = std::pair<object, object>; using value_type = std::pair<object, object>;
using iterator_category = std::input_iterator_tag; using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using pointer = value_type*; using pointer = value_type*;
using const_pointer = value_type const*; using const_pointer = value_type const*;
using reference = value_type&; using reference = value_type&;
using const_reference = const value_type&; using const_reference = const value_type&;
pairs_iterator() noexcept pairs_iterator() noexcept
: m_L(nullptr) : m_L(nullptr)
, m_next_function_ref(lua_nil) , m_next_function_ref(lua_nil)
, m_table_ref(lua_nil) , m_table_ref(lua_nil)
, m_cached_key_value_pair({ lua_nil, lua_nil }) , m_cached_key_value_pair({ lua_nil, lua_nil })
, m_key_index(empty_key_index) , m_key_index(empty_key_index)
, m_iteration_index(0) { , m_iteration_index(0) {
} }
pairs_iterator(const pairs_iterator&) = delete; pairs_iterator(const pairs_iterator&) = delete;
pairs_iterator& operator=(const pairs_iterator&) = delete; pairs_iterator& operator=(const pairs_iterator&) = delete;
pairs_iterator(pairs_iterator&& right) noexcept pairs_iterator(pairs_iterator&& right) noexcept
: m_L(right.m_L) : m_L(right.m_L)
, m_next_function_ref(std::move(right.m_next_function_ref)) , m_next_function_ref(std::move(right.m_next_function_ref))
, m_table_ref(std::move(right.m_table_ref)) , m_table_ref(std::move(right.m_table_ref))
, m_cached_key_value_pair(std::move(right.m_cached_key_value_pair)) , m_cached_key_value_pair(std::move(right.m_cached_key_value_pair))
, m_key_index(right.m_key_index) , m_key_index(right.m_key_index)
, m_iteration_index(right.m_iteration_index) { , m_iteration_index(right.m_iteration_index) {
right.m_key_index = empty_key_index; right.m_key_index = empty_key_index;
} }
pairs_iterator& operator=(pairs_iterator&& right) noexcept { pairs_iterator& operator=(pairs_iterator&& right) noexcept {
m_L = right.m_L; m_L = right.m_L;
m_next_function_ref = std::move(right.m_next_function_ref); m_next_function_ref = std::move(right.m_next_function_ref);
m_table_ref = std::move(right.m_table_ref); m_table_ref = std::move(right.m_table_ref);
m_cached_key_value_pair = std::move(right.m_cached_key_value_pair); m_cached_key_value_pair = std::move(right.m_cached_key_value_pair);
m_key_index = right.m_key_index; m_key_index = right.m_key_index;
m_iteration_index = right.m_iteration_index; m_iteration_index = right.m_iteration_index;
right.m_key_index = empty_key_index; right.m_key_index = empty_key_index;
return *this; return *this;
} }
template <typename Source> template <typename Source>
pairs_iterator(const Source& source_) noexcept : m_L(source_.lua_state()), m_key_index(empty_key_index), m_iteration_index(0) { pairs_iterator(const Source& source_) noexcept : m_L(source_.lua_state()), m_key_index(empty_key_index), m_iteration_index(0) {
if (m_L == nullptr || !source_.valid()) { if (m_L == nullptr || !source_.valid()) {
m_key_index = empty_key_index; m_key_index = empty_key_index;
return; return;
} }
int source_index = -source_.push(m_L); int source_index = -source_.push(m_L);
int abs_source_index = lua_absindex(m_L, source_index); int abs_source_index = lua_absindex(m_L, source_index);
int metatable_exists = lua_getmetatable(m_L, abs_source_index); int metatable_exists = lua_getmetatable(m_L, abs_source_index);
lua_remove(m_L, abs_source_index); lua_remove(m_L, abs_source_index);
if (metatable_exists == 1) { if (metatable_exists == 1) {
// just has a metatable, but does it have __pairs ? // just has a metatable, but does it have __pairs ?
stack_reference metatable(m_L, raw_index(abs_source_index)); stack_reference metatable(m_L, raw_index(abs_source_index));
stack::get_field<is_global_table_v<Source>, true>(m_L, meta_function::pairs, metatable.stack_index()); stack::get_field<is_global_table_v<Source>, true>(m_L, meta_function::pairs, metatable.stack_index());
optional<protected_function> maybe_pairs_function = stack::pop<optional<protected_function>>(m_L); optional<protected_function> maybe_pairs_function = stack::pop<optional<protected_function>>(m_L);
if (maybe_pairs_function.has_value()) { if (maybe_pairs_function.has_value()) {
protected_function& pairs_function = *maybe_pairs_function; protected_function& pairs_function = *maybe_pairs_function;
protected_function_result next_fn_and_table_and_first_key = pairs_function(source_); protected_function_result next_fn_and_table_and_first_key = pairs_function(source_);
if (next_fn_and_table_and_first_key.valid()) { if (next_fn_and_table_and_first_key.valid()) {
m_next_function_ref = next_fn_and_table_and_first_key.get<protected_function>(0); m_next_function_ref = next_fn_and_table_and_first_key.get<protected_function>(0);
m_table_ref = next_fn_and_table_and_first_key.get<sol::reference>(1); m_table_ref = next_fn_and_table_and_first_key.get<sol::reference>(1);
m_key_index = next_fn_and_table_and_first_key.stack_index() - 1; m_key_index = next_fn_and_table_and_first_key.stack_index() - 1;
// remove next function and table // remove next function and table
lua_remove(m_L, m_key_index); lua_remove(m_L, m_key_index);
lua_remove(m_L, m_key_index); lua_remove(m_L, m_key_index);
next_fn_and_table_and_first_key.abandon(); next_fn_and_table_and_first_key.abandon();
lua_remove(m_L, abs_source_index); lua_remove(m_L, abs_source_index);
this->operator++(); this->operator++();
m_iteration_index = 0; m_iteration_index = 0;
return; return;
} }
} }
} }
{ {
auto maybe_next = stack::stack_detail::find_lua_next_function(m_L); auto maybe_next = stack::stack_detail::find_lua_next_function(m_L);
if (maybe_next.has_value()) { if (maybe_next.has_value()) {
m_next_function_ref = std::move(*maybe_next); m_next_function_ref = std::move(*maybe_next);
m_table_ref = source_; m_table_ref = source_;
stack::push(m_L, lua_nil); stack::push(m_L, lua_nil);
m_key_index = lua_gettop(m_L); m_key_index = lua_gettop(m_L);
this->operator++(); this->operator++();
m_iteration_index = 0; m_iteration_index = 0;
return; return;
} }
} }
// okay, so none of the above worked and now we need to create // okay, so none of the above worked and now we need to create
// a shim / polyfill instead // a shim / polyfill instead
stack::push(m_L, &stack::stack_detail::c_lua_next); stack::push(m_L, &stack::stack_detail::c_lua_next);
m_next_function_ref = stack::pop<protected_function>(m_L); m_next_function_ref = stack::pop<protected_function>(m_L);
m_table_ref = source_; m_table_ref = source_;
stack::push(m_L, lua_nil); stack::push(m_L, lua_nil);
m_key_index = lua_gettop(m_L); m_key_index = lua_gettop(m_L);
this->operator++(); this->operator++();
m_iteration_index = 0; m_iteration_index = 0;
} }
pairs_iterator& operator++() { pairs_iterator& operator++() {
if (m_key_index == empty_key_index) { if (m_key_index == empty_key_index) {
return *this; return *this;
} }
{ {
sol::protected_function_result next_results = m_next_function_ref(m_table_ref, stack_reference(m_L, m_key_index)); sol::protected_function_result next_results = m_next_function_ref(m_table_ref, stack_reference(m_L, m_key_index));
if (!next_results.valid()) { if (!next_results.valid()) {
// TODO: abort, or throw an error? // TODO: abort, or throw an error?
m_clear(); m_clear();
m_key_index = empty_key_index; m_key_index = empty_key_index;
return *this; return *this;
} }
int next_results_count = next_results.return_count(); int next_results_count = next_results.return_count();
if (next_results_count < 2) { if (next_results_count < 2) {
// iteration is over! // iteration is over!
next_results.abandon(); next_results.abandon();
lua_settop(m_L, m_key_index - 1); lua_settop(m_L, m_key_index - 1);
m_key_index = empty_key_index; m_key_index = empty_key_index;
++m_iteration_index; ++m_iteration_index;
return *this; return *this;
} }
else { else {
lua_remove(m_L, m_key_index); lua_remove(m_L, m_key_index);
m_key_index = next_results.stack_index() - 1; m_key_index = next_results.stack_index() - 1;
m_cached_key_value_pair.first = stack::get<object>(m_L, m_key_index); m_cached_key_value_pair.first = stack::get<object>(m_L, m_key_index);
m_cached_key_value_pair.second = stack::get<object>(m_L, m_key_index + 1); m_cached_key_value_pair.second = stack::get<object>(m_L, m_key_index + 1);
lua_settop(m_L, m_key_index); lua_settop(m_L, m_key_index);
next_results.abandon(); next_results.abandon();
} }
} }
++m_iteration_index; ++m_iteration_index;
return *this; return *this;
} }
std::ptrdiff_t index() const { std::ptrdiff_t index() const {
return static_cast<std::ptrdiff_t>(m_iteration_index); return static_cast<std::ptrdiff_t>(m_iteration_index);
} }
const_reference operator*() const noexcept { const_reference operator*() const noexcept {
return m_cached_key_value_pair; return m_cached_key_value_pair;
} }
reference operator*() noexcept { reference operator*() noexcept {
return m_cached_key_value_pair; return m_cached_key_value_pair;
} }
friend bool operator==(const pairs_iterator& left, const pairs_iterator& right) noexcept { friend bool operator==(const pairs_iterator& left, const pairs_iterator& right) noexcept {
return left.m_table_ref == right.m_table_ref && left.m_iteration_index == right.m_iteration_index; return left.m_table_ref == right.m_table_ref && left.m_iteration_index == right.m_iteration_index;
} }
friend bool operator!=(const pairs_iterator& left, const pairs_iterator& right) noexcept { friend bool operator!=(const pairs_iterator& left, const pairs_iterator& right) noexcept {
return left.m_table_ref != right.m_table_ref || left.m_iteration_index != right.m_iteration_index; return left.m_table_ref != right.m_table_ref || left.m_iteration_index != right.m_iteration_index;
} }
friend bool operator==(const pairs_iterator& left, const pairs_sentinel&) noexcept { friend bool operator==(const pairs_iterator& left, const pairs_sentinel&) noexcept {
return left.m_key_index == empty_key_index; return left.m_key_index == empty_key_index;
} }
friend bool operator!=(const pairs_iterator& left, const pairs_sentinel&) noexcept { friend bool operator!=(const pairs_iterator& left, const pairs_sentinel&) noexcept {
return left.m_key_index != empty_key_index; return left.m_key_index != empty_key_index;
} }
friend bool operator==(const pairs_sentinel&, const pairs_iterator& left) noexcept { friend bool operator==(const pairs_sentinel&, const pairs_iterator& left) noexcept {
return left.m_key_index == empty_key_index; return left.m_key_index == empty_key_index;
} }
friend bool operator!=(const pairs_sentinel&, const pairs_iterator& left) noexcept { friend bool operator!=(const pairs_sentinel&, const pairs_iterator& left) noexcept {
return left.m_key_index != empty_key_index; return left.m_key_index != empty_key_index;
} }
~pairs_iterator() { ~pairs_iterator() {
if (m_key_index != empty_key_index) { if (m_key_index != empty_key_index) {
m_clear(); m_clear();
} }
} }
private: private:
void m_clear() noexcept { void m_clear() noexcept {
lua_remove(m_L, m_key_index); lua_remove(m_L, m_key_index);
} }
lua_State* m_L; lua_State* m_L;
protected_function m_next_function_ref; protected_function m_next_function_ref;
sol::reference m_table_ref; sol::reference m_table_ref;
std::pair<object, object> m_cached_key_value_pair; std::pair<object, object> m_cached_key_value_pair;
int m_key_index; int m_key_index;
int m_iteration_index; int m_iteration_index;
}; };
template <typename Source> template <typename Source>
class basic_pairs_range { class basic_pairs_range {
private: private:
using source_t = std::add_lvalue_reference_t<Source>; using source_t = std::add_lvalue_reference_t<Source>;
source_t m_source; source_t m_source;
public: public:
using iterator = pairs_iterator; using iterator = pairs_iterator;
using const_iterator = pairs_iterator; using const_iterator = pairs_iterator;
basic_pairs_range(source_t source_) noexcept : m_source(source_) { basic_pairs_range(source_t source_) noexcept : m_source(source_) {
} }
iterator begin() noexcept { iterator begin() noexcept {
return iterator(m_source); return iterator(m_source);
} }
iterator begin() const noexcept { iterator begin() const noexcept {
return iterator(m_source); return iterator(m_source);
} }
const_iterator cbegin() const noexcept { const_iterator cbegin() const noexcept {
return const_iterator(m_source); return const_iterator(m_source);
} }
pairs_sentinel end() noexcept { pairs_sentinel end() noexcept {
return {}; return {};
} }
pairs_sentinel end() const noexcept { pairs_sentinel end() const noexcept {
return {}; return {};
} }
pairs_sentinel cend() const noexcept { pairs_sentinel cend() const noexcept {
return {}; return {};
} }
}; };
} // namespace sol } // namespace sol
#endif // SOL_PAIRS_ITERATOR_HPP #endif // SOL_PAIRS_ITERATOR_HPP

View file

@ -1,102 +1,103 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_POINTER_LIKE_HPP #ifndef SOL_POINTER_LIKE_HPP
#define SOL_POINTER_LIKE_HPP #define SOL_POINTER_LIKE_HPP
#include <sol/base_traits.hpp> #include <sol/base_traits.hpp>
#include <utility> #include <utility>
#include <type_traits> #include <type_traits>
#include <memory>
namespace sol {
namespace sol {
namespace meta {
namespace meta_detail { namespace meta {
template <typename T> namespace meta_detail {
using is_dereferenceable_test = decltype(*std::declval<T>()); template <typename T>
using is_dereferenceable_test = decltype(*std::declval<T>());
template <typename T>
using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*()); template <typename T>
} // namespace meta_detail using is_explicitly_dereferenceable_test = decltype(std::declval<T>().operator*());
} // namespace meta_detail
template <typename T>
using is_pointer_like = std::integral_constant<bool, template <typename T>
!std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>; using is_pointer_like = std::integral_constant<bool,
!std::is_array_v<T> && (std::is_pointer_v<T> || is_detected_v<meta_detail::is_explicitly_dereferenceable_test, T>)>;
template <typename T>
constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value; template <typename T>
} // namespace meta constexpr inline bool is_pointer_like_v = is_pointer_like<T>::value;
} // namespace meta
namespace detail {
namespace detail {
template <typename T>
auto unwrap(T&& item) -> decltype(std::forward<T>(item)) { template <typename T>
return std::forward<T>(item); auto unwrap(T&& item) -> decltype(std::forward<T>(item)) {
} return std::forward<T>(item);
}
template <typename T>
T& unwrap(std::reference_wrapper<T> arg) { template <typename T>
return arg.get(); T& unwrap(std::reference_wrapper<T> arg) {
} return arg.get();
}
template <typename T>
inline decltype(auto) deref(T&& item) { template <typename T>
using Tu = meta::unqualified_t<T>; inline decltype(auto) deref(T&& item) {
if constexpr (meta::is_pointer_like_v<Tu>) { using Tu = meta::unqualified_t<T>;
return *std::forward<T>(item); if constexpr (meta::is_pointer_like_v<Tu>) {
} return *std::forward<T>(item);
else { }
return std::forward<T>(item); else {
} return std::forward<T>(item);
} }
}
template <typename T>
inline decltype(auto) deref_move_only(T&& item) { template <typename T>
using Tu = meta::unqualified_t<T>; inline decltype(auto) deref_move_only(T&& item) {
if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) { using Tu = meta::unqualified_t<T>;
return *std::forward<T>(item); if constexpr (meta::is_pointer_like_v<Tu> && !std::is_pointer_v<Tu> && !std::is_copy_constructible_v<Tu>) {
} return *std::forward<T>(item);
else { }
return std::forward<T>(item); else {
} return std::forward<T>(item);
} }
}
template <typename T>
inline T* ptr(T& val) { template <typename T>
return std::addressof(val); inline T* ptr(T& val) {
} return std::addressof(val);
}
template <typename T>
inline T* ptr(std::reference_wrapper<T> val) { template <typename T>
return std::addressof(val.get()); inline T* ptr(std::reference_wrapper<T> val) {
} return std::addressof(val.get());
}
template <typename T>
inline T* ptr(T* val) { template <typename T>
return val; inline T* ptr(T* val) {
} return val;
} // namespace detail }
} // namespace sol } // namespace detail
} // namespace sol
#endif // SOL_POINTER_LIKE_HPP
#endif // SOL_POINTER_LIKE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -1,47 +1,47 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
// clang-format off // clang-format off
#if defined(SOL_PROLOGUE_I_) #if defined(SOL_PROLOGUE_I_)
#error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue." #error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue."
#endif #endif
#define SOL_PROLOGUE_I_ 1 #define SOL_PROLOGUE_I_ 1
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_) #if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ ) #define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ )
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_) #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ ) #define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ )
#else #else
#include <type_traits> #include <type_traits>
#define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) ) #define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) )
#endif #endif
#endif #endif
// clang-format on // clang-format on

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -75,7 +75,7 @@ namespace sol {
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>, meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)), m_error_handler(get_default_handler(r.lua_state())) { basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)), m_error_handler(get_default_handler(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) { if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
@ -133,7 +133,7 @@ namespace sol {
} }
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(lua_State* L_, T&& r, handler_t eh) : base_t(L_, std::forward<T>(r)), m_error_handler(std::move(eh)) { basic_protected_function(lua_State* L_, T&& r, handler_t eh) : base_t(L_, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler); stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -146,7 +146,7 @@ namespace sol {
basic_protected_function(lua_State* L_, int index_ = -1) : basic_protected_function(L_, index_, get_default_handler(L_)) { basic_protected_function(lua_State* L_, int index_ = -1) : basic_protected_function(L_, index_, get_default_handler(L_)) {
} }
basic_protected_function(lua_State* L_, int index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) { basic_protected_function(lua_State* L_, int index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler); stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety #endif // Safety
@ -154,7 +154,7 @@ namespace sol {
basic_protected_function(lua_State* L_, absolute_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) { basic_protected_function(lua_State* L_, absolute_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
} }
basic_protected_function(lua_State* L_, absolute_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) { basic_protected_function(lua_State* L_, absolute_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler); stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety #endif // Safety
@ -162,7 +162,7 @@ namespace sol {
basic_protected_function(lua_State* L_, raw_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) { basic_protected_function(lua_State* L_, raw_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
} }
basic_protected_function(lua_State* L_, raw_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) { basic_protected_function(lua_State* L_, raw_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler); stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety #endif // Safety
@ -170,7 +170,7 @@ namespace sol {
basic_protected_function(lua_State* L_, ref_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) { basic_protected_function(lua_State* L_, ref_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
} }
basic_protected_function(lua_State* L_, ref_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) { basic_protected_function(lua_State* L_, ref_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler); stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -339,14 +339,14 @@ namespace sol {
int firstreturn = 1; int firstreturn = 1;
int returncount = 0; int returncount = 0;
call_status code = call_status::ok; call_status code = call_status::ok;
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) #if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
try { try {
#endif // No Exceptions #endif // No Exceptions
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler_v))); firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler_v)));
code = luacall(n, LUA_MULTRET, h); code = luacall(n, LUA_MULTRET, h);
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler_v); poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler_v);
returncount = poststacksize - (firstreturn - 1); returncount = poststacksize - (firstreturn - 1);
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) #if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
} }
// Handle C++ errors thrown from C++ functions bound inside of lua // Handle C++ errors thrown from C++ functions bound inside of lua
catch (const char* error) { catch (const char* error) {
@ -364,7 +364,7 @@ namespace sol {
firstreturn = lua_gettop(lua_state()); firstreturn = lua_gettop(lua_state());
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime); return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
} }
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_) #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
// LuaJIT cannot have the catchall when the safe propagation is on // LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors // but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones // if we don't at least catch std::exception ones

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -54,9 +54,9 @@ namespace sol {
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
protected_function_result() noexcept = default; protected_function_result() noexcept : protected_function_result(nullptr) {}
protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
: L(Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) { : L( Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
} }
// We do not want anyone to copy these around willy-nilly // We do not want anyone to copy these around willy-nilly
@ -99,6 +99,13 @@ namespace sol {
return status() == call_status::ok || status() == call_status::yielded; return status() == call_status::ok || status() == call_status::yielded;
} }
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#if !SOL_IS_ON(SOL_COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
template <typename T> template <typename T>
decltype(auto) get(int index_offset = 0) const { decltype(auto) get(int index_offset = 0) const {
using UT = meta::unqualified_t<T>; using UT = meta::unqualified_t<T>;
@ -109,7 +116,7 @@ namespace sol {
if (valid()) { if (valid()) {
return UT(); return UT();
} }
return UT(error(detail::direct_error, stack::get<std::string>(L, target))); return UT(stack::stack_detail::get_error(L, target));
} }
else { else {
if (!valid()) { if (!valid()) {
@ -120,16 +127,16 @@ namespace sol {
} }
else { else {
if constexpr (std::is_same_v<T, error>) { if constexpr (std::is_same_v<T, error>) {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_) #if SOL_IS_ON(SOL_SAFE_PROXIES)
if (valid()) { if (valid()) {
type t = type_of(L, target); type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)"); type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");
} }
#endif // Check Argument Safety #endif // Check Argument Safety
return error(detail::direct_error, stack::get<std::string>(L, target)); return stack::stack_detail::get_error(L, target);
} }
else { else {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_) #if SOL_IS_ON(SOL_SAFE_PROXIES)
if (!valid()) { if (!valid()) {
type t = type_of(L, target); type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)"); type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
@ -140,6 +147,10 @@ namespace sol {
} }
} }
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
type get_type(int index_offset = 0) const noexcept { type get_type(int index_offset = 0) const noexcept {
return type_of(L, index + static_cast<int>(index_offset)); return type_of(L, index + static_cast<int>(index_offset));
} }
@ -216,7 +227,7 @@ namespace sol {
template <> template <>
struct unqualified_pusher<protected_function_result> { struct unqualified_pusher<protected_function_result> {
static int push(lua_State* L, const protected_function_result& pfr) { static int push(lua_State* L, const protected_function_result& pfr) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(pfr.pop_count()), detail::not_enough_stack_space_generic); luaL_checkstack(L, static_cast<int>(pfr.pop_count()), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
int p = 0; int p = 0;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -92,7 +92,7 @@ namespace sol { namespace detail {
return; return;
} }
if (!ref.valid()) { if (!ref.valid()) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushnil(L); lua_pushnil(L);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -289,7 +289,7 @@ namespace sol {
} }
stateless_reference(lua_State* L_, global_tag_t) noexcept { stateless_reference(lua_State* L_, global_tag_t) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushglobaltable(L_); lua_pushglobaltable(L_);
@ -352,7 +352,7 @@ namespace sol {
} }
stateless_reference(lua_State* L_, int index = -1) noexcept { stateless_reference(lua_State* L_, int index = -1) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L_, index); lua_pushvalue(L_, index);
@ -383,7 +383,7 @@ namespace sol {
} }
int push(lua_State* L_) const noexcept { int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_rawgeti(L_, LUA_REGISTRYINDEX, ref); lua_rawgeti(L_, LUA_REGISTRYINDEX, ref);
@ -407,7 +407,7 @@ namespace sol {
void reset(lua_State* L_, int index_) noexcept { void reset(lua_State* L_, int index_) noexcept {
reset(L_); reset(L_);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L_, index_); lua_pushvalue(L_, index_);
@ -616,7 +616,7 @@ namespace sol {
} }
basic_reference(lua_State* L_, int index = -1) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) { basic_reference(lua_State* L_, int index = -1) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
// use L_ to stick with that state's execution stack // use L_ to stick with that state's execution stack
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L_, index); lua_pushvalue(L_, index);
@ -693,7 +693,7 @@ namespace sol {
} }
int push(lua_State* L_) const noexcept { int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
if (lua_state() == nullptr) { if (lua_state() == nullptr) {
@ -828,6 +828,8 @@ namespace sol {
stateless_reference_equals(lua_State* L_) noexcept : stateless_stack_reference_equals(L_) { stateless_reference_equals(lua_State* L_) noexcept : stateless_stack_reference_equals(L_) {
} }
using stateless_stack_reference_equals::operator();
bool operator()(const lua_nil_t& lhs, const stateless_reference& rhs) const noexcept { bool operator()(const lua_nil_t& lhs, const stateless_reference& rhs) const noexcept {
return rhs.equals(lua_state(), lhs); return rhs.equals(lua_state(), lhs);
} }
@ -839,6 +841,14 @@ namespace sol {
bool operator()(const stateless_reference& lhs, const stateless_reference& rhs) const noexcept { bool operator()(const stateless_reference& lhs, const stateless_reference& rhs) const noexcept {
return lhs.equals(lua_state(), rhs); return lhs.equals(lua_state(), rhs);
} }
bool operator()(const stateless_stack_reference& lhs, const stateless_reference& rhs) const noexcept {
return rhs.equals(lua_state(), lhs);
}
bool operator()(const stateless_reference& lhs, const stateless_stack_reference& rhs) const noexcept {
return lhs.equals(lua_state(), rhs);
}
}; };
struct reference_equals : public stack_reference_equals { struct reference_equals : public stack_reference_equals {
@ -878,6 +888,8 @@ namespace sol {
stateless_reference_hash(lua_State* L_) noexcept : stateless_stack_reference_hash(L_) { stateless_reference_hash(lua_State* L_) noexcept : stateless_stack_reference_hash(L_) {
} }
using stateless_stack_reference_hash::operator();
result_type operator()(const stateless_reference& lhs) const noexcept { result_type operator()(const stateless_reference& lhs) const noexcept {
std::hash<const void*> h; std::hash<const void*> h;
return h(lhs.pointer(lua_state())); return h(lhs.pointer(lua_state()));

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -1,6 +1,6 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -24,23 +24,23 @@
#include <sol/version.hpp> #include <sol/version.hpp>
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_) #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
#ifdef check #ifdef check
#pragma push_macro("check") #pragma push_macro("check")
#undef check #undef check
#endif #endif
#endif // Unreal Engine 4 Bullshit #endif // Unreal Engine 4 Bullshit
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) #if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow" #pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wconversion" #pragma GCC diagnostic ignored "-Wconversion"
#if __GNUC__ > 6 #if __GNUC__ > 6
#pragma GCC diagnostic ignored "-Wnoexcept-type" #pragma GCC diagnostic ignored "-Wnoexcept-type"
#endif #endif
#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) #elif SOL_IS_ON(SOL_COMPILER_CLANG)
// we'll just let this alone for now // we'll just let this alone for now
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) #elif SOL_IS_ON(SOL_COMPILER_VCXX)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS #pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS
#endif // clang++ vs. g++ vs. VC++ #endif // clang++ vs. g++ vs. VC++
@ -65,13 +65,15 @@
#include <sol/variadic_results.hpp> #include <sol/variadic_results.hpp>
#include <sol/lua_value.hpp> #include <sol/lua_value.hpp>
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) #if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) #elif SOL_IS_ON(SOL_COMPILER_CLANG)
// we'll just let this alone for now
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
#pragma warning(pop) #pragma warning(pop)
#endif // g++ #endif // g++
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_) #if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
#undef check #undef check
#pragma pop_macro("check") #pragma pop_macro("check")
#endif // Unreal Engine 4 Bullshit #endif // Unreal Engine 4 Bullshit

View file

@ -1,351 +1,384 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_STACK_HPP #ifndef SOL_STACK_HPP
#define SOL_STACK_HPP #define SOL_STACK_HPP
#include <sol/trampoline.hpp> #include <sol/trampoline.hpp>
#include <sol/stack_core.hpp> #include <sol/stack_core.hpp>
#include <sol/stack_reference.hpp> #include <sol/stack_reference.hpp>
#include <sol/stack_check.hpp> #include <sol/stack_check.hpp>
#include <sol/stack_get.hpp> #include <sol/stack_get.hpp>
#include <sol/stack_check_get.hpp> #include <sol/stack_check_get.hpp>
#include <sol/stack_push.hpp> #include <sol/stack_push.hpp>
#include <sol/stack_pop.hpp> #include <sol/stack_pop.hpp>
#include <sol/stack_field.hpp> #include <sol/stack_field.hpp>
#include <sol/stack_probe.hpp> #include <sol/stack_probe.hpp>
#include <sol/error.hpp>
#include <cstring> #include <sol/assert.hpp>
#include <array>
#include <cstring>
namespace sol { #include <array>
namespace detail {
using typical_chunk_name_t = char[SOL_ID_SIZE_I_]; namespace sol {
using typical_file_chunk_name_t = char[SOL_FILE_ID_SIZE_I_]; namespace detail {
using typical_chunk_name_t = char[SOL_ID_SIZE_I_];
inline const std::string& default_chunk_name() { using typical_file_chunk_name_t = char[SOL_FILE_ID_SIZE_I_];
static const std::string name = "";
return name; inline const std::string& default_chunk_name() {
} static const std::string name = "";
return name;
template <std::size_t N> }
const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
if (chunkname.empty()) { template <std::size_t N>
auto it = code.cbegin(); const char* make_chunk_name(const string_view& code, const std::string& chunkname, char (&basechunkname)[N]) {
auto e = code.cend(); if (chunkname.empty()) {
std::size_t i = 0; auto it = code.cbegin();
static const std::size_t n = N - 4; auto e = code.cend();
for (i = 0; i < n && it != e; ++i, ++it) { std::size_t i = 0;
basechunkname[i] = *it; static const std::size_t n = N - 4;
} for (i = 0; i < n && it != e; ++i, ++it) {
if (it != e) { basechunkname[i] = *it;
for (std::size_t c = 0; c < 3; ++i, ++c) { }
basechunkname[i] = '.'; if (it != e) {
} for (std::size_t c = 0; c < 3; ++i, ++c) {
} basechunkname[i] = '.';
basechunkname[i] = '\0'; }
return &basechunkname[0]; }
} basechunkname[i] = '\0';
else { return &basechunkname[0];
return chunkname.c_str(); }
} else {
} return chunkname.c_str();
}
inline void clear_entries(stack_reference r) { }
stack::push(r.lua_state(), lua_nil);
while (lua_next(r.lua_state(), -2)) { inline void clear_entries(stack_reference r) {
absolute_index key(r.lua_state(), -2); stack::push(r.lua_state(), lua_nil);
auto pn = stack::pop_n(r.lua_state(), 1); while (lua_next(r.lua_state(), -2)) {
stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index()); absolute_index key(r.lua_state(), -2);
} auto pn = stack::pop_n(r.lua_state(), 1);
} stack::set_field<false, true>(r.lua_state(), key, lua_nil, r.stack_index());
}
inline void clear_entries(const reference& registry_reference) { }
auto pp = stack::push_pop(registry_reference);
stack_reference ref(registry_reference.lua_state(), -1); inline void clear_entries(const reference& registry_reference) {
clear_entries(ref); auto pp = stack::push_pop(registry_reference);
} stack_reference ref(registry_reference.lua_state(), -1);
} // namespace detail clear_entries(ref);
}
namespace stack { } // namespace detail
namespace stack_detail {
template <typename T> namespace stack {
inline int push_as_upvalues(lua_State* L, T& item) { namespace stack_detail {
typedef std::decay_t<T> TValue; template <typename T>
static const std::size_t itemsize = sizeof(TValue); inline int push_as_upvalues(lua_State* L, T& item) {
static const std::size_t voidsize = sizeof(void*); typedef std::decay_t<T> TValue;
static const std::size_t voidsizem1 = voidsize - 1; static const std::size_t itemsize = sizeof(TValue);
static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize; static const std::size_t voidsize = sizeof(void*);
typedef std::array<void*, data_t_count> data_t; static const std::size_t voidsizem1 = voidsize - 1;
static const std::size_t data_t_count = (sizeof(TValue) + voidsizem1) / voidsize;
data_t data { {} }; typedef std::array<void*, data_t_count> data_t;
std::memcpy(&data[0], std::addressof(item), itemsize);
int pushcount = 0; data_t data { {} };
for (const auto& v : data) { std::memcpy(&data[0], std::addressof(item), itemsize);
lua_pushlightuserdata(L, v); int pushcount = 0;
pushcount += 1; for (const auto& v : data) {
} lua_pushlightuserdata(L, v);
return pushcount; pushcount += 1;
} }
return pushcount;
template <typename T> }
inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*); template <typename T>
typedef std::array<void*, data_t_count> data_t; inline std::pair<T, int> get_as_upvalues(lua_State* L, int index = 2) {
data_t voiddata { {} }; static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) { typedef std::array<void*, data_t_count> data_t;
voiddata[i] = lua_touserdata(L, upvalue_index(index++)); data_t voiddata { {} };
} for (std::size_t i = 0, d = 0; d < sizeof(T); ++i, d += sizeof(void*)) {
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index); voiddata[i] = lua_touserdata(L, upvalue_index(index++));
} }
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
template <typename T> }
inline std::pair<T, int> get_as_upvalues_using_function(lua_State* L, int function_index = -1) {
static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*); template <typename T>
typedef std::array<void*, data_t_count> data_t; inline std::pair<T, int> get_as_upvalues_using_function(lua_State* L, int function_index = -1) {
function_index = lua_absindex(L, function_index); static const std::size_t data_t_count = (sizeof(T) + (sizeof(void*) - 1)) / sizeof(void*);
int index = 0; typedef std::array<void*, data_t_count> data_t;
data_t voiddata { {} }; function_index = lua_absindex(L, function_index);
for (std::size_t d = 0; d < sizeof(T); d += sizeof(void*)) { int index = 0;
// first upvalue is nullptr to respect environment shenanigans data_t voiddata { {} };
// So +2 instead of +1 for (std::size_t d = 0; d < sizeof(T); d += sizeof(void*)) {
const char* upvalue_name = lua_getupvalue(L, function_index, index + 2); // first upvalue is nullptr to respect environment shenanigans
if (upvalue_name == nullptr) { // So +2 instead of +1
// We should freak out here... const char* upvalue_name = lua_getupvalue(L, function_index, index + 2);
break; if (upvalue_name == nullptr) {
} // We should freak out here...
voiddata[index] = lua_touserdata(L, -1); break;
++index; }
} voiddata[index] = lua_touserdata(L, -1);
lua_pop(L, index); ++index;
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index); }
} lua_pop(L, index);
return std::pair<T, int>(*reinterpret_cast<T*>(static_cast<void*>(voiddata.data())), index);
template <bool checked, typename Handler, typename Fx, typename... Args> }
static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, Handler&&, record&, Fx&& fx, Args&&... args) {
return std::forward<Fx>(fx)(std::forward<Args>(args)...); template <bool checked, typename Handler, typename Fx, typename... Args>
} static decltype(auto) eval(types<>, std::index_sequence<>, lua_State*, int, Handler&&, record&, Fx&& fx, Args&&... args) {
return std::forward<Fx>(fx)(std::forward<Args>(args)...);
template <bool checked, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename Handler, typename Fx, typename... FxArgs> }
static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L_, int start_index_, Handler&& handler_,
record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) { template <bool checked, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename Handler, typename Fx, typename... FxArgs>
#if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_) static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L_, int start_index_, Handler&& handler_,
// We can save performance/time by letting errors unwind produced arguments record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) {
// rather than checking everything once, and then potentially re-doing work #if 0 && SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
if constexpr (checked) { // NOTE: THIS IS TERMPORARILY TURNED OFF BECAUSE IT IMPACTS ACTUAL SEMANTICS W.R.T. THINGS LIKE LUAJIT,
return eval<checked>(types<Args...>(), // SO IT MUST REMAIN OFF UNTIL WE CAN ESTABLISH SIMILAR BEHAVIOR IN MODES WHERE `checked == false`!
std::index_sequence<Is...>(),
L_, // We can save performance/time by letting errors unwind produced arguments
start_index_, // rather than checking everything once, and then potentially re-doing work
std::forward<Handler>(handler_), if constexpr (checked) {
tracking_, return eval<checked>(types<Args...>(),
std::forward<Fx>(fx_), std::index_sequence<Is...>(),
std::forward<FxArgs>(fxargs_)..., L_,
*stack_detail::check_get_arg<Arg>(L_, start_index_ + tracking_.used, handler_, tracking_)); start_index_,
} std::forward<Handler>(handler_),
else tracking_,
#endif std::forward<Fx>(fx_),
{ std::forward<FxArgs>(fxargs_)...,
return eval<checked>(types<Args...>(), *stack_detail::check_get_arg<Arg>(L_, start_index_ + tracking_.used, handler_, tracking_));
std::index_sequence<Is...>(), }
L_, else
start_index_, #endif
std::forward<Handler>(handler_), {
tracking_, return eval<checked>(types<Args...>(),
std::forward<Fx>(fx_), std::index_sequence<Is...>(),
std::forward<FxArgs>(fxargs_)..., L_,
stack_detail::unchecked_get_arg<Arg>(L_, start_index_ + tracking_.used, tracking_)); start_index_,
} std::forward<Handler>(handler_),
} tracking_,
std::forward<Fx>(fx_),
template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs> std::forward<FxArgs>(fxargs_)...,
inline decltype(auto) call(types<R>, types<Args...> argument_types_, std::index_sequence<I...> argument_indices_, lua_State* L_, stack_detail::unchecked_get_arg<Arg>(L_, start_index_ + tracking_.used, tracking_));
int start_index_, Fx&& fx_, FxArgs&&... args_) { }
static_assert(meta::all_v<meta::is_not_move_only<Args>...>, }
"One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take "
"a reference and std::move it manually if this was your intention."); template <bool checkargs = detail::default_safe_function_calls, std::size_t... I, typename R, typename... Args, typename Fx, typename... FxArgs>
argument_handler<types<R, Args...>> handler {}; inline decltype(auto) call(types<R>, types<Args...> argument_types_, std::index_sequence<I...> argument_indices_, lua_State* L_,
record tracking {}; int start_index_, Fx&& fx_, FxArgs&&... args_) {
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) static_assert(meta::all_v<meta::is_not_move_only<Args>...>,
if constexpr (checkargs) { "One of the arguments being bound is a move-only type, and it is not being taken by reference: this will break your code. Please take "
multi_check<Args...>(L_, start_index_, handler); "a reference and std::move it manually if this was your intention.");
} argument_handler<types<R, Args...>> handler {};
#endif record tracking {};
if constexpr (std::is_void_v<R>) { #if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
eval<checkargs>( if constexpr (checkargs) {
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...); multi_check<Args...>(L_, start_index_, handler);
} }
else { #endif
return eval<checkargs>( if constexpr (std::is_void_v<R>) {
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...); eval<checkargs>(
} argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
} }
} // namespace stack_detail else {
return eval<checkargs>(
template <typename T> argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
int set_ref(lua_State* L, T&& arg, int tableindex = -2) { }
push(L, std::forward<T>(arg)); }
return luaL_ref(L, tableindex);
} template <typename T>
void raw_table_set(lua_State* L, T&& arg, int tableindex = -2) {
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs> int push_count = push(L, std::forward<T>(arg));
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) { SOL_ASSERT(push_count == 1);
using args_indices = std::make_index_sequence<sizeof...(Args)>; std::size_t unique_index = static_cast<std::size_t>(luaL_len(L, tableindex) + 1u);
if constexpr (std::is_void_v<R>) { lua_rawseti(L, tableindex, static_cast<int>(unique_index));
stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...); }
}
else { } // namespace stack_detail
return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
} template <typename T>
} int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
int push_count = push(L, std::forward<T>(arg));
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs> SOL_ASSERT(push_count == 1);
inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) { return luaL_ref(L, tableindex);
if constexpr (std::is_void_v<R>) { }
call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
} template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
else { inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... args) {
return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...); using args_indices = std::make_index_sequence<sizeof...(Args)>;
} if constexpr (std::is_void_v<R>) {
} stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
}
template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs> else {
inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) { return stack_detail::call<check_args>(tr, ta, args_indices(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
using expected_count_t = meta::count_for_pack<lua_size, Args...>; }
if constexpr (std::is_void_v<R>) { }
call<check_args>(tr,
ta, template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
L, inline decltype(auto) call(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)), if constexpr (std::is_void_v<R>) {
std::forward<Fx>(fx), call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
std::forward<FxArgs>(args)...); }
} else {
else { return call<check_args>(tr, ta, L, 1, std::forward<Fx>(fx), std::forward<FxArgs>(args)...);
return call<check_args>(tr, }
ta, }
L,
(std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)), template <bool check_args = detail::default_safe_function_calls, typename R, typename... Args, typename Fx, typename... FxArgs>
std::forward<Fx>(fx), inline decltype(auto) call_from_top(types<R> tr, types<Args...> ta, lua_State* L, Fx&& fx, FxArgs&&... args) {
std::forward<FxArgs>(args)...); using expected_count_t = meta::count_for_pack<lua_size, Args...>;
} if constexpr (std::is_void_v<R>) {
} call<check_args>(tr,
ta,
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args, L,
typename Fx, typename... FxArgs> (std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) { std::forward<Fx>(fx),
if constexpr (std::is_void_v<Ret0>) { std::forward<FxArgs>(args)...);
call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...); }
if constexpr (clean_stack) { else {
lua_settop(L, 0); return call<check_args>(tr,
} ta,
return 0; L,
} (std::max)(static_cast<int>(lua_gettop(L) - expected_count_t::value), static_cast<int>(0)),
else { std::forward<Fx>(fx),
(void)tr; std::forward<FxArgs>(args)...);
decltype(auto) r }
= call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...); }
using R = meta::unqualified_t<decltype(r)>;
using is_stack = meta::any<is_stack_based<R>, std::is_same<R, absolute_index>, std::is_same<R, ref_index>, std::is_same<R, raw_index>>; template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Ret0, typename... Ret, typename... Args,
if constexpr (clean_stack && !is_stack::value) { typename Fx, typename... FxArgs>
lua_settop(L, 0); inline int call_into_lua(types<Ret0, Ret...> tr, types<Args...> ta, lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
} if constexpr (std::is_void_v<Ret0>) {
return push_reference(L, std::forward<decltype(r)>(r)); call<check_args>(tr, ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
} if constexpr (clean_stack) {
} lua_settop(L, 0);
}
template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs> return 0;
inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) { }
using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>; else {
using args_list = typename traits_type::args_list; (void)tr;
using returns_list = typename traits_type::returns_list; decltype(auto) r
return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...); = call<check_args>(types<meta::return_type_t<Ret0, Ret...>>(), ta, L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
} using R = meta::unqualified_t<decltype(r)>;
using is_stack = meta::any<is_stack_based<R>, std::is_same<R, absolute_index>, std::is_same<R, ref_index>, std::is_same<R, raw_index>>;
inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) { if constexpr (clean_stack && !is_stack::value) {
if (lua_gettop(L) < 1) { lua_settop(L, 0);
return call_syntax::dot; }
} return push_reference(L, std::forward<decltype(r)>(r));
luaL_getmetatable(L, key.data()); }
auto pn = pop_n(L, 1); }
if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
return call_syntax::dot; template <bool check_args = detail::default_safe_function_calls, bool clean_stack = true, typename Fx, typename... FxArgs>
} inline int call_lua(lua_State* L, int start, Fx&& fx, FxArgs&&... fxargs) {
return call_syntax::colon; using traits_type = lua_bind_traits<meta::unqualified_t<Fx>>;
} using args_list = typename traits_type::args_list;
using returns_list = typename traits_type::returns_list;
inline void script( return call_into_lua<check_args, clean_stack>(returns_list(), args_list(), L, start, std::forward<Fx>(fx), std::forward<FxArgs>(fxargs)...);
lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { }
detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname); inline call_syntax get_call_syntax(lua_State* L, const string_view& key, int index) {
if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) { if (lua_gettop(L) < 1) {
lua_error(L); return call_syntax::dot;
} }
} luaL_getmetatable(L, key.data());
auto pn = pop_n(L, 1);
inline void script( if (lua_compare(L, -1, index, LUA_OPEQ) != 1) {
lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { return call_syntax::dot;
}
detail::typical_chunk_name_t basechunkname = {}; return call_syntax::colon;
const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname); }
if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
lua_error(L); inline void script(
} lua_State* L, lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
} detail::typical_chunk_name_t basechunkname = {};
const char* chunknametarget = detail::make_chunk_name("lua_Reader", chunkname, basechunkname);
inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) { if (lua_load(L, reader, data, chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) { lua_error(L);
lua_error(L); }
} }
}
inline void script(
inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) { lua_State* L, const string_view& code, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
if (L == nullptr) { detail::typical_chunk_name_t basechunkname = {};
return; const char* chunknametarget = detail::make_chunk_name(code, chunkname, basechunkname);
} if (luaL_loadbufferx(L, code.data(), code.size(), chunknametarget, to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) lua_error(L);
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); }
#endif // make sure stack doesn't overflow }
lua_pushlightuserdata(L, (void*)handler);
auto pn = pop_n(L, 1); inline void script_file(lua_State* L, const std::string& filename, load_mode mode = load_mode::any) {
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON); if (luaL_loadfilex(L, filename.c_str(), to_string(mode).c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0)) {
#else lua_error(L);
(void)L; }
(void)handler; }
#endif
} inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
inline void luajit_exception_off(lua_State* L) { if (L == nullptr) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_) return;
if (L == nullptr) { }
return; #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
} luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF); #endif // make sure stack doesn't overflow
#else lua_pushlightuserdata(L, (void*)handler);
(void)L; auto pn = pop_n(L, 1);
#endif luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_ON);
} #else
} // namespace stack (void)L;
} // namespace sol (void)handler;
#endif
#endif // SOL_STACK_HPP }
inline void luajit_exception_off(lua_State* L) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
if (L == nullptr) {
return;
}
luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC | LUAJIT_MODE_OFF);
#else
(void)L;
#endif
}
namespace stack_detail {
inline error get_error(lua_State* L, int target) {
auto maybe_exc = stack::check_get<error&>(L, target);
if (maybe_exc.has_value()) {
return maybe_exc.value();
}
return error(detail::direct_error, stack::get<std::string>(L, target));
}
inline detail::error_exception get_error_exception(lua_State* L, int target) {
auto maybe_exc = stack::check_get<detail::error_exception&>(L, target);
if (maybe_exc.has_value()) {
return maybe_exc.value();
}
return detail::error_exception(detail::direct_error, stack::get<std::string>(L, target));
}
}
} // namespace stack
} // namespace sol
#endif // SOL_STACK_HPP

View file

@ -1,98 +1,98 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this Spermission notice shall be included in all // The above copyright notice and this Spermission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_DETAIL_PAIRS_HPP #ifndef SOL_DETAIL_PAIRS_HPP
#define SOL_DETAIL_PAIRS_HPP #define SOL_DETAIL_PAIRS_HPP
#include <sol/version.hpp> #include <sol/version.hpp>
#include <sol/stack.hpp> #include <sol/stack.hpp>
#include <sol/stack_reference.hpp> #include <sol/stack_reference.hpp>
#include <sol/protected_function.hpp> #include <sol/protected_function.hpp>
#include <sol/assert.hpp> #include <sol/assert.hpp>
#include <optional> #include <optional>
namespace sol { namespace stack { namespace stack_detail { namespace sol { namespace stack { namespace stack_detail {
inline bool maybe_push_lua_next_function(lua_State* L_) { inline bool maybe_push_lua_next_function(lua_State* L_) {
stack::get_field<true, false>(L_, "next"); stack::get_field<true, false>(L_, "next");
bool is_next = stack::check<protected_function>(L_); bool is_next = stack::check<protected_function>(L_);
if (is_next) { if (is_next) {
return true; return true;
} }
stack::get_field<true, false>(L_, "table"); stack::get_field<true, false>(L_, "table");
stack::record tracking{}; stack::record tracking{};
if (!stack::loose_table_check(L_, -1, &no_panic, tracking)) { if (!stack::loose_table_check(L_, -1, &no_panic, tracking)) {
return false; return false;
} }
lua_getfield(L_, -1, "next"); lua_getfield(L_, -1, "next");
bool is_table_next_func = stack::check<protected_function>(L_, -1); bool is_table_next_func = stack::check<protected_function>(L_, -1);
if (is_table_next_func) { if (is_table_next_func) {
return true; return true;
} }
lua_pop(L_, 1); lua_pop(L_, 1);
return false; return false;
} }
inline std::optional<protected_function> find_lua_next_function(lua_State* L_) { inline std::optional<protected_function> find_lua_next_function(lua_State* L_) {
if (maybe_push_lua_next_function(L_)) { if (maybe_push_lua_next_function(L_)) {
return stack::pop<protected_function>(L_); return stack::pop<protected_function>(L_);
} }
return std::nullopt; return std::nullopt;
} }
inline int c_lua_next(lua_State* L_) noexcept { inline int c_lua_next(lua_State* L_) noexcept {
stack_reference table_stack_ref(L_, raw_index(1)); stack_reference table_stack_ref(L_, raw_index(1));
stateless_stack_reference key_stack_ref(L_, raw_index(2)); stateless_stack_reference key_stack_ref(L_, raw_index(2));
int result = lua_next(table_stack_ref.lua_state(), table_stack_ref.stack_index()); int result = lua_next(table_stack_ref.lua_state(), table_stack_ref.stack_index());
if (result == 0) { if (result == 0) {
stack::push(L_, lua_nil); stack::push(L_, lua_nil);
return 1; return 1;
} }
return 2; return 2;
} }
inline int readonly_pairs(lua_State* L_) noexcept { inline int readonly_pairs(lua_State* L_) noexcept {
int pushed = 0; int pushed = 0;
if (!maybe_push_lua_next_function(L_)) { if (!maybe_push_lua_next_function(L_)) {
// we do not have the "next" function in the global namespace // we do not have the "next" function in the global namespace
// from the "table" global entiry, use our own // from the "table" global entiry, use our own
pushed += stack::push(L_, &c_lua_next); pushed += stack::push(L_, &c_lua_next);
} }
else { else {
pushed += 1; pushed += 1;
} }
int metatable_exists = lua_getmetatable(L_, 1); int metatable_exists = lua_getmetatable(L_, 1);
sol_c_assert(metatable_exists == 1); SOL_ASSERT(metatable_exists == 1);
const auto& index_key = to_string(sol::meta_function::index); const auto& index_key = to_string(sol::meta_function::index);
lua_getfield(L_, lua_gettop(L_), index_key.c_str()); lua_getfield(L_, lua_gettop(L_), index_key.c_str());
lua_remove(L_, -2); lua_remove(L_, -2);
pushed += 1; pushed += 1;
pushed += stack::push(L_, lua_nil); pushed += stack::push(L_, lua_nil);
return pushed; return pushed;
} }
}}} // sol::stack::stack_detail }}} // sol::stack::stack_detail
#endif // SOL_DETAIL_PAIRS_HPP #endif // SOL_DETAIL_PAIRS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -30,6 +30,13 @@
namespace sol { namespace stack { namespace sol { namespace stack {
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#if !SOL_IS_ON(SOL_COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
namespace stack_detail { namespace stack_detail {
template <typename OptionalType, typename T, typename Handler> template <typename OptionalType, typename T, typename Handler>
OptionalType get_optional(lua_State* L, int index, Handler&& handler, record& tracking) { OptionalType get_optional(lua_State* L, int index, Handler&& handler, record& tracking) {
@ -70,9 +77,8 @@ namespace sol { namespace stack {
actual* mem = static_cast<actual*>(memory); actual* mem = static_cast<actual*>(memory);
return static_cast<actual>(*mem); return static_cast<actual>(*mem);
} }
actual r {};
if constexpr (!derive<element>::value) { if constexpr (!derive<element>::value) {
return {}; return OptionalType();
} }
else { else {
memory = detail::align_usertype_unique_tag<true, false>(memory); memory = detail::align_usertype_unique_tag<true, false>(memory);
@ -80,6 +86,7 @@ namespace sol { namespace stack {
memory = detail::align_usertype_unique<actual, true, false>(memory); memory = detail::align_usertype_unique<actual, true, false>(memory);
string_view ti = usertype_traits<element>::qualified_name(); string_view ti = usertype_traits<element>::qualified_name();
int cast_operation; int cast_operation;
actual r {};
if constexpr (is_actual_type_rebindable_for_v<Tu>) { if constexpr (is_actual_type_rebindable_for_v<Tu>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<Tu, void>; using rebound_actual_type = unique_usertype_rebind_actual_t<Tu, void>;
string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name(); string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
@ -103,19 +110,23 @@ namespace sol { namespace stack {
default: default:
break; break;
} }
return {}; return OptionalType();
} }
} }
else { else {
if (!check<T>(L, index, std::forward<Handler>(handler))) { if (!check<T>(L, index, std::forward<Handler>(handler))) {
tracking.use(static_cast<int>(!lua_isnone(L, index))); tracking.use(static_cast<int>(!lua_isnone(L, index)));
return {}; return OptionalType();
} }
return OptionalType(stack_detail::unchecked_get<T>(L, index, tracking)); return OptionalType(stack_detail::unchecked_get<T>(L, index, tracking));
} }
} }
} // namespace stack_detail } // namespace stack_detail
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
template <typename T, typename> template <typename T, typename>
struct qualified_check_getter { struct qualified_check_getter {
typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R; typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -32,7 +32,7 @@
#include <cstdlib> #include <cstdlib>
#include <cmath> #include <cmath>
#include <optional> #include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant> #include <variant>
#endif // variant shenanigans (thanks, Mac OSX) #endif // variant shenanigans (thanks, Mac OSX)
@ -76,7 +76,7 @@ namespace sol { namespace stack {
int isnum = 0; int isnum = 0;
const lua_Number value = lua_tonumberx(L, index, &isnum); const lua_Number value = lua_tonumberx(L, index, &isnum);
if (isnum != 0) { if (isnum != 0) {
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_) #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
const auto integer_value = llround(value); const auto integer_value = llround(value);
if (static_cast<lua_Number>(integer_value) == value) { if (static_cast<lua_Number>(integer_value) == value) {
tracking.use(1); tracking.use(1);
@ -139,7 +139,7 @@ namespace sol { namespace stack {
} }
}; };
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn, typename C> template <typename... Tn, typename C>
struct unqualified_check_getter<std::variant<Tn...>, C> { struct unqualified_check_getter<std::variant<Tn...>, C> {
typedef std::variant<Tn...> V; typedef std::variant<Tn...> V;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -28,7 +28,7 @@
namespace sol { namespace stack { namespace sol { namespace stack {
template <typename X, type expected, typename> template <typename X, typename>
struct qualified_checker { struct qualified_checker {
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) {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -32,7 +32,7 @@
#include <utility> #include <utility>
#include <cmath> #include <cmath>
#include <optional> #include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant> #include <variant>
#endif // variant shenanigans #endif // variant shenanigans
@ -116,7 +116,7 @@ namespace sol { namespace stack {
} }
else if constexpr (meta::any_same_v<T, else if constexpr (meta::any_same_v<T,
char char
#if SOL_IS_ON(SOL_CHAR8_T_I_) #if SOL_IS_ON(SOL_CHAR8_T)
, ,
char8_t char8_t
#endif #endif
@ -129,7 +129,7 @@ namespace sol { namespace stack {
tracking.use(1); tracking.use(1);
#if SOL_LUA_VERSION_I_ >= 503 #if SOL_LUA_VERSION_I_ >= 503
// Lua 5.3 and greater checks for numeric precision // Lua 5.3 and greater checks for numeric precision
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_) #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
// imprecise, sloppy conversions // imprecise, sloppy conversions
int isnum = 0; int isnum = 0;
lua_tointegerx(L_, index, &isnum); lua_tointegerx(L_, index, &isnum);
@ -138,7 +138,7 @@ namespace sol { namespace stack {
// expected type, actual type // expected type, actual type
handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string_integral); handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string_integral);
} }
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_) #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
// this check is precise, do not convert // this check is precise, do not convert
if (lua_isinteger(L_, index) == 1) { if (lua_isinteger(L_, index) == 1) {
return true; return true;
@ -160,7 +160,7 @@ namespace sol { namespace stack {
return success; return success;
#else #else
// Lua 5.2 and below checks // Lua 5.2 and below checks
#if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS_I_) #if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS)
// must pre-check, because it will convert // must pre-check, because it will convert
type t = type_of(L_, index); type t = type_of(L_, index);
if (t != type::number) { if (t != type::number) {
@ -170,7 +170,7 @@ namespace sol { namespace stack {
} }
#endif // Do not allow strings to be numbers #endif // Do not allow strings to be numbers
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_) #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
int isnum = 0; int isnum = 0;
const lua_Number v = lua_tonumberx(L_, index, &isnum); const lua_Number v = lua_tonumberx(L_, index, &isnum);
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v; const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
@ -179,9 +179,9 @@ namespace sol { namespace stack {
#endif // Safe numerics and number precision checking #endif // Safe numerics and number precision checking
if (!success) { if (!success) {
// Use defines to provide a better error message! // Use defines to provide a better error message!
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_) #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string); handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string);
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_) #elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
handler(L_, index, type::number, t, detail::not_a_number_or_number_string); handler(L_, index, type::number, t, detail::not_a_number_or_number_string);
#else #else
handler(L_, index, type::number, t, detail::not_a_number); handler(L_, index, type::number, t, detail::not_a_number);
@ -192,7 +192,7 @@ namespace sol { namespace stack {
} }
else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) { else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
tracking.use(1); tracking.use(1);
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_) #if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
bool success = lua_isnumber(L_, index) == 1; bool success = lua_isnumber(L_, index) == 1;
if (!success) { if (!success) {
// expected type, actual type // expected type, actual type
@ -218,6 +218,7 @@ namespace sol { namespace stack {
} }
else if constexpr (is_unique_usertype_v<T>) { else if constexpr (is_unique_usertype_v<T>) {
using element = unique_usertype_element_t<T>; using element = unique_usertype_element_t<T>;
using element_no_cv = meta::unqualified_t<element>;
using actual = unique_usertype_actual_t<T>; using actual = unique_usertype_actual_t<T>;
const type indextype = type_of(L_, index); const type indextype = type_of(L_, index);
tracking.use(1); tracking.use(1);
@ -229,7 +230,7 @@ namespace sol { namespace stack {
return true; return true;
} }
int metatableindex = lua_gettop(L_); int metatableindex = lua_gettop(L_);
if (stack_detail::check_metatable<d::u<element>>(L_, metatableindex)) { if (stack_detail::check_metatable<d::u<element_no_cv>>(L_, metatableindex)) {
void* memory = lua_touserdata(L_, index); void* memory = lua_touserdata(L_, index);
memory = detail::align_usertype_unique_destructor(memory); memory = detail::align_usertype_unique_destructor(memory);
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory); detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
@ -371,7 +372,7 @@ namespace sol { namespace stack {
} }
return stack::unqualified_check<ValueType>(L_, index, &no_panic, tracking); return stack::unqualified_check<ValueType>(L_, index, &no_panic, tracking);
} }
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) { else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L_, index, std::forward<Handler>(handler), tracking); return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L_, index, std::forward<Handler>(handler), tracking);
} }
@ -388,9 +389,7 @@ namespace sol { namespace stack {
return success; return success;
} }
else if constexpr (meta::is_specialization_of_v<T, user>) { else if constexpr (meta::is_specialization_of_v<T, user>) {
unqualified_checker<lightuserdata_value, type::userdata> c; return stack::unqualified_check<detail::as_value_tag<lightuserdata_value>>(L_, index, std::forward<Handler>(handler), tracking);
(void)c;
return c.check(L_, index, std::forward<Handler>(handler), tracking);
} }
else { else {
if constexpr (std::is_pointer_v<T>) { if constexpr (std::is_pointer_v<T>) {
@ -508,13 +507,13 @@ namespace sol { namespace stack {
return true; return true;
} }
else { else {
#if SOL_IS_ON(SOL_USE_INTEROP_I_) #if SOL_IS_ON(SOL_USE_INTEROP)
if (stack_detail::interop_check<U>(L_, index, indextype, handler, tracking)) { if (stack_detail::interop_check<U>(L_, index, indextype, handler, tracking)) {
return true; return true;
} }
#endif // interop extensibility #endif // interop extensibility
tracking.use(1); tracking.use(1);
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
if (lua_iscfunction(L_, index) != 0) { if (lua_iscfunction(L_, index) != 0) {
// a potential match... // a potential match...
return true; return true;
@ -539,7 +538,7 @@ namespace sol { namespace stack {
bool success = false; bool success = false;
bool has_derived = derive<T>::value || weak_derive<T>::value; bool has_derived = derive<T>::value || weak_derive<T>::value;
if (has_derived) { if (has_derived) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, detail::not_enough_stack_space_string); luaL_checkstack(L_, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
auto pn = stack::pop_n(L_, 1); auto pn = stack::pop_n(L_, 1);
@ -579,6 +578,104 @@ namespace sol { namespace stack {
} }
}; };
template <typename T, std::size_t N, type expect>
struct unqualified_checker<exhaustive_until<T, N>, expect> {
template <typename K, typename V, typename Handler>
static bool check_two(types<K, V>, lua_State* arg_L, int relindex, type, Handler&& handler, record& tracking) {
tracking.use(1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(arg_L, 3, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
int index = lua_absindex(arg_L, relindex);
lua_pushnil(arg_L);
while (lua_next(arg_L, index) != 0) {
const bool is_key_okay = stack::check<K>(arg_L, -2, std::forward<Handler>(handler), tracking);
if (!is_key_okay) {
lua_pop(arg_L, 2);
return false;
}
const bool is_value_okay = stack::check<V>(arg_L, -1, std::forward<Handler>(handler), tracking);
if (!is_value_okay) {
lua_pop(arg_L, 2);
return false;
}
lua_pop(arg_L, 1);
}
return true;
}
template <typename V, typename Handler>
static bool check_one(types<V>, lua_State* arg_L, int relindex, type, Handler&& handler, record& tracking) {
tracking.use(1);
size_t index = lua_absindex(arg_L, relindex);
// Zzzz slower but necessary thanks to the lower version API and missing functions qq
std::size_t idx = 0;
int vi = 0;
for (lua_Integer i = 0;; (void)(i += lua_size<V>::value), lua_pop(arg_L, static_cast<int>(vi))) {
vi = 0;
if (idx >= N) {
return true;
}
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(arg_L, 2, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
bool isnil = false;
for (; vi < static_cast<int>(lua_size<V>::value); ++vi) {
lua_pushinteger(arg_L, i);
lua_gettable(arg_L, static_cast<int>(index));
type vt = type_of(arg_L, -1);
isnil = vt == type::lua_nil;
if (isnil) {
if (i == 0) {
vi += 1;
goto loop_continue;
}
lua_pop(arg_L, static_cast<int>(vi + 1));
return true;
}
}
if (!stack::check<V>(arg_L, -lua_size<V>::value, std::forward<Handler>(handler), tracking)) {
lua_pop(arg_L, lua_size<V>::value);
return false;
}
++idx;
loop_continue:;
}
}
template <typename Handler>
static bool check(lua_State* arg_L, int index, Handler&& handler, record& tracking) {
using Tu = meta::unqualified_t<T>;
if constexpr (is_container_v<Tu>) {
if constexpr (meta::is_associative<Tu>::value) {
typedef typename Tu::value_type P;
typedef typename P::first_type K;
typedef typename P::second_type V;
return check_two(types<K, V>(), arg_L, index, expect, std::forward<Handler>(handler), tracking);
}
else {
typedef typename Tu::value_type V;
return check_one(types<V>(), arg_L, index, expect, std::forward<Handler>(handler), tracking);
}
}
else {
unqualified_checker<Tu, expect> c {};
return c.check(arg_L, index, std::forward<Handler>(handler), tracking);
}
}
};
template <typename T, type expect>
struct unqualified_checker<non_exhaustive<T>, expect> {
template <typename Handler>
static bool check(lua_State* arg_L, int index, Handler&& handler, record& tracking) {
return stack::check<T>(arg_L, index, std::forward<Handler>(handler), tracking);
}
};
template <typename... Args> template <typename... Args>
struct unqualified_checker<std::tuple<Args...>, type::poly> { struct unqualified_checker<std::tuple<Args...>, type::poly> {
template <typename Handler> template <typename Handler>
@ -595,7 +692,7 @@ namespace sol { namespace stack {
} }
}; };
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn> template <typename... Tn>
struct unqualified_checker<std::variant<Tn...>, type::poly> { struct unqualified_checker<std::variant<Tn...>, type::poly> {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -127,7 +127,7 @@ namespace sol {
inline void* align_usertype_pointer(void* ptr) { inline void* align_usertype_pointer(void* ptr) {
using use_align = std::integral_constant<bool, using use_align = std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of<void*>::value > 1) (std::alignment_of<void*>::value > 1)
@ -143,7 +143,7 @@ namespace sol {
template <bool pre_aligned = false, bool pre_shifted = false> template <bool pre_aligned = false, bool pre_shifted = false>
void* align_usertype_unique_destructor(void* ptr) { void* align_usertype_unique_destructor(void* ptr) {
using use_align = std::integral_constant<bool, using use_align = std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of<unique_destructor>::value > 1) (std::alignment_of<unique_destructor>::value > 1)
@ -165,7 +165,7 @@ namespace sol {
template <bool pre_aligned = false, bool pre_shifted = false> template <bool pre_aligned = false, bool pre_shifted = false>
void* align_usertype_unique_tag(void* ptr) { void* align_usertype_unique_tag(void* ptr) {
using use_align = std::integral_constant<bool, using use_align = std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of<unique_tag>::value > 1) (std::alignment_of<unique_tag>::value > 1)
@ -187,7 +187,7 @@ namespace sol {
template <typename T, bool pre_aligned = false, bool pre_shifted = false> template <typename T, bool pre_aligned = false, bool pre_shifted = false>
void* align_usertype_unique(void* ptr) { void* align_usertype_unique(void* ptr) {
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of_v<T> > 1) (std::alignment_of_v<T> > 1)
@ -210,7 +210,7 @@ namespace sol {
template <typename T> template <typename T>
void* align_user(void* ptr) { void* align_user(void* ptr) {
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of_v<T> > 1) (std::alignment_of_v<T> > 1)
@ -227,7 +227,7 @@ namespace sol {
template <typename T> template <typename T>
T** usertype_allocate_pointer(lua_State* L) { T** usertype_allocate_pointer(lua_State* L) {
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of<T*>::value > 1) (std::alignment_of<T*>::value > 1)
@ -311,7 +311,7 @@ namespace sol {
template <typename T> template <typename T>
T* usertype_allocate(lua_State* L) { T* usertype_allocate(lua_State* L) {
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of<T*>::value > 1 || std::alignment_of_v<T> > 1) (std::alignment_of<T*>::value > 1 || std::alignment_of_v<T> > 1)
@ -352,7 +352,7 @@ namespace sol {
template <typename T, typename Real> template <typename T, typename Real>
Real* usertype_unique_allocate(lua_State* L, T**& pref, unique_destructor*& dx, unique_tag*& id) { Real* usertype_unique_allocate(lua_State* L, T**& pref, unique_destructor*& dx, unique_tag*& id) {
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of<T*>::value > 1 || std::alignment_of<unique_tag>::value > 1 || std::alignment_of<unique_destructor>::value > 1 (std::alignment_of<T*>::value > 1 || std::alignment_of<unique_tag>::value > 1 || std::alignment_of<unique_destructor>::value > 1
@ -370,10 +370,10 @@ namespace sol {
constexpr std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>(); constexpr std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>();
void* pointer_adjusted; void* pointer_adjusted = nullptr;
void* dx_adjusted; void* dx_adjusted = nullptr;
void* id_adjusted; void* id_adjusted = nullptr;
void* data_adjusted; void* data_adjusted = nullptr;
bool result = attempt_alloc_unique(L, bool result = attempt_alloc_unique(L,
std::alignment_of_v<T*>, std::alignment_of_v<T*>,
sizeof(T*), sizeof(T*),
@ -406,7 +406,7 @@ namespace sol {
template <typename T> template <typename T>
T* user_allocate(lua_State* L) { T* user_allocate(lua_State* L) {
typedef std::integral_constant<bool, typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_) #if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false false
#else #else
(std::alignment_of_v<T> > 1) (std::alignment_of_v<T> > 1)
@ -571,7 +571,7 @@ namespace sol {
template <typename T, type t, typename = void> template <typename T, type t, typename = void>
struct unqualified_checker; struct unqualified_checker;
template <typename T, type t, typename = void> template <typename T, typename = void>
struct qualified_checker; struct qualified_checker;
template <typename T, typename = void> template <typename T, typename = void>
@ -709,7 +709,6 @@ namespace sol {
} }
else { else {
unqualified_getter<Tu> g {}; unqualified_getter<Tu> g {};
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
} }
} }
@ -721,7 +720,6 @@ namespace sol {
} }
else { else {
qualified_getter<T> g {}; qualified_getter<T> g {};
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
} }
} }
@ -877,7 +875,6 @@ namespace sol {
} }
else { else {
unqualified_pusher<Tu> p {}; unqualified_pusher<Tu> p {};
(void)p;
return p.push(L, std::forward<T>(t), std::forward<Args>(args)...); return p.push(L, std::forward<T>(t), std::forward<Args>(args)...);
} }
} }
@ -897,7 +894,6 @@ namespace sol {
} }
else { else {
unqualified_pusher<Tu> p {}; unqualified_pusher<Tu> p {};
(void)p;
return p.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...); return p.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
} }
} }
@ -928,7 +924,7 @@ namespace sol {
using use_reference_tag = using use_reference_tag =
meta::all< meta::all<
meta::neg<is_value_semantic_for_function<T>> meta::neg<is_value_semantic_for_function<T>>
#if SOL_IS_OFF(SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_) #if SOL_IS_OFF(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
, std::is_lvalue_reference<T>, , std::is_lvalue_reference<T>,
meta::neg<std::is_const<std::remove_reference_t<T>>>, meta::neg<std::is_const<std::remove_reference_t<T>>>,
meta::neg<is_lua_primitive<meta::unqualified_t<T>>>, meta::neg<is_lua_primitive<meta::unqualified_t<T>>>,
@ -983,9 +979,7 @@ namespace sol {
return sol_lua_check(types<Tu>(), L, index, std::forward<Handler>(handler), tracking); return sol_lua_check(types<Tu>(), L, index, std::forward<Handler>(handler), tracking);
} }
else { else {
unqualified_checker<Tu, lua_type_of_v<Tu>> c; unqualified_checker<Tu, lua_type_of_v<Tu>> c{};
// VC++ has a bad warning here: shut it up
(void)c;
return c.check(L, index, std::forward<Handler>(handler), tracking); return c.check(L, index, std::forward<Handler>(handler), tracking);
} }
} }
@ -1008,10 +1002,7 @@ namespace sol {
return sol_lua_check(types<T>(), L, index, std::forward<Handler>(handler), tracking); return sol_lua_check(types<T>(), L, index, std::forward<Handler>(handler), tracking);
} }
else { else {
using Tu = meta::unqualified_t<T>; qualified_checker<T> c{};
qualified_checker<T, lua_type_of_v<Tu>> c;
// VC++ has a bad warning here: shut it up
(void)c;
return c.check(L, index, std::forward<Handler>(handler), tracking); return c.check(L, index, std::forward<Handler>(handler), tracking);
} }
} }
@ -1065,7 +1056,6 @@ namespace sol {
} }
else { else {
unqualified_check_getter<Tu> cg {}; unqualified_check_getter<Tu> cg {};
(void)cg;
return cg.get(L, index, std::forward<Handler>(handler), tracking); return cg.get(L, index, std::forward<Handler>(handler), tracking);
} }
} }
@ -1089,7 +1079,6 @@ namespace sol {
} }
else { else {
qualified_check_getter<T> cg {}; qualified_check_getter<T> cg {};
(void)cg;
return cg.get(L, index, std::forward<Handler>(handler), tracking); return cg.get(L, index, std::forward<Handler>(handler), tracking);
} }
} }
@ -1145,7 +1134,7 @@ namespace sol {
template <typename T> template <typename T>
auto unqualified_get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get<T>(L, index, tracking)) { auto unqualified_get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get<T>(L, index, tracking)) {
#if SOL_IS_ON(SOL_SAFE_GETTER_I_) #if SOL_IS_ON(SOL_SAFE_GETTER)
static constexpr bool is_op = meta::is_optional_v<T>; static constexpr bool is_op = meta::is_optional_v<T>;
if constexpr (is_op) { if constexpr (is_op) {
return stack_detail::unchecked_unqualified_get<T>(L, index, tracking); return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
@ -1170,7 +1159,7 @@ namespace sol {
template <typename T> template <typename T>
auto get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) { auto get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
#if SOL_IS_ON(SOL_SAFE_GETTER_I_) #if SOL_IS_ON(SOL_SAFE_GETTER)
static constexpr bool is_op = meta::is_optional_v<T>; static constexpr bool is_op = meta::is_optional_v<T>;
if constexpr (is_op) { if constexpr (is_op) {
return stack_detail::unchecked_get<T>(L, index, tracking); return stack_detail::unchecked_get<T>(L, index, tracking);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -113,7 +113,17 @@ namespace sol { namespace stack {
lua_getglobal(L, &key[0]); lua_getglobal(L, &key[0]);
} }
else { else {
lua_getfield(L, tableindex, &key[0]); if constexpr (std::is_same_v<std::decay_t<Key>, const char*>) {
// Handle const char* case
if (key != nullptr) {
lua_getfield(L, tableindex, key);
} else {
push(L, lua_nil);
}
} else {
// Handle std::string case
lua_getfield(L, tableindex, key.c_str());
}
} }
} }
else if constexpr (std::is_same_v<T, meta_function>) { else if constexpr (std::is_same_v<T, meta_function>) {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -24,12 +24,15 @@
#ifndef SOL_STACK_UNQUALIFIED_GET_HPP #ifndef SOL_STACK_UNQUALIFIED_GET_HPP
#define SOL_STACK_UNQUALIFIED_GET_HPP #define SOL_STACK_UNQUALIFIED_GET_HPP
#include <sol/version.hpp>
#include <sol/stack_core.hpp> #include <sol/stack_core.hpp>
#include <sol/usertype_traits.hpp> #include <sol/usertype_traits.hpp>
#include <sol/inheritance.hpp> #include <sol/inheritance.hpp>
#include <sol/overload.hpp> #include <sol/overload.hpp>
#include <sol/error.hpp> #include <sol/error.hpp>
#include <sol/unicode.hpp> #include <sol/unicode.hpp>
#include <sol/abort.hpp>
#include <memory> #include <memory>
#include <functional> #include <functional>
@ -37,7 +40,7 @@
#include <cstdlib> #include <cstdlib>
#include <cmath> #include <cmath>
#include <string_view> #include <string_view>
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant> #include <variant>
#endif // Apple clang screwed up #endif // Apple clang screwed up
@ -169,7 +172,7 @@ namespace sol { namespace stack {
luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index)); luaL_Stream* pstream = static_cast<luaL_Stream*>(lua_touserdata(L, index));
return *pstream; return *pstream;
} }
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) { else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
return stack_detail::get_function_pointer<std::remove_pointer_t<T>>(L, index, tracking); return stack_detail::get_function_pointer<std::remove_pointer_t<T>>(L, index, tracking);
} }
@ -184,10 +187,10 @@ namespace sol { namespace stack {
struct qualified_getter { struct qualified_getter {
static decltype(auto) get(lua_State* L, int index, record& tracking) { static decltype(auto) get(lua_State* L, int index, record& tracking) {
using Tu = meta::unqualified_t<X>; using Tu = meta::unqualified_t<X>;
static constexpr bool is_userdata_of_some_kind static constexpr bool is_maybe_userdata_of_some_kind
= !std::is_reference_v< = !std::is_reference_v<
X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>; X> && is_container_v<Tu> && std::is_default_constructible_v<Tu> && !is_lua_primitive_v<Tu> && !is_transparent_argument_v<Tu>;
if constexpr (is_userdata_of_some_kind) { if constexpr (is_maybe_userdata_of_some_kind) {
if (type_of(L, index) == type::userdata) { if (type_of(L, index) == type::userdata) {
return static_cast<Tu>(stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking)); return static_cast<Tu>(stack_detail::unchecked_unqualified_get<Tu>(L, index, tracking));
} }
@ -210,11 +213,9 @@ namespace sol { namespace stack {
} }
actual r {}; actual r {};
if constexpr (!derive<element>::value) { if constexpr (!derive<element>::value) {
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_)
// In debug mode we would rather abort you for this grave failure rather // In debug mode we would rather abort you for this grave failure rather
// than let you deref a null pointer and fuck everything over // than let you deref a null pointer and fuck everything over
std::abort(); SOL_DEBUG_ABORT();
#endif
return static_cast<actual>(std::move(r)); return static_cast<actual>(std::move(r));
} }
else { else {
@ -247,11 +248,7 @@ namespace sol { namespace stack {
// uh oh.. // uh oh..
break; break;
} }
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_) SOL_DEBUG_ABORT();
// In debug mode we would rather abort you for this grave failure rather
// than let you deref a null pointer and fuck everything over
std::abort();
#endif
return static_cast<actual>(r); return static_cast<actual>(r);
} }
} }
@ -355,8 +352,8 @@ namespace sol { namespace stack {
} }
bool isnil = false; bool isnil = false;
for (int vi = 0; vi < lua_size<V>::value; ++vi) { for (int vi = 0; vi < lua_size<V>::value; ++vi) {
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VERSION_I_ >= 600 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushinteger(L, static_cast<lua_Integer>(i + vi)); lua_pushinteger(L, static_cast<lua_Integer>(i + vi));
@ -376,7 +373,7 @@ namespace sol { namespace stack {
if (i == 0) { if (i == 0) {
break; break;
} }
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VERSION_I_ >= 600 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
lua_pop(L, vi); lua_pop(L, vi);
#else #else
lua_pop(L, (vi + 1)); lua_pop(L, (vi + 1));
@ -386,7 +383,7 @@ namespace sol { namespace stack {
} }
} }
if (isnil) { if (isnil) {
#if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES_I_) && SOL_LUA_VERSION_I_ >= 600 #if SOL_IS_ON(SOL_LUA_NIL_IN_TABLES) && SOL_LUA_VERSION_I_ >= 600
#else #else
lua_pop(L, lua_size<V>::value); lua_pop(L, lua_size<V>::value);
#endif #endif
@ -404,7 +401,7 @@ namespace sol { namespace stack {
// see above comment // see above comment
goto done; goto done;
} }
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 2, detail::not_enough_stack_space_generic); luaL_checkstack(L, 2, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
bool isnil = false; bool isnil = false;
@ -443,7 +440,7 @@ namespace sol { namespace stack {
static T get(types<K, V>, lua_State* L, int relindex, record& tracking) { static T get(types<K, V>, lua_State* L, int relindex, record& tracking) {
tracking.use(1); tracking.use(1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 3, detail::not_enough_stack_space_generic); luaL_checkstack(L, 3, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
@ -486,7 +483,7 @@ namespace sol { namespace stack {
template <typename V> template <typename V>
static C get(types<V>, lua_State* L, int relindex, record& tracking) { static C get(types<V>, lua_State* L, int relindex, record& tracking) {
tracking.use(1); tracking.use(1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 3, detail::not_enough_stack_space_generic); luaL_checkstack(L, 3, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
@ -551,7 +548,7 @@ namespace sol { namespace stack {
static C get(types<K, V>, lua_State* L, int relindex, record& tracking) { static C get(types<K, V>, lua_State* L, int relindex, record& tracking) {
tracking.use(1); tracking.use(1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 3, detail::not_enough_stack_space_generic); luaL_checkstack(L, 3, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
@ -578,26 +575,20 @@ namespace sol { namespace stack {
using Tu = meta::unqualified_t<T>; using Tu = meta::unqualified_t<T>;
if constexpr (is_container_v<Tu>) { if constexpr (is_container_v<Tu>) {
if constexpr (meta::is_associative<Tu>::value) { if constexpr (meta::is_associative<Tu>::value) {
typedef typename T::value_type P; typedef typename Tu::value_type P;
typedef typename P::first_type K; typedef typename P::first_type K;
typedef typename P::second_type V; typedef typename P::second_type V;
unqualified_getter<as_table_t<T>> g; unqualified_getter<as_table_t<T>> g {};
// VC++ has a bad warning here: shut it up
(void)g;
return g.get(types<K, nested<V>>(), L, index, tracking); return g.get(types<K, nested<V>>(), L, index, tracking);
} }
else { else {
typedef typename T::value_type V; typedef typename Tu::value_type V;
unqualified_getter<as_table_t<T>> g; unqualified_getter<as_table_t<T>> g {};
// VC++ has a bad warning here: shut it up
(void)g;
return g.get(types<nested<V>>(), L, index, tracking); return g.get(types<nested<V>>(), L, index, tracking);
} }
} }
else { else {
unqualified_getter<Tu> g; unqualified_getter<Tu> g {};
// VC++ has a bad warning here: shut it up
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
} }
} }
@ -617,6 +608,20 @@ namespace sol { namespace stack {
} }
}; };
template <typename T>
struct unqualified_getter<exhaustive<T>> {
static decltype(auto) get(lua_State* arg_L, int index, record& tracking) {
return stack::get<T>(arg_L, index, tracking);
}
};
template <typename T>
struct unqualified_getter<non_exhaustive<T>> {
static decltype(auto) get(lua_State* arg_L, int index, record& tracking) {
return stack::get<T>(arg_L, index, tracking);
}
};
template <> template <>
struct unqualified_getter<userdata_value> { struct unqualified_getter<userdata_value> {
static userdata_value get(lua_State* L, int index, record& tracking) { static userdata_value get(lua_State* L, int index, record& tracking) {
@ -883,7 +888,7 @@ namespace sol { namespace stack {
struct unqualified_getter<detail::as_value_tag<T>> { struct unqualified_getter<detail::as_value_tag<T>> {
static T* get_no_lua_nil(lua_State* L, int index, record& tracking) { static T* get_no_lua_nil(lua_State* L, int index, record& tracking) {
void* memory = lua_touserdata(L, index); void* memory = lua_touserdata(L, index);
#if SOL_IS_ON(SOL_USE_INTEROP_I_) #if SOL_IS_ON(SOL_USE_INTEROP)
auto ugr = stack_detail::interop_get<T>(L, index, memory, tracking); auto ugr = stack_detail::interop_get<T>(L, index, memory, tracking);
if (ugr.first) { if (ugr.first) {
return ugr.second; return ugr.second;
@ -933,9 +938,7 @@ namespace sol { namespace stack {
tracking.use(1); tracking.use(1);
return nullptr; return nullptr;
} }
unqualified_getter<detail::as_value_tag<T>> g; unqualified_getter<detail::as_value_tag<T>> g{};
// Avoid VC++ warning
(void)g;
return g.get_no_lua_nil(L, index, tracking); return g.get_no_lua_nil(L, index, tracking);
} }
}; };
@ -943,9 +946,7 @@ namespace sol { namespace stack {
template <typename T> template <typename T>
struct unqualified_getter<non_null<T*>> { struct unqualified_getter<non_null<T*>> {
static T* get(lua_State* L, int index, record& tracking) { static T* get(lua_State* L, int index, record& tracking) {
unqualified_getter<detail::as_value_tag<T>> g; unqualified_getter<detail::as_value_tag<T>> g{};
// Avoid VC++ warning
(void)g;
return g.get_no_lua_nil(L, index, tracking); return g.get_no_lua_nil(L, index, tracking);
} }
}; };
@ -953,9 +954,7 @@ namespace sol { namespace stack {
template <typename T> template <typename T>
struct unqualified_getter<T&> { struct unqualified_getter<T&> {
static T& get(lua_State* L, int index, record& tracking) { static T& get(lua_State* L, int index, record& tracking) {
unqualified_getter<detail::as_value_tag<T>> g; unqualified_getter<detail::as_value_tag<T>> g{};
// Avoid VC++ warning
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
} }
}; };
@ -963,9 +962,7 @@ namespace sol { namespace stack {
template <typename T> template <typename T>
struct unqualified_getter<std::reference_wrapper<T>> { struct unqualified_getter<std::reference_wrapper<T>> {
static T& get(lua_State* L, int index, record& tracking) { static T& get(lua_State* L, int index, record& tracking) {
unqualified_getter<T&> g; unqualified_getter<T&> g{};
// Avoid VC++ warning
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
} }
}; };
@ -973,20 +970,16 @@ namespace sol { namespace stack {
template <typename T> template <typename T>
struct unqualified_getter<T*> { struct unqualified_getter<T*> {
static T* get(lua_State* L, int index, record& tracking) { static T* get(lua_State* L, int index, record& tracking) {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
if constexpr (std::is_function_v<T>) { if constexpr (std::is_function_v<T>) {
return stack_detail::get_function_pointer<T>(L, index, tracking); return stack_detail::get_function_pointer<T>(L, index, tracking);
} }
else { else {
unqualified_getter<detail::as_pointer_tag<T>> g; unqualified_getter<detail::as_pointer_tag<T>> g{};
// Avoid VC++ warning
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
} }
#else #else
unqualified_getter<detail::as_pointer_tag<T>> g; unqualified_getter<detail::as_pointer_tag<T>> g{};
// Avoid VC++ warning
(void)g;
return g.get(L, index, tracking); return g.get(L, index, tracking);
#endif #endif
} }
@ -1022,7 +1015,7 @@ namespace sol { namespace stack {
} }
}; };
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn> template <typename... Tn>
struct unqualified_getter<std::variant<Tn...>> { struct unqualified_getter<std::variant<Tn...>> {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -31,7 +31,7 @@
namespace sol { namespace sol {
namespace detail { namespace detail {
inline void stack_fail(int, int) { inline void stack_fail(int, int) {
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_ON(SOL_EXCEPTIONS)
throw error(detail::direct_error, "imbalanced stack after operation finish"); throw error(detail::direct_error, "imbalanced stack after operation finish");
#else #else
// Lol, what do you want, an error printout? :3c // Lol, what do you want, an error printout? :3c

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -91,4 +91,4 @@ namespace sol { namespace stack {
}; };
}} // namespace sol::stack }} // namespace sol::stack
#endif // SOL_STACK_PROBE_HPP #endif // SOL_STACK_PROBE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -30,6 +30,7 @@
#include <sol/usertype_traits.hpp> #include <sol/usertype_traits.hpp>
#include <sol/policies.hpp> #include <sol/policies.hpp>
#include <sol/unicode.hpp> #include <sol/unicode.hpp>
#include <sol/assert.hpp>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
@ -37,7 +38,7 @@
#include <limits> #include <limits>
#include <cmath> #include <cmath>
#include <string_view> #include <string_view>
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant> #include <variant>
#endif // Can use variant #endif // Can use variant
@ -52,7 +53,7 @@ namespace sol { namespace stack {
constexpr bool is_same_signedness constexpr bool is_same_signedness
= (std::is_signed_v<T> && std::is_signed_v<lua_Integer>) || (std::is_unsigned_v<T> && std::is_unsigned_v<lua_Integer>); = (std::is_signed_v<T> && std::is_signed_v<lua_Integer>) || (std::is_unsigned_v<T> && std::is_unsigned_v<lua_Integer>);
constexpr bool probaby_fits_within_lua_Integer = sizeof(T) == sizeof(lua_Integer) constexpr bool probaby_fits_within_lua_Integer = sizeof(T) == sizeof(lua_Integer)
#if SOL_IS_ON(SOL_ALL_INTEGER_VALUES_FIT_I_) #if SOL_IS_ON(SOL_ALL_INTEGER_VALUES_FIT)
&& ((std::has_unique_object_representations_v<T> && std::has_unique_object_representations_v<lua_Integer>) ? true : is_same_signedness) && ((std::has_unique_object_representations_v<T> && std::has_unique_object_representations_v<lua_Integer>) ? true : is_same_signedness)
#else #else
&& is_same_signedness && is_same_signedness
@ -75,7 +76,7 @@ namespace sol { namespace stack {
int msvc_is_ass_with_if_constexpr_push_enum(std::true_type, lua_State* L, const T& value) { int msvc_is_ass_with_if_constexpr_push_enum(std::true_type, lua_State* L, const T& value) {
if constexpr (meta::any_same_v<std::underlying_type_t<T>, if constexpr (meta::any_same_v<std::underlying_type_t<T>,
char char
#if SOL_IS_ON(SOL_CHAR8_T_I_) #if SOL_IS_ON(SOL_CHAR8_T)
, ,
char8_t char8_t
#endif #endif
@ -101,7 +102,7 @@ namespace sol { namespace stack {
} // namespace stack_detail } // namespace stack_detail
inline int push_environment_of(lua_State* L, int target_index = -1) { inline int push_environment_of(lua_State* L, int target_index = -1) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_environment); luaL_checkstack(L, 1, detail::not_enough_stack_space_environment);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
#if SOL_LUA_VERSION_I_ < 502 #if SOL_LUA_VERSION_I_ < 502
@ -141,14 +142,18 @@ namespace sol { namespace stack {
int push_environment_of(const T& target) { int push_environment_of(const T& target) {
lua_State* target_L = target.lua_state(); lua_State* target_L = target.lua_state();
int target_index = absolute_index(target_L, -target.push()); int target_index = absolute_index(target_L, -target.push());
return push_environment_of(target_L, target_index); int env_count = push_environment_of(target_L, target_index);
SOL_ASSERT(env_count == 1);
lua_rotate(target_L, target_index, 1);
lua_pop(target_L, 1);
return env_count;
} }
template <typename T> template <typename T>
struct unqualified_pusher<detail::as_value_tag<T>> { struct unqualified_pusher<detail::as_value_tag<T>> {
template <typename F, typename... Args> template <typename F, typename... Args>
static int push_fx(lua_State* L, F&& f, Args&&... args) { static int push_fx(lua_State* L, F&& f, Args&&... args) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
// Basically, we store all user-data like this: // Basically, we store all user-data like this:
@ -193,7 +198,7 @@ namespace sol { namespace stack {
static int push_fx(lua_State* L, F&& f, T* obj) { static int push_fx(lua_State* L, F&& f, T* obj) {
if (obj == nullptr) if (obj == nullptr)
return stack::push(L, lua_nil); return stack::push(L, lua_nil);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
T** pref = detail::usertype_allocate_pointer<T>(L); T** pref = detail::usertype_allocate_pointer<T>(L);
@ -249,7 +254,7 @@ namespace sol { namespace stack {
template <typename... Args> template <typename... Args>
static int push_deep(lua_State* L, Args&&... args) { static int push_deep(lua_State* L, Args&&... args) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
element** pointer_to_memory = nullptr; element** pointer_to_memory = nullptr;
@ -295,7 +300,7 @@ namespace sol { namespace stack {
return p[0]; return p[0];
} }
else if constexpr (std::is_same_v<Tu, bool>) { else if constexpr (std::is_same_v<Tu, bool>) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushboolean(L, std::forward<Args>(args)...); lua_pushboolean(L, std::forward<Args>(args)...);
@ -303,7 +308,7 @@ namespace sol { namespace stack {
} }
else if constexpr (std::is_integral_v<Tu> || std::is_same_v<Tu, lua_Integer>) { else if constexpr (std::is_integral_v<Tu> || std::is_same_v<Tu, lua_Integer>) {
const Tu& value(std::forward<Args>(args)...); const Tu& value(std::forward<Args>(args)...);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_integral); luaL_checkstack(L, 1, detail::not_enough_stack_space_integral);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
#if SOL_LUA_VERSION_I_ >= 503 #if SOL_LUA_VERSION_I_ >= 503
@ -312,11 +317,11 @@ namespace sol { namespace stack {
return 1; return 1;
} }
#endif // Lua 5.3 and above #endif // Lua 5.3 and above
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_) #if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) { if (static_cast<T>(llround(static_cast<lua_Number>(value))) != value) {
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
// Is this really worth it? // Is this really worth it?
assert(false && "integer value will be misrepresented in lua"); SOL_ASSERT_MSG(false, "integer value will be misrepresented in lua");
lua_pushinteger(L, static_cast<lua_Integer>(value)); lua_pushinteger(L, static_cast<lua_Integer>(value));
return 1; return 1;
#else #else
@ -328,7 +333,7 @@ namespace sol { namespace stack {
return 1; return 1;
} }
else if constexpr (std::is_floating_point_v<Tu> || std::is_same_v<Tu, lua_Number>) { else if constexpr (std::is_floating_point_v<Tu> || std::is_same_v<Tu, lua_Number>) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_floating); luaL_checkstack(L, 1, detail::not_enough_stack_space_floating);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushnumber(L, std::forward<Args>(args)...); lua_pushnumber(L, std::forward<Args>(args)...);
@ -338,7 +343,7 @@ namespace sol { namespace stack {
luaL_Stream* source { std::forward<Args>(args)... }; luaL_Stream* source { std::forward<Args>(args)... };
luaL_Stream* stream = static_cast<luaL_Stream*>(detail::alloc_newuserdata(L, sizeof(luaL_Stream))); luaL_Stream* stream = static_cast<luaL_Stream*>(detail::alloc_newuserdata(L, sizeof(luaL_Stream)));
stream->f = source->f; stream->f = source->f;
#if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_) #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION)
stream->closef = source->closef; stream->closef = source->closef;
#endif // LuaJIT and Lua 5.1 and below do not have #endif // LuaJIT and Lua 5.1 and below do not have
return 1; return 1;
@ -347,7 +352,7 @@ namespace sol { namespace stack {
luaL_Stream& source(std::forward<Args>(args)...); luaL_Stream& source(std::forward<Args>(args)...);
luaL_Stream* stream = static_cast<luaL_Stream*>(detail::alloc_newuserdata(L, sizeof(luaL_Stream))); luaL_Stream* stream = static_cast<luaL_Stream*>(detail::alloc_newuserdata(L, sizeof(luaL_Stream)));
stream->f = source.f; stream->f = source.f;
#if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_) #if SOL_IS_ON(SOL_LUAL_STREAM_USE_CLOSE_FUNCTION)
stream->closef = source.closef; stream->closef = source.closef;
#endif // LuaJIT and Lua 5.1 and below do not have #endif // LuaJIT and Lua 5.1 and below do not have
return 1; return 1;
@ -423,7 +428,7 @@ namespace sol { namespace stack {
lua_seti(L, tableindex, static_cast<lua_Integer>(index++)); lua_seti(L, tableindex, static_cast<lua_Integer>(index++));
} }
#else #else
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushinteger(L, static_cast<lua_Integer>(index)); lua_pushinteger(L, static_cast<lua_Integer>(index));
@ -436,7 +441,7 @@ namespace sol { namespace stack {
int firstindex = tableindex + 1 + 1; int firstindex = tableindex + 1 + 1;
for (int pi = 0; pi < p; ++pi) { for (int pi = 0; pi < p; ++pi) {
stack::push(L, index); stack::push(L, index);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L, firstindex); lua_pushvalue(L, firstindex);
@ -506,8 +511,6 @@ namespace sol { namespace stack {
struct unqualified_pusher<std::initializer_list<T>> { struct unqualified_pusher<std::initializer_list<T>> {
static int push(lua_State* L, const std::initializer_list<T>& il) noexcept { static int push(lua_State* L, const std::initializer_list<T>& il) noexcept {
unqualified_pusher<detail::as_table_tag<std::initializer_list<T>>> p {}; unqualified_pusher<detail::as_table_tag<std::initializer_list<T>>> p {};
// silence annoying VC++ warning
(void)p;
return p.push(L, il); return p.push(L, il);
} }
}; };
@ -515,7 +518,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<lua_nil_t> { struct unqualified_pusher<lua_nil_t> {
static int push(lua_State* L, lua_nil_t) noexcept { static int push(lua_State* L, lua_nil_t) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushnil(L); lua_pushnil(L);
@ -533,7 +536,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<metatable_key_t> { struct unqualified_pusher<metatable_key_t> {
static int push(lua_State* L, metatable_key_t) { static int push(lua_State* L, metatable_key_t) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, to_string(meta_function::metatable).c_str(), 4); lua_pushlstring(L, to_string(meta_function::metatable).c_str(), 4);
@ -544,7 +547,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<std::remove_pointer_t<lua_CFunction>> { struct unqualified_pusher<std::remove_pointer_t<lua_CFunction>> {
static int push(lua_State* L, lua_CFunction func, int n = 0) noexcept { static int push(lua_State* L, lua_CFunction func, int n = 0) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushcclosure(L, func, n); lua_pushcclosure(L, func, n);
@ -555,7 +558,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<lua_CFunction> { struct unqualified_pusher<lua_CFunction> {
static int push(lua_State* L, lua_CFunction func, int n = 0) { static int push(lua_State* L, lua_CFunction func, int n = 0) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushcclosure(L, func, n); lua_pushcclosure(L, func, n);
@ -563,11 +566,11 @@ namespace sol { namespace stack {
} }
}; };
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <> template <>
struct unqualified_pusher<std::remove_pointer_t<detail::lua_CFunction_noexcept>> { struct unqualified_pusher<std::remove_pointer_t<detail::lua_CFunction_noexcept>> {
static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) { static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushcclosure(L, func, n); lua_pushcclosure(L, func, n);
@ -578,7 +581,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<detail::lua_CFunction_noexcept> { struct unqualified_pusher<detail::lua_CFunction_noexcept> {
static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) { static int push(lua_State* L, detail::lua_CFunction_noexcept func, int n = 0) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushcclosure(L, func, n); lua_pushcclosure(L, func, n);
@ -590,7 +593,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<c_closure> { struct unqualified_pusher<c_closure> {
static int push(lua_State* L, c_closure cc) { static int push(lua_State* L, c_closure cc) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushcclosure(L, cc.c_function, cc.upvalues); lua_pushcclosure(L, cc.c_function, cc.upvalues);
@ -616,7 +619,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<void*> { struct unqualified_pusher<void*> {
static int push(lua_State* L, void* userdata) noexcept { static int push(lua_State* L, void* userdata) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, userdata); lua_pushlightuserdata(L, userdata);
@ -627,7 +630,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<const void*> { struct unqualified_pusher<const void*> {
static int push(lua_State* L, const void* userdata) noexcept { static int push(lua_State* L, const void* userdata) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, const_cast<void*>(userdata)); lua_pushlightuserdata(L, const_cast<void*>(userdata));
@ -638,7 +641,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<lightuserdata_value> { struct unqualified_pusher<lightuserdata_value> {
static int push(lua_State* L, lightuserdata_value userdata) noexcept { static int push(lua_State* L, lightuserdata_value userdata) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, userdata); lua_pushlightuserdata(L, userdata);
@ -649,10 +652,10 @@ namespace sol { namespace stack {
template <typename T> template <typename T>
struct unqualified_pusher<light<T>> { struct unqualified_pusher<light<T>> {
static int push(lua_State* L, light<T> l) noexcept { static int push(lua_State* L, light<T> l) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, static_cast<void*>(l.value)); lua_pushlightuserdata(L, static_cast<void*>(l.value()));
return 1; return 1;
} }
}; };
@ -661,14 +664,14 @@ namespace sol { namespace stack {
struct unqualified_pusher<user<T>> { struct unqualified_pusher<user<T>> {
template <bool with_meta = true, typename Key, typename... Args> template <bool with_meta = true, typename Key, typename... Args>
static int push_with(lua_State* L, Key&& name, Args&&... args) { static int push_with(lua_State* L, Key&& name, Args&&... args) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
// A dumb pusher // A dumb pusher
T* data = detail::user_allocate<T>(L); T* data = detail::user_allocate<T>(L);
if (with_meta) { if (with_meta) {
// Make sure we have a plain GC set for this data // Make sure we have a plain GC set for this data
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
if (luaL_newmetatable(L, name) != 0) { if (luaL_newmetatable(L, name) != 0) {
@ -724,7 +727,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<userdata_value> { struct unqualified_pusher<userdata_value> {
static int push(lua_State* L, userdata_value data) { static int push(lua_State* L, userdata_value data) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata); luaL_checkstack(L, 1, detail::not_enough_stack_space_userdata);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
void** ud = detail::usertype_allocate_pointer<void>(L); void** ud = detail::usertype_allocate_pointer<void>(L);
@ -736,7 +739,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<const char*> { struct unqualified_pusher<const char*> {
static int push_sized(lua_State* L, const char* str, std::size_t len) { static int push_sized(lua_State* L, const char* str, std::size_t len) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, str, len); lua_pushlstring(L, str, len);
@ -788,7 +791,7 @@ namespace sol { namespace stack {
template <size_t N> template <size_t N>
struct unqualified_pusher<char[N]> { struct unqualified_pusher<char[N]> {
static int push(lua_State* L, const char (&str)[N]) { static int push(lua_State* L, const char (&str)[N]) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, str, std::char_traits<char>::length(str)); lua_pushlstring(L, str, std::char_traits<char>::length(str));
@ -796,7 +799,7 @@ namespace sol { namespace stack {
} }
static int push(lua_State* L, const char (&str)[N], std::size_t sz) { static int push(lua_State* L, const char (&str)[N], std::size_t sz) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, str, sz); lua_pushlstring(L, str, sz);
@ -812,11 +815,11 @@ namespace sol { namespace stack {
} }
}; };
#if SOL_IS_ON(SOL_CHAR8_T_I_) #if SOL_IS_ON(SOL_CHAR8_T)
template <> template <>
struct unqualified_pusher<const char8_t*> { struct unqualified_pusher<const char8_t*> {
static int push_sized(lua_State* L, const char8_t* str, std::size_t len) { static int push_sized(lua_State* L, const char8_t* str, std::size_t len) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, reinterpret_cast<const char*>(str), len); lua_pushlstring(L, reinterpret_cast<const char*>(str), len);
@ -868,7 +871,7 @@ namespace sol { namespace stack {
template <size_t N> template <size_t N>
struct unqualified_pusher<char8_t[N]> { struct unqualified_pusher<char8_t[N]> {
static int push(lua_State* L, const char8_t (&str)[N]) { static int push(lua_State* L, const char8_t (&str)[N]) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
const char* str_as_char = reinterpret_cast<const char*>(static_cast<const char8_t*>(str)); const char* str_as_char = reinterpret_cast<const char*>(static_cast<const char8_t*>(str));
@ -877,7 +880,7 @@ namespace sol { namespace stack {
} }
static int push(lua_State* L, const char8_t (&str)[N], std::size_t sz) { static int push(lua_State* L, const char8_t (&str)[N], std::size_t sz) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, str, sz); lua_pushlstring(L, str, sz);
@ -902,7 +905,7 @@ namespace sol { namespace stack {
return stack::push(L, str.data(), str.size()); return stack::push(L, str.data(), str.size());
} }
else { else {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, str.c_str(), str.size()); lua_pushlstring(L, str.c_str(), str.size());
@ -915,7 +918,7 @@ namespace sol { namespace stack {
return stack::push(L, str.data(), sz); return stack::push(L, str.data(), sz);
} }
else { else {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_string); luaL_checkstack(L, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushlstring(L, str.c_str(), sz); lua_pushlstring(L, str.c_str(), sz);
@ -938,7 +941,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<meta_function> { struct unqualified_pusher<meta_function> {
static int push(lua_State* L, meta_function m) { static int push(lua_State* L, meta_function m) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_meta_function_name); luaL_checkstack(L, 1, detail::not_enough_stack_space_meta_function_name);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
const std::string& str = to_string(m); const std::string& str = to_string(m);
@ -950,7 +953,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<absolute_index> { struct unqualified_pusher<absolute_index> {
static int push(lua_State* L, absolute_index ai) { static int push(lua_State* L, absolute_index ai) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L, ai); lua_pushvalue(L, ai);
@ -961,7 +964,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<raw_index> { struct unqualified_pusher<raw_index> {
static int push(lua_State* L, raw_index ri) { static int push(lua_State* L, raw_index ri) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L, ri); lua_pushvalue(L, ri);
@ -972,7 +975,7 @@ namespace sol { namespace stack {
template <> template <>
struct unqualified_pusher<ref_index> { struct unqualified_pusher<ref_index> {
static int push(lua_State* L, ref_index ri) { static int push(lua_State* L, ref_index ri) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic); luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_rawgeti(L, LUA_REGISTRYINDEX, ri); lua_rawgeti(L, LUA_REGISTRYINDEX, ri);
@ -1244,7 +1247,7 @@ namespace sol { namespace stack {
struct unqualified_pusher<std::tuple<Args...>> { struct unqualified_pusher<std::tuple<Args...>> {
template <std::size_t... I, typename T> template <std::size_t... I, typename T>
static int push(std::index_sequence<I...>, lua_State* L, T&& t) { static int push(std::index_sequence<I...>, lua_State* L, T&& t) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(sizeof...(I)), detail::not_enough_stack_space_generic); luaL_checkstack(L, static_cast<int>(sizeof...(I)), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
int pushcount = 0; int pushcount = 0;
@ -1348,7 +1351,7 @@ namespace sol { namespace stack {
} }
}; };
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
namespace stack_detail { namespace stack_detail {
struct push_function { struct push_function {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -70,7 +70,7 @@ namespace sol {
stateless_stack_reference& operator=(const stateless_stack_reference&) noexcept = default; stateless_stack_reference& operator=(const stateless_stack_reference&) noexcept = default;
int push(lua_State* L_) const noexcept { int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push a single reference value"); luaL_checkstack(L_, 1, "not enough Lua stack space to push a single reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(L_, m_index); lua_pushvalue(L_, m_index);
@ -153,7 +153,7 @@ namespace sol {
} }
int i = r.stack_index(); int i = r.stack_index();
if (detail::xmovable(lua_state(), r.lua_state())) { if (detail::xmovable(lua_state(), r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_) #if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, "not enough Lua stack space to push a single reference value"); luaL_checkstack(L, 1, "not enough Lua stack space to push a single reference value");
#endif // make sure stack doesn't overflow #endif // make sure stack doesn't overflow
lua_pushvalue(r.lua_state(), r.stack_index()); lua_pushvalue(r.lua_state(), r.stack_index());

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -31,7 +31,7 @@
#include <sol/object.hpp> #include <sol/object.hpp>
#include <sol/lua_value.hpp> #include <sol/lua_value.hpp>
#if SOL_IS_ON(SOL_PRINT_ERRORS_I_) #if SOL_IS_ON(SOL_PRINT_ERRORS)
#include <iostream> #include <iostream>
#endif #endif
@ -51,7 +51,7 @@ namespace sol {
} }
inline int default_at_panic(lua_State* L) { inline int default_at_panic(lua_State* L) {
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
(void)L; (void)L;
return -1; return -1;
#else #else
@ -60,7 +60,7 @@ namespace sol {
if (message) { if (message) {
std::string err(message, messagesize); std::string err(message, messagesize);
lua_settop(L, 0); lua_settop(L, 0);
#if SOL_IS_ON(SOL_PRINT_ERRORS_I_) #if SOL_IS_ON(SOL_PRINT_ERRORS)
std::cerr << "[sol2] An error occurred and panic has been invoked: "; std::cerr << "[sol2] An error occurred and panic has been invoked: ";
std::cerr << err; std::cerr << err;
std::cerr << std::endl; std::cerr << std::endl;
@ -85,7 +85,7 @@ namespace sol {
const string_view& traceback = maybetraceback.value(); const string_view& traceback = maybetraceback.value();
msg.assign(traceback.data(), traceback.size()); msg.assign(traceback.data(), traceback.size());
} }
#if SOL_IS_ON(SOL_PRINT_ERRORS_I_) #if SOL_IS_ON(SOL_PRINT_ERRORS)
// std::cerr << "[sol2] An error occurred and was caught in traceback: "; // std::cerr << "[sol2] An error occurred and was caught in traceback: ";
// std::cerr << msg; // std::cerr << msg;
// std::cerr << std::endl; // std::cerr << std::endl;
@ -120,7 +120,7 @@ namespace sol {
std::string err = "sol: "; std::string err = "sol: ";
err += to_string(result.status()); err += to_string(result.status());
err += " error"; err += " error";
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) #if SOL_IS_ON(SOL_EXCEPTIONS)
std::exception_ptr eptr = std::current_exception(); std::exception_ptr eptr = std::current_exception();
if (eptr) { if (eptr) {
err += " with a "; err += " with a ";
@ -149,7 +149,7 @@ namespace sol {
string_view serr = stack::unqualified_get<string_view>(L, result.stack_index()); string_view serr = stack::unqualified_get<string_view>(L, result.stack_index());
err.append(serr.data(), serr.size()); err.append(serr.data(), serr.size());
} }
#if SOL_IS_ON(SOL_PRINT_ERRORS_I_) #if SOL_IS_ON(SOL_PRINT_ERRORS)
std::cerr << "[sol2] An error occurred and has been passed to an error handler: "; std::cerr << "[sol2] An error occurred and has been passed to an error handler: ";
std::cerr << err; std::cerr << err;
std::cerr << std::endl; std::cerr << std::endl;
@ -165,7 +165,7 @@ namespace sol {
if (towards != 0) { if (towards != 0) {
lua_rotate(L, top, towards); lua_rotate(L, top, towards);
} }
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
return result; return result;
#else #else
// just throw our error // just throw our error
@ -174,7 +174,7 @@ namespace sol {
} }
inline protected_function_result script_default_on_error(lua_State* L, protected_function_result pfr) { inline protected_function_result script_default_on_error(lua_State* L, protected_function_result pfr) {
#if SOL_IS_ON(SOL_DEFAULT_PASS_ON_ERROR_I_) #if SOL_IS_ON(SOL_DEFAULT_PASS_ON_ERROR)
return script_pass_on_error(L, std::move(pfr)); return script_pass_on_error(L, std::move(pfr));
#else #else
return script_throw_on_error(L, std::move(pfr)); return script_throw_on_error(L, std::move(pfr));

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -129,7 +129,7 @@ namespace sol {
for (auto&& library : libraries) { for (auto&& library : libraries) {
switch (library) { switch (library) {
#if SOL_LUA_VERSION_I_ <= 501 && SOL_IS_ON(SOL_USE_LUAJIT_I_) #if SOL_LUA_VERSION_I_ <= 501 && SOL_IS_ON(SOL_USE_LUAJIT)
case lib::coroutine: case lib::coroutine:
#endif // luajit opens coroutine base stuff #endif // luajit opens coroutine base stuff
case lib::base: case lib::base:
@ -140,7 +140,7 @@ namespace sol {
luaL_requiref(L, "package", luaopen_package, 1); luaL_requiref(L, "package", luaopen_package, 1);
lua_pop(L, 1); lua_pop(L, 1);
break; break;
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_) #if SOL_IS_OFF(SOL_USE_LUAJIT)
case lib::coroutine: case lib::coroutine:
#if SOL_LUA_VERSION_I_ > 501 #if SOL_LUA_VERSION_I_ > 501
luaL_requiref(L, "coroutine", luaopen_coroutine, 1); luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
@ -161,10 +161,10 @@ namespace sol {
lua_pop(L, 1); lua_pop(L, 1);
break; break;
case lib::bit32: case lib::bit32:
#if SOL_IS_ON(SOL_USE_LUAJIT_I_) #if SOL_IS_ON(SOL_USE_LUAJIT)
luaL_requiref(L, "bit32", luaopen_bit, 1); luaL_requiref(L, "bit32", luaopen_bit, 1);
lua_pop(L, 1); lua_pop(L, 1);
#elif SOL_IS_ON(SOL_LUA_BIT32_LIB_I_) #elif SOL_IS_ON(SOL_LUA_BIT32_LIB)
luaL_requiref(L, "bit32", luaopen_bit32, 1); luaL_requiref(L, "bit32", luaopen_bit32, 1);
lua_pop(L, 1); lua_pop(L, 1);
#else #else
@ -183,19 +183,19 @@ namespace sol {
lua_pop(L, 1); lua_pop(L, 1);
break; break;
case lib::utf8: case lib::utf8:
#if SOL_LUA_VERSION_I_ > 502 && SOL_IS_OFF(SOL_USE_LUAJIT_I_) #if SOL_LUA_VERSION_I_ > 502 && SOL_IS_OFF(SOL_USE_LUAJIT)
luaL_requiref(L, "utf8", luaopen_utf8, 1); luaL_requiref(L, "utf8", luaopen_utf8, 1);
lua_pop(L, 1); lua_pop(L, 1);
#endif // Lua 5.3+ only #endif // Lua 5.3+ only
break; break;
case lib::ffi: case lib::ffi:
#if SOL_IS_ON(SOL_USE_LUAJIT_I_) && SOL_IS_OFF(SOL_LUAJIT_FFI_DISABLED_I_) #if SOL_IS_ON(SOL_USE_LUAJIT) && SOL_IS_OFF(SOL_LUAJIT_FFI_DISABLED)
luaL_requiref(L, "ffi", luaopen_ffi, 1); luaL_requiref(L, "ffi", luaopen_ffi, 1);
lua_pop(L, 1); lua_pop(L, 1);
#endif // LuaJIT only #endif // LuaJIT only
break; break;
case lib::jit: case lib::jit:
#if SOL_IS_ON(SOL_USE_LUAJIT_I_) #if SOL_IS_ON(SOL_USE_LUAJIT)
luaL_requiref(L, "jit", luaopen_jit, 0); luaL_requiref(L, "jit", luaopen_jit, 0);
lua_pop(L, 1); lua_pop(L, 1);
#endif // LuaJIT Only #endif // LuaJIT Only
@ -551,7 +551,7 @@ namespace sol {
return safe_script_file(filename, env, script_default_on_error, mode); return safe_script_file(filename, env, script_default_on_error, mode);
} }
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) #if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
protected_function_result script( protected_function_result script(
lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) { lua_Reader reader, void* data, const std::string& chunkname = detail::default_chunk_name(), load_mode mode = load_mode::any) {
return safe_script(reader, data, chunkname, mode); return safe_script(reader, data, chunkname, mode);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -1,116 +1,116 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_TABLE_HPP #ifndef SOL_TABLE_HPP
#define SOL_TABLE_HPP #define SOL_TABLE_HPP
#include <sol/table_core.hpp> #include <sol/table_core.hpp>
#include <sol/lua_table.hpp> #include <sol/lua_table.hpp>
#include <sol/usertype.hpp> #include <sol/usertype.hpp>
namespace sol { namespace sol {
typedef table_core<false> table; typedef table_core<false> table;
template <bool is_global, typename base_type> template <bool is_global, typename base_type>
template <typename Class, typename Key> template <typename Class, typename Key>
usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key) { usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key) {
constant_automagic_enrollments<> enrollments {}; constant_automagic_enrollments<> enrollments {};
return this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments)); return this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments));
} }
template <bool is_global, typename base_type> template <bool is_global, typename base_type>
template <typename Class, typename Key, automagic_flags enrollment_flags> template <typename Class, typename Key, automagic_flags enrollment_flags>
usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, constant_automagic_enrollments<enrollment_flags> enrollments) { usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, constant_automagic_enrollments<enrollment_flags> enrollments) {
int mt_index = u_detail::register_usertype<Class, enrollment_flags>(this->lua_state(), std::move(enrollments)); int mt_index = u_detail::register_usertype<Class, enrollment_flags>(this->lua_state(), std::move(enrollments));
usertype<Class> mt(this->lua_state(), -mt_index); usertype<Class> mt(this->lua_state(), -mt_index);
lua_pop(this->lua_state(), 1); lua_pop(this->lua_state(), 1);
set(std::forward<Key>(key), mt); set(std::forward<Key>(key), mt);
return mt; return mt;
} }
template <bool is_global, typename base_type> template <bool is_global, typename base_type>
template <typename Class, typename Key> template <typename Class, typename Key>
usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, automagic_enrollments enrollments) { usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, automagic_enrollments enrollments) {
int mt_index = u_detail::register_usertype<Class, automagic_flags::all>(this->lua_state(), std::move(enrollments)); int mt_index = u_detail::register_usertype<Class, automagic_flags::all>(this->lua_state(), std::move(enrollments));
usertype<Class> mt(this->lua_state(), -mt_index); usertype<Class> mt(this->lua_state(), -mt_index);
lua_pop(this->lua_state(), 1); lua_pop(this->lua_state(), 1);
set(std::forward<Key>(key), mt); set(std::forward<Key>(key), mt);
return mt; return mt;
} }
template <bool is_global, typename base_type> template <bool is_global, typename base_type>
template <typename Class, typename Key, typename Arg, typename... Args, typename> template <typename Class, typename Key, typename Arg, typename... Args, typename>
usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, Arg&& arg, Args&&... args) { usertype<Class> basic_table_core<is_global, base_type>::new_usertype(Key&& key, Arg&& arg, Args&&... args) {
constexpr automagic_flags enrollment_flags = meta::any_same_v<no_construction, meta::unqualified_t<Arg>, meta::unqualified_t<Args>...> constexpr automagic_flags enrollment_flags = meta::any_same_v<no_construction, meta::unqualified_t<Arg>, meta::unqualified_t<Args>...>
? clear_flags(automagic_flags::all, automagic_flags::default_constructor) ? clear_flags(automagic_flags::all, automagic_flags::default_constructor)
: automagic_flags::all; : automagic_flags::all;
constant_automagic_enrollments<enrollment_flags> enrollments; constant_automagic_enrollments<enrollment_flags> enrollments;
enrollments.default_constructor = !detail::any_is_constructor_v<Arg, Args...>; enrollments.default_constructor = !detail::any_is_constructor_v<Arg, Args...>;
enrollments.destructor = !detail::any_is_destructor_v<Arg, Args...>; enrollments.destructor = !detail::any_is_destructor_v<Arg, Args...>;
usertype<Class> ut = this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments)); usertype<Class> ut = this->new_usertype<Class>(std::forward<Key>(key), std::move(enrollments));
static_assert(sizeof...(Args) % 2 == static_cast<std::size_t>(!detail::any_is_constructor_v<Arg>), static_assert(sizeof...(Args) % 2 == static_cast<std::size_t>(!detail::any_is_constructor_v<Arg>),
"you must pass an even number of arguments to new_usertype after first passing a constructor"); "you must pass an even number of arguments to new_usertype after first passing a constructor");
if constexpr (detail::any_is_constructor_v<Arg>) { if constexpr (detail::any_is_constructor_v<Arg>) {
ut.set(meta_function::construct, std::forward<Arg>(arg)); ut.set(meta_function::construct, std::forward<Arg>(arg));
ut.tuple_set(std::make_index_sequence<(sizeof...(Args)) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...)); ut.tuple_set(std::make_index_sequence<(sizeof...(Args)) / 2>(), std::forward_as_tuple(std::forward<Args>(args)...));
} }
else { else {
ut.tuple_set(std::make_index_sequence<(sizeof...(Args) + 1) / 2>(), std::forward_as_tuple(std::forward<Arg>(arg), std::forward<Args>(args)...)); ut.tuple_set(std::make_index_sequence<(sizeof...(Args) + 1) / 2>(), std::forward_as_tuple(std::forward<Arg>(arg), std::forward<Args>(args)...));
} }
return ut; return ut;
} }
template <typename base_type> template <typename base_type>
template <typename Key, typename Value> template <typename Key, typename Value>
basic_metatable<base_type>& basic_metatable<base_type>::set(Key&& key, Value&& value) { basic_metatable<base_type>& basic_metatable<base_type>::set(Key&& key, Value&& value) {
this->push(); this->push();
lua_State* L = this->lua_state(); lua_State* L = this->lua_state();
int target = lua_gettop(L); int target = lua_gettop(L);
optional<u_detail::usertype_storage_base&> maybe_uts = nullopt; optional<u_detail::usertype_storage_base&> maybe_uts = nullopt;
maybe_uts = u_detail::maybe_get_usertype_storage_base(L, target); maybe_uts = u_detail::maybe_get_usertype_storage_base(L, target);
if (maybe_uts) { if (maybe_uts) {
u_detail::usertype_storage_base& uts = *maybe_uts; u_detail::usertype_storage_base& uts = *maybe_uts;
uts.set(L, std::forward<Key>(key), std::forward<Value>(value)); uts.set(L, std::forward<Key>(key), std::forward<Value>(value));
return *this; return *this;
} }
else { else {
base_t::set(std::forward<Key>(key), std::forward<Value>(value)); base_t::set(std::forward<Key>(key), std::forward<Value>(value));
} }
this->pop(); this->pop();
return *this; return *this;
} }
namespace stack { namespace stack {
template <> template <>
struct unqualified_getter<metatable_key_t> { struct unqualified_getter<metatable_key_t> {
static metatable get(lua_State* L, int index = -1) { static metatable get(lua_State* L, int index = -1) {
if (lua_getmetatable(L, index) == 0) { if (lua_getmetatable(L, index) == 0) {
return metatable(L, ref_index(LUA_REFNIL)); return metatable(L, ref_index(LUA_REFNIL));
} }
return metatable(L, -1); return metatable(L, -1);
} }
}; };
} // namespace stack } // namespace stack
} // namespace sol } // namespace sol
#endif // SOL_TABLE_HPP #endif // SOL_TABLE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -330,7 +330,7 @@ namespace sol {
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_table_core(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) { basic_table_core(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
int table_index = pp.index_of(*this); int table_index = pp.index_of(*this);
constructor_handler handler {}; constructor_handler handler {};
@ -345,14 +345,14 @@ namespace sol {
} }
basic_table_core(lua_State* L, int index = -1) : basic_table_core(detail::no_safety, L, index) { basic_table_core(lua_State* L, int index = -1) : basic_table_core(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_table_core>(L, index, handler); stack::check<basic_table_core>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_table_core(lua_State* L, ref_index index) : basic_table_core(detail::no_safety, L, index) { basic_table_core(lua_State* L, ref_index index) : basic_table_core(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
int table_index = pp.index_of(*this); int table_index = pp.index_of(*this);
constructor_handler handler {}; constructor_handler handler {};
@ -364,7 +364,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<ref_t, stack_reference>>, meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_table_core>>, meta::neg<std::is_same<ref_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_table_core(T&& r) noexcept : basic_table_core(detail::no_safety, std::forward<T>(r)) { basic_table_core(T&& r) noexcept : basic_table_core(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) { if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
int table_index = pp.index_of(*this); int table_index = pp.index_of(*this);
@ -644,7 +644,7 @@ namespace sol {
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
int table_index = pp.index_of(*this); int table_index = pp.index_of(*this);
lua_State* L = base_t::lua_state(); lua_State* L = base_t::lua_state();
(void)detail::swallow { 0, (stack::set_ref(L, std::forward<Args>(args), table_index), 0)... }; (void)detail::swallow { 0, (stack::stack_detail::raw_table_set(L, std::forward<Args>(args), table_index), 0)... };
return *this; return *this;
} }

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -77,6 +77,15 @@ namespace sol {
table_proxy(Table table, T&& k) : tbl(table), key(std::forward<T>(k)) { table_proxy(Table table, T&& k) : tbl(table), key(std::forward<T>(k)) {
} }
table_proxy(const table_proxy&) = default;
table_proxy(table_proxy&&) = default;
table_proxy& operator=(const table_proxy& right) {
return set(right);
}
table_proxy& operator=(table_proxy&& right) {
return set(std::move(right));
}
template <typename T> template <typename T>
table_proxy& set(T&& item) & { table_proxy& set(T&& item) & {
tuple_set(std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>(), std::forward<T>(item)); tuple_set(std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>(), std::forward<T>(item));
@ -101,7 +110,7 @@ namespace sol {
return std::move(*this); return std::move(*this);
} }
template <typename T> template <typename T, std::enable_if_t<!std::is_same_v<meta::unqualified_t<T>, table_proxy>>* = nullptr>
table_proxy& operator=(T&& other) & { table_proxy& operator=(T&& other) & {
using Tu = meta::unwrap_unqualified_t<T>; using Tu = meta::unwrap_unqualified_t<T>;
if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu>) { if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu>) {
@ -112,7 +121,7 @@ namespace sol {
} }
} }
template <typename T> template <typename T, std::enable_if_t<!std::is_same_v<meta::unqualified_t<T>, table_proxy>>* = nullptr>
table_proxy&& operator=(T&& other) && { table_proxy&& operator=(T&& other) && {
using Tu = meta::unwrap_unqualified_t<T>; using Tu = meta::unwrap_unqualified_t<T>;
if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu> && !detail::is_msvc_callable_rigged_v<T>) { if constexpr (!is_lua_reference_or_proxy_v<Tu> && meta::is_invocable_v<Tu> && !detail::is_msvc_callable_rigged_v<T>) {
@ -133,6 +142,13 @@ namespace sol {
return std::move(*this).set(std::move(other)); return std::move(*this).set(std::move(other));
} }
template <typename T>
bool is() const {
typedef decltype(get<T>()) U;
optional<U> option = this->get<optional<U>>();
return option.has_value();
}
template <typename T> template <typename T>
decltype(auto) get() const& { decltype(auto) get() const& {
using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>; using idx_seq = std::make_index_sequence<std::tuple_size_v<meta::unqualified_t<key_type>>>;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -94,7 +94,7 @@ namespace sol {
template <typename T, template <typename T,
meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_thread>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_thread>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_thread(T&& r) : base_t(std::forward<T>(r)) { basic_thread(T&& r) : base_t(std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_thread>(lua_state(), -1, handler); stack::check<basic_thread>(lua_state(), -1, handler);
@ -106,20 +106,20 @@ namespace sol {
basic_thread& operator=(basic_thread&&) = default; basic_thread& operator=(basic_thread&&) = default;
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler> template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_thread(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) { basic_thread(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_thread>(lua_state(), -1, handler); stack::check<basic_thread>(lua_state(), -1, handler);
#endif // Safety #endif // Safety
} }
basic_thread(lua_State* L, int index = -1) : base_t(L, index) { basic_thread(lua_State* L, int index = -1) : base_t(L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_thread>(L, index, handler); stack::check<basic_thread>(L, index, handler);
#endif // Safety #endif // Safety
} }
basic_thread(lua_State* L, ref_index index) : base_t(L, index) { basic_thread(lua_State* L, ref_index index) : base_t(L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this); auto pp = stack::push_pop(*this);
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_thread>(lua_state(), -1, handler); stack::check<basic_thread>(lua_state(), -1, handler);
@ -130,7 +130,7 @@ namespace sol {
basic_thread(lua_State* L, this_state actualthread) : basic_thread(L, lua_thread_state { actualthread.L }) { basic_thread(lua_State* L, this_state actualthread) : basic_thread(L, lua_thread_state { actualthread.L }) {
} }
basic_thread(lua_State* L, lua_thread_state actualthread) : base_t(L, -stack::push(L, actualthread)) { basic_thread(lua_State* L, lua_thread_state actualthread) : base_t(L, -stack::push(L, actualthread)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_) #if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {}; constructor_handler handler {};
stack::check<basic_thread>(lua_state(), -1, handler); stack::check<basic_thread>(lua_state(), -1, handler);
#endif // Safety #endif // Safety

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -37,7 +37,7 @@
#include <array> #include <array>
#include <iterator> #include <iterator>
#include <iosfwd> #include <iosfwd>
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant> #include <variant>
#endif // variant is weird on XCode, thanks XCode #endif // variant is weird on XCode, thanks XCode
@ -479,7 +479,7 @@ namespace sol { namespace meta {
template <typename T, typename U> template <typename T, typename U>
class supports_op_less_test<T, U, void_t<decltype(std::declval<T&>() < std::declval<U&>())>> class supports_op_less_test<T, U, void_t<decltype(std::declval<T&>() < std::declval<U&>())>>
: public std::integral_constant<bool, : public std::integral_constant<bool,
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant> !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
#else #else
true true
@ -492,7 +492,7 @@ namespace sol { namespace meta {
template <typename T, typename U> template <typename T, typename U>
class supports_op_equal_test<T, U, void_t<decltype(std::declval<T&>() == std::declval<U&>())>> class supports_op_equal_test<T, U, void_t<decltype(std::declval<T&>() == std::declval<U&>())>>
: public std::integral_constant<bool, : public std::integral_constant<bool,
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant> !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
#else #else
true true
@ -505,7 +505,7 @@ namespace sol { namespace meta {
template <typename T, typename U> template <typename T, typename U>
class supports_op_less_equal_test<T, U, void_t<decltype(std::declval<T&>() <= std::declval<U&>())>> class supports_op_less_equal_test<T, U, void_t<decltype(std::declval<T&>() <= std::declval<U&>())>>
: public std::integral_constant<bool, : public std::integral_constant<bool,
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
!is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant> !is_specialization_of_v<unqualified_t<T>, std::variant> && !is_specialization_of_v<unqualified_t<U>, std::variant>
#else #else
true true
@ -530,8 +530,20 @@ namespace sol { namespace meta {
template <typename T> template <typename T>
using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>; using non_void_t = meta::conditional_t<std::is_void_v<T>, ::sol::detail::unchecked_t, T>;
template <typename T>
using detect_sentinel = typename T::sentinel;
} // namespace meta_detail } // namespace meta_detail
template <typename T, typename Fallback>
class sentinel_or {
public:
using type = detected_or_t<Fallback, meta_detail::detect_sentinel, T>;
};
template <typename T, typename Fallback>
using sentinel_or_t = typename sentinel_or<T, Fallback>::type;
template <typename T, typename U = T> template <typename T, typename U = T>
class supports_op_less : public meta_detail::supports_op_less_test<T, U> { }; class supports_op_less : public meta_detail::supports_op_less_test<T, U> { };
@ -626,11 +638,12 @@ namespace sol { namespace meta {
constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value; constexpr inline bool is_string_literal_array_of_v = is_string_literal_array_of<T, CharT>::value;
template <typename T> template <typename T>
using is_string_literal_array = boolean<std::is_array_v<T> && any_same_v<std::remove_all_extents_t<T>, char, using is_string_literal_array = boolean<std::is_array_v<T>
#if SOL_IS_ON(SOL_CHAR8_T_I_) && any_same_v<std::remove_all_extents_t<T>, char,
char8_t, #if SOL_IS_ON(SOL_CHAR8_T)
char8_t,
#endif #endif
char16_t, char32_t, wchar_t>>; char16_t, char32_t, wchar_t>>;
template <typename T> template <typename T>
constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value; constexpr inline bool is_string_literal_array_v = is_string_literal_array<T>::value;
@ -661,9 +674,8 @@ namespace sol { namespace meta {
constexpr inline bool is_string_like_v = is_string_like<T>::value; constexpr inline bool is_string_like_v = is_string_like<T>::value;
template <typename T, typename CharT = char> template <typename T, typename CharT = char>
using is_string_constructible = meta::boolean< using is_string_constructible = meta::boolean<is_string_literal_array_of_v<T, CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT>
is_string_literal_array_of_v<T, || is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT> || std::is_null_pointer_v<T>>;
CharT> || std::is_same_v<T, const CharT*> || std::is_same_v<T, CharT> || is_string_of_v<T, CharT> || std::is_same_v<T, std::initializer_list<CharT>> || is_string_view_of_v<T, CharT> || std::is_null_pointer_v<T>>;
template <typename T, typename CharT = char> template <typename T, typename CharT = char>
constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value; constexpr inline bool is_string_constructible_v = is_string_constructible<T, CharT>::value;
@ -733,7 +745,6 @@ namespace sol { namespace meta {
struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> { struct iterator_tag<T, conditional_t<false, typename std::iterator_traits<T>::iterator_category, void>> {
using type = typename std::iterator_traits<T>::iterator_category; using type = typename std::iterator_traits<T>::iterator_category;
}; };
}} // namespace sol::meta
}} // namespace sol::meta
#endif // SOL_TRAITS_HPP #endif // SOL_TRAITS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -29,7 +29,7 @@
#include <exception> #include <exception>
#include <cstring> #include <cstring>
#if SOL_IS_ON(SOL_PRINT_ERRORS_I_) #if SOL_IS_ON(SOL_PRINT_ERRORS)
#include <iostream> #include <iostream>
#endif #endif
@ -47,7 +47,7 @@ namespace sol {
// must push at least 1 object on the stack // must push at least 1 object on the stack
inline int default_exception_handler(lua_State* L, optional<const std::exception&>, string_view what) { inline int default_exception_handler(lua_State* L, optional<const std::exception&>, string_view what) {
#if SOL_IS_ON(SOL_PRINT_ERRORS_I_) #if SOL_IS_ON(SOL_PRINT_ERRORS)
std::cerr << "[sol2] An exception occurred: "; std::cerr << "[sol2] An exception occurred: ";
std::cerr.write(what.data(), static_cast<std::streamsize>(what.size())); std::cerr.write(what.data(), static_cast<std::streamsize>(what.size()));
std::cerr << std::endl; std::cerr << std::endl;
@ -72,13 +72,13 @@ namespace sol {
return exfunc(L, std::move(maybe_ex), std::move(what)); return exfunc(L, std::move(maybe_ex), std::move(what));
} }
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_) #if SOL_IS_OFF(SOL_EXCEPTIONS)
template <lua_CFunction f> template <lua_CFunction f>
int static_trampoline(lua_State* L) noexcept { int static_trampoline(lua_State* L) noexcept {
return f(L); return f(L);
} }
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <lua_CFunction_noexcept f> template <lua_CFunction_noexcept f>
int static_trampoline_noexcept(lua_State* L) noexcept { int static_trampoline_noexcept(lua_State* L) noexcept {
return f(L); return f(L);
@ -101,7 +101,7 @@ namespace sol {
#else #else
inline int lua_cfunction_trampoline(lua_State* L, lua_CFunction f) { inline int lua_cfunction_trampoline(lua_State* L, lua_CFunction f) {
#if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_) #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
return f(L); return f(L);
#else #else
try { try {
@ -116,14 +116,14 @@ namespace sol {
catch (const std::exception& e) { catch (const std::exception& e) {
call_exception_handler(L, optional<const std::exception&>(e), e.what()); call_exception_handler(L, optional<const std::exception&>(e), e.what());
} }
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_) #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
// LuaJIT cannot have the catchall when the safe propagation is on // LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors // but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones // if we don't at least catch std::exception ones
catch (...) { catch (...) {
call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception"); call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
} }
#endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it #endif
return lua_error(L); return lua_error(L);
#endif // Safe exceptions #endif // Safe exceptions
} }
@ -133,7 +133,7 @@ namespace sol {
return lua_cfunction_trampoline(L, f); return lua_cfunction_trampoline(L, f);
} }
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <lua_CFunction_noexcept f> template <lua_CFunction_noexcept f>
int static_trampoline_noexcept(lua_State* L) noexcept { int static_trampoline_noexcept(lua_State* L) noexcept {
return f(L); return f(L);
@ -151,7 +151,7 @@ namespace sol {
return f(L, std::forward<Args>(args)...); return f(L, std::forward<Args>(args)...);
} }
else { else {
#if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_) #if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
return f(L, std::forward<Args>(args)...); return f(L, std::forward<Args>(args)...);
#else #else
try { try {
@ -166,7 +166,7 @@ namespace sol {
catch (const std::exception& e) { catch (const std::exception& e) {
call_exception_handler(L, optional<const std::exception&>(e), e.what()); call_exception_handler(L, optional<const std::exception&>(e), e.what());
} }
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_) #if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
// LuaJIT cannot have the catchall when the safe propagation is on // LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors // but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones // if we don't at least catch std::exception ones
@ -187,11 +187,12 @@ namespace sol {
template <typename F, F fx> template <typename F, F fx>
inline int typed_static_trampoline(lua_State* L) { inline int typed_static_trampoline(lua_State* L) {
#if 0 #if 0
// TODO: you must evaluate the get/check_get of every // NOTE: you must evaluate the get/check_get of every
// argument, to ensure it doesn't throw // argument, to ensure it doesn't throw
// (e.g., for the sol_lua_check_access extension point!) // (e.g., for the sol_lua_check_access extension point!)
// This incluudes properly noexcept-ing all the above // This incluudes properly noexcept-ing all the above
// trampolines / safety nets // trampolines / safety nets
// This is currently not done properly because it's an enormous pain in the ass to attempt to accomplish.
if constexpr (meta::bind_traits<F>::is_noexcept) { if constexpr (meta::bind_traits<F>::is_noexcept) {
return static_trampoline_noexcept<fx>(L); return static_trampoline_noexcept<fx>(L);
} }

View file

@ -1,93 +1,93 @@
// sol2 // sol2
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to // the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // 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, // the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions: // subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all // The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software. // copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // 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 // 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 // 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. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef SOL_TUPLE_HPP #ifndef SOL_TUPLE_HPP
#define SOL_TUPLE_HPP #define SOL_TUPLE_HPP
#include <sol/forward.hpp> #include <sol/forward.hpp>
#include <sol/base_traits.hpp> #include <sol/base_traits.hpp>
#include <tuple> #include <tuple>
#include <cstddef> #include <cstddef>
namespace sol { namespace sol {
namespace detail { namespace detail {
using swallow = std::initializer_list<int>; using swallow = std::initializer_list<int>;
} // namespace detail } // namespace detail
namespace meta { namespace meta {
template <typename T> template <typename T>
using is_tuple = is_specialization_of<T, std::tuple>; using is_tuple = is_specialization_of<T, std::tuple>;
template <typename T> template <typename T>
constexpr inline bool is_tuple_v = is_tuple<T>::value; constexpr inline bool is_tuple_v = is_tuple<T>::value;
namespace detail { namespace detail {
template <typename... Args> template <typename... Args>
struct tuple_types_ { struct tuple_types_ {
typedef types<Args...> type; typedef types<Args...> type;
}; };
template <typename... Args> template <typename... Args>
struct tuple_types_<std::tuple<Args...>> { struct tuple_types_<std::tuple<Args...>> {
typedef types<Args...> type; typedef types<Args...> type;
}; };
} // namespace detail } // namespace detail
template <typename... Args> template <typename... Args>
using tuple_types = typename detail::tuple_types_<Args...>::type; using tuple_types = typename detail::tuple_types_<Args...>::type;
template <typename Arg> template <typename Arg>
struct pop_front_type; struct pop_front_type;
template <typename Arg> template <typename Arg>
using pop_front_type_t = typename pop_front_type<Arg>::type; using pop_front_type_t = typename pop_front_type<Arg>::type;
template <typename... Args> template <typename... Args>
struct pop_front_type<types<Args...>> { struct pop_front_type<types<Args...>> {
typedef void front_type; typedef void front_type;
typedef types<Args...> type; typedef types<Args...> type;
}; };
template <typename Arg, typename... Args> template <typename Arg, typename... Args>
struct pop_front_type<types<Arg, Args...>> { struct pop_front_type<types<Arg, Args...>> {
typedef Arg front_type; typedef Arg front_type;
typedef types<Args...> type; typedef types<Args...> type;
}; };
template <std::size_t N, typename Tuple> template <std::size_t N, typename Tuple>
using tuple_element = std::tuple_element<N, std::remove_reference_t<Tuple>>; using tuple_element = std::tuple_element<N, std::remove_reference_t<Tuple>>;
template <std::size_t N, typename Tuple> template <std::size_t N, typename Tuple>
using tuple_element_t = std::tuple_element_t<N, std::remove_reference_t<Tuple>>; using tuple_element_t = std::tuple_element_t<N, std::remove_reference_t<Tuple>>;
template <std::size_t N, typename Tuple> template <std::size_t N, typename Tuple>
using unqualified_tuple_element = unqualified<tuple_element_t<N, Tuple>>; using unqualified_tuple_element = unqualified<tuple_element_t<N, Tuple>>;
template <std::size_t N, typename Tuple> template <std::size_t N, typename Tuple>
using unqualified_tuple_element_t = unqualified_t<tuple_element_t<N, Tuple>>; using unqualified_tuple_element_t = unqualified_t<tuple_element_t<N, Tuple>>;
} // namespace meta } // namespace meta
} // namespace sol } // namespace sol
#endif // SOL_TUPLE_HPP #endif // SOL_TUPLE_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT) // The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors // Copyright (c) 2013-2022 Rapptz, ThePhD and contributors
// Permission is hereby granted, free of charge, to any person obtaining a copy of // 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 // this software and associated documentation files (the "Software"), to deal in
@ -39,8 +39,10 @@
#include <initializer_list> #include <initializer_list>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <limits>
#include <optional> #include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #include <memory>
#if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant> #include <variant>
#endif // variant shenanigans (thanks, Mac OSX) #endif // variant shenanigans (thanks, Mac OSX)
@ -55,7 +57,7 @@ namespace sol {
} // namespace d } // namespace d
namespace detail { namespace detail {
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_) #if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
typedef int (*lua_CFunction_noexcept)(lua_State* L) noexcept; typedef int (*lua_CFunction_noexcept)(lua_State* L) noexcept;
#else #else
typedef int (*lua_CFunction_noexcept)(lua_State* L); typedef int (*lua_CFunction_noexcept)(lua_State* L);
@ -92,7 +94,7 @@ namespace sol {
inline bool operator!=(lua_nil_t, lua_nil_t) { inline bool operator!=(lua_nil_t, lua_nil_t) {
return false; return false;
} }
#if SOL_IS_ON(SOL_NIL_I_) #if SOL_IS_ON(SOL_NIL)
using nil_t = lua_nil_t; using nil_t = lua_nil_t;
inline constexpr const nil_t& nil = lua_nil; inline constexpr const nil_t& nil = lua_nil;
#endif #endif
@ -465,6 +467,63 @@ namespace sol {
return as_container_t<T>(std::forward<T>(value)); return as_container_t<T>(std::forward<T>(value));
} }
template <typename T, std::size_t Limit = 15>
struct exhaustive_until : private detail::ebco<T> {
private:
using base_t = detail::ebco<T>;
public:
using base_t::base_t;
using base_t::value;
operator std::add_pointer_t<std::remove_reference_t<T>>() {
return std::addressof(this->base_t::value());
}
operator std::add_pointer_t<std::add_const_t<std::remove_reference_t<T>>>() const {
return std::addressof(this->base_t::value());
}
operator std::add_lvalue_reference_t<T>() {
return this->base_t::value();
}
operator std::add_const_t<std::add_lvalue_reference_t<T>>&() const {
return this->base_t::value();
}
};
template <typename T>
using exhaustive = exhaustive_until<T, (std::numeric_limits<size_t>::max)()>;
template <typename T>
struct non_exhaustive : private detail::ebco<T> {
private:
using base_t = detail::ebco<T>;
public:
using base_t::base_t;
using base_t::value;
operator std::add_pointer_t<std::remove_reference_t<T>>() {
return std::addressof(this->base_t::value());
}
operator std::add_pointer_t<std::add_const_t<std::remove_reference_t<T>>>() const {
return std::addressof(this->base_t::value());
}
operator std::add_lvalue_reference_t<T>() {
return this->base_t::value();
}
operator std::add_const_t<std::add_lvalue_reference_t<T>>&() const {
return this->base_t::value();
}
};
template <typename T> template <typename T>
struct push_invoke_t : private detail::ebco<T> { struct push_invoke_t : private detail::ebco<T> {
private: private:
@ -658,7 +717,7 @@ namespace sol {
enum class type : int { enum class type : int {
none = LUA_TNONE, none = LUA_TNONE,
lua_nil = LUA_TNIL, lua_nil = LUA_TNIL,
#if SOL_IS_ON(SOL_NIL_I_) #if SOL_IS_ON(SOL_NIL)
nil = lua_nil, nil = lua_nil,
#endif // Objective C/C++ Keyword that's found in OSX SDK and OBJC -- check for all forms to protect #endif // Objective C/C++ Keyword that's found in OSX SDK and OBJC -- check for all forms to protect
string = LUA_TSTRING, string = LUA_TSTRING,
@ -932,7 +991,7 @@ namespace sol {
template <std::size_t N> template <std::size_t N>
struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> { }; struct lua_type_of<wchar_t[N]> : std::integral_constant<type, type::string> { };
#if SOL_IS_ON(SOL_CHAR8_T_I_) #if SOL_IS_ON(SOL_CHAR8_T)
template <std::size_t N> template <std::size_t N>
struct lua_type_of<char8_t[N]> : std::integral_constant<type, type::string> { }; struct lua_type_of<char8_t[N]> : std::integral_constant<type, type::string> { };
#endif #endif
@ -949,7 +1008,7 @@ namespace sol {
template <> template <>
struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> { }; struct lua_type_of<wchar_t> : std::integral_constant<type, type::string> { };
#if SOL_IS_ON(SOL_CHAR8_T_I_) #if SOL_IS_ON(SOL_CHAR8_T)
template <> template <>
struct lua_type_of<char8_t> : std::integral_constant<type, type::string> { }; struct lua_type_of<char8_t> : std::integral_constant<type, type::string> { };
#endif #endif
@ -966,7 +1025,7 @@ namespace sol {
template <> template <>
struct lua_type_of<const wchar_t*> : std::integral_constant<type, type::string> { }; struct lua_type_of<const wchar_t*> : std::integral_constant<type, type::string> { };
#if SOL_IS_ON(SOL_CHAR8_T_I_) #if SOL_IS_ON(SOL_CHAR8_T)
template <> template <>
struct lua_type_of<const char8_t*> : std::integral_constant<type, type::string> { }; struct lua_type_of<const char8_t*> : std::integral_constant<type, type::string> { };
#endif #endif
@ -1115,7 +1174,7 @@ namespace sol {
template <> template <>
struct lua_type_of<type> : std::integral_constant<type, type::poly> { }; struct lua_type_of<type> : std::integral_constant<type, type::poly> { };
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_) #if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
template <typename T> template <typename T>
struct lua_type_of<T*> : std::integral_constant<type, std::is_function_v<T> ? type::function : type::userdata> { }; struct lua_type_of<T*> : std::integral_constant<type, std::is_function_v<T> ? type::function : type::userdata> { };
#else #else
@ -1136,7 +1195,7 @@ namespace sol {
template <> template <>
struct lua_type_of<meta_function> : std::integral_constant<type, type::string> { }; struct lua_type_of<meta_function> : std::integral_constant<type, type::string> { };
#if SOL_IS_ON(SOL_STD_VARIANT_I_) #if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn> template <typename... Tn>
struct lua_type_of<std::variant<Tn...>> : std::integral_constant<type, type::poly> { }; struct lua_type_of<std::variant<Tn...>> : std::integral_constant<type, type::poly> { };
#endif // std::variant deployment sucks on Clang #endif // std::variant deployment sucks on Clang
@ -1193,19 +1252,21 @@ namespace sol {
} // namespace detail } // namespace detail
template <typename T> template <typename T>
struct is_lua_primitive struct is_lua_primitive : std::integral_constant<bool,
: std::integral_constant<bool, type::userdata != lua_type_of_v<T> // cf
type::userdata || ((type::userdata == lua_type_of_v<T>) // cf
!= lua_type_of_v< &&meta::meta_detail::has_internal_marker_v<lua_type_of<T>> // cf
T> || ((type::userdata == lua_type_of_v<T>)&&meta::meta_detail::has_internal_marker_v<lua_type_of<T>> && !meta::meta_detail::has_internal_marker_v<lua_size<T>>) && !meta::meta_detail::has_internal_marker_v<lua_size<T>>) // cf
|| is_lua_reference_or_proxy_v<T> || meta::is_specialization_of_v<T, std::tuple> || meta::is_specialization_of_v<T, std::pair>> { }; || is_lua_reference_or_proxy_v<T> // cf
|| meta::is_specialization_of_v<T, std::tuple> // cf
|| meta::is_specialization_of_v<T, std::pair>> { };
template <typename T> template <typename T>
constexpr inline bool is_lua_primitive_v = is_lua_primitive<T>::value; constexpr inline bool is_lua_primitive_v = is_lua_primitive<T>::value;
template <typename T> template <typename T>
struct is_value_semantic_for_function struct is_value_semantic_for_function
#if SOL_IS_ON(SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_) #if SOL_IS_ON(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
: std::true_type { : std::true_type {
}; };
#else #else
@ -1360,7 +1421,7 @@ namespace sol {
template <typename T> template <typename T>
struct is_automagical struct is_automagical
: std::integral_constant<bool, : std::integral_constant<bool,
(SOL_IS_ON(SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_)) (SOL_IS_ON(SOL_DEFAULT_AUTOMAGICAL_USERTYPES))
|| (std::is_array_v< || (std::is_array_v<
meta::unqualified_t<T>> || (!std::is_same_v<meta::unqualified_t<T>, state> && !std::is_same_v<meta::unqualified_t<T>, state_view>))> { meta::unqualified_t<T>> || (!std::is_same_v<meta::unqualified_t<T>, state> && !std::is_same_v<meta::unqualified_t<T>, state_view>))> {
}; };

View file

@ -1,308 +1,308 @@
#pragma once #pragma once
#include <sol/string_view.hpp> #include <sol/string_view.hpp>
#include <array> #include <array>
#include <cstring> #include <cstring>
namespace sol { namespace sol {
// Everything here was lifted pretty much straight out of // Everything here was lifted pretty much straight out of
// ogonek, because fuck figuring it out= // ogonek, because fuck figuring it out=
namespace unicode { namespace unicode {
enum class error_code { enum class error_code {
ok = 0, ok = 0,
invalid_code_point, invalid_code_point,
invalid_code_unit, invalid_code_unit,
invalid_leading_surrogate, invalid_leading_surrogate,
invalid_trailing_surrogate, invalid_trailing_surrogate,
sequence_too_short, sequence_too_short,
overlong_sequence, overlong_sequence,
}; };
inline const string_view& to_string(error_code ec) { inline const string_view& to_string(error_code ec) {
static const string_view storage[7] = { "ok", static const string_view storage[7] = { "ok",
"invalid code points", "invalid code points",
"invalid code unit", "invalid code unit",
"invalid leading surrogate", "invalid leading surrogate",
"invalid trailing surrogate", "invalid trailing surrogate",
"sequence too short", "sequence too short",
"overlong sequence" }; "overlong sequence" };
return storage[static_cast<std::size_t>(ec)]; return storage[static_cast<std::size_t>(ec)];
} }
template <typename It> template <typename It>
struct decoded_result { struct decoded_result {
error_code error; error_code error;
char32_t codepoint; char32_t codepoint;
It next; It next;
}; };
template <typename C> template <typename C>
struct encoded_result { struct encoded_result {
error_code error; error_code error;
std::size_t code_units_size; std::size_t code_units_size;
std::array<C, 4> code_units; std::array<C, 4> code_units;
}; };
struct unicode_detail { struct unicode_detail {
// codepoint related // codepoint related
static constexpr char32_t last_code_point = 0x10FFFF; static constexpr char32_t last_code_point = 0x10FFFF;
static constexpr char32_t first_lead_surrogate = 0xD800; static constexpr char32_t first_lead_surrogate = 0xD800;
static constexpr char32_t last_lead_surrogate = 0xDBFF; static constexpr char32_t last_lead_surrogate = 0xDBFF;
static constexpr char32_t first_trail_surrogate = 0xDC00; static constexpr char32_t first_trail_surrogate = 0xDC00;
static constexpr char32_t last_trail_surrogate = 0xDFFF; static constexpr char32_t last_trail_surrogate = 0xDFFF;
static constexpr char32_t first_surrogate = first_lead_surrogate; static constexpr char32_t first_surrogate = first_lead_surrogate;
static constexpr char32_t last_surrogate = last_trail_surrogate; static constexpr char32_t last_surrogate = last_trail_surrogate;
static constexpr bool is_lead_surrogate(char32_t u) { static constexpr bool is_lead_surrogate(char32_t u) {
return u >= first_lead_surrogate && u <= last_lead_surrogate; return u >= first_lead_surrogate && u <= last_lead_surrogate;
} }
static constexpr bool is_trail_surrogate(char32_t u) { static constexpr bool is_trail_surrogate(char32_t u) {
return u >= first_trail_surrogate && u <= last_trail_surrogate; return u >= first_trail_surrogate && u <= last_trail_surrogate;
} }
static constexpr bool is_surrogate(char32_t u) { static constexpr bool is_surrogate(char32_t u) {
return u >= first_surrogate && u <= last_surrogate; return u >= first_surrogate && u <= last_surrogate;
} }
// utf8 related // utf8 related
static constexpr auto last_1byte_value = 0x7Fu; static constexpr auto last_1byte_value = 0x7Fu;
static constexpr auto last_2byte_value = 0x7FFu; static constexpr auto last_2byte_value = 0x7FFu;
static constexpr auto last_3byte_value = 0xFFFFu; static constexpr auto last_3byte_value = 0xFFFFu;
static constexpr auto start_2byte_mask = 0x80u; static constexpr auto start_2byte_mask = 0x80u;
static constexpr auto start_3byte_mask = 0xE0u; static constexpr auto start_3byte_mask = 0xE0u;
static constexpr auto start_4byte_mask = 0xF0u; static constexpr auto start_4byte_mask = 0xF0u;
static constexpr auto continuation_mask = 0xC0u; static constexpr auto continuation_mask = 0xC0u;
static constexpr auto continuation_signature = 0x80u; static constexpr auto continuation_signature = 0x80u;
static constexpr bool is_invalid(unsigned char b) { static constexpr bool is_invalid(unsigned char b) {
return b == 0xC0 || b == 0xC1 || b > 0xF4; return b == 0xC0 || b == 0xC1 || b > 0xF4;
} }
static constexpr bool is_continuation(unsigned char b) { static constexpr bool is_continuation(unsigned char b) {
return (b & unicode_detail::continuation_mask) == unicode_detail::continuation_signature; return (b & unicode_detail::continuation_mask) == unicode_detail::continuation_signature;
} }
static constexpr bool is_overlong(char32_t u, std::size_t bytes) { static constexpr bool is_overlong(char32_t u, std::size_t bytes) {
return u <= unicode_detail::last_1byte_value || (u <= unicode_detail::last_2byte_value && bytes > 2) return u <= unicode_detail::last_1byte_value || (u <= unicode_detail::last_2byte_value && bytes > 2)
|| (u <= unicode_detail::last_3byte_value && bytes > 3); || (u <= unicode_detail::last_3byte_value && bytes > 3);
} }
static constexpr int sequence_length(unsigned char b) { static constexpr int sequence_length(unsigned char b) {
return (b & start_2byte_mask) == 0 ? 1 return (b & start_2byte_mask) == 0 ? 1
: (b & start_3byte_mask) != start_3byte_mask ? 2 : (b & start_3byte_mask) != start_3byte_mask ? 2
: (b & start_4byte_mask) != start_4byte_mask ? 3 : (b & start_4byte_mask) != start_4byte_mask ? 3
: 4; : 4;
} }
static constexpr char32_t decode(unsigned char b0, unsigned char b1) { static constexpr char32_t decode(unsigned char b0, unsigned char b1) {
return (static_cast<char32_t>((b0 & 0x1Fu) << 6u) | static_cast<char32_t>(b1 & 0x3Fu)); return (static_cast<char32_t>((b0 & 0x1Fu) << 6u) | static_cast<char32_t>(b1 & 0x3Fu));
} }
static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2) { static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2) {
return static_cast<char32_t>((b0 & 0x0Fu) << 12u) | static_cast<char32_t>((b1 & 0x3Fu) << 6u) | static_cast<char32_t>(b2 & 0x3Fu); return static_cast<char32_t>((b0 & 0x0Fu) << 12u) | static_cast<char32_t>((b1 & 0x3Fu) << 6u) | static_cast<char32_t>(b2 & 0x3Fu);
} }
static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3) { static constexpr char32_t decode(unsigned char b0, unsigned char b1, unsigned char b2, unsigned char b3) {
return static_cast<char32_t>(static_cast<char32_t>((b0 & 0x07u) << 18u) | static_cast<char32_t>((b1 & 0x3F) << 12) return static_cast<char32_t>(static_cast<char32_t>((b0 & 0x07u) << 18u) | static_cast<char32_t>((b1 & 0x3F) << 12)
| static_cast<char32_t>((b2 & 0x3Fu) << 6u) | static_cast<char32_t>(b3 & 0x3Fu)); | static_cast<char32_t>((b2 & 0x3Fu) << 6u) | static_cast<char32_t>(b3 & 0x3Fu));
} }
// utf16 related // utf16 related
static constexpr char32_t last_bmp_value = 0xFFFF; static constexpr char32_t last_bmp_value = 0xFFFF;
static constexpr char32_t normalizing_value = 0x10000; static constexpr char32_t normalizing_value = 0x10000;
static constexpr int lead_surrogate_bitmask = 0xFFC00; static constexpr int lead_surrogate_bitmask = 0xFFC00;
static constexpr int trail_surrogate_bitmask = 0x3FF; static constexpr int trail_surrogate_bitmask = 0x3FF;
static constexpr int lead_shifted_bits = 10; static constexpr int lead_shifted_bits = 10;
static constexpr char32_t replacement = 0xFFFD; static constexpr char32_t replacement = 0xFFFD;
static char32_t combine_surrogates(char16_t lead, char16_t trail) { static char32_t combine_surrogates(char16_t lead, char16_t trail) {
auto hi = lead - first_lead_surrogate; auto hi = lead - first_lead_surrogate;
auto lo = trail - first_trail_surrogate; auto lo = trail - first_trail_surrogate;
return normalizing_value + ((hi << lead_shifted_bits) | lo); return normalizing_value + ((hi << lead_shifted_bits) | lo);
} }
}; };
inline encoded_result<char> code_point_to_utf8(char32_t codepoint) { inline encoded_result<char> code_point_to_utf8(char32_t codepoint) {
encoded_result<char> er; encoded_result<char> er;
er.error = error_code::ok; er.error = error_code::ok;
if (codepoint <= unicode_detail::last_1byte_value) { if (codepoint <= unicode_detail::last_1byte_value) {
er.code_units_size = 1; er.code_units_size = 1;
er.code_units = std::array<char, 4> { { static_cast<char>(codepoint) } }; er.code_units = std::array<char, 4> { { static_cast<char>(codepoint) } };
} }
else if (codepoint <= unicode_detail::last_2byte_value) { else if (codepoint <= unicode_detail::last_2byte_value) {
er.code_units_size = 2; er.code_units_size = 2;
er.code_units = std::array<char, 4> { { er.code_units = std::array<char, 4> { {
static_cast<char>(0xC0 | ((codepoint & 0x7C0) >> 6)), static_cast<char>(0xC0 | ((codepoint & 0x7C0) >> 6)),
static_cast<char>(0x80 | (codepoint & 0x3F)), static_cast<char>(0x80 | (codepoint & 0x3F)),
} }; } };
} }
else if (codepoint <= unicode_detail::last_3byte_value) { else if (codepoint <= unicode_detail::last_3byte_value) {
er.code_units_size = 3; er.code_units_size = 3;
er.code_units = std::array<char, 4> { { er.code_units = std::array<char, 4> { {
static_cast<char>(0xE0 | ((codepoint & 0xF000) >> 12)), static_cast<char>(0xE0 | ((codepoint & 0xF000) >> 12)),
static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)), static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)),
static_cast<char>(0x80 | (codepoint & 0x3F)), static_cast<char>(0x80 | (codepoint & 0x3F)),
} }; } };
} }
else { else {
er.code_units_size = 4; er.code_units_size = 4;
er.code_units = std::array<char, 4> { { er.code_units = std::array<char, 4> { {
static_cast<char>(0xF0 | ((codepoint & 0x1C0000) >> 18)), static_cast<char>(0xF0 | ((codepoint & 0x1C0000) >> 18)),
static_cast<char>(0x80 | ((codepoint & 0x3F000) >> 12)), static_cast<char>(0x80 | ((codepoint & 0x3F000) >> 12)),
static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)), static_cast<char>(0x80 | ((codepoint & 0xFC0) >> 6)),
static_cast<char>(0x80 | (codepoint & 0x3F)), static_cast<char>(0x80 | (codepoint & 0x3F)),
} }; } };
} }
return er; return er;
} }
inline encoded_result<char16_t> code_point_to_utf16(char32_t codepoint) { inline encoded_result<char16_t> code_point_to_utf16(char32_t codepoint) {
encoded_result<char16_t> er; encoded_result<char16_t> er;
if (codepoint <= unicode_detail::last_bmp_value) { if (codepoint <= unicode_detail::last_bmp_value) {
er.code_units_size = 1; er.code_units_size = 1;
er.code_units = std::array<char16_t, 4> { { static_cast<char16_t>(codepoint) } }; er.code_units = std::array<char16_t, 4> { { static_cast<char16_t>(codepoint) } };
er.error = error_code::ok; er.error = error_code::ok;
} }
else { else {
auto normal = codepoint - unicode_detail::normalizing_value; auto normal = codepoint - unicode_detail::normalizing_value;
auto lead = unicode_detail::first_lead_surrogate + ((normal & unicode_detail::lead_surrogate_bitmask) >> unicode_detail::lead_shifted_bits); auto lead = unicode_detail::first_lead_surrogate + ((normal & unicode_detail::lead_surrogate_bitmask) >> unicode_detail::lead_shifted_bits);
auto trail = unicode_detail::first_trail_surrogate + (normal & unicode_detail::trail_surrogate_bitmask); auto trail = unicode_detail::first_trail_surrogate + (normal & unicode_detail::trail_surrogate_bitmask);
er.code_units = std::array<char16_t, 4> { { static_cast<char16_t>(lead), static_cast<char16_t>(trail) } }; er.code_units = std::array<char16_t, 4> { { static_cast<char16_t>(lead), static_cast<char16_t>(trail) } };
er.code_units_size = 2; er.code_units_size = 2;
er.error = error_code::ok; er.error = error_code::ok;
} }
return er; return er;
} }
inline encoded_result<char32_t> code_point_to_utf32(char32_t codepoint) { inline encoded_result<char32_t> code_point_to_utf32(char32_t codepoint) {
encoded_result<char32_t> er; encoded_result<char32_t> er;
er.code_units_size = 1; er.code_units_size = 1;
er.code_units[0] = codepoint; er.code_units[0] = codepoint;
er.error = error_code::ok; er.error = error_code::ok;
return er; return er;
} }
template <typename It> template <typename It>
inline decoded_result<It> utf8_to_code_point(It it, It last) { inline decoded_result<It> utf8_to_code_point(It it, It last) {
decoded_result<It> dr; decoded_result<It> dr;
if (it == last) { if (it == last) {
dr.next = it; dr.next = it;
dr.error = error_code::sequence_too_short; dr.error = error_code::sequence_too_short;
return dr; return dr;
} }
unsigned char b0 = static_cast<unsigned char>(*it); unsigned char b0 = static_cast<unsigned char>(*it);
std::size_t length = static_cast<std::size_t>(unicode_detail::sequence_length(b0)); std::size_t length = static_cast<std::size_t>(unicode_detail::sequence_length(b0));
if (length == 1) { if (length == 1) {
dr.codepoint = static_cast<char32_t>(b0); dr.codepoint = static_cast<char32_t>(b0);
dr.error = error_code::ok; dr.error = error_code::ok;
++it; ++it;
dr.next = it; dr.next = it;
return dr; return dr;
} }
if (unicode_detail::is_invalid(b0) || unicode_detail::is_continuation(b0)) { if (unicode_detail::is_invalid(b0) || unicode_detail::is_continuation(b0)) {
dr.error = error_code::invalid_code_unit; dr.error = error_code::invalid_code_unit;
dr.next = it; dr.next = it;
return dr; return dr;
} }
++it; ++it;
std::array<unsigned char, 4> b; std::array<unsigned char, 4> b;
b[0] = b0; b[0] = b0;
for (std::size_t i = 1; i < length; ++i) { for (std::size_t i = 1; i < length; ++i) {
b[i] = static_cast<unsigned char>(*it); b[i] = static_cast<unsigned char>(*it);
if (!unicode_detail::is_continuation(b[i])) { if (!unicode_detail::is_continuation(b[i])) {
dr.error = error_code::invalid_code_unit; dr.error = error_code::invalid_code_unit;
dr.next = it; dr.next = it;
return dr; return dr;
} }
++it; ++it;
} }
char32_t decoded; char32_t decoded;
switch (length) { switch (length) {
case 2: case 2:
decoded = unicode_detail::decode(b[0], b[1]); decoded = unicode_detail::decode(b[0], b[1]);
break; break;
case 3: case 3:
decoded = unicode_detail::decode(b[0], b[1], b[2]); decoded = unicode_detail::decode(b[0], b[1], b[2]);
break; break;
default: default:
decoded = unicode_detail::decode(b[0], b[1], b[2], b[3]); decoded = unicode_detail::decode(b[0], b[1], b[2], b[3]);
break; break;
} }
if (unicode_detail::is_overlong(decoded, length)) { if (unicode_detail::is_overlong(decoded, length)) {
dr.error = error_code::overlong_sequence; dr.error = error_code::overlong_sequence;
return dr; return dr;
} }
if (unicode_detail::is_surrogate(decoded) || decoded > unicode_detail::last_code_point) { if (unicode_detail::is_surrogate(decoded) || decoded > unicode_detail::last_code_point) {
dr.error = error_code::invalid_code_point; dr.error = error_code::invalid_code_point;
return dr; return dr;
} }
// then everything is fine // then everything is fine
dr.codepoint = decoded; dr.codepoint = decoded;
dr.error = error_code::ok; dr.error = error_code::ok;
dr.next = it; dr.next = it;
return dr; return dr;
} }
template <typename It> template <typename It>
inline decoded_result<It> utf16_to_code_point(It it, It last) { inline decoded_result<It> utf16_to_code_point(It it, It last) {
decoded_result<It> dr; decoded_result<It> dr;
if (it == last) { if (it == last) {
dr.next = it; dr.next = it;
dr.error = error_code::sequence_too_short; dr.error = error_code::sequence_too_short;
return dr; return dr;
} }
char16_t lead = static_cast<char16_t>(*it); char16_t lead = static_cast<char16_t>(*it);
if (!unicode_detail::is_surrogate(lead)) { if (!unicode_detail::is_surrogate(lead)) {
++it; ++it;
dr.codepoint = static_cast<char32_t>(lead); dr.codepoint = static_cast<char32_t>(lead);
dr.next = it; dr.next = it;
dr.error = error_code::ok; dr.error = error_code::ok;
return dr; return dr;
} }
if (!unicode_detail::is_lead_surrogate(lead)) { if (!unicode_detail::is_lead_surrogate(lead)) {
dr.error = error_code::invalid_leading_surrogate; dr.error = error_code::invalid_leading_surrogate;
dr.next = it; dr.next = it;
return dr; return dr;
} }
++it; ++it;
auto trail = *it; auto trail = *it;
if (!unicode_detail::is_trail_surrogate(trail)) { if (!unicode_detail::is_trail_surrogate(trail)) {
dr.error = error_code::invalid_trailing_surrogate; dr.error = error_code::invalid_trailing_surrogate;
dr.next = it; dr.next = it;
return dr; return dr;
} }
dr.codepoint = unicode_detail::combine_surrogates(lead, trail); dr.codepoint = unicode_detail::combine_surrogates(lead, trail);
dr.next = ++it; dr.next = ++it;
dr.error = error_code::ok; dr.error = error_code::ok;
return dr; return dr;
} }
template <typename It> template <typename It>
inline decoded_result<It> utf32_to_code_point(It it, It last) { inline decoded_result<It> utf32_to_code_point(It it, It last) {
decoded_result<It> dr; decoded_result<It> dr;
if (it == last) { if (it == last) {
dr.next = it; dr.next = it;
dr.error = error_code::sequence_too_short; dr.error = error_code::sequence_too_short;
return dr; return dr;
} }
dr.codepoint = static_cast<char32_t>(*it); dr.codepoint = static_cast<char32_t>(*it);
dr.next = ++it; dr.next = ++it;
dr.error = error_code::ok; dr.error = error_code::ok;
return dr; return dr;
} }
} // namespace unicode } // namespace unicode
} // namespace sol } // namespace sol

Some files were not shown because too many files have changed in this diff Show more