add noexcept specializations to meta (detail) template trait structs

fixes the noexcept tests for C++17 (on my compiler)
This commit is contained in:
Rohlem 2017-06-14 19:28:12 +02:00 committed by The Phantom Derpstorm
parent db39b2f316
commit 39fdb5e041
2 changed files with 231 additions and 24 deletions

View File

@ -54,12 +54,13 @@ namespace sol {
template <std::size_t I, typename T>
using void_tuple_element_t = typename void_tuple_element<I, T>::type;
template <bool has_c_variadic, typename T, typename R, typename... Args>
template <bool it_is_noexcept, bool has_c_variadic, typename T, typename R, typename... Args>
struct basic_traits {
private:
typedef std::conditional_t<std::is_void<T>::value, int, T>& first_type;
public:
static const bool is_noexcept = it_is_noexcept;
static const bool is_member_function = std::is_void<T>::value;
static const bool has_c_var_arg = has_c_variadic;
static const std::size_t arity = sizeof...(Args);
@ -79,123 +80,250 @@ namespace sol {
};
template<typename Signature, bool b = has_deducible_signature<Signature>::value>
struct fx_traits : basic_traits<false, void, void> {};
struct fx_traits : basic_traits<false, false, void, void> {};
// Free Functions
template<typename R, typename... Args>
struct fx_traits<R(Args...), false> : basic_traits<false, void, R, Args...> {
struct fx_traits<R(Args...), false> : basic_traits<false, false, void, R, Args...> {
typedef R(*function_pointer_type)(Args...);
};
template<typename R, typename... Args>
struct fx_traits<R(*)(Args...), false> : basic_traits<false, void, R, Args...> {
struct fx_traits<R(*)(Args...), false> : basic_traits<false, false, void, R, Args...> {
typedef R(*function_pointer_type)(Args...);
};
template<typename R, typename... Args>
struct fx_traits<R(Args..., ...), false> : basic_traits<true, void, R, Args...> {
struct fx_traits<R(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
typedef R(*function_pointer_type)(Args..., ...);
};
template<typename R, typename... Args>
struct fx_traits<R(*)(Args..., ...), false> : basic_traits<true, void, R, Args...> {
struct fx_traits<R(*)(Args..., ...), false> : basic_traits<false, true, void, R, Args...> {
typedef R(*function_pointer_type)(Args..., ...);
};
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
template<typename R, typename... Args>
struct fx_traits<R(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
typedef R(*function_pointer_type)(Args...);
};
template<typename R, typename... Args>
struct fx_traits<R(*)(Args...) noexcept, false> : basic_traits<true, false, void, R, Args...> {
typedef R(*function_pointer_type)(Args...);
};
template<typename R, typename... Args>
struct fx_traits<R(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
typedef R(*function_pointer_type)(Args..., ...);
};
template<typename R, typename... Args>
struct fx_traits<R(*)(Args..., ...) noexcept, false> : basic_traits<true, true, void, R, Args...> {
typedef R(*function_pointer_type)(Args..., ...);
};
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
// Member Functions
/* C-Style Variadics */
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...), false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...), false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...);
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...), false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...), false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...);
};
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...);
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...);
};
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
/* Const Volatile */
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) const, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) const, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const volatile, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) const volatile, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const volatile;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const volatile, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) const volatile, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
};
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
/* Const Volatile */
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const volatile noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const volatile;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const volatile noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const volatile;
};
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
/* Member Function Qualifiers */
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) &, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) &, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) &, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const &, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) const &, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const &, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) const &, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const volatile &, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) const volatile &, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const volatile &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const volatile &, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) const volatile &, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) && , false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) && , false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) && ;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) && , false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) && , false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) && ;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const &&, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) const &&, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const &&;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const &&, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) const &&, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const &&;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const volatile &&, false> : basic_traits<false, T, R, Args...> {
struct fx_traits<R(T::*)(Args...) const volatile &&, false> : basic_traits<false, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const volatile &&;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const volatile &&, false> : basic_traits<true, T, R, Args...> {
struct fx_traits<R(T::*)(Args..., ...) const volatile &&, false> : basic_traits<false, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
};
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) & noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) & noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const & noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const & noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const volatile & noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const volatile &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const volatile & noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) && noexcept , false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) && ;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) && noexcept , false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) && ;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const && noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const &&;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const && noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const &&;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args...) const volatile && noexcept, false> : basic_traits<true, false, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args...) const volatile &&;
};
template<typename T, typename R, typename... Args>
struct fx_traits<R(T::*)(Args..., ...) const volatile && noexcept, false> : basic_traits<true, true, T, R, Args...> {
typedef R(T::* function_pointer_type)(Args..., ...) const volatile &&;
};
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
template<typename Signature>
struct fx_traits<Signature, true> : fx_traits<typename fx_traits<decltype(&Signature::operator())>::function_type, false> {};

View File

@ -233,6 +233,85 @@ namespace sol {
};
#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) noexcept> : public member_function_wrapper<R(O:: *)(Args...) noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) const noexcept> : public member_function_wrapper<R(O:: *)(Args...) const noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) const volatile noexcept> : public member_function_wrapper<R(O:: *)(Args...) const volatile noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) & noexcept> : public member_function_wrapper<R(O:: *)(Args...) & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) const & noexcept> : public member_function_wrapper<R(O:: *)(Args...) const & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) const volatile & noexcept> : public member_function_wrapper<R(O:: *)(Args...) const volatile & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args..., ...) & noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args..., ...) const & noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args..., ...) const volatile & noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) && noexcept> : public member_function_wrapper<R(O:: *)(Args...) & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) const && noexcept> : public member_function_wrapper<R(O:: *)(Args...) const & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args...) const volatile && noexcept> : public member_function_wrapper<R(O:: *)(Args...) const volatile & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args..., ...) && noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args..., ...) const && noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const & noexcept, R, O, Args...> {
};
template <typename R, typename O, typename... Args>
struct wrapper<R(O:: *)(Args..., ...) const volatile && noexcept> : public member_function_wrapper<R(O:: *)(Args..., ...) const volatile & noexcept, R, O, Args...> {
};
#endif//#if __cpp_noexcept_function_type >= 201510L //noexcept has become a part of a function's type
} // sol
#endif // SOL_WRAPPER_HPP