Changeset 131
- Timestamp:
- 06/24/13 21:31:15 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/array2d.hh
r130 r131 11 11 */ 12 12 13 // TODO: implement copy on resize! See image::set_region14 // TODO: implement set sub_array or something like that15 13 // TODO: make it work with the stl allocator 16 14 … … 37 35 typedef const_pointer const_iterator; 38 36 37 /** 38 *Creates a new 2D array. 39 */ 39 40 array2d() : m_size(), m_data( nullptr ) {} 41 42 /** 43 *Creates a new 2D array. 44 * 45 *@param asize The dimensions of the new array. 46 */ 40 47 array2d( const ivec2& asize ) : m_size(), m_data( nullptr ) { resize( asize ); } 48 49 /** 50 *Creates a new 2D array. 51 * 52 *@param asize_x The width of the new array. 53 *@param asize_y The height of the new array. 54 */ 55 array2d( const sint32 asize_x, const sint32 asize_y ) : m_size(), m_data( nullptr ) { resize( new ivec2( asize_x, asize_y ) ); } 41 56 57 /** 58 *Gets the dimensions of the array. 59 * 60 *@returns The size of the array. 61 */ 42 62 const ivec2& size() const { return m_size; } 63 64 /** 65 *Gets a pointer to the data in the array. 66 * 67 *@returns A pointer to the data in the array. 68 */ 43 69 pointer data() { return m_data; } 70 71 /** 72 *Gets a constant pointer to the data in the array. 73 * 74 *@returns A constant pointer to the data in the array. 75 */ 44 76 const_pointer data() const { return m_data; } 45 77 46 void resize( const ivec2& new_size ) 47 { 78 /** 79 *Changes the dimensions of the array. 80 * 81 *@param new_size The new dimensions of the array. 82 *@param preserve True to keep as much of the existing data as will fit in the new array, False to discard the existing data. 83 */ 84 void resize( const ivec2& new_size, bool preserve = false ) 85 { 86 if (new_size == m_size) return; // Don't do anything if the sizes are the same. 87 48 88 pointer new_data = new value_type[ new_size.x * new_size.y ]; 49 89 if ( m_data != nullptr ) 50 90 { 51 // TODO: implement copy! See image::set_region 52 delete[] m_data; 91 if (!preserve) 92 { 93 // Just delete the data. 94 delete[] m_data; 95 } 96 else 97 { 98 // Copy the data. Truncates the bottom or right side of the data if destination is smaller. 99 for ( sint32 i = 0; i < min(new_size.y, m_size.y); i++ ) 100 { 101 std::copy( m_data + m_size.x * i, m_data + m_size.x * i + min( new_size.x, m_size.x ), new_data + m_size.x * i ); 102 } 103 // ...then delete the original data. 104 delete[] m_data; 105 } 53 106 } 54 107 m_data = new_data; … … 56 109 } 57 110 111 /** 112 *Gets a pointer to the start of the array. 113 * 114 *@returns A pointer to the first position in the array. 115 */ 58 116 iterator begin() { return m_data; } 117 118 /** 119 *Gets a constant pointer to the start of the array. 120 * 121 *@returns A constant pointer to the first position in the array. 122 */ 59 123 const_iterator begin() const { return m_data; } 124 125 /** 126 *Gets a pointer to the end of the array. 127 * 128 *@returns A pointer to the end of the array. 129 */ 60 130 iterator end() { return m_data + ( m_size.x * m_size.y ); } 131 132 /** 133 *Gets a constant pointer to the end of the array. 134 * 135 *@returns A constant pointer to the end of the array. 136 */ 61 137 const_iterator end() const { return m_data + ( m_size.x * m_size.y ); } 62 138 139 140 /** 141 *Looks up a position by X and Y value. 142 * 143 *@param x The X position of the array to look up. 144 *@param y The Y position of the array to look up. 145 *@returns A reference to the data at the indicated position. 146 */ 63 147 inline const_reference operator() ( sint32 x, sint32 y ) const 64 148 { … … 66 150 return m_data[ y * m_size.x + x ]; 67 151 } 152 153 /** 154 *Looks up a position by X and Y value. 155 * 156 *@param x The X position of the array to look up. 157 *@param y The Y position of the array to look up. 158 *@returns A reference to the data at the indicated position. 159 */ 68 160 inline reference operator() ( sint32 x, sint32 y ) 69 161 { … … 71 163 return m_data[ y * m_size.x + x ]; 72 164 } 165 166 /** 167 *Looks up the given position in the array. 168 * 169 *@param c The position to look up. 170 *@returns A reference to the data at the indicated position. 171 */ 73 172 inline const_reference operator[] ( const ivec2& c ) const 74 173 { … … 76 175 return m_data[ c.y * m_size.x + c.x ]; 77 176 } 177 178 /** 179 *Looks up the given position in the array. 180 * 181 *@param c The position to look up. 182 *@returns A reference to the data at the indicated position. 183 */ 78 184 inline reference operator[] ( const ivec2& c ) 79 185 { … … 82 188 } 83 189 190 /** 191 *Returns a copy of this array in a new instance. 192 * 193 *@returns An independent copy of this array. 194 */ 195 array2d<T> clone() 196 { 197 array2d<T> temp = new array2d<T>(m_size); 198 for ( sint32 i = 0; i < m_size.y; i++ ) 199 { 200 std::copy( m_data + m_size.x * i, m_data + m_size.x * i + m_size.x, m_size.x * i ); 201 } 202 return temp; 203 } 204 205 /** 206 *Returns an array that represents a subset of the data in this array. 207 * 208 *@param start The upper and left bounds of data to retrieve. 209 *@param size The width and height of the data to retrieve. 210 *@returns A new 2D array containing the subset of data within the bounds specified. 211 */ 212 array2d<T> get_sub_array( const ivec2& start, const ivec2& size ) { return get_sub_array( start.x, start.y, size.x, size.y ); } 213 /** 214 *Returns an array that represents a subset of the data in this array. 215 * 216 *@param start_x The left bound of the data to retrieve. 217 *@param start_y The upper bound of the data to retrieve. 218 *@param size_x The width of the data to retrieve. 219 *@param size_y The height of the data to retrieve. 220 *@returns A new 2D array containing the subset of data within the bounds specified. 221 */ 222 array2d<T> get_sub_array( const sint32 start_x, const sint32 start_y, const sint32 size_x, const sint32 size_y) 223 { 224 // Make sure the parameters are correct and in bounds. 225 NV_ASSERT( start_x >= 0 && start_x < m_size.x && start_y >= 0 && start_y < m_size.y, "get_sub_array: start is out of bounds." ); 226 NV_ASSERT( size_x >= 1 && size_x + start_x <= m_size.x && size_y >= 1 && size_y + start_y <= m_size.y, "get_sub_array: size is invalid." ); 227 // Empty holder for the sub array of the correct size. 228 array2d<T> temp = new array2d<T>( size_x, size_y ); 229 for ( sint32 i = start_y; i < start_y + size_y; i++ ) 230 { 231 // Copy starts at start_x. 232 // Copy end is the end position. 233 // Destination is the start of the destination row. 234 // Start End Destination 235 std::copy( m_data + m_size().x * i + start_x, m_data + m_size().x * i + start_x + size_x, temp.m_data + temp.m_size().x * ( i - start_y ) ); 236 } 237 return temp; 238 } 239 240 /** 241 *Fills this array with another array. 242 * 243 *@param source The array to fill with. If it does not fit in the destination it will be truncated. 244 *@param dest_start The upper and left bounds of the data to fill. 245 */ 246 void set_sub_array( const array2d<T> source, const ivec2& dest_start ) 247 { 248 return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, source.m_size.x, source.m_size.y ); 249 } 250 251 /** 252 *Fills this array with a subset of another array. 253 * 254 *@param source The arrya to fill with. If it does not fit in the destination it will be truncated. 255 *@param dest_start The upper and left bounds of the data to fill. 256 *@param size The size of the area to copy over. 257 */ 258 void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& size ) 259 { 260 return set_sub_array( source, dest_start.x, dest_start.y, 0, 0, size.x, size.y ); 261 } 262 263 264 /** 265 *Fills this array with a subset of another array. 266 * 267 *@param source The array to fill with. If it does not fit in the destination it will be truncated. 268 *@param dest_start The upper and left bounds of the data to fill. 269 *@param source_start The upper and left bounds of the source to fill with. 270 *@param size The size of the area to copy over. 271 */ 272 void set_sub_array( const array2d<T> source, const ivec2& dest_start, const ivec2& source_start, const ivec2& size ) 273 { 274 return set_sub_array( source, dest_start.x, dest_start.y, source_start.x, source_start.y, size.x, size.y ); 275 } 276 277 /** 278 *Fills this array with another array. 279 * 280 *@param source The array to fill with. If it does not fit in the area to fill, it will be truncated. 281 *@param dest_start_x The left bound of the data to fill. 282 *@param dest_start_y The upper bound of the data to fill. 283 */ 284 void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y ) 285 { 286 return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, source.m_size.x, source.m_size.y ); 287 } 288 289 /** 290 *Fills this array with another array. 291 * 292 *@param source The array to fill with. If it does not fit in the area to fill, it will be truncated. 293 *@param dest_start_x The left bound of the data to fill. 294 *@param dest_start_y The upper bound of the data to fill. 295 *@param size_x The width of the area to copy over. 296 *@param size_y The height of the area to copy over. 297 */ 298 void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 size_x, const sint32 size_y ) 299 { 300 return set_sub_array( source, dest_start_x, dest_start_y, 0, 0, size_x, size_y ); 301 } 302 303 /** 304 *Fills this array with a subset of another array. 305 * 306 *@param source The array to fill with. If it does not fit in the area to fill, it will be truncated. 307 *@param dest_start_x The left bound of the data to fill. 308 *@param dest_start_y The upper bound of the data to fill. 309 *@param source_start_x The left bound of the source to fill with. 310 *@param source_start_y The upper bound of the source to fill with. 311 *@param size_x The width of the area to copy over. 312 *@param size_y The height of the area to copy over. 313 */ 314 void set_sub_array( const array2d<T> source, const sint32 dest_start_x, const sint32 dest_start_y, const sint32 source_start_x, const sint32 source_start_y, const sint32 size_x, const sint32 size_y ) 315 { 316 // Start by checking the parameters. Make sure nothing is out of bounds. 317 NV_ASSERT( source != nullptr, "set_sub_array: no source defined." ); 318 NV_ASSERT( dest_start_x >= 0 && dest_start_x < m_size.x && dest_start_y >= 0 && dest_start_y < m_size.y, "set_sub_array: destination start is out of bounds." ); 319 NV_ASSERT( source_start_x >= 0 && source_start_x < source.m_size.x && source_start_y >= 0 && source_start_y < source.m_size.y, "set_sub_array: source start is out of bounds." ); 320 NV_ASSERT( size_x >= 1 && size_y >= 1, "set_sub_array: invalid size specified." ); // If size is 0, nothing would be copied in the first place. 321 322 // Warn when copied data is truncated. 323 // If the end of the copied area is beyond the bounds of the destination array, data will be truncated. 324 if ( dest_start_x + min(size_x, source.m_size.x - source_start_x) > m_size.x || dest_start_y + min(size_y, source.m_size.y - source_start_y) > m_size.y ) 325 { 326 NV_LOG( LOG_WARNING, "set_sub_array: Source area does not fit in the destination area. Data will be truncated." ); 327 } 328 329 // Copy into THIS array from source the following. 330 // Highest row is either the size limit or the end of either array, whichever is smaller. 331 for ( i = 0; i < min( size_y , min ( m_size.y - dest_start_y, source.m_size.y - source_start_y ) ); i++ ) 332 { 333 // Copy the indicated row. 334 // The start position is the beginning of the current row (which is source_start_y + i), offset by source_start_x. 335 // The end position is either the size limit or the end of either array, whichever is smaller. 336 // Destination start is the beginning of the current destination row (which is dest_start_y + i), offset by dest_start_x. 337 std:copy( source.m_data + ( source_start_y + i ) * source.m_size.x + source_start_x, // Source Start 338 source.m_data + ( source_start_y + i ) * source.m_size.x + min( source.m_size.x, min( source_start_x + size_x, source_start_x + m_size.x - dest_start_x ) ), // Source End 339 m_data + (dest_start_y + i) * m_size.x + dest_start_x ) // Destination Start 340 } 341 } 342 343 /** 344 *Destructor. 345 */ 84 346 ~array2d() 85 347 { … … 90 352 } 91 353 protected: 92 pointer m_data; 93 ivec2 m_size; 354 pointer m_data; ///< Pointer to the data. 355 ivec2 m_size; ///< Allocated size of the data. 94 356 }; 95 357
Note: See TracChangeset
for help on using the changeset viewer.