OpenMiner  0.0.1a
Voxel game engine
Classes | Typedefs | Functions | Variables
sol::detail Namespace Reference

Classes

struct  accumulate
 
struct  accumulate< C, v, V, T, Args... >
 
struct  accumulate_list
 
struct  accumulate_list< C, v, V, types< Args... > >
 
struct  add_destructor_tag
 
struct  as_pointer_tag
 
struct  as_reference_tag
 
struct  as_table_tag
 
struct  as_value_tag
 
struct  check_destructor_tag
 
struct  clean
 
struct  default_construct
 
struct  default_destruct
 
struct  deleter
 
struct  deprecate_type
 
struct  direct_error_tag
 
struct  filter_base_tag
 
struct  global_tag
 
struct  has_derived
 
struct  has_internal_marker
 
struct  has_internal_marker_impl
 
struct  has_internal_marker_impl< T, typename void_< typename T::SOL_INTERNAL_UNSPECIALIZED_MARKER_ >::type >
 
struct  implicit_wrapper
 
struct  in_place_of_i
 
struct  in_place_of_t
 
struct  in_place_of_tag
 
struct  inheritance
 
struct  is_constructor
 
struct  is_constructor< factory_wrapper< Args... > >
 
struct  is_constructor< filter_wrapper< F, Filters... > >
 
struct  is_constructor< protect_t< T > >
 
struct  is_container
 
struct  is_container< std::initializer_list< T > >
 
struct  is_container< T, std::enable_if_t< meta::all< meta::has_begin_end< meta::unqualified_t< T > >, meta::neg< is_initializer_list< meta::unqualified_t< T > > >, meta::neg< meta::is_string_like< meta::unqualified_t< T > > > >::value > >
 
struct  is_container< T, std::enable_if_t< meta::all< std::is_array< meta::unqualified_t< T > >, meta::neg< meta::any_same< std::remove_all_extents_t< meta::unqualified_t< T > >, char, wchar_t, char16_t, char32_t > > >::value > >
 
struct  is_container< T, std::enable_if_t< meta::is_string_like< meta::unqualified_t< T > >::value > >
 
struct  is_destructor
 
struct  is_destructor< destructor_wrapper< Fx > >
 
struct  is_initializer_list
 
struct  is_initializer_list< std::initializer_list< T > >
 
struct  is_non_factory_constructor
 
struct  is_non_factory_constructor< constructor_wrapper< Args... > >
 
struct  is_non_factory_constructor< constructors< Args... > >
 
struct  is_non_factory_constructor< no_construction >
 
struct  is_pointer_like
 
struct  is_pointer_like< std::shared_ptr< T > >
 
struct  is_pointer_like< std::unique_ptr< T, D > >
 
struct  is_speshul
 
struct  is_speshul< protected_function_result >
 
struct  is_speshul< unsafe_function_result >
 
struct  lua_type_of
 
struct  lua_type_of< as_table_t< T > >
 
struct  lua_type_of< basic_coroutine< Base > >
 
struct  lua_type_of< basic_environment< B > >
 
struct  lua_type_of< basic_function< Base, aligned > >
 
struct  lua_type_of< basic_lightuserdata< Base > >
 
struct  lua_type_of< basic_object< Base > >
 
struct  lua_type_of< basic_protected_function< Base, aligned, Handler > >
 
struct  lua_type_of< basic_reference< b > >
 
struct  lua_type_of< basic_string_view< C, T > >
 
struct  lua_type_of< basic_table_core< b, Base > >
 
struct  lua_type_of< basic_thread< Base > >
 
struct  lua_type_of< basic_userdata< Base > >
 
struct  lua_type_of< bool >
 
struct  lua_type_of< char >
 
struct  lua_type_of< char16_t >
 
struct  lua_type_of< char16_t[N]>
 
struct  lua_type_of< char32_t >
 
struct  lua_type_of< char32_t[N]>
 
struct  lua_type_of< char[N]>
 
struct  lua_type_of< const char * >
 
struct  lua_type_of< const char16_t * >
 
struct  lua_type_of< const char32_t * >
 
struct  lua_type_of< const void * >
 
struct  lua_type_of< detail::non_lua_nil_t >
 
struct  lua_type_of< env_t >
 
struct  lua_type_of< error >
 
struct  lua_type_of< light< T > >
 
struct  lua_type_of< lightuserdata_value >
 
struct  lua_type_of< lua_CFunction >
 
struct  lua_type_of< lua_nil_t >
 
struct  lua_type_of< meta_function >
 
struct  lua_type_of< metatable_t >
 
struct  lua_type_of< nested< T >, std::enable_if_t<!::sol::is_container< T >::value > >
 
struct  lua_type_of< nested< T >, std::enable_if_t<::sol::is_container< T >::value > >
 
struct  lua_type_of< new_table >
 
struct  lua_type_of< nullopt_t >
 
struct  lua_type_of< optional< T > >
 
struct  lua_type_of< stack_count >
 
struct  lua_type_of< stack_reference >
 
struct  lua_type_of< std::basic_string< C, T, A > >
 
struct  lua_type_of< std::function< Signature > >
 
struct  lua_type_of< std::initializer_list< T > >
 
struct  lua_type_of< std::nullptr_t >
 
struct  lua_type_of< std::pair< A, B > >
 
struct  lua_type_of< std::remove_pointer_t< lua_CFunction > >
 
struct  lua_type_of< std::tuple< Args... > >
 
struct  lua_type_of< T * >
 
struct  lua_type_of< T, std::enable_if_t< std::is_arithmetic< T >::value > >
 
struct  lua_type_of< T, std::enable_if_t< std::is_enum< T >::value > >
 
struct  lua_type_of< this_environment >
 
struct  lua_type_of< this_main_state >
 
struct  lua_type_of< this_state >
 
struct  lua_type_of< type >
 
struct  lua_type_of< user< T > >
 
struct  lua_type_of< userdata_value >
 
struct  lua_type_of< variadic_args >
 
struct  lua_type_of< variadic_results >
 
struct  lua_type_of< void * >
 
struct  lua_type_of< wchar_t >
 
struct  lua_type_of< wchar_t[N]>
 
struct  no_safety_tag
 
struct  non_lua_nil_t
 
struct  protected_handler
 
struct  ref_clean
 
struct  state_deleter
 
struct  tagged
 
struct  unchecked_t
 
struct  unique_usertype
 
struct  verified_tag
 
struct  void_
 
struct  yield_tag_t
 

Typedefs

using swallow = std::initializer_list< int >
 
typedef int(* lua_CFunction_noexcept) (lua_State *L)
 
template<typename... Args>
using has_constructor = meta::any< is_constructor< meta::unqualified_t< Args >>... >
 
template<typename... Args>
using has_destructor = meta::any< is_destructor< meta::unqualified_t< Args >>... >
 
using inheritance_check_function = decltype(&inheritance< void >::type_check)
 
using inheritance_cast_function = decltype(&inheritance< void >::type_cast)
 
using inheritance_unique_cast_function = decltype(&inheritance< void >::type_unique_cast< void >)
 
using unique_destructor = void(*)(void *)
 
using unique_tag = const char *
 
using typical_chunk_name_t = char[32]
 
template<typename T >
using array_return_type = std::conditional_t< std::is_array< T >::value, std::add_lvalue_reference_t< T >, T >
 

Functions

template<std::size_t I, typename Tuple >
decltype(auto) forward_get (Tuple &&tuple)
 
