00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef VARRAY_HPP_
00034 #define VARRAY_HPP_
00035
00036 #include "detail/helper.hpp"
00037
00038 #include <memory.h>
00039
00040 #include <boost/mpl/if.hpp>
00041 #include <boost/mpl/placeholders.hpp>
00042
00050 template<class item_type, size_t _size = 0, typename size_type = size_t>
00051 class varray {
00052 private:
00053 typedef varray<item_type, _size, size_type> _varray;
00054
00055
00056 class dynamic_array {
00057 private:
00058
00059 typedef struct __array {
00060 size_type size;
00061 item_type arr[];
00062 } __array;
00063 __array *arr;
00064
00065
00066 finline size_t array_size(size_t new_size) const {
00067 return (new_size / (sizeof(item_type) * 8)) + (((new_size
00068 % (sizeof(item_type) * 8)) == 0) ? 0 : 1);
00069 }
00070
00071 public:
00072 finline dynamic_array() {
00073 arr = 0;
00074 }
00075
00076 finline ~dynamic_array() {
00077 if (arr != 0) free(arr);
00078 }
00079
00080
00081 finline size_type size() const {
00082 return (arr == 0) ? 0 : arr->size;
00083 }
00084
00085
00086 finline size_t array_size() const {
00087 return array_size(size());
00088 }
00089
00090
00091 finline void resize(size_type new_size) {
00092 size_t old_arr_size = array_size();
00093 size_t new_arr_size = array_size(new_size);
00094 if (old_arr_size != new_arr_size) {
00095 size_t nbsize = sizeof(__array ) + new_arr_size
00096 * sizeof(item_type);
00097 size_t obsize = sizeof(__array ) + old_arr_size
00098 * sizeof(item_type);
00099 __array *new_array = (__array *) malloc(nbsize);
00100 if (arr != 0) {
00101 size_t csize = std::min(nbsize, obsize);
00102 memcpy(new_array, arr, csize);
00103 if (nbsize > obsize) memset(
00104 ((uint8_t*) new_array) + obsize, 0, nbsize
00105 - obsize);
00106 free(arr);
00107 }
00108 arr = new_array;
00109 }
00110 arr->size = new_size;
00111 }
00112
00113
00114 finline item_type* array() const {
00115 return (item_type*) &arr->arr;
00116 }
00117
00118 finline int get_memory_consumption() const {
00119 return array_size() * sizeof(item_type) + sizeof(__array) +
00120 sizeof(void*);
00121 }
00122 };
00123
00124
00125 class static_array {
00126 private:
00127 static const size_t _array_size = (_size / (sizeof(item_type) * 8))
00128 + (((_size % (sizeof(item_type) * 8)) == 0) ? 0 : 1);
00129 item_type arr[_array_size];
00130
00131 public:
00132
00133 finline size_type size() const {
00134 return _size;
00135 }
00136
00137
00138 finline size_t array_size() const {
00139 return _array_size;
00140 }
00141
00142
00143 finline void resize(size_type new_size) {
00144 }
00145
00146
00147 finline item_type* array() const {
00148 return (item_type*) &arr;
00149 }
00150
00151 finline int get_memory_consumption() const {
00152 return _array_size * sizeof(item_type);
00153 }
00154 };
00155
00156
00157 typename boost::mpl::if_<boost::mpl::bool_<_size == 0>,
00158 dynamic_array, static_array>::type _array;
00159
00160 public:
00161 finline bool is_static() const {
00162 return (_size != 0);
00163 }
00164
00165 finline bool is_dynamic() const {
00166 return !is_static();
00167 }
00168
00169 finline size_type size() const {
00170 return _array.size();
00171 }
00172
00173 finline size_t array_size() const {
00174 return _array.array_size();
00175 }
00176
00177 finline void resize(size_type newSize) {
00178 _array.resize(newSize);
00179 }
00180
00181 finline item_type* array() {
00182 return _array.array();
00183 }
00184
00185 finline const item_type* array_const() const {
00186 return _array.array();
00187 }
00188
00189 finline operator item_type*() {
00190 return _array();
00191 }
00192
00193 finline int get_memory_consumption() const {
00194 return _array.get_memory_consumption();
00195 }
00196
00197 finline item_type& operator[] ( size_type index ) {
00198 return array()[index];
00199 }
00200 };
00201
00202 #endif