1 #ifndef SQL_ARRAY_INCLUDED 2 #define SQL_ARRAY_INCLUDED 3 4 /* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License, version 2.0, 8 as published by the Free Software Foundation. 9 10 This program is also distributed with certain software (including 11 but not limited to OpenSSL) that is licensed under separate terms, 12 as designated in a particular file or component or in included license 13 documentation. The authors of MySQL hereby grant you an additional 14 permission to link the program and your derivative works with the 15 separately licensed software that they have included with MySQL. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License, version 2.0, for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software Foundation, 24 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 25 26 #include <my_sys.h> 27 28 /** 29 A wrapper class which provides array bounds checking. 30 We do *not* own the array, we simply have a pointer to the first element, 31 and a length. 32 33 @remark 34 We want the compiler-generated versions of: 35 - the copy CTOR (memberwise initialization) 36 - the assignment operator (memberwise assignment) 37 38 @param Element_type The type of the elements of the container. 39 */ 40 template <typename Element_type> class Bounds_checked_array 41 { 42 public: Bounds_checked_array()43 Bounds_checked_array() : m_array(NULL), m_size(0) {} 44 Bounds_checked_array(Element_type * el,size_t size)45 Bounds_checked_array(Element_type *el, size_t size) 46 : m_array(el), m_size(size) 47 {} 48 reset()49 void reset() { m_array= NULL; m_size= 0; } 50 reset(Element_type * array,size_t size)51 void reset(Element_type *array, size_t size) 52 { 53 m_array= array; 54 m_size= size; 55 } 56 57 /** 58 Set a new bound on the array. Does not resize the underlying 59 array, so the new size must be smaller than or equal to the 60 current size. 61 */ resize(size_t new_size)62 void resize(size_t new_size) 63 { 64 DBUG_ASSERT(new_size <= m_size); 65 m_size= new_size; 66 } 67 68 Element_type &operator[](size_t n) 69 { 70 DBUG_ASSERT(n < m_size); 71 return m_array[n]; 72 } 73 74 const Element_type &operator[](size_t n) const 75 { 76 DBUG_ASSERT(n < m_size); 77 return m_array[n]; 78 } 79 element_size()80 size_t element_size() const { return sizeof(Element_type); } size()81 size_t size() const { return m_size; } 82 is_null()83 bool is_null() const { return m_array == NULL; } 84 pop_front()85 void pop_front() 86 { 87 DBUG_ASSERT(m_size > 0); 88 m_array+= 1; 89 m_size-= 1; 90 } 91 array()92 Element_type *array() const { return m_array; } 93 94 bool operator==(const Bounds_checked_array<Element_type>&rhs) const 95 { 96 return m_array == rhs.m_array && m_size == rhs.m_size; 97 } 98 bool operator!=(const Bounds_checked_array<Element_type>&rhs) const 99 { 100 return m_array != rhs.m_array || m_size != rhs.m_size; 101 } 102 103 private: 104 Element_type *m_array; 105 size_t m_size; 106 }; 107 108 /* 109 A typesafe wrapper around DYNAMIC_ARRAY 110 */ 111 112 template <class Elem> class Dynamic_array 113 { 114 DYNAMIC_ARRAY array; 115 public: 116 Dynamic_array(uint prealloc=16, uint increment=16) 117 { 118 init(prealloc, increment); 119 } 120 121 void init(uint prealloc=16, uint increment=16) 122 { 123 my_init_dynamic_array(&array, sizeof(Elem), prealloc, increment); 124 } 125 126 /** 127 @note Though formally this could be declared "const" it would be 128 misleading at it returns a non-const pointer to array's data. 129 */ at(int idx)130 Elem& at(int idx) 131 { 132 return *(((Elem*)array.buffer) + idx); 133 } 134 /// Const variant of at(), which cannot change data at(int idx)135 const Elem& at(int idx) const 136 { 137 return *(((Elem*)array.buffer) + idx); 138 } 139 140 /// @returns pointer to first element; undefined behaviour if array is empty front()141 Elem *front() 142 { 143 DBUG_ASSERT(array.elements >= 1); 144 return (Elem*)array.buffer; 145 } 146 147 /// @returns pointer to first element; undefined behaviour if array is empty front()148 const Elem *front() const 149 { 150 DBUG_ASSERT(array.elements >= 1); 151 return (const Elem*)array.buffer; 152 } 153 154 /// @returns pointer to last element; undefined behaviour if array is empty. back()155 Elem *back() 156 { 157 DBUG_ASSERT(array.elements >= 1); 158 return ((Elem*)array.buffer) + (array.elements - 1); 159 } 160 161 /// @returns pointer to last element; undefined behaviour if array is empty. back()162 const Elem *back() const 163 { 164 DBUG_ASSERT(array.elements >= 1); 165 return ((const Elem*)array.buffer) + (array.elements - 1); 166 } 167 168 /** 169 @retval false ok 170 @retval true OOM, @c my_error() has been called. 171 */ append(const Elem & el)172 bool append(const Elem &el) 173 { 174 return insert_dynamic(&array, &el); 175 } 176 177 /// Pops the last element. Does nothing if array is empty. pop()178 Elem& pop() 179 { 180 return *((Elem*)pop_dynamic(&array)); 181 } 182 del(uint idx)183 void del(uint idx) 184 { 185 delete_dynamic_element(&array, idx); 186 } 187 elements()188 int elements() const 189 { 190 return array.elements; 191 } 192 elements(uint num_elements)193 void elements(uint num_elements) 194 { 195 DBUG_ASSERT(num_elements <= array.max_element); 196 array.elements= num_elements; 197 } 198 clear()199 void clear() 200 { 201 elements(0); 202 } 203 set(uint idx,const Elem & el)204 void set(uint idx, const Elem &el) 205 { 206 set_dynamic(&array, &el, idx); 207 } 208 ~Dynamic_array()209 ~Dynamic_array() 210 { 211 delete_dynamic(&array); 212 } 213 214 typedef int (*CMP_FUNC)(const Elem *el1, const Elem *el2); 215 sort(CMP_FUNC cmp_func)216 void sort(CMP_FUNC cmp_func) 217 { 218 my_qsort(array.buffer, array.elements, sizeof(Elem), (qsort_cmp)cmp_func); 219 } 220 }; 221 222 #endif /* SQL_ARRAY_INCLUDED */ 223