template<std::size_t... I, typename Tuple >
auto forward_tuple_impl (std::index_sequence< I... >, Tuple &&tuple) -> decltype(std::tuple< decltype(forward_get< I >(tuple))... >(forward_get< I >(tuple)...))
 
template<typename Tuple >
auto forward_tuple (Tuple &&tuple)
 
template<typename T >
auto unwrap (T &&item) -> decltype(std::forward< T >(item))
 
template<typename T >
Tunwrap (std::reference_wrapper< T > arg)
 
template<typename T , meta::enable< meta::neg< is_pointer_like< meta::unqualified_t< T >>>> = meta::enabler>
auto deref (T &&item) -> decltype(std::forward< T >(item))
 
template<typename T , meta::disable< is_pointer_like< meta::unqualified_t< T >>, meta::neg< std::is_pointer< meta::unqualified_t< T >>>> = meta::enabler>
auto deref_non_pointer (T &&item) -> decltype(std::forward< T >(item))
 
template<typename T >
Tptr (T &val)
 
template<typename T >
Tptr (std::reference_wrapper< T > val)
 
template<typename T >
Tptr (T *val)
 
template<typename T , typename Dx , typename... Args>
std::unique_ptr< T, Dx > make_unique_deleter (Args &&... args)
 
const char(& default_exception_handler_name ())[11]
 
int default_exception_handler (lua_State *L, optional< const std::exception &>, string_view what)
 
int call_exception_handler (lua_State *L, optional< const std::exception &> maybe_ex, string_view what)
 
template<lua_CFunction f>
int static_trampoline (lua_State *L)
 
template<lua_CFunction f>
int static_trampoline_noexcept (lua_State *L) noexcept
 
template<typename Fx , typename... Args>
int trampoline (lua_State *L, Fx &&f, Args &&... args)
 
int c_trampoline (lua_State *L, lua_CFunction f)
 
template<typename F , F fx>
int typed_static_trampoline_raw (std::true_type, lua_State *L)
 
template<typename F , F fx>
int typed_static_trampoline_raw (std::false_type, lua_State *L)
 
template<typename F , F fx>
int typed_static_trampoline (lua_State *L)
 
template<typename T >
std::string demangle_once ()
 
template<typename T >
std::string short_demangle_once ()
 
template<typename T >
const std::stringdemangle ()
 
template<typename T >
const std::stringshort_demangle ()
 
decltype(auto) base_class_check_key ()
 
decltype(auto) base_class_cast_key ()
 
decltype(auto) base_class_index_propogation_key ()
 
decltype(auto) base_class_new_index_propogation_key ()
 
bool xmovable (lua_State *leftL, lua_State *rightL)
 
const char(& default_main_thread_name ())[9]
 
template<bool b>
lua_State * pick_main_thread (lua_State *L, lua_State *backup_if_unsupported=nullptr)
 
void stack_fail (int, int)
 
void * align (std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space, std::size_t &required_space)
 
void * align (std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
 
template<typename... Args>
std::size_t aligned_space_for (void *alignment=nullptr)
 
void * align_usertype_pointer (void *ptr)
 
template<bool pre_aligned = false>
void * align_usertype_unique_destructor (void *ptr)
 
template<bool pre_aligned = false>
void * align_usertype_unique_tag (void *ptr)
 
template<typename T , bool pre_aligned = false>
void * align_usertype_unique (void *ptr)
 
template<typename T >
void * align_user (void *ptr)
 
template<typename T >
T ** usertype_allocate_pointer (lua_State *L)
 
template<typename T >
Tusertype_allocate (lua_State *L)
 
template<typename T , typename Real >
Real * usertype_unique_allocate (lua_State *L, T **&pref, unique_destructor *&dx, unique_tag *&id)
 
template<typename T >
Tuser_allocate (lua_State *L)
 
template<typename T >
int usertype_alloc_destruct (lua_State *L)
 
template<typename T >
int unique_destruct (lua_State *L)
 
template<typename T >
int user_alloc_destruct (lua_State *L)
 
template<typename T , typename Real >
void usertype_unique_alloc_destroy (void *memory)
 
template<typename T >
int cannot_destruct (lua_State *L)
 
template<typename T >
void reserve (T &, std::size_t)
 
template<typename T , typename Al >
void reserve (std::vector< T, Al > &arr, std::size_t hint)
 
template<typename T , typename Tr , typename Al >
void reserve (std::basic_string< T, Tr, Al > &arr, std::size_t hint)
 
const std::stringdefault_chunk_name ()
 
template<std::size_t N>
const char * make_chunk_name (const string_view &code, const std::string &chunkname, char(&basechunkname)[N])
 
template<std::size_t I, typename... Args, typename T >
stack_proxy get (types< Args... >, index_value< 0 >, index_value< I >, const T &fr)
 
template<std::size_t I, std::size_t N, typename Arg , typename... Args, typename T , meta::enable< meta::boolean<(N > 0)> >
stack_proxy get (types< Arg, Args... >, index_value< N >, index_value< I >, const T &fr)
 
template<typename R , typename... Args, typename F , typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
constexpr auto resolve_i (types< R(Args...)>, F &&) -> R(meta::unqualified_t< F >::*)(Args...)
 
template<typename F , typename U = meta::unqualified_t<F>>
constexpr auto resolve_f (std::true_type, F &&f) -> decltype(resolve_i(types< meta::function_signature_t< decltype(&U::operator())>>(), std::forward< F >(f)))
 
template<typename F >
constexpr void resolve_f (std::false_type, F &&)
 
template<typename F , typename U = meta::unqualified_t<F>>
constexpr auto resolve_i (types<>, F &&f) -> decltype(resolve_f(meta::has_deducible_signature< U >(), std::forward< F >(f)))
 
template<typename... Args, typename F , typename R = std::result_of_t<F&(Args...)>>
constexpr auto resolve_i (types< Args... >, F &&f) -> decltype(resolve_i(types< R(Args...)>(), std::forward< F >(f)))
 
template<typename Sig , typename C >
constexpr Sig C::* resolve_v (std::false_type, Sig C::*mem_func_ptr)
 
template<typename Sig , typename C >
constexpr Sig C::* resolve_v (std::true_type, Sig C::*mem_variable_ptr)
 
const char(& default_handler_name ())[9]
 
template<typename base_t , typename T >
basic_function< base_tforce_cast (T &p)
 
template<typename Reference , bool is_main_ref = false>
static Reference get_default_handler (lua_State *L)
 
template<typename T >
static void set_default_handler (lua_State *L, const T &ref)
 
int fail_on_newindex (lua_State *L)
 

Variables

const auto direct_error = direct_error_tag{}
 
const bool default_safe_function_calls
 
const unchecked_t unchecked = unchecked_t{}
 
const yield_tag_t yield_tag = yield_tag_t{}
 
struct sol::detail::verified_tag verified
 
struct sol::detail::global_tag global_
 
struct sol::detail::no_safety_tag no_safety
 

Typedef Documentation

§ array_return_type

template<typename T >
using sol::detail::array_return_type = typedef std::conditional_t<std::is_array<T>::value, std::add_lvalue_reference_t<T>, T>

§ has_constructor

template<typename... Args>
using sol::detail::has_constructor = typedef meta::any<is_constructor<meta::unqualified_t<Args>>...>

§ has_destructor

template<typename... Args>
using sol::detail::has_destructor = typedef meta::any<is_destructor<meta::unqualified_t<Args>>...>

§ inheritance_cast_function

using sol::detail::inheritance_cast_function = typedef decltype(&inheritance<void>::type_cast)

§ inheritance_check_function

using sol::detail::inheritance_check_function = typedef decltype(&inheritance<void>::type_check)

§ inheritance_unique_cast_function

using sol::detail::inheritance_unique_cast_function = typedef decltype(&inheritance<void>::type_unique_cast<void>)

§ lua_CFunction_noexcept

typedef int(* sol::detail::lua_CFunction_noexcept) (lua_State *L)

§ swallow

using sol::detail::swallow = typedef std::initializer_list<int>

§ typical_chunk_name_t

using sol::detail::typical_chunk_name_t = typedef char[32]

§ unique_destructor

using sol::detail::unique_destructor = typedef void (*)(void*)

§ unique_tag

using sol::detail::unique_tag = typedef const char*

Function Documentation

§ align() [1/2]

void* sol::detail::align ( std::size_t  alignment,
std::size_t  size,
void *&  ptr,
std::size_t &  space,
std::size_t &  required_space 
)
inline
7166  {
7167  // this handels arbitrary alignments...
7168  // make this into a power-of-2-only?
7169  // actually can't: this is a C++14-compatible framework,
7170  // power of 2 alignment is C++17
7171  std::uintptr_t initial = reinterpret_cast<std::uintptr_t>(ptr);
7172  std::uintptr_t offby = static_cast<std::uintptr_t>(initial % alignment);
7173  std::uintptr_t padding = (alignment - offby) % alignment;
7174  required_space += size + padding;
7175  if (space < required_space) {
7176  return nullptr;
7177  }
7178  ptr = static_cast<void*>(static_cast<char*>(ptr) + padding);
7179  space -= padding;
7180  return ptr;
7181  }
T * ptr(T *val)
Definition: sol.hpp:1872

§ align() [2/2]

void* sol::detail::align ( std::size_t  alignment,
std::size_t  size,
void *&  ptr,
std::size_t &  space 
)
inline
7183  {
7184  std::size_t required_space = 0;
7185  return align(alignment, size, ptr, space, required_space);
7186  }
T * ptr(T *val)
Definition: sol.hpp:1872
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ align_user()

template<typename T >
void* sol::detail::align_user ( void *  ptr)
inline
7279  {
7280  typedef std::integral_constant<bool,
7281 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7282  false
7283 #else
7284  (std::alignment_of<T>::value > 1)
7285 #endif
7286  >
7287  use_align;
7288  if (!use_align::value) {
7289  return ptr;
7290  }
7291  std::size_t space = (std::numeric_limits<std::size_t>::max)();
7292  return align(std::alignment_of<T>::value, sizeof(T), ptr, space);
7293  }
T * ptr(T *val)
Definition: sol.hpp:1872
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ align_usertype_pointer()

void* sol::detail::align_usertype_pointer ( void *  ptr)
inline
7200  {
7201  typedef std::integral_constant<bool,
7202 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7203  false
7204 #else
7205  (std::alignment_of<void*>::value > 1)
7206 #endif
7207  >
7208  use_align;
7209  if (!use_align::value) {
7210  return ptr;
7211  }
7212  std::size_t space = (std::numeric_limits<std::size_t>::max)();
7213  return align(std::alignment_of<void*>::value, sizeof(void*), ptr, space);
7214  }
T * ptr(T *val)
Definition: sol.hpp:1872
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ align_usertype_unique()

template<typename T , bool pre_aligned = false>
void* sol::detail::align_usertype_unique ( void *  ptr)
inline
7258  {
7259  typedef std::integral_constant<bool,
7260 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7261  false
7262 #else
7263  (std::alignment_of<T>::value > 1)
7264 #endif
7265  >
7266  use_align;
7267  if (!pre_aligned) {
7269  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(unique_tag));
7270  }
7271  if (!use_align::value) {
7272  return ptr;
7273  }
7274  std::size_t space = (std::numeric_limits<std::size_t>::max)();
7275  return align(std::alignment_of<T>::value, sizeof(T), ptr, space);
7276  }
T * ptr(T *val)
Definition: sol.hpp:1872
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183
void * align_usertype_unique_tag(void *ptr)
Definition: sol.hpp:7238
const char * unique_tag
Definition: sol.hpp:7163

