// 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 #include namespace sol { template struct identity { typedef T type; }; template struct is_tuple : std::false_type{ }; template struct is_tuple> : std::true_type{ }; template struct unwrap { typedef T type; }; template struct unwrap> { typedef typename std::add_lvalue_reference::type type; }; template struct remove_member_pointer; template struct remove_member_pointer { typedef R type; }; 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 = typename std::remove_cv::type>::type; template using Decay = typename std::decay::type; template using Unwrap = typename unwrap::type; template struct return_type { typedef std::tuple type; }; template struct return_type { typedef T type; }; template<> struct return_type<> : types<>{ typedef void type; }; namespace detail { template>::value> struct is_function_impl : std::is_function::type> {}; 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 using has_deducible_signature_t = typename has_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 arg_tuple_type; typedef types args_type; typedef R(T::* function_pointer_type)(Args...); typedef typename std::remove_pointer::type function_type; typedef R(*free_function_pointer_type)(Args...); typedef R return_type; typedef typename std::remove_pointer::type signature_type; template using arg = typename std::tuple_element::type; }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = true; typedef std::tuple arg_tuple_type; typedef types args_type; typedef R(T::* function_pointer_type)(Args...); typedef typename std::remove_pointer::type function_type; typedef R(*free_function_pointer_type)(Args...); typedef R return_type; typedef typename std::remove_pointer::type signature_type; template using arg = typename std::tuple_element::type; }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; typedef std::tuple arg_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 typename std::remove_pointer::type signature_type; template using arg = typename std::tuple_element::type; }; template struct fx_traits { static const std::size_t arity = sizeof...(Args); static const bool is_member_function = false; typedef std::tuple arg_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 typename std::remove_pointer::type signature_type; template using arg = typename std::tuple_element::type; }; } // 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 member_traits : function_traits { }; template struct member_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 arg_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 = typename std::tuple_element::type; }; } // detail template struct member_traits : detail::member_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 auto unwrapper(T&& item) -> decltype(std::forward(item)) { return std::forward(item); } template Unwrap unwrapper(std::reference_wrapper arg) { return arg.get(); } } // sol #endif // SOL_TRAITS_HPP