naev 0.12.5
intlist.c
1/*
2 * This code was initially authored by the Stackoverflow user dragon-energy and
3 * posted under following page:
4 * https://stackoverflow.com/questions/41946007/efficient-and-well-explained-implementation-of-a-quadtree-for-2d-collision-det
5 *
6 * As for the license, the author has kindly noted:
7 *
8 * "Oh and feel free to use this code I post however you want, even for
9 * commercial projects. I would really love it if people let me know if they
10 * find it useful, but do as you wish."
11 *
12 * And generally all Stackoverflow-posted code is by default licensed with CC
13 * BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/
14 */
15#include "intlist.h"
16#include <assert.h>
17#include <stdlib.h>
18#include <string.h>
19
20void il_create( IntList *il, int num_fields )
21{
22 il->data = il->fixed;
23 il->num = 0;
24 il->cap = il_fixed_cap;
25 il->num_fields = num_fields;
26 il->free_element = -1;
27}
28
29void il_destroy( IntList *il )
30{
31 // Free the buffer only if it was heap allocated.
32 if ( il->data != il->fixed )
33 free( il->data );
34}
35
36void il_clear( IntList *il )
37{
38 il->num = 0;
39 il->free_element = -1;
40}
41
42int il_size( const IntList *il )
43{
44 return il->num;
45}
46
47int il_get( const IntList *il, int n, int field )
48{
49 assert( n >= 0 && n < il->num );
50 return il->data[n * il->num_fields + field];
51}
52
53void il_set( IntList *il, int n, int field, int val )
54{
55 assert( n >= 0 && n < il->num );
56 il->data[n * il->num_fields + field] = val;
57}
58
59int il_push_back( IntList *il )
60{
61 const int new_pos = ( il->num + 1 ) * il->num_fields;
62
63 // If the list is full, we need to reallocate the buffer to make room
64 // for the new element.
65 if ( new_pos > il->cap ) {
66 // Use double the size for the new capacity.
67 const int new_cap = new_pos * 2;
68
69 // If we're pointing to the fixed buffer, allocate a new array on the
70 // heap and copy the fixed buffer contents to it.
71 if ( il->cap == il_fixed_cap ) {
72 il->data = malloc( new_cap * sizeof( *il->data ) );
73 memcpy( il->data, il->fixed, sizeof( il->fixed ) );
74 } else {
75 // Otherwise reallocate the heap buffer to the new size.
76 il->data = realloc( il->data, new_cap * sizeof( *il->data ) );
77 }
78 // Set the old capacity to the new capacity.
79 il->cap = new_cap;
80 }
81 return il->num++;
82}
83
84void il_pop_back( IntList *il )
85{
86 // Just decrement the list size.
87 assert( il->num > 0 );
88 --il->num;
89}
90
91int il_insert( IntList *il )
92{
93 // If there's a free index in the free list, pop that and use it.
94 if ( il->free_element != -1 ) {
95 const int index = il->free_element;
96 const int pos = index * il->num_fields;
97
98 // Set the free index to the next free index.
99 il->free_element = il->data[pos];
100
101 // Return the free index.
102 return index;
103 }
104 // Otherwise insert to the back of the array.
105 return il_push_back( il );
106}
107
108void il_erase( IntList *il, int n )
109{
110 // Push the element to the free list.
111 const int pos = n * il->num_fields;
112 il->data[pos] = il->free_element;
113 il->free_element = n;
114}