Last active
March 1, 2024 11:19
-
-
Save DanGdl/055d429ccbdde6e149ba46f4d6ab1274 to your computer and use it in GitHub Desktop.
N-dimension matrixes example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MATRIXN_H_ | |
#define MATRIXN_H_ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
typedef unsigned long int dimen_t; | |
#define MATRIXN(N, name, dtype) \ | |
typedef struct name##Matrix##N { \ | |
dimen_t dimens[N]; \ | |
dtype* values; \ | |
} name##Matrix##N##_t; | |
#define MATRIXN_SET(N, name, dtype) \ | |
void name##Matrix##N##_set(name##Matrix##N##_t* const matrix, const dimen_t dimens[N], dtype value) { \ | |
if (matrix == NULL || matrix->values == NULL) return; \ | |
dimen_t idx = 0; \ | |
for (int i = 0; i < N; i++) { \ | |
if (matrix->dimens[i] < dimens[i]) return; \ | |
dimen_t size = dimens[i]; \ | |
for (int j = 0; j < i; j++) { \ | |
size *= matrix->dimens[j]; \ | |
} \ | |
idx += size; \ | |
} \ | |
matrix->values[idx] = value; \ | |
} | |
#define MATRIXN_GET(N, name, dtype) \ | |
dtype* name##Matrix##N##_get(const name##Matrix##N##_t* const matrix, const dimen_t dimens[N]) { \ | |
if (matrix == NULL || matrix->values == NULL) return NULL; \ | |
dimen_t idx = 0; \ | |
for (int i = 0; i < N; i++) { \ | |
if (matrix->dimens[i] < dimens[i]) return NULL; \ | |
dimen_t size = dimens[i]; \ | |
for (int j = 0; j < i; j++) { \ | |
size *= matrix->dimens[j]; \ | |
} \ | |
idx += size; \ | |
} \ | |
return matrix->values + idx; \ | |
} | |
#define MATRIXN_CLEAR(N, name) \ | |
void name##Matrix##N##_clear(name##Matrix##N##_t* const matrix) { \ | |
if (matrix == NULL || matrix->values == NULL) return; \ | |
free(matrix->values); \ | |
matrix->values = NULL; \ | |
for (int i = 0; i < N; i++) matrix->dimens[i] = 0; \ | |
} | |
#define MATRIXN_FREE(N, name) \ | |
void name##Matrix##N##_free(name##Matrix##N##_t** const matrix) { \ | |
if (matrix == NULL || *matrix == NULL) return; \ | |
name##Matrix##N##_clear(*matrix); \ | |
free(*matrix); \ | |
*matrix = NULL; \ | |
} | |
#define MATRIXN_PREPARE(N, name, dtype) \ | |
int name##Matrix##N##_prepare(name##Matrix##N##_t* const matrix, const dimen_t dimens[N]) { \ | |
if (matrix == NULL) return 0; \ | |
name##Matrix##N##_clear(matrix); \ | |
dimen_t size = 1; \ | |
for (int i = 0; i < N; i++) size *= dimens[i]; \ | |
if (size == 0) return -1; \ | |
matrix->values = (dtype*) calloc(size, sizeof(*(matrix->values))); \ | |
for (int i = 0; i < N; i++) matrix->dimens[i] = matrix->values ? dimens[i] : 0; \ | |
return matrix->values ? 0 : -1; \ | |
} | |
#define MATRIXN_ALLOCATE(N, name) \ | |
name##Matrix##N##_t* name##Matrix##N##_create(const dimen_t dimens[N]) { \ | |
name##Matrix##N##_t* matrix = calloc(1, sizeof(*matrix)); \ | |
if (name##Matrix##N##_prepare(matrix, dimens) != 0) { \ | |
free(matrix); \ | |
return NULL; \ | |
} \ | |
return matrix; \ | |
} | |
// functions implementations | |
#define MATRIXN_INFRA_C(N, name, dtype) \ | |
MATRIXN_CLEAR(N, name) \ | |
MATRIXN_PREPARE(N, name, dtype) \ | |
MATRIXN_SET(N, name, dtype) \ | |
MATRIXN_GET(N, name, dtype) | |
// struct and functions | |
#define MATRIXN_INFRA(N, name, dtype) \ | |
MATRIXN(N, name, dtype) \ | |
MATRIXN_INFRA_C(N, name, dtype) | |
// struct and functions + dynamic allocations for structs | |
#define MATRIXN_STRUCT_INFRA(N, name, dtype) \ | |
MATRIXN_INFRA(N, name, dtype) \ | |
MATRIXN_FREE(N, name) \ | |
MATRIXN_ALLOCATE(N, name) | |
// struct and function's declarations for header files | |
#define MATRIXN_INFRA_H(N, name, dtype) \ | |
MATRIXN(N, name, dtype) \ | |
void name##Matrix##N##_clear(name##Matrix##N##_t* const matrix) \ | |
int name##Matrix##N##_prepare(name##Matrix##N##_t* const matrix, const dimen_t dimens[N]) \ | |
void name##Matrix##N##_set(name##Matrix##N##_t* const matrix, const dimen_t dimens[N], dtype value) \ | |
const dtype* const name##Matrix##N##_get(const name##Matrix##N##_t* const matrix, const dimen_t dimens[N]) | |
// struct and function's declarations for header files + declarations for dynamic allocations | |
#define MATRIXN_STRUCT_INFRA_H(N, name, dtype) \ | |
MATRIXN_INFRA_H(N, name, dtype) \ | |
void name##Matrix##N##_free(name##Matrix##N##_t** const matrix) \ | |
name##Matrix##N##_t* name##Matrix##N##_create(const dimen_t dimens[N]) | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment