1 #ifndef INCLUDES_MYSQL_SQL_LIST_H 
    2 #define INCLUDES_MYSQL_SQL_LIST_H 
   18 #include "sql_alloc.h" 
   19 #include "my_global.h" 
   26 #include "thr_malloc.h"                          
   50     elements= tmp.elements;
 
   62   inline void link_in_list(T *element, T **next_ptr)
 
   81     elements+= save->elements;
 
   90       elements+= save->elements;
 
  117     :next(next_par),info(info_par)
 
  127 extern MYSQL_PLUGIN_IMPORT 
list_node end_of_list;
 
  142 typedef int (*Node_cmp_func)(
void *n1, 
void *n2, 
void *arg);
 
  152   bool operator==(
const base_list &rhs)
 const 
  155       elements == rhs.elements &&
 
  156       first == rhs.first &&
 
  160   inline void empty() { elements=0; first= &end_of_list; last=&first;}
 
  173     elements= tmp.elements;
 
  175     last= elements ? tmp.last : &first;
 
  185   inline bool push_back(
void *info)
 
  187     if (((*last)=
new list_node(info, &end_of_list)))
 
  189       last= &(*last)->next;
 
  195   inline bool push_back(
void *info, 
MEM_ROOT *mem_root)
 
  197     if (((*last)=
new (mem_root) 
list_node(info, &end_of_list)))
 
  199       last= &(*last)->next;
 
  205   inline bool push_front(
void *info)
 
  223     else if (last == &(*prev)->next)
 
  230     if (!list->is_empty())
 
  234       elements+= list->elements;
 
  237   inline void *pop(
void)
 
  239     if (first == &end_of_list) 
