MySQL  8.0.17
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, 2019, Oracle and/or its affiliates. All rights reserved.
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 */
44 template <typename T>
45 class SQL_I_List {
46  public:
48  /** The first element in the list. */
49  T *first;
50  /** A reference to the next element in the list. */
51  T **next;
52 
53  SQL_I_List() { empty(); }
54 
55  SQL_I_List(const SQL_I_List &tmp)
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 empty() {
63  elements = 0;
64  first = NULL;
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 = NULL;
73  }
74 
75  inline void save_and_clear(SQL_I_List<T> *save) {
76  *save = *this;
77  empty();
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 
97  SQL_I_List &operator=(SQL_I_List &) = default;
98  SQL_I_List &operator=(SQL_I_List &&) = default;
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 
116 struct 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 = 0;
124  next = this;
125  }
126 };
127 
129 
130 class base_list {
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 empty() {
142  elements = 0;
143  first = &end_of_list;
144  last = &first;
145  }
146  inline base_list() { empty(); }
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  */
156  base_list(const base_list &tmp)
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  if (((*last) = new (*THR_MALLOC) list_node(info, &end_of_list))) {
173  last = &(*last)->next;
174  elements++;
175  return 0;
176  }
177  return 1;
178  }
179  inline bool push_back(void *info, MEM_ROOT *mem_root) {
180  if (((*last) = new (mem_root) list_node(info, &end_of_list))) {
181  last = &(*last)->next;
182  elements++;
183  return 0;
184  }
185  return 1;
186  }
187  inline bool push_front(void *info) {
188  list_node *node = new (*THR_MALLOC) list_node(info, first);
189  if (node) {
190  if (last == &first) last = &node->next;
191  first = node;
192  elements++;
193  return 0;
194  }
195  return 1;
196  }
197  inline bool push_front(void *info, MEM_ROOT *mem_root) {
198  list_node *node = new (mem_root) list_node(info, first);
199  if (node) {
200  if (last == &first) last = &node->next;
201  first = node;
202  elements++;
203  return false;
204  }
205  return true;
206  }
207 
208  void remove(list_node **prev) {
209  list_node *node = (*prev)->next;
210  if (!--elements)
211  last = &first;
212  else if (last == &(*prev)->next)
213  last = prev;
214  destroy(*prev);
215  *prev = node;
216  }
217  inline void concat(base_list *list) {
218  if (!list->is_empty()) {
219  *last = list->first;
220  last = list->last;
221  elements += list->elements;
222  }
223  }
224  inline void *pop(void) {
225  if (first == &end_of_list) return 0;
226  list_node *tmp = first;
227  first = first->next;
228  if (!--elements) last = &first;
229  return tmp->info;
230  }
231  inline void disjoin(base_list *list) {
232  list_node **prev = &first;
233  list_node *node = first;
234  list_node *list_first = list->first;
235  elements = 0;
236  while (node && node != list_first) {
237  prev = &node->next;
238  node = node->next;
239  elements++;
240  }
241  *prev = *last;
242  last = prev;
243  }
244  inline void prepend(base_list *list) {
245  if (!list->is_empty()) {
246  *list->last = first;
247  if (is_empty()) last = list->last;
248  first = list->first;
249  elements += list->elements;
250  }
251  }
252  /**
253  Swap two lists.
254  */
255  inline void swap(base_list &rhs) {
256  std::swap(first, rhs.first);
257  std::swap(last, rhs.last);
259  }
260  inline list_node *last_node() { return *last; }
261  inline list_node *first_node() { return first; }
262  inline void *head() { return first->info; }
263  inline const void *head() const { return first->info; }
264  inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
265  inline bool is_empty() const { return first == &end_of_list; }
266  inline list_node *last_ref() { return &end_of_list; }
267  inline uint size() const { return elements; }
268  friend class base_list_iterator;
269  friend class error_list;
270  friend class error_list_iterator;
271 
272 #ifdef LIST_EXTRA_DEBUG
273  /*
274  Check list invariants and print results into trace. Invariants are:
275  - (*last) points to end_of_list
276  - There are no NULLs in the list.
277  - base_list::elements is the number of elements in the list.
278 
279  SYNOPSIS
280  check_list()
281  name Name to print to trace file
282 
283  RETURN
284  1 The list is Ok.
285  0 List invariants are not met.
286  */
287 
288  bool check_list(const char *name) {
289  base_list *list = this;
290  list_node *node = first;
291  uint cnt = 0;
292 
293  while (node->next != &end_of_list) {
294  if (!node->info) {
295  DBUG_PRINT("list_invariants",
296  ("%s: error: NULL element in the list", name));
297  return false;
298  }
299  node = node->next;
300  cnt++;
301  }
302  if (last != &(node->next)) {
303  DBUG_PRINT("list_invariants", ("%s: error: wrong last pointer", name));
304  return false;
305  }
306  if (cnt + 1 != elements) {
307  DBUG_PRINT("list_invariants", ("%s: error: wrong element count", name));
308  return false;
309  }
310  DBUG_PRINT("list_invariants", ("%s: list is ok", name));
311  return true;
312  }
313 #endif // LIST_EXTRA_DEBUG
314 
315  protected:
316  void after(void *info, list_node *node) {
317  list_node *new_node = new (*THR_MALLOC) list_node(info, node->next);
318  node->next = new_node;
319  elements++;
320  if (last == &(node->next)) last = &new_node->next;
321  }
322  bool after(void *info, list_node *node, MEM_ROOT *mem_root) {
323  list_node *new_node = new (mem_root) list_node(info, node->next);
324  if (!new_node) return true; // OOM
325 
326  node->next = new_node;
327  elements++;
328  if (last == &(node->next)) last = &new_node->next;
329 
330  return false;
331  }
332 };
333 
335  protected:
338  void sublist(base_list &ls, uint elm) {
339  ls.first = *el;
340  ls.last = list->last;
341  ls.elements = elm;
342  }
343 
344  public:
345  base_list_iterator() : list(0), el(0), prev(0), current(0) {}
346 
347  base_list_iterator(base_list &list_par) { init(list_par); }
348 
349  inline void init(base_list &list_par) {
350  list = &list_par;
351  el = &list_par.first;
352  prev = 0;
353  current = 0;
354  }
355 
356  inline void *next(void) {
357  prev = el;
358  current = *el;
359  el = &current->next;
360  return current->info;
361  }
362  inline void *next_fast(void) {
363  list_node *tmp;
364  tmp = *el;
365  el = &tmp->next;
366  return tmp->info;
367  }
368  inline void rewind(void) { el = &list->first; }
369  inline void *replace(void *element) { // Return old element
370  void *tmp = current->info;
371  DBUG_ASSERT(current->info != 0);
372  current->info = element;
373  return tmp;
374  }
375  void *replace(base_list &new_list) {
376  void *ret_value = current->info;
377  if (!new_list.is_empty()) {
378  *new_list.last = current->next;
379  current->info = new_list.first->info;
380  current->next = new_list.first->next;
381  if ((list->last == &current->next) && (new_list.elements > 1))
382  list->last = new_list.last;
383  list->elements += new_list.elements - 1;
384  }
385  return ret_value; // return old element
386  }
387  inline void remove(void) // Remove current
388  {
389  list->remove(prev);
390  el = prev;
391  current = 0; // Safeguard
392  }
393  void after(void *element) // Insert element after current
394  {
395  list->after(element, current);
396  current = current->next;
397  el = &current->next;
398  }
399  bool after(void *a, MEM_ROOT *mem_root) {
400  if (list->after(a, current, mem_root)) return true;
401 
402  current = current->next;
403  el = &current->next;
404  return false;
405  }
406  inline void **ref(void) // Get reference pointer
407  {
408  return &current->info;
409  }
410  inline bool is_last(void) { return el == list->last; }
411  inline bool is_before_first() const { return current == NULL; }
412  bool prepend(void *a, MEM_ROOT *mem_root) {
413  if (list->push_front(a, mem_root)) return true;
414 
415  el = &list->first;
416  prev = el;
417  el = &(*el)->next;
418 
419  return false;
420  }
421  friend class error_list_iterator;
422 };
423 
424 template <class T>
426 
427 template <class T>
428 class List : public base_list {
429  public:
430  List() : base_list() {}
431  inline List(const List<T> &tmp) : base_list(tmp) {}
432  List &operator=(const List &tmp) {
433  return static_cast<List &>(base_list::operator=(tmp));
434  }
435  inline List(const List<T> &tmp, MEM_ROOT *mem_root)
436  : base_list(tmp, mem_root) {}
437  /*
438  Typecasting to (void *) it's necessary if we want to declare List<T> with
439  constant T parameter (like List<const char>), since the untyped storage
440  is "void *", and assignment of const pointer to "void *" is a syntax error.
441  */
442  inline bool push_back(T *a) { return base_list::push_back((void *)a); }
443  inline bool push_back(T *a, MEM_ROOT *mem_root) {
444  return base_list::push_back((void *)a, mem_root);
445  }
446  inline bool push_front(T *a) { return base_list::push_front((void *)a); }
447  inline bool push_front(T *a, MEM_ROOT *mem_root) {
448  return base_list::push_front((void *)a, mem_root);
449  }
450  inline T *head() { return static_cast<T *>(base_list::head()); }
451  inline const T *head() const {
452  return static_cast<const T *>(base_list::head());
453  }
454  inline T **head_ref() { return (T **)base_list::head_ref(); }
455  inline T *pop() { return (T *)base_list::pop(); }
459  void delete_elements(void) {
460  list_node *element, *next;
461  for (element = first; element != &end_of_list; element = next) {
462  next = element->next;
463  delete (T *)element->info;
464  }
465  empty();
466  }
467 
468  void destroy_elements(void) {
469  list_node *element, *next;
470  for (element = first; element != &end_of_list; element = next) {
471  next = element->next;
472  destroy((T *)element->info);
473  }
474  empty();
475  }
476 
477  T *operator[](uint index) const {
479  list_node *current = first;
480  for (uint i = 0; i < index; ++i) current = current->next;
481  return static_cast<T *>(current->info);
482  }
483 
484  void replace(uint index, T *new_value) {
486  list_node *current = first;
487  for (uint i = 0; i < index; ++i) current = current->next;
488  current->info = new_value;
489  }
490 
491  bool swap_elts(uint index1, uint index2) {
492  if (index1 == index2) return false;
493 
494  if (index1 >= elements || index2 >= elements) return true; // error
495 
496  if (index2 < index1) std::swap(index1, index2);
497 
498  list_node *current1 = first;
499  for (uint i = 0; i < index1; ++i) current1 = current1->next;
500 
501  list_node *current2 = current1;
502  for (uint i = 0; i < index2 - index1; ++i) current2 = current2->next;
503 
504  std::swap(current1->info, current2->info);
505 
506  return false;
507  }
508 
509  /**
510  @brief
511  Sort the list
512 
513  @param cmp node comparison function
514 
515  @details
516  The function sorts list nodes by an exchange sort algorithm.
517  The order of list nodes isn't changed, values of info fields are
518  swapped instead. Due to this, list iterators that are initialized before
519  sort could be safely used after sort, i.e they wouldn't cause a crash.
520  As this isn't an effective algorithm the list to be sorted is supposed to
521  be short.
522  */
523  template <typename Node_cmp_func>
524  void sort(Node_cmp_func cmp) {
525  if (elements < 2) return;
526  for (list_node *n1 = first; n1 && n1 != &end_of_list; n1 = n1->next) {
527  for (list_node *n2 = n1->next; n2 && n2 != &end_of_list; n2 = n2->next) {
528  if (cmp(static_cast<T *>(n1->info), static_cast<T *>(n2->info)) > 0) {
529  void *tmp = n1->info;
530  n1->info = n2->info;
531  n2->info = tmp;
532  }
533  }
534  }
535  }
536 
537  // For C++11 range-based for loops.
539  iterator begin() { return iterator(first); }
541  // If the list overlaps another list, last isn't actually
542  // the last element, and if so, we'd give a different result from
543  // List_iterator_fast.
544  DBUG_ASSERT((*last)->next == &end_of_list);
545 
546  return iterator(*last);
547  }
548 
551  const_iterator end() const {
552  DBUG_ASSERT((*last)->next == &end_of_list);
553  return const_iterator(*last);
554  }
557  DBUG_ASSERT((*last)->next == &end_of_list);
558  return const_iterator(*last);
559  }
560 };
561 
562 template <class T>
563 class List_iterator : public base_list_iterator {
564  public:
567  inline void init(List<T> &a) { base_list_iterator::init(a); }
568  inline T *operator++(int) { return (T *)base_list_iterator::next(); }
569  inline T *replace(T *a) { return (T *)base_list_iterator::replace(a); }
570  inline T *replace(List<T> &a) { return (T *)base_list_iterator::replace(a); }
571  inline void rewind(void) { base_list_iterator::rewind(); }
572  inline void remove() { base_list_iterator::remove(); }
573  inline void after(T *a) { base_list_iterator::after(a); }
574  inline bool after(T *a, MEM_ROOT *mem_root) {
576  }
577  inline T **ref(void) { return (T **)base_list_iterator::ref(); }
578 };
579 
580 template <class T>
582  protected:
583  inline T *replace(T *) { return (T *)0; }
584  inline T *replace(List<T> &) { return (T *)0; }
585  inline void remove(void) {}
586  inline void after(T *) {}
587  inline T **ref(void) { return (T **)0; }
588 
589  public:
592  inline void init(List<T> &a) { base_list_iterator::init(a); }
593  inline T *operator++(int) { return (T *)base_list_iterator::next_fast(); }
594  inline void rewind(void) { base_list_iterator::rewind(); }
595  void sublist(List<T> &list_arg, uint el_arg) {
596  base_list_iterator::sublist(list_arg, el_arg);
597  }
598 };
599 
600 /*
601  Like List_iterator<T>, but with an STL-compatible interface
602  (ForwardIterator), so that you can use it in range-based for loops.
603  Prefer this to List_iterator<T> wherever possible, but also prefer
604  std::vector<T> or std::list<T> to List<T> wherever possible.
605  */
606 template <class T>
607 class List_STL_Iterator {
608  public:
609  explicit List_STL_Iterator(list_node *node) : m_current(node) {}
610 
611  // Iterator (required for InputIterator).
612  T &operator*() const { return *static_cast<T *>(m_current->info); }
613 
616  return *this;
617  }
618 
619  using difference_type = ptrdiff_t;
620  using value_type = T; // NOTE: std::remove_cv_t<T> from C++20.
621  using pointer = T *;
622  using reference = T &;
623  using iterator_category = std::forward_iterator_tag;
624 
625  // EqualityComparable (required for InputIterator).
626  bool operator==(const List_STL_Iterator &other) const {
627  return m_current == other.m_current;
628  }
629 
630  // InputIterator (required for ForwardIterator).
631  bool operator!=(const List_STL_Iterator &other) const {
632  return !(*this == other);
633  }
634 
635  T *operator->() const { return static_cast<T *>(m_current->info); }
636 
637  // DefaultConstructible (required for ForwardIterator).
639 
640  // ForwardIterator.
642  List_STL_Iterator copy = *this;
644  return copy;
645  }
646 
647  private:
649 };
650 
651 template <typename T>
653 template <typename T>
655 
656 /*
657  A simple intrusive list.
658 
659  NOTE: this inherently unsafe, since we rely on <T> to have
660  the same layout as ilink<T> (see base_ilist::sentinel).
661  Please consider using a different strategy for linking objects.
662 */
663 
664 template <typename T>
665 class ilink {
666  T **prev, *next;
667 
668  public:
669  ilink() : prev(NULL), next(NULL) {}
670 
671  void unlink() {
672  /* Extra tests because element doesn't have to be linked */
673  if (prev) *prev = next;
674  if (next) next->prev = prev;
675  prev = NULL;
676  next = NULL;
677  }
678 
679  friend class base_ilist<T>;
680  friend class base_ilist_iterator<T>;
681 };
682 
683 /* Needed to be able to have an I_List of char* strings in mysqld.cc. */
684 
685 class i_string : public ilink<i_string> {
686  public:
687  const char *ptr;
688  i_string() : ptr(0) {}
689  i_string(const char *s) : ptr(s) {}
690 };
691 
692 /* needed for linked list of two strings for replicate-rewrite-db */
693 class i_string_pair : public ilink<i_string_pair> {
694  public:
695  const char *key;
696  const char *val;
697  i_string_pair() : key(0), val(0) {}
698  i_string_pair(const char *key_arg, const char *val_arg)
699  : key(key_arg), val(val_arg) {}
700 };
701 
702 template <class T>
704 
705 template <typename T>
706 class base_ilist {
707  T *first;
709 
710  static_assert(!std::is_polymorphic<T>::value,
711  "Do not use this for classes with virtual members");
712 
713  public:
714  // The sentinel is not a T, but at least it is a POD
716  first = static_cast<T *>(&sentinel);
717  sentinel.prev = &first;
718  }
719  base_ilist() { empty(); }
720 
721  // The sentinel is not a T, but at least it is a POD
722  bool is_empty() const SUPPRESS_UBSAN {
723  return first == static_cast<const T *>(&sentinel);
724  }
725 
726  /// Pushes new element in front of list.
727  void push_front(T *a) {
728  first->prev = &a->next;
729  a->next = first;
730  a->prev = &first;
731  first = a;
732  }
733 
734  /// Pushes new element to the end of the list, i.e. in front of the sentinel.
735  void push_back(T *a) {
736  *sentinel.prev = a;
737  a->next = static_cast<T *>(&sentinel);
738  a->prev = sentinel.prev;
739  sentinel.prev = &a->next;
740  }
741 
742  // Unlink first element, and return it.
743  T *get() {
744  if (is_empty()) return NULL;
745  T *first_link = first;
746  first_link->unlink();
747  return first_link;
748  }
749 
750  T *head() { return is_empty() ? NULL : first; }
751 
752  /**
753  Moves list elements to new owner, and empties current owner (i.e. this).
754 
755  @param[in,out] new_owner The new owner of the list elements.
756  Should be empty in input.
757  */
758 
759  void move_elements_to(base_ilist *new_owner) {
760  DBUG_ASSERT(new_owner->is_empty());
761  new_owner->first = first;
762  new_owner->sentinel = sentinel;
763  empty();
764  }
765 
766  friend class base_ilist_iterator<T>;
767 
768  private:
769  /*
770  We don't want to allow copying of this class, as that would give us
771  two list heads containing the same elements.
772  So we declare, but don't define copy CTOR and assignment operator.
773  */
774  base_ilist(const base_ilist &);
775  void operator=(const base_ilist &);
776 };
777 
778 template <typename T>
779 class base_ilist_iterator {
781  T **el, *current;
782 
783  public:
785  : list(&list_par), el(&list_par.first), current(NULL) {}
786 
787  // The sentinel is not a T, but at least it is a POD
788  T *next(void) SUPPRESS_UBSAN {
789  /* This is coded to allow push_back() while iterating */
790  current = *el;
791  if (current == static_cast<T *>(&list->sentinel)) return NULL;
792  el = &current->next;
793  return current;
794  }
795 };
796 
797 template <class T>
798 class I_List : private base_ilist<T> {
799  public:
800  using base_ilist<T>::empty;
802  using base_ilist<T>::get;
805  using base_ilist<T>::head;
806  void move_elements_to(I_List<T> *new_owner) {
808  }
809  friend class I_List_iterator<T>;
810 };
811 
812 template <class T>
813 class I_List_iterator : public base_ilist_iterator<T> {
814  public:
816  inline T *operator++(int) { return base_ilist_iterator<T>::next(); }
817 };
818 
821 
822 template <class T>
823 List<T> *List_merge(T *head, List<T> *tail) {
824  tail->push_front(head);
825  return tail;
826 }
827 
828 #endif // INCLUDES_MYSQL_SQL_LIST_H
uint size() const
Definition: sql_list.h:267
Definition: sql_list.h:652
void concat(List< T > *list)
Definition: sql_list.h:456
bool push_back(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:443
T value_type
Definition: sql_list.h:620
friend class error_list
Definition: sql_list.h:269
ilink< T > sentinel
Definition: sql_list.h:708
void after(T *)
Definition: sql_list.h:586
list_node * last_ref()
Definition: sql_list.h:266
bool operator==(const base_list &rhs) const
Definition: sql_list.h:137
bool after(void *info, list_node *node, MEM_ROOT *mem_root)
Definition: sql_list.h:322
void after(T *a)
Definition: sql_list.h:573
const_iterator end() const
Definition: sql_list.h:551
T ** ref(void)
Definition: sql_list.h:577
std::forward_iterator_tag iterator_category
Definition: sql_list.h:623
void move_elements_to(base_ilist *new_owner)
Moves list elements to new owner, and empties current owner (i.e.
Definition: sql_list.h:759
void sublist(base_list &ls, uint elm)
Definition: sql_list.h:338
void after(void *info, list_node *node)
Definition: sql_list.h:316
#define SUPPRESS_UBSAN
Definition: my_compiler.h:130
const string name("\ame\)
T ** next
A reference to the next element in the list.
Definition: sql_list.h:51
int cmp
Definition: dbug_analyze.cc:237
bool swap_elts(uint index1, uint index2)
Definition: sql_list.h:491
void ** head_ref()
Definition: sql_list.h:264
uint size() const
Definition: sql_list.h:95
bool is_empty() const
Definition: sql_list.h:265
T * first
Definition: sql_list.h:707
void rewind(void)
Definition: sql_list.h:594
void * next(void)
Definition: sql_list.h:356
T * replace(T *)
Definition: sql_list.h:583
#define MYSQL_PLUGIN_IMPORT
Definition: my_sharedlib.h:70
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:735
T * replace(List< T > &)
Definition: sql_list.h:584
T * operator++(int)
Definition: sql_list.h:593
bool prepend(void *a, MEM_ROOT *mem_root)
Definition: sql_list.h:412
void destroy_elements(void)
Definition: sql_list.h:468
List< T > * List_merge(T *head, List< T > *tail)
Definition: sql_list.h:823
bool push_front(void *info)
Definition: sql_list.h:187
for(ix=1;ix< argc &&argv[ix][0]=='-';ix++)
Definition: main.cc:10
void save_and_clear(SQL_I_List< T > *save)
Definition: sql_list.h:75
void swap(base_list &rhs)
Swap two lists.
Definition: sql_list.h:255
base_list_iterator()
Definition: sql_list.h:345
T ** head_ref()
Definition: sql_list.h:454
const_iterator cend() const
Definition: sql_list.h:556
Sergei Dialog Client Authentication NULL
Definition: dialog.cc:352
bool is_last(void)
Definition: sql_list.h:410
List_STL_Iterator & operator++()
Definition: sql_list.h:614
void ** ref(void)
Definition: sql_list.h:406
bool push_back(void *info, MEM_ROOT *mem_root)
Definition: sql_list.h:179
void push_front(SQL_I_List< T > *save)
Definition: sql_list.h:80
Simple intrusive linked list.
Definition: item.h:80
bool push_back(void *info)
Definition: sql_list.h:171
list_node * first
Definition: sql_list.h:132
void push_back(SQL_I_List< T > *save)
Definition: sql_list.h:87
Definition: sql_list.h:425
bool push_front(void *info, MEM_ROOT *mem_root)
Definition: sql_list.h:197
class udf_list * list
base_ilist()
Definition: sql_list.h:719
void rewind(void)
Definition: sql_list.h:368
List_STL_Iterator operator++(int)
Definition: sql_list.h:641
void concat(base_list *list)
Definition: sql_list.h:217
Definition: sql_list.h:334
bool is_before_first() const
Definition: sql_list.h:411
bool push_front(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:447
SQL_I_List(const SQL_I_List &tmp)
Definition: sql_list.h:55
List & operator=(const List &tmp)
Definition: sql_list.h:432
void * pop(void)
Definition: sql_list.h:224
T ** ref(void)
Definition: sql_list.h:587
iterator begin()
Definition: sql_list.h:539
base_ilist_iterator(base_ilist< T > &list_par)
Definition: sql_list.h:784
Functions related to handling of plugins and other dynamically loaded libraries.
void * replace(void *element)
Definition: sql_list.h:369
void link_in_list(T *element, T **next_ptr)
Definition: sql_list.h:68
void empty() SUPPRESS_UBSAN
Definition: sql_list.h:715
void init(base_list &list_par)
Definition: sql_list.h:349
list_node * first_node()
Definition: sql_list.h:261
void disjoin(List< T > *list)
Definition: sql_list.h:457
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:165
T * head()
Definition: sql_list.h:750
list_node * next
Definition: sql_list.h:117
list_node * current
Definition: sql_list.h:337
void remove(void)
Definition: sql_list.h:387
void empty()
Definition: sql_list.h:141
#define DBUG_ASSERT(A)
Definition: my_dbug.h:183
SQL_I_List & operator=(SQL_I_List &)=default
List_STL_Iterator< const T > const_iterator
Definition: sql_list.h:549
char * index(const char *, int c)
Definition: mysql.cc:2847
MYSQL_PLUGIN_IMPORT list_node end_of_list
Definition: sql_list.cc:27
Definition: sql_list.h:703
void operator=(const base_ilist &)
I_List_iterator(I_List< T > &a)
Definition: sql_list.h:815
const char * val
Definition: sql_list.h:696
T * operator++(int)
Definition: sql_list.h:816
List_iterator()
Definition: sql_list.h:566
friend class error_list_iterator
Definition: sql_list.h:421
Definition: aggregate_check.h:523
T & operator*() const
Definition: sql_list.h:612
base_list()
Definition: sql_list.h:146
i_string()
Definition: sql_list.h:688
list_node()
Definition: sql_list.h:121
const void * head() const
Definition: sql_list.h:263
void * head()
Definition: sql_list.h:262
List_iterator(List< T > &a)
Definition: sql_list.h:565
const char * ptr
Definition: sql_list.h:687
Header for compiler-dependent features.
Definition: sql_list.h:693
void remove(list_node **prev)
Definition: sql_list.h:208
void push_front(T *a)
Pushes new element in front of list.
Definition: sql_list.h:727
unsigned int uint
Definition: uca-dump.cc:29
List_STL_Iterator(list_node *node)
Definition: sql_list.h:609
SQL_I_List()
Definition: sql_list.h:53
void sort(Node_cmp_func cmp)
Sort the list.
Definition: sql_list.h:524
list_node * m_current
Definition: sql_list.h:648
bool operator!=(const List_STL_Iterator &other) const
Definition: sql_list.h:631
list_node(void *info_par, list_node *next_par)
Definition: sql_list.h:119
list_node * last_node()
Definition: sql_list.h:260
List(const List< T > &tmp)
Definition: sql_list.h:431
base_ilist< T > * list
Definition: sql_list.h:780
uint elements
Definition: sql_list.h:47
Definition: sql_list.h:654
T * next(void) SUPPRESS_UBSAN
Definition: sql_list.h:788
list_node - a node of a single-linked list.
Definition: sql_list.h:116
bool operator==(const List_STL_Iterator &other) const
Definition: sql_list.h:626
static MEM_ROOT mem_root
Definition: client_plugin.cc:107
List_STL_Iterator< T > iterator
Definition: sql_list.h:538
void * info
Definition: sql_list.h:118
bool is_empty() const SUPPRESS_UBSAN
Definition: sql_list.h:722
T & reference
Definition: sql_list.h:622
List_STL_Iterator()
Definition: sql_list.h:638
T * pop()
Definition: sql_list.h:455
T * replace(T *a)
Definition: sql_list.h:569
void disjoin(base_list *list)
Definition: sql_list.h:231
T * current
Definition: sql_list.h:781
void init(List< T > &a)
Definition: sql_list.h:567
Definition: sql_list.h:130
void free_list(I_List< i_string_pair > *list)
Definition: sql_list.cc:29
bool after(T *a, MEM_ROOT *mem_root)
Definition: sql_list.h:574
thread_local MEM_ROOT ** THR_MALLOC
Definition: mysqld.cc:1333
base_list * list
Definition: sql_list.h:336
uint elements
Definition: sql_list.h:135
const char * key
Definition: sql_list.h:695
i_string_pair()
Definition: sql_list.h:697
void move_elements_to(I_List< T > *new_owner)
Definition: sql_list.h:806
Definition: sql_list.h:581
void init(List< T > &a)
Definition: sql_list.h:592
T * operator[](uint index) const
Definition: sql_list.h:477
friend class error_list_iterator
Definition: sql_list.h:270
void prepend(List< T > *list)
Definition: sql_list.h:458
void destroy(T *ptr)
Definition: my_alloc.h:377
Definition: protocol_classic.h:46
void rewind(void)
Definition: sql_list.h:571
T * first
The first element in the list.
Definition: sql_list.h:49
static void swap(String &a, String &b) noexcept
Definition: sql_string.h:583
base_list & operator=(const base_list &tmp)
Definition: sql_list.h:160
i_string_pair(const char *key_arg, const char *val_arg)
Definition: sql_list.h:698
void prepend(base_list *list)
Definition: sql_list.h:244
const_iterator cbegin() const
Definition: sql_list.h:555
T ** el
Definition: sql_list.h:781
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
const string value("\alue\)
list_node ** prev
Definition: sql_list.h:337
const_iterator begin() const
Definition: sql_list.h:550
T * replace(List< T > &a)
Definition: sql_list.h:570
Log info(cout, "NOTE")
List()
Definition: sql_list.h:430
T * pointer
Definition: sql_list.h:621
void delete_elements(void)
Definition: sql_list.h:459
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:77
void sublist(List< T > &list_arg, uint el_arg)
Definition: sql_list.h:595
Definition: item.h:78
bool push_back(T *a)
Definition: sql_list.h:442
void empty()
Definition: sql_list.h:62
list_node ** last
Definition: sql_list.h:132
void * next_fast(void)
Definition: sql_list.h:362
const T * head() const
Definition: sql_list.h:451
T * head()
Definition: sql_list.h:450
ptrdiff_t difference_type
Definition: sql_list.h:619
bool after(void *a, MEM_ROOT *mem_root)
Definition: sql_list.h:399
void * replace(base_list &new_list)
Definition: sql_list.h:375
iterator end()
Definition: sql_list.h:540
T * operator->() const
Definition: sql_list.h:635
List_iterator_fast()
Definition: sql_list.h:591
List(const List< T > &tmp, MEM_ROOT *mem_root)
Definition: sql_list.h:435
T * operator++(int)
Definition: sql_list.h:568
Definition: sql_list.h:685
void replace(uint index, T *new_value)
Definition: sql_list.h:484
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
list_node ** el
Definition: sql_list.h:337
bool push_front(T *a)
Definition: sql_list.h:446
base_list_iterator(base_list &list_par)
Definition: sql_list.h:347
List_iterator_fast(List< T > &a)
Definition: sql_list.h:590
void after(void *element)
Definition: sql_list.h:393
i_string(const char *s)
Definition: sql_list.h:689