#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_TRAITS_HPP #define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_TRAITS_HPP #include "function_traits.hpp" #include "utils.hpp" #include "meta_list.hpp" #include "void_t.hpp" #include #include namespace kgr { namespace detail { template struct to_false { using type = std::false_type; }; template using false_t = typename to_false::type; template struct to_int { using type = int; }; // Workaround for visual studio to take the address of a generic lambda template T exact(T); template using int_t = typename to_int::type; template struct identity { using type = T; }; template using identity_t = typename identity::type; // things missing from c++11 (to be removed when switching to c++14) template using enable_if_t = typename std::enable_if::type; template using decay_t = typename std::decay::type; template using tuple_element_t = typename std::tuple_element::type; template using aligned_storage_t = typename std::aligned_storage::type; template struct seq {}; template struct seq_gen : seq_gen {}; template struct seq_gen<0, S...> { using type = seq; }; template struct TupleSeqGen; template struct TupleSeqGen> : seq_gen {}; template struct TupleSeqGen> : seq_gen {}; template using tuple_seq = typename TupleSeqGen::type; template using function_seq = tuple_seq>; template using tuple_seq_minus = typename detail::seq_gen::value - (n > meta_list_size::value ? meta_list_size::value : n)>::type; // SFINAE utilities template using is_explicitly_convertible = std::is_constructible; template struct has_autocall : std::false_type {}; template struct has_autocall> : std::true_type {}; template struct has_forward : std::false_type {}; template struct has_forward().forward())>> : std::true_type {}; template struct is_service : std::false_type {}; template struct is_service::value || std::is_abstract::value) && has_forward::value>> : std::true_type {}; // Here, usual traits using void_t don't quite work with visual studio for this particular case. template struct has_construct_helper { private: template static std::true_type test(int); template static std::false_type test(...); public: using type = decltype(test(0)); }; template using has_construct = typename has_construct_helper::type; template struct is_invoke_call : std::false_type {}; template struct is_invoke_call> : std::true_type {}; template using is_member_autocall = std::integral_constant::value>; template class Map, typename T, typename = void> struct is_complete_map : std::false_type {}; template class Map, typename T> struct is_complete_map::Service>> : std::true_type {}; struct Sink { constexpr Sink() = default; template constexpr operator T&& () const; template constexpr operator const T& () const; }; template struct is_brace_constructible_helper { private: template static decltype(static_cast(U{std::declval()...}), std::true_type{}) test(int); template static std::false_type test(...); public: using type = decltype(test(0)); }; template struct has_emplace_helper { private: template static decltype(static_cast(std::declval().emplace(std::declval()...)), std::true_type{}) test(int); template static std::false_type test(...); public: using type = decltype(test(0)); }; template using is_service_embeddable = std::integral_constant::value && sizeof(T) <= sizeof(void*) && alignof(T) <= alignof(void*) >; template using has_emplace = typename has_emplace_helper::type; template using is_brace_constructible = typename is_brace_constructible_helper::type; template using is_only_brace_constructible = std::integral_constant::value && !std::is_constructible::value>; template struct remove_rvalue_reference { using type = T; }; template struct remove_rvalue_reference { using type = T; }; template using remove_rvalue_reference_t = typename remove_rvalue_reference::type; template using is_someway_constructible = std::integral_constant::value || std::is_constructible::value>; template using is_emplaceable = std::integral_constant::value && has_emplace::value>; template using is_service_instantiable = std::integral_constant::value || is_someway_constructible::value>; } // namespace detail } // namespace kgr #endif // KGR_KANGARU_INCLUDE_KANGARU_DETAIL_TRAITS_HPP