Skip to content

Instantly share code, notes, and snippets.

@DanGdl
Last active March 1, 2024 11:19
Show Gist options
  • Save DanGdl/055d429ccbdde6e149ba46f4d6ab1274 to your computer and use it in GitHub Desktop.
Save DanGdl/055d429ccbdde6e149ba46f4d6ab1274 to your computer and use it in GitHub Desktop.
N-dimension matrixes example
#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