GCC Code Coverage Report


Directory: ./
File: submodules/ECS/lib/vector/source/vector.c
Date: 2023-09-29 04:53:15
Exec Total Coverage
Lines: 0 97 0.0%
Branches: 0 42 0.0%

Line Branch Exec Source
1 /*
2 * Filename: /workspaces/our_rpg/lib/vector/source/vector.c
3 * Path: /workspaces/our_rpg/lib/vector/source
4 * Created Date: Thursday, December 29th 2022, 10:41:19 pm
5 * Author: osvegn
6 *
7 * Copyright (c) 2023 our_rpg
8 */
9
10 #include "vector.h"
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
14
15
16 /// @brief It swaps two elements in the vector.
17 /// @param this The vector_t object.
18 /// @param first_element The index of the first element to swap.
19 /// @param second_element the index of the second element to swap.
20 /// @return 0, or -1 if an error occurs.
21 static int swap(vector_t *this, unsigned int first_element, unsigned int second_element)
22 {
23 void *tmp = NULL;
24 void *first = NULL;
25 void *second = NULL;
26
27 if (first_element > this->_size || second_element > this->_size)
28 return -1;
29 tmp = malloc(this->_element_size);
30 if (!tmp)
31 return -1;
32 first = (char *)this->pointer + first_element * this->_element_size;
33 second = (char *)this->pointer + second_element * this->_element_size;
34 memcpy(tmp, first, this->_element_size);
35 memcpy(first, second, this->_element_size);
36 memcpy(second, tmp, this->_element_size);
37 free(tmp);
38 return 0;
39 }
40
41 /// @brief It returns a pointer to the first element of the vector.
42 /// @param this The vector on which find an element.
43 /// @return A pointer to the last element.
44 static void *front(vector_t *this)
45 {
46 return this->pointer;
47 }
48
49 /// @brief It returns a pointer to the last element of the vector.
50 /// @param this The vector on which find an element.
51 /// @return A pointer to the last element.
52 static void *back(vector_t *this)
53 {
54 if (!this->pointer)
55 return NULL;
56 return (char *)this->pointer + (this->_size - 1) * this->_element_size;
57 }
58
59 /// @brief It returns a pointer to the element ask at position index.
60 /// @param this The vector on which find an element.
61 /// @param index The position of the element in the vector.
62 /// @return A pointer to the element asked.
63 static void *at(vector_t *this, unsigned int index)
64 {
65 if (index >= this->_size || !this->pointer)
66 return NULL;
67 return (char *)this->pointer + index * this->_element_size;
68 }
69
70 /// @brief It resizes the allocated memory to fix with the actual memory usage.
71 /// @param this The vector the to be udpate.
72 /// @return 0, or -1 if an error occurs.
73 static int shrink_to_fit(vector_t *this)
74 {
75 this->pointer = realloc(this->pointer, this->_size * this->_element_size);
76 this->_capacity = this->_size;
77 if (!this->pointer)
78 return -1;
79 return 0;
80 }
81
82 /// @brief It returns the capacity of the vector.
83 /// @param this The vector to be ckeck.
84 /// @return The capacity of the vector as unsigned int.
85 static unsigned int capacity(vector_t *this)
86 {
87 return this->_capacity;
88 }
89
90 /// @brief It returns the this of the vector.
91 /// @param this The vector to be check.
92 /// @return The size of the vector as unsigned int.
93 static unsigned int size(vector_t *this)
94 {
95 return this->_size;
96 }
97
98 /// @brief It returns if the vector is empty or not.
99 /// @param this The vector to be check.
100 /// @return True, or false if the vector isn't empty.
101 static bool empty(vector_t *this)
102 {
103 if (this->_size)
104 return false;
105 return true;
106 }
107
108 /// @brief It clears the vector, by setting the size to 0.
109 /// @param this The vector to be clear.
110 /// @return 0.
111 static int clear(vector_t *this)
112 {
113 this->_size = 0;
114 return 0;
115 }
116
117 /// @brief It erases an element of a vector at a given index.
118 /// It also moves all following elements in the vector.
119 /// @param this The vector on which the element will be removed.
120 /// @param index The element position on the vector to be removed.
121 /// @return 0, or -1 if an error occurs.
122 static int erase(vector_t *this, unsigned int index)
123 {
124 if (index > this->_size)
125 return -1;
126 memcpy((char *)this->pointer + index * this->_element_size, (char *)this->pointer + (index + 1) * this->_element_size, (this->_size - (index + 1)) * this->_element_size);
127 this->_size--;
128 return 0;
129 }
130
131 /// @brief It removes the last element of a vector.
132 /// @param this The vector on which the element will be removed.
133 /// @return 0.
134 static int pop_back(vector_t *this)
135 {
136 this->_size--;
137 return 0;
138 }
139
140 /// @brief The print_at function prints an element at the given index
141 /// using print_fct function pointer.
142 /// The format dependant on how print_fct function pointer print the data.
143 /// @param this The vector on which print an element.
144 /// @param index The position of the element to print.
145 /// @param print_fct The function pointer used to know how to print an
146 /// element.
147 /// @return It returns the value of print_fct, or -1 if an error occurs.
148 static int print_at(vector_t *this, unsigned int index, int (*print_fct)(void *data))
149 {
150 if (index > this->_size)
151 return -1;
152 return print_fct((char *)this->pointer + index * this->_element_size);
153 }
154
155 /// @brief The print function prints all elements of the vector.
156 /// The format dependant on how print_fct function pointer print the data.
157 /// @param this The vector on which print all elements.
158 /// @param print_fct The function pointer used to know how to print an
159 /// element.
160 /// @return 0, or -1 if print_fct return -1.
161 static int print(vector_t *this, int (*print_fct)(void *data))
162 {
163 printf("[");
164 fflush(stdout);
165 for (unsigned int i = 0; i < this->_size; i++) {
166 if (this->print_at(this, i, print_fct) < 0)
167 return -1;
168 if (i + 1 < this->_size) {
169 printf(", ");
170 fflush(stdout);
171 }
172 }
173 printf("]\n");
174 fflush(stdout);
175 return 0;
176 }
177
178 /// @brief The emplace function adds an element at the given index.
179 /// It increases the capacity of the vector if needed.
180 /// @param this The vector on which adds an element.
181 /// @param data The data to be added.
182 /// @param index The index where the data must be added.
183 /// @return 0, or -1 if an error occurs.
184 static int emplace(vector_t *this, void *data, unsigned int index)
185 {
186 void *ptr = NULL;
187
188 if (index > this->_capacity)
189 return -1;
190 if (this->_size == this->_capacity) {
191 this->pointer = realloc(this->pointer, (this->_capacity + 1) * this->_element_size);
192 if (!this->pointer)
193 return -1;
194 this->_capacity++;
195 }
196 ptr = (char *)this->pointer + index * this->_element_size;
197 for (unsigned int i = this->_size; i > index; i--) {
198 memcpy((char *)this->pointer + i * this->_element_size, (char *)this->pointer + (i - 1) * this->_element_size, this->_element_size);
199 }
200 memcpy(ptr, data, this->_element_size);
201 this->_size++;
202 return 0;
203 }
204
205 /// @brief The emplace_back function adds an element at the end.
206 /// It increases the capacity of the vector if needed.
207 /// @param this The vector on which adds an element.
208 /// @param data The data to be added.
209 /// @return 0, or -1 if an error occurs.
210 static int emplace_back(vector_t *this, void *data)
211 {
212 if (this->_size == this->_capacity) {
213 this->pointer = realloc(this->pointer, (this->_capacity + 1) * this->_element_size);
214 if (!this->pointer)
215 return -1;
216 this->_capacity++;
217 }
218 memcpy((char *)this->pointer + this->_size * this->_element_size, data, this->_element_size);
219 this->_size++;
220 return 0;
221 }
222
223 /// @brief This is the destructor of a vector. It frees the pointer.
224 /// @param this The vector to be free.
225 static void destructor(vector_t *this)
226 {
227 if (this->pointer)
228 free(this->pointer);
229 }
230
231 int vector_constructor(vector_t *this, unsigned int element_size, unsigned int element_number)
232 {
233 this->_element_size = element_size;
234 this->pointer = malloc(this->_element_size * element_number);
235 if (!this->pointer)
236 return - 1;
237 this->_size = 0;
238 this->_capacity = element_number;
239 this->destructor = &destructor;
240 this->emplace = &emplace;
241 this->emplace_back = &emplace_back;
242 this->print_at = &print_at;
243 this->print = &print;
244 this->clear = &clear;
245 this->erase = &erase;
246 this->pop_back = &pop_back;
247 this->swap = &swap;
248 this->at = &at;
249 this->back = &back;
250 this->front = &front;
251 this->empty = &empty;
252 this->size = &size;
253 this->capacity = &capacity;
254 this->shrink_to_fit = &shrink_to_fit;
255 return 0;
256 }
257