summaryrefslogtreecommitdiff
path: root/asl
diff options
context:
space:
mode:
authorSteven Le Rouzic <steven.lerouzic@gmail.com>2024-08-23 20:05:22 +0200
committerSteven Le Rouzic <steven.lerouzic@gmail.com>2024-08-23 20:05:22 +0200
commit19ce24de5e8ef31be2925074e962ae23aaf65be0 (patch)
tree08bb129f79ced8efe3f6f4002b0750395adb7f21 /asl
parentea795dcccb136a45fa08a8a82953f95343706c6c (diff)
Some work on ptr
Diffstat (limited to 'asl')
-rw-r--r--asl/BUILD.bazel3
-rw-r--r--asl/meta.hpp19
-rw-r--r--asl/meta_tests.cpp8
-rw-r--r--asl/ptr.hpp74
-rw-r--r--asl/ptr_tests.cpp14
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; }