128 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
 | |
| #pragma once
 | |
| 
 | |
| #if !defined(MIJIN_UTIL_TRAITS_HPP_INCLUDED)
 | |
| #define MIJIN_UTIL_TRAITS_HPP_INCLUDED 1
 | |
| 
 | |
| #include <tuple>
 | |
| 
 | |
| namespace mijin
 | |
| {
 | |
| 
 | |
| //
 | |
| // public defines
 | |
| //
 | |
| 
 | |
| //
 | |
| // public constants
 | |
| //
 | |
| 
 | |
| //
 | |
| // public types
 | |
| //
 | |
| 
 | |
| template<typename T>
 | |
| struct always_false
 | |
| {
 | |
|     static constexpr bool value = false;
 | |
| };
 | |
| 
 | |
| template<typename T>
 | |
| inline constexpr bool always_false_v = always_false<T>::value;
 | |
| 
 | |
| template<auto V>
 | |
| struct always_false_val
 | |
| {
 | |
|     static constexpr bool value = false;
 | |
| };
 | |
| 
 | |
| template<auto V>
 | |
| inline constexpr bool always_false_val_v = always_false_val<V>::value;
 | |
| 
 | |
| template<template<typename> typename TFilter, typename... TArgs>
 | |
| struct TypeFilter;
 | |
| 
 | |
| template<template<typename> typename TFilter>
 | |
| struct TypeFilter<TFilter>
 | |
| {
 | |
|     using type_t = std::tuple<>;
 | |
| };
 | |
| 
 | |
| template<template<typename> typename TFilter, typename TFirst, typename... TArgs>
 | |
| struct TypeFilter<TFilter, TFirst, TArgs...>
 | |
| {
 | |
|     static consteval auto makeTypeHelper()
 | |
|     {
 | |
|         using base_t = typename TypeFilter<TFilter, TArgs...>::type_t;
 | |
| 
 | |
|         // note: not using decltype, as the compiler might think it is being evaluated
 | |
|         if constexpr (!TFilter<TFirst>::value) {
 | |
|             return static_cast<base_t*>(nullptr);
 | |
|         }
 | |
|         else {
 | |
|             auto wrapper = []<typename... TArgsInner>(std::tuple<TArgsInner...>*)
 | |
|             {
 | |
|                 return static_cast<std::tuple<TFirst, TArgsInner...>*>(nullptr);
 | |
|             };
 | |
|             return wrapper(static_cast<base_t*>(nullptr));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     using type_t = std::remove_pointer_t<decltype(makeTypeHelper())>;
 | |
| };
 | |
| 
 | |
| template<template<typename> typename TFilter, typename... TArgs>
 | |
| auto typeFilterHelper(std::tuple<TArgs...>*)
 | |
| {
 | |
|     return static_cast<typename TypeFilter<TFilter, TArgs...>::type_t*>(nullptr);
 | |
| }
 | |
| 
 | |
| template<template<typename> typename TFilter, typename TTuple>
 | |
| using filter_types_t = std::remove_pointer_t<decltype(typeFilterHelper<TFilter>(static_cast<TTuple*>(nullptr)))>;
 | |
| 
 | |
| template<template<typename> typename TPredicate, typename... TArgs>
 | |
| auto mapTypesHelper(std::tuple<TArgs...>)
 | |
| {
 | |
|     return static_cast<std::tuple<TPredicate<TArgs>...>*>(nullptr);
 | |
| }
 | |
| 
 | |
| template<template<typename> typename TPredicate, typename TTuple>
 | |
| using map_types_t = std::remove_pointer_t<decltype(mapTypesHelper<TPredicate>(std::declval<TTuple>()))>;
 | |
| 
 | |
| template<template<typename> typename TPredicate, template<typename> typename TTemplate>
 | |
| struct map_template {
 | |
|     template<typename T>
 | |
|     using type_t = TTemplate<TPredicate<T>>;
 | |
| };
 | |
| 
 | |
| template<typename T, typename... Types>
 | |
| struct is_any_type : std::disjunction<std::is_same<T, Types>...> {};
 | |
| 
 | |
| template<typename T, typename... Types>
 | |
| static constexpr bool is_any_type_v = is_any_type<T, Types...>::value;
 | |
| 
 | |
| template<typename TElement, typename TCollection>
 | |
| struct is_type_member;
 | |
| 
 | |
| template<typename TElement, template<typename...> typename TCollection, typename... Ts>
 | |
| struct is_type_member<TElement, TCollection<Ts...>>
 | |
|   : std::bool_constant<(... || std::is_same<TElement, Ts>{})>
 | |
| {};
 | |
| 
 | |
| template<typename TElement, typename TCollection>
 | |
| constexpr bool is_type_member_v = is_type_member<TElement, TCollection>::value;
 | |
| 
 | |
| //
 | |
| // public functions
 | |
| //
 | |
| 
 | |
| template<typename THelper, typename TType>
 | |
| decltype(auto) delayEvaluation(TType&& value)
 | |
| {
 | |
|     return static_cast<TType&&>(value);
 | |
| }
 | |
| 
 | |
| } // namespace mijin
 | |
| 
 | |
| #endif // !defined(MIJIN_UTIL_TRAITS_HPP_INCLUDED)
 |