§ align_usertype_unique_destructor()

template<bool pre_aligned = false>
void* sol::detail::align_usertype_unique_destructor ( void *  ptr)
inline
7217  {
7218  typedef std::integral_constant<bool,
7219 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7220  false
7221 #else
7222  (std::alignment_of<unique_destructor>::value > 1)
7223 #endif
7224  >
7225  use_align;
7226  if (!pre_aligned) {
7228  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(void*));
7229  }
7230  if (!use_align::value) {
7231  return static_cast<void*>(static_cast<void**>(ptr) + 1);
7232  }
7233  std::size_t space = (std::numeric_limits<std::size_t>::max)();
7234  return align(std::alignment_of<unique_destructor>::value, sizeof(unique_destructor), ptr, space);
7235  }
T * ptr(T *val)
Definition: sol.hpp:1872
void * align_usertype_pointer(void *ptr)
Definition: sol.hpp:7200
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183
void(*)(void *) unique_destructor
Definition: sol.hpp:7159

§ align_usertype_unique_tag()

template<bool pre_aligned = false>
void* sol::detail::align_usertype_unique_tag ( void *  ptr)
inline
7238  {
7239  typedef std::integral_constant<bool,
7240 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7241  false
7242 #else
7243  (std::alignment_of<unique_tag>::value > 1)
7244 #endif
7245  >
7246  use_align;
7247  if (!pre_aligned) {
7249  ptr = static_cast<void*>(static_cast<char*>(ptr) + sizeof(unique_destructor));
7250  }
7251  if (!use_align::value) {
7252  return ptr;
7253  }
7254  std::size_t space = (std::numeric_limits<std::size_t>::max)();
7255  return align(std::alignment_of<unique_tag>::value, sizeof(unique_tag), ptr, space);
7256  }
T * ptr(T *val)
Definition: sol.hpp:1872
void * align_usertype_unique_destructor(void *ptr)
Definition: sol.hpp:7217
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183
const char * unique_tag
Definition: sol.hpp:7163
void(*)(void *) unique_destructor
Definition: sol.hpp:7159

§ aligned_space_for()

template<typename... Args>
std::size_t sol::detail::aligned_space_for ( void *  alignment = nullptr)
inline
7189  {
7190  char* start = static_cast<char*>(alignment);
7191  auto specific_align = [&alignment](std::size_t a, std::size_t s) {
7192  std::size_t space = (std::numeric_limits<std::size_t>::max)();
7193  alignment = align(a, s, alignment, space);
7194  alignment = static_cast<void*>(static_cast<char*>(alignment) + s);
7195  };
7196  (void)detail::swallow{ int{}, (specific_align(std::alignment_of<Args>::value, sizeof(Args)), int{})... };
7197  return static_cast<char*>(alignment) - start;
7198  }
std::initializer_list< int > swallow
Definition: sol.hpp:462
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ base_class_cast_key()

decltype(auto) sol::detail::base_class_cast_key ( )
inline
6219  {
6220  static const auto& key = "class_cast";
6221  return key;
6222  }

§ base_class_check_key()

