~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_list.h

  • Committer: Brian Aker
  • Date: 2011-02-24 19:58:57 UTC
  • mfrom: (2183.2.25 list2)
  • mto: This revision was merged to the branch mainline in revision 2199.
  • Revision ID: brian@tangent.org-20110224195857-24p1kalw92bmco2n
More list

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
  unsigned char *first;
36
36
  unsigned char **next;
37
37
 
38
 
  inline void clear()
 
38
  void clear()
39
39
  {
40
40
    elements=0;
41
41
    first=0;
47
47
    return elements;
48
48
  }
49
49
 
50
 
  inline void link_in_list(unsigned char *element,unsigned char **next_ptr)
 
50
  void link_in_list(unsigned char *element,unsigned char **next_ptr)
51
51
  {
52
52
    elements++;
53
53
    (*next)=element;
54
54
    next= next_ptr;
55
55
    *next=0;
56
56
  }
57
 
  inline void save_and_clear(struct st_sql_list *save)
 
57
  void save_and_clear(struct st_sql_list *save)
58
58
  {
59
59
    *save= *this;
60
60
    clear();
61
61
  }
62
 
  inline void push_front(struct st_sql_list *save)
 
62
  void push_front(struct st_sql_list *save)
63
63
  {
64
64
    *save->next= first;                         /* link current list last */
65
65
    first= save->first;
66
66
    elements+= save->elements;
67
67
  }
68
 
  inline void push_back(struct st_sql_list *save)
 
68
  void push_back(struct st_sql_list *save)
