17namespace ds::linked_list
47 { t.cell_reset() } -> std::same_as<void>;
63 { t.cell_is_singleton() } -> std::same_as<bool>;
68 { t.cell_is_singleton_check() } -> std::same_as<bool>;
73 { t.cell_is_doubleton() } -> std::same_as<bool>;
90 template<cell::HasCellOperations T>
94 return e == e->cell_prev();
97 template<cell::HasCellOperations T>
98 requires(cell::HasIsSingleton<T>)
99 __always_inline
bool is_singleton(T *e)
101 return e->cell_is_singleton();
111 template<cell::HasCellOperations T>
112 requires(!cell::HasIsSingletonCheck<T>)
115 return (e == e->cell_next()) && (e == e->cell_prev());
118 template<cell::HasCellOperations T>
119 requires(cell::HasIsSingletonCheck<T>)
120 __always_inline
bool is_singleton_check(T *e)
122 return e->is_singleton_check();
135 template<cell::HasCellOperations T>
136 requires(!cell::HasIsDoubleton<T>)
139 return e->cell_prev() == e->cell_next();
142 template<cell::HasCellOperations T>
143 requires(cell::HasIsDoubleton<T>)
144 __always_inline
bool is_doubleton(T *e)
146 return e->cell_is_doubleton();
155 template<cell::HasCellOperations T>
158 return (e == e->cell_prev()->cell_next()) &&
159 (e == e->cell_next()->cell_prev());
175 template<cell::HasCellOperations Cell>
178 curr->cell_prev()->cell_next() = elem->cell_next();
179 elem->cell_next()->cell_prev() = curr->cell_prev();
180 curr->cell_prev() = elem;
181 elem->cell_next() = curr;
196 template<cell::HasCellOperations Cell,
typename P>
200 auto prev = curr->cell_prev();
201 elem->cell_next() = curr;
202 elem->cell_prev() = prev;
203 prev->cell_next() = elem;
219 template<cell::HasCellOperations Cell,
typename P>
223 auto next = curr->cell_next();
224 elem->cell_prev() = curr;
225 elem->cell_next() = next;
226 next->cell_prev() = elem;
253 template<cell::HasCellOperations Cell>
256 auto p = el->cell_prev();
257 auto n = er->cell_next();
263 template<cell::HasCellOperations Cell>
264 __always_inline Cell *unsafe_remove(Cell *e)
266 return unsafe_remove(e, e);
275 template<cell::HasCellOperations Cell>
278 auto next = rem->cell_next();
279 auto prevnext = prev->cell_next();
281 next->cell_prev() = prev;
310 template<cell::HasCellOperations Cell>
311 __always_inline Cell *
remove(Cell *el, Cell *er)
314 el->cell_prev() = er;
315 er->cell_next() = el;
319 template<cell::HasCellOperations Cell>
320 __always_inline Cell *remove(Cell *e)
332 template<cell::HasCellOperations Cell,
typename F>
333 __always_inline
bool search(Cell *from, Cell *to, F f)
336 for (elem = from; elem != to; elem = elem->cell_next())
351 template<cell::HasCellOperations Cell,
typename F>
352 __always_inline
bool search(Cell *elem, F f)
354 return search(
static_cast<Cell *
>(elem->cell_next()), elem, f);
361 template<cell::HasCellOperationsReset CellTemplateArg>
364 using Cell = CellTemplateArg;
377 Cell
sentinel __attribute__((__cheri_no_subobject_bounds__)) = {};
379 __always_inline
void reset()
384 __always_inline
bool is_empty()
389 __always_inline
void append(Cell *elem)
391 linked_list::insert_before(&
sentinel, elem);
394 __always_inline
void append_emplace(Cell *elem)
396 linked_list::emplace_before(&
sentinel, elem);
399 __always_inline
void prepend(Cell *elem)
401 linked_list::insert_before(elem, &
sentinel);
404 __always_inline Cell *first()
409 __always_inline Cell *last()
414 __always_inline Cell *unsafe_take_first()
417 linked_list::unsafe_remove_link(&
sentinel, f);
421 __always_inline Cell *take_all()
423 auto p = linked_list::unsafe_remove(&
sentinel);
429 __always_inline
bool search(F f)
431 return linked_list::search(&
sentinel, f);
441 Pointer *prev, *next;
449 __always_inline
void cell_reset()
454 __always_inline
auto cell_next()
459 __always_inline
auto cell_prev()
471 class __cheri_no_subobject_bounds PtrAddr
473 ptraddr_t prev, next;
482 __always_inline
void cell_reset()
487 __always_inline
auto cell_next()
492 __always_inline
auto cell_prev()
502 __always_inline
bool cell_is_singleton()
507 __always_inline
bool cell_is_doubleton()
521 template<ptrdiff_t Offset>
524 ptraddr_t prev, next;
534 __always_inline
void cell_reset()
539 __always_inline
auto cell_next()
545 __always_inline
auto cell_prev()
556 __always_inline
bool cell_is_singleton()
561 __always_inline
bool cell_is_doubleton()
Helper class for accessing capability properties on pointers.
AddressProxy address()
Access the address of the capability.
Like the above, but with a constant offset on the interpretation of its addresss fields.
Pointer references are pointer proxies, shockingly enough.
Equipped with a context for bounds, an address reference can be a proxy for a pointer.
The primitive, required, abstract interface to our cons cells.
Additional, optional overrides available within implementation of cons cells.
Reset a cell to a singleton ring.
Proxies<P,T> if P is a proxy object for T*-s.
bool is_singleton_check(T *e)
Like is_singleton(), but checks both edges.
bool is_singleton(T *e)
Self-loops indicate either the sentinels of an empty list or, less often, singletons without their se...
void emplace_before(P curr, Cell *elem)
Emplacement before.
bool is_doubleton(T *e)
Doubletons are either singleton collections (with both the sentinel and the single element satisfying...
Cell * unsafe_remove(Cell *el, Cell *er)
Remove from the list without turning the removed span into a well-formed ring.
bool is_well_formed(T *e)
Verify linkage invariants.
void emplace_after(P curr, Cell *elem)
Emplacement after.
Cell * remove(Cell *el, Cell *er)
Remove from the ring, cleaving the ring into two well-formed rings.
void insert_before(Cell *curr, Cell *elem)
Insert a ring of elem-ents (typically, a singleton ring) before the curr-ent element (or sentinel) in...
bool search(Cell *from, Cell *to, F f)
Search through a span of a ring, inclusively from from through exclusively to to, applying f to each ...
auto unsafe_remove_link(Cell *prev, Cell *rem)
Remove a particular element rem from the ring, already knowing its adjacent, previous link prev.
Convenience wrapper for a sentinel cons cell, encapsulating some common patterns.
Cell sentinel
The sentinel node itself.