summaryrefslogtreecommitdiffhomepage
path: root/docs/carray_api.md
blob: f74ee1576ba23b0a1c79a4890a503991e75e9a96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# STC [carr2, carr3](../include/stc/carray.h): Dynamic Multi-dimensional Arrays
![Array](pics/array.jpg)

The **carr2** and **carr3** are templated 2D and 3D dynamic arrays. They are allocated on the heap as a single
contiguous block of memory. The arrays can be indexed like regular constant size multi-dimensional arrays in C.

See the c++ class [boost::multi_array](https://www.boost.org/doc/libs/release/libs/multi_array) for similar functionality.

## Header file and declaration

```c
#define i_tag       // defaults to i_val name
#define i_val       // value: REQUIRED
#define i_valfrom   // clone func i_val => i_val - defaults to plain copy
#define i_valdel    // destroy value func - defaults to empty destruct

#include <stc/carr2.h> // or <stc/carr3.h>
```
`X` should be replaced by the value of `i_tag` in all of the following documentation.

## Methods

carr2_X:
```c
carr2_X             carr2_X_init(size_t xdim, size_t ydim);
carr2_X             carr2_X_with_values(size_t xdim, size_t ydim, Value val);
carr2_X             carr2_X_with_storage(size_t xdim, size_t ydim, Value* array);
carr2_X             carr2_X_clone(carr2_X arr);
void                carr2_X_copy(carr2_X* self, carr2_X other);
Value*              carr2_X_release(carr2_X* self);       // release storage (not freed)
void                carr2_X_del(carr2_X* self);

size_t              carr2_X_size(carr2_X arr);
Value*              carr2_X_data(carr2_X* self);          // access storage data
Value*              carr2_X_at(carr2_X* self, size_t x, size_t y);

carr2_X_iter_t      carr2_X_begin(const carr2_X* self);
carr2_X_iter_t      carr2_X_end(const carr2_X* self);
void                carr2_X_next(carr2_X_iter_t* it);
```
carr3:
```c
carr3_X             carr3_X_init(size_t xdim, size_t ydim, size_t zdim);
carr3_X             carr3_X_with_values(size_t xdim, size_t ydim, size_t zdim, Value val);
carr3_X             carr3_X_with_storage(size_t xdim, size_t ydim, size_t zdim, Value* array);
carr3_X             carr3_X_clone(carr3_X arr);
void                carr3_X_copy(carr3_X* self, carr3_X other);
Value*              carr3_X_release(carr3_X* self);       // release storage (not freed)
void                carr3_X_del(carr3_X* self);

size_t              carr3_X_size(carr3_X arr);
Value*              carr3_X_data(carr3_X* self);          // access storage data
Value*              carr3_X_at(carr3_X* self, size_t x, size_t y, size_t z);

carr3_X_iter_t      carr3_X_begin(const carr3_X* self);
carr3_X_iter_t      carr3_X_end(const carr3_X* self);
void                carr3_X_next(carr3_X_iter_t* it);
```
## Types

| Type name         | Type definition                                      | Used to represent... |
|:------------------|:-----------------------------------------------------|:---------------------|
| `carr2_X`         | `struct { i_val **data; size_t xdim, ydim; }`        | The array 2D type    |
| `carr2_X_value_t` | `i_val`                                              | The value type       |
| `carr2_X_iter_t`  | `struct { i_val *ref; }`                             | Iterator type        |
|                   |                                                      |                      |
| `carr3_X`         | `struct { i_val ***data; size_t xdim, ydim, zdim; }` | The array 3D type    |
| `carr3_X_value_t` | `i_val`                                              | The value type       |
| `carr3_X_iter_t`  | `struct { i_val *ref; }`                             | Iterator type        |

The **carr3** elements can be accessed like `carr3_i arr = ...; int val = arr.data[x][y][z];`, or with `carr3_i_at(&arr, x, y, z)`.

## Example
```c
#include <stdio.h>

#define i_tag i
#define i_val uint32_t
#include <stc/carr2.h>

#define i_tag f
#define i_val float
#include <stc/carr3.h>

int main()
{
    // Ex1
    int xd = 30, yd = 20, zd = 10;
    // define arr3[30][20][10], initialized with zeros.
    carr3_f arr3 = carr3_f_with_values(xd, yd, zd, 0.0f);
    arr3.data[5][4][3] = 3.14f;

    float *arr1 = arr3.data[5][4];
    float **arr2 = arr3.data[5];

    printf("%f\n", arr1[3]); // 3.14
    printf("%f\n", arr2[4][3]); // 3.14
    printf("%f\n", arr3.data[5][4][3]); // 3.14
    carr3_f_del(&arr3); // free array

    // Ex2
    int w = 256, h = 128;
    carr2_i image = carr2_i_init(w, h);
    int n = 0;
    c_foreach (i, carr2_i, image) {
        uint32_t t = n++ % 256;
        *i.ref = t | t << 8 | t << 16 | 255;
    }

    for (int y = 0; y < image.ydim; ++y)
        image.data[y][y] = 0xffffffff;
    carr2_i_del(&image);
}
```
Output:
```
3.140000
3.140000
3.140000
```