quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

ares_array.h (12106B)


      1 /* MIT License
      2  *
      3  * Copyright (c) 2024 Brad House
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a copy
      6  * of this software and associated documentation files (the "Software"), to deal
      7  * in the Software without restriction, including without limitation the rights
      8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9  * copies of the Software, and to permit persons to whom the Software is
     10  * furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *
     24  * SPDX-License-Identifier: MIT
     25  */
     26 #ifndef __ARES__ARRAY_H
     27 #define __ARES__ARRAY_H
     28 
     29 #include "ares.h"
     30 
     31 /*! \addtogroup ares_array Array Data Structure
     32  *
     33  * This is an array with helpers.  It is meant to have as little overhead
     34  * as possible over direct array management by applications but to provide
     35  * safety and some optimization features.  It can also return the array in
     36  * native form once all manipulation has been performed.
     37  *
     38  * @{
     39  */
     40 
     41 struct ares_array;
     42 
     43 /*! Opaque data structure for array */
     44 typedef struct ares_array ares_array_t;
     45 
     46 /*! Callback to free user-defined member data
     47  *
     48  *  \param[in] data  pointer to member of array to be destroyed. The pointer
     49  *                   itself must not be destroyed, just the data it contains.
     50  */
     51 typedef void (*ares_array_destructor_t)(void *data);
     52 
     53 /*! Callback to compare two array elements used for sorting
     54  *
     55  *  \param[in] data1 array member 1
     56  *  \param[in] data2 array member 2
     57  *  \return < 0 if data1 < data2, > 0 if data1 > data2, 0 if data1 == data2
     58  */
     59 typedef int (*ares_array_cmp_t)(const void *data1, const void *data2);
     60 
     61 /*! Create an array object
     62  *
     63  *  NOTE: members of the array are typically going to be an going to be a
     64  *        struct with compiler/ABI specific padding to ensure proper alignment.
     65  *        Care needs to be taken if using primitive types, especially floating
     66  *        point numbers which size may not indicate the required alignment.
     67  *        For example, a double may be 80 bits (10 bytes), but required
     68  *        alignment of 16 bytes.  In such a case, a member_size of 16 would be
     69  *        required to be used.
     70  *
     71  *  \param[in] destruct     Optional. Destructor to call on a removed member
     72  *  \param[in] member_size  Size of array member, usually determined using
     73  *                          sizeof() for the member such as a struct.
     74  *
     75  *  \return array object or NULL on out of memory
     76  */
     77 CARES_EXTERN ares_array_t *ares_array_create(size_t member_size,
     78                                              ares_array_destructor_t destruct);
     79 
     80 
     81 /*! Request the array be at least the requested size.  Useful if the desired
     82  *  array size is known prior to populating the array to prevent reallocations.
     83  *
     84  *  \param[in] arr  Initialized array object.
     85  *  \param[in] size Minimum number of members
     86  *  \return ARES_SUCCESS on success, ARES_EFORMERR on misuse,
     87  *    ARES_ENOMEM on out of memory */
     88 CARES_EXTERN ares_status_t ares_array_set_size(ares_array_t *arr, size_t size);
     89 
     90 /*! Sort the array using the given comparison function.  This is not
     91  *  persistent, any future elements inserted will not maintain this sort.
     92  *
     93  *  \param[in]  arr      Initialized array object.
     94  *  \param[in]  cb       Sort callback
     95  *  \return ARES_SUCCESS on success
     96  */
     97 CARES_EXTERN ares_status_t ares_array_sort(ares_array_t    *arr,
     98                                            ares_array_cmp_t cmp);
     99 
    100 /*! Destroy an array object.  If a destructor is set, will be called on each
    101  *  member of the array.
    102  *
    103  *  \param[in] arr     Initialized array object.
    104  */
    105 CARES_EXTERN void          ares_array_destroy(ares_array_t *arr);
    106 
    107 /*! Retrieve the array in the native format.  This will also destroy the
    108  *  container.  It is the responsibility of the caller to free the returned
    109  *  pointer and also any data within each array element.
    110  *
    111  *  \param[in] arr  Initialized array object
    112  *  \param[out] num_members the number of members in the returned array
    113  *  \return pointer to native array on success, NULL on failure.
    114  */
    115 CARES_EXTERN void  *ares_array_finish(ares_array_t *arr, size_t *num_members);
    116 
    117 /*! Retrieve the number of members in the array
    118  *
    119  *  \param[in] arr     Initialized array object.
    120  *  \return numbrer of members
    121  */
    122 CARES_EXTERN size_t ares_array_len(const ares_array_t *arr);
    123 
    124 /*! Insert a new array member at the given index
    125  *
    126  *  \param[out] elem_ptr Optional. Pointer to the returned array element.
    127  *  \param[in]  arr      Initialized array object.
    128  *  \param[in]  idx      Index in array to place new element, will shift any
    129  *                       elements down that exist after this point.
    130  *  \return ARES_SUCCESS on success, ARES_EFORMERR on bad index,
    131  *          ARES_ENOMEM on out of memory.
    132  */
    133 CARES_EXTERN ares_status_t ares_array_insert_at(void        **elem_ptr,
    134                                                 ares_array_t *arr, size_t idx);
    135 
    136 /*! Insert a new array member at the end of the array
    137  *
    138  *  \param[out] elem_ptr Optional. Pointer to the returned array element.
    139  *  \param[in]  arr      Initialized array object.
    140  *  \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory.
    141  */
    142 CARES_EXTERN ares_status_t ares_array_insert_last(void        **elem_ptr,
    143                                                   ares_array_t *arr);
    144 
    145 /*! Insert a new array member at the beginning of the array
    146  *
    147  *  \param[out] elem_ptr Optional. Pointer to the returned array element.
    148  *  \param[in]  arr      Initialized array object.
    149  *  \return ARES_SUCCESS on success, ARES_ENOMEM on out of memory.
    150  */
    151 CARES_EXTERN ares_status_t ares_array_insert_first(void        **elem_ptr,
    152                                                    ares_array_t *arr);
    153 
    154 
    155 /*! Insert a new array member at the given index and copy the data pointed
    156  *  to by the data pointer into the array.  This will copy member_size bytes
    157  *  from the provided pointer, this may not be safe for some data types
    158  *  that may have a smaller size than the provided member_size which includes
    159  *  padding as discussed in ares_array_create().
    160  *
    161  *  \param[in]  arr      Initialized array object.
    162  *  \param[in]  idx      Index in array to place new element, will shift any
    163  *                       elements down that exist after this point.
    164  *  \param[in]  data_ptr Pointer to data to copy into array.
    165  *  \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data
    166  * ptr, ARES_ENOMEM on out of memory.
    167  */
    168 CARES_EXTERN ares_status_t ares_array_insertdata_at(ares_array_t *arr,
    169                                                     size_t        idx,
    170                                                     const void   *data_ptr);
    171 
    172 /*! Insert a new array member at the end of the array and copy the data pointed
    173  *  to by the data pointer into the array.  This will copy member_size bytes
    174  *  from the provided pointer, this may not be safe for some data types
    175  *  that may have a smaller size than the provided member_size which includes
    176  *  padding as discussed in ares_array_create().
    177  *
    178  *  \param[in]  arr      Initialized array object.
    179  *  \param[in]  data_ptr Pointer to data to copy into array.
    180  *  \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data
    181  * ptr, ARES_ENOMEM on out of memory.
    182  */
    183 CARES_EXTERN ares_status_t ares_array_insertdata_last(ares_array_t *arr,
    184                                                       const void   *data_ptr);
    185 
    186 /*! Insert a new array member at the beginning of the array and copy the data
    187  * pointed to by the data pointer into the array.  This will copy member_size
    188  * bytes from the provided pointer, this may not be safe for some data types
    189  *  that may have a smaller size than the provided member_size which includes
    190  *  padding as discussed in ares_array_create().
    191  *
    192  *  \param[in]  arr      Initialized array object.
    193  *  \param[in]  data_ptr Pointer to data to copy into array.
    194  *  \return ARES_SUCCESS on success, ARES_EFORMERR on bad index or null data
    195  * ptr, ARES_ENOMEM on out of memory.
    196  */
    197 CARES_EXTERN ares_status_t ares_array_insertdata_first(ares_array_t *arr,
    198                                                        const void   *data_ptr);
    199 
    200 /*! Fetch a pointer to the given element in the array
    201  *  \param[in]  array  Initialized array object
    202  *  \param[in]  idx    Index to fetch
    203  *  \return pointer on success, NULL on failure */
    204 CARES_EXTERN void         *ares_array_at(ares_array_t *arr, size_t idx);
    205 
    206 /*! Fetch a pointer to the first element in the array
    207  *  \param[in]  array  Initialized array object
    208  *  \return pointer on success, NULL on failure */
    209 CARES_EXTERN void         *ares_array_first(ares_array_t *arr);
    210 
    211 /*! Fetch a pointer to the last element in the array
    212  *  \param[in]  array  Initialized array object
    213  *  \return pointer on success, NULL on failure */
    214 CARES_EXTERN void         *ares_array_last(ares_array_t *arr);
    215 
    216 /*! Fetch a constant pointer to the given element in the array
    217  *  \param[in]  array  Initialized array object
    218  *  \param[in]  idx    Index to fetch
    219  *  \return pointer on success, NULL on failure */
    220 CARES_EXTERN const void   *ares_array_at_const(const ares_array_t *arr,
    221                                                size_t              idx);
    222 
    223 /*! Fetch a constant pointer to the first element in the array
    224  *  \param[in]  array  Initialized array object
    225  *  \return pointer on success, NULL on failure */
    226 CARES_EXTERN const void   *ares_array_first_const(const ares_array_t *arr);
    227 
    228 /*! Fetch a constant pointer to the last element in the array
    229  *  \param[in]  array  Initialized array object
    230  *  \return pointer on success, NULL on failure */
    231 CARES_EXTERN const void   *ares_array_last_const(const ares_array_t *arr);
    232 
    233 /*! Claim the data from the specified array index, copying it to the buffer
    234  *  provided by the caller.  The index specified in the array will then be
    235  *  removed (without calling any possible destructor)
    236  *
    237  *  \param[in,out] dest      Optional. Buffer to hold array member. Pass NULL
    238  *                           if not needed.  This could leak memory if array
    239  *                           member needs destructor if not provided.
    240  *  \param[in]     dest_size Size of buffer provided, used as a sanity check.
    241  *                           Must match member_size provided to
    242  *                           ares_array_create() if dest_size specified.
    243  *  \param[in]     arr       Initialized array object
    244  *  \param[in]     idx       Index to claim
    245  *  \return ARES_SUCCESS on success, ARES_EFORMERR on usage failure.
    246  */
    247 CARES_EXTERN ares_status_t ares_array_claim_at(void *dest, size_t dest_size,
    248                                                ares_array_t *arr, size_t idx);
    249 
    250 /*! Remove the member at the specified array index.  The destructor will be
    251  *  called.
    252  *
    253  *  \param[in] arr  Initialized array object
    254  *  \param[in] idx  Index to remove
    255  *  \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use
    256  */
    257 CARES_EXTERN ares_status_t ares_array_remove_at(ares_array_t *arr, size_t idx);
    258 
    259 /*! Remove the first member of the array.
    260  *
    261  *  \param[in] arr  Initialized array object
    262  *  \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use
    263  */
    264 CARES_EXTERN ares_status_t ares_array_remove_first(ares_array_t *arr);
    265 
    266 /*! Remove the last member of the array.
    267  *
    268  *  \param[in] arr  Initialized array object
    269  *  \return ARES_SUCCESS if removed, ARES_EFORMERR on invalid use
    270  */
    271 CARES_EXTERN ares_status_t ares_array_remove_last(ares_array_t *arr);
    272 
    273 
    274 /*! @} */
    275 
    276 #endif /* __ARES__ARRAY_H */