aboutsummaryrefslogtreecommitdiff
path: root/src/vector.h
blob: 7deb8d31b9e27d6e847c566fe9c67366ff19f74e (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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
 * @file vector.h
 * @brief Dynamic array (vector) implementation.
 * @details This module provides a generic resizable array data structure
 *          that can store pointers to any datatype. The vector automatically
 *          grows as elements are added, using a growth factor to mediate
 *          reallocation costs.
 */

#ifndef VECTOR_H
#define VECTOR_H

#include <stddef.h>

/**
 * @def VECTOR_INITIAL_CAPACITY
 * @brief Initial capacity of a vector.
 * @details The vector will be allocated with space for this many elements
 *          when first created. This value is chosen to balance memory usage
 *          and the number of early reallocations.
 */
#define VECTOR_INITIAL_CAPACITY 10

/**
 * @def VECTOR_GROWTH_FACTOR
 * @brief Multiplicative factor for vector capacity growth.
 * @details When the vector reaches capacity and needs to grow, the new
 *          capacity is calculated as (current_capacity * GROWTH_FACTOR).
 */
#define VECTOR_GROWTH_FACTOR 2

/**
 * @struct Vector
 * @brief A dynamic resizable array (vector) of generic pointers.
 * @details The vector maintains an underlying array that grows dynamically
 *          as elements are added. It tracks both the number of elements
 *          currently stored (size) and the total allocated space (capacity).
 */
typedef struct Vector Vector;

/**
 * @struct Vector
 * @brief A dynamic array container structure.
 */
struct Vector {
    /**
     * @brief Array of generic data pointers.
     * @details A dynamically allocated array of (void*) pointers,
     *          referencing to the actual data. The array has space for
     *          at least @p capacity elements. The caller is responsible
     *          for managing the memory that these pointers reference.
     */
    void **data;

    /**
     * @brief The number of elements currently stored in the vector.
     * @details Valid indices range from 0 to (size - 1). This value is
     *          incremented when elements are added and decremented when
     *          elements are removed.
     */
    size_t size;

    /**
     * @brief The total allocated space (in number of elements).
     * @details The underlying @p data array has space for this many pointers.
     *          When size reaches capacity, the vector is reallocated with
     *          a new capacity of (capacity * GROWTH_FACTOR). Always
     *          capacity >= size.
     */
    size_t capacity;
};

/**
 * @brief Allocates and initializes an empty vector.
 *
 * @return A pointer to the newly created vector, or NULL if memory
 *         allocation fails.
 *
 * @note The caller is responsible for freeing the returned vector
 *       using vector_delete().
 */
Vector *vector_new(void);

/**
 * @brief Deallocates the given vector.
 *
 * @param v Pointer to the vector to delete. If NULL, this function
 *          does nothing.
 *
 * @note This function deallocates only the vector structure, not the
 *       data it contains. The caller retains ownership of the data.
 */
void vector_delete(Vector *v);

/**
 * @brief Appends an element to the end of the vector.
 *
 * @param v Pointer to the vector.
 * @param element Pointer to the element to append.
 *
 * @note The vector does not take ownership of the element, only stores
 *       a pointer to it.
 */
void vector_push(Vector *v, void *element);

/**
 * @brief Removes and returns the last element from the vector.
 *
 * @param v Pointer to the vector.
 *
 * @return The data pointer of the removed last element.
 *
 * @pre The vector must not be empty.
 */
void *vector_pop(Vector *v);

/**
 * @brief Returns the element at the given index in the vector.
 *
 * @param v Pointer to the vector.
 * @param index The index of the element to retrieve.
 *
 * @return The data pointer at the given index.
 *
 * @pre The index must be valid (0 <= index < vector_size(v)).
 */
void *vector_get(Vector *v, size_t index);

/**
 * @brief Sets the element at the given index in the vector.
 *
 * @param v Pointer to the vector.
 * @param index The index of the element to set.
 * @param element Pointer to the new element.
 *
 * @pre The index must be valid (0 <= index < vector_size(v)).
 */
void vector_set(Vector *v, size_t index, void *element);

/**
 * @brief Returns the number of elements in the vector.
 *
 * @param v Pointer to the vector.
 *
 * @return The number of elements currently in the vector.
 */
size_t vector_size(Vector *v);

/**
 * @brief Checks if the vector is empty.
 *
 * @param v Pointer to the vector.
 *
 * @return Non-zero if the vector is empty, 0 otherwise.
 */
int vector_is_empty(Vector *v);

/**
 * @brief Removes all elements from the vector.
 *
 * @param v Pointer to the vector.
 *
 * @note This function only clears the vector structure, not the data
 *       it contained. The caller retains ownership of the data.
 */
void vector_clear(Vector *v);

#endif // !VECTOR_H