From 28cd1523faaf053e520fff822bd89cb5aa7a8e62 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 29 Mar 2026 17:19:23 -0400 Subject: [PATCH] xo-gc stack: + gc-report-object-types() primitive --- include/xo/object2/DDictionary.hpp | 7 +++++ include/xo/object2/DInteger.hpp | 2 ++ src/object2/DArray.cpp | 22 ++++++++++++++-- src/object2/DDictionary.cpp | 42 ++++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 7 deletions(-) diff --git a/include/xo/object2/DDictionary.hpp b/include/xo/object2/DDictionary.hpp index af66f3e..63a7eba 100644 --- a/include/xo/object2/DDictionary.hpp +++ b/include/xo/object2/DDictionary.hpp @@ -112,6 +112,8 @@ namespace xo { /** return value associated with @p key, if key is present **/ std::optional> lookup(const DString * key) const noexcept; + /** return value associated with @p key, if key is present **/ + std::optional> lookup_cstr(const char * key) const noexcept; /** return element @p key-value pair at position @p index (0-based) **/ std::pair> at_index(size_type index) const; @@ -139,6 +141,11 @@ namespace xo { **/ bool try_update(const pair_type & kvpair); + /** update key-value pair for existing @p key to map to @p value. + * false if @p key not already present. + **/ + bool try_update_cstr(const char * key, obj value); + /** convenience method: * try_upsert pair (k, @p value), after boxing c-style string @p key with @p mm to get k **/ diff --git a/include/xo/object2/DInteger.hpp b/include/xo/object2/DInteger.hpp index f1fa16a..a67e18d 100644 --- a/include/xo/object2/DInteger.hpp +++ b/include/xo/object2/DInteger.hpp @@ -35,6 +35,8 @@ namespace xo { operator long() const noexcept { return value_; } + void assign_value(long x) noexcept { this->value_ = x; } + // GCObject facet std::size_t shallow_size() const noexcept; diff --git a/src/object2/DArray.cpp b/src/object2/DArray.cpp index 8ec7369..a55fbf9 100644 --- a/src/object2/DArray.cpp +++ b/src/object2/DArray.cpp @@ -101,7 +101,7 @@ namespace xo { bool DArray::resize(size_type new_z) noexcept { - if (new_z >= capacity_) { + if (new_z > capacity_) { return false; } else if (new_z > size_) { // ensure new size is zeroed (we/re not zeroing if/when we shrink) @@ -149,7 +149,25 @@ namespace xo { pps->write("]"); return true; } else { - pps->write("[...]"); + pps->write("["); + + for (size_type i = 0, n = this->size(); i < n; ++i) { + if (i == 0) { + /* indent, but credit initial [ */ + pps->indent(std::max(pps->indent_width(), 1u) - 1); + } else { + /* indent after newline */ + pps->newline_indent(ppii.ci1()); + } + + obj elt = this->at(i).to_facet(); + + assert(elt.data()); + + pps->pretty(elt); + } + + pps->write("]"); return false; } } diff --git a/src/object2/DDictionary.cpp b/src/object2/DDictionary.cpp index faa4458..d585ded 100644 --- a/src/object2/DDictionary.cpp +++ b/src/object2/DDictionary.cpp @@ -50,6 +50,21 @@ namespace xo { return {}; } + std::optional> + DDictionary::lookup_cstr(const char * key) const noexcept + { + for (DArray::size_type i = 0, z = keys_->size(); i < z; ++i) { + auto i_key = obj::from(keys_->at(i)); + + assert(i_key); + + if (strcmp(key, i_key->data()) == 0) + return values_->at(i); + } + + return {}; + } + std::pair> DDictionary::at_index(size_type ix) const { @@ -104,6 +119,24 @@ namespace xo { return false; } + bool + DDictionary::try_update_cstr(const char * key, obj value) + { + for (size_type i = 0, n = keys_->size(); i < n; ++i) { + auto key_i = obj::from((*keys_)[i]); + + assert(key_i); + + if (strcmp(key, key_i->data()) == 0) { + values_->assign_at(i, value); + + return true; + } + } + + return false; + } + bool DDictionary::try_upsert_cstr(obj mm, const char * key_cstr, obj value) { @@ -183,8 +216,7 @@ namespace xo { pps->write("{"); for (size_type i = 0, n = this->size(); i < n; ++i) { - if (i > 0) - pps->write(" "); + pps->write(" "); obj key = FacetRegistry::instance().variant((*keys_)[i]); @@ -203,7 +235,7 @@ namespace xo { pps->write(";"); } - pps->write("}"); + pps->write(" }"); return true; } else { pps->write("{"); @@ -211,10 +243,10 @@ namespace xo { for (size_type i = 0, n = this->size(); i < n; ++i) { if (i == 0) { /* indent, but credit initial {. using same line for first (key,value) */ - ppii.pps()->indent(std::max(ppii.pps()->indent_width(), 1u) - 1); + pps->indent(std::max(pps->indent_width(), 1u) - 1); } else { /* indent after newline */ - ppii.pps()->newline_indent(ppii.ci1()); + pps->newline_indent(ppii.ci1()); } obj key