aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-01-11 06:00:41 -0800
committerChris Robinson <[email protected]>2019-01-11 06:00:41 -0800
commit8aedaea5fb92d9cfed0a3e1f959f903fca713ec3 (patch)
tree3f92c5765780c00ea0109c2b45ee7d7b86e65782
parente7d77f5caa424597ab8023f92f00bfa50f8b78f8 (diff)
Add a flexible array template container
-rw-r--r--common/almalloc.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/common/almalloc.h b/common/almalloc.h
index 15d0263a..a2abc200 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -90,6 +90,48 @@ template<typename T, typename ...ArgsT>
std::unique_ptr<T> make_unique(ArgsT&&...args)
{ return std::unique_ptr<T>{new T{std::forward<ArgsT>(args)...}}; }
+
+/* A flexible array type. Used either standalone or at the end of a parent
+ * struct, with placement new, to have a run-time-sized array that's embedded
+ * with its size.
+ */
+template<typename T,size_t alignment=DEF_ALIGN>
+struct FlexArray {
+ const size_t mSize;
+ alignas(alignment) T mArray[];
+
+ static constexpr size_t CalcSizeof(size_t count) noexcept
+ { return std::max<size_t>(offsetof(FlexArray, mArray) + sizeof(T)*count, sizeof(FlexArray)); }
+
+ FlexArray(size_t size) : mSize{size}
+ { new (mArray) T[mSize]; }
+ ~FlexArray()
+ {
+ for(size_t i{0u};i < mSize;++i)
+ mArray[i].~T();
+ }
+
+ FlexArray(const FlexArray&) = delete;
+ FlexArray& operator=(const FlexArray&) = delete;
+
+ size_t size() const noexcept { return mSize; }
+
+ T *data() noexcept { return mArray; }
+ const T *data() const noexcept { return mArray; }
+
+ T& operator[](size_t i) noexcept { return mArray[i]; }
+ const T& operator[](size_t i) const noexcept { return mArray[i]; }
+
+ T *begin() noexcept { return mArray; }
+ const T *begin() const noexcept { return mArray; }
+ const T *cbegin() const noexcept { return mArray; }
+ T *end() noexcept { return mArray + mSize; }
+ const T *end() const noexcept { return mArray + mSize; }
+ const T *cend() const noexcept { return mArray + mSize; }
+
+ DEF_PLACE_NEWDEL()
+};
+
} // namespace al
#endif /* AL_MALLOC_H */