/** @file DList.hpp * * @author Roland Conybeare, Dec 2025 **/ #pragma once #include //#include "xo/alloc2/gcobject/RGCObject.hpp" #include #include namespace xo { namespace scm { // TODO: consider renaming to DCons struct DList { using size_type = std::size_t; using AGCObject = xo::mm::AGCObject; using AAllocator = xo::mm::AAllocator; using ppindentinfo = xo::print::ppindentinfo; DList(xo::obj h, DList * r) : head_{h}, rest_{r} {} template static obj nil(); /** shortcut for * cons(mm, cdr, cdr.data()) **/ template static obj cons(obj mm, obj car, obj cdr); /** sentinel for null list **/ static DList * _nil(); /** list with first element @p car, * followed by contents of list @p cdr. * Shares structure with @p cdr **/ static DList * _cons(obj mm, obj car, DList * cdr); /** list with one element @p h1, allocated from @p mm **/ static DList * list(obj mm, obj h1); /** list with two elements @p h1, @p h2, allocated from @p mm **/ static DList * list(obj mm, obj h1, obj h2); /** 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; /** pretty-printing driver; combine layout+printing **/ bool pretty(const ppindentinfo & ppii) const; /** first member of list **/ obj head_; /** remainder of list **/ DList * rest_ = nullptr; }; template obj DList::nil() { return obj(DList::_nil()); } template obj DList::cons(obj mm, obj car, obj cdr) { return obj(DList::_cons(mm, car, cdr.data())); } } /*namespace scm*/ } /*namespace xo*/ /* end DList.hpp */