LCOV - code coverage report
Current view: top level - src/plugins/ni/nickel-1.1.0/src/include/bohr - ds_vector.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 13 13 100.0 %
Date: 2019-09-12 12:28:41 Functions: 1 2 50.0 %

          Line data    Source code
       1             : // lgtm [cpp/missing-header-guard]
       2             : 
       3             : /******************************************************************************
       4             :  * Darmstadtium - a library of data structures
       5             :  * Ds_vector - a vector (growable array) library
       6             :  * One of the Bohr Game Libraries (see chaoslizard.org/devel/bohr)
       7             :  * Copyright (C) 2008 Charles Lindsay.  Some rights reserved; see COPYING.
       8             :  * $Id: ds_vector.h 317 2008-01-05 21:45:34Z chaz $
       9             :  ******************************************************************************/
      10             : 
      11             : 
      12             : // You must be careful about including this file multiple times.  Each time it's
      13             : // included in the same source file it must have a different Ds_VECTOR_SUFFIX.
      14             : 
      15             : #include <stddef.h>
      16             : #include <stdint.h>
      17             : #include <stdlib.h>
      18             : #include <string.h>
      19             : 
      20             : #include <kdbhelper.h>
      21             : 
      22             : 
      23             : // Controls inlining of this library's functions.
      24             : #ifndef Ds_VECTOR_INLINE
      25             : #ifdef Ds_INLINE
      26             : #define Ds_VECTOR_INLINE Ds_INLINE
      27             : #else
      28             : #define Ds_VECTOR_INLINE inline static
      29             : #endif
      30             : #endif
      31             : 
      32             : // Nix non-critical C99 keywords in compilers that don't support them.
      33             : #if ((!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) && !defined(restrict))
      34             : #define restrict
      35             : #define _Ds_VECTOR_DEFINED_RESTRICT
      36             : #endif
      37             : 
      38             : 
      39             : // How to grow when the buffer is insufficient.  The following values are
      40             : // available: 1 - the buffer will grow to the exact needed size; 2 - the  buffer
      41             : // will double in size until sufficient (default); or 4 - the buffer will
      42             : // quadruple in size until sufficient.
      43             : #ifndef Ds_VECTOR_BEHAVIOR
      44             : #define Ds_VECTOR_BEHAVIOR 2
      45             : #endif
      46             : 
      47             : // The type stored in Ds_vectors for this instance of the library.
      48             : #ifndef Ds_VECTOR_TYPE
      49             : #define Ds_VECTOR_TYPE int
      50             : #endif
      51             : 
      52             : // Suffix appended to all symbols exported by this header.
      53             : #ifndef Ds_VECTOR_SUFFIX
      54             : #define Ds_VECTOR_SUFFIX
      55             : #endif
      56             : 
      57             : // Macros to make symbols including a defined suffix (there's a seemingly
      58             : // extraneous middle step because it must pass through the macro processor twice
      59             : // to get what Ds_VECTOR_SUFFIX is defined as, instead of "Ds_VECTOR_SUFFIX").
      60             : #define __Ds_VECTOR_SYMBOL_CAT(symbol, suffix) symbol##suffix
      61             : #define _Ds_VECTOR_SYMBOL_CAT(symbol, suffix) __Ds_VECTOR_SYMBOL_CAT (symbol, suffix)
      62             : #define _Ds_VECTOR_SYMBOL(symbol) _Ds_VECTOR_SYMBOL_CAT (symbol, Ds_VECTOR_SUFFIX)
      63             : 
      64             : // Define symbols that in reality have a suffix attached to them.
      65             : #define Ds_vector _Ds_VECTOR_SYMBOL (Ds_vector)
      66             : #define Ds_InitVector _Ds_VECTOR_SYMBOL (Ds_InitVector)
      67             : #define Ds_FreeVector _Ds_VECTOR_SYMBOL (Ds_FreeVector)
      68             : #define Ds_InsertVectorItems _Ds_VECTOR_SYMBOL (Ds_InsertVectorItems)
      69             : #define Ds_RemoveVectorItems _Ds_VECTOR_SYMBOL (Ds_RemoveVectorItems)
      70             : #define Ds_ResizeVector _Ds_VECTOR_SYMBOL (Ds_ResizeVector)
      71             : 
      72             : 
      73             : // Tells Ds_Insert- and RemoveVectorItems() to use the last items in the vector.
      74             : #define Ds_VECTOR_END SIZE_MAX
      75             : 
      76             : 
      77             : // A growable array.
      78             : typedef struct Ds_vector
      79             : {
      80             :         Ds_VECTOR_TYPE * buf; // the memory buffer
      81             :         size_t num;        // how many items in it
      82             :         size_t cap;        // how many items the buffer can hold
      83             : 
      84             : } Ds_vector;
      85             : #define Ds_VECTOR_INIT                                                                                                                     \
      86             :         {                                                                                                                                  \
      87             :                 NULL, 0, 0                                                                                                                 \
      88             :         } // initializer
      89             : 
      90             : 
      91             : /* Reserves an initial capacity for the Ds_vector.  Returns 0/nonzero on
      92             :  * failure/success.
      93             :  */
      94             : Ds_VECTOR_INLINE int Ds_InitVector (Ds_vector * restrict v, size_t cap)
      95             : {
      96        2090 :         *v = (Ds_vector) Ds_VECTOR_INIT;
      97             : 
      98        2090 :         if (cap > 0)
      99             :         {
     100        2193 :                 if (!(v->buf = (Ds_VECTOR_TYPE *) elektraMalloc (cap * sizeof (Ds_VECTOR_TYPE)))) return 0;
     101             : 
     102        2193 :                 v->cap = cap;
     103             :         }
     104             : 
     105             :         return 1;
     106             : }
     107             : 
     108             : /* Frees all memory associated with the Ds_vector.
     109             :  */
     110             : Ds_VECTOR_INLINE void Ds_FreeVector (Ds_vector * restrict v)
     111             : {
     112        2193 :         if (v->buf)
     113             :         {
     114        2193 :                 elektraFree (v->buf);
     115             :         }
     116        2193 :         *v = (Ds_vector) Ds_VECTOR_INIT;
     117             : }
     118             : 
     119             : /* Inserts items somewhere into the Ds_vector.  pos is the 0-based offset to
     120             :  * place the inserted items--use Ds_VECTOR_END to mean the end of the existing
     121             :  * items.  Returns 0/nonzero on failure/success.  The vector won't be modified
     122             :  * if it fails.
     123             :  */
     124             : Ds_VECTOR_INLINE int Ds_InsertVectorItems (Ds_vector * restrict v, const Ds_VECTOR_TYPE * restrict items, size_t num, size_t pos)
     125             : {
     126             :         size_t new_cap;
     127             : 
     128             : #if (Ds_VECTOR_BEHAVIOR == 1)
     129             :         new_cap = v->num + num;
     130             : #else
     131             :         new_cap = (v->cap ? v->cap : 1);
     132             :         while (new_cap < v->num + num)
     133             : #if (Ds_VECTOR_BEHAVIOR == 4)
     134             :                 new_cap <<= 2; // the same as *= 4
     135             : #else
     136             :                 new_cap <<= 1; // the same as *= 2
     137             : #endif
     138             : #endif
     139             :         if (new_cap > v->cap)
     140             :         {
     141             :                 Ds_VECTOR_TYPE * new_buf;
     142             :                 if (!(new_buf = (Ds_VECTOR_TYPE *) realloc (v->buf, new_cap * sizeof (Ds_VECTOR_TYPE))))
     143             :                 {
     144             :                         return 0;
     145             :                 }
     146             :                 v->buf = new_buf;
     147             :                 v->cap = new_cap;
     148             :         }
     149             : 
     150             :         if (pos > v->num)
     151             :                 pos = v->num;
     152             :         else if (pos < v->num)
     153             :         {
     154             :                 memmove (v->buf + pos + num, v->buf + pos, (v->num - pos) * sizeof (Ds_VECTOR_TYPE));
     155             :         }
     156             : 
     157             :         memcpy (v->buf + pos, items, num * sizeof (Ds_VECTOR_TYPE));
     158             :         v->num += num;
     159             : 
     160             :         return 1;
     161             : }
     162             : 
     163             : /* Takes items out of the Ds_vector, optionally copying them to a buffer.
     164             :  */
     165             : Ds_VECTOR_INLINE void Ds_RemoveVectorItems (Ds_vector * restrict v, Ds_VECTOR_TYPE * restrict items, size_t num, size_t pos)
     166             : {
     167             :         if (num > v->num) num = v->num;
     168             :         if (pos > v->num - num) pos = v->num - num;
     169             : 
     170             :         if (items) memcpy (items, v->buf + pos, num * sizeof (Ds_VECTOR_TYPE));
     171             : 
     172             :         if (v->num - num - pos > 0)
     173             :         {
     174             :                 memmove (v->buf + pos, v->buf + num + pos, (v->num - num - pos) * sizeof (Ds_VECTOR_TYPE));
     175             :         }
     176             :         v->num -= num;
     177             : }
     178             : 
     179             : /* Resizes the Ds_vector.  Returns 0/nonzero on failure/success.
     180             :  */
     181           4 : Ds_VECTOR_INLINE int Ds_ResizeVector (Ds_vector * restrict v, size_t cap)
     182             : {
     183           4 :         if (cap > 0)
     184             :         {
     185             :                 Ds_VECTOR_TYPE * new_buf;
     186             : 
     187           4 :                 if (!(new_buf = (Ds_VECTOR_TYPE *) realloc (v->buf, cap * sizeof (Ds_VECTOR_TYPE))))
     188             :                 {
     189             :                         return 0;
     190             :                 }
     191             : 
     192           4 :                 v->buf = new_buf;
     193           4 :                 v->cap = cap;
     194             : 
     195           4 :                 if (v->num > cap) v->num = cap;
     196             :         }
     197             : 
     198             :         return 1;
     199             : }
     200             : 
     201             : 
     202             : // We don't want these internal names clogging up the global namespace.
     203             : #undef Ds_ResizeVector
     204             : #undef Ds_RemoveVectorItems
     205             : #undef Ds_InsertVectorItems
     206             : #undef Ds_FreeVector
     207             : #undef Ds_InitVector
     208             : #undef Ds_vector
     209             : #undef _Ds_VECTOR_SYMBOL
     210             : #undef _Ds_VECTOR_SYMBOL_CAT
     211             : #undef __Ds_VECTOR_SYMBOL_CAT
     212             : 
     213             : // Undefine these so it's easier to change them and include this file again.
     214             : #undef Ds_VECTOR_SUFFIX
     215             : #undef Ds_VECTOR_TYPE
     216             : #undef Ds_VECTOR_BEHAVIOR
     217             : 
     218             : #ifdef _Ds_VECTOR_DEFINED_RESTRICT
     219             : #undef _Ds_VECTOR_DEFINED_RESTRICT
     220             : #undef restrict
     221             : #endif

Generated by: LCOV version 1.13