diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-08-23 20:05:22 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-08-23 20:05:22 +0200 |
commit | 19ce24de5e8ef31be2925074e962ae23aaf65be0 (patch) | |
tree | 08bb129f79ced8efe3f6f4002b0750395adb7f21 /asl | |
parent | ea795dcccb136a45fa08a8a82953f95343706c6c (diff) |
Some work on ptr
Diffstat (limited to 'asl')
-rw-r--r-- | asl/BUILD.bazel | 3 | ||||
-rw-r--r-- | asl/meta.hpp | 19 | ||||
-rw-r--r-- | asl/meta_tests.cpp | 8 | ||||
-rw-r--r-- | asl/ptr.hpp | 74 | ||||
-rw-r--r-- | asl/ptr_tests.cpp | 14 |
5 files changed, 117 insertions, 1 deletions
diff --git a/asl/BUILD.bazel b/asl/BUILD.bazel index c5f443e..4fdeb38 100644 --- a/asl/BUILD.bazel +++ b/asl/BUILD.bazel @@ -3,6 +3,7 @@ cc_library( hdrs = [
"integers.hpp",
"meta.hpp",
+ "ptr.hpp",
"utility.hpp",
],
visibility = ["//visibility:public"],
@@ -17,4 +18,4 @@ cc_library( deps = [
":asl",
],
-) for name in ["integers", "meta"]]
+) for name in ["integers", "meta", "ptr"]]
diff --git a/asl/meta.hpp b/asl/meta.hpp index b3e0697..411d890 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -2,6 +2,10 @@ namespace asl {
+template<typename... Args> struct types {};
+
+struct empty {};
+
template<typename T> struct id { using type = T; };
template<typename T, T kValue> struct integral_constant { static constexpr T value = kValue; };
@@ -29,6 +33,12 @@ template<typename T> auto _as_rref_helper(...) -> id<T>; template<typename T> using as_lref_t = decltype(_as_lref_helper<T>(0))::type;
template<typename T> using as_rref_t = decltype(_as_rref_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; };
+
+template<typename T> using un_ref_t = _un_ref_t<T>::type;
+
template<typename T, typename... Args> concept constructible = __is_constructible(T, Args...);
template<typename T> concept default_constructible = constructible<T>;
@@ -123,4 +133,13 @@ template<typename T, int N> struct _is_array_helper<T[N]> : true_type {}; template<typename T> concept is_array = _is_array_helper<T>::value;
+template<typename T>
+auto _devoid_helper()
+{
+ if constexpr (is_void<T>) return id<empty>{};
+ else return id<T>{};
+}
+
+template<typename T> using devoid_t = decltype(_devoid_helper<T>())::type;
+
} // namespace asl
diff --git a/asl/meta_tests.cpp b/asl/meta_tests.cpp index c2b27f4..8293319 100644 --- a/asl/meta_tests.cpp +++ b/asl/meta_tests.cpp @@ -145,4 +145,12 @@ 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::is_same<int, asl::devoid_t<int>>);
+static_assert(asl::is_same<asl::empty, asl::devoid_t<void>>);
+
+static_assert(asl::is_same<int, asl::un_ref_t<int>>);
+static_assert(asl::is_same<int, asl::un_ref_t<int&>>);
+static_assert(asl::is_same<int, asl::un_ref_t<int&&>>);
+static_assert(asl::is_same<int() &, asl::un_ref_t<int() &>>);
+
int main() { return 0; }
diff --git a/asl/ptr.hpp b/asl/ptr.hpp new file mode 100644 index 0000000..2d90e7b --- /dev/null +++ b/asl/ptr.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include "asl/integers.hpp" +#include "asl/meta.hpp" + +namespace asl +{ +namespace ptr_internal +{ + +template<is_void T> +struct void_metadata +{ + using metadata = empty; + using pointee = T; +}; + +template<is_array T> +struct array_metadata {}; + +template<typename T> +struct array_metadata<T[]> +{ + using metadata = isize_t; + using pointee = T; +}; + +template<typename T, isize_t N> +struct array_metadata<T[N]> +{ + using metadata = empty; + using pointee = T[N]; +}; + +template<is_object T> +struct object_metadata +{ + using metadata = empty; + using pointee = T; +}; + +template<is_func T> +struct func_metadata +{ + using metadata = empty; + using pointee = tame_t<T>*; +}; + +template<is_ref T> +struct ref_metadata +{ + using metadata = empty; + using pointee = un_ref_t<T>*; +}; + +template<is_void T> void_metadata<T> select_ptr_metadata(types<T>); +template<is_array T> array_metadata<T> select_ptr_metadata(types<T>); +template<is_object T> object_metadata<T> select_ptr_metadata(types<T>) requires (!is_array<T>); +template<is_func T> func_metadata<T> select_ptr_metadata(types<T>); +template<is_ref T> ref_metadata<T> select_ptr_metadata(types<T>); + +template<typename T> +using metadata = decltype(select_ptr_metadata(types<T>{})); + +} // namespace ptr_internal + +template<typename T> +concept ptr_metadata = requires +{ + is_object<typename T::metadata>; + is_object<typename T::pointee>; +}; + +} // namespace asl diff --git a/asl/ptr_tests.cpp b/asl/ptr_tests.cpp new file mode 100644 index 0000000..be27f0d --- /dev/null +++ b/asl/ptr_tests.cpp @@ -0,0 +1,14 @@ +#include "asl/ptr.hpp" + +using namespace asl; + +static_assert(ptr_metadata<ptr_internal::metadata<void>>); +static_assert(ptr_metadata<ptr_internal::metadata<int[]>>); +static_assert(ptr_metadata<ptr_internal::metadata<int[56]>>); +static_assert(ptr_metadata<ptr_internal::metadata<int>>); +static_assert(ptr_metadata<ptr_internal::metadata<int()>>); +static_assert(ptr_metadata<ptr_internal::metadata<int(int) const &>>); +static_assert(ptr_metadata<ptr_internal::metadata<const int&>>); +static_assert(ptr_metadata<ptr_internal::metadata<int&&>>); + +int main() { return 0; } |