18 # include <functional>
25 template <
typename T,
typename Compare = std::less<T> >
28 template <
typename ChildClass>
52 # if __cplusplus >= 201103L
92 template <
typename T_,
typename Compare>
118 return *
static_cast<type*
>(m_tail);
126 if(m_tail ==
nullptr) {
128 m_tail = m_head = elem.
prev = elem.
next = &elem;
142 if(m_tail == m_head) {
143 m_tail = m_head =
nullptr;
147 m_tail = m_tail->
prev;
159 return *
static_cast<type*
>(m_head);
167 if(m_head ==
nullptr) {
169 m_tail = m_head = elem.
prev = elem.
next = &elem;
183 if(m_tail == m_head) {
184 m_tail = m_head =
nullptr;
188 m_head = m_head->
next;
199 zth_assert(m_head !=
nullptr || m_tail ==
nullptr);
200 return m_head ==
nullptr;
209 m_head = m_tail =
nullptr;
221 return !m_current && m_start;
226 return m_current == m_start;
231 return atBegin() ? m_start : m_current;
236 return m_current == rhs.m_current;
241 return !(*
this == rhs);
254 m_current = m_current->
prev == m_start ? nullptr : m_current->
prev;
288 return *
static_cast<type*
>(elem);
314 if(it.get() == &elem)
332 }
else if(pos.atBegin()) {
350 }
else if(pos.get() == m_tail) {
363 if(m_head == &elem) {
365 }
else if(m_tail == &elem) {
368 elem.prev->next = elem.next;
369 elem.next->prev = elem.prev;
371 elem.next = elem.prev =
nullptr;
378 if(it.get() == &elem)
395 template <
typename T,
typename Compare>
436 x.left = x.right =
nullptr;
448 m_t = m_head =
nullptr;
471 else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
473 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
475 else if((uintptr_t)&x < (uintptr_t)t)
486 return static_cast<type&
>(*m_head);
496 else if(t->left->level == t->level) {
509 else if(!t->right || !t->right->right)
511 else if(t->level == t->right->right->level) {
515 zth_assert(r->level < std::numeric_limits<decltype(r->level)>::max());
526 x.left = x.right =
nullptr;
528 }
else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
530 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
531 t->right =
insert_(x, t->right);
532 else if((uintptr_t)&x < (uintptr_t)t)
535 t->right =
insert_(x, t->right);
537 if(t == m_head && t->
left)
548 if(!t->left && !t->right) {
550 }
else if(!t->left) {
563 }
else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
565 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
566 t->right =
delete_(x, t->right);
567 else if((uintptr_t)&x < (uintptr_t)t)
570 t->right =
delete_(x, t->right);
574 t->right =
skew(t->right);
576 t->right->right =
skew(t->right->right);
578 t->right =
split(t->right);
604 return t ?
lowest(t->right) :
nullptr;
609 return t ?
highest(t->left) :
nullptr;
615 decltype(t->level) ll = t->left ? t->left->level : 0;
616 decltype(t->level) lr = t->right ? t->right->level : 0;
617 decltype(t->level) should_be = (decltype(t->level))((ll < lr ? ll : lr) + 1u);
618 if(should_be < t->level) {
619 t->level = should_be;
620 if(t->right && should_be < t->right->level)
621 t->right->level = should_be;
628 zth_dbg(list,
"SortedList %p (head %p):",
this, m_head);
642 !t->left || m_comp(
static_cast<type&
>(*t->left),
static_cast<type&
>(*t))
643 || (!m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(*t->left))
644 && ((uintptr_t)t > (uintptr_t)t->left)));
646 !t->right || m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(*t->right))
647 || (!m_comp(
static_cast<type&
>(*t->right),
static_cast<type&
>(*t))
648 || ((uintptr_t)t < (uintptr_t)t->right)));
650 zth_assert(t->left || t->right || t->level == 1);
651 zth_assert(!t->left || t->left->level == t->level - 1);
653 !t->right || t->right->level == t->level - 1
654 || t->right->level == t->level);
655 zth_assert(!t->right || !t->right->right || t->right->right->level < t->level);
656 zth_assert(t->level < 2 || (t->left && t->right));
666 zth_dbg(list,
"%*s (null)", indent,
"");
668 zth_dbg(list,
"%*s node %p level=%d: %s", indent,
"",
static_cast<type*
>(t),
669 t->level,
static_cast<type*
>(t)->str().c_str());
bool operator==(iterator const &rhs) const noexcept
iterator operator--(int) noexcept
type * operator->() const noexcept
bool atEnd() const noexcept
iterator & operator++() noexcept
bool operator!=(iterator const &rhs) const noexcept
constexpr iterator(elem_type *start, elem_type *current=nullptr) noexcept
elem_type * get() const noexcept
bool atBegin() const noexcept
type & operator*() const noexcept
iterator & operator--() noexcept
iterator operator++(int) noexcept
iterator begin() const noexcept
size_t size() const noexcept
void erase(elem_type &elem) noexcept
bool contains(type &elem) const noexcept
bool empty() const noexcept
iterator erase(iterator const &pos) noexcept
bool contains(elem_type &elem) const noexcept
type & back() const noexcept
type & front() const noexcept
constexpr List() noexcept
void push_back(elem_type &elem) noexcept
iterator insert(iterator const &pos, elem_type &elem) noexcept
void push_front(elem_type &elem) noexcept
iterator end() const noexcept
void pop_front() noexcept
Listable< type > elem_type
void rotate(elem_type &elem) noexcept
type * listNext() const noexcept
Listable & operator=(Listable &&l) noexcept
constexpr Listable() noexcept
type * listPrev() const noexcept
Listable & operator=(Listable const &rhs) noexcept
constexpr Listable(Listable const &e) noexcept
Listable(Listable &&l) noexcept
void erase(elem_type &x) noexcept
void check() const noexcept
void insert(elem_type &x) noexcept
bool contains(elem_type &x) const noexcept
static void decrease_level(elem_type *t) noexcept
static elem_type * predecessor(elem_type *t) noexcept
type & front() const noexcept
size_t size() const noexcept
elem_type * insert_(elem_type &x, elem_type *t) noexcept
static elem_type * successor(elem_type *t) noexcept
static void print(elem_type *t, int indent=0) noexcept
elem_type * delete_(elem_type &x, elem_type *t) noexcept
static elem_type * highest(elem_type *t) noexcept
size_t check(elem_type *t) const noexcept
static elem_type * skew(elem_type *t) noexcept
constexpr SortedList() noexcept
static elem_type * lowest(elem_type *t) noexcept
bool empty() const noexcept
Listable< type > elem_type
static elem_type * split(elem_type *t) noexcept
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
static bool const EnableAssert
When true, enable zth_assert().
static int const Print_list
static bool const SupportDebugPrint
Add support to enable debug output prints.
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define ZTH_CLASS_NOCOPY(Class)