decltype(auto) sol::detail::base_class_check_key ( )
inline
6214  {
6215  static const auto& key = "class_check";
6216  return key;
6217  }

§ base_class_index_propogation_key()

decltype(auto) sol::detail::base_class_index_propogation_key ( )
inline
6224  {
6225  static const auto& key = u8"\xF0\x9F\x8C\xB2.index";
6226  return key;
6227  }
unsigned char u8

§ base_class_new_index_propogation_key()

decltype(auto) sol::detail::base_class_new_index_propogation_key ( )
inline
6229  {
6230  static const auto& key = u8"\xF0\x9F\x8C\xB2.new_index";
6231  return key;
6232  }
unsigned char u8

§ c_trampoline()

int sol::detail::c_trampoline ( lua_State *  L,
lua_CFunction  f 
)
inline
5977  {
5978  return trampoline(L, f);
5979  }
int trampoline(lua_State *L, Fx &&f, Args &&... args)
Definition: sol.hpp:5946

§ call_exception_handler()

int sol::detail::call_exception_handler ( lua_State *  L,
optional< const std::exception &>  maybe_ex,
string_view  what 
)
inline
5850  {
5851  lua_getglobal(L, default_exception_handler_name());
5852  type t = static_cast<type>(lua_type(L, -1));
5853  if (t != type::lightuserdata) {
5854  lua_pop(L, 1);
5855  return default_exception_handler(L, std::move(maybe_ex), std::move(what));
5856  }
5857  void* vfunc = lua_touserdata(L, -1);
5858  lua_pop(L, 1);
5859  if (vfunc == nullptr) {
5860  return default_exception_handler(L, std::move(maybe_ex), std::move(what));
5861  }
5862  exception_handler_function exfunc = reinterpret_cast<exception_handler_function>(vfunc);
5863  return exfunc(L, std::move(maybe_ex), std::move(what));
5864  }
type
Definition: sol.hpp:5173
int(*)(lua_State *, optional< const std::exception & >, string_view) exception_handler_function
Definition: sol.hpp:5831
int default_exception_handler(lua_State *L, optional< const std::exception &>, string_view what)
Definition: sol.hpp:5840
const char(& default_exception_handler_name())[11]
Definition: sol.hpp:5834
basic_lightuserdata< reference > lightuserdata
Definition: sol.hpp:352

§ cannot_destruct()

template<typename T >
int sol::detail::cannot_destruct ( lua_State *  L)
inline
7578  {
7579  return luaL_error(L, "cannot call the destructor for '%s': it is either hidden (protected/private) or removed with '= delete' and thusly this type is being destroyed without properly destructing, invoking undefined behavior: please bind a usertype and specify a custom destructor to define the behavior properly", detail::demangle<T>().data());
7580  }

§ default_chunk_name()

const std::string& sol::detail::default_chunk_name ( )
inline
11710  {
11711  static const std::string name = "";
11712  return name;
11713  }

§ default_exception_handler()

int sol::detail::default_exception_handler ( lua_State *  L,
optional< const std::exception &>  ,
string_view  what 
)
inline
5840  {
5841 #if defined(SOL_PRINT_ERRORS) && SOL_PRINT_ERRORS
5842  std::cerr << "[sol2] An exception occurred: ";
5843  std::cerr.write(what.data(), what.size());
5844  std::cerr << std::endl;
5845 #endif
5846  lua_pushlstring(L, what.data(), what.size());
5847  return 1;
5848  }

§ default_exception_handler_name()

const char(& sol::detail::default_exception_handler_name ( ) )[11]
inline
5834  {
5835  static const char name[11] = "sol.\xE2\x98\xA2\xE2\x98\xA2";
5836  return name;
5837  }

§ default_handler_name()

const char(& sol::detail::default_handler_name ( ) )[9]
inline
15054  {
15055  static const char name[9] = "sol.\xF0\x9F\x94\xA9";
15056  return name;
15057  }

§ default_main_thread_name()

const char(& sol::detail::default_main_thread_name ( ) )[9]
inline
6569  {
6570  static const char name[9] = "sol.\xF0\x9F\x93\x8C";
6571  return name;
6572  }

§ demangle()

template<typename T >
const std::string& sol::detail::demangle ( )
inline
6146  {
6147  static const std::string d = demangle_once<T>();
6148  return d;
6149  }

§ demangle_once()

template<typename T >
std::string sol::detail::demangle_once ( )
inline
6102  {
6103  std::string realname = ctti_get_type_name<T>();
6104  return realname;
6105  }

§ deref()

template<typename T , meta::enable< meta::neg< is_pointer_like< meta::unqualified_t< T >>>> = meta::enabler>
auto sol::detail::deref ( T &&  item) -> decltype(std::forward<T>(item))
inline
1842  {
1843  return std::forward<T>(item);
1844  }

§ deref_non_pointer()

template<typename T , meta::disable< is_pointer_like< meta::unqualified_t< T >>, meta::neg< std::is_pointer< meta::unqualified_t< T >>>> = meta::enabler>
auto sol::detail::deref_non_pointer ( T &&  item) -> decltype(std::forward<T>(item))
inline
1852  {
1853  return std::forward<T>(item);
1854  }

§ fail_on_newindex()

int sol::detail::fail_on_newindex ( lua_State *  L)
inline
20007  {
20008  return luaL_error(L, "sol: cannot modify the elements of an enumeration table");
20009  }

§ force_cast()

template<typename base_t , typename T >
basic_function<base_t> sol::detail::force_cast ( T p)
15096  {
15097  return p;
15098  }

§ forward_get()

template<std::size_t I, typename Tuple >
decltype(auto) sol::detail::forward_get ( Tuple &&  tuple)
1816  {
1817  return std::forward<meta::tuple_element_t<I, Tuple>>(std::get<I>(tuple));
1818  }

§ forward_tuple()

template<typename Tuple >
auto sol::detail::forward_tuple ( Tuple &&  tuple)
1826  {
1827  auto x = forward_tuple_impl(std::make_index_sequence<std::tuple_size<meta::unqualified_t<Tuple>>::value>(), std::forward<Tuple>(tuple));
1828  return x;
1829  }
auto forward_tuple_impl(std::index_sequence< I... >, Tuple &&tuple) -> decltype(std::tuple< decltype(forward_get< I >(tuple))... >(forward_get< I >(tuple)...))
Definition: sol.hpp:1821

§ forward_tuple_impl()

template<std::size_t... I, typename Tuple >
auto sol::detail::forward_tuple_impl ( std::index_sequence< I... >  ,
Tuple &&  tuple 
) -> decltype(std::tuple<decltype(forward_get<I>(tuple))...>(forward_get<I>(tuple)...))
1821  {
1822  return std::tuple<decltype(forward_get<I>(tuple))...>(std::move(std::get<I>(tuple))...);
1823  }

§ get() [1/2]

template<std::size_t I, typename... Args, typename T >
stack_proxy sol::detail::get ( types< Args... >  ,
index_value< 0 >  ,
index_value< I >  ,
const T fr 
)
12556  {
12557  return stack_proxy(fr.lua_state(), static_cast<int>(fr.stack_index() + I));
12558  }

§ get() [2/2]

template<std::size_t I, std::size_t N, typename Arg , typename... Args, typename T , meta::enable< meta::boolean<(N > 0)> >
stack_proxy sol::detail::get ( types< Arg, Args... >  ,
index_value< N >  ,
index_value< I >  ,
const T fr 
)
12561  {
12562  return get(types<Args...>(), index_value<N - 1>(), index_value<I + lua_size<Arg>::value>(), fr);
12563  }

