seems to work?

cpp
Avril 4 years ago
parent 4b7180ed5d
commit 525c81c150
Signed by: flanchan
GPG Key ID: 284488987C31F630

BIN
cow.o

Binary file not shown.

@ -3,6 +3,7 @@
#ifdef __cplusplus #ifdef __cplusplus
#define restrict __restrict__ #define restrict __restrict__
extern "C" {
#endif #endif
#include <stdlib.h> #include <stdlib.h>
@ -35,6 +36,7 @@ size_t cow_size(const cow_t* cow);
#ifdef __cplusplus #ifdef __cplusplus
#undef restrict #undef restrict
}
#endif #endif
#endif /* _COW_H */ #endif /* _COW_H */

@ -5,34 +5,52 @@
#include <memory> #include <memory>
struct Cow { struct Cow {
struct Fake;
Cow() = delete; Cow() = delete;
Cow(size_t size); Cow(size_t size);
Cow(Cow&& m); Cow(Cow&& m);
virtual ~Cow(); virtual ~Cow();
virtual Fake clone() const;
inline void* area() { return cow_ptr(get_raw()); }
inline const void* area() const { return cow_ptr_of(const void, get_raw()); }
inline size_t size() const { return cow_size(get_raw()); }
static Cow from_raw(cow_t* owned); inline unsigned char* as_bytes() { return (unsigned char*)area(); }
inline const unsigned char* as_bytes() const { return (const unsigned char*)area(); }
struct Fake; unsigned char& operator[](size_t index);
const unsigned char& operator[](size_t index) const;
static Cow from_raw(cow_t* owned);
private: private:
struct _inner; struct _inner;
Cow(cow_t* raw); Cow(cow_t* raw);
protected: protected:
const std::shared_ptr<_inner> super;
Cow(const Cow& c); Cow(const Cow& c);
const std::shared_ptr<_inner> super;
virtual cow_t* get_raw() const;
}; };
struct Cow::Fake : Cow { struct Cow::Fake : Cow {
Fake() = delete; Fake() = delete;
Fake(const Fake& copy);
Fake(Fake&& move);
~Fake();
Fake(const Fake& c); Fake clone() const override;
Fake(Fake&& m);
~Fake(); static Fake from_real(const Cow& real);
static Fake from_parent(const Cow& parent);
protected:
cow_t* get_raw() const override;
private: private:
Fake(const Cow& parent); Fake(const Cow& real);
cow_t* fake;
};
cow_t* const fake;
};

@ -24,16 +24,36 @@ Cow::_inner::_inner(cow_t* ptr) : ptr(ptr){}
Cow::Cow(size_t size) : super(std::make_shared<_inner>(size)){} Cow::Cow(size_t size) : super(std::make_shared<_inner>(size)){}
Cow::Cow(cow_t* raw) : super(std::make_shared<_inner>(raw)){} Cow::Cow(cow_t* raw) : super(std::make_shared<_inner>(raw)){}
Cow::~Cow(){}
Cow::Cow(Cow&& m) : super(std::move(*const_cast<std::shared_ptr<_inner>*>(&super))){} Cow::Cow(Cow&& m) : super(std::move(*const_cast<std::shared_ptr<_inner>*>(&super))){}
Cow::Cow(const Cow& c) : super(c.super){}
Cow::~Cow(){}
Cow Cow::from_raw(cow_t* owned) { if(cow_is_fake(owned)) throw "Trying to create real from fake raw"; else return Cow(owned); } Cow Cow::from_raw(cow_t* owned) { if(cow_is_fake(owned)) throw "Trying to create real from fake raw"; else return Cow(owned); }
Cow::Fake::Fake(const Cow& parent) : Cow(parent), fake(cow_clone(parent.super->ptr)){} Cow::Fake Cow::clone() const { return Fake::from_real(*this); }
Cow::Fake::~Fake() { if(fake) { cow_free(fake); *const_cast<cow_t**>(&fake) = nullptr; } } cow_t* Cow::get_raw() const { return super->ptr; }
Cow::Fake Cow::Fake::from_parent(const Cow& parent) { return Fake(parent); }
Cow::Fake::Fake(const Cow& copy) : Cow(copy), fake(cow_clone(copy.super->ptr)){}
Cow::Fake::Fake(const Fake& copy) : Fake(*static_cast<const Cow*>(&copy)){}
Cow::Fake::Fake(Fake&& move) : Cow(std::move(move)), fake(move.fake) Cow::Fake::Fake(Fake&& move) : Cow(std::move(move)), fake(move.fake)
{ {
*const_cast<cow_t**>(&fake) = nullptr; *const_cast<cow_t**>(&move.fake) = nullptr;
}
Cow::Fake::~Fake() { if(fake) cow_free(fake); }
Cow::Fake Cow::Fake::Fake::from_real(const Cow& real) { return Fake(real); }
Cow::Fake Cow::Fake::clone() const { return Fake(*this); }
cow_t* Cow::Fake::get_raw() const { return fake; }
// Operators
unsigned char& Cow::operator[](size_t index) {
if(index >= size()) throw "Size too large";
return as_bytes()[index];
}
const unsigned char& Cow::operator[](size_t index) const {
if(index >= size()) throw "Size too large";
return as_bytes()[index];
} }

@ -0,0 +1,12 @@
#include <cow.hpp>
int main()
{
Cow real(4096);
Cow::Fake clone = real.clone();
{
Cow::Fake clone2 = clone.clone();
}
return 0;
}
Loading…
Cancel
Save