mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
77901bb654
get turned into getter<T>, matches pusher<T> and uses same semantics as std::allocator and other things used throughout the codebase ----- userdata has its traits defined outside in new file of userdata to prevent errors when trying to use those typetraits in places before userdata.hpp gets included userdata was changed to support returning itself via pointers or references. rework of stack changes semantics based on T&, T*, and T&& (the last one tries to create a new userdata and move in data) solves problems maybe presented in https://github.com/Rapptz/sol/issues/25 ----- container.hpp is attempt at solving original problem before going on wild tangent with userdata, stack, and get is going to attempt to use userdata to allow transporation of containers losslessly, perhaps without copying need ----- found out trying to return a std::function does not work -- not sure what do exactly? perhaps should push c closure as last thing, but right now it is tied to a key value (code comes from table.hpp and set_function) will just have to think over how stack arranges itself and learn what to do
208 lines
7.1 KiB
C++
208 lines
7.1 KiB
C++
// The MIT License (MIT)
|
|
|
|
// Copyright (c) 2013 Danny Y., Rapptz
|
|
|
|
// 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_TRAITS_HPP
|
|
#define SOL_TRAITS_HPP
|
|
|
|
#include "tuple.hpp"
|
|
#include <type_traits>
|
|
|
|
namespace sol {
|
|
template<class T, class...>
|
|
struct are_same : std::true_type { };
|
|
|
|
template<class T, class U, class... Args>
|
|
struct are_same<T, U, Args...> : std::integral_constant <bool, std::is_same<T, U>::value && are_same<T, Args...>::value> { };
|
|
|
|
template<bool B>
|
|
using Bool = std::integral_constant<bool, B>;
|
|
|
|
template<typename T>
|
|
using Not = Bool<!T::value>;
|
|
|
|
template<typename Condition, typename Then, typename Else>
|
|
using If = typename std::conditional<Condition::value, Then, Else>::type;
|
|
|
|
template<typename... Args>
|
|
struct And : Bool<true> {};
|
|
|
|
template<typename T, typename... Args>
|
|
struct And<T, Args...> : If<T, And<Args...>, Bool<false>> {};
|
|
|
|
template<typename... Args>
|
|
struct Or : Bool<true> {};
|
|
|
|
template<typename T, typename... Args>
|
|
struct Or<T, Args...> : If<Not<T>, Or<Args...>, Bool<true>> {};
|
|
|
|
template<typename... Args>
|
|
using EnableIf = typename std::enable_if<And<Args...>::value, int>::type;
|
|
|
|
template<typename... Args>
|
|
using DisableIf = typename std::enable_if<Not<And<Args...>>::value, int>::type;
|
|
|
|
template<typename T>
|
|
using Unqualified = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
|
|
|
template<typename T>
|
|
using Decay = typename std::decay<T>::type;
|
|
|
|
template<typename... Args>
|
|
struct return_type {
|
|
typedef std::tuple<Args...> type;
|
|
};
|
|
|
|
template<typename T>
|
|
struct return_type<T> {
|
|
typedef T type;
|
|
};
|
|
|
|
template<>
|
|
struct return_type<> : types<>{
|
|
typedef void type;
|
|
};
|
|
|
|
template<typename... Args>
|
|
struct is_tuple : std::false_type{ };
|
|
|
|
template<typename... Args>
|
|
struct is_tuple<std::tuple<Args...>> : std::true_type{ };
|
|
|
|
template <typename T, template <typename...> class Templ>
|
|
struct is_specialization_of : std::false_type { };
|
|
template <typename... T, template <typename...> class Templ>
|
|
struct is_specialization_of<Templ<T...>, Templ> : std::true_type { };
|
|
|
|
namespace detail {
|
|
template<typename T, bool isclass = std::is_class<Unqualified<T>>::value>
|
|
struct is_function_impl : std::is_function<typename std::remove_pointer<T>::type> {};
|
|
|
|
template<typename T>
|
|
struct is_function_impl<T, true> {
|
|
using yes = char;
|
|
using no = struct { char s[2]; };
|
|
|
|
struct F { void operator()(); };
|
|
struct Derived : T, F {};
|
|
template<typename U, U> struct Check;
|
|
|
|
template<typename V>
|
|
static no test(Check<void (F::*)(), &V::operator()>*);
|
|
|
|
template<typename>
|
|
static yes test(...);
|
|
|
|
static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
|
|
};
|
|
} // detail
|
|
|
|
template<typename T>
|
|
struct Function : Bool<detail::is_function_impl<T>::value> {};
|
|
|
|
template<typename TFuncSignature>
|
|
struct function_traits;
|
|
|
|
template<typename T, typename R, typename... Args>
|
|
struct function_traits<R(T::*)(Args...)> {
|
|
static const std::size_t arity = sizeof...(Args);
|
|
static const bool is_member_function = true;
|
|
typedef std::tuple<Args...> arg_tuple_type;
|
|
typedef types<Args...> args_type;
|
|
typedef R(T::* function_pointer_type)(Args...);
|
|
typedef typename std::remove_pointer<function_pointer_type>::type function_type;
|
|
typedef R(*free_function_pointer_type)(Args...);
|
|
typedef R return_type;
|
|
template<std::size_t i>
|
|
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
|
};
|
|
|
|
template<typename T, typename R, typename... Args>
|
|
struct function_traits<R(T::*)(Args...) const> {
|
|
static const std::size_t arity = sizeof...(Args);
|
|
static const bool is_member_function = true;
|
|
typedef std::tuple<Args...> arg_tuple_type;
|
|
typedef types<Args...> args_type;
|
|
typedef R(T::* function_pointer_type)(Args...);
|
|
typedef typename std::remove_pointer<function_pointer_type>::type function_type;
|
|
typedef R(*free_function_pointer_type)(Args...);
|
|
typedef R return_type;
|
|
template<std::size_t i>
|
|
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
|
};
|
|
|
|
template<typename R, typename... Args>
|
|
struct function_traits<R(Args...)> {
|
|
static const std::size_t arity = sizeof...(Args);
|
|
static const bool is_member_function = false;
|
|
typedef std::tuple<Args...> arg_tuple_type;
|
|
typedef types<Args...> args_type;
|
|
typedef R(function_type)(Args...);
|
|
typedef R(*function_pointer_type)(Args...);
|
|
typedef R(*free_function_pointer_type)(Args...);
|
|
typedef R return_type;
|
|
template<std::size_t i>
|
|
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
|
};
|
|
|
|
template<typename R, typename... Args>
|
|
struct function_traits<R(*)(Args...)> {
|
|
static const std::size_t arity = sizeof...(Args);
|
|
static const bool is_member_function = false;
|
|
typedef std::tuple<Args...> arg_tuple_type;
|
|
typedef types<Args...> args_type;
|
|
typedef R(function_type)(Args...);
|
|
typedef R(*function_pointer_type)(Args...);
|
|
typedef R(*free_function_pointer_type)(Args...);
|
|
typedef R return_type;
|
|
template<std::size_t i>
|
|
using arg = typename std::tuple_element<i, arg_tuple_type>::type;
|
|
};
|
|
|
|
struct has_begin_end_impl {
|
|
template<typename T, typename U = Unqualified<T>,
|
|
typename B = decltype(std::declval<U&>().begin()),
|
|
typename E = decltype(std::declval<U&>().end())>
|
|
static std::true_type test(int);
|
|
|
|
template<typename...>
|
|
static std::false_type test(...);
|
|
};
|
|
|
|
template<typename T>
|
|
struct has_begin_end : decltype(has_begin_end_impl::test<T>(0)) {};
|
|
|
|
struct has_key_value_pair_impl {
|
|
template<typename T, typename U = Unqualified<T>,
|
|
typename V = typename U::value_type,
|
|
typename F = decltype(std::declval<V&>().first),
|
|
typename S = decltype(std::declval<V&>().second)>
|
|
static std::true_type test(int);
|
|
|
|
template<typename...>
|
|
static std::false_type test(...);
|
|
};
|
|
|
|
template<typename T>
|
|
struct has_key_value_pair : decltype(has_key_value_pair_impl::test<T>(0)) {};
|
|
} // sol
|
|
|
|
#endif // SOL_TRAITS_HPP
|