1 module soundio.list;
2 
3 extern(C): @nogc: nothrow: __gshared:
4 
5 import soundio.util;
6 import soundio.soundio_internal;
7 import core.stdc.stdlib;
8 
9 package:
10 
11 struct SOUNDIO_LIST(Type) {
12     Type *items;
13     int length;
14     int capacity;
15 
16     void deinit() {
17         free(this.items);
18     }
19 
20     int ensure_capacity(int new_capacity) {
21         int better_capacity = soundio_int_max(this.capacity, 16);
22         while (better_capacity < new_capacity)
23             better_capacity = better_capacity * 2;
24         if (better_capacity != this.capacity) {
25             Type *new_items = REALLOCATE_NONZERO!Type(this.items, better_capacity);
26             if (!new_items)
27                 return SoundIoError.NoMem;
28             this.items = new_items;
29             this.capacity = better_capacity;
30         }
31         return 0;
32     }
33 
34     int append(Type item) {
35         int err = ensure_capacity(this.length + 1);
36         if (err)
37             return err;
38         this.items[this.length] = item;
39         this.length += 1;
40         return 0;
41     }
42 
43     Type val_at(int index) {
44         assert(index >= 0);
45         assert(index < this.length);
46         return this.items[index];
47     }
48 
49     /* remember that the pointer to this item is invalid after you
50      * modify the length of the list
51      */
52     Type* ptr_at(int index) {
53         assert(index >= 0);
54         assert(index < this.length);
55         return &this.items[index];
56     }
57 
58     Type pop() {
59         assert(this.length >= 1);
60         this.length -= 1;
61         return this.items[this.length];
62     }
63 
64     int resize(int new_length) {
65         assert(new_length >= 0);
66         int err = ensure_capacity(new_length);
67         if (err)
68             return err;
69         this.length = new_length;
70         return 0;
71     }
72 
73     int add_one() {
74         return resize(this.length + 1);
75     }
76 
77     Type last_val() {
78         assert(this.length >= 1);
79         return this.items[this.length - 1];
80     }
81 
82     Type* last_ptr() {
83         assert(this.length >= 1);
84         return &this.items[this.length - 1];
85     }
86 
87     void clear() {
88         this.length = 0;
89     }
90 
91     Type swap_remove(int index) {
92         assert(index >= 0);
93         assert(index < this.length);
94         Type last = pop();
95         if (index == this.length)
96             return last;
97         Type item = this.items[index];
98         this.items[index] = last;
99         return item;
100     }
101 }