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
25
27
#include <algorithm>
26
#include <drizzled/memory/sql_alloc.h>
27
#include <drizzled/visibility.h>
31
typedef struct st_sql_list
28
#include "drizzled/memory/sql_alloc.h"
29
#include "drizzled/visibility.h"
35
/** Struct to handle simple linked lists. */
36
typedef struct st_sql_list {
34
38
unsigned char *first;
35
39
unsigned char **next;
41
st_sql_list() {} /* Remove gcc warning */
49
void link_in_list(unsigned char *element,unsigned char **next_ptr)
48
inline void link_in_list(unsigned char *element,unsigned char **next_ptr)
56
void save_and_clear(struct st_sql_list *save)
55
inline void save_and_clear(struct st_sql_list *save)
61
void push_front(struct st_sql_list *save)
60
inline void push_front(struct st_sql_list *save)
63
62
*save->next= first; /* link current list last */
64
63
first= save->first;
65
64
elements+= save->elements;
67
void push_back(struct st_sql_list *save)
66
inline void push_back(struct st_sql_list *save)
125
126
relies on this behaviour. This logic is quite tricky: please do not use
126
127
it in any new code.
128
base_list(const base_list &tmp) :memory::SqlAlloc()
129
inline base_list(const base_list &tmp) :memory::SqlAlloc()
130
131
elements= tmp.elements;
131
132
first= tmp.first;
132
133
last= elements ? tmp.last : &first;
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_root)
143
*last = new (mem_root) list_node(info, &end_of_list);
144
last= &(*last)->next;
147
void push_front(void *info)
135
inline base_list(bool) { }
136
inline bool push_back(void *info)
138
if (((*last)=new list_node(info, &end_of_list)))
140
last= &(*last)->next;
146
inline bool push_back(void *info, memory::Root *mem_root)
148
if (((*last)=new (mem_root) list_node(info, &end_of_list)))
150
last= &(*last)->next;
156
inline bool push_front(void *info)
149
158
list_node *node=new list_node(info,first);
155
169
void remove(list_node **prev)
210
void swap(base_list &rhs)
224
inline void swap(base_list &rhs)
212
226
std::swap(first, rhs.first);
213
227
std::swap(last, rhs.last);
214
228
std::swap(elements, rhs.elements);
216
bool is_empty() { return first == &end_of_list ; }
230
inline list_node* last_node() { return *last; }
231
inline list_node* first_node() { return first;}
232
inline void *head() { return first->info; }
233
inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
234
inline bool is_empty() { return first == &end_of_list ; }
235
inline list_node *last_ref() { return &end_of_list; }
217
236
friend class base_list_iterator;
237
friend class error_list;
238
friend class error_list_iterator;
219
240
#ifdef LIST_EXTRA_DEBUG
278
299
list_node **el,**prev,*current;
280
300
void sublist(base_list &ls, uint32_t elm)
283
303
ls.last= list->last;
284
304
ls.elements= elm;
286
307
base_list_iterator()
287
308
:list(0), el(0), prev(0), current(0)
290
base_list_iterator(base_list &list_par, list_node** el0)
291
:list(&list_par), el(el0), prev(0), current(0)
311
base_list_iterator(base_list &list_par)
314
inline void init(base_list &list_par)
322
inline void *next(void)
327
return current->info;
329
inline void *next_fast(void)
336
inline void rewind(void)
340
inline void *replace(void *element)
341
{ // Return old element
342
void *tmp=current->info;
343
assert(current->info != 0);
344
current->info=element;
295
347
void *replace(base_list &new_list)
297
349
void *ret_value=current->info;
300
352
*new_list.last=current->next;
301
353
current->info=new_list.first->info;
302
354
current->next=new_list.first->next;
303
if (list->last == ¤t->next && new_list.elements > 1)
304
list->last= new_list.last;
355
if ((list->last == ¤t->next) && (new_list.elements > 1))
356
list->last= new_list.last;
305
357
list->elements+=new_list.elements-1;
307
359
return ret_value; // return old element
309
void remove() // Remove current
361
inline void remove(void) // Remove current
311
363
list->remove(prev);
318
370
current=current->next;
319
371
el= ¤t->next;
373
inline void **ref(void) // Get reference pointer
375
return ¤t->info;
377
inline bool is_last(void)
379
return el == &list->last_ref()->next;
381
friend class error_list_iterator;
323
template <class T> class List_iterator;
325
template <class T> class List : public base_list
384
template <class T> class List :public base_list
328
typedef List_iterator<T> iterator;
330
friend class List_iterator<T>;
333
List(const List<T> &tmp) : base_list(tmp) {}
334
List(const List<T> &tmp, memory::Root *mem_root) : base_list(tmp, mem_root) {}
335
void push_back(T *a) { base_list::push_back(a); }
336
void push_back(T *a, memory::Root *mem_root) { base_list::push_back(a, mem_root); }
337
void push_front(T *a) { base_list::push_front(a); }
338
T& front() {return *static_cast<T*>(first->info); }
339
T* pop() {return static_cast<T*>(base_list::pop()); }
340
void concat(List<T> *list) { base_list::concat(list); }
341
void disjoin(List<T> *list) { base_list::disjoin(list); }
342
void prepand(List<T> *list) { base_list::prepand(list); }
343
void delete_elements()
387
inline List() :base_list() {}
388
inline List(const List<T> &tmp) :base_list(tmp) {}
389
inline List(const List<T> &tmp, memory::Root *mem_root) :
390
base_list(tmp, mem_root) {}
391
inline bool push_back(T *a) { return base_list::push_back(a); }
392
inline bool push_back(T *a, memory::Root *mem_root)
393
{ return base_list::push_back(a, mem_root); }
394
inline bool push_front(T *a) { return base_list::push_front(a); }
395
inline T* head() {return (T*) base_list::head(); }
396
inline T** head_ref() {return (T**) base_list::head_ref(); }
397
inline T* pop() {return (T*) base_list::pop(); }
398
inline void concat(List<T> *list) { base_list::concat(list); }
399
inline void disjoin(List<T> *list) { base_list::disjoin(list); }
400
inline void prepand(List<T> *list) { base_list::prepand(list); }
401
void delete_elements(void)
345
403
list_node *element,*next;
346
404
for (element=first; element != &end_of_list; element=next)
348
406
next=element->next;
349
407
delete (T*) element->info;
356
return iterator(*this, &first);
364
void set_size(size_t v)
370
template <class T> class List_iterator : public base_list_iterator
373
List_iterator(List<T>& a, list_node** b) : base_list_iterator(a, b) {};
375
T *operator++(int) { prev=el; current= *el; el= ¤t->next; return (T*)current->info; }
376
T *replace(T *a) { T* old = (T*) current->info; current->info= a; return old; }
377
void replace(List<T> &a) { base_list_iterator::replace(a); }
378
T** ref() { return (T**) ¤t->info; }
382
return *(T*)current->info;
387
return (T*)current->info;
414
template <class T> class List_iterator :public base_list_iterator
417
List_iterator(List<T> &a) : base_list_iterator(a) {}
418
List_iterator() : base_list_iterator() {}
419
inline void init(List<T> &a) { base_list_iterator::init(a); }
420
inline T* operator++(int) { return (T*) base_list_iterator::next(); }
421
inline T *replace(T *a) { return (T*) base_list_iterator::replace(a); }
422
inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
423
inline void rewind(void) { base_list_iterator::rewind(); }
424
inline void remove() { base_list_iterator::remove(); }
425
inline void after(T *a) { base_list_iterator::after(a); }
426
inline T** ref(void) { return (T**) base_list_iterator::ref(); }
430
template <class T> class List_iterator_fast :public base_list_iterator
433
inline T *replace(T *) { return (T*) 0; }
434
inline T *replace(List<T> &) { return (T*) 0; }
435
inline void remove(void) { }
436
inline void after(T *) { }
437
inline T** ref(void) { return (T**) 0; }
440
inline List_iterator_fast(List<T> &a) : base_list_iterator(a) {}
441
inline List_iterator_fast() : base_list_iterator() {}
442
inline void init(List<T> &a) { base_list_iterator::init(a); }
443
inline T* operator++(int) { return (T*) base_list_iterator::next_fast(); }
444
inline void rewind(void) { base_list_iterator::rewind(); }
445
void sublist(List<T> &list_arg, uint32_t el_arg)
447
base_list_iterator::sublist(list_arg, el_arg);
453
Make a deep copy of each list element.
455
@note A template function and not a template method of class List
456
is employed because of explicit template instantiation:
457
in server code there are explicit instantiations of List<T> and
458
an explicit instantiation of a template requires that any method
459
of the instantiated class used in the template can be resolved.
460
Evidently not all template arguments have clone() method with
463
@return You must query the error state in Session for out-of-memory
464
situation after calling this function.
467
template <typename T>
470
list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
472
/* Make a deep copy of each element */
473
List_iterator<T> it(list);
476
it.replace(el->clone(mem_root));
391
479
} /* namespace drizzled */
481
#endif /* DRIZZLED_SQL_LIST_H */