From 26379aad1cab647cee3231ae9b72d1bfafb4f482 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 10 Apr 2026 20:31:26 -0400 Subject: [PATCH] xo-object2: DArray: + DArray.pop_back + no ub on oom --- xo-object2/include/xo/object2/DArray.hpp | 8 ++++- xo-object2/src/object2/DArray.cpp | 42 +++++++++++++++++++----- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/xo-object2/include/xo/object2/DArray.hpp b/xo-object2/include/xo/object2/DArray.hpp index 27b0961d..1d3499aa 100644 --- a/xo-object2/include/xo/object2/DArray.hpp +++ b/xo-object2/include/xo/object2/DArray.hpp @@ -111,10 +111,16 @@ namespace xo { bool assign_at(size_type index, obj elt) noexcept; /** append @p elt at the end of array. - * true on success, false otherwise + * true on success, false otherwise. + * on failure array is unaltered **/ bool push_back(obj elt) noexcept; + /** store last element in array into @p elt and decrement array size. + * true on success; false on failure (implies array was empty) + **/ + bool pop_back(obj * p_elt = nullptr) noexcept; + ///@} /** @defgroup darray-general general methods **/ ///@{ diff --git a/xo-object2/src/object2/DArray.cpp b/xo-object2/src/object2/DArray.cpp index c6e83ee6..a181f9c3 100644 --- a/xo-object2/src/object2/DArray.cpp +++ b/xo-object2/src/object2/DArray.cpp @@ -18,6 +18,7 @@ namespace xo { using xo::facet::typeseq; namespace scm { + // TODO: error reporting? DArray * DArray::empty(obj mm, size_type cap) @@ -27,12 +28,14 @@ namespace xo { void * mem = mm.alloc(typeseq::id(), sizeof(DArray) + cap * sizeof(obj)); - result = new (mem) DArray(); + if (mem) [[likely]] { + result = new (mem) DArray(); - assert(result); + assert(result); - result->capacity_ = cap; - result->size_ = 0; + result->capacity_ = cap; + result->size_ = 0; + } return result; } @@ -44,12 +47,14 @@ namespace xo { { DArray * dest = empty(mm, new_cap); - /** could just memcpy here **/ - for (size_type i = 0, n = src->size(); i < n; ++i) { - dest->elts_[i] = src->elts_[i]; - } + if (dest) [[likely]] { + /** could just memcpy here **/ + for (size_type i = 0, n = src->size(); i < n; ++i) { + dest->elts_[i] = src->elts_[i]; + } - dest->size_ = src->size(); + dest->size_ = src->size(); + } return dest; } @@ -98,6 +103,25 @@ namespace xo { } } + bool + DArray::pop_back(obj * p_elt) noexcept + { + if (size_ > 0) { + --size_; + + obj & last = elts_[size_]; + + if (p_elt) + *p_elt = last; + + last.reset(); // hygiene + + return true; + } + + return false; + } + bool DArray::resize(size_type new_z) noexcept {