More refactoring

This commit is contained in:
Leonardo Vencovsky committed 2023-01-19 13:06:40 +01:00
1 parent c1070c4858
commit e4d58db474
34 files changed
+5295 -74

No files matched your search

+5
View File
@@ -288,3 +288,8 @@ You can use them as Stacks, Queues and Deques, but with modern memory hierarchy
### You can't structurally modify a collection when iterating over it
Modifying a collection will possibly invalidate all iterators currently initialized by it. Currently, the only collection that allows this is the LinkedList (using the node-based functions, not the iterator).
## Special Macros
* `CMC_NO_ALLOC` - disables `"cor/alloc.h"`
* `CMC_NO_IMPORTS` - disables all imports from the standard library at `"cor/core.h"`
+88
View File
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/**
* bitset.h
*
* Creation Date: 30/04/2020
*
* Authors:
* Leonardo Vencovsky (https://github.com/LeoVen)
*
*/
/**
* BitSet
*
* A Bit Set is an array where each bit can be individually modified and queried
* by using bitwise operators such as |, &, ^, ~, >> and << (or, and, xor, not,
* right shift, left shift respectively).
*
* Implementation
*
* This BitSet implementation uses an array of type cmc_bitset_word which can be
* typedefed to any unsigned type such as uint8_t, uint16_t, uint32_t, uint64_t,
* size_t, etc. The BitSet does not make use of K or V. Because of that, it also
* doesn't have Functions Tables.
*
* The BitSet is initialized with a custom capacity but, if a bit index accessed
* is greater than the total capacity, the BitSet will resize. This means that
* the BitSet will try to guarantee that every bit index is accessible, as long
* as there is enough memory.
*/
#include "cor/bitset.h"
#include "cor/core.h"
/**
* Used values
* SNAME - struct name and prefix of other related structs
* PFX - functions prefix
*/
/* Structs definition */
#include "cmc/bitset/struct.h"
/* Function declaration */
#include "cmc/bitset/header.h"
/* Function implementation */
#include "cmc/bitset/code.h"
/**
* Extensions
*
* INIT - Initializes the struct on the stack
* ITER - bitset iterator
* STR - Print helper functions
*/
#define CMC_EXT_BITSET_PARTS INIT, ITER, STR
/**/
#include "cmc/bitset/ext/struct.h"
/**/
#include "cmc/bitset/ext/header.h"
/**/
#include "cmc/bitset/ext/code.h"
#include "cor/undef.h"
+431
View File
@@ -0,0 +1,431 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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 */
bool CMC_(PFX, _impl_resize)(struct SNAME *_bitset_, size_t n_bits, bool do_resize);
struct SNAME *CMC_(PFX, _new)(size_t n_bits)
{
return CMC_(PFX, _new_custom)(n_bits, NULL, NULL);
}
struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks)
{
CMC_CALLBACKS_MAYBE_UNUSED(callbacks);
if (n_bits < 1)
return NULL;
if (!alloc)
alloc = &cmc_alloc_node_default;
size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1;
struct SNAME *_bitset_ = alloc->malloc(sizeof(struct SNAME));
if (!_bitset_)
return NULL;
_bitset_->buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word));
if (!_bitset_->buffer)
{
alloc->free(_bitset_);
return NULL;
}
_bitset_->capacity = capacity;
_bitset_->flag = CMC_FLAG_OK;
_bitset_->alloc = alloc;
CMC_CALLBACKS_ASSIGN(_bitset_, callbacks);
return _bitset_;
}
struct SNAME CMC_(PFX, _init)(size_t n_bits)
{
return CMC_(PFX, _init_custom)(n_bits, NULL, NULL);
}
struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *CMC_UNUSED(callbacks))
{
CMC_CALLBACKS_MAYBE_UNUSED(callbacks);
struct SNAME _bitset_ = { 0 };
if (n_bits < 1)
return _bitset_;
if (!alloc)
alloc = &cmc_alloc_node_default;
size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1;
_bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word));
if (!_bitset_.buffer)
return _bitset_;
_bitset_.capacity = capacity;
_bitset_.flag = CMC_FLAG_OK;
_bitset_.alloc = alloc;
CMC_CALLBACKS_ASSIGN(&_bitset_, callbacks);
return _bitset_;
}
void CMC_(PFX, _free)(struct SNAME *_bitset_)
{
free(_bitset_->buffer);
free(_bitset_);
}
void CMC_(PFX, _release)(struct SNAME _bitset_)
{
free(_bitset_.buffer);
}
void CMC_(PFX, _customize)(struct SNAME *_bitset_, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks)
{
CMC_CALLBACKS_MAYBE_UNUSED(callbacks);
if (!alloc)
_bitset_->alloc = &cmc_alloc_node_default;
else
_bitset_->alloc = alloc;
CMC_CALLBACKS_ASSIGN(_bitset_, callbacks);
_bitset_->flag = CMC_FLAG_OK;
}
bool CMC_(PFX, _set)(struct SNAME *_bitset_, size_t bit_index)
{
if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false))
return false;
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
size_t i = cmc_bidx_to_widx(bit_index);
_bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits);
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, create);
return true;
}
bool CMC_(PFX, _set_range)(struct SNAME *_bitset_, size_t from, size_t to)
{
if (to < from)
{
_bitset_->flag = CMC_FLAG_INVALID;
return false;
}
if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false))
return false;
size_t start_index = cmc_bidx_to_widx(from);
size_t end_index = cmc_bidx_to_widx(to);
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
/* 1111 ... 1111 */
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
cmc_bitset_word shift_start = from % bits;
cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits;
cmc_bitset_word start_mask = ones << shift_start;
cmc_bitset_word end_mask = ones >> shift_end;
if (start_index == end_index)
{
_bitset_->buffer[end_index] |= (start_mask & end_mask);
}
else
{
_bitset_->buffer[start_index] |= start_mask;
for (size_t i = start_index + 1; i < end_index; i++)
_bitset_->buffer[i] |= ~((cmc_bitset_word)0);
_bitset_->buffer[end_index] |= end_mask;
}
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, create);
return true;
}
bool CMC_(PFX, _clear)(struct SNAME *_bitset_, size_t bit_index)
{
if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false))
return false;
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
size_t i = cmc_bidx_to_widx(bit_index);
_bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits));
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, delete);
return true;
}
bool CMC_(PFX, _clear_range)(struct SNAME *_bitset_, size_t from, size_t to)
{
if (to < from)
{
_bitset_->flag = CMC_FLAG_INVALID;
return false;
}
if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false))
return false;
size_t start_index = cmc_bidx_to_widx(from);
size_t end_index = cmc_bidx_to_widx(to);
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
/* 1111 ... 1111 */
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
cmc_bitset_word shift_start = from % bits;
cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits;
cmc_bitset_word start_mask = ones << shift_start;
cmc_bitset_word end_mask = ones >> shift_end;
if (start_index == end_index)
{
_bitset_->buffer[end_index] &= ~(start_mask & end_mask);
}
else
{
_bitset_->buffer[start_index] &= ~start_mask;
for (size_t i = start_index + 1; i < end_index; i++)
_bitset_->buffer[i] = 0;
_bitset_->buffer[end_index] &= ~end_mask;
}
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, delete);
return true;
}
bool CMC_(PFX, _flip)(struct SNAME *_bitset_, size_t bit_index)
{
if (!CMC_(PFX, _impl_resize)(_bitset_, bit_index + 1, false))
return false;
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
size_t i = cmc_bidx_to_widx(bit_index);
_bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits);
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, update);
return true;
}
bool CMC_(PFX, _flip_range)(struct SNAME *_bitset_, size_t from, size_t to)
{
if (to < from)
{
_bitset_->flag = CMC_FLAG_INVALID;
return false;
}
if (!CMC_(PFX, _impl_resize)(_bitset_, to + 1, false))
return false;
size_t start_index = cmc_bidx_to_widx(from);
size_t end_index = cmc_bidx_to_widx(to);
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
/* 1111 ... 1111 */
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
cmc_bitset_word shift_start = from % bits;
cmc_bitset_word shift_end = (cmc_bitset_word)(-(to + 1)) % bits;
cmc_bitset_word start_mask = ones << shift_start;
cmc_bitset_word end_mask = ones >> shift_end;
if (start_index == end_index)
{
_bitset_->buffer[end_index] ^= (start_mask & end_mask);
}
else
{
_bitset_->buffer[start_index] ^= start_mask;
for (size_t i = start_index + 1; i < end_index; i++)
_bitset_->buffer[i] ^= ones;
_bitset_->buffer[end_index] ^= end_mask;
}
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, update);
return true;
}
bool CMC_(PFX, _put)(struct SNAME *_bitset_, size_t bit_index, bool state)
{
if (state)
return CMC_(PFX, _set)(_bitset_, bit_index);
else
return CMC_(PFX, _clear)(_bitset_, bit_index);
}
bool CMC_(PFX, _put_range)(struct SNAME *_bitset_, size_t from, size_t to, bool state)
{
if (state)
return CMC_(PFX, _set_range)(_bitset_, from, to);
else
return CMC_(PFX, _clear_range)(_bitset_, from, to);
}
bool CMC_(PFX, _set_all)(struct SNAME *_bitset_)
{
for (size_t i = 0; i < _bitset_->capacity; i++)
_bitset_->buffer[i] = ~((cmc_bitset_word)0);
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, create);
return true;
}
bool CMC_(PFX, _clear_all)(struct SNAME *_bitset_)
{
for (size_t i = 0; i < _bitset_->capacity; i++)
_bitset_->buffer[i] = 0;
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, delete);
return true;
}
bool CMC_(PFX, _flip_all)(struct SNAME *_bitset_)
{
for (size_t i = 0; i < _bitset_->capacity; i++)
_bitset_->buffer[i] ^= ~((cmc_bitset_word)0);
_bitset_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_bitset_, create);
return true;
}
bool CMC_(PFX, _get)(struct SNAME *_bitset_, size_t bit_index)
{
/* How many bits in a word */
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * CHAR_BIT;
cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)];
return w & ((cmc_bitset_word)1 << (bit_index % bits));
}
bool CMC_(PFX, _resize)(struct SNAME *_bitset_, size_t n_bits)
{
return CMC_(PFX, _impl_resize)(_bitset_, n_bits, true);
}
/* When do_resize is false, then we just want to assure that the bitset */
/* can accommodate n_bits */
bool CMC_(PFX, _impl_resize)(struct SNAME *_bitset_, size_t n_bits, bool do_resize)
{
if (n_bits == 0)
{
_bitset_->flag = CMC_FLAG_INVALID;
return false;
}
/* -1 because n_bits is 1-based and we need to pass a 0-based index */
/* +1 to have a 1-based result */
size_t words = cmc_bidx_to_widx(n_bits - 1) + 1;
/* Be sure we are not always shrinking when we just want to make */
/* sure that we have enough size for n_bits */
if (!do_resize && words <= _bitset_->capacity)
return true;
cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word));
if (!new_buffer)
{
_bitset_->flag = CMC_FLAG_ALLOC;
return false;
}
_bitset_->buffer = new_buffer;
/* Make new bits be all zeroes */
if (_bitset_->capacity < words)
memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word));
_bitset_->capacity = words;
CMC_CALLBACKS_CALL(_bitset_, resize);
_bitset_->flag = CMC_FLAG_OK;
return true;
}
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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_BITSET_INIT
#endif /* CMC_EXT_BITSET_INIT */
/**
* ITER
*
* Bitset bi-directional iterator.
*/
#ifdef CMC_EXT_BITSET_ITER
/* Iterator Functions */
/* Iterator Initialization */
/* Iterator State */
/* Iterator Movement */
/* Iterator Access */
#endif /* CMC_EXT_BITSET_ITER */
/**
* STR
*
* Print helper functions.
*/
#ifdef CMC_EXT_BITSET_STR
#endif /* CMC_EXT_BITSET_STR */
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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_BITSET_INIT
#endif /* CMC_EXT_BITSET_INIT */
/**
* ITER
*
* Bitset bi-directional iterator.
*/
#ifdef CMC_EXT_BITSET_ITER
/* Iterator Functions */
/* Iterator Initialization */
/* Iterator State */
/* Iterator Movement */
/* Iterator Access */
#endif /* CMC_EXT_BITSET_ITER */
/**
* STR
*
* Print helper functions.
*/
#ifdef CMC_EXT_BITSET_STR
#endif /* CMC_EXT_BITSET_STR */
+45
View File
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/**
* ITER
*
* Bitset bi-directional iterator.
*/
#ifdef CMC_EXT_BITSET_ITER
/* BitSet Iterator */
struct CMC_DEF_ITER(SNAME)
{
/* Target bitset */
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;
};
#endif /* CMC_EXT_BITSET_ITER */
+52
View File
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/* Collection Allocation and Deallocation */
struct SNAME *CMC_(PFX, _new)(size_t n_bits);
struct SNAME *CMC_(PFX, _new_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks);
struct SNAME CMC_(PFX, _init)(size_t n_bits);
struct SNAME CMC_(PFX, _init_custom)(size_t n_bits, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks);
void CMC_(PFX, _free)(struct SNAME *_bitset_);
void CMC_(PFX, _release)(struct SNAME _bitset_);
void CMC_(PFX, _customize)(struct SNAME *_bitset_, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks);
/* Collection Input and Output */
bool CMC_(PFX, _set)(struct SNAME *_bitset_, size_t bit_index);
bool CMC_(PFX, _set_range)(struct SNAME *_bitset_, size_t from, size_t to);
bool CMC_(PFX, _clear)(struct SNAME *_bitset_, size_t bit_index);
bool CMC_(PFX, _clear_range)(struct SNAME *_bitset_, size_t from, size_t to);
bool CMC_(PFX, _flip)(struct SNAME *_bitset_, size_t bit_index);
bool CMC_(PFX, _flip_range)(struct SNAME *_bitset_, size_t from, size_t to);
bool CMC_(PFX, _put)(struct SNAME *_bitset_, size_t bit_index, bool state);
bool CMC_(PFX, _put_range)(struct SNAME *_bitset_, size_t from, size_t to, bool state);
bool CMC_(PFX, _set_all)(struct SNAME *_bitset_);
bool CMC_(PFX, _clear_all)(struct SNAME *_bitset_);
bool CMC_(PFX, _flip_all)(struct SNAME *_bitset_);
/* Element Access */
bool CMC_(PFX, _get)(struct SNAME *_bitset_, size_t bit_index);
/* Collection State */
/* Collection Utility */
bool CMC_(PFX, _resize)(struct SNAME *_bitset_, size_t n_bits);
+42
View File
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/* BitSet Structure */
struct SNAME
{
/* Dynamic Array of Bits */
cmc_bitset_word *buffer;
/* Current array capacity */
size_t capacity;
/* Currently used bits */
/* This should always be true: */
/* capacity - count < sizeof(cmc_bitset_word) * CHAR_BIT */
size_t count;
/* Flags indicating errors or success */
int flag;
/* Custom allocation functions */
struct CMC_ALLOC_NODE_NAME *alloc;
/* Custom callback functions */
CMC_CALLBACKS_DECL;
};
+362
View File
@@ -0,0 +1,362 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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)(struct SNAME *_heap_, size_t index);
static void CMC_(PFX, _impl_float_down)(struct SNAME *_heap_, size_t index);
struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val)
{
return CMC_(PFX, _new_custom)(capacity, HO, f_val, NULL, NULL);
}
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val,
struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks)
{
CMC_CALLBACKS_MAYBE_UNUSED(callbacks);
if (capacity < 1)
return NULL;
if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP)
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;
_heap_->buffer = alloc->calloc(capacity, sizeof(V));
if (!_heap_->buffer)
{
alloc->free(_heap_);
return NULL;
}
_heap_->capacity = capacity;
_heap_->count = 0;
_heap_->HO = HO;
_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_)
{
if (_heap_->f_val->free)
{
for (size_t i = 0; i < _heap_->count; i++)
{
_heap_->f_val->free(_heap_->buffer[i]);
}
}
memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity);
_heap_->count = 0;
_heap_->flag = CMC_FLAG_OK;
}
void CMC_(PFX, _free)(struct SNAME *_heap_)
{
if (_heap_->f_val->free)
{
for (size_t i = 0; i < _heap_->count; i++)
{
_heap_->f_val->free(_heap_->buffer[i]);
}
}
_heap_->alloc->free(_heap_->buffer);
_heap_->alloc->free(_heap_);
}
void CMC_(PFX, _customize)(struct SNAME *_heap_, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks)
{
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)
{
if (CMC_(PFX, _full)(_heap_))
{
if (!CMC_(PFX, _resize)(_heap_, _heap_->count * 2))
return false;
}
_heap_->buffer[_heap_->count++] = value;
if (_heap_->count > 1)
{
CMC_(PFX, _impl_float_up)(_heap_, _heap_->count - 1);
}
_heap_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_heap_, create);
return true;
}
bool CMC_(PFX, _remove)(struct SNAME *_heap_)
{
if (CMC_(PFX, _empty)(_heap_))
{
_heap_->flag = CMC_FLAG_EMPTY;
return false;
}
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1];
_heap_->buffer[_heap_->count - 1] = (V){ 0 };
_heap_->count--;
CMC_(PFX, _impl_float_down)(_heap_, 0);
_heap_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_heap_, delete);
return true;
}
V CMC_(PFX, _peek)(struct SNAME *_heap_)
{
if (CMC_(PFX, _empty)(_heap_))
{
_heap_->flag = CMC_FLAG_EMPTY;
return (V){ 0 };
}
_heap_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_heap_, read);
return _heap_->buffer[0];
}
bool CMC_(PFX, _contains)(struct SNAME *_heap_, V value)
{
_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], value) == 0)
{
result = true;
break;
}
}
CMC_CALLBACKS_CALL(_heap_, read);
return result;
}
bool CMC_(PFX, _empty)(struct SNAME *_heap_)
{
return _heap_->count == 0;
}
bool CMC_(PFX, _full)(struct SNAME *_heap_)
{
return _heap_->count >= _heap_->capacity;
}
size_t CMC_(PFX, _count)(struct SNAME *_heap_)
{
return _heap_->count;
}
size_t CMC_(PFX, _capacity)(struct SNAME *_heap_)
{
return _heap_->capacity;
}
int CMC_(PFX, _flag)(struct SNAME *_heap_)
{
return _heap_->flag;
}
bool CMC_(PFX, _resize)(struct SNAME *_heap_, size_t capacity)
{
_heap_->flag = CMC_FLAG_OK;
if (_heap_->capacity == capacity)
goto success;
if (capacity < _heap_->count)
{
_heap_->flag = CMC_FLAG_INVALID;
return false;
}
V *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity);
if (!new_buffer)
{
_heap_->flag = CMC_FLAG_ALLOC;
return false;
}
/* TODO zero out new slots */
_heap_->buffer = new_buffer;
_heap_->capacity = capacity;
success:
CMC_CALLBACKS_CALL(_heap_, resize);
return true;
}
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_heap_)
{
struct SNAME *result = CMC_(PFX, _new_custom)(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, NULL);
if (!result)
{
_heap_->flag = CMC_FLAG_ERROR;
return NULL;
}
CMC_CALLBACKS_ASSIGN(result, _heap_->callbacks);
if (_heap_->f_val->cpy)
{
for (size_t i = 0; i < _heap_->count; i++)
result->buffer[i] = _heap_->f_val->cpy(_heap_->buffer[i]);
}
else
memcpy(result->buffer, _heap_->buffer, sizeof(V) * _heap_->count);
result->count = _heap_->count;
_heap_->flag = CMC_FLAG_OK;
return result;
}
bool CMC_(PFX, _equals)(struct SNAME *_heap1_, struct SNAME *_heap2_)
{
_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++)
{
if (_heap1_->f_val->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0)
return false;
}
return true;
}
static void CMC_(PFX, _impl_float_up)(struct SNAME *_heap_, size_t index)
{
/* Current index */
size_t C = index;
V child = _heap_->buffer[C];
V parent = _heap_->buffer[(index - 1) / 2];
int mod = _heap_->HO;
while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0)
{
/* Swap between C (current element) and its parent */
V tmp = _heap_->buffer[C];
_heap_->buffer[C] = _heap_->buffer[(C - 1) / 2];
_heap_->buffer[(C - 1) / 2] = tmp;
/* Go to parent */
C = (C - 1) / 2;
/* Prevent the two lines below from accessing a negative index */
if (C == 0)
break;
child = _heap_->buffer[C];
parent = _heap_->buffer[(C - 1) / 2];
}
}
static void CMC_(PFX, _impl_float_down)(struct SNAME *_heap_, size_t index)
{
int mod = _heap_->HO;
while (index < _heap_->count)
{
size_t L = 2 * index + 1;
size_t R = 2 * index + 2;
size_t C = index;
/* Determine if we swap with the left or right element */
if (L < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[L], _heap_->buffer[C]) * mod > 0)
{
C = L;
}
if (R < _heap_->count && _heap_->f_val->cmp(_heap_->buffer[R], _heap_->buffer[C]) * mod > 0)
{
C = R;
}
/* Swap only if either left or right was picked, otherwise done */
if (C != index)
{
V tmp = _heap_->buffer[index];
_heap_->buffer[index] = _heap_->buffer[C];
_heap_->buffer[C] = tmp;
index = C;
}
else
break;
}
}
+265
View File
@@ -0,0 +1,265 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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_HEAP_INIT
#endif /* CMC_EXT_HEAP_INIT */
/**
* ITER
*
* Heap bi-directional iterator.
*/
#ifdef CMC_EXT_HEAP_ITER
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target)
{
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)
{
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)
{
return CMC_(PFX, _empty)(iter->target) || iter->start;
}
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter)
{
return CMC_(PFX, _empty)(iter->target) || iter->end;
}
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
if (CMC_(PFX, _empty)(iter->target))
return (V){ 0 };
return iter->target->buffer[iter->cursor];
}
size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter)
{
return iter->cursor;
}
#endif /* CMC_EXT_HEAP_ITER */
/**
* STR
*
* Print helper functions.
*/
#ifdef CMC_EXT_HEAP_STR
bool CMC_(PFX, _to_string)(struct SNAME *_heap_, FILE *fptr)
{
struct SNAME *h_ = _heap_;
const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap";
return 0 <= fprintf(fptr,
"struct %s<%s> "
"at %p { "
"buffer:%p, "
"capacity:%" PRIuMAX ", "
"count:%" PRIuMAX ", "
"type:%s, "
"flag:%d, "
"f_val:%p, "
"alloc:%p, "
"callbacks: %p}",
CMC_TO_STRING(SNAME), CMC_TO_STRING(V), h_, h_->buffer, h_->capacity, h_->count, t, 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)
{
fprintf(fptr, "%s", start);
for (size_t i = 0; i < _heap_->count; i++)
{
if (!_heap_->f_val->str(fptr, _heap_->buffer[i]))
return false;
if (i + 1 < _heap_->count)
fprintf(fptr, "%s", separator);
}
fprintf(fptr, "%s", end);
return true;
}
#endif /* CMC_EXT_HEAP_STR */
+72
View File
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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_HEAP_INIT
#endif /* CMC_EXT_HEAP_INIT */
/**
* ITER
*
* Heap bi-directional iterator.
*/
#ifdef CMC_EXT_HEAP_ITER
/* 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_HEAP_ITER */
/**
* STR
*
* Print helper functions.
*/
#ifdef CMC_EXT_HEAP_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_HEAP_STR */
+45
View File
@@ -0,0 +1,45 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/**
* ITER
*
* Heap bi-directional iterator.
*/
#ifdef CMC_EXT_HEAP_ITER
/* Heap Iterator */
struct CMC_DEF_ITER(SNAME)
{
/* Target heap */
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;
};
#endif /* CMC_EXT_HEAP_ITER */
+66
View File
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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 Allocation and Deallocation */
struct SNAME *CMC_(PFX, _new)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val);
struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, enum cmc_heap_order HO, struct CMC_DEF_FVAL(SNAME) * f_val,
struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *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_, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks);
/* Collection Input and Output */
bool CMC_(PFX, _insert)(struct SNAME *_heap_, V value);
bool CMC_(PFX, _remove)(struct SNAME *_heap_);
/* Element Access */
V CMC_(PFX, _peek)(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_);
+43
View File
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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 */
V *buffer;
/* Current array capacity */
size_t capacity;
/* Current amount of elements in the heap */
size_t count;
/* Heap order (MaxHeap or MinHeap) */
enum cmc_heap_order HO;
/* Flags indicating errors or success */
int flag;
/* Value function table */
struct CMC_DEF_FVAL(SNAME) * f_val;
/* Custom allocation functions */
struct CMC_ALLOC_NODE_NAME *alloc;
/* Custom callback functions */
CMC_CALLBACKS_DECL;
};
+761
View File
@@ -0,0 +1,761 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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)
{
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,
struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *callbacks)
{
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_)
{
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_)
{
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_, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *callbacks)
{
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)
{
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_, create);
return true;
}
bool CMC_(PFX, _remove_max)(struct SNAME *_heap_)
{
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_, delete);
return true;
}
bool CMC_(PFX, _remove_min)(struct SNAME *_heap_)
{
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_, delete);
return true;
}
bool CMC_(PFX, _update_max)(struct SNAME *_heap_, V value)
{
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_, update);
return true;
}
bool CMC_(PFX, _update_min)(struct SNAME *_heap_, V value)
{
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_, update);
return true;
}
V CMC_(PFX, _max)(struct SNAME *_heap_)
{
if (CMC_(PFX, _empty)(_heap_))
{
_heap_->flag = CMC_FLAG_EMPTY;
return (V){ 0 };
}
_heap_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_heap_, read);
/* 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_)
{
if (CMC_(PFX, _empty)(_heap_))
{
_heap_->flag = CMC_FLAG_EMPTY;
return (V){ 0 };
}
_heap_->flag = CMC_FLAG_OK;
CMC_CALLBACKS_CALL(_heap_, read);
return _heap_->buffer[0][0];
}
bool CMC_(PFX, _contains)(struct SNAME *_heap_, V value)
{
_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_, read);
return result;
}
bool CMC_(PFX, _empty)(struct SNAME *_heap_)
{
return _heap_->count == 0;
}
bool CMC_(PFX, _full)(struct SNAME *_heap_)
{
/* 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_)
{
return _heap_->count;
}
size_t CMC_(PFX, _capacity)(struct SNAME *_heap_)
{
return _heap_->capacity;
}
int CMC_(PFX, _flag)(struct SNAME *_heap_)
{
return _heap_->flag;
}
bool CMC_(PFX, _resize)(struct SNAME *_heap_, size_t capacity)
{
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_, resize);
return true;
}
struct SNAME *CMC_(PFX, _copy_of)(struct SNAME *_heap_)
{
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_)
{
_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_)
{
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_)
{
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_)
{
/* 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_)
{
/* 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;
}
}
+266
View File
@@ -0,0 +1,266 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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_INTERVALHEAP_INIT
#endif /* CMC_EXT_INTERVALHEAP_INIT */
/**
* ITER
*
* Intervalheap bi-directional iterator.
*
* TODO allow creation of iterators exclusively for min or max heap
*/
#ifdef CMC_EXT_INTERVALHEAP_ITER
struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME *target)
{
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)
{
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)
{
return CMC_(PFX, _empty)(iter->target) || iter->start;
}
bool CMC_(PFX, _iter_at_end)(struct CMC_DEF_ITER(SNAME) * iter)
{
return CMC_(PFX, _empty)(iter->target) || iter->end;
}
bool CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
return iter->cursor;
}
#endif /* CMC_EXT_INTERVALHEAP_ITER */
/**
* STR
*
* Print helper functions.
*/
#ifdef CMC_EXT_INTERVALHEAP_STR
bool CMC_(PFX, _to_string)(struct SNAME *_heap_, FILE *fptr)
{
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)
{
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_INTERVALHEAP_STR */
+88
View File
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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_INTERVALHEAP_INIT
#endif /* CMC_EXT_INTERVALHEAP_INIT */
/**
* ITER
*
* List bi-directional iterator.
*/
#ifdef CMC_EXT_INTERVALHEAP_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_INTERVALHEAP_ITER */
/**
* STR
*
* Print helper functions.
*/
#ifdef CMC_EXT_INTERVALHEAP_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_INTERVALHEAP_STR */
+23
View File
@@ -0,0 +1,23 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
+72
View File
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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,
struct CMC_ALLOC_NODE_NAME *alloc, struct CMC_CALLBACKS_NAME *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_, struct CMC_ALLOC_NODE_NAME *alloc,
struct CMC_CALLBACKS_NAME *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_);
+44
View File
@@ -0,0 +1,44 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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 */
struct CMC_ALLOC_NODE_NAME *alloc;
/* Custom callback functions */
CMC_CALLBACKS_DECL;
};
+4
View File
@@ -35,6 +35,8 @@
#ifndef CMC_COR_ALLOC_H
#define CMC_COR_ALLOC_H
#ifndef CMC_NO_ALLOC
#ifdef CMC_CAMEL_CASE
#define CMC_ALLOC_NODE_NAME CMCAllocNode
#else
@@ -58,4 +60,6 @@ static struct CMC_ALLOC_NODE_NAME
void (*free)(void *);
} CMC_UNUSED cmc_alloc_node_default = { malloc, calloc, realloc, free };
#endif /* CMC_NO_ALLOC */
#endif /* CMC_COR_ALLOC_H */
+1 -1
View File
@@ -39,7 +39,7 @@
#ifndef CMC_COR_BITSET_H
#define CMC_COR_BITSET_H
#include <stdint.h>
#include "core.h"
/* Defines the underlaying data type for the bitset array */
/* Possible values: uint64_t, uint32_t, uint16_t, uint8_t, size_t */
+5
View File
@@ -45,13 +45,18 @@
#ifndef CMC_COR_CORE_H
#define CMC_COR_CORE_H
#ifndef CMC_NO_IMPORTS
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif /* CMC_NO_IMPORTS */
#if defined(__GNUC__) || defined(__clang__)
#define CMC_UNUSED __attribute__((__unused__))
#else
+88
View File
@@ -0,0 +1,88 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/**
* heap.h
*
* Creation Date: 25/03/2019
*
* Authors:
* Leonardo Vencovsky (https://github.com/LeoVen)
*
*/
/**
* Heap
*
* The Heap is a specialized tree-based data structure which is essentially a
* complete tree that satisfies the heap property:
* - MaxHeap:
* - The root node is the greatest element of the unique set of keys.
* - A node key is always greater than or equal to its children keys.
* - Minheap:
* - The root node is the smallest element of the unique set of keys.
* - A node Key is always greater than or equal to its children keys.
*
* The heap is mostly used to implement priority queues. Sometimes it can also
* be used to sort elements. There are three main functions:
* - insert : Adds an element to the heap
* - remove_(min/max): Removes the min/max element from the heap
* - min/max : Accesses the min/max element from the heap
*/
#include "cor/core.h"
#include "cor/heap.h"
/**
* Used values
* V - heap value data type
* SNAME - struct name and prefix of other related structs
* PFX - functions prefix
*/
/* Structs definition */
#include "cmc/heap/struct.h"
/* Function declaration */
#include "cmc/heap/header.h"
/* Function implementation */
#include "cmc/heap/code.h"
/**
* Extensions
*
* INIT - Initializes the struct on the stack
* ITER - heap iterator
* STR - Print helper functions
*/
#define CMC_EXT_HEAP_PARTS ITER, SETF, STR
/**/
#include "cmc/heap/ext/struct.h"
/**/
#include "cmc/heap/ext/header.h"
/**/
#include "cmc/heap/ext/code.h"
#include "cor/undef.h"
+80
View File
@@ -0,0 +1,80 @@
/**
* Copyright (c) 2019 Leonardo Vencovsky
*
* This file is part of the C Macro Collections Libray.
*
* 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.
*/
/**
* intervalheap.h
*
* Creation Date: 06/07/2019
*
* Authors:
* Leonardo Vencovsky (https://github.com/LeoVen)
*
*/
/**
* Interval Heap
*
* An interval heap is a specialized heap with:
*
* - O(1) - Find Min
* - O(1) - Find Max
* - O(log n) - Insert
* - O(log n) - Remove Min
* - O(log n) - Remove Max
*/
#include "cor/core.h"
/**
* Used values
* V - intervalheap value data type
* SNAME - struct name and prefix of other related structs
* PFX - functions prefix
*/
/* Structs definition */
#include "cmc/intervalheap/struct.h"
/* Function declaration */
#include "cmc/intervalheap/header.h"
/* Function implementation */
#include "cmc/intervalheap/code.h"
/**
* Extensions
*
* INIT - Initializes the struct on the stack
* ITER - intervalheap iterator
* STR - Print helper functions
*/
#define CMC_EXT_HEAP_PARTS ITER, SETF, STR
/**/
#include "cmc/intervalheap/ext/struct.h"
/**/
#include "cmc/intervalheap/ext/header.h"
/**/
#include "cmc/intervalheap/ext/code.h"
#include "cor/undef.h"
+1 -1
View File
@@ -1,5 +1,5 @@
CC=gcc
CFLAGS=-Wall -Wextra -Werror -fprofile-arcs -ftest-coverage -g -O0
CFLAGS=-Wall -Wextra -Werror -fprofile-arcs -ftest-coverage -ftime-report -g -O0
INCLUDE=-I ../src
main:
+12 -12
View File
@@ -1,18 +1,18 @@
#include <inttypes.h>
#include <stdio.h>
// #include "unt_bitset.h"
#include "unt_bitset.h"
#include "unt_deque.h"
#include "unt_hashbidimap.h"
#include "unt_hashmap.h"
#include "unt_hashmultimap.h"
#include "unt_hashmultiset.h"
#include "unt_hashset.h"
// #include "unt_heap.h"
// #include "unt_intervalheap.h"
#include "unt_heap.h"
#include "unt_intervalheap.h"
// #include "unt_linkedlist.h"
#include "unt_list.h"
// #include "unt_queue.h"
#include "unt_queue.h"
// #include "unt_sortedlist.h"
#include "unt_stack.h"
// #include "unt_treemap.h"
@@ -52,8 +52,8 @@ int main(void)
cmc_timer_start(timer);
uintmax_t tests = 0, units = 0;
// cmc_run(CMCBitSet, units, tests);
// cmc_run(CMCBitSetIter, units, tests);
cmc_run(CMCBitSet, units, tests);
cmc_run(CMCBitSetIter, units, tests);
cmc_run(CMCDeque, units, tests);
cmc_run(CMCDequeIter, units, tests);
cmc_run(CMCHashBidiMap, units, tests);
@@ -66,16 +66,16 @@ int main(void)
cmc_run(CMCHashMultiSetIter, units, tests);
cmc_run(CMCHashSet, units, tests);
cmc_run(CMCHashSetIter, units, tests);
// cmc_run(CMCHeap, units, tests);
// cmc_run(CMCHeapIter, units, tests);
// cmc_run(CMCIntervalHeap, units, tests);
// cmc_run(CMCIntervalHeapIter, units, tests);
cmc_run(CMCHeap, units, tests);
cmc_run(CMCHeapIter, units, tests);
cmc_run(CMCIntervalHeap, units, tests);
cmc_run(CMCIntervalHeapIter, units, tests);
// cmc_run(CMCLinkedList, units, tests);
// cmc_run(CMCLinkedListIter, units, tests);
cmc_run(CMCList, units, tests);
cmc_run(CMCListIter, units, tests);
// cmc_run(CMCQueue, units, tests);
// cmc_run(CMCQueueIter, units, tests);
cmc_run(CMCQueue, units, tests);
cmc_run(CMCQueueIter, units, tests);
// cmc_run(CMCSortedList, units, tests);
// cmc_run(CMCSortedListIter, units, tests);
cmc_run(CMCStack, units, tests);
+454
View File
@@ -0,0 +1,454 @@
#ifndef CMC_TESTS_UNT_BITSET_H
#define CMC_TESTS_UNT_BITSET_H
#include "utl.h"
#define PFX bs
#define SNAME bitset
#define CMC_EXT_BITSET_INIT
#define CMC_EXT_BITSET_ITER
#define CMC_EXT_BITSET_STR
#include "cmc/bitset.h"
struct cmc_alloc_node *bs_alloc_node =
&(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
CMC_CREATE_UNIT(CMCBitSet, true, {
const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
printf("%s", cmc_test_color(5));
printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n");
printf("%s", cmc_test_color(0));
CMC_CREATE_TEST(PFX##_new(), {
struct bitset *bs = bs_new(64);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_not_equals(ptr, NULL, bs->buffer);
cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity);
cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs->alloc->free);
cmc_assert_equals(ptr, NULL, bs->callbacks);
bs_free(bs);
bs = bs_new(129);
cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity);
bs_free(bs);
bs = bs_new(0);
cmc_assert_equals(ptr, NULL, bs);
});
CMC_CREATE_TEST(PFX##_new_custom(), {
struct bitset *bs = bs_new_custom(64, bs_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_not_equals(ptr, NULL, bs->buffer);
cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs->capacity);
cmc_assert_equals(ptr, bs_alloc_node, bs->alloc);
cmc_assert_equals(ptr, callbacks, bs->callbacks);
bs_free(bs);
bs = bs_new_custom(129, NULL, NULL);
cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity);
bs_free(bs);
bs = bs_new_custom(0, bs_alloc_node, callbacks);
cmc_assert_equals(ptr, NULL, bs);
});
CMC_CREATE_TEST(PFX##_init(), {
struct bitset bs = bs_init(64);
cmc_assert_not_equals(ptr, NULL, bs.buffer);
cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity);
cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs.alloc->malloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs.alloc->calloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs.alloc->realloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs.alloc->free);
cmc_assert_equals(ptr, NULL, bs.callbacks);
bs_release(bs);
bs = bs_init(129);
cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity);
bs_release(bs);
bs = bs_init(0);
cmc_assert_equals(ptr, NULL, bs.buffer);
});
CMC_CREATE_TEST(PFX##_init_custom(), {
struct bitset bs = bs_init_custom(64, bs_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, bs.buffer);
cmc_assert_equals(size_t, cmc_bidx_to_widx(63) + 1, bs.capacity);
cmc_assert_equals(ptr, bs_alloc_node, bs.alloc);
cmc_assert_equals(ptr, callbacks, bs.callbacks);
bs_release(bs);
bs = bs_init_custom(129, NULL, NULL);
cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity);
bs_release(bs);
bs = bs_init_custom(0, bs_alloc_node, callbacks);
cmc_assert_equals(ptr, NULL, bs.buffer);
});
CMC_CREATE_TEST(PFX##_customize(), {
struct bitset *bs = bs_new(word_bits);
cmc_assert_not_equals(ptr, NULL, bs);
bs->flag = CMC_FLAG_ERROR;
bs_customize(bs, bs_alloc_node, callbacks);
cmc_assert_equals(ptr, bs_alloc_node, bs->alloc);
cmc_assert_equals(ptr, callbacks, bs->callbacks);
cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
bs->flag = CMC_FLAG_ERROR;
bs_customize(bs, NULL, NULL);
cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, bs->alloc->malloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, bs->alloc->calloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, bs->alloc->realloc);
cmc_assert_equals(ptr, cmc_alloc_node_default.free, bs->alloc->free);
cmc_assert_equals(ptr, NULL, bs->callbacks);
cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_set(), {
struct bitset *bs = bs_new(word_bits);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
bs->flag = CMC_FLAG_ERROR;
cmc_assert(bs_set(bs, 0));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]);
cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
bs->buffer[0] = 0;
cmc_assert(bs_set(bs, word_bits - 1));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)), bs->buffer[0]);
cmc_assert(bs_set(bs, word_bits * 8 - 1));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 1)),
bs->buffer[cmc_bidx_to_widx(word_bits * 8 - 1)]);
cmc_assert(bs_set(bs, word_bits * 18 - 2));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)),
bs->buffer[cmc_bidx_to_widx(word_bits * 18 - 2)]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_set_range(), {
struct bitset *bs = bs_new(word_bits);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
bs->flag = CMC_FLAG_ERROR;
cmc_assert(bs_set_range(bs, 0, 0));
cmc_assert_equals(uint8_t, 1, bs->buffer[0]);
cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
cmc_assert(!bs_set_range(bs, 1, 0));
cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag);
bs->buffer[0] = 0;
cmc_assert(bs_set_range(bs, 4, 7)); /* 1111 0000 */
cmc_assert_equals(uint8_t, 240, bs->buffer[0]);
cmc_assert(bs_set_range(bs, 2, 2)); /* 1111 0100 */
cmc_assert_equals(uint8_t, 244, bs->buffer[0]);
cmc_assert(bs_set_range(bs, word_bits * 6 - 2, word_bits * 6 - 2));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ((cmc_bitset_word)1 << (word_bits - 2)),
bs->buffer[cmc_bidx_to_widx(word_bits * 6 - 2)]);
// Make sure we have at least word_bits * 40 slots
bs_set(bs, word_bits * 40);
cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, (~(cmc_bitset_word)0), bs->buffer[cmc_bidx_to_widx(word_bits * 20)]);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20 - 1)]);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 21 + 1)]);
cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1));
cmc_assert_equals(size_t, 100, bs->capacity);
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_clear(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
bs->buffer[0] = 1; // 0001
cmc_assert(bs_clear(bs, 0));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
bs->buffer[0] = 10; // 1010
cmc_assert(bs_clear(bs, 1));
cmc_assert(bs_clear(bs, 3));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_clear(bs, word_bits * 100 - 1));
cmc_assert_equals(size_t, 100, bs->capacity);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_clear_range(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(!bs_clear_range(bs, 1, 0));
cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag);
cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1));
cmc_assert_equals(size_t, 100, bs->capacity);
cmc_assert(bs_set_range(bs, word_bits * 20, word_bits * 21 - 1));
cmc_assert(bs_clear_range(bs, word_bits * 20, word_bits * 21 - 1));
cmc_assert_equals(uint32_t, 0, bs->buffer[cmc_bidx_to_widx(word_bits * 20)]);
for (size_t i = 0; i < bs->capacity; i++)
bs->buffer[i] = ~((cmc_bitset_word)0);
cmc_assert(bs_set_range(bs, 0, word_bits * 100 - 1));
cmc_assert(bs_clear_range(bs, 0, word_bits * 100 - 1));
cmc_assert_equals(size_t, 100, bs->capacity);
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(size_t, 0, bs->buffer[0]);
cmc_assert(bs_clear_range(bs, 0, word_bits * 200 - 1));
cmc_assert_equals(size_t, 200, bs->capacity);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_flip(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_flip(bs, 0));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]);
cmc_assert(bs_flip(bs, 0));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_set_range(bs, 0, 2)); // 0111
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 7, bs->buffer[0]);
cmc_assert(bs_flip(bs, 1)); // 0101
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 5, bs->buffer[0]);
cmc_assert(bs_flip(bs, word_bits * 100 - 1));
cmc_assert_equals(size_t, 100, bs->capacity);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_flip_range(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_flip_range(bs, 0, 0));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]);
cmc_assert(bs_flip_range(bs, 0, 0));
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_flip_range(bs, 1, 4)); // 0001 1110
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 30, bs->buffer[0]);
cmc_assert(bs_flip_range(bs, 2, 3)); // 0001 0010
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 18, bs->buffer[0]);
cmc_assert(bs_flip_range(bs, 0, 2)); // 0001 0101
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 21, bs->buffer[0]);
bs->buffer[0] = 0;
cmc_assert(bs_flip_range(bs, 0, word_bits * 100 - 1));
cmc_assert_equals(size_t, 100, bs->capacity);
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_put(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_put(bs, 1, true)); // 0010
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]);
cmc_assert(bs_put(bs, 0, false)); // 0010
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]);
cmc_assert(bs_put(bs, 1, false)); // 0000
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_put(bs, 3, true)); // 1000
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 8, bs->buffer[0]);
cmc_assert(bs_put(bs, 0, true)); // 1001
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 9, bs->buffer[0]);
cmc_assert(bs_put(bs, 3, false)); // 0001
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 1, bs->buffer[0]);
cmc_assert(bs_put(bs, word_bits * 100 - 1, true));
cmc_assert_equals(size_t, 100, bs->capacity);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_put_range(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
cmc_assert(bs_put_range(bs, 1, 2, true)); // 0110
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 6, bs->buffer[0]);
cmc_assert(bs_put_range(bs, 0, 1, false)); // 0100
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 4, bs->buffer[0]);
cmc_assert(bs_put_range(bs, 1, 3, true)); // 1110
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 14, bs->buffer[0]);
cmc_assert(bs_put_range(bs, 2, 3, false)); // 0010
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 2, bs->buffer[0]);
cmc_assert(bs_put_range(bs, 0, word_bits * 100 - 1, true));
cmc_assert_equals(size_t, 100, bs->capacity);
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
cmc_assert(bs_put_range(bs, 0, word_bits * 100 - 1, false));
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_set_all(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(bs_set_all(bs));
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_clear_all(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(bs_set_all(bs));
cmc_assert(bs_clear_all(bs));
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_flip_all(), {
struct bitset *bs = bs_new(word_bits * 10 - 1);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(bs_flip_all(bs));
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
cmc_assert(bs_flip_all(bs));
for (size_t i = 0; i < bs->capacity; i++)
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[i]);
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_get(), {
struct bitset *bs = bs_new(64);
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert(bs_set(bs, 1));
cmc_assert(bs_get(bs, 1));
bs_free(bs);
});
CMC_CREATE_TEST(PFX##_resize(), {
struct bitset *bs = bs_new(64);
// WIP
bs_free(bs);
});
});
CMC_CREATE_UNIT(CMCBitSetIter, true, {
// const size_t word_bytes = sizeof(cmc_bitset_word);
// const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
printf("%s", cmc_test_color(5));
printf(" BitSet<" CMC_TO_STRING(CMC_BITSET_WORD_TYPE) ">\n");
printf("%s", cmc_test_color(0));
CMC_CREATE_TEST(PFX##_iter_start(), {
struct bitset *bs = bs_new(64);
// WIP
bs_free(bs);
});
});
#endif /* CMC_TESTS_UNT_BITSET_H */
+1 -15
View File
@@ -308,6 +308,7 @@ CMC_CREATE_UNIT(CMCHashMultiMap, true, {
cmc_assert(hmm_equals(map, map2));
hmm_free(map);
hmm_free(map2);
});
CMC_CREATE_TEST(PFX##_equals(), {
@@ -1013,19 +1014,4 @@ CMC_CREATE_UNIT(CMCHashMultiMapIter, true, {
});
});
#ifdef CMC_TEST_MAIN
int main(void)
{
int result = CMCHashMultiMap() + CMCHashMultiMapIter();
printf(" +---------------------------------------------------------------+");
printf("\n");
printf(" | CMCHashMultiMap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED");
printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
#endif /* CMC_TESTS_UNT_HASHMULTIMAP_H */
-15
View File
@@ -853,19 +853,4 @@ CMC_CREATE_UNIT(CMCHashMultiSetIter, true, {
});
});
#ifdef CMC_TEST_MAIN
int main(void)
{
int result = CMCHashMultiSet() + CMCHashMultiSetIter();
printf(" +---------------------------------------------------------------+");
printf("\n");
printf(" | CMCHashMultiSet Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED");
printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
#endif /* CMC_TESTS_UNT_HASHMULTISET_H */
-15
View File
@@ -1033,19 +1033,4 @@ CMC_CREATE_UNIT(CMCHashSetIter, true, {
});
});
#ifdef CMC_TEST_MAIN
int main(void)
{
int result = CMCHashSet() + CMCHashSetIter();
printf(" +---------------------------------------------------------------+");
printf("\n");
printf(" | CMCHashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
#endif /* CMC_TESTS_UNT_HASHSET_H */
+720
View File
@@ -0,0 +1,720 @@
#ifndef CMC_TESTS_UNT_HEAP_H
#define CMC_TESTS_UNT_HEAP_H
#include "utl.h"
#define V size_t
#define PFX h
#define SNAME heap
#define CMC_EXT_HEAP_INIT
#define CMC_EXT_HEAP_ITER
#define CMC_EXT_HEAP_STR
#include "cmc/heap.h"
struct heap_fval *h_fval = &(struct heap_fval){
.cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
CMC_CREATE_UNIT(CMCHeap, true, {
CMC_CREATE_TEST(new, {
struct heap *h = h_new(1000000, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
cmc_assert_not_equals(ptr, NULL, h->buffer);
cmc_assert_equals(size_t, 1000000, h_capacity(h));
cmc_assert_equals(size_t, 0, h_count(h));
h_free(h);
});
CMC_CREATE_TEST(new[edge_case capacity = 0], {
struct heap *h = h_new(0, CMC_MAX_HEAP, h_fval);
cmc_assert_equals(ptr, NULL, h);
});
CMC_CREATE_TEST(new[edge_case capacity = UINT64_MAX], {
struct heap *h = h_new(UINT64_MAX, CMC_MAX_HEAP, h_fval);
cmc_assert_equals(ptr, NULL, h);
});
CMC_CREATE_TEST(clear[count capacity], {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 0; i < 50; i++)
h_insert(h, i);
cmc_assert_equals(size_t, 50, h_count(h));
h_clear(h);
cmc_assert_equals(size_t, 0, h_count(h));
cmc_assert_equals(size_t, 100, h_capacity(h));
h_free(h);
});
CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], {
struct heap *h = h_new(1, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 0; i < 50; i++)
cmc_assert(h_insert(h, i));
cmc_assert_equals(size_t, 50, h_count(h));
h_free(h);
});
CMC_CREATE_TEST(insert, {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
cmc_assert(h_insert(h, 10));
h_free(h);
});
CMC_CREATE_TEST(insert[item preservation], {
struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 0; i <= 100; i++)
cmc_assert(h_insert(h, i));
size_t sum = 0;
for (size_t i = 0; i < h_count(h); i++)
sum += h->buffer[i];
cmc_assert_equals(size_t, 5050, sum);
h_free(h);
});
CMC_CREATE_TEST(remove, {
struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 0; i <= 100; i++)
cmc_assert(h_insert(h, i));
cmc_assert_equals(size_t, 100, h_peek(h));
cmc_assert(h_remove(h));
cmc_assert_equals(size_t, 99, h_peek(h));
h_free(h);
});
CMC_CREATE_TEST(remove[count = 0], {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
cmc_assert(!h_remove(h));
h_free(h);
});
CMC_CREATE_TEST(remove[sorted], {
struct heap *h = h_new(100, CMC_MIN_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 1; i <= 100; i++)
cmc_assert(h_insert(h, i));
size_t i = 0;
size_t arr[100];
while (!h_empty(h))
{
arr[i++] = h_peek(h);
cmc_assert(h_remove(h));
}
cmc_assert_array_sorted_any(size_t, arr, cmc_size_cmp, 0, 99);
h_free(h);
});
CMC_CREATE_TEST(peek, {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 1; i <= 100; i++)
cmc_assert(h_insert(h, i));
cmc_assert_equals(size_t, 100, h_peek(h));
h_free(h);
});
CMC_CREATE_TEST(peek[count = 0], {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
cmc_assert_equals(size_t, (size_t){ 0 }, h_peek(h));
h_free(h);
});
CMC_CREATE_TEST(flags, {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
h->flag = CMC_FLAG_ERROR;
// insert
cmc_assert(h_insert(h, 10));
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
h->flag = CMC_FLAG_ERROR;
// remove
cmc_assert(h_remove(h));
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
cmc_assert(!h_remove(h));
cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h));
// peek
cmc_assert(h_insert(h, 10));
h_peek(h);
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
cmc_assert(h_remove(h));
h_peek(h);
cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h));
// clear
h_clear(h);
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
h->flag = CMC_FLAG_ERROR;
// contains
h_contains(h, 10);
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
h->flag = CMC_FLAG_ERROR;
// copy of
struct heap *h2 = h_copy_of(h);
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h2));
h->flag = CMC_FLAG_ERROR;
h2->flag = CMC_FLAG_ERROR;
// equals
cmc_assert(h_equals(h, h2));
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h2));
h_free(h);
h_free(h2);
});
CMC_CREATE_TEST(callbacks, {
struct heap *h = h_new_custom(100, CMC_MAX_HEAP, h_fval, NULL, callbacks);
cmc_assert_not_equals(ptr, NULL, h);
total_create = 0;
total_read = 0;
total_update = 0;
total_delete = 0;
total_resize = 0;
cmc_assert(h_insert(h, 10));
cmc_assert_equals(int32_t, 1, total_create);
cmc_assert(h_remove(h));
cmc_assert_equals(int32_t, 1, total_delete);
cmc_assert(h_insert(h, 10));
cmc_assert_equals(int32_t, 2, total_create);
cmc_assert_equals(size_t, 10, h_peek(h));
cmc_assert_equals(int32_t, 1, total_read);
cmc_assert(h_contains(h, 10));
cmc_assert_equals(int32_t, 2, total_read);
cmc_assert(h_resize(h, 1000));
cmc_assert_equals(int32_t, 1, total_resize);
cmc_assert(h_resize(h, 100));
cmc_assert_equals(int32_t, 2, total_resize);
cmc_assert_equals(int32_t, 2, total_create);
cmc_assert_equals(int32_t, 2, total_read);
cmc_assert_equals(int32_t, 0, total_update);
cmc_assert_equals(int32_t, 1, total_delete);
cmc_assert_equals(int32_t, 2, total_resize);
h_customize(h, NULL, NULL);
cmc_assert_equals(ptr, NULL, h->callbacks);
h_clear(h);
cmc_assert(h_insert(h, 10));
cmc_assert(h_remove(h));
cmc_assert(h_insert(h, 10));
cmc_assert_equals(size_t, 10, h_peek(h));
cmc_assert(h_contains(h, 10));
cmc_assert(h_resize(h, 1000));
cmc_assert(h_resize(h, 100));
cmc_assert_equals(int32_t, 2, total_create);
cmc_assert_equals(int32_t, 2, total_read);
cmc_assert_equals(int32_t, 0, total_update);
cmc_assert_equals(int32_t, 1, total_delete);
cmc_assert_equals(int32_t, 2, total_resize);
cmc_assert_equals(ptr, NULL, h->callbacks);
h_free(h);
total_create = 0;
total_read = 0;
total_update = 0;
total_delete = 0;
total_resize = 0;
});
});
CMC_CREATE_UNIT(CMCHeapIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_start(h);
cmc_assert_equals(ptr, h, it.target);
cmc_assert_equals(size_t, 0, it.cursor);
cmc_assert_equals(bool, true, it.start);
cmc_assert_equals(bool, true, it.end);
cmc_assert(h_iter_at_start(&it));
cmc_assert(h_iter_at_end(&it));
cmc_assert(h_insert(h, 1));
cmc_assert(h_insert(h, 2));
it = h_iter_start(h);
cmc_assert_equals(size_t, 0, it.cursor);
cmc_assert_equals(bool, false, it.end);
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_end(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_end(h);
cmc_assert_equals(ptr, h, it.target);
cmc_assert_equals(size_t, 0, it.cursor);
cmc_assert_equals(bool, true, it.start);
cmc_assert_equals(bool, true, it.end);
cmc_assert(h_iter_at_start(&it));
cmc_assert(h_iter_at_end(&it));
cmc_assert(h_insert(h, 1));
cmc_assert(h_insert(h, 2));
cmc_assert(h_insert(h, 3));
it = h_iter_end(h);
cmc_assert_equals(size_t, h->count - 1, it.cursor);
cmc_assert_equals(bool, false, it.start);
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_at_start(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_start(h);
// Empty checks
cmc_assert(h_iter_at_start(&it));
it = h_iter_end(h);
cmc_assert(h_iter_at_start(&it));
// Non-empty check
cmc_assert(h_insert(h, 1));
it = h_iter_end(h);
cmc_assert(!h_iter_at_start(&it));
it = h_iter_start(h);
cmc_assert(h_iter_at_start(&it));
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_at_end(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_start(h);
// Empty check
cmc_assert(h_iter_at_end(&it));
it = h_iter_end(h);
cmc_assert(h_iter_at_end(&it));
// Non-empty check
cmc_assert(h_insert(h, 1));
it = h_iter_end(h);
cmc_assert(h_iter_at_end(&it));
it = h_iter_start(h);
cmc_assert(!h_iter_at_end(&it));
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_to_start(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_start(h);
cmc_assert(!h_iter_to_start(&it));
for (size_t i = 1; i <= 100; i++)
{
if (i % 2 == 0)
h_insert(h, i);
else
h_insert(h, i);
}
cmc_assert_equals(size_t, 100, h->count);
it = h_iter_end(h);
cmc_assert(!h_iter_at_start(&it));
cmc_assert(h_iter_at_end(&it));
cmc_assert_equals(size_t, 99, it.cursor);
cmc_assert(h_iter_to_start(&it));
cmc_assert(h_iter_at_start(&it));
cmc_assert(!h_iter_at_end(&it));
cmc_assert_equals(size_t, 0, it.cursor);
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_to_end(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_end(h);
cmc_assert(!h_iter_to_end(&it));
for (size_t i = 1; i <= 100; i++)
{
if (i % 2 == 0)
h_insert(h, i);
else
h_insert(h, i);
}
it = h_iter_start(h);
cmc_assert(h_iter_at_start(&it));
cmc_assert(!h_iter_at_end(&it));
cmc_assert(h_iter_to_end(&it));
cmc_assert(!h_iter_at_start(&it));
cmc_assert(h_iter_at_end(&it));
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_next(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_start(h);
cmc_assert(!h_iter_next(&it));
for (size_t i = 1; i <= 1000; i++)
{
if (i % 2 == 0)
h_insert(h, i);
else
h_insert(h, i);
}
size_t sum = 0;
for (it = h_iter_start(h); !h_iter_at_end(&it); h_iter_next(&it))
{
sum += h_iter_value(&it);
}
cmc_assert_equals(size_t, 500500, sum);
sum = 0;
h_iter_to_start(&it);
do
{
sum += h_iter_value(&it);
} while (h_iter_next(&it));
cmc_assert_equals(size_t, 500500, sum);
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_prev(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_end(h);
cmc_assert(!h_iter_prev(&it));
for (size_t i = 1; i <= 1000; i++)
{
if (i % 2 == 0)
h_insert(h, i);
else
h_insert(h, i);
}
size_t sum = 0;
for (it = h_iter_end(h); !h_iter_at_start(&it); h_iter_prev(&it))
{
sum += h_iter_value(&it);
}
cmc_assert_equals(size_t, 500500, sum);
sum = 0;
h_iter_to_end(&it);
do
{
sum += h_iter_value(&it);
} while (h_iter_prev(&it));
cmc_assert_equals(size_t, 500500, sum);
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_advance(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_start(h);
cmc_assert(!h_iter_advance(&it, 1));
for (size_t i = 1; i <= 1000; i++)
h_insert(h, i);
it = h_iter_start(h);
cmc_assert(!h_iter_advance(&it, 0));
cmc_assert(!h_iter_advance(&it, h->count));
size_t sum = 0;
for (it = h_iter_start(h);;)
{
sum += h_iter_value(&it);
if (!h_iter_advance(&it, 2))
break;
cmc_assert_equals(size_t, 0, h_iter_index(&it) % 2);
}
cmc_assert(h_iter_to_start(&it));
cmc_assert(h_iter_next(&it));
cmc_assert_equals(size_t, 1, h_iter_index(&it));
for (;;)
{
sum += h_iter_value(&it);
if (!h_iter_advance(&it, 2))
break;
cmc_assert_equals(size_t, 1, h_iter_index(&it) % 2);
}
cmc_assert_equals(size_t, 500500, sum);
h_iter_to_start(&it);
cmc_assert(h_iter_advance(&it, h->count - 1));
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_rewind(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_end(h);
cmc_assert(!h_iter_rewind(&it, 1));
for (size_t i = 0; i <= 1000; i++)
h_insert(h, i);
it = h_iter_end(h);
cmc_assert(!h_iter_rewind(&it, 0));
cmc_assert(!h_iter_rewind(&it, h->count));
size_t sum = 0;
for (it = h_iter_end(h);;)
{
sum += h_iter_value(&it);
if (!h_iter_rewind(&it, 2))
break;
cmc_assert_equals(size_t, 0, h_iter_index(&it) % 2);
}
cmc_assert(h_iter_to_end(&it));
cmc_assert(h_iter_prev(&it));
cmc_assert_equals(size_t, h->count - 2, h_iter_index(&it));
for (;;)
{
sum += h_iter_value(&it);
if (!h_iter_rewind(&it, 2))
break;
cmc_assert_equals(size_t, 1, h_iter_index(&it) % 2);
}
cmc_assert_equals(size_t, 500500, sum);
h_iter_to_end(&it);
cmc_assert(h_iter_rewind(&it, h->count - 1));
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_go_to(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_end(h);
cmc_assert(!h_iter_go_to(&it, 0));
it = h_iter_start(h);
cmc_assert(!h_iter_go_to(&it, 0));
for (size_t i = 0; i <= 1000; i++)
h_insert(h, i);
cmc_assert_equals(size_t, 1001, h->count);
it = h_iter_start(h);
size_t sum = 0;
for (size_t i = 0; i < 1001; i++)
{
h_iter_go_to(&it, i);
sum += h_iter_value(&it);
}
cmc_assert_equals(size_t, 500500, sum);
sum = 0;
for (size_t i = 1001; i > 0; i--)
{
cmc_assert(h_iter_go_to(&it, i - 1));
sum += h_iter_value(&it);
}
cmc_assert_equals(size_t, 500500, sum);
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_value(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
struct heap_iter it = h_iter_end(h);
cmc_assert_equals(size_t, (size_t){ 0 }, h_iter_value(&it));
cmc_assert(h_insert(h, 1));
cmc_assert(h_insert(h, 3));
cmc_assert(h_insert(h, 2));
it = h_iter_start(h);
cmc_assert_equals(size_t, 3, h_iter_value(&it));
h_free(h);
});
CMC_CREATE_TEST(PFX##_iter_index(), {
struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
for (size_t i = 0; i <= 1000; i++)
h_insert(h, i);
struct heap_iter it = h_iter_start(h);
for (size_t i = 0; i < 1001; i++)
{
cmc_assert_equals(size_t, i, h_iter_index(&it));
h_iter_next(&it);
}
it = h_iter_end(h);
for (size_t i = 1001; i > 0; i--)
{
cmc_assert_equals(size_t, i - 1, h_iter_index(&it));
h_iter_prev(&it);
}
h_free(h);
});
});
#endif /* CMC_TESTS_UNT_HEAP_H */
File diff suppressed because it is too large. Load diff
-15
View File
@@ -837,19 +837,4 @@ CMC_CREATE_UNIT(CMCStackIter, true, {
});
});
#ifdef CMC_TEST_MAIN
int main(void)
{
int result = CMCStack() + CMCStackIter();
printf(" +---------------------------------------------------------------+");
printf("\n");
printf(" | CMCStack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
#endif /* CMC_TESTS_UNT_STACK_H */