Line data Source code
1 : /* File: universal_array_list.inl; Copyright and License: see below */
2 :
3 : #include "u8/u8_trace.h"
4 : #include "u8/u8_log.h"
5 : #include <assert.h>
6 : #include <string.h>
7 :
8 9 : static inline void universal_array_list_init ( universal_array_list_t *this_,
9 : unsigned int max_elements,
10 : void *elements,
11 : size_t element_size,
12 : ptrdiff_t step_size,
13 : void (*copy_ctor)(void* to_instance, const void* from_instance),
14 : bool (*equal)(const void* instance_1, const void* instance_2),
15 : void (*dtor)(void* instance) )
16 : {
17 9 : U8_TRACE_INFO_INT( "- max_elements:", max_elements );
18 9 : U8_TRACE_INFO_INT( "- element_size:", element_size );
19 9 : U8_TRACE_INFO_INT( "- step_size:", step_size );
20 9 : assert( element_size <= step_size );
21 9 : assert( (element_size+sizeof(int)) > step_size ); /* something is wrong if there is more padding than an int */
22 9 : assert( elements != NULL );
23 9 : assert( max_elements != 0 ); /* a list of size 0 could be valid - but most likely this function is called with wrong arguments */
24 :
25 9 : (*this_).length = 0;
26 9 : (*this_).elements = elements;
27 9 : (*this_).max_elements = max_elements;
28 9 : (*this_).element_size = element_size;
29 9 : (*this_).step_size = step_size;
30 9 : (*this_).copy_ctor = copy_ctor;
31 9 : (*this_).equal = equal;
32 9 : (*this_).dtor = dtor;
33 9 : }
34 :
35 8 : static inline void universal_array_list_destroy ( universal_array_list_t *this_ )
36 : {
37 8 : assert( (*this_).length <= (*this_).max_elements );
38 8 : assert( (*this_).elements != NULL );
39 :
40 8 : universal_array_list_clear( this_ );
41 8 : }
42 :
43 3 : static inline void universal_array_list_trace ( const universal_array_list_t *this_ )
44 : {
45 3 : assert( (*this_).length <= (*this_).max_elements );
46 3 : assert( (*this_).elements != NULL );
47 :
48 3 : U8_TRACE_INFO( "universal_array_list_t" );
49 3 : U8_TRACE_INFO_INT( "- length:", (*this_).length );
50 3 : U8_TRACE_INFO_INT( "- max_elements:", (*this_).max_elements );
51 3 : U8_TRACE_INFO_INT( "- element_size:", (*this_).element_size );
52 3 : U8_TRACE_INFO_INT( "- step_size:", (*this_).step_size );
53 3 : U8_TRACE_INFO_STR( "- copy_ctor:", ((*this_).copy_ctor == NULL)?"NULL":"exists" );
54 3 : U8_TRACE_INFO_STR( "- equal:", ((*this_).equal == NULL)?"NULL":"exists" );
55 3 : U8_TRACE_INFO_STR( "- dtor:", ((*this_).dtor == NULL)?"NULL":"exists" );
56 3 : }
57 :
58 5 : static inline bool universal_array_list_is_empty ( const universal_array_list_t *this_ )
59 : {
60 5 : return ( 0 == (*this_).length );
61 : }
62 :
63 16 : static inline u8_error_t universal_array_list_append ( universal_array_list_t *this_, const void* element )
64 : {
65 16 : assert( (*this_).length <= (*this_).max_elements );
66 16 : assert( (*this_).elements != NULL );
67 :
68 : u8_error_t err_result;
69 :
70 16 : if ( (*this_).length < (*this_).max_elements )
71 : {
72 14 : unsigned int index = (*this_).length;
73 14 : (*this_).length ++;
74 14 : void *pos = universal_array_list_get_ptr( this_, index );
75 14 : if ( (*this_).copy_ctor != NULL )
76 : {
77 4 : (*this_).copy_ctor( pos, element );
78 : }
79 : else
80 : {
81 10 : memcpy( pos, element, (*this_).element_size );
82 : }
83 14 : err_result = U8_ERROR_NONE;
84 : }
85 : else
86 : {
87 2 : err_result = U8_ERROR_ARRAY_BUFFER_EXCEEDED;
88 : }
89 :
90 16 : return err_result;
91 : }
92 :
93 5 : static inline u8_error_t universal_array_list_append_all ( universal_array_list_t *this_, const universal_array_list_t *that )
94 : {
95 5 : assert( that != NULL );
96 :
97 5 : u8_error_t err_result = U8_ERROR_NONE;
98 5 : const unsigned int len = universal_array_list_get_length(that);
99 10 : for ( unsigned int idx = 0; (idx < len)&&(err_result == 0); idx ++ )
100 : {
101 5 : err_result = universal_array_list_append( this_, universal_array_list_get_const( that, idx ) );
102 : }
103 :
104 5 : return err_result;
105 : }
106 :
107 23 : static inline void *universal_array_list_get_ptr ( universal_array_list_t *this_, unsigned int index )
108 : {
109 23 : assert( (*this_).length <= (*this_).max_elements );
110 23 : assert( (*this_).elements != NULL );
111 :
112 : void *result;
113 :
114 23 : if ( index < (*this_).length )
115 : {
116 21 : result = ((char*)(*this_).elements) + ((*this_).step_size * index);
117 : }
118 : else
119 : {
120 2 : result = NULL;
121 : }
122 :
123 23 : return result;
124 : }
125 :
126 19 : static inline void const *universal_array_list_get_const ( const universal_array_list_t *this_, unsigned int index )
127 : {
128 19 : assert( (*this_).length <= (*this_).max_elements );
129 19 : assert( (*this_).elements != NULL );
130 :
131 : void const *result;
132 :
133 19 : if ( index < (*this_).length )
134 : {
135 17 : result = ((const char*)(*this_).elements) + ((*this_).step_size * index);
136 : }
137 : else
138 : {
139 2 : result = NULL;
140 : }
141 :
142 19 : return result;
143 : }
144 :
145 3 : static inline int universal_array_list_get_index_of ( const universal_array_list_t *this_, const void* element )
146 : {
147 3 : assert( (*this_).length <= (*this_).max_elements );
148 3 : assert( (*this_).elements != NULL );
149 3 : assert( element != NULL );
150 :
151 3 : int result = -1;
152 :
153 3 : if ( (*this_).equal != NULL )
154 : {
155 2 : for ( unsigned int index = 0; ( index < (*this_).length )&&( result == -1 ); index ++ )
156 : {
157 1 : const void *current = universal_array_list_get_const( this_, index );
158 1 : if ( (*this_).equal( current, element ) )
159 : {
160 1 : result = index;
161 : }
162 : }
163 : }
164 : else
165 : {
166 4 : for ( unsigned int index = 0; ( index < (*this_).length )&&( result == -1 ); index ++ )
167 : {
168 2 : const void *current = universal_array_list_get_const( this_, index );
169 2 : if ( 0 == memcmp( current, element, (*this_).element_size ) )
170 : {
171 1 : result = index;
172 : }
173 : }
174 : }
175 :
176 3 : return result;
177 : }
178 :
179 12 : static inline void universal_array_list_clear ( universal_array_list_t *this_ )
180 : {
181 12 : assert( (*this_).length <= (*this_).max_elements );
182 12 : assert( (*this_).elements != NULL );
183 :
184 12 : if ( (*this_).dtor != NULL )
185 : {
186 5 : for ( unsigned int index = 0; index < (*this_).length; index ++ )
187 : {
188 3 : void *current = universal_array_list_get_ptr( this_, index );
189 3 : (*this_).dtor( current );
190 : }
191 : }
192 12 : (*this_).length = 0;
193 12 : }
194 :
195 26 : static inline unsigned int universal_array_list_get_length ( const universal_array_list_t *this_ )
196 : {
197 26 : return (*this_).length;
198 : }
199 :
200 :
201 : /*
202 : Copyright 2020-2025 Andreas Warnke
203 :
204 : Licensed under the Apache License, Version 2.0 (the "License");
205 : you may not use this file except in compliance with the License.
206 : You may obtain a copy of the License at
207 :
208 : http://www.apache.org/licenses/LICENSE-2.0
209 :
210 : Unless required by applicable law or agreed to in writing, software
211 : distributed under the License is distributed on an "AS IS" BASIS,
212 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
213 : See the License for the specific language governing permissions and
214 : limitations under the License.
215 : */
|