26template <
typename T = Listable,
typename Compare = std::less<T> >
52# if __cplusplus >= 201103L
85 template <
typename T,
typename Compare>
89template <
typename T = Listable>
98 template <
bool cyclic>
108 return !m_current && m_start;
113 return m_current == m_start;
129 return get() == rhs.get();
135 return !(*
this == rhs);
183 return *
static_cast<type*
>(elem);
191 user_type
const&
user() const noexcept
229 return *
static_cast<type*
>(m_tail);
251 if(m_tail ==
nullptr) {
253 m_tail = m_head = elem.
prev = elem.
next = &elem;
256 elem.next = m_tail->
next;
269 if(m_tail == m_head) {
270 m_tail = m_head =
nullptr;
274 m_tail = m_tail->
prev;
288 return *
static_cast<type*
>(m_head);
308 if(m_head ==
nullptr) {
310 m_tail = m_head = elem.
prev = elem.
next = &elem;
326 if(m_tail == m_head) {
327 m_tail = m_head =
nullptr;
331 m_head = m_head->
next;
344 zth_assert(m_head !=
nullptr || m_tail ==
nullptr);
345 return m_head ==
nullptr;
354 m_head = m_tail =
nullptr;
376 if(it.get() == &elem)
394 }
else if(pos.atBegin()) {
413 }
else if(pos.get() == m_tail) {
426 if(m_head == &elem) {
428 }
else if(m_tail == &elem) {
431 elem.prev->next = elem.next;
432 elem.next->prev = elem.prev;
434 elem.next = elem.prev =
nullptr;
451template <
typename T,
typename Compare>
492 x.left = x.right =
nullptr;
504 m_t = m_head =
nullptr;
527 else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
529 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
531 else if((uintptr_t)&x < (uintptr_t)t)
542 return static_cast<type&
>(*m_head);
552 else if(t->left->level == t->level) {
565 else if(!t->right || !t->right->right)
567 else if(t->level == t->right->right->level) {
582 x.left = x.right =
nullptr;
584 }
else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
586 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
587 t->right =
insert_(x, t->right);
588 else if((uintptr_t)&x < (uintptr_t)t)
591 t->right =
insert_(x, t->right);
593 if(t == m_head && t->
left)
604 if(!t->left && !t->right) {
606 }
else if(!t->left) {
619 }
else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
621 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
622 t->right =
delete_(x, t->right);
623 else if((uintptr_t)&x < (uintptr_t)t)
626 t->right =
delete_(x, t->right);
630 t->right =
skew(t->right);
632 t->right->right =
skew(t->right->right);
634 t->right =
split(t->right);
660 return t ?
lowest(t->right) :
nullptr;
665 return t ?
highest(t->left) :
nullptr;
672 decltype(t->level) ll = t->left ? t->left->level : 0;
673 decltype(t->level) lr = t->right ? t->right->level : 0;
674 decltype(t->level) should_be = (
decltype(t->level))((ll < lr ? ll : lr) + 1U);
675 if(should_be < t->level) {
676 t->level = should_be;
677 if(t->right && should_be < t->right->level)
678 t->right->level = should_be;
685 zth_dbg(list,
"SortedList %p (head %p):",
this, m_head);
699 !t->left || m_comp(
static_cast<type&
>(*t->left),
static_cast<type&
>(*t))
700 || (!m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(*t->left))
701 && ((uintptr_t)t > (uintptr_t)t->left)));
703 !t->right || m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(*t->right))
704 || (!m_comp(
static_cast<type&
>(*t->right),
static_cast<type&
>(*t))
705 || ((uintptr_t)t < (uintptr_t)t->right)));
707 zth_assert(t->left || t->right || t->level == 1);
708 zth_assert(!t->left || t->left->level == t->level - 1);
710 !t->right || t->right->level == t->level - 1
711 || t->right->level == t->level);
712 zth_assert(!t->right || !t->right->right || t->right->right->level < t->level);
713 zth_assert(t->level < 2 || (t->left && t->right));
723 zth_dbg(list,
"%*s (null)", indent,
"");
725 zth_dbg(list,
"%*s node %p level=%d: %s", indent,
"",
static_cast<type*
>(t),
726 t->
level,
static_cast<type*
>(t)->str().c_str());
748#
if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
800 }
else if(m_head->
arg == a) {
void add(function_type f, arg_type a=arg_type()) noexcept
Hookable< type > hookable_type
void operator()(type x) const noexcept
hookable_type::function_type function_type
hookable_type::arg_type arg_type
void remove(arg_type a) noexcept
void once(type x) noexcept
void(* function_type)(type, arg_type)
Hookable(function_type f, arg_type a=arg_type(), Hookable *n=nullptr) noexcept
Hookable * operator()(type x) const noexcept
Iterator operator--(int) noexcept
bool operator==(Iterator< C > const &rhs) const noexcept
bool operator!=(Iterator< C > const &rhs) const noexcept
user_type & user() noexcept
bool atEnd() const noexcept
constexpr Iterator(elem_type *start, elem_type *current=nullptr) noexcept
Iterator & operator++() noexcept
bool atBegin() const noexcept
Iterator & operator--() noexcept
user_type const & user() const noexcept
Iterator operator++(int) noexcept
elem_type * get() const noexcept
type & operator*() const noexcept
type * operator->() const noexcept
user_type const & user_back() const noexcept
Iterator< false > iterator
iterator begin() const noexcept
elem_type::user_type user_type
size_t size() const noexcept
bool empty() const noexcept
user_type const & user_front() const noexcept
iterator erase(iterator const &pos) noexcept
iterator push_back(elem_type &elem) noexcept
user_type erase(elem_type &elem) noexcept
constexpr List() noexcept
iterator insert(iterator const &pos, elem_type &elem) noexcept
user_type pop_front() noexcept
iterator push_front(elem_type &elem) noexcept
user_type pop_back() noexcept
type & back() const noexcept
iterator end() const noexcept
bool contains(elem_type const &elem) const noexcept
cyclic_iterator cyclic(elem_type &start) const noexcept
user_type & user_front() noexcept
user_type & user_back() noexcept
type & front() const noexcept
Iterator< true > cyclic_iterator
void rotate(elem_type &elem) noexcept
Listable(Listable &&l) noexcept
Listable & operator=(Listable &&l) noexcept
constexpr Listable(Listable const &e) noexcept
constexpr Listable() noexcept
Listable & operator=(Listable const &rhs) noexcept
void erase(elem_type &x) noexcept
void check() const noexcept
void insert(elem_type &x) noexcept
bool contains(elem_type &x) const noexcept
elem_type * insert_(elem_type &x, elem_type *t) noexcept
static void decrease_level(elem_type *t) noexcept
static elem_type * lowest(elem_type *t) noexcept
type & front() const noexcept
static elem_type * successor(elem_type *t) noexcept
static elem_type * skew(elem_type *t) noexcept
size_t size() const noexcept
static void print(elem_type *t, int indent=0) noexcept
size_t check(elem_type *t) const noexcept
elem_type * delete_(elem_type &x, elem_type *t) noexcept
static elem_type * split(elem_type *t) noexcept
constexpr SortedList() noexcept
static elem_type * highest(elem_type *t) noexcept
static elem_type * predecessor(elem_type *t) noexcept
bool empty() const 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)
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.