intial commit
This commit is contained in:
118
source/mijin/util/traits.hpp
Normal file
118
source/mijin/util/traits.hpp
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
#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;
|
||||
|
||||
//
|
||||
// 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)
|
||||
Reference in New Issue
Block a user