C++: Add documentation for SharedVector

This commit is contained in:
Simon Hausmann 2021-06-24 17:04:58 +02:00
parent d9857a3308
commit f7c7d2e67a

View file

@ -15,14 +15,19 @@ LICENSE END */
namespace sixtyfps { namespace sixtyfps {
/// SharedVector is a vector template class similar to std::vector that's primarily used for passing
/// data in and out of the SixtyFPS run-time library. It uses implicit-sharing to make creating
/// copies cheap. Only when a function changes the vector's data, a copy is is made.
template<typename T> template<typename T>
struct SharedVector struct SharedVector
{ {
/// Creates a new, empty vector.
SharedVector() SharedVector()
: inner(const_cast<SharedVectorHeader *>(reinterpret_cast<const SharedVectorHeader *>( : inner(const_cast<SharedVectorHeader *>(reinterpret_cast<const SharedVectorHeader *>(
cbindgen_private::sixtyfps_shared_vector_empty()))) cbindgen_private::sixtyfps_shared_vector_empty())))
{ {
} }
/// Creates a new vector that holds all the elements of the given std::initializer_list \a args.
SharedVector(std::initializer_list<T> args) : SharedVector() SharedVector(std::initializer_list<T> args) : SharedVector()
{ {
auto new_array = SharedVector::with_capacity(args.size()); auto new_array = SharedVector::with_capacity(args.size());
@ -35,13 +40,17 @@ struct SharedVector
*this = std::move(new_array); *this = std::move(new_array);
} }
/// Creates a new vector that is a copy of \a other.
SharedVector(const SharedVector &other) : inner(other.inner) SharedVector(const SharedVector &other) : inner(other.inner)
{ {
if (inner->refcount > 0) { if (inner->refcount > 0) {
++inner->refcount; ++inner->refcount;
} }
} }
/// Destroys this vector. The underlying data is destroyed if no other
/// vector references it.
~SharedVector() { drop(); } ~SharedVector() { drop(); }
/// Assigns the data of \a other to this vector and returns a reference to this vector.
SharedVector &operator=(const SharedVector &other) SharedVector &operator=(const SharedVector &other)
{ {
if (other.inner == inner) { if (other.inner == inner) {
@ -54,46 +63,63 @@ struct SharedVector
} }
return *this; return *this;
} }
/// Move-assign's \a other to this vector and returns a reference to this vector.
SharedVector &operator=(SharedVector &&other) SharedVector &operator=(SharedVector &&other)
{ {
std::swap(inner, other.inner); std::swap(inner, other.inner);
return *this; return *this;
} }
/// Returns a const pointer to the first element of this vector.
const T *cbegin() const { return reinterpret_cast<const T *>(inner + 1); } const T *cbegin() const { return reinterpret_cast<const T *>(inner + 1); }
/// Returns a const pointer that points past the last element of this vector. The
/// pointer cannot be dereferenced, it can only be used for comparison.
const T *cend() const { return cbegin() + inner->size; } const T *cend() const { return cbegin() + inner->size; }
/// Returns a const pointer to the first element of this vector.
const T *begin() const { return cbegin(); } const T *begin() const { return cbegin(); }
/// Returns a const pointer that points past the last element of this vector. The
/// pointer cannot be dereferenced, it can only be used for comparison.
const T *end() const { return cend(); } const T *end() const { return cend(); }
/// Returns a pointer to the first element of this vector.
T *begin() T *begin()
{ {
detach(inner->size); detach(inner->size);
return reinterpret_cast<T *>(inner + 1); return reinterpret_cast<T *>(inner + 1);
} }
/// Returns a pointer that points past the last element of this vector. The
/// pointer cannot be dereferenced, it can only be used for comparison.
T *end() T *end()
{ {
detach(inner->size); detach(inner->size);
return begin() + inner->size; return begin() + inner->size;
} }
/// Returns the number of elements in this vector.
std::size_t size() const { return inner->size; } std::size_t size() const { return inner->size; }
/// Returns true if there are no elements on this vector; false otherwise.
bool empty() const { return inner->size == 0; } bool empty() const { return inner->size == 0; }
/// This indexing operator returns a reference to the \a index'th element of this vector.
T &operator[](std::size_t index) { return begin()[index]; } T &operator[](std::size_t index) { return begin()[index]; }
/// This indexing operator returns a const reference to the \a index'th element of this vector.
const T &operator[](std::size_t index) const { return begin()[index]; } const T &operator[](std::size_t index) const { return begin()[index]; }
/// Returns a reference to the \a index'th element of this vector.
const T &at(std::size_t index) const { return begin()[index]; } const T &at(std::size_t index) const { return begin()[index]; }
/// Appends the \a value as a new element to the end of this vector.
void push_back(const T &value) void push_back(const T &value)
{ {
detach(inner->size + 1); detach(inner->size + 1);
new (end()) T(value); new (end()) T(value);
inner->size++; inner->size++;
} }
/// Moves the \a value as a new element to the end of this vector.
void push_back(T &&value) void push_back(T &&value)
{ {
detach(inner->size + 1); detach(inner->size + 1);
@ -101,12 +127,16 @@ struct SharedVector
inner->size++; inner->size++;
} }
/// Returns true if the vector \a a has the same number of elements as \a b
/// and all the elements also compare equal; false otherwise.
friend bool operator==(const SharedVector &a, const SharedVector &b) friend bool operator==(const SharedVector &a, const SharedVector &b)
{ {
if (a.size() != a.size()) if (a.size() != a.size())
return false; return false;
return std::equal(a.cbegin(), a.cend(), b.cbegin()); return std::equal(a.cbegin(), a.cend(), b.cbegin());
} }
/// Returns false if the vector \a a has the same number of elements as \a b
/// and all the elements also compare equal; true otherwise.
friend bool operator!=(const SharedVector &a, const SharedVector &b) { return !(a == b); } friend bool operator!=(const SharedVector &a, const SharedVector &b) { return !(a == b); }
private: private: