From a37207e9d7cc887aade6b559f260f60ee5d0cce7 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 26 Apr 2019 23:35:09 -0300 Subject: [PATCH] Added get_ref Gets the reference of a value. Useful for primitive values like int, char, double, size_t, etc. The only collections with this function are associative collections (when getting the value) and lists (working as an update method). Other collections have not received this function because they are either sorted by the values so changing it would break the structure or because removing and adding back again the element is done instantaneously. --- Documentation.md | 20 ++++++++++++++++++++ src/hashmap.h | 11 +++++++++++ src/heap.h | 9 +++++++++ src/linkedlist.h | 17 +++++++++++++++++ src/list.h | 12 ++++++++++++ src/treemap.h | 11 +++++++++++ 6 files changed, 80 insertions(+) diff --git a/Documentation.md b/Documentation.md index 6e54d1d..e2322f6 100644 --- a/Documentation.md +++ b/Documentation.md @@ -86,6 +86,7 @@ Sequences Input / Output * [\_front()](#list_front) * [\_get()](#list_get) +* [\_get_ref()](#list_get_ref) * [\_back()](#list_back) * [\_indexof()](#list_indexof) * [\_contains()](#list_contains) @@ -449,6 +450,25 @@ Returns the element located at the given index if the list is not empty. 1. `V` - The element in the list located at the given index. 2. `0` or `NULL` - If the list is empty, or if `index` is greater than or equal to the list `count`. +## [ \_get\_ref() ](#list_function_index) + +Returns a reference to the element located at the given index if the list is not empty. + +#### Declaration + +> `FMOD V *PFX##_get_ref(SNAME *_list_, size_t index);` + +#### Parameters + +1. `SNAME *_list_` - Target list. +2. `size_t index` - Index to retrieve a reference to an element. + * Can't be greater than or equal to the list `count`. + +#### Returns + +1. `V*` - A reference to the element in the list located at the given index. +2. `NULL` - If the list is empty, or if `index` is greater than or equal to the list `count`. + ## [ \_back() ](#list_function_index) Returns the last element (located at index `count - 1`) if the list is not empty. diff --git a/src/hashmap.h b/src/hashmap.h index 1ab2c5d..9ff0b48 100644 --- a/src/hashmap.h +++ b/src/hashmap.h @@ -130,6 +130,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \ FMOD bool PFX##_contains(SNAME *_map_, K key); \ FMOD V PFX##_get(SNAME *_map_, K key); \ + FMOD V *PFX##_get_ref(SNAME *_map_, K key); \ FMOD bool PFX##_empty(SNAME *_map_); \ FMOD size_t PFX##_count(SNAME *_map_); \ \ @@ -365,6 +366,16 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531, return entry->value; \ } \ \ + FMOD V *PFX##_get_ref(SNAME *_map_, K key) \ + { \ + SNAME##_entry *entry = PFX##_get_entry(_map_, key); \ + \ + if (!entry) \ + return NULL; \ + \ + return &(entry->value); \ + } \ + \ FMOD bool PFX##_empty(SNAME *_map_) \ { \ return _map_->count == 0; \ diff --git a/src/heap.h b/src/heap.h index 068aafa..1650015 100644 --- a/src/heap.h +++ b/src/heap.h @@ -76,6 +76,7 @@ typedef enum HeapOrder FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \ FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \ FMOD V PFX##_peek(SNAME *_heap_); \ + FMOD V *PFX##_peek_ref(SNAME *_heap_); \ FMOD bool PFX##_contains(SNAME *_heap_, V element); \ FMOD bool PFX##_empty(SNAME *_heap_); \ FMOD bool PFX##_full(SNAME *_heap_); \ @@ -207,6 +208,14 @@ typedef enum HeapOrder return _heap_->buffer[0]; \ } \ \ + FMOD V *PFX##_peek_ref(SNAME *_heap_) \ + { \ + if (PFX##_empty(_heap_)) \ + return NULL; \ + \ + return &(_heap_->buffer[0]); \ + } \ + \ FMOD bool PFX##_contains(SNAME *_heap_, V element) \ { \ for (size_t i = 0; i < _heap_->count; i++) \ diff --git a/src/linkedlist.h b/src/linkedlist.h index bbf61b6..2a539ad 100644 --- a/src/linkedlist.h +++ b/src/linkedlist.h @@ -82,6 +82,7 @@ FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \ FMOD V PFX##_front(SNAME *_list_); \ FMOD V PFX##_get(SNAME *_list_, size_t index); \ + FMOD V *PFX##_get_ref(SNAME *_list_, size_t index); \ FMOD V PFX##_back(SNAME *_list_); \ FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \ FMOD bool PFX##_empty(SNAME *_list_); \ @@ -338,6 +339,22 @@ return scan->data; \ } \ \ + FMOD V *PFX##_get_ref(SNAME *_list_, size_t index) \ + { \ + if (index >= _list_->count) \ + return NULL; \ + \ + if (PFX##_empty(_list_)) \ + return NULL; \ + \ + SNAME##_node *scan = PFX##_get_node(_list_, index); \ + \ + if (scan == NULL) \ + return NULL; \ + \ + return &(scan->data); \ + } \ + \ FMOD V PFX##_back(SNAME *_list_) \ { \ if (PFX##_empty(_list_)) \ diff --git a/src/list.h b/src/list.h index c40b008..4492550 100644 --- a/src/list.h +++ b/src/list.h @@ -79,6 +79,7 @@ FMOD SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to); \ FMOD V PFX##_front(SNAME *_list_); \ FMOD V PFX##_get(SNAME *_list_, size_t index); \ + FMOD V *PFX##_get_ref(SNAME *_list_, size_t index); \ FMOD V PFX##_back(SNAME *_list_); \ FMOD size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start); \ FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \ @@ -402,6 +403,17 @@ return _list_->buffer[index]; \ } \ \ + FMOD V *PFX##_get_ref(SNAME *_list_, size_t index) \ + { \ + if (index >= _list_->count) \ + return NULL; \ + \ + if (PFX##_empty(_list_)) \ + return NULL; \ + \ + return &(_list_->buffer[index]); \ + } \ + \ FMOD V PFX##_back(SNAME *_list_) \ { \ if (PFX##_empty(_list_)) \ diff --git a/src/treemap.h b/src/treemap.h index a6d3bc5..1c4c635 100644 --- a/src/treemap.h +++ b/src/treemap.h @@ -83,6 +83,7 @@ FMOD bool PFX##_max(SNAME *_map_, K *key, V *value); \ FMOD bool PFX##_min(SNAME *_map_, K *key, V *value); \ FMOD V PFX##_get(SNAME *_map_, K key); \ + FMOD V *PFX##_get_ref(SNAME *_map_, K key); \ FMOD bool PFX##_contains(SNAME *_map_, K key); \ FMOD bool PFX##_empty(SNAME *_map_); \ FMOD size_t PFX##_count(SNAME *_map_); \ @@ -422,6 +423,16 @@ return node->value; \ } \ \ + FMOD V *PFX##_get_ref(SNAME *_map_, K key) \ + { \ + SNAME##_node *node = PFX##_get_node(_map_, key); \ + \ + if (!node) \ + return NULL; \ + \ + return &(node->value); \ + } \ + \ FMOD bool PFX##_contains(SNAME *_map_, K key) \ { \ SNAME##_node *scan = _map_->root; \