§ get_default_handler()

template<typename Reference , bool is_main_ref = false>
static Reference sol::detail::get_default_handler ( lua_State *  L)
static
15101  {
15102  if (is_stack_based<Reference>::value || L == nullptr)
15103  return Reference(L, lua_nil);
15104  L = is_main_ref ? main_thread(L, L) : L;
15105  lua_getglobal(L, default_handler_name());
15106  auto pp = stack::pop_n(L, 1);
15107  return Reference(L, -1);
15108  }
lua_State * main_thread(lua_State *L, lua_State *backup_if_unsupported=nullptr)
Definition: sol.hpp:6676
const lua_nil_t lua_nil
Definition: sol.hpp:4683
push_popper_n< top_level > pop_n(lua_State *L, int x)
Definition: sol.hpp:6671
const char(& default_handler_name())[9]
Definition: sol.hpp:15054

§ make_chunk_name()

template<std::size_t N>
const char* sol::detail::make_chunk_name ( const string_view code,
const std::string chunkname,
char(&)  basechunkname[N] 
)
11716  {
11717  if (chunkname.empty()) {
11718  auto it = code.cbegin();
11719  auto e = code.cend();
11720  std::size_t i = 0;
11721  static const std::size_t n = N - 4;
11722  for (i = 0; i < n && it != e; ++i, ++it) {
11723  basechunkname[i] = *it;
11724  }
11725  if (it != e) {
11726  for (std::size_t c = 0; c < 3; ++i, ++c) {
11727  basechunkname[i] = '.';
11728  }
11729  }
11730  basechunkname[i] = '\0';
11731  return &basechunkname[0];
11732  }
11733  else {
11734  return chunkname.c_str();
11735  }
11736  }

§ make_unique_deleter()

template<typename T , typename Dx , typename... Args>
std::unique_ptr<T, Dx> sol::detail::make_unique_deleter ( Args &&...  args)
inline
4477  {
4478  return std::unique_ptr<T, Dx>(new T(std::forward<Args>(args)...));
4479  }

§ pick_main_thread()

template<bool b>
lua_State* sol::detail::pick_main_thread ( lua_State *  L,
lua_State *  backup_if_unsupported = nullptr 
)
inline
6703  {
6704  (void)L;
6705  (void)backup_if_unsupported;
6706  if (b) {
6707  return main_thread(L, backup_if_unsupported);
6708  }
6709  return L;
6710  }
lua_State * main_thread(lua_State *L, lua_State *backup_if_unsupported=nullptr)
Definition: sol.hpp:6676

§ ptr() [1/3]

template<typename T >
T* sol::detail::ptr ( T val)
inline
1862  {
1863  return std::addressof(val);
1864  }

§ ptr() [2/3]

template<typename T >
T* sol::detail::ptr ( std::reference_wrapper< T val)
inline
1867  {
1868  return std::addressof(val.get());
1869  }

§ ptr() [3/3]

template<typename T >
T* sol::detail::ptr ( T val)
inline
1872  {
1873  return val;
1874  }

§ reserve() [1/3]

template<typename T >
void sol::detail::reserve ( T ,
std::size_t   
)
7583  {
7584  }

§ reserve() [2/3]

template<typename T , typename Al >
void sol::detail::reserve ( std::vector< T, Al > &  arr,
std::size_t  hint 
)
7587  {
7588  arr.reserve(hint);
7589  }

§ reserve() [3/3]

template<typename T , typename Tr , typename Al >
void sol::detail::reserve ( std::basic_string< T, Tr, Al > &  arr,
std::size_t  hint 
)
7592  {
7593  arr.reserve(hint);
7594  }

§ resolve_f() [1/2]

template<typename F , typename U = meta::unqualified_t<F>>
constexpr auto sol::detail::resolve_f ( std::true_type  ,
F &&  f 
) -> decltype(resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f)))
inline
14298  {
14299  return resolve_i(types<meta::function_signature_t<decltype(&U::operator())>>(), std::forward<F>(f));
14300  }
typename bind_traits< Signature >::signature_type function_signature_t
Definition: sol.hpp:1035
constexpr auto resolve_i(types< Args... >, F &&f) -> decltype(resolve_i(types< R(Args...)>(), std::forward< F >(f)))
Definition: sol.hpp:14314

§ resolve_f() [2/2]

template<typename F >
constexpr void sol::detail::resolve_f ( std::false_type  ,
F &&   
)
inline
14303  {
14304  static_assert(meta::has_deducible_signature<F>::value,
14305  "Cannot use no-template-parameter call with an overloaded functor: specify the signature");
14306  }

§ resolve_i() [1/3]

template<typename R , typename... Args, typename F , typename = std::result_of_t<meta::unqualified_t<F>(Args...)>>
constexpr auto sol::detail::resolve_i ( types< R(Args...)>  ,
F &&   
) -> R (meta::unqualified_t<F>::*)(Args...)
inline
14290  {
14291  using Sig = R(Args...);
14292  typedef meta::unqualified_t<F> Fu;
14293  return static_cast<Sig Fu::*>(&Fu::operator());
14294  }

§ resolve_i() [2/3]

template<typename F , typename U = meta::unqualified_t<F>>
constexpr auto sol::detail::resolve_i ( types<>  ,
F &&  f 
) -> decltype(resolve_f(meta::has_deducible_signature<U>(), std::forward<F>(f)))
inline
14309  {
14310  return resolve_f(meta::has_deducible_signature<U>{}, std::forward<F>(f));
14311  }
constexpr void resolve_f(std::false_type, F &&)
Definition: sol.hpp:14303

§ resolve_i() [3/3]

template<typename... Args, typename F , typename R = std::result_of_t<F&(Args...)>>
constexpr auto sol::detail::resolve_i ( types< Args... >  ,
F &&  f 
) -> decltype(resolve_i(types<R(Args...)>(), std::forward<F>(f)))
inline
14314  {
14315  return resolve_i(types<R(Args...)>(), std::forward<F>(f));
14316  }
constexpr auto resolve_i(types< Args... >, F &&f) -> decltype(resolve_i(types< R(Args...)>(), std::forward< F >(f)))
Definition: sol.hpp:14314

§ resolve_v() [1/2]

template<typename Sig , typename C >
constexpr Sig C::* sol::detail::resolve_v ( std::false_type  ,
Sig C::*  mem_func_ptr 
)
inline
14319  {
14320  return mem_func_ptr;
14321  }

§ resolve_v() [2/2]

template<typename Sig , typename C >
constexpr Sig C::* sol::detail::resolve_v ( std::true_type  ,
Sig C::*  mem_variable_ptr 
)
inline
14324  {
14325  return mem_variable_ptr;
14326  }

§ set_default_handler()

template<typename T >
static void sol::detail::set_default_handler ( lua_State *  L,
const T ref 
)
static
15111  {
15112  if (L == nullptr) {
15113  return;
15114  }
15115  if (!ref.valid()) {
15116  lua_pushnil(L);
15117  lua_setglobal(L, default_handler_name());
15118  }
15119  else {
15120  ref.push(L);
15121  lua_setglobal(L, default_handler_name());
15122  }
15123  }
const char(& default_handler_name())[9]
Definition: sol.hpp:15054

§ short_demangle()

