Lots of windows fixes and some more improvements.
This commit is contained in:
@@ -21,6 +21,9 @@ namespace mijin
|
||||
// public types
|
||||
//
|
||||
|
||||
struct Type_; // use as typevar
|
||||
struct Any_; // use as placeholder in templates
|
||||
|
||||
template<typename T>
|
||||
struct always_false
|
||||
{
|
||||
@@ -95,11 +98,88 @@ struct map_template {
|
||||
using type_t = TTemplate<TPredicate<T>>;
|
||||
};
|
||||
|
||||
template<typename T, typename... Types>
|
||||
struct is_any_type : std::disjunction<std::is_same<T, Types>...> {};
|
||||
template<template<typename...> typename TTemplate, typename TType>
|
||||
struct is_template_instance : std::false_type {};
|
||||
|
||||
template<template<typename...> typename TTemplate, typename... TArgs>
|
||||
struct is_template_instance<TTemplate, TTemplate<TArgs...>> : std::true_type {};
|
||||
|
||||
template<template<typename...> typename TTemplate, typename TType>
|
||||
constexpr bool is_template_instance_v = is_template_instance<TTemplate, TType>::value;
|
||||
|
||||
namespace impl
|
||||
{
|
||||
template<template<typename...> typename TTemplate, typename... TArgsTTmpl>
|
||||
struct tmpl_param_comparator
|
||||
{
|
||||
template<typename TTmpl, typename TInstance>
|
||||
static constexpr bool compare_single = std::is_same_v<TTmpl, TInstance> or std::is_same_v<TTmpl, Any_>;
|
||||
|
||||
template<typename T>
|
||||
struct matches : std::false_type {};
|
||||
|
||||
// original (which MSVC didn't like for some reason :/)
|
||||
// template<typename... TArgsInstance>
|
||||
// struct matches<TTemplate<TArgsInstance...>> : std::bool_constant<(compare_single<TArgsTTmpl, TArgsInstance> && ...)> {};
|
||||
|
||||
template<template<typename...> typename TOtherTemplate, typename... TArgsInstance> requires(is_template_instance_v<TTemplate, TOtherTemplate<TArgsInstance...>>)
|
||||
struct matches<TOtherTemplate<TArgsInstance...>> : std::bool_constant<(compare_single<TArgsTTmpl, TArgsInstance> && ...)> {};
|
||||
|
||||
template<typename T>
|
||||
using matches_t = matches<T>;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename TTemplate, typename TType>
|
||||
struct match_template_type : std::false_type {};
|
||||
|
||||
template<template<typename...> typename TTemplate, typename TType, typename... TArgs>
|
||||
struct match_template_type<TTemplate<TArgs...>, TType> : impl::tmpl_param_comparator<TTemplate, TArgs...>::template matches_t<TType> {};
|
||||
|
||||
template<typename TTemplate, typename TType>
|
||||
constexpr bool match_template_type_v = match_template_type<TTemplate, TType>::value;
|
||||
|
||||
// similar to std::is_same, but allows placeholders
|
||||
// - is_type_or_impl<some_tmpl<Type_>, some_type> resolves to some_tmpl<some_type>
|
||||
// - is_type_or_impl<some_tmpl<Any_, int>, some_type> checks if some_type is an instance of some_tmpl with int as 2nd parameter
|
||||
template<typename TMatch, typename TConcrete>
|
||||
struct type_matches
|
||||
{
|
||||
using type = std::is_same<TMatch, TConcrete>;
|
||||
};
|
||||
|
||||
template<template<typename> typename TTmplMatch, typename TConcrete>
|
||||
struct type_matches<TTmplMatch<Type_>, TConcrete>
|
||||
{
|
||||
using type = TTmplMatch<TConcrete>;
|
||||
};
|
||||
|
||||
template<template<typename...> typename TTmplMatch, typename TConcrete, typename... TArgs>
|
||||
struct type_matches<TTmplMatch<TArgs...>, TConcrete>
|
||||
{
|
||||
using type = match_template_type<TTmplMatch<TArgs...>, TConcrete>;
|
||||
};
|
||||
|
||||
template<typename TMatch, typename TConcrete>
|
||||
using type_matches_t = type_matches<TMatch, TConcrete>::type;
|
||||
|
||||
template<typename TMatch, typename TConcrete>
|
||||
inline constexpr bool type_matches_v = type_matches_t<TMatch, TConcrete>::value;
|
||||
|
||||
template<typename TConcrete, typename... TMatches>
|
||||
struct is_any_type : std::disjunction<std::is_same<TConcrete, TMatches>...> {};
|
||||
|
||||
template<typename TConcrete, typename... TMatches>
|
||||
static constexpr bool is_any_type_v = is_any_type<TConcrete, TMatches...>::value;
|
||||
|
||||
template<typename TConcrete, typename... TMatches>
|
||||
struct match_any_type : std::disjunction<type_matches_t<TMatches, TConcrete>...> {};
|
||||
|
||||
template<typename TConcrete, typename... TMatches>
|
||||
static constexpr bool match_any_type_v = match_any_type<TConcrete, TMatches...>::value;
|
||||
|
||||
template<typename T, typename... Types>
|
||||
static constexpr bool is_any_type_v = is_any_type<T, Types...>::value;
|
||||
concept union_type = match_any_type_v<T, Types...>;
|
||||
|
||||
template<typename TElement, typename TCollection>
|
||||
struct is_type_member;
|
||||
@@ -139,15 +219,6 @@ struct TypeAtHelper<0, TArg, TArgs...>
|
||||
template<std::size_t I, typename... TArgs>
|
||||
using type_at_t = TypeAtHelper<I, TArgs...>::type_t;
|
||||
|
||||
template<template<typename...> typename TTemplate, typename TType>
|
||||
struct is_template_instance : std::false_type {};
|
||||
|
||||
template<template<typename...> typename TTemplate, typename... TArgs>
|
||||
struct is_template_instance<TTemplate, TTemplate<TArgs...>> : std::true_type {};
|
||||
|
||||
template<template<typename...> typename TTemplate, typename TType>
|
||||
constexpr bool is_template_instance_v = is_template_instance<TTemplate, TType>::value;
|
||||
|
||||
template<typename TDefault, template<typename...> typename TOper, typename... TArgs>
|
||||
struct detect_or
|
||||
{
|
||||
@@ -192,6 +263,34 @@ decltype(auto) delayEvaluation(TType&& value)
|
||||
return static_cast<TType&&>(value);
|
||||
}
|
||||
|
||||
#define MIJIN_STATIC_TESTS 1
|
||||
#if MIJIN_STATIC_TESTS
|
||||
namespace test
|
||||
{
|
||||
template<typename T, typename U>
|
||||
struct MyTemplate {};
|
||||
|
||||
static_assert(match_template_type_v<MyTemplate<Any_, int>, MyTemplate<int, int>>);
|
||||
static_assert(match_template_type_v<MyTemplate<Any_, Any_>, MyTemplate<int, int>>);
|
||||
static_assert(type_matches_v<MyTemplate<Any_, int>, MyTemplate<int, int>>);
|
||||
static_assert(type_matches_v<MyTemplate<Any_, Any_>, MyTemplate<int, int>>);
|
||||
static_assert(!type_matches_v<MyTemplate<double, int>, MyTemplate<int, int>>);
|
||||
static_assert(type_matches_v<MyTemplate<Any_, Any_>, MyTemplate<int, double>>);
|
||||
static_assert(type_matches_v<std::is_pointer<Type_>, void*>);
|
||||
|
||||
static_assert(union_type<int, int>);
|
||||
static_assert(!union_type<int>);
|
||||
static_assert(!union_type<int, double>);
|
||||
static_assert(union_type<MyTemplate<int, int>, MyTemplate<int, int>>);
|
||||
static_assert(union_type<MyTemplate<int, int>, MyTemplate<Any_, int>>);
|
||||
static_assert(union_type<MyTemplate<int, int>, MyTemplate<Any_, Any_>>);
|
||||
static_assert(union_type<MyTemplate<int, int>, MyTemplate<double, double>, MyTemplate<Any_, Any_>>);
|
||||
static_assert(!union_type<int*, int>);
|
||||
static_assert(union_type<int*, std::is_pointer<Type_>>);
|
||||
static_assert(!union_type<int, std::is_pointer<Type_>>);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace mijin
|
||||
|
||||
#endif // !defined(MIJIN_UTIL_TRAITS_HPP_INCLUDED)
|
||||
|
||||
Reference in New Issue
Block a user