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