template<typename T >
const std::string& sol::detail::short_demangle ( )
inline
6152  {
6153  static const std::string d = short_demangle_once<T>();
6154  return d;
6155  }

§ short_demangle_once()

template<typename T >
std::string sol::detail::short_demangle_once ( )
inline
6108  {
6109  std::string realname = ctti_get_type_name<T>();
6110  // This isn't the most complete but it'll do for now...?
6111  static const std::array<std::string, 10> ops = {{"operator<", "operator<<", "operator<<=", "operator<=", "operator>", "operator>>", "operator>>=", "operator>=", "operator->", "operator->*"}};
6112  int level = 0;
6113  std::ptrdiff_t idx = 0;
6114  for (idx = static_cast<std::ptrdiff_t>(realname.empty() ? 0 : realname.size() - 1); idx > 0; --idx) {
6115  if (level == 0 && realname[idx] == ':') {
6116  break;
6117  }
6118  bool isleft = realname[idx] == '<';
6119  bool isright = realname[idx] == '>';
6120  if (!isleft && !isright)
6121  continue;
6122  bool earlybreak = false;
6123  for (const auto& op : ops) {
6124  std::size_t nisop = realname.rfind(op, idx);
6125  if (nisop == std::string::npos)
6126  continue;
6127  std::size_t nisopidx = idx - op.size() + 1;
6128  if (nisop == nisopidx) {
6129  idx = static_cast<std::ptrdiff_t>(nisopidx);
6130  earlybreak = true;
6131  }
6132  break;
6133  }
6134  if (earlybreak) {
6135  continue;
6136  }
6137  level += isleft ? -1 : 1;
6138  }
6139  if (idx > 0) {
6140  realname.erase(0, realname.length() < static_cast<std::size_t>(idx) ? realname.length() : idx + 1);
6141  }
6142  return realname;
6143  }

§ stack_fail()

void sol::detail::stack_fail ( int  ,
int   
)
inline
7105  {
7106 #if !(defined(SOL_NO_EXCEPTIONS) && SOL_NO_EXCEPTIONS)
7107  throw error(detail::direct_error, "imbalanced stack after operation finish");
7108 #else
7109  // Lol, what do you want, an error printout? :3c
7110  // There's no sane default here. The right way would be C-style abort(), and that's not acceptable, so
7111  // hopefully someone will register their own stack_fail thing for the `fx` parameter of stack_guard.
7112 #endif // No Exceptions
7113  }
const auto direct_error
Definition: sol.hpp:411

§ static_trampoline()

template<lua_CFunction f>
int sol::detail::static_trampoline ( lua_State *  L)
5894  {
5895 #if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
5896  return f(L);
5897 
5898 #else
5899  try {
5900  return f(L);
5901  }
5902  catch (const char* cs) {
5903  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(cs));
5904  }
5905  catch (const std::string& s) {
5906  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(s.c_str(), s.size()));
5907  }
5908  catch (const std::exception& e) {
5909  call_exception_handler(L, optional<const std::exception&>(e), e.what());
5910  }
5911 #if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
5912  // LuaJIT cannot have the catchall when the safe propagation is on
5913  // but LuaJIT will swallow all C++ errors
5914  // if we don't at least catch std::exception ones
5915  catch (...) {
5916  call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
5917  }
5918 #endif // LuaJIT cannot have the catchall, but we must catch std::exceps for it
5919  return lua_error(L);
5920 #endif // Safe exceptions
5921  }
int call_exception_handler(lua_State *L, optional< const std::exception &> maybe_ex, string_view what)
Definition: sol.hpp:5850
constexpr nullopt_t nullopt
Definition: sol.hpp:3498
basic_string_view< char > string_view
Definition: sol.hpp:1186

§ static_trampoline_noexcept()

template<lua_CFunction f>
int sol::detail::static_trampoline_noexcept ( lua_State *  L)
noexcept
5940  {
5941  return f(L);
5942  }

§ trampoline()

template<typename Fx , typename... Args>
int sol::detail::trampoline ( lua_State *  L,
Fx &&  f,
Args &&...  args 
)
5946  {
5947  if (meta::bind_traits<meta::unqualified_t<Fx>>::is_noexcept) {
5948  return f(L, std::forward<Args>(args)...);
5949  }
5950 #if defined(SOL_EXCEPTIONS_SAFE_PROPAGATION) && !defined(SOL_LUAJIT)
5951  return f(L, std::forward<Args>(args)...);
5952 #else
5953  try {
5954  return f(L, std::forward<Args>(args)...);
5955  }
5956  catch (const char* cs) {
5957  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(cs));
5958  }
5959  catch (const std::string& s) {
5960  call_exception_handler(L, optional<const std::exception&>(nullopt), string_view(s.c_str(), s.size()));
5961  }
5962  catch (const std::exception& e) {
5963  call_exception_handler(L, optional<const std::exception&>(e), e.what());
5964  }
5965 #if !defined(SOL_EXCEPTIONS_SAFE_PROPAGATION)
5966  // LuaJIT cannot have the catchall when the safe propagation is on
5967  // but LuaJIT will swallow all C++ errors
5968  // if we don't at least catch std::exception ones
5969  catch (...) {
5970  call_exception_handler(L, optional<const std::exception&>(nullopt), "caught (...) exception");
5971  }
5972 #endif
5973  return lua_error(L);
5974 #endif
5975  }
int call_exception_handler(lua_State *L, optional< const std::exception &> maybe_ex, string_view what)
Definition: sol.hpp:5850
constexpr nullopt_t nullopt
Definition: sol.hpp:3498
basic_string_view< char > string_view
Definition: sol.hpp:1186

§ typed_static_trampoline()

template<typename F , F fx>
int sol::detail::typed_static_trampoline ( lua_State *  L)
inline
5993  {
5994  return typed_static_trampoline_raw<F, fx>(std::integral_constant<bool, meta::bind_traits<F>::is_noexcept>(), L);
5995  }

§ typed_static_trampoline_raw() [1/2]

template<typename F , F fx>
int sol::detail::typed_static_trampoline_raw ( std::true_type  ,
lua_State *  L 
)
inline
5983  {
5984  return static_trampoline_noexcept<fx>(L);
5985  }

§ typed_static_trampoline_raw() [2/2]

template<typename F , F fx>
int sol::detail::typed_static_trampoline_raw ( std::false_type  ,
lua_State *  L 
)
inline
5988  {
5989  return static_trampoline<fx>(L);
5990  }

§ unique_destruct()

template<typename T >
int sol::detail::unique_destruct ( lua_State *  L)
inline
7548  {
7549  void* memory = lua_touserdata(L, 1);
7550  memory = align_usertype_unique_destructor(memory);
7551  unique_destructor& dx = *static_cast<unique_destructor*>(memory);
7552  memory = static_cast<void*>(static_cast<char*>(memory) + sizeof(unique_destructor));
7553  memory = align_usertype_unique_tag<true>(memory);
7554  memory = static_cast<void*>(static_cast<char*>(memory) + sizeof(unique_tag));
7555  (dx)(memory);
7556  return 0;
7557  }
void * align_usertype_unique_destructor(void *ptr)
Definition: sol.hpp:7217
const char * unique_tag
Definition: sol.hpp:7163
void(*)(void *) unique_destructor
Definition: sol.hpp:7159

§ unwrap() [1/2]

