/** @file DList.cpp * * @author Roland Conybeare, Dec 2025 **/ #include "DList.hpp" #include "list/IPrintable_DList.hpp" #include "list/IGCObject_DList.hpp" #include #include #include #include #include #include namespace xo { using xo::print::APrintable; using xo::mm::AGCObject; using xo::facet::FacetRegistry; using xo::facet::typeseq; namespace scm { static DList s_null(obj(), nullptr); DList * DList::_nil() { return &s_null; } DList * DList::_cons(obj mm, obj car, DList * cdr) { void * mem = mm.alloc_for(); return new (mem) DList(car, cdr); } #ifdef OBSOLETE DList * DList::list(obj mm, obj h1) { void * mem = mm.alloc(typeseq::id(), sizeof(DList)); return new (mem) DList(h1, DList::_nil()); } DList * DList::list(obj mm, obj h1, obj h2) { void * mem = mm.alloc(typeseq::id(), sizeof(DList)); return new (mem) DList(h1, DList::list(mm, h2)); } #endif bool DList::is_empty() const noexcept { return this == &s_null; } auto DList::size() const noexcept -> size_type { const DList * l = this; size_type z = 0; while (l && l != &s_null) { ++z; l = l->rest_; } return z; } auto DList::at(size_type index) const -> obj { size_type ix = index; const DList * l = this; while (l->rest_ && (ix > 0)) { --ix; l = l->rest_; } if (ix > 0) { assert(l == nullptr); throw std::runtime_error (tostr("DList::at: out-of-range index where [0..z) expected", xtag("index", index), xtag("z", this->size()))); } assert(l); return l->head_; } void DList::assign_rest(DList * r) { scope log(XO_DEBUG(true), "need write barrier"); this->rest_ = r; } bool DList::pretty(const ppindentinfo & ppii) const { /* adapted from ppstate.pretty_struct(), see also */ using xo::print::ppstate; ppstate * pps = ppii.pps(); if (ppii.upto()) { /* perhaps print on one line */ pps->write("("); /* TODO: probably use iterators here, when available */ const DList * l = this; size_t i = 0; while (!l->is_empty()) { if (i > 0) pps->write(" "); obj elt = FacetRegistry::instance().variant(l->head_); assert(elt.data()); if (!pps->print_upto(elt)) return false; l = l->rest_; ++i; } pps->write(")"); return true; } else { pps->write("(...)"); return false; } } // ----- GCObject facet ------ auto DList::shallow_size() const noexcept -> size_type { return sizeof(DList); } DList * DList::shallow_copy(obj mm) const noexcept { return mm.std_copy_for(this); } auto DList::forward_children(obj gc) noexcept -> size_type { //scope log(XO_DEBUG(true)); gc.forward_inplace(&head_); //gc.forward_inplace(head_.iface(), (void **)&(head_.data_)); gc.forward_inplace(&rest_); //auto iface = xo::facet::impl_for(); //gc.forward_inplace(&iface, (void **)(&rest_)); return this->shallow_size(); } } /*namespace scm*/ } /*namespace xo*/ /* end DList.cpp */