My Project
|
00001 /* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software 00014 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ 00015 00016 00017 #ifndef MEM_ROOT_ARRAY_INCLUDED 00018 #define MEM_ROOT_ARRAY_INCLUDED 00019 00020 #include <my_alloc.h> 00021 00046 template<typename Element_type, bool has_trivial_destructor> 00047 class Mem_root_array 00048 { 00049 public: 00050 Mem_root_array(MEM_ROOT *root) 00051 : m_root(root), m_array(NULL), m_size(0), m_capacity(0) 00052 { 00053 DBUG_ASSERT(m_root != NULL); 00054 } 00055 00056 ~Mem_root_array() 00057 { 00058 clear(); 00059 } 00060 00061 Element_type &at(size_t n) 00062 { 00063 DBUG_ASSERT(n < size()); 00064 return m_array[n]; 00065 } 00066 00067 const Element_type &at(size_t n) const 00068 { 00069 DBUG_ASSERT(n < size()); 00070 return m_array[n]; 00071 } 00072 00073 // Returns a pointer to the first element in the array. 00074 Element_type *begin() { return &m_array[0]; } 00075 00076 // Returns a pointer to the past-the-end element in the array. 00077 Element_type *end() { return &m_array[size()]; } 00078 00079 // Erases all of the elements. 00080 void clear() 00081 { 00082 if (!empty()) 00083 chop(0); 00084 } 00085 00086 /* 00087 Chops the tail off the array, erasing all tail elements. 00088 @param pos Index of first element to erase. 00089 */ 00090 void chop(const size_t pos) 00091 { 00092 DBUG_ASSERT(pos < m_size); 00093 if (!has_trivial_destructor) 00094 { 00095 for (size_t ix= pos; ix < m_size; ++ix) 00096 { 00097 Element_type *p= &m_array[ix]; 00098 p->~Element_type(); // Destroy discarded element. 00099 } 00100 } 00101 m_size= pos; 00102 } 00103 00104 /* 00105 Reserves space for array elements. 00106 Copies over existing elements, in case we are re-expanding the array. 00107 00108 @param n number of elements. 00109 @retval true if out-of-memory, false otherwise. 00110 */ 00111 bool reserve(size_t n) 00112 { 00113 if (n <= m_capacity) 00114 return false; 00115 00116 void *mem= alloc_root(m_root, n * element_size()); 00117 if (!mem) 00118 return true; 00119 Element_type *array= static_cast<Element_type*>(mem); 00120 00121 // Copy all the existing elements into the new array. 00122 for (size_t ix= 0; ix < m_size; ++ix) 00123 { 00124 Element_type *new_p= &array[ix]; 00125 Element_type *old_p= &m_array[ix]; 00126 new (new_p) Element_type(*old_p); // Copy into new location. 00127 if (!has_trivial_destructor) 00128 old_p->~Element_type(); // Destroy the old element. 00129 } 00130 00131 // Forget the old array. 00132 m_array= array; 00133 m_capacity= n; 00134 return false; 00135 } 00136 00137 /* 00138 Adds a new element at the end of the array, after its current last 00139 element. The content of this new element is initialized to a copy of 00140 the input argument. 00141 00142 @param element Object to copy. 00143 @retval true if out-of-memory, false otherwise. 00144 */ 00145 bool push_back(const Element_type &element) 00146 { 00147 const size_t min_capacity= 20; 00148 const size_t expansion_factor= 2; 00149 if (0 == m_capacity && reserve(min_capacity)) 00150 return true; 00151 if (m_size == m_capacity && reserve(m_capacity * expansion_factor)) 00152 return true; 00153 Element_type *p= &m_array[m_size++]; 00154 new (p) Element_type(element); 00155 return false; 00156 } 00157 00158 size_t capacity() const { return m_capacity; } 00159 size_t element_size() const { return sizeof(Element_type); } 00160 bool empty() const { return size() == 0; } 00161 size_t size() const { return m_size; } 00162 00163 private: 00164 MEM_ROOT *const m_root; 00165 Element_type *m_array; 00166 size_t m_size; 00167 size_t m_capacity; 00168 00169 // Not (yet) implemented. 00170 Mem_root_array(const Mem_root_array&); 00171 Mem_root_array &operator=(const Mem_root_array&); 00172 }; 00173 00174 00175 #endif // MEM_ROOT_ARRAY_INCLUDED