// The MIT License (MIT) // Copyright (c) 2013-2016 Rapptz 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_TRAITS_HPP #define SOL_TRAITS_HPP #include "tuple.hpp" #include #include #include namespace sol { template struct identity { typedef T type; }; template using identity_t = typename identity::type; template struct is_tuple : std::false_type{ }; template struct is_tuple> : std::true_type{ }; template struct unwrapped { typedef T type; }; template struct unwrapped> { typedef T type; }; template struct remove_member_pointer; template struct remove_member_pointer { typedef R type; }; template struct remove_member_pointer { typedef R type; }; template using remove_member_pointer_t = remove_member_pointer; template class Templ> struct is_specialization_of : std::false_type { }; template class Templ> struct is_specialization_of, Templ> : std::true_type { }; template struct are_same : std::true_type { }; template struct are_same : std::integral_constant ::value && are_same::value> { }; template using Type = typename T::type; template using Bool = std::integral_constant; template using Not = Bool; template using If = typename std::conditional::type; template using TypeIf = typename std::conditional, Type>::type; template struct And : Bool {}; template struct And : If, Bool> {}; template struct Or : Bool {}; template struct Or : If, Or> {}; template using EnableIf = typename std::enable_if::value, int>::type; template using DisableIf = typename std::enable_if>::value, int>::type; template using Unqualified = std::remove_cv_t>; template using Unwrapped = typename unwrapped::type; template struct return_type { typedef std::tuple type; }; template struct return_type { typedef T type; }; template<> struct return_type<> { typedef void type; }; template using return_type_t = typename return_type::type; template using ReturnTypeOr = typename std::conditional<(sizeof...(Args) < 1), Empty, return_type_t>::type; template using ReturnType = ReturnTypeOr; namespace detail { template>::value> struct is_function_impl : std::is_function> {}; template struct is_function_impl { using yes = char; using no = struct { char s[2]; }; struct F { void operator()(); }; struct Derived : T, F {}; template struct Check; template static no test(Check*); template static yes test(...); static const bool value = sizeof(test(0)) == sizeof(yes); }; template struct check_deducible_signature { struct nat {}; template static auto test(int) -> decltype(&G::operator(), void()); template static auto test(...) -> nat; using type = std::is_void(0))>; }; } // detail template struct has_deducible_signature : detail::check_deducible_signature::type { }; template struct Function : Bool::value> {}; namespace detail { template::value> struct fx_traits; template struct fx_traits : fx_traits { }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; typedef std::tuple args_tuple_type; typedef types args_type; typedef R(T::* function_pointer_type)(Args...); typedef std::remove_pointer_t function_type; typedef R(*free_function_pointer_type)(Args...); typedef R return_type; typedef std::remove_pointer_t signature_type; template using arg = std::tuple_element_t; }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; typedef std::tuple args_tuple_type; typedef types args_type; typedef R(T::* function_pointer_type)(Args...); typedef std::remove_pointer_t function_type; typedef R(*free_function_pointer_type)(Args...); typedef R return_type; typedef std::remove_pointer_t signature_type; template using arg = std::tuple_element_t; }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; typedef std::tuple args_tuple_type; typedef types args_type; typedef R(function_type)(Args...); typedef R(*function_pointer_type)(Args...); typedef R(*free_function_pointer_type)(Args...); typedef R return_type; typedef std::remove_pointer_t signature_type; template using arg = std::tuple_element_t; }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; typedef std::tuple args_tuple_type; typedef types args_type; typedef R(function_type)(Args...); typedef R(*function_pointer_type)(Args...); typedef R(*free_function_pointer_type)(Args...); typedef R return_type; typedef std::remove_pointer_t signature_type; template using arg = std::tuple_element_t; }; } // detail template struct function_traits : detail::fx_traits> {}; template using function_args_t = typename function_traits::args_type; template using function_signature_t = typename function_traits::signature_type; template using function_return_t = typename function_traits::return_type; namespace detail { template::value> struct callable_traits : function_traits { }; template struct callable_traits { typedef typename remove_member_pointer::type Arg; typedef typename remove_member_pointer::type R; typedef Signature signature_type; static const bool is_member_function = false; static const std::size_t arity = 1; typedef std::tuple args_tuple_type; typedef types args_type; typedef R return_type; typedef R(function_type)(Arg); typedef R(*function_pointer_type)(Arg); typedef R(*free_function_pointer_type)(Arg); template using arg = std::tuple_element_t; }; } // detail template struct callable_traits : detail::callable_traits> { }; struct has_begin_end_impl { template, typename B = decltype(std::declval().begin()), typename E = decltype(std::declval().end())> static std::true_type test(int); template static std::false_type test(...); }; template struct has_begin_end : decltype(has_begin_end_impl::test(0)) {}; struct has_key_value_pair_impl { template, typename V = typename U::value_type, typename F = decltype(std::declval().first), typename S = decltype(std::declval().second)> static std::true_type test(int); template static std::false_type test(...); }; template struct has_key_value_pair : decltype(has_key_value_pair_impl::test(0)) {}; template using is_string_constructible = Or, const char*>, std::is_same, char>, std::is_same, std::string>, std::is_same, std::initializer_list>>; template using is_c_str = Or>, char*>, std::is_same, std::string>>; template auto unwrap(T&& item) -> decltype(std::forward(item)) { return std::forward(item); } template T& unwrap(std::reference_wrapper arg) { return arg.get(); } template T& deref(T& item) { return item; } template T& deref(T* item) { return *item; } template decltype(auto) deref(std::unique_ptr& item) { return *item; } template T& deref(std::shared_ptr& item) { return *item; } template decltype(auto) deref(const std::unique_ptr& item) { return *item; } template T& deref(const std::shared_ptr& item) { return *item; } template inline T* ptr(T& val) { return std::addressof(val); } template inline T* ptr(std::reference_wrapper val) { return std::addressof(val.get()); } template inline T* ptr(T* val) { return val; } namespace detail { template , std::tuple>> = 0> decltype(auto) force_tuple(T&& x) { return std::forward_as_tuple(x); } template , std::tuple>> = 0> decltype(auto) force_tuple(T&& x) { return std::forward(x); } } // detail template decltype(auto) tuplefy(X&&... x ) { return std::tuple_cat(detail::force_tuple(x)...); } } // sol #endif // SOL_TRAITS_HPP