MySQL 8.0.39
Source Code Documentation
sql_list.h
Go to the documentation of this file.
1#ifndef INCLUDES_MYSQL_SQL_LIST_H
2#define INCLUDES_MYSQL_SQL_LIST_H
3/* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8
9 This program is designed to work with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation. The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have either included with
15 the program or referenced in the documentation.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25
26#include <stddef.h>
27#include <sys/types.h>
28#include <algorithm>
29#include <iterator>
30#include <type_traits>
31
32#include "my_alloc.h"
33#include "my_compiler.h"
34#include "my_dbug.h"
35#include "my_sharedlib.h"
36#include "sql/thr_malloc.h"
37
38/**
39 Simple intrusive linked list.
40
41 @remark Similar in nature to base_list, but intrusive. It keeps a
42 a pointer to the first element in the list and a indirect
43 reference to the last element.
44*/
45template <typename T>
47 public:
49 /** The first element in the list. */
51 /** A reference to the next element in the list. */
52 T **next;
53
55
57 : elements(tmp.elements),
58 first(tmp.first),
59 next(elements ? tmp.next : &first) {}
60
61 SQL_I_List(SQL_I_List &&) = default;
62
63 inline void clear() {
64 elements = 0;
65 first = nullptr;
66 next = &first;
67 }
68
69 inline void link_in_list(T *element, T **next_ptr) {
70 elements++;
71 (*next) = element;
72 next = next_ptr;
73 *next = nullptr;
74 }
75
76 inline void save_and_clear(SQL_I_List<T> *save) {
77 *save = *this;
78 clear();
79 }
80
81 inline void push_front(SQL_I_List<T> *save) {
82 /* link current list last */
83 *save->next = first;
84 first = save->first;
85 elements += save->elements;
86 }
87
88 inline void push_back(SQL_I_List<T> *save) {
89 if (save->first) {
90 *next = save->first;
91 next = save->next;
92 elements += save->elements;
93 }
94 }
95
96 inline uint size() const { return elements; }
97
100};
101
102/*
103 Basic single linked list
104 Used for item and item_buffs.
105 All list ends with a pointer to the 'end_of_list' element, which
106 data pointer is a null pointer and the next pointer points to itself.
107 This makes it very fast to traverse lists as we don't have to
108 test for a specialend condition for list that can't contain a null
109 pointer.
110*/
111
112/**
113 list_node - a node of a single-linked list.
114 @note We never call a destructor for instances of this class.
115*/
116
117struct list_node {
119 void *info;
120 list_node(void *info_par, list_node *next_par)
121 : next(next_par), info(info_par) {}
122 list_node() /* For end_of_list */
123 {
124 info = nullptr;
125 next = this;
126 }
127};
128
130
132 protected:
134
135 public:
137
138 bool operator==(const base_list &rhs) const {
139 return elements == rhs.elements && first == rhs.first && last == rhs.last;
140 }
141
142 inline void clear() {
143 elements = 0;
145 last = &first;
146 }
147 inline base_list() { clear(); }
148 /**
149 This is a shallow copy constructor that implicitly passes the ownership
150 from the source list to the new instance. The old instance is not
151 updated, so both objects end up sharing the same nodes. If one of
152 the instances then adds or removes a node, the other becomes out of
153 sync ('last' pointer), while still operational. Some old code uses and
154 relies on this behaviour. This logic is quite tricky: please do not use
155 it in any new code.
156 */
158 : first(tmp.first),
159 last(tmp.elements ? tmp.last : &first),
160 elements(tmp.elements) {}
162 elements = tmp.elements;
163 first = tmp.first;
164 last = elements ? tmp.last : &first;
165 return *this;
166 }
167 /**
168 Construct a deep copy of the argument in memory root mem_root.
169 The elements themselves are copied by pointer.
170 */
171 base_list(const base_list &rhs, MEM_ROOT *mem_root);
172 inline bool push_back(void *info) {
173 *last = new (*THR_MALLOC) list_node(info, &end_of_list);
174 if (*last) {
175 last = &(*last)->next;
176 elements++;
177 return false;
178 }
179 return true;
180 }
181 inline bool push_back(void *info, MEM_ROOT *mem_root) {
183 if (*last) {
184 last = &(*last)->next;
185 elements++;
186 return false;
187 }
188 return true;
189 }
190 inline bool push_front(void *info) {
191 list_node *node = new (*THR_MALLOC) list_node(info, first);
192 if (node) {
193 if (last == &first) last = &node->next;
194 first = node;
195 elements++;
196 return false;
197 }
198 return true;
199 }
200 inline bool push_front(void *info, MEM_ROOT *mem_root) {
201 list_node *node = new (mem_root) list_node(info, first);
202 if (node) {
203 if (last == &first) last = &node->next;
204 first = node;
205 elements++;
206 return false;
207 }
208 return true;
209 }
210
211 void remove(list_node **prev) {
212 list_node *node = (*prev)->next;
213 if (!--elements)
214 last = &first;
215 else if (last == &(*prev)->next)
216 last = prev;
217 destroy(*prev);
218 *prev = node;
219 }
220 inline void concat(base_list *list) {
221 if (!list->is_empty()) {
222 *last = list->first;
223 last = list->last;
224 elements += list->elements;
225 }
226 }
227 inline void *pop(void) {
228 if (first == &end_of_list) return nullptr;
229 list_node *tmp = first;
230 first = first->next;
231 if (!--elements) last = &first;
232 return tmp->info;
233 }
234 inline void disjoin(base_list *list) {
235 list_node **prev = &first;
236 list_node *node = first;
237 list_node *list_first = list->first;
238 elements = 0;
239 while (node && node != list_first) {
240 prev = &node->next;
241 node = node->next;
242 elements++;
243 }
244 *prev = *last;
245 last = prev;
246 }
247 inline void prepend(base_list *list) {
248 if (!list->is_empty()) {
249 *list->last = first;
250 if (is_empty()) last = list->last;
251 first = list->first;
252 elements += list->elements;
253 }
254 }
255 /**
256 Swap two lists.
257 */
258 inline void swap(base_list &rhs) {
259 std::swap(first, rhs.first);
260 std::swap(last, rhs.last);
262 }
263 inline list_node *last_node() { return *last; }
264 inline list_node *first_node() { return first; }
265 inline void *head() { return first->info; }
266 inline const void *head() const { return first->info; }
267 inline void **head_ref() {
268 return first != &end_of_list ? &first->info : nullptr;
269 }
270 inline bool is_empty() const { return first == &end_of_list; }
271 inline list_node *last_ref() { return &end_of_list; }
272 inline uint size() const { return elements; }
273 friend class base_list_iterator;
274 friend class error_list;
276
277#ifdef LIST_EXTRA_DEBUG
278 /*
279 Check list invariants and print results into trace. Invariants are:
280 - (*last) points to end_of_list
281 - There are no NULLs in the list.
282 - base_list::elements is the number of elements in the list.
283
284 SYNOPSIS
285 check_list()
286 name Name to print to trace file
287
288 RETURN
289 1 The list is Ok.
290 0 List invariants are not met.
291 */
292
293 bool check_list(const char *name) {
294 base_list *list = this;
295 list_node *node = first;
296 uint cnt = 0;
297
298 while (node->next != &end_of_list) {
299 if (!node->info) {
300 DBUG_PRINT("list_invariants",
301 ("%s: error: NULL element in the list", name));
302 return false;
303 }
304 node = node->next;
305 cnt++;
306 }
307 if (last != &(node->next)) {
308 DBUG_PRINT("list_invariants", ("%s: error: wrong last pointer", name));
309 return false;
310 }
311 if (cnt + 1 != elements) {
312 DBUG_PRINT("list_invariants", ("%s: error: wrong element count", name));
313 return false;
314 }
315 DBUG_PRINT("list_invariants", ("%s: list is ok", name));
316 return true;
317 }
318#endif // LIST_EXTRA_DEBUG
319
320 protected:
321 void after(void *info, list_node *node) {
322 list_node *new_node = new (*THR_MALLOC) list_node(info, node->next);
323 node->next = new_node;
324 elements++;
325 if (last == &(node->next)) last = &new_node->next;
326 }
327 bool after(void *info, list_node *node, MEM_ROOT *mem_root) {
328 list_node *new_node = new (mem_root) list_node(info, node->next);
329 if (!new_node) return true; // OOM
330
331 node->next = new_node;
332 elements++;
333 if (last == &(node->next)) last = &new_node->next;
334
335 return false;
336 }
337};
338
340 protected:
343 void sublist(base_list &ls, uint elm) {
344 ls.first = *el;
345 ls.last = list->last;
346 ls.elements = elm;
347 }
348
349 public:
352
353 base_list_iterator(base_list &list_par) { init(list_par); }
354
355 inline void init(base_list &list_par) {
356 list = &list_par;
357 el = &list_par.first;
358 prev = nullptr;
359 current = nullptr;
360 }
361
362 inline void *next(void) {
363 prev = el;
364 current = *el;
365 el = &current->next;
366 return current->info;
367 }
368 inline void *next_fast(void) {
369 list_node *tmp;
370 tmp = *el;
371 el = &tmp->next;
372 return tmp->info;
373 }
374 inline void rewind(void) { el = &list->first; }
375 inline void *replace(void *element) { // Return old element
376 void *tmp = current->info;
377 assert(current->info != nullptr);
378 current->info = element;
379 return tmp;
380 }
381 void *replace(base_list &new_list) {
382 void *ret_value = current->info;
383 if (!new_list.is_empty()) {
384 *new_list.last = current->next;
385 current->info = new_list.first->info;
386 current->next = new_list.first->next;
387 if ((list->last == &current->next) && (new_list.elements > 1))
388 list->last = new_list.last;
389 list->elements += new_list.elements - 1;
390 }
391 return ret_value; // return old element
392 }
393 inline void remove(void) // Remove current
394 {
395 list->remove(prev);
396 el = prev;
397 current = nullptr; // Safeguard
398 }
399 void after(void *element) // Insert element after current
400 {
401 list->after(element, current);
403 el = &current->next;
404 }
405 bool after(void *a, MEM_ROOT *mem_root) {
406 if (list->after(a, current, mem_root)) return true;
407
409 el = &current->next;
410 return false;
411 }
412 inline void **ref(void) // Get reference pointer
413 {
414 return &current->info;
415 }
416 inline bool is_last(void) { return el == list->last; }
417 inline bool is_before_first() const { return current == nullptr; }
418 bool prepend(void *a, MEM_ROOT *mem_root) {
419 if (list->push_front(a, mem_root)) return true;
420
421 el = &list->first;
422 prev = el;
423 el = &(*el)->next;
424
425 return false;
426 }
428};
429
430template <class T>
432
433template <class T>
434class List : public base_list {
435 public:
437 inline List(const List<T> &tmp) : base_list(tmp) {}
438 List &operator=(const List &tmp) {
439 return static_cast<List &>(base_list::operator=(tmp));
440 }
441 inline List(const List<T> &tmp, MEM_ROOT *mem_root)
442 : base_list(tmp, mem_root) {}
443 /*
444 Typecasting to (void *) it's necessary if we want to declare List<T> with
445 constant T parameter (like List<const char>), since the untyped storage
446 is "void *", and assignment of const pointer to "void *" is a syntax error.
447 */
448 inline bool push_back(T *a) {
449 return base_list::push_back(const_cast<void *>(((const void *)a)));
450 }
451 inline bool push_back(T *a, MEM_ROOT *mem_root) {
452 return base_list::push_back(const_cast<void *>((const void *)a), mem_root);
453 }
454 inline bool push_front(T *a) {
455 return base_list::push_front(const_cast<void *>((const void *)a));
456 }
457 inline bool push_front(T *a, MEM_ROOT *mem_root) {
458 return base_list::push_front(const_cast<void *>((const void *)a), mem_root);
459 }
460 inline T *head() { return static_cast<T *>(base_list::head()); }
461 inline const T *head() const {
462 return static_cast<const T *>(base_list::head());
463 }
464 inline T **head_ref() { return (T **)base_list::head_ref(); }
465 inline T *pop() { return (T *)base_list::pop(); }
469 void delete_elements(void) {
470 list_node *element, *next;
471 for (element = first; element != &end_of_list; element = next) {
472 next = element->next;
473 delete (T *)element->info;
474 }
475 clear();
476 }
477
478 void destroy_elements(void) {
479 list_node *element, *next;
480 for (element = first; element != &end_of_list; element = next) {
481 next = element->next;
482 destroy((T *)element->info);
483 }
484 clear();
485 }
486
487 T *operator[](uint index) const {
488 assert(index < elements);
489 list_node *current = first;
490 for (uint i = 0; i < index; ++i) current = current->next;
491 return static_cast<T *>(current->info);
492 }
493
494 void replace(uint index, T *new_value) {
495 assert(index < elements);
496 list_node *current = first;
497 for (uint i = 0; i < index; ++i) current = current->next;
498 current->info = new_value;
499 }
500
501 bool swap_elts(uint index1, uint index2) {
502 if (index1 == index2) return false;
503
504 if (index1 >= elements || index2 >= elements) return true; // error
505
506 if (index2 < index1) std::swap(index1, index2);
507
508 list_node *current1 = first;
509 for (uint i = 0; i < index1; ++i) current1 = current1->next;
510
511 list_node *current2 = current1;
512 for (uint i = 0; i < index2 - index1; ++i) current2 = current2->next;
513
514 std::swap(current1->info, current2->info);
515
516 return false;
517 }
518
519 /**
520 @brief
521 Sort the list
522
523 @param cmp node comparison function
524
525 @details
526 The function sorts list nodes by an exchange sort algorithm.
527 The order of list nodes isn't changed, values of info fields are
528 swapped instead. Due to this, list iterators that are initialized before
529 sort could be safely used after sort, i.e they wouldn't cause a crash.
530 As this isn't an effective algorithm the list to be sorted is supposed to
531 be short.
532 */
533 template <typename Node_cmp_func>
534 void sort(Node_cmp_func cmp) {
535 if (elements < 2) return;
536 for (list_node *n1 = first; n1 && n1 != &end_of_list; n1 = n1->next) {
537 for (list_node *n2 = n1->next; n2 && n2 != &end_of_list; n2 = n2->next) {
538 if (cmp(static_cast<T *>(n1->info), static_cast<T *>(n2->info)) > 0) {
539 void *tmp = n1->info;
540 n1->info = n2->info;
541 n2->info = tmp;
542 }
543 }
544 }
545 }
546
547 // For C++11 range-based for loops.
551 // If the list overlaps another list, last isn't actually
552 // the last element, and if so, we'd give a different result from
553 // List_iterator_fast.
554 assert((*last)->next == &end_of_list);
555
556 return iterator(*last);
557 }
558
562 assert((*last)->next == &end_of_list);
563 return const_iterator(*last);
564 }
567 assert((*last)->next == &end_of_list);
568 return const_iterator(*last);
569 }
570};
571
572template <class T>
574 public:
577 inline void init(List<T> &a) { base_list_iterator::init(a); }
578 inline T *operator++(int) { return (T *)base_list_iterator::next(); }
579 inline T *replace(T *a) { return (T *)base_list_iterator::replace(a); }
580 inline T *replace(List<T> &a) { return (T *)base_list_iterator::replace(a); }
581 inline void rewind(void) { base_list_iterator::rewind(); }
583 inline void after(T *a) { base_list_iterator::after(a); }
584 inline bool after(T *a, MEM_ROOT *mem_root) {
586 }
587 inline T **ref(void) {
588 return const_cast<T **>(
589 (std::remove_const_t<T> **)base_list_iterator::ref());
590 }
591};
592
593template <class T>
595 protected:
596 inline T *replace(T *) { return (T *)0; }
597 inline T *replace(List<T> &) { return (T *)0; }
598 inline void remove(void) {}
599 inline void after(T *) {}
600 inline T **ref(void) { return (T **)0; }
601
602 public:
605 inline void init(List<T> &a) { base_list_iterator::init(a); }
606 inline T *operator++(int) { return (T *)base_list_iterator::next_fast(); }
607 inline void rewind(void) { base_list_iterator::rewind(); }
608 void sublist(List<T> &list_arg, uint el_arg) {
609 base_list_iterator::sublist(list_arg, el_arg);
610 }
611};
612
613/*
614 Like List_iterator<T>, but with an STL-compatible interface
615 (ForwardIterator), so that you can use it in range-based for loops.
616 Prefer this to List_iterator<T> wherever possible, but also prefer
617 std::vector<T> or std::list<T> to List<T> wherever possible.
618 */
619template <class T>
621 public:
622 explicit List_STL_Iterator(list_node *node) : m_current(node) {}
623
624 // Iterator (required for InputIterator).
625 T &operator*() const { return *static_cast<T *>(m_current->info); }
626
629 return *this;
630 }
631
632 using difference_type = ptrdiff_t;
633 using value_type = T; // NOTE: std::remove_cv_t<T> from C++20.
634 using pointer = T *;
635 using reference = T &;
636 using iterator_category = std::forward_iterator_tag;
637
638 // EqualityComparable (required for InputIterator).
639 bool operator==(const List_STL_Iterator &other) const {
640 return m_current == other.m_current;
641 }
642
643 // InputIterator (required for ForwardIterator).
644 bool operator!=(const List_STL_Iterator &other) const {
645 return !(*this == other);
646 }
647
648 T *operator->() const { return static_cast<T *>(m_current->info); }
649
650 // DefaultConstructible (required for ForwardIterator).
651 List_STL_Iterator() = default;
652
653 // ForwardIterator.
655 List_STL_Iterator copy = *this;
657 return copy;
658 }
659
660 private:
662};
663
664template <typename T>
665class base_ilist;
666template <typename T>
668
669/*
670 A simple intrusive list.
671
672 NOTE: this inherently unsafe, since we rely on <T> to have
673 the same layout as ilink<T> (see base_ilist::sentinel).
674 Please consider using a different strategy for linking objects.
675*/
676
677template <typename T>
678class ilink {
679 T **prev, *next;
680
681 public:
683
684 void unlink() {
685 /* Extra tests because element doesn't have to be linked */
686 if (prev) *prev = next;
687 if (next) next->prev = prev;
688 prev = nullptr;
689 next = nullptr;
690 }
691
692 friend class base_ilist<T>;
693 friend class base_ilist_iterator<T>;
694};
695
696/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
697
698class i_string : public ilink<i_string> {
699 public:
700 const char *ptr;
702 i_string(const char *s) : ptr(s) {}
703};
704
705/* needed for linked list of two strings for replicate-rewrite-db */
706class i_string_pair : public ilink<i_string_pair> {
707 public:
708 const char *key;
709 const char *val;
711 i_string_pair(const char *key_arg, const char *val_arg)
712 : key(key_arg), val(val_arg) {}
713};
714
715template <class T>
716class I_List_iterator;
717
718template <typename T>
722
723 static_assert(!std::is_polymorphic<T>::value,
724 "Do not use this for classes with virtual members");
725
726 public:
727 // The sentinel is not a T, but at least it is a POD
729 first = static_cast<T *>(&sentinel);
730 sentinel.prev = &first;
731 }
733
734 // The sentinel is not a T, but at least it is a POD
736 return first == static_cast<const T *>(&sentinel);
737 }
738
739 /// Pushes new element in front of list.
740 void push_front(T *a) {
741 first->prev = &a->next;
742 a->next = first;
743 a->prev = &first;
744 first = a;
745 }
746
747 /// Pushes new element to the end of the list, i.e. in front of the sentinel.
748 void push_back(T *a) {
749 *sentinel.prev = a;
750 a->next = static_cast<T *>(&sentinel);
751 a->prev = sentinel.prev;
752 sentinel.prev = &a->next;
753 }
754
755 // Unlink first element, and return it.
756 T *get() {
757 if (is_empty()) return nullptr;
758 T *first_link = first;
759 first_link->unlink();
760 return first_link;
761 }
762
763 T *head() { return is_empty() ? nullptr : first; }
764
765 /**
766 Moves list elements to new owner, and empties current owner (i.e. this).
767
768 @param[in,out] new_owner The new owner of the list elements.
769 Should be empty in input.
770 */
771
772 void move_elements_to(base_ilist *new_owner) {
773 assert(new_owner->is_empty());
774 new_owner->first = first;
775 new_owner->sentinel = sentinel;
776 clear();
777 }
778
779 friend class base_ilist_iterator<T>;
780
781 private:
782 /*
783 We don't want to allow copying of this class, as that would give us
784 two list heads containing the same elements.
785 So we declare, but don't define copy CTOR and assignment operator.
786 */
788 void operator=(const base_ilist &);
789};
790
791template <typename T>
794 T **el, *current;
795
796 public:
798 : list(&list_par), el(&list_par.first), current(nullptr) {}
799
800 // The sentinel is not a T, but at least it is a POD
802 /* This is coded to allow push_back() while iterating */
803 current = *el;
804 if (current == static_cast<T *>(&list->sentinel)) return nullptr;
805 el = &current->next;
806 return current;
807 }
808};
809
810template <class T>
811class I_List : private base_ilist<T> {
812 public:
815 using base_ilist<T>::get;
819 void move_elements_to(I_List<T> *new_owner) {
821 }
822 friend class I_List_iterator<T>;
823};
824
825template <class T>
827 public:
829 inline T *operator++(int) { return base_ilist_iterator<T>::next(); }
830};
831
833
834#endif // INCLUDES_MYSQL_SQL_LIST_H
Definition: sql_list.h:826
I_List_iterator(I_List< T > &a)
Definition: sql_list.h:828
T * operator++(int)
Definition: sql_list.h:829
Definition: sql_list.h:811
void move_elements_to(I_List< T > *new_owner)
Definition: sql_list.h:819
Definition: sql_list.h:620
T & operator*() const
Definition: sql_list.h:625
T * operator->() const
Definition: sql_list.h:648
T value_type
Definition: sql_list.h:633
bool operator==(const List_STL_Iterator &other) const
Definition: sql_list.h:639
List_STL_Iterator()=default
std::forward_iterator_tag iterator_category
Definition: sql_list.h:636
list_node * m_current
Definition: sql_list.h:661
T * pointer
Definition: sql_list.h:634
List_STL_Iterator(list_node *node)
Definition: sql_list.h:622
T & reference
Definition: sql_list.h:635
List_STL_Iterator & operator++()
Definition: sql_list.h:627
List_STL_Iterator operator++(int)
Definition: sql_list.h:654
bool operator!=(const List_STL_Iterator &other) const
Definition: sql_list.h:644
ptrdiff_t difference_type
Definition: sql_list.h:632
Definition: sql_list.h:594
T * replace(T *)
Definition: sql_list.h:596
List_iterator_fast(List< T > &a)
Definition: sql_list.h:603
void after(T *)
Definition: sql_list.h:599
void remove(void)
Definition: sql_list.h:598
T ** ref(void)
Definition: sql_list.h:600
void sublist(List< T > &list_arg, uint el_arg)
Definition: sql_list.h:608
void init(List< T > &a)
Definition: sql_list.h:605
void rewind(void)
Definition: sql_list.h:607
T * operator++(int)
Definition: sql_list.h:606
T * replace(List< T > &)
Definition: sql_list.h:597
List_iterator_fast()
Definition: sql_list.h:604
Definition: sql_list.h:573
List_iterator()
Definition: sql_list.h:576
void init(List< T > &a)
Definition: sql_list.h:577
T ** ref(void)
Definition: sql_list.h:587
void after(T *a)
Definition: sql_list.h:583
T * replace(List< T > &a)
Definition: sql_list.h:580
T * replace(T *a)
Definition: sql_list.h:579
T * operator++(int)
Definition: sql_list.h:578
bool after(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:584
void remove()
Definition: sql_list.h:582
void rewind(void)
Definition: sql_list.h:581
List_iterator(List< T > &a)
Definition: sql_list.h:575
Definition: sql_list.h:434
bool push_back(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:451
iterator begin()
Definition: sql_list.h:549
const_iterator begin() const
Definition: sql_list.h:560
const_iterator cend() const
Definition: sql_list.h:566
void delete_elements(void)
Definition: sql_list.h:469
const T * head() const
Definition: sql_list.h:461
List_STL_Iterator< const T > const_iterator
Definition: sql_list.h:559
void destroy_elements(void)
Definition: sql_list.h:478
List()
Definition: sql_list.h:436
List(const List< T > &tmp, MEM_ROOT *mem_root)
Definition: sql_list.h:441
void sort(Node_cmp_func cmp)
Sort the list.
Definition: sql_list.h:534
bool swap_elts(uint index1, uint index2)
Definition: sql_list.h:501
T * head()
Definition: sql_list.h:460
void disjoin(List< T > *list)
Definition: sql_list.h:467
bool push_back(T *a)
Definition: sql_list.h:448
List_STL_Iterator< T > iterator
Definition: sql_list.h:548
const_iterator end() const
Definition: sql_list.h:561
bool push_front(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:457
List(const List< T > &tmp)
Definition: sql_list.h:437
List & operator=(const List &tmp)
Definition: sql_list.h:438
T ** head_ref()
Definition: sql_list.h:464
T * operator[](uint index) const
Definition: sql_list.h:487
const_iterator cbegin() const
Definition: sql_list.h:565
iterator end()
Definition: sql_list.h:550
void prepend(List< T > *list)
Definition: sql_list.h:468
T * pop()
Definition: sql_list.h:465
bool push_front(T *a)
Definition: sql_list.h:454
void replace(uint index, T *new_value)
Definition: sql_list.h:494
void concat(List< T > *list)
Definition: sql_list.h:466
Simple intrusive linked list.
Definition: sql_list.h:46
void save_and_clear(SQL_I_List< T > *save)
Definition: sql_list.h:76
T * first
The first element in the list.
Definition: sql_list.h:50
void push_front(SQL_I_List< T > *save)
Definition: sql_list.h:81
void push_back(SQL_I_List< T > *save)
Definition: sql_list.h:88
void link_in_list(T *element, T **next_ptr)
Definition: sql_list.h:69
uint elements
Definition: sql_list.h:48
SQL_I_List()
Definition: sql_list.h:54
T ** next
A reference to the next element in the list.
Definition: sql_list.h:52
SQL_I_List & operator=(SQL_I_List &)=default
uint size() const
Definition: sql_list.h:96
void clear()
Definition: sql_list.h:63
SQL_I_List(const SQL_I_List &tmp)
Definition: sql_list.h:56
SQL_I_List(SQL_I_List &&)=default
SQL_I_List & operator=(SQL_I_List &&)=default
Definition: sql_list.h:792
T * current
Definition: sql_list.h:794
T * next(void) SUPPRESS_UBSAN
Definition: sql_list.h:801
base_ilist_iterator(base_ilist< T > &list_par)
Definition: sql_list.h:797
base_ilist< T > * list
Definition: sql_list.h:793
T ** el
Definition: sql_list.h:794
Definition: sql_list.h:719
T * get()
Definition: sql_list.h:756
void operator=(const base_ilist &)
void move_elements_to(base_ilist *new_owner)
Moves list elements to new owner, and empties current owner (i.e.
Definition: sql_list.h:772
T * first
Definition: sql_list.h:720
bool is_empty() const SUPPRESS_UBSAN
Definition: sql_list.h:735
void clear() SUPPRESS_UBSAN
Definition: sql_list.h:728
T * head()
Definition: sql_list.h:763
base_ilist(const base_ilist &)
void push_front(T *a)
Pushes new element in front of list.
Definition: sql_list.h:740
void push_back(T *a)
Pushes new element to the end of the list, i.e. in front of the sentinel.
Definition: sql_list.h:748
ilink< T > sentinel
Definition: sql_list.h:721
base_ilist()
Definition: sql_list.h:732
Definition: sql_list.h:339
void init(base_list &list_par)
Definition: sql_list.h:355
list_node ** prev
Definition: sql_list.h:342
void * next_fast(void)
Definition: sql_list.h:368
void ** ref(void)
Definition: sql_list.h:412
bool is_last(void)
Definition: sql_list.h:416
bool is_before_first() const
Definition: sql_list.h:417
void after(void *element)
Definition: sql_list.h:399
list_node ** el
Definition: sql_list.h:342
void * replace(void *element)
Definition: sql_list.h:375
void sublist(base_list &ls, uint elm)
Definition: sql_list.h:343
base_list_iterator()
Definition: sql_list.h:350
friend class error_list_iterator
Definition: sql_list.h:427
base_list_iterator(base_list &list_par)
Definition: sql_list.h:353
void rewind(void)
Definition: sql_list.h:374
list_node * current
Definition: sql_list.h:342
base_list * list
Definition: sql_list.h:341
void remove(void)
Definition: sql_list.h:393
bool prepend(void *a, MEM_ROOT *mem_root)
Definition: sql_list.h:418
bool after(void *a, MEM_ROOT *mem_root)
Definition: sql_list.h:405
void * replace(base_list &new_list)
Definition: sql_list.h:381
void * next(void)
Definition: sql_list.h:362
Definition: sql_list.h:131
bool push_back(void *info)
Definition: sql_list.h:172
void ** head_ref()
Definition: sql_list.h:267
list_node * last_ref()
Definition: sql_list.h:271
void disjoin(base_list *list)
Definition: sql_list.h:234
base_list(const base_list &tmp)
This is a shallow copy constructor that implicitly passes the ownership from the source list to the n...
Definition: sql_list.h:157
void concat(base_list *list)
Definition: sql_list.h:220
friend class error_list
Definition: sql_list.h:274
list_node * first_node()
Definition: sql_list.h:264
bool push_front(void *info)
Definition: sql_list.h:190
void * pop(void)
Definition: sql_list.h:227
uint size() const
Definition: sql_list.h:272
base_list()
Definition: sql_list.h:147
void swap(base_list &rhs)
Swap two lists.
Definition: sql_list.h:258
bool push_back(void *info, MEM_ROOT *mem_root)
Definition: sql_list.h:181
const void * head() const
Definition: sql_list.h:266
friend class error_list_iterator
Definition: sql_list.h:275
void after(void *info, list_node *node)
Definition: sql_list.h:321
list_node * last_node()
Definition: sql_list.h:263
bool is_empty() const
Definition: sql_list.h:270
void * head()
Definition: sql_list.h:265
bool operator==(const base_list &rhs) const
Definition: sql_list.h:138
void prepend(base_list *list)
Definition: sql_list.h:247
void remove(list_node **prev)
Definition: sql_list.h:211
uint elements
Definition: sql_list.h:136
list_node ** last
Definition: sql_list.h:133
base_list & operator=(const base_list &tmp)
Definition: sql_list.h:161
bool after(void *info, list_node *node, MEM_ROOT *mem_root)
Definition: sql_list.h:327
void clear()
Definition: sql_list.h:142
list_node * first
Definition: sql_list.h:133
bool push_front(void *info, MEM_ROOT *mem_root)
Definition: sql_list.h:200
Definition: sql_list.h:706
const char * val
Definition: sql_list.h:709
i_string_pair(const char *key_arg, const char *val_arg)
Definition: sql_list.h:711
i_string_pair()
Definition: sql_list.h:710
const char * key
Definition: sql_list.h:708
Definition: sql_list.h:698
i_string(const char *s)
Definition: sql_list.h:702
const char * ptr
Definition: sql_list.h:700
i_string()
Definition: sql_list.h:701
static MEM_ROOT mem_root
Definition: client_plugin.cc:110
static int cmp(Bigint *a, Bigint *b)
Definition: dtoa.cc:1064
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:222
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
Header for compiler-dependent features.
#define SUPPRESS_UBSAN
Definition: my_compiler.h:134
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:181
Functions related to handling of plugins and other dynamically loaded libraries.
#define MYSQL_PLUGIN_IMPORT
Definition: my_sharedlib.h:71
Log info(cout, "NOTE")
void copy(Shards< COUNT > &dst, const Shards< COUNT > &src) noexcept
Copy the counters, overwrite destination.
Definition: ut0counter.h:354
static int destroy(mysql_cond_t *that, const char *, unsigned int)
Definition: mysql_cond_v1_native.cc:54
std::list< T, ut::allocator< T > > list
Specialization of list which uses ut_allocator.
Definition: ut0new.h:2878
MYSQL_PLUGIN_IMPORT list_node end_of_list
Definition: sql_list.cc:29
void free_list(I_List< i_string > *list)
Definition: sql_list.cc:31
static void swap(String &a, String &b) noexcept
Definition: sql_string.h:642
case opt name
Definition: sslopt-case.h:33
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:83
list_node - a node of a single-linked list.
Definition: sql_list.h:117
list_node * next
Definition: sql_list.h:118
list_node()
Definition: sql_list.h:122
list_node(void *info_par, list_node *next_par)
Definition: sql_list.h:120
void * info
Definition: sql_list.h:119
unsigned int uint
Definition: uca9-dump.cc:75