LCOV - code coverage report
Current view: top level - ROOT-Sim/src/datatypes - array.h Hit Total Coverage
Test: doc-coverage.info Lines: 1 25 4.0 %
Date: 2020-02-28 13:00:44

          Line data    Source code
       1           1 : /**
       2             :  *                      Copyright (C) 2008-2018 HPDCS Group
       3             :  *                      http://www.dis.uniroma1.it/~hpdcs
       4             :  *
       5             :  *
       6             :  * This file is part of ROOT-Sim (ROme OpTimistic Simulator).
       7             :  *
       8             :  * ROOT-Sim is free software; you can redistribute it and/or modify it under the
       9             :  * terms of the GNU General Public License as published by the Free Software
      10             :  * Foundation; only version 3 of the License applies.
      11             :  *
      12             :  * ROOT-Sim is distributed in the hope that it will be useful, but WITHOUT ANY
      13             :  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      14             :  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along with
      17             :  * ROOT-Sim; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      19             :  *
      20             :  * @file array.h
      21             :  * @brief This is the implementation of a dynamic array, used for managing various data structures
      22             :  * @author Andrea Piccione
      23             :  * @date 18 June 2018
      24             :  */
      25             : 
      26             : #ifndef ARRAY_H_
      27             : #define ARRAY_H_
      28             : 
      29             : #include <mm/dymelor.h>
      30             : 
      31             : #include <memory.h>
      32             : 
      33             : // TODO: add some type checking and size checking (is it necessary?)
      34             : 
      35           0 : #define INIT_SIZE_ARRAY 8U
      36             : 
      37           0 : #define rootsim_array(type) \
      38             :                 struct { \
      39             :                         type *items; \
      40             :                         unsigned count, capacity; \
      41             :                 }
      42             : 
      43             : // you can use the array to directly index items, but do at your risk and peril
      44           0 : #define array_items(self) ((self).items)
      45             : 
      46           0 : #define array_count(self) ((self).count)
      47             : 
      48           0 : #define array_capacity(self) ((self).capacity)
      49             : 
      50           0 : #define array_shrink(self) ({ \
      51             :                 if (array_count(self) > INIT_SIZE_ARRAY && array_count(self) * 3 <= array_capacity(self)) { \
      52             :                         array_capacity(self) /= 2; \
      53             :                         array_items(self) = rsrealloc(array_items(self), array_capacity(self) * sizeof(*array_items(self))); \
      54             :                 } \
      55             :         })
      56             : 
      57           0 : #define array_expand(self) ({ \
      58             :                 if(array_count(self) >= array_capacity(self)){\
      59             :                         array_capacity(self) *= 2; \
      60             :                         array_items(self) = rsrealloc(array_items(self), array_capacity(self) * sizeof(*array_items(self))); \
      61             :                 } \
      62             :         })
      63             : 
      64           0 : #define array_new(type) ({ \
      65             :                 rootsim_array(type) *__newarr; \
      66             :                 __newarr = rsalloc(sizeof(*__newarr)); \
      67             :                 array_init(*__newarr);\
      68             :                 __newarr; \
      69             :         })
      70             : 
      71           0 : #define array_free(self) ({ \
      72             :                 rsfree(array_items(self)); \
      73             :                 rsfree(&(self)); \
      74             :         })
      75             : 
      76           0 : #define array_init(self) ({ \
      77             :                 array_capacity(self) = INIT_SIZE_ARRAY; \
      78             :                 array_items(self) = rsalloc(array_capacity(self) * sizeof(*array_items(self))); \
      79             :                 array_count(self) = 0; \
      80             :         })
      81             : 
      82           0 : #define array_fini(self) ({ \
      83             :                 rsfree(array_items(self)); \
      84             :         })
      85             : //fixme array_expand doesn't work when reserving with count high since it only doubles once
      86           0 : #define array_reserve(self, count) ({ \
      87             :                 __typeof__(array_count(self)) __rsvidx = array_count(self); \
      88             :                 array_count(self) += (count); \
      89             :                 array_expand(self); \
      90             :                 &(array_items(self)[__rsvidx]); \
      91             : })
      92             : 
      93           0 : #define array_push(self, elem) ({ \
      94             :                 array_expand(self); \
      95             :                 array_items(self)[array_count(self)] = (elem); \
      96             :                 array_count(self)++; \
      97             :         })
      98             : 
      99           0 : #define array_pop(self) ({ \
     100             :                 if(unlikely(!array_count(self))) \
     101             :                         rootsim_error(true, "pop of an empty array"); \
     102             :                 __typeof__(*array_items(self)) __popval; \
     103             :                 array_count(self)--; \
     104             :                 __popval = array_items(self)[array_count(self)]; \
     105             :                 array_shrink(self); \
     106             :                 __popval; \
     107             :         })
     108             : 
     109           0 : #define array_add_at(self, i, elem) ({ \
     110             :                 if(unlikely(array_count(self) <= (i))) \
     111             :                         rootsim_error(true, "out of bound add in a dynamic array"); \
     112             :                 array_expand(self); \
     113             :                 memmove(&(array_items(self)[(i)+1]), &(array_items(self)[(i)]), sizeof(*array_items(self)) * (array_count(self)-(i))); \
     114             :                 array_items(self)[(i)] = (elem); \
     115             :                 array_count(self)++; \
     116             :         })
     117             : 
     118           0 : #define array_lazy_remove_at(self, i) ({ \
     119             :                 if(unlikely(array_count(self) <= (i))) \
     120             :                         rootsim_error(true, "out of bound removal in a dynamic array"); \
     121             :                 __typeof__(*array_items(self)) __rmval; \
     122             :                 array_count(self)--; \
     123             :                 __rmval = array_items(self)[(i)]; \
     124             :                 array_items(self)[(i)] = array_items(self)[array_count(self)]; \
     125             :                 array_shrink(self); \
     126             :                 __rmval; \
     127             :         })
     128             : 
     129           0 : #define array_remove_at(self, i) ({ \
     130             :                 if(unlikely(array_count(self) <= (i))) \
     131             :                         rootsim_error(true, "out of bound removal in a dynamic array"); \
     132             :                 __typeof__(*array_items(self)) __rmval; \
     133             :                 array_count(self)--; \
     134             :                 __rmval = array_items(self)[(i)]; \
     135             :                 memmove(&(array_items(self)[(i)]), &(array_items(self)[(i)+1]), sizeof(*array_items(self)) * (array_count(self)-(i))); \
     136             :                 array_shrink(self); \
     137             :                 __rmval; \
     138             :         })
     139             : 
     140           0 : #define array_remove(self, elem) ({ \
     141             :                 typeof(array_count(self)) __cntr = array_count(self); \
     142             :                 while(__cntr--){ \
     143             :                         if(array_items(self)[__cntr] == (elem)){\
     144             :                                 array_remove_at(self, __cntr); \
     145             :                                 break; \
     146             :                         } \
     147             :                 } \
     148             :         })
     149             : //this isn't checked CARE! TODO add checking
     150           0 : #define array_peek(self) (array_items(self)[array_count(self)-1])
     151             : //this isn't checked CARE! TODO add checking
     152           0 : #define array_get_at(self, i) (array_items(self)[i])
     153             : 
     154           0 : #define array_empty(self) (array_count(self) == 0)
     155             : 
     156           0 : #define array_dump_size(self) ({ \
     157             :                 sizeof(array_count(self)) + array_count(self)*sizeof(*array_items(self)); \
     158             :         })
     159             : 
     160           0 : #define array_dump(self, mem_area) ({ \
     161             :                 memcpy((mem_area), &array_count(self), sizeof(array_count(self))); \
     162             :                 (mem_area) = ((unsigned char *)(mem_area)) + sizeof(array_count(self)); \
     163             :                 memcpy((mem_area), array_items(self), array_count(self) * sizeof(*array_items(self))); \
     164             :                 mem_area = ((unsigned char *)(mem_area)) + array_count(self) * sizeof(*array_items(self)); \
     165             :         })
     166             : 
     167           0 : #define array_load(self, mem_area) ({ \
     168             :                 memcpy(&array_count(self), (mem_area), sizeof(array_count(self))); \
     169             :                 (mem_area) = ((unsigned char *)(mem_area)) + sizeof(array_count(self)); \
     170             :                 array_capacity(self) = max(array_count(self), INIT_SIZE_ARRAY); \
     171             :                 array_items(self) = rsalloc(array_capacity(self) * sizeof(*array_items(self))); \
     172             :                 memcpy(array_items(self), (mem_area), array_count(self) * sizeof(*array_items(self))); \
     173             :                 (mem_area) = ((unsigned char *)(mem_area)) + (array_count(self) * sizeof(*array_items(self))); \
     174             :         })
     175             : 
     176             : #endif /* ARRAY_H_ */

Generated by: LCOV version 1.12