libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_array_map.h
Go to the documentation of this file.
1/*! \file
2 * \brief ::GblArrayMap container and related functions
3 * \ingroup containers
4 * \copydoc GblArrayMap
5 *
6 * \bug
7 * - Extracting the last item will still invoke its destructor!
8 *
9 * \author Falco Girgis
10 */
11#ifndef GIMBAL_ARRAY_MAP_H
12#define GIMBAL_ARRAY_MAP_H
13
14#include "../core/gimbal_typedefs.h"
15#include "../strings/gimbal_quark.h"
16#include "../meta/types/gimbal_variant.h"
17#include "../core/gimbal_result.h"
18
19#define GBL_ARRAY_MAP_NPOS GBL_NPOS //!< Invalid index identifier returned when an entry couldn't be found
20#define GBL_ARRAY_MAP_SIZE(elements) (sizeof(GblArrayMap) + (sizeof(GblArrayMapEntry)*(elements))) //!< Calculates total size of the GblArrayMap structure with elements
21#define GBL_ARRAY_MAP_BINARY_SEARCH_CUTOFF_SIZE 40 //!< Magical break-even point for when binary searches out-perform linear searches, based on profiling
22
23#define GBL_PSELF GblArrayMap** ppSelf
24#define GBL_PCSELF GblArrayMap*const* ppSelf
25
27
28GBL_FORWARD_DECLARE_STRUCT(GblArrayMapEntry);
30
31typedef GBL_RESULT (*GblArrayMapDtorFn)(const GblArrayMap*, uintptr_t key, void* pEntry); //!< Custom destructor type for userdata values
32typedef int (*GblArrayMapCmpFn) (const GblArrayMap*, uintptr_t key1, uintptr_t key2); //!< Custom comparator for nontrivial key types
33
34/*! Represents a single K,V data entry within a GblArrayMap
35 *
36 * \note
37 * The destructor field is only used for userdata values, while
38 * GblVariant values have automatic lifetime management.
39 *
40 * \sa GblArrayMap
41 */
42typedef struct GblArrayMapEntry {
43 uintptr_t key; //!< Opaque key value
44 GblVariant value; //!< Using value.type == GBL_INVALID_TYPE to signify userdata
45 GblArrayMapDtorFn dtor; //!< Optional custom destructor for userdata types
46} GblArrayMapEntry;
47
48/*! Dynamic array-based [K,V] pair associative container
49 * \ingroup containers
50 *
51 * Contiguous array-based associative container with [K,V] pairs.
52 * GblArrayMap is essentially a flat map structure with a few specific
53 * properties:
54 *
55 * - Value types can either be uinptr_t userdata or typed GblVariants
56 * - Userdata types can have per-entry custom destructors
57 * - For non-trivial key types, a custom comparator can be specified
58 * - insertion and searching can either be done sorted in a binary search or unsorted linearly
59 *
60 * \note
61 * GblArrayMap is a lazily-allocated structure, meaning it isn't actually allocated until it's
62 * needed. This is why the majority of the API takes a pointer to a pointer, so a NULL pointer
63 * value is a valid empty map. You can optionally preconstruct the structure with GblArrayMap_create.
64 *
65 * \sa GblArrayMapEntry
66 */
67typedef struct GblArrayMap {
69 GblContext* pCtx; //!< Optional custom context
70 GblArrayMapCmpFn pFnComparator; //!< Optional custom comparator
71 size_t binarySearches : 1; //!< Optionally sort values and use binary searches
72#ifdef GBL_64BIT
73 size_t size : 63; //!< Number of elements within the map
74#elif defined(GBL_32BIT)
75 size_t size : 31;
76#endif
78} GblArrayMap;
79
80//! Pre-creates a GblArrayMap with the given comparator, binary search config, and context.
82 GblBool binarySearch,
83 GblContext* pCtx) GBL_NOEXCEPT;
84//! Destroys a GblArrayMap.
86//! Returns the number of entries within the given map.
88//! Returns the context associated with the given map.
90//! Returns whether the given map is empty.
92//! Returns whether the given map is sorted and uses binary searches.
94//! Returns true if the given map contains the given key.
96//! Returns true if the given map contains the given key, associated with a userdata value.
98//! Returns true if the given map contains the given key, associated with a GblVariant value.
100//! Returns the GblVariant or userdata value associated with the given key as a uintptr_t.
102//! Returns the GblVariant associated with the given key.
104//! Returns the GblVariant or userdata value associated with the given key, erroring if not found.
106//! Returns the GblVariant associated with the given key, erroring if not found.
108//! Inserts or replaces the entry with the given key with a userdata value and optional destructor.
110 uintptr_t key,
111 uintptr_t value,
112 GblArrayMapDtorFn pDtor) GBL_NOEXCEPT;
113//! Inserts or replaces the entry with the given key with a GblVariant.
115 uintptr_t key,
116 GblVariant* pVariant) GBL_NOEXCEPT;
117//! Attempts to insert a new entry with the given key and userdata, returning the insertion index.
119 uintptr_t key,
120 uintptr_t value,
121 GblArrayMapDtorFn pDtor) GBL_NOEXCEPT;
122//! Attempts to insert a new entry with the given key and GblVariant value, returning insertion index.
124 uintptr_t key,
125 GblVariant* pVariant) GBL_NOEXCEPT;
126//! Attempts to erase the value with the given key, returning GBL_FALSE if not found.
128//! Attempts to remove the GblVariant with the given key, moving it into the given pointer if found.
130 uintptr_t key,
131 GblVariant* pVariant) GBL_NOEXCEPT;
132//! Attempts to remove the value with the given key, moving it into the given pointer if found.
134 uintptr_t key,
135 uintptr_t* pValue) GBL_NOEXCEPT;
136//! Clears all entries within the given map.
138//! Returns the index of the entry with the given key.
140//! Returns the key for the entry at the given index.
142//! Returns the value for the entry at the given index.
144//! Returns the GblVariant for the entry at the given index.
146
148
149/*!
150 * \fn GblArrayMap* GblArrayMap_create(GblArrayMapCmpFn pFnComparator, GblBool binarySearches, GblContext* pCtx)
151 * \param pFnComparator
152 * \param binarySearches
153 * \param pCtx
154 * \return pointer to a new GblArrayMap
155 * \relatedalso GblArrayMap
156 */
157/*!
158 * \fn GBL_RESULT GblArrayMap_destroy(GblArrayMap** ppSelf)
159 * \param ppSelf
160 * \return GBL_RESULT_SUCCESS or error code upon failure
161 * \relatedalso GblArrayMap
162 */
163/*!
164 * \fn GblBool GblArrayMap_erase(GblArrayMap** ppSelf, uintptr_t key)
165 * \param ppSelf
166 * \param key
167 * \return GBL_TRUE if the entry with the given key was removed.
168 * \relatedalso GblArrayMap
169 */
170/*!
171 * \fn GblBool GblArrayMap_extractVariant(GblArrayMap** ppSelf, uintptr_t key, GblVariant* pVariant)
172 * \param ppSelf
173 * \param key
174 * \param pVariant
175 * \return GBL_TRUE if the given variant was extracted
176 * \relatesalso GblArrayMap
177 */
178/*!
179 * \fn GblBool GblArrayMap_extractValue(GblArrayMap** ppSelf, uintptr_t key, uintptr_t* pValue)
180 * \param ppSelf
181 * \param key
182 * \param pValue
183 * \return GBL_TRUE if the given value was successfully extracted
184 * \relatedalso GblArrayMap
185 */
186/*!
187 * \fn void GblArrayMap_clear(GblArrayMap** ppSelf)
188 * \param ppSelf
189 * \relatedalso GblArrayMap
190 */
191
192
193#undef GBL_PCSELF
194#undef GBL_PSELF
195
196#endif // GIMBAL_ARRAY_MAP_HPP
GblBool GblArrayMap_empty(GblArrayMap *const *ppSelf)
Returns whether the given map is empty.
GBL_RESULT GblArrayMap_destroy(GblArrayMap **ppSelf)
Destroys a GblArrayMap.
uintptr_t GblArrayMap_atValue(GblArrayMap *const *ppSelf, uintptr_t key)
Returns the GblVariant or userdata value associated with the given key, erroring if not found.
#define GBL_PSELF
size_t GblArrayMap_size(GblArrayMap *const *ppSelf)
Returns the number of entries within the given map.
GblContext * GblArrayMap_context(GblArrayMap *const *ppSelf)
Returns the context associated with the given map.
#define GBL_PCSELF
size_t GblArrayMap_insertUserdata(GblArrayMap **ppSelf, uintptr_t key, uintptr_t value, GblArrayMapDtorFn pDtor)
Attempts to insert a new entry with the given key and userdata, returning the insertion index.
GblVariant * GblArrayMap_getVariant(GblArrayMap *const *ppSelf, uintptr_t key)
Returns the GblVariant associated with the given key.
GblBool GblArrayMap_extractVariant(GblArrayMap **ppSelf, uintptr_t key, GblVariant *pVariant)
Attempts to remove the GblVariant with the given key, moving it into the given pointer if found.
GBL_RESULT GblArrayMap_setUserdata(GblArrayMap **ppSelf, uintptr_t key, uintptr_t value, GblArrayMapDtorFn pDtor)
Inserts or replaces the entry with the given key with a userdata value and optional destructor.
GblBool GblArrayMap_contains(GblArrayMap *const *ppSelf, uintptr_t key)
Returns true if the given map contains the given key.
GblArrayMap * GblArrayMap_create(GblArrayMapCmpFn pFnComp, GblBool binarySearch, GblContext *pCtx)
Pre-creates a GblArrayMap with the given comparator, binary search config, and context.
size_t GblArrayMap_insertVariant(GblArrayMap **ppSelf, uintptr_t key, GblVariant *pVariant)
Attempts to insert a new entry with the given key and GblVariant value, returning insertion index.
GblBool GblArrayMap_extractValue(GblArrayMap **ppSelf, uintptr_t key, uintptr_t *pValue)
Attempts to remove the value with the given key, moving it into the given pointer if found.
GblVariant * GblArrayMap_atVariant(GblArrayMap *const *ppSelf, uintptr_t key)
Returns the GblVariant associated with the given key, erroring if not found.
GblVariant * GblArrayMap_probeVariant(GblArrayMap *const *ppSelf, size_t index)
Returns the GblVariant for the entry at the given index.
size_t GblArrayMap_find(GblArrayMap *const *ppSelf, uintptr_t key)
Returns the index of the entry with the given key.
GBL_RESULT GblArrayMap_setVariant(GblArrayMap **ppSelf, uintptr_t key, GblVariant *pVariant)
Inserts or replaces the entry with the given key with a GblVariant.
uintptr_t GblArrayMap_probeKey(GblArrayMap *const *ppSelf, size_t index)
Returns the key for the entry at the given index.
GblBool GblArrayMap_binarySearches(GblArrayMap *const *ppSelf)
Returns whether the given map is sorted and uses binary searches.
uintptr_t GblArrayMap_probeValue(GblArrayMap *const *ppSelf, size_t index)
Returns the value for the entry at the given index.
GblBool GblArrayMap_containsVariant(GblArrayMap *const *ppSelf, uintptr_t key)
Returns true if the given map contains the given key, associated with a GblVariant value.
void GblArrayMap_clear(GblArrayMap **ppSelf)
Clears all entries within the given map.
int(* GblArrayMapCmpFn)(const GblArrayMap *, uintptr_t key1, uintptr_t key2)
Custom comparator for nontrivial key types.
GblBool GblArrayMap_erase(GblArrayMap **ppSelf, uintptr_t key)
Attempts to erase the value with the given key, returning GBL_FALSE if not found.
GblBool GblArrayMap_containsUserdata(GblArrayMap *const *ppSelf, uintptr_t key)
Returns true if the given map contains the given key, associated with a userdata value.
uintptr_t GblArrayMap_getValue(GblArrayMap *const *ppSelf, uintptr_t key)
Returns the GblVariant or userdata value associated with the given key as a uintptr_t.
#define GBL_NOEXCEPT
#define GBL_DECLS_BEGIN
#define GBL_FORWARD_DECLARE_STRUCT(S)
#define GBL_PRIVATE_BEGIN
#define GBL_EXPORT
#define GBL_PRIVATE_END
Private data structure.
uint8_t GblBool
Basic boolean type, standardized to sizeof(char)
#define GBL_NPOS
Represents a single K,V data entry within a GblArrayMap.
GblVariant value
Using value.type == GBL_INVALID_TYPE to signify userdata.
uintptr_t key
Opaque key value.
GblArrayMapDtorFn dtor
Optional custom destructor for userdata types.
Dynamic array-based [K,V] pair associative container.
GblArrayMapCmpFn pFnComparator
Optional custom comparator.
GblContext * pCtx
Optional custom context.
size_t binarySearches
Optionally sort values and use binary searches.
size_t size
Number of elements within the map.