69
69
  {
70
70
    if (save->first)
71
71
    {
115
115
  uint32_t elements;
116
116
public:
117
117
 
118
 
  inline void clear() { elements=0; first= &end_of_list; last=&first;}
119
 
  inline base_list() { clear(); }
 
118
  void clear() { elements=0; first= &end_of_list; last=&first;}
 
119
  base_list() { clear(); }
120
120
  /**
121
121
    This is a shallow copy constructor that implicitly passes the ownership
122
122
    from the source list to the new instance. The old instance is not
126
126
    relies on this behaviour. This logic is quite tricky: please do not use
127
127
    it in any new code.
128
128
  */
129
 
  inline base_list(const base_list &tmp) :memory::SqlAlloc()
 
129
  base_list(const base_list &tmp) :memory::SqlAlloc()
130
130
  {
131
131
    elements= tmp.elements;
132
132
    first= tmp.first;
133
133
    last= elements ? tmp.last : &first;
134
134
  }
135
 
  inline base_list(bool) { }
136
 
  inline bool push_back(void *info)
 
135
  base_list(bool) { }
 
136
  bool push_back(void *info)
137
137
  {
138
138
    if (((*last)=new list_node(info, &end_of_list)))
139
139
    {
143
143
    }
144
144
    return 1;
145
145
  }
146
 
  inline bool push_back(void *info, memory::Root *mem_root)
 
146
  bool push_back(void *info, memory::Root *mem_root)
147
147
  {
148
148
    if (((*last)=new (mem_root) list_node(info, &end_of_list)))
149
149
    {
153
153
    }
154
154
    return 1;
155
155
  }
156
 
  inline bool push_front(void *info)
 
156
  bool push_front(void *info)
157
157
  {
158
158
    list_node *node=new list_node(info,first);
159
159
    if (node)
176
176
    delete *prev;
177
177
    *prev=node;
178
178
  }
179
 
  inline void concat(base_list *list)
 
179
  void concat(base_list *list)
180
180
  {
181
181
    if (!list->is_empty())
182
182
    {
185
185
      elements+= list->elements;
186
186
    }
187
187
  }
188
 
  inline void *pop(void)
 
188
  void *pop()
189
189
  {
190
190
    if (first == &end_of_list) return 0;
191
191
    list_node *tmp=first;
194
194
      last= &first;
195
195
    return tmp->info;
196
196
  }
197
 
  inline void disjoin(base_list *list)
 
197
  void disjoin(base_list *list)
198
198
  {
199
199
    list_node **prev= &first;
200
200
    list_node *node= first;
209
209
    *prev= *last;
210
210
    last= prev;
211
211
  }
212
 
  inline void prepand(base_list *list)
 
212
  void prepand(base_list *list)
213
213
  {
214
214
    if (!list->is_empty())
215
215
    {
221
221
  /**
222
222
    Swap two lists.
223
223
  */
224
 
  inline void swap(base_list &rhs)
 
224
  void swap(base_list &rhs)
225
225
  {
226
226
    std::swap(first, rhs.first);
227
227
    std::swap(last, rhs.last);
228
228
    std::swap(elements, rhs.elements);
229
229
  }
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; }
 
230
  bool is_empty() { return first == &end_of_list ; }
236
231
  friend class base_list_iterator;
237
232
 
238
233
#ifdef LIST_EXTRA_DEBUG
311
306
  {
312
307
  }
313
308
 
314
 
  inline void *next(void)
 
309
  void *next()
315
310
  {
316
311
    prev=el;
317
312
    current= *el;
318
313
    el= &current->next;
319
314
    return current->info;
320
315
  }
321
 
  inline void *replace(void *element)
322
 
  {                                             // Return old element
323
 
    void *tmp=current->info;
324
 
    assert(current->info != 0);
325
 
    current->info=element;
326
 
    return tmp;
327
 
  }
328
316
  void *replace(base_list &new_list)
329
317
  {
330
318
    void *ret_value=current->info;
333
321
      *new_list.last=current->next;
334
322
      current->info=new_list.first->info;
335
323
      current->next=new_list.first->next;
336
 
      if ((list->last == &current->next) && (new_list.elements > 1))
337
 
        list->last= new_list.last;
 
324
      if (list->last == &current->next && new_list.elements > 1)
 
325
        list->last= new_list.last;
338
326
      list->elements+=new_list.elements-1;
339
327
    }
340
328
    return ret_value;                           // return old element
341
329
  }
342
 
  inline void remove(void)                      // Remove current
 
330
  void remove()                 // Remove current
343
331
  {
344
332
    list->remove(prev);
345
333
    el=prev;
351
339
    current=current->next;
352
340
    el= &current->next;
353
341
  }
354
 
  inline void **ref(void)                       // Get reference pointer
355
 
  {
356
 
    return &current->info;
357
 
  }
358
 
  inline bool is_last(void)
359
 
  {
360
 
    return el == &list->last_ref()->next;
361
 
  }
362
342
};
363
343
 
364
344
template <class T> class List_iterator;
365
345
 
366
 
template <class T> class List :public base_list
 
346
template <class T> class List : public base_list
367
347
{
368
348
public:
369
349
  typedef List_iterator<T> iterator;
370
350
 
371
351
  friend class List_iterator<T>;
372
352
 
373
 
  inline List() :base_list() {}
374
 
  inline List(const List<T> &tmp) :base_list(tmp) {}
375
 
  inline List(const List<T> &tmp, memory::Root *mem_root) :
376
 
    base_list(tmp, mem_root) {}
377
 
  inline bool push_back(T *a) { return base_list::push_back(a); }
378
 
  inline bool push_back(T *a, memory::Root *mem_root)
379
 
  { return base_list::push_back(a, mem_root); }
380
 
  inline bool push_front(T *a) { return base_list::push_front(a); }
381
 
  inline T* head() {return static_cast<T*>(base_list::head()); }
382
 
  inline T* pop()  {return static_cast<T*>(base_list::pop()); }
383
 
  inline void concat(List<T> *list) { base_list::concat(list); }
384
 
  inline void disjoin(List<T> *list) { base_list::disjoin(list); }
385
 
  inline void prepand(List<T> *list) { base_list::prepand(list); }
386
 
  void delete_elements(void)
 
353
  List() {}
 
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()
387
365
  {
388
366
    list_node *element,*next;
389
367
    for (element=first; element != &end_of_list; element=next)
410
388
  }
411
389
};
412
390
 
413
 
 
414
 
template <class T> class List_iterator :public base_list_iterator
 
391
template <class T> class List_iterator : public base_list_iterator
415
392
{
416
393
public:
417
394
  List_iterator(List<T>& a, list_node** b) : base_list_iterator(a, b) {};
418
395
  List_iterator() {};
419
 
  inline T *operator++(int) { return (T*) base_list_iterator::next(); }
420
 
  inline T *replace(T *a)   { return (T*) base_list_iterator::replace(a); }
421
 
  inline T *replace(List<T> &a) { return (T*) base_list_iterator::replace(a); }
422
 
  inline T** ref(void)      { return (T**) base_list_iterator::ref(); }
 
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**) &current->info; }
 
400
 
 
401
  T& operator*()
 
402
  {
 
403
    return *(T*)current->info;
 
404
  }
423
405
};
424
406
 
425
 
/**
426
 
  Make a deep copy of each list element.
427
 
 
428
 
  @note A template function and not a template method of class List
429
 
  is employed because of explicit template instantiation:
430
 
  in server code there are explicit instantiations of List<T> and
431
 
  an explicit instantiation of a template requires that any method
432
 
  of the instantiated class used in the template can be resolved.
433
 
  Evidently not all template arguments have clone() method with
434
 
  the right signature.
435
 
 
436
 
  @return You must query the error state in Session for out-of-memory
437
 
  situation after calling this function.
438
 
*/
439
 
 
440
 
template <typename T>
441
 
void list_copy_and_replace_each_value(List<T> &list, memory::Root *mem_root)
442
 
{
443
 
  /* Make a deep copy of each element */
444
 
  typename List<T>::iterator it(list.begin());
445
 
  T *el;
446
 
  while ((el= it++))
447
 
    it.replace(el->clone(mem_root));
448
 
}
449
 
 
450
407
} /* namespace drizzled */
451
408
 
452
409
#endif /* DRIZZLED_SQL_LIST_H */