diff options
author | unknown <kostja@bodhi.local> | 2007-01-15 13:10:07 +0300 |
---|---|---|
committer | unknown <kostja@bodhi.local> | 2007-01-15 13:10:07 +0300 |
commit | 408d7752495684425a96c32feaedb4cd865a826a (patch) | |
tree | 267e52364d28d1d17e8c9dd45c15c9917ce3be95 /sql/sql_list.h | |
parent | 31e01f0a74dd4988ab0628ff0d1b832a190340fe (diff) | |
parent | a8103a89b4ad39031abd1db242beca1b4332c895 (diff) | |
download | mariadb-git-408d7752495684425a96c32feaedb4cd865a826a.tar.gz |
Manual merge.
mysql-test/r/sp.result:
Auto merged
mysql-test/t/sp.test:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_list.h:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
Diffstat (limited to 'sql/sql_list.h')
-rw-r--r-- | sql/sql_list.h | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/sql/sql_list.h b/sql/sql_list.h index 1f2d7841f8a..d00a4598af5 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -61,21 +61,24 @@ public: pointer. */ -class list_node :public Sql_alloc + +/** + list_node - a node of a single-linked list. + @note We never call a destructor for instances of this class. +*/ + +struct list_node :public Sql_alloc { -public: list_node *next; void *info; list_node(void *info_par,list_node *next_par) :next(next_par),info(info_par) - {} + {} list_node() /* For end_of_list */ - { - info=0; - next= this; - } - friend class base_list; - friend class base_list_iterator; + { + info= 0; + next= this; + } }; @@ -91,12 +94,57 @@ public: inline void empty() { elements=0; first= &end_of_list; last=&first;} inline base_list() { empty(); } + /** + This is a shallow copy constructor that implicitly passes the ownership + from the source list to the new instance. The old instance is not + updated, so both objects end up sharing the same nodes. If one of + the instances then adds or removes a node, the other becomes out of + sync ('last' pointer), while still operational. Some old code uses and + relies on this behaviour. This logic is quite tricky: please do not use + it in any new code. + */ inline base_list(const base_list &tmp) :Sql_alloc() { elements= tmp.elements; first= tmp.first; last= elements ? tmp.last : &first; } + /** + Construct a deep copy of the argument in memory root mem_root. + The elements themselves are copied by pointer. + */ + inline base_list(const base_list &rhs, MEM_ROOT *mem_root) + { + if (rhs.elements) + { + /* + It's okay to allocate an array of nodes at once: we never + call a destructor for list_node objects anyway. + */ + first= (list_node*) alloc_root(mem_root, + sizeof(list_node) * rhs.elements); + if (first) + { + elements= rhs.elements; + list_node *dst= first; + list_node *src= rhs.first; + for (; dst < first + elements - 1; dst++, src= src->next) + { + dst->info= src->info; + dst->next= dst + 1; + } + /* Copy the last node */ + dst->info= src->info; + dst->next= &end_of_list; + /* Setup 'last' member */ + last= &dst->next; + return; + } + } + elements= 0; + first= &end_of_list; + last= &first; + } inline base_list(bool error) { } inline bool push_back(void *info) { @@ -347,6 +395,8 @@ template <class T> class List :public base_list public: inline List() :base_list() {} inline List(const List<T> &tmp) :base_list(tmp) {} + inline List(const List<T> &tmp, MEM_ROOT *mem_root) : + base_list(tmp, mem_root) {} inline bool push_back(T *a) { return base_list::push_back(a); } inline bool push_back(T *a, MEM_ROOT *mem_root) { return base_list::push_back(a, mem_root); } |