summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2025-02-25 22:46:15 +0100
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2025-02-25 22:46:15 +0100
commit507a994399c9ddf7e78bd4a290e05f54ddc2f3a6 (patch)
tree3039364a5e8372a3f353e1f4315eb252024c6496 /asl
parenta808626873cde6665fbcb27de4f1a8e16518b2da (diff)
Add copy_cref_t
Diffstat (limited to 'asl')
-rw-r--r--asl/base/meta.hpp22
-rw-r--r--asl/base/meta_tests.cpp20
2 files changed, 41 insertions, 1 deletions
diff --git a/asl/base/meta.hpp b/asl/base/meta.hpp
index 17a7620..bbe5547 100644
--- a/asl/base/meta.hpp
+++ b/asl/base/meta.hpp
@@ -96,6 +96,8 @@ template<typename T> struct _un_const_helper<const T> { using type = T; };
template<typename T> using un_const_t = _un_const_helper<T>::type;
+template<typename T> using as_const_t = const T;
+
template<typename T> struct _is_const_helper : false_type {};
template<typename T> struct _is_const_helper<const T> : true_type {};
@@ -108,7 +110,7 @@ template<typename T> using un_volatile_t = _un_volatile_helper<T>::type;
template<typename T> using un_cv_t = un_volatile_t<un_const_t<T>>;
-template<typename T> using un_cvref_t = un_ref_t<un_cv_t<T>>;
+template<typename T> using un_cvref_t = un_cv_t<un_ref_t<T>>;
template<typename T> concept is_void = same_as<void, un_cv_t<T>>;
@@ -120,6 +122,24 @@ template<typename T> concept is_ref = _is_ref_helper<T>::l || _is_ref_helper<T>:
template<typename T> concept is_rref = _is_ref_helper<T>::r;
template<typename T> concept is_lref = _is_ref_helper<T>::l;
+template<typename From, typename To, bool kLref = is_lref<From>, bool kRref = is_rref<From>>
+struct _copy_ref_helper { using type = To; };
+
+template<typename From, typename To>
+struct _copy_ref_helper<From, To, true, false> { using type = as_lref_t<To>; };
+
+template<typename From, typename To>
+struct _copy_ref_helper<From, To, false, true> { using type = as_rref_t<To>; };
+
+template<typename From, typename To, bool kIsConst = is_const<un_ref_t<From>>>
+struct _copy_const_helper { using type = To; };
+
+template<typename From, typename To>
+struct _copy_const_helper<From, To, true> { using type = const To; };
+
+template<typename From, typename To> using copy_cref_t =
+ _copy_ref_helper<From, typename _copy_const_helper<From, un_cvref_t<To>>::type>::type;
+
template<typename T> struct _is_ptr_helper : false_type {};
template<typename T> struct _is_ptr_helper<T*> : true_type {};
diff --git a/asl/base/meta_tests.cpp b/asl/base/meta_tests.cpp
index 7aa7145..99cc6c0 100644
--- a/asl/base/meta_tests.cpp
+++ b/asl/base/meta_tests.cpp
@@ -287,3 +287,23 @@ ASL_TEST(deref)
wants_base_ptr(&asl::deref<Base>(d));
}
+static_assert(asl::same_as<asl::copy_cref_t<int, float>, float>);
+static_assert(asl::same_as<asl::copy_cref_t<int, const float>, float>);
+static_assert(asl::same_as<asl::copy_cref_t<int, float&&>, float>);
+static_assert(asl::same_as<asl::copy_cref_t<int, const float&>, float>);
+
+static_assert(asl::same_as<asl::copy_cref_t<int&&, float>, float&&>);
+static_assert(asl::same_as<asl::copy_cref_t<int&&, const float>, float&&>);
+static_assert(asl::same_as<asl::copy_cref_t<int&&, float&&>, float&&>);
+static_assert(asl::same_as<asl::copy_cref_t<int&&, const float&>, float&&>);
+
+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::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::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::copy_cref_t<const int&, float&&>, const float&>);
+static_assert(asl::same_as<asl::copy_cref_t<const int&, const float&>, const float&>);
+