mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-27 12:29:41 +00:00
83 lines
2.3 KiB
C++
83 lines
2.3 KiB
C++
/* LICENSE BEGIN
|
|
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
|
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
|
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
|
|
|
SPDX-License-Identifier: GPL-3.0-only
|
|
This file is also available under commercial licensing terms.
|
|
Please contact info@sixtyfps.io for more information.
|
|
LICENSE END */
|
|
#pragma once
|
|
#include "sixtyfps_sharedarray_internal.h"
|
|
#include <atomic>
|
|
|
|
namespace sixtyfps {
|
|
|
|
template<typename T>
|
|
struct SharedArray
|
|
{
|
|
SharedArray()
|
|
: inner(const_cast<SharedArrayHeader*>(reinterpret_cast<const SharedArrayHeader*>(
|
|
cbindgen_private::sixtyfps_shared_array_empty())))
|
|
{ }
|
|
|
|
SharedArray(const SharedArray &other)
|
|
: inner(other.inner)
|
|
{
|
|
if (inner->refcount > 0) {
|
|
++inner->refcount;
|
|
}
|
|
}
|
|
~SharedArray()
|
|
{
|
|
drop();
|
|
}
|
|
SharedArray &operator=(const SharedArray &other)
|
|
{
|
|
if (other.inner == inner) { return *this; }
|
|
drop();
|
|
inner = other.inner;
|
|
if (inner->refcount > 0) {
|
|
++inner->refcount;
|
|
}
|
|
return *this;
|
|
}
|
|
SharedArray &operator=(SharedArray &&other)
|
|
{
|
|
std::swap(inner, other.inner);
|
|
return *this;
|
|
}
|
|
|
|
const T *begin() const {
|
|
return reinterpret_cast<const T *>(inner + 1);
|
|
}
|
|
|
|
const T *end() const {
|
|
return begin() + inner->size;
|
|
}
|
|
|
|
private:
|
|
|
|
void drop() {
|
|
if (inner->refcount > 0 && (--inner->refcount) == 0) {
|
|
auto b = begin(), e = end();
|
|
for (auto it = b; it < e; ++it) {
|
|
it->~T();
|
|
}
|
|
}
|
|
cbindgen_private::sixtyfps_shared_array_free(
|
|
reinterpret_cast<uint8_t *>(inner),
|
|
sizeof(SharedArrayHeader) + inner->capacity * sizeof(T),
|
|
alignof(SharedArrayHeader));
|
|
}
|
|
|
|
// Unfortunately, this cannot be generated by cbindgen because std::atomic is not understood
|
|
struct SharedArrayHeader {
|
|
std::atomic<std::intptr_t> refcount;
|
|
std::size_t size;
|
|
std::size_t capacity;
|
|
};
|
|
static_assert(alignof(T) <= alignof(SharedArrayHeader), "Not yet supported because we would need to add padding");
|
|
SharedArrayHeader *inner;
|
|
};
|
|
}
|