utils_array.h
Go to the documentation of this file.
1
12#ifndef CCGL_UTILS_ARRAY_H
13#define CCGL_UTILS_ARRAY_H
14
15#include <new> // std::nothrow
16#include <cstdarg> // variable arguments
17#include <iostream>
18#include <vector>
19
20#include "basic.h"
21
22using std::vector;
23using std::cout;
24using std::endl;
25using std::nothrow;
26
27namespace ccgl {
32namespace utils_array {
40template <typename T, typename INI_T>
41bool Initialize1DArray(int row, T*& data, INI_T init_value);
42
50template <typename T, typename INI_T>
51bool Initialize1DArray(int row, T*& data, INI_T* init_data);
52
53template <typename T, typename INI_T>
54bool Initialize1DArray4ItpWeight(int row, T*& data, INI_T* init_data, int itp_weight_data_length);
71template <typename T, typename INI_T>
72bool Initialize2DArray(int row, int col, T**& data, INI_T init_value);
73
83template <typename T, typename INI_T>
84bool Initialize2DArray(int row, int col, T**& data, INI_T** init_data);
85
94template <typename T1, typename T2>
95bool Initialize2DArray(T1* init_data, int& rows, int& max_cols, T2**& data);
96
101template <typename T>
102void Release1DArray(T*& data);
103
108template <typename T>
109void Release2DArray(T**& data);
110
128template <typename T>
129void BatchRelease1DArray(T*& data, ...);
130
144template <typename T>
145void BatchRelease2DArray(int nrows, T**& data, ...);
146
152void Output1DArrayToTxtFile(int n, const float* data, const char* filename);
153
159void Output2DArrayToTxtFile(int rows, int cols, const float** data, const char* filename);
160
172template <typename T>
173void Read1DArrayFromTxtFile(const char* filename, int& rows, T*& data);
174
186template <typename T>
187void Read2DArrayFromTxtFile(const char* filename, int& rows, T**& data);
188
199template <typename T>
200void Read2DArrayFromString(const char* s, int& rows, T**& data);
201
208template <typename T>
209bool ValueInVector(T val, const vector<T>& vec);
210
216template <typename T>
217void RemoveValueInVector(T val, vector<T>& vec);
218
228template <typename T>
229class Array2D {
230 T** data_ptr;
231 vuint32_t m_rows;
232 vuint32_t m_cols;
233
234 T** create2DArray(vuint32_t nrows, vuint32_t ncols, const T& val = T()) {
235 T** ptr = nullptr;
236 T* pool = nullptr;
237 try {
238 ptr = new(nothrow) T*[nrows]; // allocate pointers (Do not throw here)
239 pool = new(nothrow) T[nrows*ncols]; // allocate pool (Do not throw here)
240 for (vuint32_t i = 0; i < nrows * ncols; i++) {
241 pool[i] = val;
242 }
243 // now point the row pointers to the appropriate positions in the memory pool
244 for (vuint32_t i = 0; i < nrows; ++i, pool += ncols) {
245 ptr[i] = pool;
246 }
247 return ptr;
248 } catch (std::bad_alloc& ex) {
249 delete[] ptr; // either this is nullptr or it was allocated
250 // throw ex; // memory allocation error
251 }
252 }
253
254public:
255 typedef T value_type;
256 T** data() {
257 return data_ptr;
258 }
259
260 vuint32_t get_rows() const { return m_rows; }
261
262 vuint32_t get_cols() const { return m_cols; }
263
264 Array2D() : data_ptr(nullptr), m_rows(0), m_cols(0) {}
265 Array2D(vuint32_t rows, vuint32_t cols, const T& val = T()) {
266 if (rows <= 0)
267 throw std::invalid_argument("number of rows is 0"); // TODO, DO not throw here
268 if (cols <= 0)
269 throw std::invalid_argument("number of columns is 0"); // TODO, DO not throw here
270 data_ptr = create2DArray(rows, cols, val);
271 m_rows = rows;
272 m_cols = cols;
273 }
274
275 ~Array2D() {
276 if (data_ptr) {
277 delete[] data_ptr[0]; // remove the pool
278 delete[] data_ptr; // remove the pointers
279 }
280 }
281
282 Array2D(const Array2D& rhs) : m_rows(rhs.m_rows), m_cols(rhs.m_cols) {
283 data_ptr = create2DArray(m_rows, m_cols);
284 std::copy(&rhs.data_ptr[0][0], &rhs.data_ptr[m_rows - 1][m_cols], &data_ptr[0][0]);
285 }
286
287 Array2D(Array2D&& rhs) NOEXCEPT {
288 data_ptr = rhs.data_ptr;
289 m_rows = rhs.m_rows;
290 m_cols = rhs.m_cols;
291 rhs.data_ptr = nullptr;
292 }
293
294 Array2D& operator=(Array2D&& rhs) NOEXCEPT {
295 if (&rhs != this) {
296 swap(rhs, *this);
297 }
298 return *this;
299 }
300
301 void swap(Array2D& left, Array2D& right) {
302 std::swap(left.data_ptr, right.data_ptr);
303 std::swap(left.m_cols, right.m_cols);
304 std::swap(left.m_rows, right.m_rows);
305 }
306
307 Array2D& operator = (const Array2D& rhs) {
308 if (&rhs != this) {
309 Array2D temp(rhs);
310 swap(*this, temp);
311 }
312 return *this;
313 }
314
315 T* operator[](vuint32_t row) {
316 return data_ptr[row];
317 }
318
319 const T* operator[](vuint32_t row) const {
320 return data_ptr[row];
321 }
322
323 void create(vuint32_t rows, vuint32_t cols, const T& val = T()) {
324 *this = Array2D(rows, cols, val);
325 }
326};
327
328
329/************ Implementation of template functions ******************/
330template <typename T, typename INI_T>
331bool Initialize1DArray(const int row, T*& data, const INI_T init_value) {
332 if (nullptr != data) {
333 //Should allow an array to re-enter this function then just return? --wyj
334 //cout << "The input 1D array pointer is not nullptr. No initialization performed!" << endl;
335 return false;
336 }
337 if (row <= 0) {
338 cout << "The data length MUST be greater than 0!" << endl;
339 data = nullptr;
340 return false;
341 }
342 data = new(nothrow)T[row];
343 if (nullptr == data) {
344 delete[] data;
345 cout << "Bad memory allocated during 1D array initialization!" << endl;
346 data = nullptr;
347 return false;
348 }
349 T init = static_cast<T>(init_value);
350#pragma omp parallel for
351 for (int i = 0; i < row; i++) {
352 data[i] = init;
353 }
354 return true;
355}
356
357template <typename T, typename INI_T>
358bool Initialize1DArray(const int row, T*& data, INI_T* const init_data) {
359 if (nullptr != data) {
360 cout << "The input 1D array pointer is not nullptr. No initialization performed!" << endl;
361 return false;
362 }
363 data = new(nothrow) T[row];
364 if (nullptr == data) {
365 delete[] data;
366 cout << "Bad memory allocated during 1D array initialization!" << endl;
367 return false;
368 }
369 if (nullptr == init_data) {
370 cout << "The input parameter init_data MUST NOT be nullptr!" << endl;
371 return false;
372 }
373#pragma omp parallel for
374 for (int i = 0; i < row; i++) {
375 data[i] = static_cast<T>(init_data[i]);
376 }
377 return true;
378}
379
380template <typename T, typename INI_T>
381bool Initialize2DArray(const int row, const int col, T**& data,
382 const INI_T init_value) {
383 if (nullptr != data) {
384 cout << "The input 2D array pointer is not nullptr. No initialization performed!" << endl;
385 return false;
386 }
387 data = new(nothrow) T*[row];
388 if (nullptr == data) {
389 delete[] data;
390 cout << "Bad memory allocated during initialize rows of the 2D array!" << endl;
391 return false;
392 }
393 T* pool = nullptr;
394 pool = new(nothrow) T[row * col];
395 if (nullptr == pool) {
396 delete[] pool;
397 cout << "Bad memory allocated during initialize data pool of the 2D array!" << endl;
398 return false;
399 }
400 // Initialize the data pool
401 T init = static_cast<T>(init_value);
402#pragma omp parallel for
403 for (int i = 0; i < row * col; i++) {
404 pool[i] = init;
405 }
406 // Now point the row pointers to the appropriate positions in the data pool
407 for (int i = 0; i < row; ++i, pool += col) {
408 data[i] = pool;
409 }
410 return true;
411}
412
413template <typename T, typename INI_T>
414bool Initialize2DArray(const int row, const int col, T**& data,
415 INI_T** const init_data) {
416 bool flag = Initialize2DArray(row, col, data, init_data[0][0]);
417 if (!flag) { return false; }
418#pragma omp parallel for
419 for (int i = 0; i < row; i++) {
420 for (int j = 0; j < col; j++) {
421 data[i][j] = static_cast<T>(init_data[i][j]);
422 }
423 }
424 return true;
425}
426
427template <typename T1, typename T2>
428bool Initialize2DArray(T1* init_data, int& rows, int& max_cols, T2**& data) {
429 int idx = 0;
430 rows = CVT_INT(init_data[idx++]);
431 data = new(nothrow) T2* [rows];
432 if (nullptr == data) {
433 delete[] data;
434 cout << "Bad memory allocated during initialize rows of the 2D array!" << endl;
435 return false;
436 }
437 T2* pool = nullptr;
438 // Get actual data length of init_data, excluding the first element which is 'rows'
439 int* cols = new int[rows];
440 max_cols = -1;
441 for (int i = 0; i < rows; i++) {
442 cols[i] = CVT_INT(init_data[idx]);
443 idx += cols[i] + 1;
444 if (cols[i] > max_cols) { max_cols = cols[i]; }
445 }
446 int length = idx - 1;
447 // New a 1d array to store data
448 Initialize1DArray(length, pool, init_data + 1);
449 // Now point the row pointers to the appropriate positions in the data pool
450 int pos = 0;
451 for (int i = 0; i < rows; ++i) {
452 data[i] = pool + pos;
453 pos += cols[i] + 1;
454 }
455 delete[] cols;
456 return true;
457}
458
459template <typename T>
460void Release1DArray(T*& data) {
461 if (nullptr != data) {
462 delete[] data;
463 data = nullptr;
464 }
465}
466
467template <typename T>
468void Release2DArray(T**& data) {
469 if (nullptr == data) {
470 return;
471 }
472 delete[] data[0]; // delete the memory pool
473 delete[] data; // delete row pointers
474 data = nullptr;
475}
476
477template <typename T>
478void BatchRelease1DArray(T*& data, ...) {
479 va_list arg_ptr;
480 va_start(arg_ptr, data);
481 Release1DArray(data);
482 T* arg_value = va_arg(arg_ptr, T*);
483 while (nullptr != arg_value) {
484 Release1DArray(arg_value);
485 arg_value = va_arg(arg_ptr, T*);
486 }
487 va_end(arg_ptr);
488}
489
490template <typename T>
491void BatchRelease2DArray(const int nrows, T**& data, ...) {
492 va_list arg_ptr;
493 va_start(arg_ptr, data);
494 Release2DArray(nrows, data);
495 T** arg_value = va_arg(arg_ptr, T**);
496 while (nullptr != arg_value) {
497 Release2DArray(nrows, arg_value);
498 arg_value = va_arg(arg_ptr, T**);
499 }
500 va_end(arg_ptr);
501}
502
503template <typename T>
504bool ValueInVector(const T val, const vector<T>& vec) {
505 if (vec.empty()) {
506 return false;
507 }
508 if (find(vec.begin(), vec.end(), val) == vec.end()) {
509 return false;
510 }
511 return true;
512}
513
514template <typename T>
515void RemoveValueInVector(const T val, vector<T>& vec) {
516 for (auto iter = vec.begin(); iter != vec.end();) {
517 if (*iter == val) {
518 iter = vec.erase(iter);
519 } else {
520 ++iter;
521 }
522 }
523}
524
525} /* utils_array */
526} /* namespace: ccgl */
527
528#endif /* CCGL_UTILS_ARRAY_H */
Basic definitions.
#define NOEXCEPT
A compatible reference to noexcept or throw() if not supported by the compiler.
Definition: basic.h:153
#define CVT_INT(param)
A reference to the postfix of executable file for RELWITHDEBINFO mode.
Definition: basic.h:325
Rudimentary RAII class of 2D Array which occupy successive memory.
Definition: utils_array.h:229
void Release1DArray(T *&data)
Release DT_Array1D data.
Definition: utils_array.h:460
bool Initialize1DArray(int row, T *&data, INI_T init_value)
Initialize DT_Array1D data.
Definition: utils_array.h:331
bool Initialize2DArray(int row, int col, T **&data, INI_T init_value)
Initialize DT_Array2D data.
Definition: utils_array.h:381
void Read2DArrayFromTxtFile(const char *filename, int &rows, T **&data)
Read 2D array from file The input file should follow the format: a 2D array sized rows * rows.
Definition: utils_array.cpp:40
void RemoveValueInVector(T val, vector< T > &vec)
Remove value in vector container.
Definition: utils_array.h:515
void Output2DArrayToTxtFile(const int rows, const int cols, const float **data, const char *filename)
Write 2D array to a file.
Definition: utils_array.cpp:16
void BatchRelease1DArray(T *&data,...)
Batch release of 1D array Variable arguments with the end of nullptr.
Definition: utils_array.h:478
bool ValueInVector(T val, const vector< T > &vec)
If value in vector container.
Definition: utils_array.h:504
void Read2DArrayFromString(const char *s, int &rows, T **&data)
Read 2D array from string The input string should follow the format: float value, total number is row...
Definition: utils_array.cpp:58
void Output1DArrayToTxtFile(const int n, const float *data, const char *filename)
Write 1D array to a file.
Definition: utils_array.cpp:8
void BatchRelease2DArray(int nrows, T **&data,...)
Batch release of 2D array,.
Definition: utils_array.h:491
void Read1DArrayFromTxtFile(const char *filename, int &rows, T *&data)
Read 1D array from file The input file should follow the format: a 1D array sized rows * 1.
Definition: utils_array.cpp:28
void Release2DArray(T **&data)
Release DT_Array2D data.
Definition: utils_array.h:468
Common Cross-platform Geographic Library (CCGL)
Definition: basic.cpp:17