26template <
typename T = Listable,
typename Compare = std::less<T> >
53# if __cplusplus >= 201103L
87 template <
typename T,
typename Compare>
91template <
typename T = Listable>
100 template <
bool cyclic>
110 return !m_current && m_start;
115 return m_current == m_start;
131 return get() == rhs.get();
137 return !(*
this == rhs);
185 return *
static_cast<type*
>(elem);
193 user_type
const&
user() const noexcept
231 return *
static_cast<type*
>(m_tail);
253 if(m_tail ==
nullptr) {
255 m_tail = m_head = elem.
prev = elem.
next = &elem;
258 elem.next = m_tail->
next;
271 if(m_tail == m_head) {
272 m_tail = m_head =
nullptr;
276 m_tail = m_tail->
prev;
290 return *
static_cast<type*
>(m_head);
310 if(m_head ==
nullptr) {
312 m_tail = m_head = elem.
prev = elem.
next = &elem;
328 if(m_tail == m_head) {
329 m_tail = m_head =
nullptr;
333 m_head = m_head->
next;
346 zth_assert(m_head !=
nullptr || m_tail ==
nullptr);
347 return m_head ==
nullptr;
356 m_head = m_tail =
nullptr;
378 if(it.get() == &elem)
396 }
else if(pos.atBegin()) {
415 }
else if(pos.get() == m_tail) {
428 if(m_head == &elem) {
430 }
else if(m_tail == &elem) {
433 elem.prev->next = elem.next;
434 elem.next->prev = elem.prev;
436 elem.next = elem.prev =
nullptr;
453template <
typename T,
typename Compare>
494 x.left = x.right =
nullptr;
506 m_t = m_head =
nullptr;
529 else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
531 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
533 else if((uintptr_t)&x < (uintptr_t)t)
544 return static_cast<type&
>(*m_head);
554 else if(t->left->level == t->level) {
567 else if(!t->right || !t->right->right)
569 else if(t->level == t->right->right->level) {
584 x.left = x.right =
nullptr;
586 }
else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
588 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
589 t->right =
insert_(x, t->right);
590 else if((uintptr_t)&x < (uintptr_t)t)
593 t->right =
insert_(x, t->right);
595 if(t == m_head && t->
left)
606 if(!t->left && !t->right) {
608 }
else if(!t->left) {
621 }
else if(m_comp(
static_cast<type&
>(x),
static_cast<type&
>(*t)))
623 else if(m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(x)))
624 t->right =
delete_(x, t->right);
625 else if((uintptr_t)&x < (uintptr_t)t)
628 t->right =
delete_(x, t->right);
632 t->right =
skew(t->right);
634 t->right->right =
skew(t->right->right);
636 t->right =
split(t->right);
662 return t ?
lowest(t->right) :
nullptr;
667 return t ?
highest(t->left) :
nullptr;
674 decltype(t->level) ll = t->left ? t->left->level : 0;
675 decltype(t->level) lr = t->right ? t->right->level : 0;
676 decltype(t->level) should_be = (
decltype(t->level))((ll < lr ? ll : lr) + 1U);
677 if(should_be < t->level) {
678 t->level = should_be;
679 if(t->right && should_be < t->right->level)
680 t->right->level = should_be;
687 zth_dbg(list,
"SortedList %p (head %p):",
this, m_head);
701 !t->left || m_comp(
static_cast<type&
>(*t->left),
static_cast<type&
>(*t))
702 || (!m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(*t->left))
703 && ((uintptr_t)t > (uintptr_t)t->left)));
705 !t->right || m_comp(
static_cast<type&
>(*t),
static_cast<type&
>(*t->right))
706 || (!m_comp(
static_cast<type&
>(*t->right),
static_cast<type&
>(*t))
707 || ((uintptr_t)t < (uintptr_t)t->right)));
709 zth_assert(t->left || t->right || t->level == 1);
710 zth_assert(!t->left || t->left->level == t->level - 1);
712 !t->right || t->right->level == t->level - 1
713 || t->right->level == t->level);
714 zth_assert(!t->right || !t->right->right || t->right->right->level < t->level);
715 zth_assert(t->level < 2 || (t->left && t->right));
725 zth_dbg(list,
"%*s (null)", indent,
"");
727 zth_dbg(list,
"%*s node %p level=%d: %s", indent,
"",
static_cast<type*
>(t),
728 t->
level,
static_cast<type*
>(t)->str().c_str());
750#
if defined(__cpp_noexcept_function_type) && __cpp_noexcept_function_type >= 201510
802 }
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.