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