/** @file DArray.cpp * * @author Roland Conybeare, Jan 2026 **/ #include "DArray.hpp" #include #include #include namespace xo { using xo::mm::AGCObject; using xo::facet::typeseq; namespace scm { DArray * DArray::empty(obj mm, size_type cap) { assert(cap > 0); DArray * result = nullptr; if (cap > 0) { void * mem = mm.alloc(typeseq::id(), sizeof(DArray) + cap * sizeof(obj)); result = new (mem) DArray(); assert(result); result->capacity_ = cap; result->size_ = 0; } return result; } obj DArray::at(size_type ix) const { if (ix < size_) { return elts_[ix]; } else { throw std::runtime_error(tostr("DArray::at: out-of-range index where [0..z) expected", xtag("index", ix), xtag("z", this->size()))); return obj(); } } bool DArray::push_back(obj elt) noexcept { if (size_ >= capacity_) { return false; } else { static_assert(!std::is_trivially_constructible_v>); void * mem = &(elts_[size_]); new (mem) obj(elt); ++(this->size_); return true; } } // gc hooks for IGCObject_DArray std::size_t DArray::shallow_size() const noexcept { return sizeof(DArray); } DArray * DArray::shallow_copy(obj mm) const noexcept { DArray * copy = (DArray *)mm.alloc_copy((std::byte *)this); if (copy) { copy->capacity_ = capacity_; copy->size_ = size_; constexpr auto c_obj_z = sizeof(obj); /* memcpy sufficient for obj */ ::memcpy((void*)&(copy->elts_[0]), (void*)&(elts_[0]), capacity_ * c_obj_z); } return copy; } std::size_t DArray::forward_children(obj gc) noexcept { for (size_type i = 0; i < size_; ++i) { obj & elt = elts_[i]; gc.forward_inplace(elt.iface(), (void **)&(elt.data_)); } return shallow_size(); } } /*namespace scm*/ } /*namespace xo*/