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