diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-03-20 19:28:56 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-03-20 19:29:08 +0100 |
commit | a665c590d5089bb4bcb72193542b60ef571409a3 (patch) | |
tree | 9e6a47c4332d25fcb64280bc0742d27b6a0f3291 /asl | |
parent | 7023c0cc9a7c6d2085f018d5524df6a726d6e487 (diff) |
Add decay
Diffstat (limited to 'asl')
-rw-r--r-- | asl/base/meta.hpp | 25 | ||||
-rw-r--r-- | asl/base/meta_tests.cpp | 14 |
2 files changed, 35 insertions, 4 deletions
diff --git a/asl/base/meta.hpp b/asl/base/meta.hpp index 8bebf2f..93e5603 100644 --- a/asl/base/meta.hpp +++ b/asl/base/meta.hpp @@ -54,6 +54,11 @@ template<typename T> using as_rref_t = decltype(_as_rref_helper<T>(0))::type; template<typename T> consteval as_rref_t<T> declval() {} +template<typename T> auto _as_ptr_helper(int) -> id<T*>; +template<typename T> auto _as_ptr_helper(...) -> id<T>; + +template<typename T> using as_ptr_t = decltype(_as_ptr_helper<T>(0))::type; + template<typename T> struct _un_ref_t { using type = T; }; template<typename T> struct _un_ref_t<T&> { using type = T; }; template<typename T> struct _un_ref_t<T&&> { using type = T; }; @@ -191,11 +196,23 @@ template<typename T> concept is_func = _is_func_helper<tame_t<T>>::value; template<typename T> concept is_object = !is_void<T> && !is_ref<T> && !is_func<T>; -template<typename T> struct _is_array_helper : false_type {}; -template<typename T> struct _is_array_helper<T[]> : true_type {}; -template<typename T, int N> struct _is_array_helper<T[N]> : true_type {}; +template<typename T> struct _array_helper : false_type { using type = T; }; +template<typename T> struct _array_helper<T[]> : true_type { using type = T; }; +template<typename T, int N> struct _array_helper<T[N]> : true_type { using type = T; }; + +template<typename T> concept is_array = _array_helper<T>::value; -template<typename T> concept is_array = _is_array_helper<T>::value; +template<typename T> using remove_extent_t = _array_helper<T>::type; + +template<typename T> +using decay_t = + select_t< + is_array<un_ref_t<T>>, + as_ptr_t<remove_extent_t<un_ref_t<T>>>, + select_t< + is_func<un_ref_t<T>>, + as_ptr_t<un_ref_t<T>>, + un_cv_t<un_ref_t<T>>>>; template<typename T> struct _is_floating_point_helper : false_type {}; template<> struct _is_floating_point_helper<float> : true_type {}; diff --git a/asl/base/meta_tests.cpp b/asl/base/meta_tests.cpp index 490b453..bcd9775 100644 --- a/asl/base/meta_tests.cpp +++ b/asl/base/meta_tests.cpp @@ -189,6 +189,10 @@ static_assert(!asl::is_array<void>); static_assert(!asl::is_array<void(int)>); static_assert(!asl::is_array<int(float) const && noexcept>); +static_assert(asl::same_as<int, asl::remove_extent_t<int>>); +static_assert(asl::same_as<int, asl::remove_extent_t<int[]>>); +static_assert(asl::same_as<int, asl::remove_extent_t<int[67]>>); + static_assert(asl::same_as<int, asl::un_ref_t<int>>); static_assert(asl::same_as<int, asl::un_ref_t<int&>>); static_assert(asl::same_as<int, asl::un_ref_t<int&&>>); @@ -318,3 +322,13 @@ static_assert(asl::same_as<asl::copy_cref_t<const int&, const float>, const floa static_assert(asl::same_as<asl::copy_cref_t<const int&, float&&>, const float&>); static_assert(asl::same_as<asl::copy_cref_t<const int&, const float&>, const float&>); +static_assert(asl::same_as<asl::decay_t<int>, int>); +static_assert(!asl::same_as<asl::decay_t<int>, float>); +static_assert(asl::same_as<asl::decay_t<int&>, int>); +static_assert(asl::same_as<asl::decay_t<int&&>, int>); +static_assert(asl::same_as<asl::decay_t<const int&>, int>); +static_assert(asl::same_as<asl::decay_t<int[2]>, int*>); +static_assert(!asl::same_as<asl::decay_t<int[4][2]>, int*>); +static_assert(!asl::same_as<asl::decay_t<int[4][2]>, int**>); +static_assert(asl::same_as<asl::decay_t<int[4][2]>, int(*)[2]>); +static_assert(asl::same_as<asl::decay_t<int(int)>, int(*)(int)>); |