From 2c88d329b989b833dd8c00e21660f06fa6b64601 Mon Sep 17 00:00:00 2001 From: Avril Date: Fri, 11 Jun 2021 01:56:29 +0100 Subject: [PATCH] typed cow testing n stuff --- include/cow/typed.hpp | 51 +++++++++++++++++++++++-------------------- src/test/main.cpp | 7 ++++++ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/include/cow/typed.hpp b/include/cow/typed.hpp index 34f9572..dedadd7 100644 --- a/include/cow/typed.hpp +++ b/include/cow/typed.hpp @@ -6,39 +6,42 @@ template struct TypedCow : private Cow, public _cow_util::Span { struct Fake; - - inline TypedCow(size_t sz) : TypedCow(sz, T()) {} + friend class Fake; + + TypedCow() = delete; + inline TypedCow(TypedCow&& move) : Cow(std::move(move.super)) { /* Moves the shared_ptr. No need to move the elements. */ } + // protected: copy + + inline TypedCow(size_t sz) : Cow(sz * sizeof(T)) { init_copy(T()); } + inline TypedCow(size_t sz, const T& copy_from) : TypedCow(sz) { init_copy(copy_from); } template - inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz, T(std::forward(args)...)) {} + inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz) { init_copy( T(std::forward(args)...) ); } - inline TypedCow(TypedCow&& move) : Cow(std::move(move.super)) { - unsigned char* bytes = this->as_bytes(); - for(size_t i=0;i& copy) : Cow(copy.super) { - unsigned char* bytes = this->as_bytes(); - for(size_t i=0;ias_bytes(); - for(size_t i=0;i(bytes + (sizeof(T)*i))->~T(); - } + inline ~TypedCow() { uninit(); } - void* area() { return (*this).Cow::area(); } - const void* area() const { return (*this).Cow::area(); } - inline size_t size() const override { return (*this).Cow::size() / sizeof(T); } + 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(this->as_bytes() + (sizeof(T) * i)); } inline const T& operator[](size_t i) const { if (i>=size()) throw "idx"; else return *reinterpret_cast(this->as_bytes() + (sizeof(T) * i)); } - private: - inline explicit TypedCow(size_t sz, const T& copy_from) : Cow(sz * sizeof(T)) { + protected: + // Should only be used for creating Fakes. Copies the refcounted pointer. + inline TypedCow(const TypedCow& copy) : Cow(copy.super) {} + + // UNSAFE: Placement-new's copys of `copy_from` into `0..size()` of this instance. + inline void init_copy(const T& copy_from) { unsigned char* bytes = this->as_bytes(); - for(size_t i=0;ias_bytes(); + for(size_t i=0;i(bytes + (sizeof(T)*i))->~T(); } }; diff --git a/src/test/main.cpp b/src/test/main.cpp index 0dc4850..8df8991 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -169,6 +169,12 @@ void moving_cow(Cow moved) read_fake(moved); } +void typed_cow() +{ + TypedCow tc(1024); + +} + int main() { Cow _area(4000); @@ -217,6 +223,7 @@ int main() printf("First byte of: fake = %x\n", clone[0]); read_fake(clone); //clone still functions because of refcount on origin. + typed_cow(); printf("Last error: %d, %s\n", cow_err(), *cow_err_msg(cow_err())); try { Cow should_fail(SIZE_MAX);