Home | History | Annotate | Download | only in vector
      1 /*
      2 The MIT License(MIT)
      3 Copyright(c) 2016 Peter Goldsborough
      4 
      5 Permission is hereby granted, free of charge, to any person obtaining a copy of
      6 this software and associated documentation files(the "Software"), to deal in
      7 the Software without restriction, including without limitation the rights to
      8 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
      9 the Software, and to permit persons to whom the Software is furnished to do so,
     10 subject to the following conditions :
     11 
     12 The above copyright notice and this permission notice shall be included in all
     13 copies or substantial portions of the Software.
     14 
     15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
     17 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
     18 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
     19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21 */
     22 
     23 #define __STDC_WANT_LIB_EXT1__ 1
     24 
     25 #include <assert.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 
     29 #include "third_party/vector/vector.h"
     30 
     31 int aom_vector_setup(Vector *vector, size_t capacity, size_t element_size) {
     32   assert(vector != NULL);
     33 
     34   if (vector == NULL) return VECTOR_ERROR;
     35 
     36   vector->size = 0;
     37   vector->capacity = MAX(VECTOR_MINIMUM_CAPACITY, capacity);
     38   vector->element_size = element_size;
     39   vector->data = malloc(vector->capacity * element_size);
     40 
     41   return vector->data == NULL ? VECTOR_ERROR : VECTOR_SUCCESS;
     42 }
     43 
     44 int aom_vector_copy(Vector *destination, Vector *source) {
     45   assert(destination != NULL);
     46   assert(source != NULL);
     47   assert(aom_vector_is_initialized(source));
     48   assert(!aom_vector_is_initialized(destination));
     49 
     50   if (destination == NULL) return VECTOR_ERROR;
     51   if (source == NULL) return VECTOR_ERROR;
     52   if (aom_vector_is_initialized(destination)) return VECTOR_ERROR;
     53   if (!aom_vector_is_initialized(source)) return VECTOR_ERROR;
     54 
     55   /* Copy ALL the data */
     56   destination->size = source->size;
     57   destination->capacity = source->size * 2;
     58   destination->element_size = source->element_size;
     59 
     60   /* Note that we are not necessarily allocating the same capacity */
     61   destination->data = malloc(destination->capacity * source->element_size);
     62   if (destination->data == NULL) return VECTOR_ERROR;
     63 
     64   memcpy(destination->data, source->data, aom_vector_byte_size(source));
     65 
     66   return VECTOR_SUCCESS;
     67 }
     68 
     69 int aom_vector_copy_assign(Vector *destination, Vector *source) {
     70   assert(destination != NULL);
     71   assert(source != NULL);
     72   assert(aom_vector_is_initialized(source));
     73   assert(aom_vector_is_initialized(destination));
     74 
     75   if (destination == NULL) return VECTOR_ERROR;
     76   if (source == NULL) return VECTOR_ERROR;
     77   if (!aom_vector_is_initialized(destination)) return VECTOR_ERROR;
     78   if (!aom_vector_is_initialized(source)) return VECTOR_ERROR;
     79 
     80   aom_vector_destroy(destination);
     81 
     82   return aom_vector_copy(destination, source);
     83 }
     84 
     85 int aom_vector_move(Vector *destination, Vector *source) {
     86   assert(destination != NULL);
     87   assert(source != NULL);
     88 
     89   if (destination == NULL) return VECTOR_ERROR;
     90   if (source == NULL) return VECTOR_ERROR;
     91 
     92   *destination = *source;
     93   source->data = NULL;
     94 
     95   return VECTOR_SUCCESS;
     96 }
     97 
     98 int aom_vector_move_assign(Vector *destination, Vector *source) {
     99   aom_vector_swap(destination, source);
    100   return aom_vector_destroy(source);
    101 }
    102 
    103 int aom_vector_swap(Vector *destination, Vector *source) {
    104   void *temp;
    105 
    106   assert(destination != NULL);
    107   assert(source != NULL);
    108   assert(aom_vector_is_initialized(source));
    109   assert(aom_vector_is_initialized(destination));
    110 
    111   if (destination == NULL) return VECTOR_ERROR;
    112   if (source == NULL) return VECTOR_ERROR;
    113   if (!aom_vector_is_initialized(destination)) return VECTOR_ERROR;
    114   if (!aom_vector_is_initialized(source)) return VECTOR_ERROR;
    115 
    116   _vector_swap(&destination->size, &source->size);
    117   _vector_swap(&destination->capacity, &source->capacity);
    118   _vector_swap(&destination->element_size, &source->element_size);
    119 
    120   temp = destination->data;
    121   destination->data = source->data;
    122   source->data = temp;
    123 
    124   return VECTOR_SUCCESS;
    125 }
    126 
    127 int aom_vector_destroy(Vector *vector) {
    128   assert(vector != NULL);
    129 
    130   if (vector == NULL) return VECTOR_ERROR;
    131 
    132   free(vector->data);
    133   vector->data = NULL;
    134 
    135   return VECTOR_SUCCESS;
    136 }
    137 
    138 /* Insertion */
    139 int aom_vector_push_back(Vector *vector, void *element) {
    140   assert(vector != NULL);
    141   assert(element != NULL);
    142 
    143   if (_vector_should_grow(vector)) {
    144     if (_vector_adjust_capacity(vector) == VECTOR_ERROR) {
    145       return VECTOR_ERROR;
    146     }
    147   }
    148 
    149   _vector_assign(vector, vector->size, element);
    150 
    151   ++vector->size;
    152 
    153   return VECTOR_SUCCESS;
    154 }
    155 
    156 int aom_vector_push_front(Vector *vector, void *element) {
    157   return aom_vector_insert(vector, 0, element);
    158 }
    159 
    160 int aom_vector_insert(Vector *vector, size_t index, void *element) {
    161   void *offset;
    162 
    163   assert(vector != NULL);
    164   assert(element != NULL);
    165   assert(index <= vector->size);
    166 
    167   if (vector == NULL) return VECTOR_ERROR;
    168   if (element == NULL) return VECTOR_ERROR;
    169   if (vector->element_size == 0) return VECTOR_ERROR;
    170   if (index > vector->size) return VECTOR_ERROR;
    171 
    172   if (_vector_should_grow(vector)) {
    173     if (_vector_adjust_capacity(vector) == VECTOR_ERROR) {
    174       return VECTOR_ERROR;
    175     }
    176   }
    177 
    178   /* Move other elements to the right */
    179   if (_vector_move_right(vector, index) == VECTOR_ERROR) {
    180     return VECTOR_ERROR;
    181   }
    182 
    183   /* Insert the element */
    184   offset = _vector_offset(vector, index);
    185   memcpy(offset, element, vector->element_size);
    186   ++vector->size;
    187 
    188   return VECTOR_SUCCESS;
    189 }
    190 
    191 int aom_vector_assign(Vector *vector, size_t index, void *element) {
    192   assert(vector != NULL);
    193   assert(element != NULL);
    194   assert(index < vector->size);
    195 
    196   if (vector == NULL) return VECTOR_ERROR;
    197   if (element == NULL) return VECTOR_ERROR;
    198   if (vector->element_size == 0) return VECTOR_ERROR;
    199   if (index >= vector->size) return VECTOR_ERROR;
    200 
    201   _vector_assign(vector, index, element);
    202 
    203   return VECTOR_SUCCESS;
    204 }
    205 
    206 /* Deletion */
    207 int aom_vector_pop_back(Vector *vector) {
    208   assert(vector != NULL);
    209   assert(vector->size > 0);
    210 
    211   if (vector == NULL) return VECTOR_ERROR;
    212   if (vector->element_size == 0) return VECTOR_ERROR;
    213 
    214   --vector->size;
    215 
    216 #ifndef VECTOR_NO_SHRINK
    217   if (_vector_should_shrink(vector)) {
    218     _vector_adjust_capacity(vector);
    219   }
    220 #endif
    221 
    222   return VECTOR_SUCCESS;
    223 }
    224 
    225 int aom_vector_pop_front(Vector *vector) { return aom_vector_erase(vector, 0); }
    226 
    227 int aom_vector_erase(Vector *vector, size_t index) {
    228   assert(vector != NULL);
    229   assert(index < vector->size);
    230 
    231   if (vector == NULL) return VECTOR_ERROR;
    232   if (vector->element_size == 0) return VECTOR_ERROR;
    233   if (index >= vector->size) return VECTOR_ERROR;
    234 
    235   /* Just overwrite */
    236   _vector_move_left(vector, index);
    237 
    238 #ifndef VECTOR_NO_SHRINK
    239   if (--vector->size == vector->capacity / 4) {
    240     _vector_adjust_capacity(vector);
    241   }
    242 #endif
    243 
    244   return VECTOR_SUCCESS;
    245 }
    246 
    247 int aom_vector_clear(Vector *vector) { return aom_vector_resize(vector, 0); }
    248 
    249 /* Lookup */
    250 void *aom_vector_get(Vector *vector, size_t index) {
    251   assert(vector != NULL);
    252   assert(index < vector->size);
    253 
    254   if (vector == NULL) return NULL;
    255   if (vector->element_size == 0) return NULL;
    256   if (index >= vector->size) return NULL;
    257 
    258   return _vector_offset(vector, index);
    259 }
    260 
    261 const void *aom_vector_const_get(const Vector *vector, size_t index) {
    262   assert(vector != NULL);
    263   assert(index < vector->size);
    264 
    265   if (vector == NULL) return NULL;
    266   if (vector->element_size == 0) return NULL;
    267   if (index >= vector->size) return NULL;
    268 
    269   return _vector_const_offset(vector, index);
    270 }
    271 
    272 void *aom_vector_front(Vector *vector) { return aom_vector_get(vector, 0); }
    273 
    274 void *aom_vector_back(Vector *vector) {
    275   return aom_vector_get(vector, vector->size - 1);
    276 }
    277 
    278 /* Information */
    279 
    280 bool aom_vector_is_initialized(const Vector *vector) {
    281   return vector->data != NULL;
    282 }
    283 
    284 size_t aom_vector_byte_size(const Vector *vector) {
    285   return vector->size * vector->element_size;
    286 }
    287 
    288 size_t aom_vector_free_space(const Vector *vector) {
    289   return vector->capacity - vector->size;
    290 }
    291 
    292 bool aom_vector_is_empty(const Vector *vector) { return vector->size == 0; }
    293 
    294 /* Memory management */
    295 int aom_vector_resize(Vector *vector, size_t new_size) {
    296   if (new_size <= vector->capacity * VECTOR_SHRINK_THRESHOLD) {
    297     vector->size = new_size;
    298     if (_vector_reallocate(vector, new_size * VECTOR_GROWTH_FACTOR) == -1) {
    299       return VECTOR_ERROR;
    300     }
    301   } else if (new_size > vector->capacity) {
    302     if (_vector_reallocate(vector, new_size * VECTOR_GROWTH_FACTOR) == -1) {
    303       return VECTOR_ERROR;
    304     }
    305   }
    306 
    307   vector->size = new_size;
    308 
    309   return VECTOR_SUCCESS;
    310 }
    311 
    312 int aom_vector_reserve(Vector *vector, size_t minimum_capacity) {
    313   if (minimum_capacity > vector->capacity) {
    314     if (_vector_reallocate(vector, minimum_capacity) == VECTOR_ERROR) {
    315       return VECTOR_ERROR;
    316     }
    317   }
    318 
    319   return VECTOR_SUCCESS;
    320 }
    321 
    322 int aom_vector_shrink_to_fit(Vector *vector) {
    323   return _vector_reallocate(vector, vector->size);
    324 }
    325 
    326 /* Iterators */
    327 Iterator aom_vector_begin(Vector *vector) { return aom_vector_iterator(vector, 0); }
    328 
    329 Iterator aom_vector_end(Vector *vector) {
    330   return aom_vector_iterator(vector, vector->size);
    331 }
    332 
    333 Iterator aom_vector_iterator(Vector *vector, size_t index) {
    334   Iterator iterator = { NULL, 0 };
    335 
    336   assert(vector != NULL);
    337   assert(index <= vector->size);
    338 
    339   if (vector == NULL) return iterator;
    340   if (index > vector->size) return iterator;
    341   if (vector->element_size == 0) return iterator;
    342 
    343   iterator.pointer = _vector_offset(vector, index);
    344   iterator.element_size = vector->element_size;
    345 
    346   return iterator;
    347 }
    348 
    349 void *iterator_get(Iterator *iterator) { return iterator->pointer; }
    350 
    351 int iterator_erase(Vector *vector, Iterator *iterator) {
    352   size_t index = iterator_index(vector, iterator);
    353 
    354   if (aom_vector_erase(vector, index) == VECTOR_ERROR) {
    355     return VECTOR_ERROR;
    356   }
    357 
    358   *iterator = aom_vector_iterator(vector, index);
    359 
    360   return VECTOR_SUCCESS;
    361 }
    362 
    363 void iterator_increment(Iterator *iterator) {
    364   assert(iterator != NULL);
    365   // iterator->pointer += iterator->element_size;
    366   iterator->pointer =
    367       (unsigned char *)iterator->pointer + iterator->element_size;
    368 }
    369 
    370 void iterator_decrement(Iterator *iterator) {
    371   assert(iterator != NULL);
    372   // iterator->pointer -= iterator->element_size;
    373   iterator->pointer =
    374       (unsigned char *)iterator->pointer - iterator->element_size;
    375 }
    376 
    377 void *iterator_next(Iterator *iterator) {
    378   void *current = iterator->pointer;
    379   iterator_increment(iterator);
    380 
    381   return current;
    382 }
    383 
    384 void *iterator_previous(Iterator *iterator) {
    385   void *current = iterator->pointer;
    386   iterator_decrement(iterator);
    387 
    388   return current;
    389 }
    390 
    391 bool iterator_equals(Iterator *first, Iterator *second) {
    392   assert(first->element_size == second->element_size);
    393   return first->pointer == second->pointer;
    394 }
    395 
    396 bool iterator_is_before(Iterator *first, Iterator *second) {
    397   assert(first->element_size == second->element_size);
    398   return first->pointer < second->pointer;
    399 }
    400 
    401 bool iterator_is_after(Iterator *first, Iterator *second) {
    402   assert(first->element_size == second->element_size);
    403   return first->pointer > second->pointer;
    404 }
    405 
    406 size_t iterator_index(Vector *vector, Iterator *iterator) {
    407   assert(vector != NULL);
    408   assert(iterator != NULL);
    409   // return (iterator->pointer - vector->data) / vector->element_size;
    410   return ((unsigned char *)iterator->pointer - (unsigned char *)vector->data) /
    411          vector->element_size;
    412 }
    413 
    414 /***** PRIVATE *****/
    415 
    416 bool _vector_should_grow(Vector *vector) {
    417   assert(vector->size <= vector->capacity);
    418   return vector->size == vector->capacity;
    419 }
    420 
    421 bool _vector_should_shrink(Vector *vector) {
    422   assert(vector->size <= vector->capacity);
    423   return vector->size == vector->capacity * VECTOR_SHRINK_THRESHOLD;
    424 }
    425 
    426 size_t _vector_free_bytes(const Vector *vector) {
    427   return aom_vector_free_space(vector) * vector->element_size;
    428 }
    429 
    430 void *_vector_offset(Vector *vector, size_t index) {
    431   // return vector->data + (index * vector->element_size);
    432   return (unsigned char *)vector->data + (index * vector->element_size);
    433 }
    434 
    435 const void *_vector_const_offset(const Vector *vector, size_t index) {
    436   // return vector->data + (index * vector->element_size);
    437   return (unsigned char *)vector->data + (index * vector->element_size);
    438 }
    439 
    440 void _vector_assign(Vector *vector, size_t index, void *element) {
    441   /* Insert the element */
    442   void *offset = _vector_offset(vector, index);
    443   memcpy(offset, element, vector->element_size);
    444 }
    445 
    446 int _vector_move_right(Vector *vector, size_t index) {
    447   assert(vector->size < vector->capacity);
    448 
    449   /* The location where to start to move from. */
    450   void *offset = _vector_offset(vector, index);
    451 
    452   /* How many to move to the right. */
    453   size_t elements_in_bytes = (vector->size - index) * vector->element_size;
    454 
    455 #ifdef __STDC_LIB_EXT1__
    456   size_t right_capacity_in_bytes =
    457       (vector->capacity - (index + 1)) * vector->element_size;
    458 
    459   /* clang-format off */
    460     int return_code =  memmove_s(
    461         offset + vector->element_size,
    462         right_capacity_in_bytes,
    463         offset,
    464         elements_in_bytes);
    465 
    466   /* clang-format on */
    467 
    468   return return_code == 0 ? VECTOR_SUCCESS : VECTOR_ERROR;
    469 
    470 #else
    471   // memmove(offset + vector->element_size, offset, elements_in_bytes);
    472   memmove((unsigned char *)offset + vector->element_size, offset,
    473           elements_in_bytes);
    474   return VECTOR_SUCCESS;
    475 #endif
    476 }
    477 
    478 void _vector_move_left(Vector *vector, size_t index) {
    479   size_t right_elements_in_bytes;
    480   void *offset;
    481 
    482   /* The offset into the memory */
    483   offset = _vector_offset(vector, index);
    484 
    485   /* How many to move to the left */
    486   right_elements_in_bytes = (vector->size - index - 1) * vector->element_size;
    487 
    488   // memmove(offset, offset + vector->element_size, right_elements_in_bytes);
    489   memmove(offset, (unsigned char *)offset + vector->element_size,
    490           right_elements_in_bytes);
    491 }
    492 
    493 int _vector_adjust_capacity(Vector *vector) {
    494   return _vector_reallocate(vector,
    495                             MAX(1, vector->size * VECTOR_GROWTH_FACTOR));
    496 }
    497 
    498 int _vector_reallocate(Vector *vector, size_t new_capacity) {
    499   size_t new_capacity_in_bytes;
    500   void *old;
    501   assert(vector != NULL);
    502 
    503   if (new_capacity < VECTOR_MINIMUM_CAPACITY) {
    504     if (vector->capacity > VECTOR_MINIMUM_CAPACITY) {
    505       new_capacity = VECTOR_MINIMUM_CAPACITY;
    506     } else {
    507       /* NO-OP */
    508       return VECTOR_SUCCESS;
    509     }
    510   }
    511 
    512   new_capacity_in_bytes = new_capacity * vector->element_size;
    513   old = vector->data;
    514 
    515   if ((vector->data = malloc(new_capacity_in_bytes)) == NULL) {
    516     return VECTOR_ERROR;
    517   }
    518 
    519 #ifdef __STDC_LIB_EXT1__
    520   /* clang-format off */
    521     if (memcpy_s(vector->data,
    522                              new_capacity_in_bytes,
    523                              old,
    524                              aom_vector_byte_size(vector)) != 0) {
    525         return VECTOR_ERROR;
    526     }
    527 /* clang-format on */
    528 #else
    529   memcpy(vector->data, old, aom_vector_byte_size(vector));
    530 #endif
    531 
    532   vector->capacity = new_capacity;
    533 
    534   free(old);
    535 
    536   return VECTOR_SUCCESS;
    537 }
    538 
    539 void _vector_swap(size_t *first, size_t *second) {
    540   size_t temp = *first;
    541   *first = *second;
    542   *second = temp;
    543 }
    544