diff options
Diffstat (limited to 'asl/ptr.hpp')
-rw-r--r-- | asl/ptr.hpp | 69 |
1 files changed, 64 insertions, 5 deletions
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 |