Move everything out of src folder
This commit is contained in:
1 parent
2c1eb41280
commit
47ece66520
135 files changed
+13
-7
No files matched your search
@@ -0,0 +1,860 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Leonardo Vencovsky
|
||||
*
|
||||
* This file is part of the C Macro Collections Library.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Implementation Detail Functions */
|
||||
static void CMC_(PFX, _impl_float_up_max)(struct SNAME *_heap_);
|
||||
static void CMC_(PFX, _impl_float_up_min)(struct SNAME *_heap_);
|
||||
static void CMC_(PFX, _impl_float_down_max)(struct SNAME *_heap_);
|
||||
static void CMC_(PFX, _impl_float_down_min)(struct SNAME *_heap_);
|
||||
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return CMC_(PFX, _new_custom)(capacity, f_val, NULL, NULL);
|
||||
}
|
||||
|
||||
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, CMC_ALLOC_TYPE alloc,
|
||||
CMC_CALLBACK_TYPE callbacks)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
CMC_CALLBACKS_MAYBE_UNUSED(callbacks);
|
||||
|
||||
if (capacity == 0 || capacity == UINTMAX_MAX)
|
||||
return NULL;
|
||||
|
||||
if (!f_val)
|
||||
return NULL;
|
||||
|
||||
if (!alloc)
|
||||
alloc = &cmc_alloc_node_default;
|
||||
|
||||
struct SNAME *_heap_ = alloc->malloc(sizeof(struct SNAME));
|
||||
|
||||
if (!_heap_)
|
||||
return NULL;
|
||||
|
||||
capacity = (capacity + capacity % 2) / 2;
|
||||
|
||||
_heap_->buffer = alloc->calloc(capacity, sizeof(V[2]));
|
||||
|
||||
if (!_heap_->buffer)
|
||||
{
|
||||
alloc->free(_heap_);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_heap_->capacity = capacity;
|
||||
_heap_->size = 0;
|
||||
_heap_->count = 0;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
_heap_->f_val = f_val;
|
||||
_heap_->alloc = alloc;
|
||||
CMC_CALLBACKS_ASSIGN(_heap_, callbacks);
|
||||
|
||||
return _heap_;
|
||||
}
|
||||
|
||||
void CMC_(PFX, _clear)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (_heap_->f_val->free)
|
||||
{
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
_heap_->f_val->free(_heap_->buffer[i / 2][i % 2]);
|
||||
}
|
||||
}
|
||||
|
||||
memset(_heap_->buffer, 0, sizeof(V[2]) * _heap_->capacity);
|
||||
|
||||
_heap_->size = 0;
|
||||
_heap_->count = 0;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
|
||||
void CMC_(PFX, _free)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (_heap_->f_val->free)
|
||||
{
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
_heap_->f_val->free(_heap_->buffer[i / 2][i % 2]);
|
||||
}
|
||||
}
|
||||
|
||||
_heap_->alloc->free(_heap_->buffer);
|
||||
|
||||
_heap_->alloc->free(_heap_);
|
||||
}
|
||||
|
||||
void CMC_(PFX, _customize)(struct SNAME *_heap_, CMC_ALLOC_TYPE alloc, CMC_CALLBACK_TYPE callbacks)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
CMC_CALLBACKS_MAYBE_UNUSED(callbacks);
|
||||
|
||||
if (!alloc)
|
||||
_heap_->alloc = &cmc_alloc_node_default;
|
||||
else
|
||||
_heap_->alloc = alloc;
|
||||
|
||||
CMC_CALLBACKS_ASSIGN(_heap_, callbacks);
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _insert)(struct SNAME *_heap_, V value)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _full)(_heap_))
|
||||
{
|
||||
if (!CMC_(PFX, _resize)(_heap_, _heap_->capacity * 4))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_heap_->count % 2 == 0)
|
||||
{
|
||||
/* Occupying a new node */
|
||||
_heap_->buffer[_heap_->size][0] = value;
|
||||
_heap_->buffer[_heap_->size][1] = (V){ 0 };
|
||||
|
||||
_heap_->size++;
|
||||
}
|
||||
else
|
||||
{
|
||||
V(*node)[2] = &(_heap_->buffer[_heap_->size - 1]);
|
||||
|
||||
/* Decide if the new element goes into the MinHeap or MaxHeap */
|
||||
if (_heap_->f_val->cmp((*node)[0], value) > 0)
|
||||
{
|
||||
/* Swap current value and add new element to the MinHeap */
|
||||
(*node)[1] = (*node)[0];
|
||||
(*node)[0] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No need to swap and add the new element to the MaxHeap */
|
||||
(*node)[1] = value;
|
||||
}
|
||||
}
|
||||
|
||||
_heap_->count++;
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
if (_heap_->count > 2)
|
||||
{
|
||||
/* Determine wheather to do a MaxHeap insert or a MinHeap */
|
||||
/* insert. For any integer this index calculation results in */
|
||||
/* an even number representing the parent of the last value */
|
||||
V(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]);
|
||||
|
||||
if (_heap_->f_val->cmp((*parent)[0], value) > 0)
|
||||
CMC_(PFX, _impl_float_up_min)(_heap_);
|
||||
else if (_heap_->f_val->cmp((*parent)[1], value) < 0)
|
||||
CMC_(PFX, _impl_float_up_max)(_heap_);
|
||||
/* else no float up required */
|
||||
}
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _remove_max)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(_heap_))
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_EMPTY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_heap_->count == 1)
|
||||
{
|
||||
_heap_->buffer[0][0] = (V){ 0 };
|
||||
|
||||
_heap_->count--;
|
||||
_heap_->size--;
|
||||
|
||||
goto success;
|
||||
}
|
||||
|
||||
/* Swap the result with the last element in the MaxHeap and float */
|
||||
/* it down */
|
||||
V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]);
|
||||
|
||||
if (_heap_->count % 2 == 1)
|
||||
{
|
||||
/* Grab from MinHeap and discard last node */
|
||||
_heap_->buffer[0][1] = (*last_node)[0];
|
||||
|
||||
(*last_node)[0] = (V){ 0 };
|
||||
|
||||
_heap_->size--;
|
||||
}
|
||||
else
|
||||
{
|
||||
_heap_->buffer[0][1] = (*last_node)[1];
|
||||
|
||||
(*last_node)[1] = (V){ 0 };
|
||||
}
|
||||
|
||||
_heap_->count--;
|
||||
|
||||
/* FLoat Down on the MaxHeap */
|
||||
CMC_(PFX, _impl_float_down_max)(_heap_);
|
||||
|
||||
success:
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _remove_min)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(_heap_))
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_EMPTY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_heap_->count == 1)
|
||||
{
|
||||
_heap_->buffer[0][0] = (V){ 0 };
|
||||
|
||||
_heap_->count--;
|
||||
_heap_->size--;
|
||||
|
||||
goto success;
|
||||
}
|
||||
|
||||
/* Swap the result with the last element in the MinHeap and float */
|
||||
/* it down */
|
||||
V(*last_node)[2] = &(_heap_->buffer[_heap_->size - 1]);
|
||||
|
||||
_heap_->buffer[0][0] = (*last_node)[0];
|
||||
|
||||
if (_heap_->count % 2 == 1)
|
||||
{
|
||||
/* Discard last node */
|
||||
(*last_node)[0] = (V){ 0 };
|
||||
|
||||
_heap_->size--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Place the MaxHeap value in the MinHeap value spot */
|
||||
(*last_node)[0] = (*last_node)[1];
|
||||
(*last_node)[1] = (V){ 0 };
|
||||
}
|
||||
|
||||
_heap_->count--;
|
||||
|
||||
/* FLoat Down on the MinHeap */
|
||||
CMC_(PFX, _impl_float_down_min)(_heap_);
|
||||
|
||||
success:
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _update_max)(struct SNAME *_heap_, V value)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(_heap_))
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_EMPTY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_heap_->count == 1)
|
||||
{
|
||||
_heap_->buffer[0][0] = value;
|
||||
}
|
||||
else if (_heap_->f_val->cmp(value, _heap_->buffer[0][0]) < 0)
|
||||
{
|
||||
/* Corner case: we are updating the Max value but it is less */
|
||||
/* than the Min value */
|
||||
_heap_->buffer[0][1] = _heap_->buffer[0][0];
|
||||
_heap_->buffer[0][0] = value;
|
||||
|
||||
CMC_(PFX, _impl_float_down_max)(_heap_);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update Max element and float it down */
|
||||
_heap_->buffer[0][1] = value;
|
||||
|
||||
CMC_(PFX, _impl_float_down_max)(_heap_);
|
||||
}
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _update_min)(struct SNAME *_heap_, V value)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(_heap_))
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_EMPTY;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_heap_->count == 1)
|
||||
{
|
||||
_heap_->buffer[0][0] = value;
|
||||
}
|
||||
else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0)
|
||||
{
|
||||
/* Corner case: we are updating the Min value but it is greater */
|
||||
/* than the Max value. */
|
||||
_heap_->buffer[0][0] = _heap_->buffer[0][1];
|
||||
_heap_->buffer[0][1] = value;
|
||||
|
||||
CMC_(PFX, _impl_float_down_min)(_heap_);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update Min element and float it down */
|
||||
_heap_->buffer[0][0] = value;
|
||||
|
||||
CMC_(PFX, _impl_float_down_min)(_heap_);
|
||||
}
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
V CMC_(PFX, _max)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(_heap_))
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_EMPTY;
|
||||
return (V){ 0 };
|
||||
}
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
/* If there is only one element, then the maximum element is the */
|
||||
/* same as the one in the MinHeap */
|
||||
if (_heap_->count == 1)
|
||||
return _heap_->buffer[0][0];
|
||||
|
||||
return _heap_->buffer[0][1];
|
||||
}
|
||||
|
||||
V CMC_(PFX, _min)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(_heap_))
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_EMPTY;
|
||||
return (V){ 0 };
|
||||
}
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return _heap_->buffer[0][0];
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _contains)(struct SNAME *_heap_, V value)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
bool result = false;
|
||||
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
if (_heap_->f_val->cmp(_heap_->buffer[i / 2][i % 2], value) == 0)
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _empty)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return _heap_->count == 0;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _full)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
/* The heap is full if all nodes are completely filled */
|
||||
return _heap_->size >= _heap_->capacity && _heap_->count % 2 == 0;
|
||||
}
|
||||
|
||||
size_t CMC_(PFX, _count)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return _heap_->count;
|
||||
}
|
||||
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return _heap_->capacity;
|
||||
}
|
||||
|
||||
int CMC_(PFX, _flag)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return _heap_->flag;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _resize)(struct SNAME *_heap_, size_t capacity)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (_heap_->capacity == capacity)
|
||||
goto success;
|
||||
|
||||
if (capacity < _heap_->count)
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_INVALID;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Prevent overflow */
|
||||
if (capacity == UINTMAX_MAX)
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_ERROR;
|
||||
return false;
|
||||
}
|
||||
|
||||
capacity += capacity % 2;
|
||||
|
||||
V(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(V[2]) * capacity);
|
||||
|
||||
if (!new_buffer)
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_ALLOC;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (capacity > _heap_->capacity)
|
||||
{
|
||||
memset(new_buffer + _heap_->capacity, 0, sizeof(V[2]) * (capacity - _heap_->capacity));
|
||||
}
|
||||
|
||||
_heap_->buffer = new_buffer;
|
||||
_heap_->capacity = capacity;
|
||||
|
||||
success:
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
CMC_CALLBACKS_CALL(_heap_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
struct SNAME *result = _heap_->alloc->malloc(sizeof(struct SNAME));
|
||||
|
||||
if (!result)
|
||||
{
|
||||
_heap_->flag = CMC_FLAG_ALLOC;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(result, _heap_, sizeof(struct SNAME));
|
||||
|
||||
result->buffer = _heap_->alloc->malloc(sizeof(V[2]) * _heap_->capacity);
|
||||
|
||||
if (!result->buffer)
|
||||
{
|
||||
_heap_->alloc->free(result);
|
||||
_heap_->flag = CMC_FLAG_ALLOC;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_heap_->f_val->cpy)
|
||||
{
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
result->buffer[i / 2][i % 2] = _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]);
|
||||
}
|
||||
else
|
||||
memcpy(result->buffer, _heap_->buffer, sizeof(V[2]) * _heap_->capacity);
|
||||
|
||||
result->capacity = _heap_->capacity;
|
||||
result->size = _heap_->size;
|
||||
result->count = _heap_->count;
|
||||
result->flag = CMC_FLAG_OK;
|
||||
result->f_val = _heap_->f_val;
|
||||
result->alloc = _heap_->alloc;
|
||||
CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks);
|
||||
|
||||
_heap_->flag = CMC_FLAG_OK;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _equals)(struct SNAME *_heap1_, struct SNAME *_heap2_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
_heap1_->flag = CMC_FLAG_OK;
|
||||
_heap2_->flag = CMC_FLAG_OK;
|
||||
|
||||
if (_heap1_->count != _heap2_->count)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < _heap1_->count; i++)
|
||||
{
|
||||
V value1 = _heap1_->buffer[i / 2][i % 2];
|
||||
V value2 = _heap2_->buffer[i / 2][i % 2];
|
||||
|
||||
if (_heap1_->f_val->cmp(value1, value2) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CMC_(PFX, _impl_float_up_max)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
size_t index = _heap_->size - 1;
|
||||
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]);
|
||||
|
||||
/* FLoat Up on the MaxHeap */
|
||||
while (index > 0)
|
||||
{
|
||||
/* Parent index */
|
||||
size_t P_index = (index - 1) / 2;
|
||||
|
||||
V(*parent)[2] = &(_heap_->buffer[P_index]);
|
||||
|
||||
if (index == _heap_->size - 1 && _heap_->count % 2 != 0)
|
||||
{
|
||||
/* In this case, the current node has no MaxHeap value so */
|
||||
/* we instead compare with the MinHeap value */
|
||||
if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0)
|
||||
break;
|
||||
|
||||
/* Since the comparison above passed now we need to swap */
|
||||
/* the current node with the parent but it will have to be */
|
||||
/* done with the node's MinHeap value since the MaxHeap */
|
||||
/* value doesn't exist */
|
||||
V tmp = (*curr_node)[0];
|
||||
(*curr_node)[0] = (*parent)[1];
|
||||
(*parent)[1] = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Usual case, just compare both MaxHeap values */
|
||||
if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0)
|
||||
break;
|
||||
|
||||
/* Swap with parent and repeat */
|
||||
V tmp = (*curr_node)[1];
|
||||
(*curr_node)[1] = (*parent)[1];
|
||||
(*parent)[1] = tmp;
|
||||
}
|
||||
|
||||
/* Update indexe and node */
|
||||
index = P_index;
|
||||
curr_node = parent;
|
||||
}
|
||||
}
|
||||
|
||||
static void CMC_(PFX, _impl_float_up_min)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
size_t index = _heap_->size - 1;
|
||||
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]);
|
||||
|
||||
/* FLoat Up on the MinHeap */
|
||||
while (index > 0)
|
||||
{
|
||||
/* Parent index */
|
||||
size_t P_index = (index - 1) / 2;
|
||||
|
||||
V(*parent)[2] = &(_heap_->buffer[P_index]);
|
||||
|
||||
if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0)
|
||||
break;
|
||||
|
||||
/* Swap with parent and repeat */
|
||||
V tmp = (*curr_node)[0];
|
||||
(*curr_node)[0] = (*parent)[0];
|
||||
(*parent)[0] = tmp;
|
||||
|
||||
/* Update indexe and node */
|
||||
index = P_index;
|
||||
curr_node = parent;
|
||||
}
|
||||
}
|
||||
|
||||
static void CMC_(PFX, _impl_float_down_max)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
/* Floats Down from the MaxHeap */
|
||||
size_t index = 0;
|
||||
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]);
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* If there are no children it is done */
|
||||
if (2 * index + 1 >= _heap_->size)
|
||||
break;
|
||||
|
||||
/* Child index to be compared with current value */
|
||||
size_t child;
|
||||
size_t L_index = index * 2 + 1;
|
||||
size_t R_index = index * 2 + 2;
|
||||
|
||||
/* If there are two children, pick the smallest one */
|
||||
if (R_index < _heap_->size)
|
||||
{
|
||||
V(*L)[2] = &(_heap_->buffer[L_index]);
|
||||
V(*R)[2] = &(_heap_->buffer[R_index]);
|
||||
|
||||
/* If the right child is the last node and there is no */
|
||||
/* MaxHeap value */
|
||||
/* then do the comparison with the MinHeap value */
|
||||
if (R_index == _heap_->size - 1 && _heap_->count % 2 != 0)
|
||||
child = _heap_->f_val->cmp((*L)[1], (*R)[0]) > 0 ? L_index : R_index;
|
||||
else
|
||||
child = _heap_->f_val->cmp((*L)[1], (*R)[1]) > 0 ? L_index : R_index;
|
||||
}
|
||||
/* Pick the only one available */
|
||||
else
|
||||
child = L_index;
|
||||
|
||||
V(*child_node)[2] = &(_heap_->buffer[child]);
|
||||
|
||||
/* Again, check if the child node is the last one and has no */
|
||||
/* MaxHeap value */
|
||||
if (child == _heap_->size - 1 && _heap_->count % 2 != 0)
|
||||
{
|
||||
/* Odd case, compare with MinHeap value */
|
||||
/* If current value is not less than the child node's */
|
||||
/* value it is done */
|
||||
if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0)
|
||||
break;
|
||||
|
||||
/* Otherwise swap and continue */
|
||||
V tmp = (*child_node)[0];
|
||||
(*child_node)[0] = (*curr_node)[1];
|
||||
(*curr_node)[1] = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If current value is not less than the child node's */
|
||||
/* value it is done */
|
||||
if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0)
|
||||
break;
|
||||
|
||||
/* Otherwise swap and continue */
|
||||
V tmp = (*child_node)[1];
|
||||
(*child_node)[1] = (*curr_node)[1];
|
||||
(*curr_node)[1] = tmp;
|
||||
|
||||
/* Check if the MinHeap and MaxHeap values need to be */
|
||||
/* swapped */
|
||||
if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
|
||||
{
|
||||
/* Swap because the MinHeap value is greater than the */
|
||||
/* MaxHeap value */
|
||||
tmp = (*child_node)[0];
|
||||
(*child_node)[0] = (*child_node)[1];
|
||||
(*child_node)[1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update index and node */
|
||||
index = child;
|
||||
curr_node = child_node;
|
||||
}
|
||||
}
|
||||
|
||||
static void CMC_(PFX, _impl_float_down_min)(struct SNAME *_heap_)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
/* Floats Down from the MinHeap */
|
||||
size_t index = 0;
|
||||
|
||||
V(*curr_node)[2] = &(_heap_->buffer[index]);
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* If there are no children it is done */
|
||||
if (2 * index + 1 >= _heap_->size)
|
||||
break;
|
||||
|
||||
/* Child index to be compared with current value */
|
||||
size_t child;
|
||||
size_t L_index = index * 2 + 1;
|
||||
size_t R_index = index * 2 + 2;
|
||||
|
||||
/* If there are two children, pick the smallest one */
|
||||
if (R_index < _heap_->size)
|
||||
{
|
||||
V(*L)[2] = &(_heap_->buffer[L_index]);
|
||||
V(*R)[2] = &(_heap_->buffer[R_index]);
|
||||
|
||||
child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index;
|
||||
}
|
||||
/* Pick the only one available */
|
||||
else
|
||||
child = L_index;
|
||||
|
||||
V(*child_node)[2] = &(_heap_->buffer[child]);
|
||||
|
||||
/* If current value is smaller than the child node's value, it */
|
||||
/* is done */
|
||||
if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0)
|
||||
break;
|
||||
|
||||
/* Otherwise swap and continue */
|
||||
V tmp = (*child_node)[0];
|
||||
(*child_node)[0] = (*curr_node)[0];
|
||||
(*curr_node)[0] = tmp;
|
||||
|
||||
/* If the child node is the last node check if the MinHeap and */
|
||||
/* MaxHeap values need to be swapped */
|
||||
if (child != _heap_->size - 1 || _heap_->count % 2 == 0)
|
||||
{
|
||||
if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
|
||||
{
|
||||
/* Swap because the MinHeap value is greater than the */
|
||||
/* MaxHeap value */
|
||||
tmp = (*child_node)[0];
|
||||
(*child_node)[0] = (*child_node)[1];
|
||||
(*child_node)[1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update index and node */
|
||||
index = child;
|
||||
curr_node = child_node;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Leonardo Vencovsky
|
||||
*
|
||||
* This file is part of the C Macro Collections Library.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* INIT
|
||||
*
|
||||
* The part 'INIT' gives a new way of initializing a collection. The collection
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers).
|
||||
*/
|
||||
#ifdef CMC_EXT_INIT
|
||||
|
||||
#endif /* CMC_EXT_INIT */
|
||||
|
||||
/**
|
||||
* ITER
|
||||
*
|
||||
* Intervalheap bi-directional iterator.
|
||||
*
|
||||
* TODO allow creation of iterators exclusively for min or max heap
|
||||
*/
|
||||
#ifdef CMC_EXT_ITER
|
||||
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
struct CMC_DEF_ITER(SNAME) iter;
|
||||
|
||||
iter.target = target;
|
||||
iter.cursor = 0;
|
||||
iter.start = true;
|
||||
iter.end = CMC_(PFX, _empty)(target);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
struct CMC_DEF_ITER(SNAME) iter;
|
||||
|
||||
iter.target = target;
|
||||
iter.cursor = 0;
|
||||
iter.start = CMC_(PFX, _empty)(target);
|
||||
iter.end = true;
|
||||
|
||||
if (!CMC_(PFX, _empty)(target))
|
||||
iter.cursor = target->count - 1;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->start;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return CMC_(PFX, _empty)(iter->target) || iter->end;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (!CMC_(PFX, _empty)(iter->target))
|
||||
{
|
||||
iter->cursor = 0;
|
||||
iter->start = true;
|
||||
iter->end = CMC_(PFX, _empty)(iter->target);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (!CMC_(PFX, _empty)(iter->target))
|
||||
{
|
||||
iter->cursor = iter->target->count - 1;
|
||||
iter->start = CMC_(PFX, _empty)(iter->target);
|
||||
iter->end = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (iter->end)
|
||||
return false;
|
||||
|
||||
if (iter->cursor + 1 == iter->target->count)
|
||||
{
|
||||
iter->end = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->start = CMC_(PFX, _empty)(iter->target);
|
||||
|
||||
iter->cursor++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (iter->start)
|
||||
return false;
|
||||
|
||||
if (iter->cursor == 0)
|
||||
{
|
||||
iter->start = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
iter->end = CMC_(PFX, _empty)(iter->target);
|
||||
|
||||
iter->cursor--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns true only if the iterator moved */
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (iter->end)
|
||||
return false;
|
||||
|
||||
if (iter->cursor + 1 == iter->target->count)
|
||||
{
|
||||
iter->end = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (steps == 0 || iter->cursor + steps >= iter->target->count)
|
||||
return false;
|
||||
|
||||
if (iter->end)
|
||||
return false;
|
||||
|
||||
iter->start = CMC_(PFX, _empty)(iter->target);
|
||||
|
||||
iter->cursor += steps;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns true only if the iterator moved */
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (iter->start)
|
||||
return false;
|
||||
|
||||
if (iter->cursor == 0)
|
||||
{
|
||||
iter->start = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (steps == 0 || iter->cursor < steps)
|
||||
return false;
|
||||
|
||||
iter->end = CMC_(PFX, _empty)(iter->target);
|
||||
|
||||
iter->cursor -= steps;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns true only if the iterator was able to be positioned at the */
|
||||
/* given index */
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (index >= iter->target->count)
|
||||
return false;
|
||||
|
||||
if (iter->cursor > index)
|
||||
return CMC_(PFX, _iter_rewind)(iter, iter->cursor - index);
|
||||
else if (iter->cursor < index)
|
||||
return CMC_(PFX, _iter_advance)(iter, index - iter->cursor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
if (CMC_(PFX, _empty)(iter->target))
|
||||
return (V){ 0 };
|
||||
|
||||
return iter->target->buffer[iter->cursor / 2][iter->cursor % 2];
|
||||
}
|
||||
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
return iter->cursor;
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_ITER */
|
||||
|
||||
/**
|
||||
* STR
|
||||
*
|
||||
* Print helper functions.
|
||||
*/
|
||||
#ifdef CMC_EXT_STR
|
||||
|
||||
bool CMC_(PFX, _to_string)(struct SNAME *_heap_, FILE *fptr)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
struct SNAME *h_ = _heap_;
|
||||
|
||||
return 0 <= fprintf(fptr,
|
||||
"struct %s<%s> "
|
||||
"at %p { "
|
||||
"buffer:%p, "
|
||||
"capacity:%" PRIuMAX ", "
|
||||
"size:%" PRIuMAX ", "
|
||||
"count:%" PRIuMAX ", "
|
||||
"flag:%d, "
|
||||
"f_val:%p, "
|
||||
"alloc:%p, "
|
||||
"callbacks:%p }",
|
||||
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->size, h_->count,
|
||||
h_->flag, h_->f_val, h_->alloc, CMC_CALLBACKS_GET(h_));
|
||||
}
|
||||
|
||||
bool CMC_(PFX, _print)(struct SNAME *_heap_, FILE *fptr, const char *start, const char *separator, const char *end)
|
||||
{
|
||||
#ifdef CMC_DEV
|
||||
CMC_DEV_FCALL;
|
||||
#endif
|
||||
|
||||
fprintf(fptr, "%s", start);
|
||||
|
||||
for (size_t i = 0; i < _heap_->count; i++)
|
||||
{
|
||||
if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2]))
|
||||
return false;
|
||||
|
||||
if (i + 1 < _heap_->count)
|
||||
fprintf(fptr, "%s", separator);
|
||||
}
|
||||
|
||||
fprintf(fptr, "%s", end);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* CMC_EXT_STR */
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Leonardo Vencovsky
|
||||
*
|
||||
* This file is part of the C Macro Collections Library.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* INIT
|
||||
*
|
||||
* The part 'INIT' gives a new way of initializing a collection. The collection
|
||||
* struct is not heap allocated, only its internal structure (nodes, buffers).
|
||||
*/
|
||||
#ifdef CMC_EXT_INIT
|
||||
|
||||
#endif /* CMC_EXT_INIT */
|
||||
|
||||
/**
|
||||
* ITER
|
||||
*
|
||||
* List bi-directional iterator.
|
||||
*/
|
||||
#ifdef CMC_EXT_ITER
|
||||
|
||||
/* IntervalHeap Iterator */
|
||||
struct CMC_DEF_ITER(SNAME)
|
||||
{
|
||||
/* Target IntervalHeap */
|
||||
struct SNAME *target;
|
||||
|
||||
/* Cursor's position (index) */
|
||||
size_t cursor;
|
||||
|
||||
/* If the iterator has reached the start of the iteration */
|
||||
bool start;
|
||||
|
||||
/* If the iterator has reached the end of the iteration */
|
||||
bool end;
|
||||
};
|
||||
|
||||
/* Iterator Initialization */
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target);
|
||||
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME *target);
|
||||
/* Iterator State */
|
||||
bool CMC_(PFX, _iter_at_start)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
/* Iterator Movement */
|
||||
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
bool CMC_(PFX, _iter_advance)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps);
|
||||
bool CMC_(PFX, _iter_rewind)(struct CMC_DEF_ITER(SNAME) * iter, size_t steps);
|
||||
bool CMC_(PFX, _iter_go_to)(struct CMC_DEF_ITER(SNAME) * iter, size_t index);
|
||||
/* Iterator Access */
|
||||
V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
|
||||
|
||||
#endif /* CMC_EXT_ITER */
|
||||
|
||||
/**
|
||||
* STR
|
||||
*
|
||||
* Print helper functions.
|
||||
*/
|
||||
#ifdef CMC_EXT_STR
|
||||
|
||||
bool CMC_(PFX, _to_string)(struct SNAME *_heap_, FILE *fptr);
|
||||
bool CMC_(PFX, _print)(struct SNAME *_heap_, FILE *fptr, const char *start, const char *separator, const char *end);
|
||||
|
||||
#endif /* CMC_EXT_STR */
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Leonardo Vencovsky
|
||||
*
|
||||
* This file is part of the C Macro Collections Library.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Leonardo Vencovsky
|
||||
*
|
||||
* This file is part of the C Macro Collections Library.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Value struct function table */
|
||||
struct CMC_DEF_FVAL(SNAME)
|
||||
{
|
||||
/* Comparator function */
|
||||
CMC_DEF_FTAB_CMP(V);
|
||||
/* Copy function */
|
||||
CMC_DEF_FTAB_CPY(V);
|
||||
/* To string function */
|
||||
CMC_DEF_FTAB_STR(V);
|
||||
/* Free from memory function */
|
||||
CMC_DEF_FTAB_FREE(V);
|
||||
/* Hash function */
|
||||
CMC_DEF_FTAB_HASH(V);
|
||||
/* Priority function */
|
||||
CMC_DEF_FTAB_PRI(V);
|
||||
};
|
||||
|
||||
/* Collection Functions */
|
||||
/* Collection Allocation and Deallocation */
|
||||
struct SNAME *CMC_(PFX, _new)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val);
|
||||
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val, CMC_ALLOC_TYPE alloc,
|
||||
CMC_CALLBACK_TYPE callbacks);
|
||||
void CMC_(PFX, _clear)(struct SNAME *_heap_);
|
||||
void CMC_(PFX, _free)(struct SNAME *_heap_);
|
||||
/* Customization of Allocation and Callbacks */
|
||||
void CMC_(PFX, _customize)(struct SNAME *_heap_, CMC_ALLOC_TYPE alloc, CMC_CALLBACK_TYPE callbacks);
|
||||
/* Collection Input and Output */
|
||||
bool CMC_(PFX, _insert)(struct SNAME *_heap_, V value);
|
||||
bool CMC_(PFX, _remove_max)(struct SNAME *_heap_);
|
||||
bool CMC_(PFX, _remove_min)(struct SNAME *_heap_);
|
||||
/* Collection Update */
|
||||
bool CMC_(PFX, _update_max)(struct SNAME *_heap_, V value);
|
||||
bool CMC_(PFX, _update_min)(struct SNAME *_heap_, V value);
|
||||
/* Element Access */
|
||||
V CMC_(PFX, _max)(struct SNAME *_heap_);
|
||||
V CMC_(PFX, _min)(struct SNAME *_heap_);
|
||||
/* Collection State */
|
||||
bool CMC_(PFX, _contains)(struct SNAME *_heap_, V value);
|
||||
bool CMC_(PFX, _empty)(struct SNAME *_heap_);
|
||||
bool CMC_(PFX, _full)(struct SNAME *_heap_);
|
||||
size_t CMC_(PFX, _count)(struct SNAME *_heap_);
|
||||
size_t CMC_(PFX, _capacity)(struct SNAME *_heap_);
|
||||
int CMC_(PFX, _flag)(struct SNAME *_heap_);
|
||||
/* Collection Utility */
|
||||
bool CMC_(PFX, _resize)(struct SNAME *_heap_, size_t capacity);
|
||||
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_heap_);
|
||||
bool CMC_(PFX, _equals)(struct SNAME *_heap1_, struct SNAME *_heap2_);
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Leonardo Vencovsky
|
||||
*
|
||||
* This file is part of the C Macro Collections Library.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
struct SNAME
|
||||
{
|
||||
/* Dynamic array of elements */
|
||||
/* buffer[n][0] is MinHeap and buffer[n][1] is MaxHeap */
|
||||
V (*buffer)[2];
|
||||
/* Current array capacity */
|
||||
size_t capacity;
|
||||
/* Current amount of pairs of values in the array */
|
||||
size_t size;
|
||||
/* Current amount of elements in the heap */
|
||||
size_t count;
|
||||
/* Flags indicating errors or success */
|
||||
int flag;
|
||||
/* Value function table */
|
||||
struct CMC_DEF_FVAL(SNAME) * f_val;
|
||||
/* Custom allocation functions */
|
||||
CMC_ALLOC_TYPE alloc;
|
||||
/* Custom callback functions */
|
||||
CMC_CALLBACKS_DECL;
|
||||
};
|
||||
Reference in new issue
Block a user