diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-08-24 11:53:39 +0200 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2024-08-24 11:53:39 +0200 |
commit | 2cd972bb3eed7886a6b1d0d1b3ead24c8cf3fe4f (patch) | |
tree | 7480ca5f6c3fa303ad79afede1422bdf321fcbf2 /asl | |
parent | 19ce24de5e8ef31be2925074e962ae23aaf65be0 (diff) |
More work
Diffstat (limited to 'asl')
-rw-r--r-- | asl/meta.hpp | 5 | ||||
-rw-r--r-- | asl/meta_tests.cpp | 8 | ||||
-rw-r--r-- | asl/ptr.hpp | 69 | ||||
-rw-r--r-- | asl/ptr_tests.cpp | 20 |
4 files changed, 88 insertions, 14 deletions
diff --git a/asl/meta.hpp b/asl/meta.hpp index 411d890..93bd1dd 100644 --- a/asl/meta.hpp +++ b/asl/meta.hpp @@ -85,6 +85,11 @@ template<typename T> struct _is_ref_helper<T&&> { static constexpr bool l = fals template<typename T> concept is_ref = _is_ref_helper<T>::l || _is_ref_helper<T>::r;
+template<typename T> struct _is_ptr_helper : false_type {};
+template<typename T> struct _is_ptr_helper<T*> : true_type {};
+
+template<typename T> concept is_ptr = _is_ptr_helper<un_cv_t<T>>::value;
+
template<typename T> struct _tame_helper { using type = T; };
#define TAME_HELPER_IMPL(TRAILING) \
diff --git a/asl/meta_tests.cpp b/asl/meta_tests.cpp index 8293319..210e735 100644 --- a/asl/meta_tests.cpp +++ b/asl/meta_tests.cpp @@ -99,6 +99,14 @@ static_assert(!asl::is_ref<void>); static_assert(!asl::is_ref<void()>);
static_assert(!asl::is_ref<void() const &&>);
+static_assert(asl::is_ptr<int*>);
+static_assert(asl::is_ptr<const int* const>);
+static_assert(asl::is_ptr<const volatile int*>);
+static_assert(!asl::is_ptr<int>);
+static_assert(!asl::is_ptr<void>);
+static_assert(!asl::is_ptr<void()>);
+static_assert(!asl::is_ptr<void() const &&>);
+
static_assert(asl::is_same<int, asl::tame_t<int>>);
static_assert(asl::is_same<int(), asl::tame_t<int()>>);
static_assert(asl::is_same<int(float), asl::tame_t<int(float)>>);
diff --git a/asl/ptr.hpp b/asl/ptr.hpp index 2d90e7b..9065e74 100644 --- a/asl/ptr.hpp +++ b/asl/ptr.hpp @@ -2,9 +2,33 @@ #include "asl/integers.hpp" #include "asl/meta.hpp" +#include "asl/utility.hpp" namespace asl { + +// @Todo Shitty span, improve this +template<is_object T, isize_t kLen> +struct span +{ + static constexpr bool kDynamic = kLen < 0; + + using size_type = select_t<kDynamic, isize_t, empty>; + + constexpr span(T* begin, isize_t len) requires kDynamic + : m_begin{begin} + , m_len{len} + {} + + constexpr span(T* begin) requires (!kDynamic) + : m_begin{begin} + , m_len{} + {} + + T* m_begin; + ASL_NO_UNIQUE_ADDRESS size_type m_len; +}; + namespace ptr_internal { @@ -13,23 +37,37 @@ struct void_metadata { using metadata = empty; using pointee = T; + + constexpr auto deref(pointee* ptr) { return ptr; } }; template<is_array T> struct array_metadata {}; -template<typename T> +template<is_object T> struct array_metadata<T[]> { using metadata = isize_t; using pointee = T; + + constexpr auto deref(pointee* ptr) + { + return span<pointee, -1>(ptr, m_len); + } + + isize_t m_len; }; -template<typename T, isize_t N> +template<is_object T, isize_t N> struct array_metadata<T[N]> { using metadata = empty; using pointee = T[N]; + + constexpr auto deref(pointee* ptr) + { + return span<T, N>(static_cast<T*>(*ptr)); + } }; template<is_object T> @@ -37,20 +75,26 @@ struct object_metadata { using metadata = empty; using pointee = T; + + constexpr auto deref(pointee* ptr) { return ptr; } }; template<is_func T> struct func_metadata { using metadata = empty; - using pointee = tame_t<T>*; + using pointee = tame_t<T>* const; + + constexpr auto deref(pointee* ptr) { return *ptr; } }; template<is_ref T> struct ref_metadata { using metadata = empty; - using pointee = un_ref_t<T>*; + using pointee = un_ref_t<T>* const; + + constexpr auto deref(pointee* ptr) { return *ptr; } }; template<is_void T> void_metadata<T> select_ptr_metadata(types<T>); @@ -65,10 +109,25 @@ using metadata = decltype(select_ptr_metadata(types<T>{})); } // namespace ptr_internal template<typename T> -concept ptr_metadata = requires +concept ptr_metadata = requires (T metadata, typename T::pointee* ptr) { is_object<typename T::metadata>; is_object<typename T::pointee>; + + { metadata.deref(ptr) }; +}; + +template<typename T> +class ptr +{ + using meta = ptr_internal::metadata<T>; + static_assert(ptr_metadata<meta>); + + meta::pointee* m_ptr; + ASL_NO_UNIQUE_ADDRESS meta m_meta; + +public: + }; } // namespace asl diff --git a/asl/ptr_tests.cpp b/asl/ptr_tests.cpp index be27f0d..64c0ae2 100644 --- a/asl/ptr_tests.cpp +++ b/asl/ptr_tests.cpp @@ -1,14 +1,16 @@ #include "asl/ptr.hpp" -using namespace asl; +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<void>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<int[]>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<int[56]>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<int>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<int()>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<int(int) const &>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<const int&>>); +static_assert(asl::ptr_metadata<asl::ptr_internal::metadata<int&&>>); -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&&>>); +static_assert(sizeof(asl::ptr<int>) == sizeof(int*)); +static_assert(sizeof(asl::ptr<int[]>) == sizeof(int*) * 2); +static_assert(sizeof(asl::ptr<int[67]>) == sizeof(int*)); int main() { return 0; } |