template<typename T >
auto sol::detail::unwrap ( T &&  item) -> decltype(std::forward<T>(item))
1832  {
1833  return std::forward<T>(item);
1834  }

§ unwrap() [2/2]

template<typename T >
T& sol::detail::unwrap ( std::reference_wrapper< T arg)
1837  {
1838  return arg.get();
1839  }

§ user_alloc_destruct()

template<typename T >
int sol::detail::user_alloc_destruct ( lua_State *  L)
inline
7560  {
7561  void* memory = lua_touserdata(L, 1);
7562  memory = align_user<T>(memory);
7563  T* data = static_cast<T*>(memory);
7564  std::allocator<T> alloc;
7565  std::allocator_traits<std::allocator<T>>::destroy(alloc, data);
7566  return 0;
7567  }

§ user_allocate()

template<typename T >
T* sol::detail::user_allocate ( lua_State *  L)
inline
7502  {
7503  typedef std::integral_constant<bool,
7504 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7505  false
7506 #else
7507  (std::alignment_of<T>::value > 1)
7508 #endif
7509  >
7510  use_align;
7511  if (!use_align::value) {
7512  T* pointer = static_cast<T*>(lua_newuserdata(L, sizeof(T)));
7513  return pointer;
7514  }
7515 
7516  static const std::size_t initial_size = aligned_space_for<T>(nullptr);
7517  static const std::size_t misaligned_size = aligned_space_for<T>(reinterpret_cast<void*>(0x1));
7518 
7519  std::size_t allocated_size = initial_size;
7520  void* unadjusted = lua_newuserdata(L, allocated_size);
7521  void* adjusted = align(std::alignment_of<T>::value, sizeof(T), unadjusted, allocated_size);
7522  if (adjusted == nullptr) {
7523  lua_pop(L, 1);
7524  // try again, add extra space for alignment padding
7525  allocated_size = misaligned_size;
7526  unadjusted = lua_newuserdata(L, allocated_size);
7527  adjusted = align(std::alignment_of<T>::value, sizeof(T), unadjusted, allocated_size);
7528  if (adjusted == nullptr) {
7529  lua_pop(L, 1);
7530  luaL_error(L, "cannot properly align memory for '%s'", detail::demangle<T>().data());
7531  }
7532  }
7533  return static_cast<T*>(adjusted);
7534  }
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ usertype_alloc_destruct()

template<typename T >
int sol::detail::usertype_alloc_destruct ( lua_State *  L)
inline
7537  {
7538  void* memory = lua_touserdata(L, 1);
7539  memory = align_usertype_pointer(memory);
7540  T** pdata = static_cast<T**>(memory);
7541  T* data = *pdata;
7542  std::allocator<T> alloc{};
7543  std::allocator_traits<std::allocator<T>>::destroy(alloc, data);
7544  return 0;
7545  }
void * align_usertype_pointer(void *ptr)
Definition: sol.hpp:7200

§ usertype_allocate()

template<typename T >
T* sol::detail::usertype_allocate ( lua_State *  L)
inline
7333  {
7334  typedef std::integral_constant<bool,
7335 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7336  false
7337 #else
7338  (std::alignment_of<T*>::value > 1 || std::alignment_of<T>::value > 1)
7339 #endif
7340  >
7341  use_align;
7342  if (!use_align::value) {
7343  T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(T)));
7344  T*& pointerreference = *pointerpointer;
7345  T* allocationtarget = reinterpret_cast<T*>(pointerpointer + 1);
7346  pointerreference = allocationtarget;
7347  return allocationtarget;
7348  }
7349 
7350  /* the assumption is that `lua_newuserdata` -- unless someone
7351  passes a specific lua_Alloc that gives us bogus, un-aligned pointers
7352  -- uses malloc, which tends to hand out more or less aligned pointers to memory
7353  (most of the time, anyhow)
7354 
7355  but it's not guaranteed, so we have to do a post-adjustment check and increase padding
7356 
7357  we do this preliminarily with compile-time stuff, to see
7358  if we strike lucky with the allocator and alignment values
7359 
7360  otherwise, we have to re-allocate the userdata and
7361  over-allocate some space for additional padding because
7362  compilers are optimized for aligned reads/writes
7363  (and clang will barf UBsan errors on us for not being aligned)
7364  */
7365  static const std::size_t initial_size = aligned_space_for<T*, T>(nullptr);
7366  static const std::size_t misaligned_size = aligned_space_for<T*, T>(reinterpret_cast<void*>(0x1));
7367 
7368  void* pointer_adjusted;
7369  void* data_adjusted;
7370  auto attempt_alloc = [](lua_State* L, std::size_t allocated_size, void*& pointer_adjusted, void*& data_adjusted) -> bool {
7371  void* adjusted = lua_newuserdata(L, allocated_size);
7372  pointer_adjusted = align(std::alignment_of<T*>::value, sizeof(T*), adjusted, allocated_size);
7373  if (pointer_adjusted == nullptr) {
7374  lua_pop(L, 1);
7375  return false;
7376  }
7377  // subtract size of what we're going to allocate there
7378  allocated_size -= sizeof(T*);
7379  adjusted = static_cast<void*>(static_cast<char*>(pointer_adjusted) + sizeof(T*));
7380  data_adjusted = align(std::alignment_of<T>::value, sizeof(T), adjusted, allocated_size);
7381  if (data_adjusted == nullptr) {
7382  lua_pop(L, 1);
7383  return false;
7384  }
7385  return true;
7386  };
7387  bool result = attempt_alloc(L, initial_size, pointer_adjusted, data_adjusted);
7388  if (!result) {
7389  // we're likely to get something that fails to perform the proper allocation a second time,
7390  // so we use the suggested_new_size bump to help us out here
7391  pointer_adjusted = nullptr;
7392  data_adjusted = nullptr;
7393  result = attempt_alloc(L, misaligned_size, pointer_adjusted, data_adjusted);
7394  if (!result) {
7395  if (pointer_adjusted == nullptr) {
7396  luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
7397  }
7398  else {
7399  luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
7400  }
7401  return nullptr;
7402  }
7403  }
7404 
7405  T** pointerpointer = reinterpret_cast<T**>(pointer_adjusted);
7406  T*& pointerreference = *pointerpointer;
7407  T* allocationtarget = reinterpret_cast<T*>(data_adjusted);
7408  pointerreference = allocationtarget;
7409  return allocationtarget;
7410  }
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ usertype_allocate_pointer()

template<typename T >
T** sol::detail::usertype_allocate_pointer ( lua_State *  L)
inline
7296  {
7297  typedef std::integral_constant<bool,
7298 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7299  false
7300 #else
7301  (std::alignment_of<T*>::value > 1)
7302 #endif
7303  >
7304  use_align;
7305  if (!use_align::value) {
7306  T** pointerpointer = static_cast<T**>(lua_newuserdata(L, sizeof(T*)));
7307  return pointerpointer;
7308  }
7309  static const std::size_t initial_size = aligned_space_for<T*>(nullptr);
7310  static const std::size_t misaligned_size = aligned_space_for<T*>(reinterpret_cast<void*>(0x1));
7311 
7312  std::size_t allocated_size = initial_size;
7313  void* unadjusted = lua_newuserdata(L, initial_size);
7314  void* adjusted = align(std::alignment_of<T*>::value, sizeof(T*), unadjusted, allocated_size);
7315  if (adjusted == nullptr) {
7316  lua_pop(L, 1);
7317  // what kind of absolute garbage trash allocator are we dealing with?
7318  // whatever, add some padding in the case of MAXIMAL alignment waste...
7319  allocated_size = misaligned_size;
7320  unadjusted = lua_newuserdata(L, allocated_size);
7321  adjusted = align(std::alignment_of<T*>::value, sizeof(T*), unadjusted, allocated_size);
7322  if (adjusted == nullptr) {
7323  // trash allocator can burn in hell
7324  lua_pop(L, 1);
7325  //luaL_error(L, "if you are the one that wrote this allocator you should feel bad for doing a worse job than malloc/realloc and should go read some books, yeah?");
7326  luaL_error(L, "cannot properly align memory for '%s'", detail::demangle<T*>().data());
7327  }
7328  }
7329  return static_cast<T**>(adjusted);
7330  }
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183

