mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / mem_root_array.h
blob2dcc475cd7b704e6bd57cdb063fca06b00b88e6b
1 /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17 #ifndef MEM_ROOT_ARRAY_INCLUDED
18 #define MEM_ROOT_ARRAY_INCLUDED
20 #include <my_alloc.h>
22 /**
23 A typesafe replacement for DYNAMIC_ARRAY.
24 We use MEM_ROOT for allocating storage, rather than the C++ heap.
25 The interface is chosen to be similar to std::vector.
27 @remark
28 Unlike DYNAMIC_ARRAY, elements are properly copied
29 (rather than memcpy()d) if the underlying array needs to be expanded.
31 @remark
32 Depending on has_trivial_destructor, we destroy objects which are
33 removed from the array (including when the array object itself is destroyed).
35 @remark
36 Note that MEM_ROOT has no facility for reusing free space,
37 so don't use this if multiple re-expansions are likely to happen.
39 @param Element_type The type of the elements of the container.
40 Elements must be copyable.
41 @param has_trivial_destructor If true, we don't destroy elements.
42 We could have used type traits to determine this.
43 __has_trivial_destructor is supported by some (but not all)
44 compilers we use.
46 template<typename Element_type, bool has_trivial_destructor>
47 class Mem_root_array
49 public:
50 Mem_root_array(MEM_ROOT *root)
51 : m_root(root), m_array(NULL), m_size(0), m_capacity(0)
53 DBUG_ASSERT(m_root != NULL);
56 ~Mem_root_array()
58 clear();
61 Element_type &at(size_t n)
63 DBUG_ASSERT(n < size());
64 return m_array[n];
67 const Element_type &at(size_t n) const
69 DBUG_ASSERT(n < size());
70 return m_array[n];
73 // Returns a pointer to the first element in the array.
74 Element_type *begin() { return &m_array[0]; }
76 // Returns a pointer to the past-the-end element in the array.
77 Element_type *end() { return &m_array[size()]; }
79 // Erases all of the elements.
80 void clear()
82 if (!empty())
83 chop(0);
87 Chops the tail off the array, erasing all tail elements.
88 @param pos Index of first element to erase.
90 void chop(const size_t pos)
92 DBUG_ASSERT(pos < m_size);
93 if (!has_trivial_destructor)
95 for (size_t ix= pos; ix < m_size; ++ix)
97 Element_type *p= &m_array[ix];
98 p->~Element_type(); // Destroy discarded element.
101 m_size= pos;
105 Reserves space for array elements.
106 Copies over existing elements, in case we are re-expanding the array.
108 @param n number of elements.
109 @retval true if out-of-memory, false otherwise.
111 bool reserve(size_t n)
113 if (n <= m_capacity)
114 return false;
116 void *mem= alloc_root(m_root, n * element_size());
117 if (!mem)
118 return true;
119 Element_type *array= static_cast<Element_type*>(mem);
121 // Copy all the existing elements into the new array.
122 for (size_t ix= 0; ix < m_size; ++ix)
124 Element_type *new_p= &array[ix];
125 Element_type *old_p= &m_array[ix];
126 new (new_p) Element_type(*old_p); // Copy into new location.
127 if (!has_trivial_destructor)
128 old_p->~Element_type(); // Destroy the old element.
131 // Forget the old array.
132 m_array= array;
133 m_capacity= n;
134 return false;
138 Adds a new element at the end of the array, after its current last
139 element. The content of this new element is initialized to a copy of
140 the input argument.
142 @param element Object to copy.
143 @retval true if out-of-memory, false otherwise.
145 bool push_back(const Element_type &element)
147 const size_t min_capacity= 20;
148 const size_t expansion_factor= 2;
149 if (0 == m_capacity && reserve(min_capacity))
150 return true;
151 if (m_size == m_capacity && reserve(m_capacity * expansion_factor))
152 return true;
153 Element_type *p= &m_array[m_size++];
154 new (p) Element_type(element);
155 return false;
158 size_t capacity() const { return m_capacity; }
159 size_t element_size() const { return sizeof(Element_type); }
160 bool empty() const { return size() == 0; }
161 size_t size() const { return m_size; }
163 private:
164 MEM_ROOT *const m_root;
165 Element_type *m_array;
166 size_t m_size;
167 size_t m_capacity;
169 // Not (yet) implemented.
170 Mem_root_array(const Mem_root_array&);
171 Mem_root_array &operator=(const Mem_root_array&);
175 #endif // MEM_ROOT_ARRAY_INCLUDED