diff --git a/include/cow.hpp b/include/cow.hpp index 26758aa..9b4e793 100644 --- a/include/cow.hpp +++ b/include/cow.hpp @@ -4,9 +4,9 @@ #include -#include "slice.hpp" +#include "cow/slice.hpp" -struct Cow : public Span { +struct Cow : public _cow_util::Span { struct Fake; Cow() = delete; diff --git a/include/cow/slice.hpp b/include/cow/slice.hpp new file mode 100644 index 0000000..bd8fbf7 --- /dev/null +++ b/include/cow/slice.hpp @@ -0,0 +1,114 @@ +#pragma once + +namespace _cow_util { + /// A type that spans a sized region of memory + template + struct Span { + virtual const void* area() const =0; + virtual void* area() = 0; + virtual size_t size() const = 0; + + inline T* ptr() { return (T*)area(); } + inline const T* ptr() const { return (const T*)area(); } + + inline size_t size_bytes() const { return size() * sizeof(T); } + + inline unsigned char* as_bytes() { return (unsigned char*)area(); } + inline const unsigned char* as_bytes() const { return (const unsigned char*)area(); } + + inline T& operator[](size_t index) { + if(index >= size()) throw "index out of range"; + return ptr()[index]; + } + inline const T& operator[](size_t index) const { + if(index >= size()) throw "index out of range"; + return ptr()[index]; + } + + inline T* operator&() { return &(*this)[0]; } + inline const T* operator&() const {return &(*this)[0]; } + + inline T* operator->() { return &(*this)[0]; } + inline const T* operator->() const {return &(*this)[0]; } + + inline T& operator*() { return (*this)[0]; } + inline const T& operator*() const { return (*this)[0]; } + + + template + inline U* area_as() requires(sizeof(T) % sizeof(U) == 0) { return (U*)area(); } + template + inline const U* area_as() const requires(sizeof(T) % sizeof(U) == 0) { return (U*)area(); } + + 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) const + { + return start < size(); + } + inline bool bounds_ok(size_t start, size_t len) const + { + return (start + len) <= size() && bounds_ok(start); + } + + inline ssize_t wrap_len(ssize_t len) const + { + if(size() ==0 ) return 0; + return len < 0 ? wrap_len(size() + len) : ((size_t)len) % size(); + } + + /// Slice (absolute). Specify start and end. + inline const Slice slice_abs(size_t start, size_t end) const { auto len = end -start; if(bounds_ok(start,len)) return Slice(const_cast(ptr()+start), len); else throw "Out of bounds slice"; } + inline Slice slice_abs(size_t start, size_t end) { auto len = end -start; if(bounds_ok(start,len)) return Slice(ptr()+start, len); else throw "Out of bounds slice"; } + + /// Slice (relative). Specify start and length. + inline const Slice slice(size_t start, size_t len) const { if(bounds_ok(start,len)) return Slice(const_cast(ptr()+start), len); else throw "Out of bounds slice"; } + 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"; } + + + /// Slice from 0. Specify length. + inline Slice slice(size_t len) { return slice(0, len); } + inline const Slice slice(size_t len) const { return slice(0, len); }//slice(start, size()-start); } + + /// Slice total. + inline Slice slice() { return slice(0, size()); } + inline const Slice slice() const { return slice(0, size()); } + + /// Slice wrapping. Specify start and end that may wrap over and/or under the span's size. + inline Slice slice_wrap(ssize_t start, ssize_t end) { return slice_abs((size_t)wrap_len(start), (size_t)wrap_len(end)); } + inline const Slice slice_wrap(ssize_t start, ssize_t end) const { return slice_abs((size_t)wrap_len(start), (size_t)wrap_len(end)); } + inline Slice slice_wrap(ssize_t len) { return slice_abs((size_t)wrap_len(len)); } + inline const Slice slice_wrap(ssize_t len) const { return slice_abs((size_t)wrap_len(len)); } + + template + inline Span::Slice reinterpret() { return typename Span::Slice((U*)area(), size_bytes() / sizeof(U)); } + template + inline Span::Slice reinterpret() const { return typename Span::Slice((const U*)area(), size_bytes() / sizeof(U)); } + }; + + /// 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(const_cast(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 + using Slice = Span::Slice; +} diff --git a/include/slice.hpp b/include/slice.hpp deleted file mode 100644 index 6977874..0000000 --- a/include/slice.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -/// A type that spans a sized region of memory -template -struct Span { - virtual const void* area() const =0; - virtual void* area() = 0; - virtual size_t size() const = 0; - - inline T* ptr() { return (T*)area(); } - inline const T* ptr() const { return (const T*)area(); } - - inline size_t size_bytes() const { return size() * sizeof(T); } - - inline unsigned char* as_bytes() { return (unsigned char*)area(); } - inline const unsigned char* as_bytes() const { return (const unsigned char*)area(); } - - inline T& operator[](size_t index) { - if(index >= size()) throw "index out of range"; - return ptr()[index]; - } - inline const T& operator[](size_t index) const { - if(index >= size()) throw "index out of range"; - return ptr()[index]; - } - - inline T* operator&() { return &(*this)[0]; } - inline const T* operator&() const {return &(*this)[0]; } - - inline T* operator->() { return &(*this)[0]; } - inline const T* operator->() const {return &(*this)[0]; } - - inline T& operator*() { return (*this)[0]; } - inline const T& operator*() const { return (*this)[0]; } - - - template - inline U* area_as() requires(sizeof(T) % sizeof(U) == 0) { return (U*)area(); } - template - inline const U* area_as() const requires(sizeof(T) % sizeof(U) == 0) { return (U*)area(); } - - 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) const - { - return start < size(); - } - inline bool bounds_ok(size_t start, size_t len) const - { - return (start + len) <= size() && bounds_ok(start); - } - - inline ssize_t wrap_len(ssize_t len) const - { - if(size() ==0 ) return 0; - return len < 0 ? wrap_len(size() + len) : ((size_t)len) % size(); - } - - /// Slice (absolute). Specify start and end. - inline const Slice slice_abs(size_t start, size_t end) const { auto len = end -start; if(bounds_ok(start,len)) return Slice(const_cast(ptr()+start), len); else throw "Out of bounds slice"; } - inline Slice slice_abs(size_t start, size_t end) { auto len = end -start; if(bounds_ok(start,len)) return Slice(ptr()+start, len); else throw "Out of bounds slice"; } - - /// Slice (relative). Specify start and length. - inline const Slice slice(size_t start, size_t len) const { if(bounds_ok(start,len)) return Slice(const_cast(ptr()+start), len); else throw "Out of bounds slice"; } - 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"; } - - - /// Slice from 0. Specify length. - inline Slice slice(size_t len) { return slice(0, len); } - inline const Slice slice(size_t len) const { return slice(0, len); }//slice(start, size()-start); } - - /// Slice total. - inline Slice slice() { return slice(0, size()); } - inline const Slice slice() const { return slice(0, size()); } - - /// Slice wrapping. Specify start and end that may wrap over and/or under the span's size. - inline Slice slice_wrap(ssize_t start, ssize_t end) { return slice_abs((size_t)wrap_len(start), (size_t)wrap_len(end)); } - inline const Slice slice_wrap(ssize_t start, ssize_t end) const { return slice_abs((size_t)wrap_len(start), (size_t)wrap_len(end)); } - inline Slice slice_wrap(ssize_t len) { return slice_abs((size_t)wrap_len(len)); } - inline const Slice slice_wrap(ssize_t len) const { return slice_abs((size_t)wrap_len(len)); } - - template - inline Span::Slice reinterpret() { return typename Span::Slice((U*)area(), size_bytes() / sizeof(U)); } - template - inline Span::Slice reinterpret() const { return typename Span::Slice((const U*)area(), size_bytes() / sizeof(U)); } -}; - -/// 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(const_cast(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 -using Slice = Span::Slice; diff --git a/src/test/main.cpp b/src/test/main.cpp index a99f9b2..a83b1ef 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -1,8 +1,17 @@ #include #include +#include #include +#include + +int main() +{ + return 0; +} + +/* template void print_slice(Slice memory) { @@ -54,4 +63,4 @@ int main() read_fake(clone); //clone still functions because of refcount on origin. return 0; -} +}*/