annotate arrayalloc.h @ 13:de3961f74f30 tip

Add Linux/gcc Makefile; build fix
author Chris Cannam
date Mon, 05 Sep 2011 15:22:35 +0100
parents 977f541d6683
children
rev   line source
xue@11 1 /*
xue@11 2 Harmonic sinusoidal modelling and tools
xue@11 3
xue@11 4 C++ code package for harmonic sinusoidal modelling and relevant signal processing.
xue@11 5 Centre for Digital Music, Queen Mary, University of London.
xue@11 6 This file copyright 2011 Wen Xue.
xue@11 7
xue@11 8 This program is free software; you can redistribute it and/or
xue@11 9 modify it under the terms of the GNU General Public License as
xue@11 10 published by the Free Software Foundation; either version 2 of the
xue@11 11 License, or (at your option) any later version.
xue@11 12 */
xue@1 13 #ifndef ARRAYALLOC
xue@1 14 #define ARRAYALLOC
xue@1 15
Chris@5 16 /**
Chris@5 17 \file arrayalloc.h - 2D, 3D and 4D array memory allocation routines.
xue@1 18
xue@1 19 An x-dimensional array (x=2, 3, 4, ...) is managed as a single memory block hosting all records, plus
xue@1 20 an index block which is a (x-1)D array itself. Therefore a 2D array is allocated as two 1D arrays, a
xue@1 21 3D array is allocated as three 1D arrays, etc.
xue@1 22
xue@1 23 Examples:
xue@1 24 Alloc2(4, N, x) declares an array x[4][N] of double-precision floating points.
xue@1 25 Allocate3(int, K, L, M, x) allocates an array x[K][L][M] of integers and returns x as int***.
xue@1 26
xue@1 27 This file also includes a garbage collector class MList that works with arrays allcoated in this way.
xue@1 28 */
xue@1 29
xue@1 30
xue@1 31 #include <stdlib.h>
xue@1 32
xue@1 33 //2D array allocation macros for declaring an array of double
xue@1 34 #define Alloc2(M, N, x) \
xue@1 35 double **x=new double*[M]; x[0]=new double[(M)*(N)]; for (int _z=1; _z<M; _z++) x[_z]=&x[0][_z*(N)];
xue@1 36 #define Alloc2L(M, N, x, LIST) Alloc2(M, N, x); if (LIST) LIST->Add(x, 2);
xue@1 37 //2D array allocation macros for all data types
xue@1 38 #define Allocate2(INT, M, N, x) \
xue@1 39 x=new INT*[M]; x[0]=new INT[(M)*(N)]; for (int _z=1; _z<M; _z++) x[_z]=&x[0][_z*(N)];
xue@1 40 #define Allocate2L(INT, M, N, x, LIST) Allocate2(INT, M, N, x); if (LIST) LIST->Add(x, 2);
xue@1 41 //2D array deallocation macro
xue@1 42 #define DeAlloc2(x) {if (x) {delete[] (char*)(x[0]); delete[] x; x=0;}}
xue@1 43
xue@1 44 //3D array allocation macro for declaring an array of double
xue@1 45 #define Alloc3(L, M, N, x) \
xue@1 46 double*** x=new double**[L]; x[0]=new double*[(L)*(M)]; x[0][0]=new double[(L)*(M)*(N)]; \
xue@1 47 for (int _z=0; _z<L; _z++) {x[_z]=&x[0][_z*(M)]; x[_z][0]=&x[0][0][_z*(M)*(N)]; \
xue@1 48 for (int __z=1; __z<M; __z++) x[_z][__z]=&x[_z][0][__z*(N)]; }
xue@1 49 //3D array allocation macros for all data types
xue@1 50 #define Allocate3(INT, L, M, N, x) \
xue@1 51 x=new INT**[L]; x[0]=new INT*[(L)*(M)]; x[0][0]=new INT[(L)*(M)*(N)]; \
xue@1 52 for (int _z=0; _z<L; _z++) {x[_z]=&x[0][_z*(M)]; x[_z][0]=&x[0][0][_z*(M)*(N)]; \
xue@1 53 for (int __z=1; __z<M; __z++) x[_z][__z]=&x[_z][0][__z*(N)]; }
xue@1 54 #define Allocate3L(INT, M, N, O, x, LIST) Allocate3(INT, M, N, O, x); if (LIST) LIST->Add(x, 3);
xue@1 55 //3D array deallocation macro
xue@1 56 #define DeAlloc3(x) {if (x) {delete[] (char*)(x[0][0]); delete[] x[0]; delete[] x; x=0;}}
xue@1 57
xue@1 58 //4D array allocation macro for declaring an array of double
xue@1 59 #define Alloc4(L, M, N, O, x) \
xue@1 60 double**** x=new double***[L]; x[0]=new double**[(L)*(M)]; \
xue@1 61 x[0][0]=new double*[(L)*(M)*(N)]; x[0][0][0]=new double[(L)*(M)*(N)*(O)]; \
xue@1 62 for (int _z=0; _z<L; _z++){ \
xue@1 63 x[_z]=&x[0][_z*(M)]; x[_z][0]=&x[0][0][_z*(M)*(N)]; x[_z][0][0]=&x[0][0][0][_z*(M)*(N)*(O)]; \
xue@1 64 for (int __z=0; __z<M; __z++){ \
xue@1 65 x[_z][__z]=&x[_z][0][__z*(N)]; x[_z][__z][0]=&x[_z][0][0][__z*(N)*(O)]; \
xue@1 66 for (int ___z=1; ___z<N; ___z++) x[_z][__z][___z]=&d[_z][__z][0][___z*(O)]; }}
xue@1 67 //4D array deallocation macro
xue@1 68 #define DeAlloc4(x) {if (x) {delete[] (char*)(x[0][0][0]); delete[] x[0][0]; delete[] x[0]; delete[] x; x=0;}}
xue@1 69
xue@1 70
xue@1 71 /*
xue@1 72 MList is a garbage collector for arrays created using Alloc* or Allocate* (*=2, 3, 4). After being
xue@1 73 added to the list the arrays will be automatically freed when MList is deleted.
xue@1 74
xue@1 75 Using MList:
xue@1 76 Create an MList object and add all buffers (1D, 2D, 3D or 4D) to be recycled to the MList using
xue@1 77 MList::Add(...). Deleting the MList will recycle all the added buffers.
xue@1 78
xue@1 79 Example:
xue@1 80 Alloc2L(4, N, x, mlist) declares 2D array x and registers it with garbage collector mlist,so that x is
xue@1 81 freed when mlist is deleted.
xue@1 82 */
xue@1 83 class MList
xue@1 84 {
xue@1 85 public:
xue@1 86 int cap[4];
xue@1 87 int count[4];
xue@1 88 void** List[4];
xue@1 89 MList(){for (int i=0; i<4; i++) cap[i]=64, count[i]=0, List[i]=(void**)malloc(sizeof(void*)*cap[i]);}
xue@1 90 ~MList(){
xue@1 91 for (int i=0; i<count[0]; i++){delete[] (char*)(List[0][i]); List[0][i]=0;} free(List[0]);
xue@1 92 for (int i=0; i<count[1]; i++){void** tmp=(void**)List[1][i]; DeAlloc2(tmp); List[1][i]=0;} free(List[1]);
xue@1 93 for (int i=0; i<count[2]; i++){void*** tmp=(void***)List[2][i]; DeAlloc3(tmp); List[2][i]=0;} free(List[2]);
xue@1 94 for (int i=0; i<count[3]; i++){void**** tmp=(void****)List[3][i]; DeAlloc4(tmp); List[3][i]=0;} free(List[3]);}
xue@1 95 void __fastcall Add(void* item, int Dim){
xue@1 96 int Gr=Dim-1; if (count[Gr]==cap[Gr]) IncCap(Gr); List[Gr][count[Gr]++]=item;}
xue@1 97 void IncCap(int Gr){cap[Gr]+=64; List[Gr]=(void**)realloc(List[Gr], sizeof(void*)*cap[Gr]);}
xue@1 98 };
xue@1 99
xue@1 100 #endif