[*] Improved AuMin/AuMax - New prototype: constexpr Ret_t AuMin(const A &a, const B &b)

[+] AuCommonType_t
This commit is contained in:
Reece Wilson 2023-10-17 03:26:43 +01:00
parent 3507f862c7
commit c0977cbc0a
2 changed files with 80 additions and 6 deletions

View File

@ -7,14 +7,16 @@
***/
#pragma once
template <class T>
constexpr const T &AuMin(const T &a, const T &b)
template <typename A, typename B, typename Ret_t =
AuConditional_t<AuIsClass_v<A>, A, AuCommonType_t<A, B>>>
constexpr Ret_t AuMin(const A &a, const B &b)
{
return a < b ? a : b;
}
template <class T>
constexpr const T &AuMax(const T &a, const T &b)
template <typename A, typename B, typename Ret_t =
AuConditional_t<AuIsClass_v<A>, A, AuCommonType_t<A, B>>>
constexpr Ret_t AuMax(const A &a, const B &b)
{
return a < b ? b : a;
}

View File

@ -78,7 +78,7 @@ namespace _audetail
AuFalseType TestIsPtrConvertible(const volatile void *);
template <class, typename>
auto TestIsBaseOf(...)->AuTrueType;
auto TestIsBaseOf(...) -> AuTrueType;
template <class B, typename D>
auto TestIsBaseOf(int) -> decltype(TestIsPtrConvertible<B>(static_cast<D *>(nullptr)));
@ -361,6 +361,12 @@ using AuDecay_t = AuConditional_t<
>
>;
template <class T>
struct AuDecay
{
using type = AuDecay_t<T>;
};
template <template <class...> class Base, typename Derived>
struct AuIsBaseOfTemplateImpl
{
@ -424,6 +430,72 @@ static auto AuGetAmbiguousMethod2(Ret_t(T :: *a)(Args...))
return a;
}
// I dont think I can easily implement these in templates
// For the sake of syntax sugar, these will be macros for now
#define AuGetAmbiguousMethod(Ret_t, Args, T, Method) AuGetAmbiguousMethod2<Ret_t, T, AU_BRACKET_SCOPE Args >(&T::Method)
#define AuGetAmbiguousMethod_v AuGetAmbiguousMethod
#define AuGetAmbiguousMethod_v AuGetAmbiguousMethod
namespace _audetail
{
// yoinking https://en.cppreference.com/w/cpp/types/common_type
template<class...>
struct common_type
{ };
template<class T>
struct common_type<T> : common_type<T, T>
{ };
namespace ctdetail
{
template<class...>
using void_t = void;
template<class T1, class T2>
using conditional_result_t = decltype(false ? AuDeclVal<T1>() : AuDeclVal<T2>());
template<class, class, class = void>
struct decay_conditional_result
{ };
template<class T1, class T2>
struct decay_conditional_result<T1, T2, void_t<conditional_result_t<T1, T2>>>
: AuDecay<conditional_result_t<T1, T2>>
{ };
template<class T1, class T2, class = void>
struct common_type_2_impl : decay_conditional_result<const T1 &, const T2 &>
{ };
template<class T1, class T2>
struct common_type_2_impl<T1, T2, void_t<conditional_result_t<T1, T2>>>
: decay_conditional_result<T1, T2>
{ };
}
template<class T1, class T2>
struct common_type<T1, T2>
: AuConditional<AuIsSame_v<T1,typename AuDecay_t<T1>> && AuIsSame_v<T2, AuDecay_t<T2>>,
ctdetail::common_type_2_impl<T1, T2>,
common_type<AuDecay_t<T1>, AuDecay_t<T2>>>::type
{};
namespace ctdetail
{
template<class AlwaysVoid, class T1, class T2, class...R>
struct common_type_multi_impl
{ };
template<class T1, class T2, class...R>
struct common_type_multi_impl<void_t<typename common_type<T1, T2>::type>, T1, T2, R...>
: common_type<typename common_type<T1, T2>::type, R...>
{ };
}
}
template <class T, class T2>
using AuCommonType = typename _audetail::common_type<T, T2>;
template <class T, class T2>
using AuCommonType_t = typename _audetail::common_type<T, T2>::type;