17
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_SQL_LIST_H
21
#define DRIZZLED_SQL_LIST_H
27
25
#include <algorithm>
28
#include "drizzled/memory/sql_alloc.h"
26
#include <drizzled/memory/sql_alloc.h>
27
#include <drizzled/visibility.h>
33
/** Struct to handle simple linked lists. */
34
typedef struct st_sql_list {
36
34
unsigned char *first;
37
35
unsigned char **next;
39
st_sql_list() {} /* Remove gcc warning */
46
inline void link_in_list(unsigned char *element,unsigned char **next_ptr)
49
void link_in_list(unsigned char *element,unsigned char **next_ptr)
53
inline void save_and_clear(struct st_sql_list *save)
56
void save_and_clear(SQL_LIST *save)
58
inline void push_front(struct st_sql_list *save)
61
void push_front(SQL_LIST *save)
60
63
*save->next= first; /* link current list last */
61
64
first= save->first;
62
65
elements+= save->elements;
64
inline void push_back(struct st_sql_list *save)
67
void push_back(SQL_LIST *save)
106
extern list_node end_of_list;
108
extern DRIZZLED_API list_node end_of_list;
108
110
class base_list :public memory::SqlAlloc
111
113
list_node *first,**last;
116
inline void empty() { elements=0; first= &end_of_list; last=&first;}
117
inline base_list() { empty(); }
117
void clear() { elements=0; first= &end_of_list; last=&first;}
118
base_list() { clear(); }
119
120
This is a shallow copy constructor that implicitly passes the ownership
120
121
from the source list to the new instance. The old instance is not
124
125
relies on this behaviour. This logic is quite tricky: please do not use
125
126
it in any new code.
127
inline base_list(const base_list &tmp) :memory::SqlAlloc()
128
base_list(const base_list &tmp) :memory::SqlAlloc()
129
130
elements= tmp.elements;
130
131
first= tmp.first;
131
132
last= elements ? tmp.last : &first;
133
inline base_list(bool) { }
134
inline bool push_back(void *info)
136
if (((*last)=new list_node(info, &end_of_list)))
138
last= &(*last)->next;
144
inline bool push_back(void *info, memory::Root *mem_root)
146
if (((*last)=new (mem_root) list_node(info, &end_of_list)))
148
last= &(*last)->next;
154
inline bool push_front(void *info)
135
void push_back(void *info)
137
*last = new list_node(info, &end_of_list);
138
last= &(*last)->next;
141
void push_back(void *info, memory::Root& mem)
143
*last = new (mem) list_node(info, &end_of_list);
144
last= &(*last)->next;
147
void push_front(void *info)
156
149
list_node *node=new list_node(info,first);
167
155
void remove(list_node **prev)
222
inline void swap(base_list &rhs)
210
void swap(base_list &rhs)
224
212
std::swap(first, rhs.first);
225
213
std::swap(last, rhs.last);
226
214
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; }
216
bool is_empty() { return first == &end_of_list ; }
234
217
friend class base_list_iterator;
235
friend class error_list;
236
friend class error_list_iterator;
238
219
#ifdef LIST_EXTRA_DEBUG
297
277
list_node **el,**prev,*current;
298
void sublist(base_list &ls, uint32_t elm)
279
void sublist(base_list &ls, uint32_t elm) const
301
282
ls.last= list->last;
302
283
ls.elements= elm;
305
285
base_list_iterator()
306
286
:list(0), el(0), prev(0), current(0)
309
base_list_iterator(base_list &list_par)
312
inline void init(base_list &list_par)
320
inline void *next(void)
325
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;
289
base_list_iterator(base_list &list_par, list_node** el0)
290
:list(&list_par), el(el0), prev(0), current(0)
345
294
void *replace(base_list &new_list)
347
296
void *ret_value=current->info;
350
299
*new_list.last=current->next;
351
300
current->info=new_list.first->info;
352
301
current->next=new_list.first->next;
353
if ((list->last == ¤t->next) && (new_list.elements > 1))
354
list->last= new_list.last;
302
if (list->last == ¤t->next && new_list.elements > 1)
303
list->last= new_list.last;
355
304
list->elements+=new_list.elements-1;
357
306
return ret_value; // return old element
359
inline void remove(void) // Remove current
308
void remove() // Remove current
361
310
list->remove(prev);
368
317
current=current->next;
369
318
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
322
template <class T> class List_iterator;
324
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)
327
typedef List_iterator<T> iterator;
329
friend class List_iterator<T>;
332
List(const List<T> &tmp) : base_list(tmp) {}
333
List(const List<T> &tmp, memory::Root *mem_root) : base_list(tmp, mem_root) {}
334
T& front() {return *static_cast<T*>(first->info); }
335
T* pop() {return static_cast<T*>(base_list::pop()); }
336
void concat(List<T> *list) { base_list::concat(list); }
337
void disjoin(List<T> *list) { base_list::disjoin(list); }
338
void prepand(List<T> *list) { base_list::prepand(list); }
339
void delete_elements()
401
341
list_node *element,*next;
402
342
for (element=first; element != &end_of_list; element=next)
404
344
next=element->next;
405
345
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));
352
return iterator(*this, &first);
360
void set_size(size_t v)
366
template <class T> class List_iterator : public base_list_iterator
369
List_iterator(List<T>& a, list_node** b) : base_list_iterator(a, b) {};
371
T *operator++(int) { prev=el; current= *el; el= ¤t->next; return (T*)current->info; }
372
T *replace(T *a) { T* old = (T*) current->info; current->info= a; return old; }
373
void replace(List<T> &a) { base_list_iterator::replace(a); }
374
T** ref() { return (T**) ¤t->info; }
378
return *(T*)current->info;
383
return (T*)current->info;
477
387
} /* namespace drizzled */
479
#endif /* DRIZZLED_SQL_LIST_H */