§ usertype_unique_alloc_destroy()

template<typename T , typename Real >
void sol::detail::usertype_unique_alloc_destroy ( void *  memory)
inline
7570  {
7571  memory = align_usertype_unique<Real, true>(memory);
7572  Real* target = static_cast<Real*>(memory);
7573  std::allocator<Real> alloc;
7574  std::allocator_traits<std::allocator<Real>>::destroy(alloc, target);
7575  }

§ usertype_unique_allocate()

template<typename T , typename Real >
Real* sol::detail::usertype_unique_allocate ( lua_State *  L,
T **&  pref,
unique_destructor *&  dx,
unique_tag *&  id 
)
inline
7413  {
7414  typedef std::integral_constant<bool,
7415 #if defined(SOL_NO_MEMORY_ALIGNMENT) && SOL_NO_MEMORY_ALIGNMENT
7416  false
7417 #else
7418  (std::alignment_of<T*>::value > 1 || std::alignment_of<unique_tag>::value > 1 || std::alignment_of<unique_destructor>::value > 1 || std::alignment_of<Real>::value > 1)
7419 #endif
7420  >
7421  use_align;
7422  if (!use_align::value) {
7423  pref = static_cast<T**>(lua_newuserdata(L, sizeof(T*) + sizeof(detail::unique_destructor) + sizeof(unique_tag) + sizeof(Real)));
7424  dx = static_cast<detail::unique_destructor*>(static_cast<void*>(pref + 1));
7425  id = static_cast<unique_tag*>(static_cast<void*>(dx + 1));
7426  Real* mem = static_cast<Real*>(static_cast<void*>(id + 1));
7427  return mem;
7428  }
7429 
7430  static const std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>(nullptr);
7431  static const std::size_t misaligned_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>(reinterpret_cast<void*>(0x1));
7432 
7433  void* pointer_adjusted;
7434  void* dx_adjusted;
7435  void* id_adjusted;
7436  void* data_adjusted;
7437  auto attempt_alloc = [](lua_State* L, std::size_t allocated_size, void*& pointer_adjusted, void*& dx_adjusted, void*& id_adjusted, void*& data_adjusted) -> bool {
7438  void* adjusted = lua_newuserdata(L, allocated_size);
7439  pointer_adjusted = align(std::alignment_of<T*>::value, sizeof(T*), adjusted, allocated_size);
7440  if (pointer_adjusted == nullptr) {
7441  lua_pop(L, 1);
7442  return false;
7443  }
7444  allocated_size -= sizeof(T*);
7445 
7446  adjusted = static_cast<void*>(static_cast<char*>(pointer_adjusted) + sizeof(T*));
7447  dx_adjusted = align(std::alignment_of<unique_destructor>::value, sizeof(unique_destructor), adjusted, allocated_size);
7448  if (dx_adjusted == nullptr) {
7449  lua_pop(L, 1);
7450  return false;
7451  }
7452  allocated_size -= sizeof(unique_destructor);
7453 
7454  adjusted = static_cast<void*>(static_cast<char*>(dx_adjusted) + sizeof(unique_destructor));
7455 
7456  id_adjusted = align(std::alignment_of<unique_tag>::value, sizeof(unique_tag), adjusted, allocated_size);
7457  if (id_adjusted == nullptr) {
7458  lua_pop(L, 1);
7459  return false;
7460  }
7461  allocated_size -= sizeof(unique_tag);
7462 
7463  adjusted = static_cast<void*>(static_cast<char*>(id_adjusted) + sizeof(unique_tag));
7464  data_adjusted = align(std::alignment_of<Real>::value, sizeof(Real), adjusted, allocated_size);
7465  if (data_adjusted == nullptr) {
7466  lua_pop(L, 1);
7467  return false;
7468  }
7469  return true;
7470  };
7471  bool result = attempt_alloc(L, initial_size, pointer_adjusted, dx_adjusted, id_adjusted, data_adjusted);
7472  if (!result) {
7473  // we're likely to get something that fails to perform the proper allocation a second time,
7474  // so we use the suggested_new_size bump to help us out here
7475  pointer_adjusted = nullptr;
7476  dx_adjusted = nullptr;
7477  id_adjusted = nullptr;
7478  data_adjusted = nullptr;
7479  result = attempt_alloc(L, misaligned_size, pointer_adjusted, dx_adjusted, id_adjusted, data_adjusted);
7480  if (!result) {
7481  if (pointer_adjusted == nullptr) {
7482  luaL_error(L, "aligned allocation of userdata block (pointer section) for '%s' failed", detail::demangle<T>().c_str());
7483  }
7484  else if (dx_adjusted == nullptr) {
7485  luaL_error(L, "aligned allocation of userdata block (deleter section) for '%s' failed", detail::demangle<T>().c_str());
7486  }
7487  else {
7488  luaL_error(L, "aligned allocation of userdata block (data section) for '%s' failed", detail::demangle<T>().c_str());
7489  }
7490  return nullptr;
7491  }
7492  }
7493 
7494  pref = static_cast<T**>(pointer_adjusted);
7495  dx = static_cast<detail::unique_destructor*>(dx_adjusted);
7496  id = static_cast<unique_tag*>(id_adjusted);
7497  Real* mem = static_cast<Real*>(data_adjusted);
7498  return mem;
7499  }
void * align(std::size_t alignment, std::size_t size, void *&ptr, std::size_t &space)
Definition: sol.hpp:7183
const char * unique_tag
Definition: sol.hpp:7163
void(*)(void *) unique_destructor
Definition: sol.hpp:7159

§ xmovable()

bool sol::detail::xmovable ( lua_State *  leftL,
lua_State *  rightL 
)
inline
6435  {
6436  if (rightL == nullptr || leftL == nullptr || leftL == rightL) {
6437  return false;
6438  }
6439  const void* leftregistry = lua_topointer(leftL, LUA_REGISTRYINDEX);
6440  const void* rightregistry = lua_topointer(rightL, LUA_REGISTRYINDEX);
6441  return leftregistry == rightregistry;
6442  }

Variable Documentation

§ default_safe_function_calls

const bool sol::detail::default_safe_function_calls
Initial value:
=
false

§ direct_error

const auto sol::detail::direct_error = direct_error_tag{}

§ global_

struct sol::detail::global_tag sol::detail::global_

§ no_safety

struct sol::detail::no_safety_tag sol::detail::no_safety

§ unchecked

const unchecked_t sol::detail::unchecked = unchecked_t{}

§ verified

struct sol::detail::verified_tag sol::detail::verified

§ yield_tag

const yield_tag_t sol::detail::yield_tag = yield_tag_t{}