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-2024 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 : */