typed cow testing n stuff

absolute-shit
Avril 4 years ago
parent 382efd5d43
commit 2c88d329b9
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -6,39 +6,42 @@
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;
friend class Fake;
inline TypedCow(size_t sz) : TypedCow(sz, T()) {} TypedCow() = delete;
inline TypedCow(TypedCow<T>&& 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<typename... Args> template<typename... Args>
inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz, T(std::forward<Args>(args)...)) {} inline TypedCow(size_t sz, Args&&... args) : TypedCow(sz) { init_copy( T(std::forward<Args>(args)...) ); }
inline TypedCow(TypedCow<T>&& move) : Cow(std::move(move.super)) { inline ~TypedCow() { uninit(); }
unsigned char* bytes = this->as_bytes();
for(size_t i=0;i<size();i++)
new ((void*)(bytes + (sizeof(T)*i))) T(std::move(move[i]));
}
inline TypedCow(const TypedCow<T>& copy) : Cow(copy.super) {
unsigned char* bytes = this->as_bytes();
for(size_t i=0;i<size();i++)
new ((void*)(bytes + (sizeof(T)*i))) T(copy[i]);
}
inline ~TypedCow() {
unsigned char* bytes = this->as_bytes();
for(size_t i=0;i<size();i++)
reinterpret_cast<T*>(bytes + (sizeof(T)*i))->~T();
}
void* area() { return (*this).Cow::area(); } inline void* area() { return Cow::area(); }
const void* area() const { return (*this).Cow::area(); } inline const void* area() const { return Cow::area(); }
inline size_t size() const override { return (*this).Cow::size() / sizeof(T); } 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 T& operator[](size_t i) { if (i>=size()) throw "idx"; else return *reinterpret_cast<T*>(this->as_bytes() + (sizeof(T) * i)); }
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 const T& operator[](size_t i) const { if (i>=size()) throw "idx"; else return *reinterpret_cast<const T*>(this->as_bytes() + (sizeof(T) * i)); }
private: protected:
inline explicit TypedCow(size_t sz, const T& copy_from) : Cow(sz * sizeof(T)) { // 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.
inline void init_copy(const T& copy_from) {
unsigned char* bytes = this->as_bytes(); unsigned char* bytes = this->as_bytes();
for(size_t i=0;i<sz;i++) for(size_t i=0;i<size();i++)
new ((void*)(bytes + (sizeof(T)*i))) T(copy_from); new ((void*)(bytes + (sizeof(T)*i))) T(copy_from);
}
// UNSAFE: Explicitly calls destructors of each element in this instance.
inline void uninit() {
unsigned char* bytes = this->as_bytes();
for(size_t i=0;i<size();i++)
reinterpret_cast<T*>(bytes + (sizeof(T)*i))->~T();
} }
}; };

@ -169,6 +169,12 @@ void moving_cow(Cow moved)
read_fake(moved); read_fake(moved);
} }
void typed_cow()
{
TypedCow<int> tc(1024);
}
int main() int main()
{ {
Cow _area(4000); Cow _area(4000);
@ -217,6 +223,7 @@ int main()
printf("First byte of: fake = %x\n", clone[0]); printf("First byte of: fake = %x\n", clone[0]);
read_fake(clone); //clone still functions because of refcount on origin. 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())); printf("Last error: %d, %s\n", cow_err(), *cow_err_msg(cow_err()));
try { try {
Cow should_fail(SIZE_MAX); Cow should_fail(SIZE_MAX);

Loading…
Cancel
Save