#pragma once #if !defined(MIJIN_UTIL_TRAITS_HPP_INCLUDED) #define MIJIN_UTIL_TRAITS_HPP_INCLUDED 1 #include namespace mijin { // // public defines // // // public constants // // // public types // template struct always_false { static constexpr bool value = false; }; template inline constexpr bool always_false_v = always_false::value; template struct always_false_val { static constexpr bool value = false; }; template inline constexpr bool always_false_val_v = always_false_val::value; template typename TFilter, typename... TArgs> struct TypeFilter; template typename TFilter> struct TypeFilter { using type_t = std::tuple<>; }; template typename TFilter, typename TFirst, typename... TArgs> struct TypeFilter { static consteval auto makeTypeHelper() { using base_t = typename TypeFilter::type_t; // note: not using decltype, as the compiler might think it is being evaluated if constexpr (!TFilter::value) { return static_cast(nullptr); } else { auto wrapper = [](std::tuple*) { return static_cast*>(nullptr); }; return wrapper(static_cast(nullptr)); } } using type_t = std::remove_pointer_t; }; template typename TFilter, typename... TArgs> auto typeFilterHelper(std::tuple*) { return static_cast::type_t*>(nullptr); } template typename TFilter, typename TTuple> using filter_types_t = std::remove_pointer_t(static_cast(nullptr)))>; template typename TPredicate, typename... TArgs> auto mapTypesHelper(std::tuple) { return static_cast...>*>(nullptr); } template typename TPredicate, typename TTuple> using map_types_t = std::remove_pointer_t(std::declval()))>; template typename TPredicate, template typename TTemplate> struct map_template { template using type_t = TTemplate>; }; template struct is_any_type : std::disjunction...> {}; template static constexpr bool is_any_type_v = is_any_type::value; template struct is_type_member; template typename TCollection, typename... Ts> struct is_type_member> : std::bool_constant<(... || std::is_same{})> {}; template constexpr bool is_type_member_v = is_type_member::value; template using copy_const_t = std::conditional_t, std::add_const_t, std::remove_const_t>; template using copy_volatile_t = std::conditional_t, std::add_volatile_t, std::remove_volatile_t>; template using copy_cv_t = copy_const_t>; template using delay_type_t = TActual; template struct TypeAtHelper { using type_t = typename TypeAtHelper::type_t; }; template struct TypeAtHelper<0, TArg, TArgs...> { using type_t = TArg; }; template using type_at_t = TypeAtHelper::type_t; template typename TTemplate, typename TType> struct is_template_instance : std::false_type {}; template typename TTemplate, typename... TArgs> struct is_template_instance> : std::true_type {}; template typename TTemplate, typename TType> constexpr bool is_template_instance_v = is_template_instance::value; // // public functions // template decltype(auto) delayEvaluation(TType&& value) { return static_cast(value); } } // namespace mijin #endif // !defined(MIJIN_UTIL_TRAITS_HPP_INCLUDED)