/** @file DList.hpp * * @author Roland Conybeare, Dec 2025 **/ #pragma once #include #include #include namespace xo { namespace scm { // TODO: consider renaming to DCons // See also ListOps in ListOps.hpp // struct DList { using size_type = std::size_t; using AGCObject = xo::mm::AGCObject; using AAllocator = xo::mm::AAllocator; using ACollector = xo::mm::ACollector; using ppindentinfo = xo::print::ppindentinfo; public: DList(xo::obj h, DList * r) : head_{h}, rest_{r} {} /** sentinel for null list. * Application code may prefer ListOps::nil() **/ static DList * _nil(); /** list with first element @p car, * followed by contents of list @p cdr. * Shares structure with @p cdr * Application code may prefer ListOps::cons() **/ static DList * _cons(obj mm, obj car, DList * cdr); /** DList length is at least 1 **/ bool is_empty() const noexcept; /** DList models a finite sequence **/ bool is_finite() const noexcept { return true; }; /** return number of elements in this DList **/ size_type size() const noexcept; /** return element at 0-based index @p ix **/ obj at(size_type ix) const; /** assign rest-pointer **/ void assign_rest(DList * r); /** pretty-printing driver; combine layout+printing **/ bool pretty(const ppindentinfo & ppii) const; // GCObject facet size_type shallow_size() const noexcept; DList * shallow_copy(obj mm) const noexcept; size_type forward_children(obj gc) noexcept; /** first member of list **/ obj head_; /** remainder of list **/ DList * rest_ = nullptr; }; } /*namespace scm*/ } /*namespace xo*/ /* end DList.hpp */