From 150ab70dc17eaa2469b8a852c2a1cc74e5a93e8f Mon Sep 17 00:00:00 2001 From: Avril Date: Sat, 5 Jun 2021 13:41:11 +0100 Subject: [PATCH] span has dedicated simple memory Slice child --- include/cow.hpp | 4 ++-- include/slice.hpp | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/cow.hpp b/include/cow.hpp index ab1364e..26758aa 100644 --- a/include/cow.hpp +++ b/include/cow.hpp @@ -6,7 +6,7 @@ #include "slice.hpp" -struct Cow : public Slice { +struct Cow : public Span { struct Fake; Cow() = delete; @@ -30,7 +30,7 @@ struct Cow : public Slice { /// There is also likely no benefit using this over `size()` in LTO enabled builds. /// /// XXX: Deprecated function for now. It seems `size()` offers better codegen on LTO and non-LTO enabled builds. - [[deprecated]] inline size_t size_unsafe() const { return _cow_size_unsafe(get_raw()); } + [[deprecated("size() is safer and offers better codegen.")]] inline size_t size_unsafe() const { return _cow_size_unsafe(get_raw()); } static Cow from_raw(cow_t* owned); diff --git a/include/slice.hpp b/include/slice.hpp index 29f343e..c5b63fa 100644 --- a/include/slice.hpp +++ b/include/slice.hpp @@ -1,7 +1,8 @@ #pragma once +/// A type that spans a sized region of memory template -struct Slice { +struct Span { virtual const void* area() const =0; virtual void* area() = 0; virtual size_t size() const = 0; @@ -30,4 +31,39 @@ struct Slice { template size_t size_as() const requires(sizeof(T) % sizeof(U) == 0) { return size_bytes() / sizeof(U); } + + struct Slice; + + inline bool bounds_ok(size_t start, size_t len) + { + return (start + len) < size(); + } + inline bool bounds_ok(size_t start) + { + return start < size(); + } + + inline Slice slice(size_t start, size_t len) { if(bounds_ok(start,len)) return Slice(ptr()+start, len); else throw "Out of bounds slice"; } + inline Slice slice(size_t start) { return slice(start, size()-start); } }; + +/// A slice of memory with a backing pointer and size. +template +struct Span::Slice : public Span { + inline Slice(T* ptr, size_t sz) : _area((void*)ptr), _size(sz){} + inline Slice(const Span& slice) : _area(slice.area()), _size(slice.size()){} + inline Slice(const Slice& copy) = default; + inline Slice(Slice&& copy) : _area(copy._area), _size(copy._size){ *const_cast(©._size) = 0; } + Slice() = delete; + + inline const void* area() const override { return _area; } + inline void* area() override { return _area; } + inline size_t size() const override { return _size; } + + private: + void* const _area; + const size_t _size; +}; + +template +typename Span::Slice Slice;