#pragma once #include "asl/integers.hpp" #include "asl/meta.hpp" #include "asl/utility.hpp" namespace asl { // @Todo Shitty span, improve this template struct span { static constexpr bool kDynamic = kLen < 0; using size_type = select_t; 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 { template struct void_metadata { using metadata = empty; using pointee = T; constexpr auto deref(pointee* ptr) { return ptr; } }; template struct array_metadata {}; template struct array_metadata { using metadata = isize_t; using pointee = T; constexpr auto deref(pointee* ptr) { return span(ptr, m_len); } isize_t m_len; }; template struct array_metadata { using metadata = empty; using pointee = T[N]; constexpr auto deref(pointee* ptr) { return span(static_cast(*ptr)); } }; template struct object_metadata { using metadata = empty; using pointee = T; constexpr auto deref(pointee* ptr) { return ptr; } }; template struct func_metadata { using metadata = empty; using pointee = tame_t* const; constexpr auto deref(pointee* ptr) { return *ptr; } }; template struct ref_metadata { using metadata = empty; using pointee = un_ref_t* const; constexpr auto deref(pointee* ptr) { return *ptr; } }; template void_metadata select_ptr_metadata(types); template array_metadata select_ptr_metadata(types); template object_metadata select_ptr_metadata(types) requires (!is_array); template func_metadata select_ptr_metadata(types); template ref_metadata select_ptr_metadata(types); template using metadata = decltype(select_ptr_metadata(types{})); } // namespace ptr_internal template concept ptr_metadata = requires (T metadata, typename T::pointee* ptr) { is_object; is_object; { metadata.deref(ptr) }; }; template class ptr { using meta = ptr_internal::metadata; static_assert(ptr_metadata); meta::pointee* m_ptr; ASL_NO_UNIQUE_ADDRESS meta m_meta; public: }; } // namespace asl