20
20
#ifndef DRIZZLED_SQL_LIST_H
21
21
#define DRIZZLED_SQL_LIST_H
27
26
#include <algorithm>
28
#include "drizzled/memory/sql_alloc.h"
27
#include <drizzled/memory/sql_alloc.h>
28
#include <drizzled/visibility.h>
32
typedef struct st_sql_list
33
/** Struct to handle simple linked lists. */
34
typedef struct st_sql_list {
36
35
unsigned char *first;
37
36
unsigned char **next;
39
st_sql_list() {} /* Remove gcc warning */
46
inline void link_in_list(unsigned char *element,unsigned char **next_ptr)
50
void link_in_list(unsigned char *element,unsigned char **next_ptr)
53
inline void save_and_clear(struct st_sql_list *save)
57
void save_and_clear(struct st_sql_list *save)
58
inline void push_front(struct st_sql_list *save)
62
void push_front(struct st_sql_list *save)
60
64
*save->next= first; /* link current list last */
61
65
first= save->first;
62
66
elements+= save->elements;
64
inline void push_back(struct st_sql_list *save)
68
void push_back(struct st_sql_list *save)
106
extern list_node end_of_list;
109
extern DRIZZLED_API list_node end_of_list;
108
111
class base_list :public memory::SqlAlloc
111
114
list_node *first,**last;
116
inline void empty() { elements=0; first= &end_of_list; last=&first;}
117
inline base_list() { empty(); }
118
void clear() { elements=0; first= &end_of_list; last=&first;}
119
base_list() { clear(); }
119
121
This is a shallow copy constructor that implicitly passes the ownership
120
122
from the source list to the new instance. The old instance is not
124
126
relies on this behaviour. This logic is quite tricky: please do not use
125
127
it in any new code.
127
inline base_list(const base_list &tmp) :memory::SqlAlloc()
129
base_list(const base_list &tmp) :memory::SqlAlloc()
129
131
elements= tmp.elements;
130
132
first= tmp.first;
131
133
last= elements ? tmp.last : &first;
133
inline base_list(bool) { }
134
inline bool push_back(void *info)
136
bool push_back(void *info)
136
138
if (((*last)=new list_node(info, &end_of_list)))
222
inline void swap(base_list &rhs)
224
void swap(base_list &rhs)
224
226
std::swap(first, rhs.first);
225
227
std::swap(last, rhs.last);
226
228
std::swap(elements, rhs.elements);
228
inline list_node* last_node() { return *last; }
229
inline list_node* first_node() { return first;}
230
inline void *head() { return first->info; }
231
inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
232
inline bool is_empty() { return first == &end_of_list ; }
233
inline list_node *last_ref() { return &end_of_list; }
230
bool is_empty() { return first == &end_of_list ; }
234
231
friend class base_list_iterator;
235
friend class error_list;
236
friend class error_list_iterator;
238
233
#ifdef LIST_EXTRA_DEBUG
297
292
list_node **el,**prev,*current;
298
294
void sublist(base_list &ls, uint32_t elm)
301
297
ls.last= list->last;
302
298
ls.elements= elm;
305
300
base_list_iterator()
306
301
:list(0), el(0), prev(0), current(0)
309
base_list_iterator(base_list &list_par)
312
inline void init(base_list &list_par)
304
base_list_iterator(base_list &list_par, list_node** el0)
305
:list(&list_par), el(el0), prev(0), current(0)
320
inline void *next(void)
324
313
el= ¤t->next;
325
314
return current->info;
327
inline void *next_fast(void)
334
inline void rewind(void)
338
inline void *replace(void *element)
339
{ // Return old element
340
void *tmp=current->info;
341
assert(current->info != 0);
342
current->info=element;
345
316
void *replace(base_list &new_list)
347
318
void *ret_value=current->info;
350
321
*new_list.last=current->next;
351
322
current->info=new_list.first->info;
352
323
current->next=new_list.first->next;
353
if ((list->last == ¤t->next) && (new_list.elements > 1))
354
list->last= new_list.last;
324
if (list->last == ¤t->next && new_list.elements > 1)
325
list->last= new_list.last;
355
326
list->elements+=new_list.elements-1;
357
328
return ret_value; // return old element
359
inline void remove(void) // Remove current
330
void remove() // Remove current
361
332
list->remove(prev);
368
339
current=current->next;
369
340
el= ¤t->next;
371
inline void **ref(void) // Get reference pointer
373
return ¤t->info;
375
inline bool is_last(void)
377
return el == &list->last_ref()->next;
379
friend class error_list_iterator;
382
template <class T> class List :public base_list
344
template <class T> class List_iterator;
346
template <class T> class List : public base_list
385
inline List() :base_list() {}
386
inline List(const List<T> &tmp) :base_list(tmp) {}
387
inline List(const List<T> &tmp, memory::Root *mem_root) :
388
base_list(tmp, mem_root) {}
389
inline bool push_back(T *a) { return base_list::push_back(a); }
390
inline bool push_back(T *a, memory::Root *mem_root)
391
{ return base_list::push_back(a, mem_root); }
392
inline bool push_front(T *a) { return base_list::push_front(a); }
393
inline T* head() {return (T*) base_list::head(); }
394
inline T** head_ref() {return (T**) base_list::head_ref(); }
395
inline T* pop() {return (T*) base_list::pop(); }
396
inline void concat(List<T> *list) { base_list::concat(list); }
397
inline void disjoin(List<T> *list) { base_list::disjoin(list); }
398
inline void prepand(List<T> *list) { base_list::prepand(list); }
399
void delete_elements(void)
349
typedef List_iterator<T> iterator;
351
friend class List_iterator<T>;
354
List(const List<T> &tmp) : base_list(tmp) {}
355
List(const List<T> &tmp, memory::Root *mem_root) : base_list(tmp, mem_root) {}
356
bool push_back(T *a) { return base_list::push_back(a); }
357
bool push_back(T *a, memory::Root *mem_root) { return base_list::push_back(a, mem_root); }
358
bool push_front(T *a) { return base_list::push_front(a); }
359
T& front() {return *static_cast<T*>(first->info); }
360
T* pop() {return static_cast<T*>(base_list::pop()); }
361
void concat(List<T> *list) { base_list::concat(list); }
362
void disjoin(List<T> *list) { base_list::disjoin(list); }
363
void prepand(List<T> *list) { base_list::prepand(list); }
364
void delete_elements()
401
366
list_node *element,*next;
402
367
for (element=first; element != &end_of_list; element=next)
404
369
next=element->next;
405
370
delete (T*) element->info;
412
template <class T> class List_iterator :public base_list_iterator
415
List_iterator(List<T> &a) : base_list_iterator(a) {}
416
List_iterator() : base_list_iterator() {}
417
inline void init(List<T> &a) { base_list_iterator::init(a); }
418
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
419
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
420
inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
421
inline void rewind(void) { base_list_iterator::rewind(); }
422
inline void remove() { base_list_iterator::remove(); }
423
inline void after(T *a) { base_list_iterator::after(a); }
424
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
428
template <class T> class List_iterator_fast :public base_list_iterator
431
inline T *replace(T *) { return (T*) 0; }
432
inline T *replace(List<T> &) { return (T*) 0; }
433
inline void remove(void) { }
434
inline void after(T *) { }
435
inline T** ref(void) { return (T**) 0; }
438
inline List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
439
inline List_iterator_fast() : base_list_iterator() {}
440
inline void init(List<T> &a) { base_list_iterator::init(a); }
441
inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
442
inline void rewind(void) { base_list_iterator::rewind(); }
443
void sublist(List<T> &list_arg, uint32_t el_arg)
445
base_list_iterator::sublist(list_arg, el_arg);
451
Make a deep copy of each list element.
453
@note A template function and not a template method of class List
454
is employed because of explicit template instantiation:
455
in server code there are explicit instantiations of List<T> and
456
an explicit instantiation of a template requires that any method
457
of the instantiated class used in the template can be resolved.
458
Evidently not all template arguments have clone() method with
461
@return You must query the error state in Session for out-of-memory
462
situation after calling this function.
465
template <typename T>
468
list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
470
/* Make a deep copy of each element */
471
List_iterator<T> it(list);
474
it.replace(el->clone(mem_root));
377
return iterator(*this, &first);
385
void set_size(size_t v)
391
template <class T> class List_iterator : public base_list_iterator
394
List_iterator(List<T>& a, list_node** b) : base_list_iterator(a, b) {};
396
T *operator++(int) { return (T*) base_list_iterator::next(); }
397
T *replace(T *a) { T* old = (T*) current->info; current->info= a; return old; }
398
void replace(List<T> &a) { base_list_iterator::replace(a); }
399
T** ref() { return (T**) ¤t->info; }
403
return *(T*)current->info;
477
407
} /* namespace drizzled */