return 0;
 
  252     while (node && node != list_first)
 
  263     if (!list->is_empty())
 
  267       elements+= list->elements;
 
  285   void sort(Node_cmp_func cmp, 
void *arg)
 
  289     for (
list_node *n1= first; n1 && n1 != &end_of_list; n1= n1->next)
 
  291       for (
list_node *n2= n1->next; n2 && n2 != &end_of_list; n2= n2->next)
 
  293         if ((*cmp)(n1->info, n2->info, arg) > 0)
 
  307     swap_variables(
list_node *, first, rhs.first);
 
  308     swap_variables(
list_node **, last, rhs.last);
 
  309     swap_variables(uint, elements, rhs.elements);
 
  311   inline list_node* last_node() { 
return *last; }
 
  312   inline list_node* first_node() { 
return first;}
 
  313   inline void *head() { 
return first->info; }
 
  314   inline void **head_ref() { 
return first != &end_of_list ? &first->info : 0; }
 
  315   inline bool is_empty()
 const { 
return first == &end_of_list ; }
 
  316   inline list_node *last_ref() { 
return &end_of_list; }
 
  318   friend class error_list;
 
  319   friend class error_list_iterator;
 
  321 #ifdef LIST_EXTRA_DEBUG 
  337   bool check_list(
const char *
name)
 
  343     while (node->next != &end_of_list)
 
  347         DBUG_PRINT(
"list_invariants",(
"%s: error: NULL element in the list", 
 
  354     if (last != &(node->next))
 
  356       DBUG_PRINT(
"list_invariants", (
"%s: error: wrong last pointer", name));
 
  359     if (cnt+1 != elements)
 
  361       DBUG_PRINT(
"list_invariants", (
"%s: error: wrong element count", name));
 
  364     DBUG_PRINT(
"list_invariants", (
"%s: list is ok", name));
 
  367 #endif // LIST_EXTRA_DEBUG 
  375     if (last == &(node->next))
 
  376       last= &new_node->next;
 
  393     :list(0), el(0), prev(0), current(0)
 
  407   inline void *next(
void)
 
  412     return current->info;
 
  414   inline void *next_fast(
void)
 
  421   inline void rewind(
void)
 
  425   inline void *
replace(
void *element)
 
  427     void *tmp=current->info;
 
  428     DBUG_ASSERT(current->info != 0);
 
  429     current->info=element;
 
  434     void *ret_value=current->info;
 
  435     if (!new_list.is_empty())
 
  437       *new_list.last=current->next;
 
  438       current->info=new_list.first->info;
 
  439       current->next=new_list.first->next;
 
  440       if ((list->last == ¤t->next) && (new_list.elements > 1))
 
  441         list->last= new_list.last;
 
  442       list->elements+=new_list.elements-1;
 
  446   inline void remove(void)                      
 
  452   void after(
void *element)                     
 
  454     list->after(element,current);
 
  455     current=current->next;
 
  458   inline void **ref(
void)                       
 
  460     return ¤t->info;
 
  462   inline bool is_last(
void)
 
  464     return el == &list->last_ref()->next;
 
  466   friend class error_list_iterator;
 
  481   inline bool push_back(T *a) { 
return base_list::push_back((
void *) a); }
 
  482   inline bool push_back(T *a, 
MEM_ROOT *mem_root)
 
  483   { 
return base_list::push_back((
void *) a, mem_root); }
 
  484   inline bool push_front(T *a) { 
return base_list::push_front((
void *) a); }
 
  485   inline T* head() {
return (T*) base_list::head(); }
 
  486   inline T** head_ref() {
return (T**) base_list::head_ref(); }
 
  487   inline T* pop()  {
return (T*) base_list::pop(); }
 
  488   inline void concat(
List<T> *list) { base_list::concat(list); }
 
  489   inline void disjoin(
List<T> *list) { base_list::disjoin(list); }
 
  490   inline void prepand(
List<T> *list) { base_list::prepand(list); }
 
  491   void delete_elements(
void)
 
  494     for (element=first; element != &end_of_list; element=next)
 
  497       delete (T*) element->info;
 
  511   inline void init(
List<T> &a) { base_list_iterator::init(a); }
 
  512   inline T* operator++(
int) { 
return (T*) base_list_iterator::next(); }
 
  513   inline T *
replace(T *a)   { 
return (T*) base_list_iterator::replace(a); }
 
  514   inline T *
replace(
List<T> &a) { 
return (T*) base_list_iterator::replace(a); }
 
  515   inline void rewind(
void)  { base_list_iterator::rewind(); }
 
  516   inline void remove()      { base_list_iterator::remove(); }
 
  517   inline void after(T *a)   { base_list_iterator::after(a); }
 
  518   inline T** ref(
void)      { 
return (T**) base_list_iterator::ref(); }
 
  525   inline T *
replace(T *a)   { 
return (T*) 0; }
 
  527   inline void remove(void)  { }
 
  528   inline void after(T *a)   { }
 
  529   inline T** ref(
void)      { 
return (T**) 0; }
 
  534   inline void init(
List<T> &a) { base_list_iterator::init(a); }
 
  535   inline T* operator++(
int) { 
return (T*) base_list_iterator::next_fast(); }
 
  536   inline void rewind(
void)  { base_list_iterator::rewind(); }
 
  537   void sublist(
List<T> &list_arg, uint el_arg)
 
  539     base_list_iterator::sublist(list_arg, el_arg);
 
  555 template <
typename T>
 
  560   ilink() : prev(NULL), next(NULL) {}
 
  565     if (prev) *prev= next;
 
  566     if (next) next->prev=prev;
 
  571   virtual ~
ilink() { unlink(); }                
 
  596     key(key_arg),val(val_arg) {}
 
  610     first= 
static_cast<T*
>(&sentinel);
 
  611     sentinel.prev= &first;
 
  614   bool is_empty()
 const { 
return first == 
static_cast<const T*
>(&sentinel); }
 
  619     first->prev= &a->next;
 
  629     a->next= 
static_cast<T*
>(&sentinel);
 
  630     a->prev= sentinel.prev;
 
  631     sentinel.prev= &a->next;
 
  639     T *first_link= first;
 
  640     first_link->unlink();
 
  644   T *head() { 
return is_empty() ? NULL : first; }
 
  655     DBUG_ASSERT(new_owner->is_empty());
 
  656     new_owner->first= first;
 
  657     new_owner->sentinel= sentinel;
 
  689     if (current == static_cast<T*>(&list->sentinel))
 
  707   void move_elements_to(
I_List<T>* new_owner) {
 
  739 template <
typename T>
 
  748     it.replace(el->clone(mem_root));
 
  754 #endif // INCLUDES_MYSQL_SQL_LIST_H