My Project
mem_root_array.h
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines