736 lines
24 KiB
C
736 lines
24 KiB
C
/**
|
|
* @file kMap.h
|
|
* @brief Declares the kMap class.
|
|
*
|
|
* @internal
|
|
* Copyright (C) 2012-2021 by LMI Technologies Inc.
|
|
* Licensed under the MIT License.
|
|
* Redistributed files must retain the above copyright notice.
|
|
*/
|
|
#ifndef K_API_MAP_H
|
|
#define K_API_MAP_H
|
|
|
|
#include <kApi/kApiDef.h>
|
|
|
|
/**
|
|
* @class kMap
|
|
* @extends kObject
|
|
* @ingroup kApi-Data
|
|
* @brief Represents a collection of key-value pairs stored in a hash table.
|
|
*
|
|
* The kMap class represents a hash table of key-value pairs. The kMap constructor accepts kType arguments that determine
|
|
* the key type and value type.
|
|
*
|
|
* The map will automatically grow as new items are inserted. The size of the internal bucket array is always
|
|
* a power of two and secondary hashing is not performed on keys. This places the burden on the caller to ensure
|
|
* that keys have roughly uniform distribution, else clustering may occur. If in doubt, consider installing
|
|
* a custom hash function (via kMap_SetHashFx) to ensure good key distribution.
|
|
*
|
|
* The following example illustrates how to construct a kMap instance, populate it, and access elements.
|
|
*
|
|
@code {.c}
|
|
kStatus MapExample()
|
|
{
|
|
kMap map = kNULL;
|
|
kText32 keys[] = { "one", "two", "three", "four", "five" };
|
|
k32s values[] = { 1, 2, 3, 4, 5 };
|
|
k32s result = 0;
|
|
kMapItem resultIt = kNULL; //map iterator
|
|
kSize i;
|
|
kMapItem it = kNULL; //map iterator
|
|
|
|
kTry
|
|
{
|
|
//create a map that can store small char-array keys and 32-bit integer values
|
|
kTest(kMap_Construct(&map, kTypeOf(kText32), kTypeOf(k32s), 0, kNULL));
|
|
|
|
//add some initial items to the map
|
|
for (i = 0; i < kCountOf(keys); ++i)
|
|
{
|
|
kTest(kMap_Add(map, &keys[i], &values[i]));
|
|
}
|
|
|
|
//perform some queries;
|
|
//kMap_Find looks up a key and returns the value
|
|
if (kSuccess(kMap_Find(map, "three", &result)))
|
|
{
|
|
printf("three: %d\n", result);
|
|
}
|
|
|
|
//kMap_FindItem looks up a key and returns an iterator to the key-value pair
|
|
if (kSuccess(kMap_FindItem(map, "four", &resultIt)))
|
|
{
|
|
printf("four: %d\n", kMap_ValueAs_(map, resultIt, k32s));
|
|
}
|
|
|
|
//print some information about the map
|
|
printf("Key type: %s\n", kType_Name(kMap_KeyType(map)));
|
|
printf("Value type: %s\n", kType_Name(kMap_ValueType(map)));
|
|
printf("Count: %u\n", (k32u) kMap_Count(map));
|
|
|
|
//print the map items; note, the items will not be printed in sorted order
|
|
//because kMap is not a sorted collection
|
|
it = kMap_First(map);
|
|
|
|
while (!kIsNull(it))
|
|
{
|
|
const kChar* key = kMap_Key(map, it);
|
|
k32s value = *(k32s*) kMap_Value(map, it);
|
|
|
|
printf("key: %s, value: %d\n", key, value);
|
|
|
|
it = kMap_Next(map, it);
|
|
}
|
|
}
|
|
kFinally
|
|
{
|
|
kObject_Destroy(map);
|
|
|
|
kEndFinally();
|
|
}
|
|
|
|
return kOK;
|
|
}
|
|
@endcode
|
|
*
|
|
* For maps that contain key or value <em>objects</em> (e.g. kString) as opposed to <em>values</em> (e.g. kText32),
|
|
* the objects are not automatically destroyed when the map is destroyed. To recursively destroy both the map and its
|
|
* keys/values, use kObject_Dispose. Similarly, kMap does not automatically dispose key/value objects when they are
|
|
* replaced or cleared from the map.
|
|
*
|
|
@code {.c}
|
|
kStatus MapOfObjectsExample()
|
|
{
|
|
kMap map = kNULL;
|
|
kString keyIn = kNULL;
|
|
kImage valueIn = kNULL;
|
|
kString keyOut = kNULL;
|
|
kImage valueOut = kNULL;
|
|
kImage result = kNULL;
|
|
kMapItem resultIt = kNULL; //map iterator
|
|
kMapItem it = kNULL; //map iterator
|
|
|
|
kTry
|
|
{
|
|
//create a map that can store kString keys and kImage values
|
|
kTest(kMap_Construct(&map, kTypeOf(kString), kTypeOf(kImage), 0, kNULL));
|
|
|
|
//add some initial items to the map
|
|
kTest(kString_Construct(&keyIn, "one", kNULL));
|
|
kTest(kImage_Construct(&valueIn, kTypeOf(k8u), 100, 100, kNULL));
|
|
kTest(kMap_AddT(map, &keyIn, &valueIn));
|
|
keyIn = valueIn = kNULL;
|
|
|
|
kTest(kString_Construct(&keyIn, "two", kNULL));
|
|
kTest(kImage_Construct(&valueIn, kTypeOf(k8u), 200, 200, kNULL));
|
|
kTest(kMap_AddT(map, &keyIn, &valueIn));
|
|
keyIn = valueIn = kNULL;
|
|
|
|
kTest(kString_Construct(&keyIn, "three", kNULL));
|
|
kTest(kImage_Construct(&valueIn, kTypeOf(k8u), 300, 300, kNULL));
|
|
kTest(kMap_AddT(map, &keyIn, &valueIn));
|
|
keyIn = valueIn = kNULL;
|
|
|
|
//perform some queries;
|
|
//kMap_FindT looks up a key and returns the value
|
|
if (kSuccess(kMap_FindT(map, "two", &result)))
|
|
{
|
|
printf("two: width(%u), height(%u)\n", (k32u)kImage_Width(result), (k32u)kImage_Height(result));
|
|
}
|
|
|
|
//kMap_FindItemT looks up a key and returns an iterator to the key-value pair
|
|
if (kSuccess(kMap_FindItemT(map, "one", &resultIt)))
|
|
{
|
|
kImage image = kMap_ValueAsT(map, resultIt, kImage);
|
|
|
|
printf("one: width(%u), height(%u)\n", (k32u)kImage_Width(image), (k32u)kImage_Height(image));
|
|
}
|
|
|
|
//there are several ways to replace a key/value pair, depending on whether it is already known
|
|
//that the key is in the collection, and whether the key/value need to be destroyed/disposed;
|
|
//the approach below first removes and destroys the key/value if they exist, then adds replacements
|
|
if (kSuccess(kMap_RemoveT(map, "one", &keyOut, &valueOut)))
|
|
{
|
|
kObject_Destroy(keyOut);
|
|
kObject_Destroy(valueOut);
|
|
}
|
|
|
|
kTest(kString_Construct(&keyIn, "one", kNULL));
|
|
kTest(kImage_Construct(&valueIn, kTypeOf(k8u), 1000, 1000, kNULL));
|
|
kTest(kMap_AddT(map, &keyIn, &valueIn));
|
|
keyIn = valueIn = kNULL;
|
|
}
|
|
kFinally
|
|
{
|
|
//clean up temp variables, in case of error above
|
|
kObject_Destroy(keyIn);
|
|
kObject_Destroy(valueIn);
|
|
|
|
//dispose map; will destroy internal key/value objects
|
|
kObject_Dispose(map);
|
|
|
|
kEndFinally();
|
|
}
|
|
|
|
return kOK;
|
|
}
|
|
@endcode
|
|
*
|
|
* kMap supports the kObject_Clone, kObject_Dispose, and kObject_Size methods.
|
|
*
|
|
* kMap supports the kdat6 serialization protocol.
|
|
*
|
|
*/
|
|
//typedef kObject kMap; --forward-declared in kApiDef.x.h
|
|
|
|
/**
|
|
* Represents a key-value pair within a map.
|
|
* @typedef kPointer kMapItem
|
|
* @relates kMap
|
|
*/
|
|
typedef kPointer kMapItem;
|
|
|
|
#include <kApi/Data/kMap.x.h>
|
|
|
|
/**
|
|
* Constructs a kMap object.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param keyType Type of map key.
|
|
* @param valueType Type of map value.
|
|
* @param initialCapacity Capacity initially reserved for map items.
|
|
* @param allocator Memory allocator.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_Construct(kMap* map, kType keyType, kType valueType, kSize initialCapacity, kAlloc allocator);
|
|
|
|
/**
|
|
* Reallocates the map.
|
|
*
|
|
* Existing items are discarded.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param keyType Type of map key.
|
|
* @param valueType Type of map value.
|
|
* @param initialCapacity Capacity initially reserved for map items.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_Allocate(kMap map, kType keyType, kType valueType, kSize initialCapacity);
|
|
|
|
/**
|
|
* Performs a shallow copy of the source map.
|
|
*
|
|
* Source key-value pairs are copied by value; if the source map contains objects, the object
|
|
* handles are copied but the objects are not cloned.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param source Map to be copied.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_Assign(kMap map, kMap source);
|
|
|
|
/**
|
|
* Sets a custom key equality comparator.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param function Key equality function (or kNULL to unset).
|
|
* @return Operation status.
|
|
*/
|
|
kInlineFx(kStatus) kMap_SetEqualsFx(kMap map, kEqualsFx function)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
obj->equalsFx = function;
|
|
|
|
return kOK;
|
|
}
|
|
/**
|
|
* Sets a custom hash code generator.
|
|
*
|
|
* Calling this method will cause the existing map keys to be rehashed using
|
|
* using the new hash function. If changing both the equals function and the hash function,
|
|
* change equals first, then hash.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param function Hash code function (or kNULL to unset).
|
|
* @return Operation status.
|
|
*/
|
|
kInlineFx(kStatus) kMap_SetHashFx(kMap map, kHashFx function)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
obj->hashFx = function;
|
|
|
|
kCheck(xkMap_Rehash(map));
|
|
|
|
return kOK;
|
|
}
|
|
|
|
/**
|
|
* Returns the key type.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return Key type.
|
|
*/
|
|
kInlineFx(kType) kMap_KeyType(kMap map)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
return obj->keyField.type;
|
|
}
|
|
|
|
/**
|
|
* Returns the value type.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return Key type.
|
|
*/
|
|
kInlineFx(kType) kMap_ValueType(kMap map)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
return obj->valueField.type;
|
|
}
|
|
|
|
/**
|
|
* Returns the count of map elements.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return Count of elements.
|
|
*/
|
|
kInlineFx(kSize) kMap_Count(kMap map)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
return obj->count;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of elements for which space has been allocated.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return Map capacity, in elements.
|
|
*/
|
|
kInlineFx(kSize) kMap_Capacity(kMap map)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
return obj->capacity;
|
|
}
|
|
|
|
/**
|
|
* Finds the value associated with the given key.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key to be found.
|
|
* @param value Optionally receives value (can be kNULL).
|
|
* @return kOK if found; kERROR_NOT_FOUND if not found.
|
|
*/
|
|
kFx(kStatus) kMap_Find(kMap map, const void* key, void* value);
|
|
|
|
/**
|
|
* Finds the value associated with the given key.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key or value type is not equal to the
|
|
* size of the collection key or value type, respectively.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Strongly-typed pointer to key that should be found.
|
|
* @param VPtr_value Strongly-typed pointer to destination for found value.
|
|
* @return kOK if found; kERROR_NOT_FOUND if not found.
|
|
*/
|
|
#define kMap_FindT(kMap_map, KPtr_key, VPtr_value) \
|
|
xkMap_FindT(kMap_map, KPtr_key, VPtr_value, sizeof(*(KPtr_key)), sizeof(*(VPtr_value)))
|
|
|
|
/**
|
|
* Reports whether the specified key is present in the map.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key.
|
|
* @return kTRUE if found.
|
|
*/
|
|
kInlineFx(kBool) kMap_Has(kMap map, const void* key)
|
|
{
|
|
return kSuccess(kMap_Find(map, key, kNULL));
|
|
}
|
|
|
|
/**
|
|
* Reports whether the specified key is present in the map.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key type is not equal to the
|
|
* size of the collection key type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Strongly-typed pointer to key.
|
|
* @return kTRUE if found.
|
|
*/
|
|
#define kMap_HasT(kMap_map, KPtr_key) \
|
|
xkMap_HasT(kMap_map, KPtr_key, sizeof(*(KPtr_key)))
|
|
|
|
/**
|
|
* Adds a new key-value pair.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key.
|
|
* @param value Pointer to value.
|
|
* @return kOK if added; kERROR_ALREADY_EXISTS if key already present.
|
|
*/
|
|
kFx(kStatus) kMap_Add(kMap map, const void* key, const void* value);
|
|
|
|
/**
|
|
* Adds a new key-value pair.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key or value type is not equal to the
|
|
* size of the collection key or value type, respectively.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Strongly-typed pointer to key.
|
|
* @param VPtr_value Strongly-typed pointer to value.
|
|
* @return kOK if added; kERROR_ALREADY_EXISTS if key already present.
|
|
*/
|
|
#define kMap_AddT(kMap_map, KPtr_key, VPtr_value) \
|
|
xkMap_AddT(kMap_map, KPtr_key, VPtr_value, sizeof(*(KPtr_key)), sizeof(*(VPtr_value)))
|
|
|
|
/**
|
|
* Adds or replaces a key-value pair.
|
|
*
|
|
* For object-based keys or values, the old objects are not automatically disposed. In this case,
|
|
* consider using kMap_Remove to first remove and dispose the existing item, then kMap_Add
|
|
* to add the new item.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key.
|
|
* @param value Pointer to value.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_Replace(kMap map, const void* key, const void* value);
|
|
|
|
/**
|
|
* Adds or replaces a key-value pair.
|
|
*
|
|
* For object-based keys or values, the old objects are not automatically disposed. In this case,
|
|
* consider using kMap_Remove to first remove and dispose the existing item, then kMap_Add
|
|
* to add the new item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key or value type is not equal to the
|
|
* size of the collection key or value type, respectively.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Strongly-typed pointer to key.
|
|
* @param VPtr_value Strongly-typed pointer to value.
|
|
* @return Operation status.
|
|
*/
|
|
#define kMap_ReplaceT(kMap_map, KPtr_key, VPtr_value) \
|
|
xkMap_ReplaceT(kMap_map, KPtr_key, VPtr_value, sizeof(*(KPtr_key)), sizeof(*(VPtr_value)))
|
|
|
|
/**
|
|
* Removes a key-value pair from the map, optionally returning the old key and/or value.
|
|
*
|
|
* For object-based keys or values, the old objects are not automatically disposed. In this case,
|
|
* use the oldKey and/or oldValue parameters to receive the previous object(s) and then dispose
|
|
* them.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key.
|
|
* @param oldKey Optionally receives key (can be kNULL).
|
|
* @param oldValue Optionally receives value (can be kNULL).
|
|
* @return kOK if removed; kERROR_NOT_FOUND if key not found.
|
|
*/
|
|
kFx(kStatus) kMap_Remove(kMap map, const void* key, void* oldKey, void* oldValue);
|
|
|
|
/**
|
|
* Removes a key-value pair from the map, returning the old key and/or value.
|
|
*
|
|
* For object-based keys or values, the old objects are not automatically disposed. In this case,
|
|
* use the oldKey and/or oldValue parameters to receive the previous object(s) and then dispose
|
|
* them.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key or value type is not equal to the
|
|
* size of the collection key or value type, respectively.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Pointer to key.
|
|
* @param KPtr_oldKey Strongly-typed destination pointer to receive old key.
|
|
* @param VPtr_oldValue Strongly-typed destination pointer to receive old value.
|
|
* @return kOK if removed; kERROR_NOT_FOUND if key not found.
|
|
*/
|
|
#define kMap_RemoveT(kMap_map, KPtr_key, KPtr_oldKey, VPtr_oldValue) \
|
|
xkMap_RemoveT(kMap_map, KPtr_key, KPtr_oldKey, VPtr_oldValue, sizeof(*(KPtr_key)), sizeof(*(KPtr_oldKey)), sizeof(*(VPtr_oldValue)))
|
|
|
|
/**
|
|
* Removes a key-value pair from the map.
|
|
*
|
|
* For object-based keys or values, the old objects are not automatically disposed. In this case,
|
|
* kMap_Remove can be used instead to receive the old keys/values.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key.
|
|
* @return kOK if removed; kERROR_NOT_FOUND if key not found.
|
|
*/
|
|
kInlineFx(kStatus) kMap_Discard(kMap map, const void* key)
|
|
{
|
|
return kMap_Remove(map, key, kNULL, kNULL);
|
|
}
|
|
|
|
/**
|
|
* Removes a key-value pair from the map.
|
|
*
|
|
* For object-based keys or values, the old objects are not automatically disposed. In this case,
|
|
* use kMap_Remove instead to access the old keys/values.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key type is not equal to the
|
|
* size of the collection key type.
|
|
*
|
|
* @relates @memberof kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Strongly-typed pointer to key.
|
|
* @return kOK if removed; kERROR_NOT_FOUND if key not found.
|
|
*/
|
|
#define kMap_DiscardT(kMap_map, KPtr_key) \
|
|
xkMap_DiscardT(kMap_map, KPtr_key, sizeof(*(KPtr_key)))
|
|
|
|
/**
|
|
* Ensures that capacity is reserved for at least the specified number of map items.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param capacity Map capacity, in items.
|
|
* @return kOK if removed; kERROR_NOT_FOUND if key not found.
|
|
*/
|
|
kFx(kStatus) kMap_Reserve(kMap map, kSize capacity);
|
|
|
|
/**
|
|
* Sets the count of map items to zero.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_Clear(kMap map);
|
|
|
|
/**
|
|
* Disposes any elements in the map and sets the count of map items to zero.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_Purge(kMap map);
|
|
|
|
/**
|
|
* Gets a reference to the first map item (key-value pair).
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @return First map item, or kNULL.
|
|
*/
|
|
kFx(kMapItem) kMap_First(kMap map);
|
|
|
|
/**
|
|
* Given a map item, gets a reference to the next map item.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param item Map item.
|
|
* @return Next map item, or kNULL.
|
|
*/
|
|
kFx(kMapItem) kMap_Next(kMap map, kMapItem item);
|
|
|
|
/**
|
|
* Finds the map item associated with the given key.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param key Pointer to key.
|
|
* @param item Optionally receives map item (can be kNULL).
|
|
* @return kOK if found; kERROR_NOT_FOUND if not found.
|
|
*/
|
|
kFx(kStatus) kMap_FindItem(kMap map, const void* key, kMapItem* item);
|
|
|
|
/**
|
|
* Finds the map item associated with the given key.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key type is not equal to the
|
|
* size of the collection key type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param KPtr_key Strongly-typed pointer to key.
|
|
* @param kMapItemPtr_item Optionally receives map item (can be kNULL).
|
|
* @return kOK if found; kERROR_NOT_FOUND if not found.
|
|
*/
|
|
#define kMap_FindItemT(kMap_map, KPtr_key, kMapItemPtr_item) \
|
|
xkMap_FindItemT(kMap_map, KPtr_key, kMapItemPtr_item, sizeof(*(KPtr_key)))
|
|
|
|
/**
|
|
* Removes an item from the map.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param item Map item.
|
|
* @return Operation status.
|
|
*/
|
|
kFx(kStatus) kMap_RemoveItem(kMap map, kMapItem item);
|
|
|
|
/**
|
|
* Returns a pointer to the key associated with a map item.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param item Map item.
|
|
* @return Pointer to key.
|
|
*/
|
|
kInlineFx(const void*) kMap_Key(kMap map, kMapItem item)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
return kPointer_ByteOffset(item, (kSSize)obj->keyField.offset);
|
|
}
|
|
|
|
/**
|
|
* Returns a strongly-typed pointer to the key associated with a map item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key type is not equal to the
|
|
* size of the collection key type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param kMapItem_item Map item.
|
|
* @param K Key type identifier (e.g., k32s).
|
|
* @return Strongly-typed pointer to key.
|
|
*/
|
|
#define kMap_KeyT(kMap_map, kMapItem_item, K) \
|
|
kCast(K*, xkMap_KeyT(kMap_map, kMapItem_item, sizeof(K)))
|
|
|
|
/**
|
|
* Gets the key associated with a map item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified key type is not equal to the
|
|
* size of the collection key type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param kMapItem_item Map item.
|
|
* @param K Key type identifier (e.g., k32s).
|
|
* @return Key content.
|
|
*/
|
|
#define kMap_KeyAsT(kMap_map, kMapItem_item, K) \
|
|
kPointer_ReadAs(xkMap_KeyAsT(kMap_map, kMapItem_item, sizeof(K)), K)
|
|
|
|
/**
|
|
* Returns a pointer to the value associated with a map item.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param item Map item.
|
|
* @return Pointer to value.
|
|
*/
|
|
kInlineFx(void*) kMap_Value(kMap map, kMapItem item)
|
|
{
|
|
kObj(kMap, map);
|
|
|
|
return kPointer_ByteOffset(item, (kSSize)obj->valueField.offset);
|
|
}
|
|
|
|
/**
|
|
* Returns a strongly-typed pointer to the value associated with a map item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified value type is not equal to the
|
|
* size of the collection value type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param kMapItem_item Map item.
|
|
* @param V Value type identifier (e.g., k32s).
|
|
* @return Strongly-typed pointer to value.
|
|
*/
|
|
#define kMap_ValueT(kMap_map, kMapItem_item, V) \
|
|
kCast(V*, xkMap_ValueT(kMap_map, kMapItem_item, sizeof(V)))
|
|
|
|
/**
|
|
* Sets the value associated with a map item.
|
|
*
|
|
* @public @memberof kMap
|
|
* @param map Map object.
|
|
* @param item Map item.
|
|
* @param value Pointer to value to be copied into the map item.
|
|
* @return Operation status.
|
|
*/
|
|
kInlineFx(kStatus) kMap_SetValue(kMap map, kMapItem item, const void* value)
|
|
{
|
|
kObj(kMap, map);
|
|
void* valueSlot = kMap_Value(map, item);
|
|
|
|
kValue_Import(obj->valueField.type, valueSlot, value);
|
|
|
|
return kOK;
|
|
}
|
|
|
|
/**
|
|
* Sets the value associated with a map item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified value type is not equal to the
|
|
* size of the collection value type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param kMapItem_item Map item.
|
|
* @param VPtr_value Strongly-typed pointer to value to be copied into the map item.
|
|
* @return Operation status.
|
|
*/
|
|
#define kMap_SetValueT(kMap_map, kMapItem_item, VPtr_value) \
|
|
xkMap_SetValueT(kMap_map, kMapItem_item, VPtr_value, sizeof(*(VPtr_value)))
|
|
|
|
/**
|
|
* Sets the value associated with a map item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified value type is not equal to the
|
|
* size of the collection value type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param kMapItem_item Map item.
|
|
* @param V_value Item value.
|
|
* @param V Value type identifier (e.g., k32s).
|
|
* @return Value content.
|
|
*/
|
|
#define kMap_SetValueAsT(kMap_map, kMapItem_item, V_value, V) \
|
|
(kPointer_WriteAs(xkMap_ValueAsT(kMap_map, kMapItem_item, sizeof(V)), V_value, V), (void)0)
|
|
|
|
/**
|
|
* Gets the value associated with a map item.
|
|
*
|
|
* A debug assertion will be raised if the size of the specified value type is not equal to the
|
|
* size of the collection value type.
|
|
*
|
|
* @relates kMap
|
|
* @param kMap_map Map object.
|
|
* @param kMapItem_item Map item.
|
|
* @param V Value type identifier (e.g., k32s).
|
|
* @return Value content.
|
|
*/
|
|
#define kMap_ValueAsT(kMap_map, kMapItem_item, V) \
|
|
kPointer_ReadAs(xkMap_ValueAsT(kMap_map, kMapItem_item, sizeof(V)), V)
|
|
|
|
#endif
|