fuck this language honsetly what shit
absolute-shit
Avril 3 years ago
parent 2c88d329b9
commit 646482c555
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -27,6 +27,7 @@ struct Cow : public _cow_util::Span<unsigned char> {
virtual Fake clone() const; virtual Fake clone() const;
protected:
inline void* area() override { inline void* area() override {
auto raw = get_raw(); auto raw = get_raw();
return raw ? cow_ptr(raw) : nullptr; return raw ? cow_ptr(raw) : nullptr;
@ -35,6 +36,7 @@ struct Cow : public _cow_util::Span<unsigned char> {
auto raw = get_raw(); auto raw = get_raw();
return raw ? cow_ptr_of(const void, raw) : nullptr; return raw ? cow_ptr_of(const void, raw) : nullptr;
} }
public:
/// Get the size of the mapped area. /// Get the size of the mapped area.
/// ///

@ -5,9 +5,10 @@
#include <utility> #include <utility>
#include <cow.hpp> #include <cow.hpp>
#include "slice.hpp"
namespace _cow_util { namespace _cow_util {
struct Area { struct Area : public Span<unsigned char> {
Area() = delete; Area() = delete;
explicit Area(size_t sz); explicit Area(size_t sz);
@ -30,7 +31,13 @@ namespace _cow_util {
inline cow_t* raw() const { return _area->raw(); } inline cow_t* raw() const { return _area->raw(); }
inline size_t size() const override { return _area->size(); }
~Area(); ~Area();
protected:
inline void* area() override { return _area->ptr(); }
inline const void* area() const override { return _area->ptr(); }
private: private:
const std::unique_ptr<Cow> _area; const std::unique_ptr<Cow> _area;
}; };

@ -4,17 +4,19 @@ namespace _cow_util {
/// A type that spans a sized region of memory /// A type that spans a sized region of memory
template<typename T> template<typename T>
struct Span { struct Span {
protected:
virtual const void* area() const =0; virtual const void* area() const =0;
virtual void* area() = 0; virtual void* area() = 0;
public:
virtual size_t size() const = 0; virtual size_t size() const = 0;
inline T* ptr() { return (T*)area(); } inline T* ptr() { return reinterpret_cast<T*>(area()); }
inline const T* ptr() const { return (const T*)area(); } inline const T* ptr() const { return reinterpret_cast<const T*>(area()); }
inline size_t size_bytes() const { return size() * sizeof(T); } inline size_t size_bytes() const { return size() * sizeof(T); }
inline unsigned char* as_bytes() { return (unsigned char*)area(); } inline unsigned char* as_bytes() { return area_as<unsigned char>(); }
inline const unsigned char* as_bytes() const { return (const unsigned char*)area(); } inline const unsigned char* as_bytes() const { return area_as<unsigned char>(); }
inline T& operator[](size_t index) { inline T& operator[](size_t index) {
if(index >= size()) throw "index out of range"; if(index >= size()) throw "index out of range";
@ -38,9 +40,9 @@ namespace _cow_util {
inline operator T*() { return &(*this)[0]; } inline operator T*() { return &(*this)[0]; }
template<typename U> template<typename U>
inline U* area_as() requires(sizeof(T) % sizeof(U) == 0) { return (U*)area(); } inline U* area_as() requires(sizeof(T) % sizeof(U) == 0) { return reinterpret_cast<U*>(area()); }
template<typename U> template<typename U>
inline const U* area_as() const requires(sizeof(T) % sizeof(U) == 0) { return (U*)area(); } inline const U* area_as() const requires(sizeof(T) % sizeof(U) == 0) { return reinterpret_cast<const U*>(area()); }
template<typename U> template<typename U>
size_t size_as() const requires(sizeof(T) % sizeof(U) == 0) { return size_bytes() / sizeof(U); } size_t size_as() const requires(sizeof(T) % sizeof(U) == 0) { return size_bytes() / sizeof(U); }
@ -89,23 +91,24 @@ namespace _cow_util {
inline const Slice slice_wrap(ssize_t len) const { 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<typename U> template<typename U>
inline Span<U>::Slice reinterpret() { return typename Span<U>::Slice((U*)area(), size_bytes() / sizeof(U)); } inline Span<U>::Slice reinterpret() { return typename Span<U>::Slice(area_as<U>(), size_bytes() / sizeof(U)); }
template<typename U> template<typename U>
inline Span<const U>::Slice reinterpret() const { return typename Span<const U>::Slice((const U*)area(), size_bytes() / sizeof(U)); } inline Span<const U>::Slice reinterpret() const { return typename Span<const U>::Slice(area_as<U>(), size_bytes() / sizeof(U)); }
}; };
/// A slice of memory with a backing pointer and size. /// A slice of memory with a backing pointer and size.
template<typename T> template<typename T>
struct Span<T>::Slice : public Span<T> { struct Span<T>::Slice : public Span<T> {
inline Slice(T* ptr, size_t sz) : _area((void*)ptr), _size(sz){} inline Slice(T* ptr, size_t sz) : _area(reinterpret_cast<void*>(ptr)), _size(sz){}
inline Slice(const Span<T>& slice) : _area(const_cast<void*>(slice.area())), _size(slice.size()){} inline Slice(const Span<T>& slice) : _area(const_cast<void*>(slice.area())), _size(slice.size()){}
inline Slice(const Slice& copy) = default; inline Slice(const Slice& copy) = default;
inline Slice(Slice&& copy) : _area(copy._area), _size(copy._size){ *const_cast<size_t*>(&copy._size) = 0; } inline Slice(Slice&& copy) : _area(copy._area), _size(copy._size){ *const_cast<size_t*>(&copy._size) = 0; }
Slice() = delete; Slice() = delete;
inline size_t size() const override { return _size; }
protected:
inline const void* area() const override { return _area; } inline const void* area() const override { return _area; }
inline void* area() override { return _area; } inline void* area() override { return _area; }
inline size_t size() const override { return _size; }
private: private:
void* const _area; void* const _area;

@ -3,6 +3,8 @@
#include <cow.hpp> #include <cow.hpp>
#include <utility> #include <utility>
XXX: Fuck this. Rewrite to use composition. Inheritance is a comlpete joke.
template<typename T> template<typename T>
struct TypedCow : private Cow, public _cow_util::Span<T> { struct TypedCow : private Cow, public _cow_util::Span<T> {
struct Fake; struct Fake;
@ -17,35 +19,44 @@ struct TypedCow : private Cow, public _cow_util::Span<T> {
template<typename... Args> template<typename... Args>
inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz) { init_copy( T(std::forward<Args>(args)...) ); } inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz) { init_copy( T(std::forward<Args>(args)...) ); }
inline ~TypedCow() { uninit(); } virtual inline ~TypedCow() { uninit(); }
inline void* area() { return Cow::area(); }
inline const void* area() const { return Cow::area(); }
inline size_t size() const override { return Cow::size() / sizeof(T); }
inline T& operator[](size_t i) { if (i>=size()) throw "idx"; else return *reinterpret_cast<T*>(this->as_bytes() + (sizeof(T) * i)); } inline Cow::Fake clone() const override { return Cow::clone(); }
inline const T& operator[](size_t i) const { if (i>=size()) throw "idx"; else return *reinterpret_cast<const T*>(this->as_bytes() + (sizeof(T) * i)); } inline Fake clone() const { return Fake(Cow::clone()); }
inline size_t size() const override { return Cow::size() / sizeof(T); }
protected: protected:
// Should only be used for creating Fakes. Copies the refcounted pointer. inline void* area() override { return Cow::area(); }
inline TypedCow(const TypedCow<T>& copy) : Cow(copy.super) {} inline const void* area() const override { return Cow::area(); }
//// Should only be used for creating Fakes. Copies the refcounted pointer.
//inline TypedCow(const TypedCow<T>& copy) : Cow(copy.super) {}
// UNSAFE: Placement-new's copys of `copy_from` into `0..size()` of this instance. // UNSAFE: Placement-new's copys of `copy_from` into `0..size()` of this instance.
inline void init_copy(const T& copy_from) { inline void init_copy(const T& copy_from) {
unsigned char* bytes = this->as_bytes(); T* ptr = _cow_util::Span<T>::ptr();
for(size_t i=0;i<size();i++) for(size_t i=0;i<size();i++)
new ((void*)(bytes + (sizeof(T)*i))) T(copy_from); new ((void*)(ptr+i)) T(copy_from);
} }
// UNSAFE: Explicitly calls destructors of each element in this instance. // UNSAFE: Explicitly calls destructors of each element in this instance.
inline void uninit() { inline void uninit() {
unsigned char* bytes = this->as_bytes(); T* ptr = _cow_util::Span<T>::ptr();
for(size_t i=0;i<size();i++) for(size_t i=0;i<size();i++)
reinterpret_cast<T*>(bytes + (sizeof(T)*i))->~T(); (ptr+i)->~T();
} }
}; };
template<typename T> template<typename T>
struct TypedCow<T>::Fake : private Cow::Fake, public _cow_util::Span<T> { struct TypedCow<T>::Fake : private Cow::Fake, public _cow_util::Span<T> {
Fake() = delete;
explicit inline Fake(Cow::Fake&& untyped) : Cow::Fake(untyped){}
inline Fake(const Fake& copy) : Fake(copy.Cow::Fake::clone()){}
inline Fake(Fake&& move) : Cow::Fake(std::move(move)) {}
inline ~Fake(){}
inline size_t size() const override { return Cow::Fake::size(); }
protected:
inline const void* area() const override { return Cow::Fake::area(); }
inline void* area() override { return Cow::Fake::area(); }
}; };

@ -147,7 +147,7 @@ namespace Tiling {
template<typename T = unsigned char> template<typename T = unsigned char>
void print_slice(Slice<T> memory) void print_slice(Slice<T> memory)
{ {
printf("slice: { %p, %lu (%lu bytes) }\n", memory.area(), memory.size(), memory.size_bytes()); printf("slice: { %p, %lu (%lu bytes) }\n", memory.ptr(), memory.size(), memory.size_bytes());
} }
@ -210,7 +210,7 @@ int main()
Cow::Fake clone = real; Cow::Fake clone = real;
printf("Fake size: %lu\n", clone.size()); printf("Fake size: %lu\n", clone.size());
printf("Fake ptr: %p\n", clone.area()); printf("Fake ptr: %p\n", clone.ptr());
read_fake(clone); read_fake(clone);
write_fake(clone, "hello fake!"); write_fake(clone, "hello fake!");

Loading…
Cancel
Save