diff --git a/.clang-format b/.clang-format index 36f4664..3c0bd05 100644 --- a/.clang-format +++ b/.clang-format @@ -1,13 +1,13 @@ # clang-format 9.0.0 Language: Cpp BasedOnStyle: LLVM -AlignEscapedNewlines: Left +AlignEscapedNewlines: DontAlign AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false BreakBeforeBraces: Allman BreakStringLiterals: false -ColumnLimit: 80 +ColumnLimit: 120 Cpp11BracedListStyle: false ForEachMacros: ["CMC_FOREACH", "CMC_FOREACH_REV"] IndentCaseLabels: true diff --git a/.github/workflows/test_suit.yml b/.github/workflows/test_suit.yml index c51bb75..e60a5df 100644 --- a/.github/workflows/test_suit.yml +++ b/.github/workflows/test_suit.yml @@ -10,8 +10,8 @@ jobs: steps: - uses: actions/checkout@v2 - name: Setup Environment - run: sudo apt install make valgrind gcc + run: sudo apt install make valgrind gcc python - name: Test Suite - run: make -C ./tests/main nocov - - name: Valgrind Test - run: make -C ./tests/main valgrind + run: python autogen.py -e -b -r -nf + # - name: Valgrind Test + # run: make -C ./tests/main valgrind diff --git a/.gitignore b/.gitignore index a2d2de1..d755066 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,6 @@ dkms.conf # Experimental folder experimental/ + +# Test / Code Coverage build folder +build diff --git a/.travis.yml b/.travis.yml index ff0bf29..eb93d61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,23 @@ -dist: trusty +dist: xenial os: linux language: c compiler: gcc addons: apt: sources: + - deadsnakes - ubuntu-toolchain-r-test packages: - - gcc-7 + - gcc-9 - cmake + - python3.8 script: - - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc - - export CC=gcc-7 -# - make -C ./tests/ - - make -C ./tests/main/ + - sudo ln -s /usr/bin/gcc-9 /usr/local/bin/gcc + - sudo ln -s /usr/bin/gcov-9 /usr/local/bin/gcov + - sudo ln -s /usr/bin/python3.8 /usr/local/bin/python + - gcc --version + - gcov --version + - python --version + - python autogen.py -e -b -cv -r -nf after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/CHANGELOG b/CHANGELOG index 922e52d..120734c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,22 @@ # RELEASE.MAJOR.MINOR +0.24.0 + A lot of breaking changes, with the library more modular now + Comeback of PUBLIC and PRIVATE for the CMC sub-library + Callbacks are now optional and can be turned off by defining CMC_NO_CALLBACKS + Added EXT library + New macro CMC_CAMEL_CASE can change the library's style where the default is snake case + Added: + ./cor/alloc.h + ./cor/callbacks.h + ./cor/heap.h + Complete rework of tests and code coverage using autogen.py + Removed cmc_flags, where now every flag is an enum (CMC_FLAGS_OK, CMC_FLAGS_ERROR, etc) + Different include guards + New way to generate code using PARAM + Code now completely changed by using the CMC_ macro to concatenate tokens + Token concatenation with SNAME now uses special macros that allow customization of the suffixes + 0.23.1 Added ./cor/bitset.h Added foreach tests @@ -8,6 +25,7 @@ 0.23.0 Added ./cmc/bitset.h + Added ./cor/flags.h Added ./utl/futils.h Added ./utl/mutex.h Added ./utl/thread.h diff --git a/Makefile b/Makefile deleted file mode 100644 index 64ac000..0000000 --- a/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# This file is useful to format all the source files and header in this library using clang-format - -.PHONY: all cmc dev sac utl tests FORCE - -all: cmc cor dev sac utl tests - -cmc: FORCE - clang-format --style=file -i ./src/cmc/*.h - -cor: FORCE - clang-format --style=file -i ./src/cor/*.h - -dev: FORCE - clang-format --style=file -i ./src/dev/*.h - -sac: FORCE - clang-format --style=file -i ./src/sac/*.h - -utl: FORCE - clang-format --style=file -i ./src/utl/*.h - -tests: FORCE - clang-format --style=file -i ./tests/main/unt/*.c ./tests/main/main.c ./tests/*.c - -FORCE: diff --git a/README.md b/README.md index d85b64f..239129e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@
-
+
@@ -21,13 +21,133 @@
## Table of Contents
-* Project Structure
-* Available Collections
-* Features
-* Overall To-Do
-* Design Decisions
-* What to use
-* How to use
+* [Installation](#installation)
+* [Contributing](#contributing)
+* [Usage](#usage)
+* [Features](#features)
+* [Project Structure](#project-structure)
+* [Available Collections](#available-collections)
+* [Other Features](#other-features)
+* [Design Decisions](#design-decisions)
+* [What to use](#what-to-use)
+* [Code Review](#code-review)
+
+## Installation
+
+No installation is required. The entire library is made of header files and can be directly included into your project.
+
+## Contributing
+
+There is a lot to be done. You can check the `TODO` file in the root of the repository or the issues in the github page. Also, tests and documentation are in constant development. Also check out the `STATUS` file for the status on the development of the library.
+
+## Usage
+
+The header `macro_collections.h` includes every feature from the library and comes with higher level APIs that help you generate collections from specific sub-libraries with specific extensions.
+
+Below is a minimal example that makes use of some core functionalities. And a lot of explanation too!
+
+```c
+// This is the master header. This will include every feature of the library.
+// This comes with many helper macros (high level API) and utility functions.
+#include "macro_collections.h"
+
+// A PARAM is a standard way to pass required parameters to the lower level API.
+// It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them
+// are used, so we can leave them empty. We are creating a list of value int.
+#define MY_LIST_PARAMS (intl, int_list, , , int)
+
+// High level API. Generate a LIST from the CMC library with the STR extension
+// using our previously defined PARAMs. Every collections has a CORE part that
+// needs to be generated first. Then, we can add other parts after. This macro
+// does all of that for us. The STR part will provide us with a function that
+// will be used later.
+C_MACRO_COLLECTIONS_GEN(CMC, LIST, MY_LIST_PARAMS, (STR))
+
+int main(void)
+{
+ // Our list type is defined by SNAME and all functions are prefixed by PFX
+ // (PFX can also be thought as the function's namespace). Also, nodes,
+ // entries, iterators and other structures are prefixed by SNAME. So PFX is
+ // for functions and SNAME is for structs, where the main one is simply
+ // 'struct SNAME'.
+ // To initialize a list we need to pass in an initial capacity and something
+ // that is called a function table for the V type.
+ // This function table is a struct with methods that will extract some
+ // (sometimes) necessary behaviour from your custom data type. Things like
+ // hash, comparison and printing. A list doesn't require any of these
+ // functions. That is, the CORE module doesn't use any of them.
+ // But since we are using the STR module, we will need to define the 'str'
+ // function. luckily, for the 'int' type, the library already provides such
+ // function (cmc_i32_str), provided by the /utl/futils.h header file.
+ struct int_list *list = intl_new(32, &(struct int_list_fval){ .str = cmc_i32_str, NULL });
+
+ // Check if the list was successfully initialized. It could fail if the
+ // initial capacity is too big or if 'struct int_list_fval *' is NULL,
+ // because every data structure must have a valid function table.
+ if (!list)
+ return 1;
+
+ // Add some items to the list. The CMC data structures are all dynamically
+ // sized. So there can be as many items as you want as long as you have
+ // enough memory.
+ for (int i = 0; i < 100; i++)
+ {
+ // Try to add an element to the list. If it fails you can check what
+ // caused it by getting its flag.
+ if (!intl_push_back(list, i))
+ {
+ enum cmc_flags flag = intl_flag(list);
+ // Use cmc_flags_to_str to map the enum error to a string.
+ fprintf(stderr, "%s : push_back failed\n", cmc_flags_to_str[flag]);
+ }
+ }
+
+ // Now we will use the STR module, the _print() function. This is where the
+ // '.str' from the function table comes into play. If we haven't defined it,
+ // the program would've crashed. We also need to define to which file we
+ // will be printing the list's content. In this case, the terminal. Also,
+ // some strings need to be defined. They will be printed: before all elements,
+ // between each one, and after all elements. This is very usefull and can
+ // print a data structure very nicely.
+ intl_print(list, stdout, "[ ", ", ", " ]\n");
+
+ // You should see a nicely printed list in your terminal.
+
+ // Free all of its resources
+ intl_free(list);
+}
+```
+
+Now all you have to do is to compile the source code with `-I /path/to/library/src`. There is no required installation or pre-compilation.
+
+## Features
+
+The C Macro Collections library is organized into many other sub-libraries. The following table is a quick overview.
+
+| Library | Name | Description |
+| :-----: | -------------------------------- | ------------------------------------------------------------------------------------------- |
+| CMC | Macro Collections | The main library with dynamically-sized collections |
+| COR | Core | Core functionalities used by more than one collection, usually from different sub-libraries |
+| EXT | Extensions | Extension to collections from CMC, SAC and TSC libraries |
+| INT | Integrations | Macros that facilitate the creation of code that involves more than one type of collection |
+| SAC | Statically Allocated Collections | Collections with a fixed sized array that don't use any heap allocation |
+| TSC | Thread-Safe Collections | Collections that allow multiple operations from multiple threads |
+| UTL | Utilities | General utilities |
+
+Every macro that generates code for a certain collection can be found with the following template. Some exceptions exist as certain collections don't have or can't have some features. One big example is the `UTL` library, which does not follow this pattern.
+
+```
+macro_name := CMC_[ lib ]_[ collection ]_[ part ]_[ file ]
+
+lib := CMC | COR | DEV | EXT | INT | SAC | TSC
+collection := BITSET | DEQUE | HASHBIDIMAP | ... | TREEMULTISET | TREESET
+part := CORE | ITER | INIT | ... | SETF | NODE
+file := HEADER | SOURCE
+```
+
+__Some `collection`s might not be present in a certain `lib`. Check the documentation.__
+
+Every macro is suffixed by `CMC` and each section is separated by an underscore (`_`). The first section is the library (`lib`). The second is the collection name in all uppercase. Then the `part` (or which module) that you wish to generate. And last, if it is code that should belong to a header file or code that should belong to a source file.
## Project Structure
@@ -38,53 +158,46 @@
* __src__ - All headers part of the C Macro Collections Library
* __cmc__ - The main C Macro Collections Library
* __cor__ - Core includes in the C Macro Collections Library
- * __dev__ - The main C Macro Collections Library for development (containing logging)
- * __sac__ - Statically Allocated Collections
- * __utl__ - Utility like ForEach macros, logging, etc
+ * __ext__ - Extensions to the CMC, SAC and TSC collections
+ * __int__ - Integrations between Collections
+ * __sac__ - Statically Allocated Collections
+ * __tsc__ - Thread Safe Collections
+ * __utl__ - Utilities like ForEach macros, logging, etc
* __macro\_collections.h__ - Master header containing all collections and utilities
* __tests__ - Where all tests are hosted
## Available Collections
-* Linear Collections
- * List, LinkedList, Deque, Stack, Queue, SortedList
-* Sets
- * HashSet, TreeSet, HashMultiSet
-* Maps
- * HashMap, TreeMap, HashMultiMap
-* Bidirectional Maps
- * HashBidiMap
-* Heaps
- * Heap, IntervalHeap
-* WIP
- * BitSet, Matrix, TreeBidiMap, TreeMultiMap, TreeMultiSet
+Check out the STATUS file at the root of the project for more information.
__The following table is an overview of all the currently available or upcoming data structures__:
-| Collection
| Abstract Data Type
| Data Structure
| Details |
-| :--------------------------------: | :---------------------------------: | :-----------------------------: | :-----------------------------------: |
-| BitSet
_bitset.h_ | Set | Dynamic Array | A set of bits that can be individually modified and queried, each identified by a bit index |
-| Deque
_deque.h_ | Double-Ended Queue | Dynamic Circular Array | A circular array that allows `push` and `pop` on both ends (only) at constant time |
-| HashBidiMap
_hashbidimap.h_ | Bidirectional Map | Two Hashtables | A bijection between two sets of unique keys and unique values `K <-> V` using two hashtables |
-| HashMap
_hashmap.h_ | Map | Flat Hashtable | A unique set of keys associated with a value `K -> V` with constant time look up using a hashtable with open addressing and robin hood hashing |
-| HashMultiMap
_hashmultimap.h_ | Multimap | Hashtable | A mapping of multiple keys with one node per key using a hashtable with separate chaining |
-| HashMultiSet
_hashmultiset.h_ | Multiset | Flat Hashtable | A mapping of a value and its multiplicity using a hashtable with open addressing and robin hood hashing |
-| HashSet
_hashset.h_ | Set | Flat Hashtable | A unique set of values with constant time look up using a hashtable with open addressing and robin hood hashing |
-| Heap
_heap.h_ | Priority Queue | Dynamic Array | A binary heap as a dynamic array as an implicit data structure |
-| IntervalHeap
_intervalheap.h_ | Double-Ended Priority Queue | Custom Dynamic Array | A dynamic array of nodes, each hosting one value from the MinHeap and one from the MaxHeap |
-| LinkedList
_linkedlist.h_ | List | Doubly-Linked List | A default doubly-linked list |
-| List
_list.h_ | List | Dynamic Array | A dynamic array with `push` and `pop` anywhere on the array |
-| Matrix
_WIP_ | Regular Matrix | Dynamic Array of Dynamic Arrays | A regular matrix with arbitrary rows and columns |
-| Queue
_queue.h_ | FIFO | Dynamic Circular Array | A queue using a circular array with `enqueue` at the `back` index and `dequeue` at the `front` index |
-| SortedList
_sortedlist.h_ | Sorted List | Sorted Dynamic Array | A lazily sorted dynamic array that is sorted only when necessary |
-| Stack
_stack.h_ | FILO | Dynamic Array | A stack with push and pop at the end of a dynamic array |
-| TreeBidiMap
_WIP_ | Sorted Bidirectional Map | Two AVL Trees | A sorted bijection between two sets of unique keys and unique values `K <-> V` using two AVL trees |
-| TreeMap
_treemap.h_ | Sorted Map | AVL Tree | A unique set of keys associated with a value `K -> V` using an AVL tree with `log(n)` look up and sorted iteration |
-| TreeMultiMap
_WIP_ | Sorted Multimap | AVL Tree | A sorted mapping of multiple keys with one node per key using an AVL Tree of linked-lists |
-| TreeMultiSet
_WIP_ | Sorted Multiset | AVL Tree | A sorted mapping of a value and its multiplicity using an AVL tree |
-| TreeSet
_treeset.h_ | Sorted Set | AVL Tree | A unique set of keys using an AVL tree with `log(n)` look up and sorted iteration |
+| Collection | Abstract Data Type
| Data Structure
| Details |
+| :--------------------------------: | :---------------------------------: | :-----------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------: |
+| BitSet
_bitset.h_ | Set | Dynamic Array | A set of bits that can be individually modified and queried, each identified by a bit index |
+| Deque
_deque.h_ | Double-Ended Queue | Dynamic Circular Array | A circular array that allows `push` and `pop` on both ends (only) at constant time |
+| HashBidiMap
_hashbidimap.h_ | Bidirectional Map | Two Hashtables | A bijection between two sets of unique keys and unique values `K <-> V` using two hashtables |
+| HashMap
_hashmap.h_ | Map | Flat Hashtable | A unique set of keys associated with a value `K -> V` with constant time look up using a hashtable with open addressing and robin hood hashing |
+| HashMultiMap
_hashmultimap.h_ | Multimap | Hashtable | A mapping of multiple keys with one node per key using a hashtable with separate chaining |
+| HashMultiSet
_hashmultiset.h_ | Multiset | Flat Hashtable | A mapping of a value and its multiplicity using a hashtable with open addressing and robin hood hashing |
+| HashSet
_hashset.h_ | Set | Flat Hashtable | A unique set of values with constant time look up using a hashtable with open addressing and robin hood hashing |
+| Heap
_heap.h_ | Priority Queue | Dynamic Array | A binary heap as a dynamic array as an implicit data structure |
+| IntervalHeap
_intervalheap.h_ | Double-Ended Priority Queue | Custom Dynamic Array | A dynamic array of nodes, each hosting one value from the MinHeap and one from the MaxHeap |
+| LinkedList
_linkedlist.h_ | List | Doubly-Linked List | A default doubly-linked list |
+| List
_list.h_ | List | Dynamic Array | A dynamic array with `push` and `pop` anywhere on the array |
+| Queue
_queue.h_ | FIFO | Dynamic Circular Array | A queue using a circular array with `enqueue` at the `back` index and `dequeue` at the `front` index |
+| SkipList
_WIP_ | Sorted List | Skip List | A sorted Linked List with average O(log n) search, insertion and deletion complexity |
+| SortedList
_sortedlist.h_ | Sorted List | Sorted Dynamic Array | A lazily sorted dynamic array that is sorted only when necessary |
+| Stack
_stack.h_ | FILO | Dynamic Array | A stack with push and pop at the end of a dynamic array |
+| TreeBidiMap
_WIP_ | Sorted Bidirectional Map | Two AVL Trees | A sorted bijection between two sets of unique keys and unique values `K <-> V` using two AVL trees |
+| TreeMap
_treemap.h_ | Sorted Map | AVL Tree | A unique set of keys associated with a value `K -> V` using an AVL tree with `log(n)` look up and sorted iteration |
+| TreeMultiMap
_WIP_ | Sorted Multimap | AVL Tree | A sorted mapping of multiple keys with one node per key using an AVL Tree of linked-lists |
+| TreeMultiSet
_WIP_ | Sorted Multiset | AVL Tree | A sorted mapping of a value and its multiplicity using an AVL tree |
+| TreeSet
_treeset.h_ | Sorted Set | AVL Tree | A unique set of keys using an AVL tree with `log(n)` look up and sorted iteration |
-## Features
+## Other Features
+
+These are some features within the library that are implemented by all collections.
### Two-way iterators
@@ -136,8 +249,8 @@ A priority function works much like the comparator function except that it compa
The following table shows which functions are required, optional or never used for each Collection:
-| Collection | CMP | CPY | STR | FREE | HASH | PRI |
-| ---------- | :-: | :-: | :-: | :--: | :--: | :-: |
+| Collection | CMP | CPY | STR | FREE | HASH | PRI |
+| ------------ | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: | :------------------------------------------------------: |
| Deque |  |  |  |  |  |  |
| HashMap |  |  |  |  |  |  |
| HashBidiMap |  |  |  |  |  |  |
@@ -154,23 +267,13 @@ The following table shows which functions are required, optional or never used f
| TreeMap |  |  |  |  |  |  |
| TreeSet |  |  |  |  |  |  |
-| Color | Label |
-| :---: | ----- |
-|  | Required for basic functionality. |
-|  | Required for specific functions. |
+| Color | Label |
+| :------------------------------------------------------: | ----------------------------------------- |
+|  | Required for basic functionality. |
+|  | Required for specific functions. |
|  | Required for non-core specific functions. |
-|  | Optional. |
-|  | Not Used. |
-
-## Overall To-Do
-
-In the long term, these are the steps left for the completion of this library:
-
-* Complete the implementation of all the functions in the scope of the TODO file for the main collections;
-* Reorganize and complete all tests for the `cmc` collections;
-* Make an exact copy of all collections to `dev` with many logging utility, for them to be used under development;
-* Port all of these collections to be statically allocated and be part of the `sac` library;
-* Complete all tests for `sac`.
+|  | Optional. |
+|  | Not Used. |
## Design Decisions
@@ -198,6 +301,8 @@ Modifying a collection will possibly invalidate all iterators currently initiali
## What to use
+(Outdated)
+
The following table shows how each collection is implemented and how well they do when using as common [abstract data types](https://en.wikipedia.org/wiki/Abstract_data_type).
* **Ideal** - The collection implements correctly the abstract data type;
@@ -210,62 +315,14 @@ The following table shows how each collection is implemented and how well they d


-## How to use
+## Code Review
-To generate the collection, all you need to do is to include the necessary header files. You can include the containers you want to use individually or you can include the master header, `macro_collections.h`, that comes with the entire C-Macro-Collections library.
+Check out some code reviews that covers some parts the project. Most of them were posted a long time ago and are probably outdated.
-### Macros
-
-> Note here that `SNAME` represents the uppercase name of the collection.
-
-Every collection is separated by two parts:
-
-* `HEADER` - Contains all struct definitions and function definitions.
-* `SOURCE` - Contains all function implementations.
-
-All collections have three main macros:
-
-* `CMC_GENERATE_SNAME` - Generates `CMC_GENERATE_SNAME_HEADER` and `CMC_GENERATE_SNAME_SOURCE`.
-
-Or you can generate each part individually:
-
-* `CMC_GENERATE_SNAME_HEADER` - Generates all struct definitions and function definitions.
-* `CMC_GENERATE_SNAME_SOURCE` - Generates all function implementations.
-
-### Parameters
-
-When including `macro_collections.h` in your source code you gain access to a macro called `CMC_COLLECTION_GENERATE` with the following parameters:
-
-* __C__ - Container name in uppercase (*BIDIMAP*, *DEQUE*, *HASHMAP*, *HASHSET*, *HEAP*, *INTERVALHEAP*, *LINKEDLIST*, *LIST*, *MULTIMAP*, *MULTISET*, *QUEUE*, *SORTEDLIST*, *STACK*, *TREEMAP*, *TREESET*).
-* __PFX__ - Functions prefix or namespace.
-* __SNAME__ - Structure name (`struct SNAME`).
-* __K__ - Key type. Only used in *HASHMAP*, *TREEMAP*, *MULTIMAP* and *BIDIMAP*; ignored by others.
-* __V__ - Value type. Primary type for most collections, or value to be mapped by *HASHMAP*, *TREEMAP*, *MULTIMAP* and *BIDIMAP*.
-
-**In fact, all macros follow this pattern.** So whenever you see a macro with a bunch of parameters and you don't know what they are, you can check out the above list.
-
-### For Each
-
-There are 2 for-each macros:
-
-* `CMC_FOREACH` - Starts at the start of the collection towards the end.
-* `CMC_FOREACH_REV` - Starts at the end of the collection towards the start.
-
-* __PFX__ - Functions prefix or namespace.
-* __SNAME__ - Structure name.
-* __TARGET__ - The variable name of the collection you wish to iterate over.
-* __ITERNAME__ - Iterator variable name.
-
-For `CMC_FOREACH` and `CMC_FOREACH_REV` you will be able to name the iterator variable through the __ITERNAME__ parameter.
-
-
.+){UNIQUE_FLAG}', result)
+
+ if match is None:
+ os.remove(TMP_FILE)
+ print('Didn\'t match FLAG. Probably because compilation failed.', file=sys.stderr)
+ exit(1)
+
+ file = open(f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}', 'w')
+
+ if ftype == 'HEADER':
+ file.write(
+ f'''
+ #ifndef CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H
+ #define CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H
+
+ #include "macro_collections.h"
+ {match.group('code')}
+
+ #endif /* CMC_{data['LIB']}_{data['COLLECTION']}_TEST_H */
+ ''')
+ else:
+ file.write(
+ f'''
+ #include {data["h"]}
+
+ {match.group("code")}
+ ''')
+
+ file.flush()
+ file.close()
+
+ print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{DIR_MAP[ftype]}/{data["LIB"].lower()}/{data["SNAME"]}.{EXT_MAP[ftype]}')
+
+ os.remove(TMP_FILE)
+
+
+def format_expand():
+ '''
+ Format the files outputted by 'expand_code'.
+ '''
+ cmd = ['clang-format', '--style=file', '--verbose', '-i']
+ dirs_to_format = [f'{OUTPUT_DIR}/{DIR_MAP[ftype]}/{lib.lower()}/*.{EXT_MAP[ftype]}' for ftype in DIR_MAP.keys() for lib in ALL_LIBS]
+ cmd.extend(dirs_to_format)
+ execute_command(cmd)
+
+
+def format_code(source: bool, tests: bool):
+ '''
+ Format all source files from the main library or test files.
+ '''
+ if source:
+ execute_command(['find', './src/', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i'])
+ if tests:
+ execute_command(['find', './tests/', '-name', '*.c', '-o', '-name', '*.h', '|', 'xargs', 'clang-format', '--style=file', '--verbose', '-i'])
+
+
+def build_tests(with_coverage: bool):
+ '''
+ Build all object files and the main executable for tests
+ '''
+ cflags = CFLAGS.copy()
+
+ if with_coverage:
+ cflags += CVFLAGS
else:
- # only V
- type_params = f', {data["val"]}'
+ cflags += ['-O3']
- file.write(
- f'''
- #include {data['h']}
+ for data in COLLECTIONS:
+ cmd = [CC]
+ cmd += cflags
+ cmd += TINCLUDE # This one needs to go first
+ cmd += INCLUDE
+ cmd += ['-c', f"{SRC_DIR}/{data['LIB'].lower()}/{data['SNAME']}.c"]
+ cmd += ['-o', f"{OBJ_DIR}/{data['LIB'].lower()}/{data['SNAME']}.o"]
+ execute_command(cmd)
- {UNIQUE_FLAG}
+ # Build OUTPUT_DIR/main.c
+ cmd = [CC]
+ cmd += cflags
+ cmd += TINCLUDE # This one needs to go first
+ cmd += INCLUDE
+ cmd += ['-c', f'{OUTPUT_DIR}/main.c']
+ cmd += ['-o', f"{OBJ_DIR}/main.o"]
+ execute_command(cmd)
- CMC_GENERATE_{data['t']}({data['pfx']}, {data['sname']}{type_params})
+ # Link everything producing OUTPUT_DIR/main.exe
+ cmd = [CC]
+ cmd += cflags
+ cmd += LFLAGS
+ cmd += ['-o', TEST_EXE]
+ cmd += [f'{OBJ_DIR}/main.o']
+ cmd += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.o' for data in COLLECTIONS]
+ execute_command(cmd)
- {UNIQUE_FLAG}
- ''')
- file.flush()
- file.close()
+def run_tests(coverage: bool):
+ '''
+ Runs tests. If coverage, run gcov.
+ '''
+ execute_command([full_path(TEST_EXE)])
- result = subprocess.getoutput(f'{CC} {FLAGS} {INCLUDE} {TMP_FILE}')
+ if coverage:
+ objects = [f'{OBJ_DIR}/main.gcda']
+ objects += [f'{OBJ_DIR}/{data["LIB"].lower()}/{data["SNAME"]}.gcda' for data in COLLECTIONS]
+ execute_command(['gcov'] + GCOV_FLAGS + objects)
+ execute_command(['mv', '*.gcov', GCOV_DIR])
- # (?s) makes '.' match anything, even '\n'
- match = re.search(fr'(?s){UNIQUE_FLAG}(?P.+){UNIQUE_FLAG}', result)
- if match is None:
- os.remove(TMP_FILE)
- print('Didn\'t match FLAG. Probably because compilation failed.')
- exit(1)
+if __name__ == '__main__':
+ p = argparse.ArgumentParser('autogen.py', usage='%(prog)s [options]')
- file = open(f'{OUTPUT_DIR}/{data["sname"]}.c', 'w')
+ p.add_argument('-sc', '--show-config',
+ help='Displays the current configuration',
+ action='store_true',
+ dest='config')
- file.write(
- f'''#ifndef CMC_TEST_SRC_{data['t']}
- #define CMC_TEST_SRC_{data['t']}
+ tests = p.add_argument_group('tests', 'For dealing with tests')
- #include {data["h"]}\n{match.group("code")}
+ tests.add_argument('-c', '--clean',
+ help='Cleans all build objects',
+ default=False,
+ action='store_true',
+ dest='clean')
+ tests.add_argument('-cf', '--clean-full',
+ help='Cleans all build objects, source and header files, and removes folders',
+ default=False,
+ action='store_true',
+ dest='cleanfull')
+ tests.add_argument('-e', '--expand',
+ help='Expands the header and source files',
+ default=False,
+ action='store_true',
+ dest='expand')
+ tests.add_argument('-nf', '--no-format',
+ help='Does not format the output of expand. Can be used when you might not have clang-format',
+ default=False,
+ action='store_true',
+ dest='noformat')
+ tests.add_argument('-b', '--build',
+ help='Compile the object files and the main executable',
+ default=False,
+ action='store_true',
+ dest='build')
+ tests.add_argument('-r', '--run',
+ help='Runs tests, assuming that it is already built',
+ default=False,
+ action='store_true',
+ dest='run')
+ tests.add_argument('-cv', '--coverage',
+ help='Adds the code coverage flags for compilation',
+ default=False,
+ action='store_true',
+ dest='coverage')
+ tests.add_argument('-rr', '--rerun',
+ help='Compile the object files again and then run the tests',
+ default=False,
+ action='store_true',
+ dest='rerun')
- #endif /* CMC_TEST_SRC_{data['t']} */
- ''')
+ source = p.add_argument_group('source', 'For dealing with the source files and formatting')
- file.flush()
- file.close()
+ source.add_argument('-fs', '--format-source',
+ help='Format the source code',
+ default=False,
+ action='store_true',
+ dest='fmt_source')
+ source.add_argument('-ft', '--format-tests',
+ help='Format tests files',
+ default=False,
+ action='store_true',
+ dest='fmt_tests')
- print(f'Generated {data["h"]: >20} -> {OUTPUT_DIR}/{data["sname"]}.c')
+ args = p.parse_args()
-os.remove(TMP_FILE)
+ if args.config:
+ print(CONFIG)
+ exit(0)
-# Format all files
-print('Formating files...')
-subprocess.call(['clang-format', '--style=file', '-i', f'{OUTPUT_DIR}/*.c'])
-print('Done')
+ if args.clean or args.cleanfull:
+ clean_build(args.cleanfull)
+
+ if not args.cleanfull:
+ assert_structure()
+ assert_executable(CC)
+
+ if args.expand:
+ expand_code()
+ if not args.noformat:
+ assert_executable('clang-format')
+ format_expand()
+ else:
+ # In case the next task is to build the code from source
+ # This warning is a very annoying one from gcc
+ CFLAGS += ['-Wno-misleading-indentation']
+
+ if args.fmt_source or args.fmt_tests:
+ assert_executable('find')
+ assert_executable('xargs')
+ format_code(args.fmt_source, args.fmt_tests)
+
+ if args.build:
+ build_tests(args.coverage)
+ if args.run:
+ run_tests(args.coverage)
+ elif args.rerun:
+ build_tests(args.coverage)
+ run_tests(args.coverage)
+ elif args.run:
+ run_tests(args.coverage)
diff --git a/benchmarks/C++ Comparison/hashtable/hashmap.c b/benchmarks/C++ Comparison/hashtable/hashmap.c
new file mode 100644
index 0000000..5956b8b
--- /dev/null
+++ b/benchmarks/C++ Comparison/hashtable/hashmap.c
@@ -0,0 +1,62 @@
+#ifndef COUNT
+#error "Please define COUNT"
+#endif
+
+#include "murmurhash.h"
+
+#include "macro_collections.h"
+
+#include "../../util/twister.c"
+
+CMC_CMC_HASHMAP_CORE(PUBLIC, HEADER, (hm, hashmap, , uint64_t, uint64_t))
+CMC_CMC_HASHMAP_CORE(PUBLIC, SOURCE, (hm, hashmap, , uint64_t, uint64_t))
+
+int cmp(uint64_t a, uint64_t b)
+{
+ return (a > b) - (a < b);
+}
+
+// size_t hash(uint64_t a)
+// {
+// size_t x = (size_t)a;
+// x = ((x >> 16) ^ x) * 0x45d9f3b;
+// x = ((x >> 16) ^ x) * 0x45d9f3b;
+// x = (x >> 16) ^ x;
+// return x;
+// }
+
+size_t hash(uint64_t k)
+{
+ static size_t seed = 211106232532969;
+ return MurMurHash(&k, sizeof(k), seed);
+}
+
+struct hashmap_fkey *fkey = &(struct hashmap_fkey) {
+ .cmp = cmp,
+ .hash = hash,
+ NULL
+};
+
+struct hashmap_fval *fval = &(struct hashmap_fval) {
+ .cmp = cmp,
+ .hash = hash,
+ NULL
+};
+
+int main(void)
+{
+ mt_state tw;
+ twist_init(&tw, 50331653);
+
+ struct hashmap *map = hm_new(COUNT, 0.6, fkey, fval);
+
+ for (uint64_t i = 0; i < COUNT; i++)
+ {
+ uint64_t v = twist_uint64(&tw);
+ hm_insert(map, v, v);
+ }
+
+ hm_free(map);
+
+ return 0;
+}
diff --git a/benchmarks/C++ Comparison/hashtable/hashmultimap.c b/benchmarks/C++ Comparison/hashtable/hashmultimap.c
new file mode 100644
index 0000000..2bac19a
--- /dev/null
+++ b/benchmarks/C++ Comparison/hashtable/hashmultimap.c
@@ -0,0 +1,61 @@
+#ifndef COUNT
+#error "Please define COUNT"
+#endif
+
+#include "murmurhash.h"
+
+#include "macro_collections.h"
+
+#include "../../util/twister.c"
+
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , uint64_t, uint64_t))
+
+int cmp(uint64_t a, uint64_t b)
+{
+ return (a > b) - (a < b);
+}
+
+// size_t hash(uint64_t a)
+// {
+// size_t x = (size_t)a;
+// x = ((x >> 16) ^ x) * 0x45d9f3b;
+// x = ((x >> 16) ^ x) * 0x45d9f3b;
+// x = (x >> 16) ^ x;
+// return x;
+// }
+
+size_t hash(uint64_t k)
+{
+ static size_t seed = 211106232532969;
+ return MurMurHash(&k, sizeof(k), seed);
+}
+
+struct hashmultimap_fkey *fkey = &(struct hashmultimap_fkey) {
+ .cmp = cmp,
+ .hash = hash,
+ NULL
+};
+
+struct hashmultimap_fval *fval = &(struct hashmultimap_fval) {
+ .cmp = cmp,
+ .hash = hash,
+ NULL
+};
+
+int main(void)
+{
+ mt_state tw;
+ twist_init(&tw, 50331653);
+
+ struct hashmultimap *map = hmm_new(COUNT, 0.6, fkey, fval);
+
+ for (uint64_t i = 0; i < COUNT; i++)
+ {
+ uint64_t v = twist_uint64(&tw);
+ hmm_insert(map, v, v);
+ }
+
+ hmm_free(map);
+
+ return 0;
+}
diff --git a/benchmarks/C++ Comparison/hashtable/murmurhash.h b/benchmarks/C++ Comparison/hashtable/murmurhash.h
new file mode 100644
index 0000000..a334dd9
--- /dev/null
+++ b/benchmarks/C++ Comparison/hashtable/murmurhash.h
@@ -0,0 +1,58 @@
+// https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/hash_bytes.cc
+
+#ifndef MURMURHASH
+#define MURMURHASH
+
+#include
+
+inline size_t unaligned_load(const char *p)
+{
+ size_t result;
+ memcpy(&result, p, sizeof(result));
+ return result;
+}
+
+inline size_t load_bytes(const char *p, int n)
+{
+ size_t result = 0;
+ --n;
+ do
+ {
+ result = (result << 8) + (unsigned char)(p[n]);
+ } while (--n >= 0);
+ return result;
+}
+
+inline size_t shift_mix(size_t v)
+{
+ return v ^ (v >> 47);
+}
+
+size_t MurMurHash(const void *ptr, size_t len, size_t seed)
+{
+ static const size_t mul = (((size_t)0xc6a4a793UL) << 32UL) + (size_t)0x5bd1e995UL;
+ const char *const buf = (const char *)(ptr);
+
+ // Remove the bytes not divisible by the sizeof(size_t). This
+ // allows the main loop to process the data as 64-bit integers.
+ const size_t len_aligned = len & ~(size_t)0x7;
+ const char *const end = buf + len_aligned;
+ size_t hash = seed ^ (len * mul);
+ for (const char *p = buf; p != end; p += 8)
+ {
+ const size_t data = shift_mix(unaligned_load(p) * mul) * mul;
+ hash ^= data;
+ hash *= mul;
+ }
+ if ((len & 0x7) != 0)
+ {
+ const size_t data = load_bytes(end, len & 0x7);
+ hash ^= data;
+ hash *= mul;
+ }
+ hash = shift_mix(hash) * mul;
+ hash = shift_mix(hash);
+ return hash;
+}
+
+#endif /* MURMURHASH */
diff --git a/benchmarks/C++ Comparison/hashtable/script.py b/benchmarks/C++ Comparison/hashtable/script.py
new file mode 100644
index 0000000..bd939ec
--- /dev/null
+++ b/benchmarks/C++ Comparison/hashtable/script.py
@@ -0,0 +1,57 @@
+import os
+import sys
+import time
+import subprocess
+
+ITERATIONS = 10
+COUNT = 20000000
+VERBOSE = False
+
+NL = '\n'
+
+INCLUDE = "../../../src"
+CC = 'gcc'
+CCPP = 'g++' # LoL
+OPT = '-O3'
+
+print(f'Using {CC} compiler')
+
+
+def execute_command(commands):
+ print(' '.join(commands))
+ subprocess.run(commands, shell=True)
+
+
+# Common args
+args = ['-I', INCLUDE, OPT, f'-DCOUNT={COUNT}', '-DCMC_NO_CALLBACKS']
+
+map_args = [CC, 'hashmap.c', '-o', 'hashmap.exe']
+mmap_args = [CC, 'hashmultimap.c', '-o', 'hashmultimap.exe']
+cpp_args = [CCPP, 'unorderedmap.cpp', '-I', INCLUDE, '-o', 'unorderedmap.exe', OPT, f'-DCOUNT={COUNT}']
+
+map_args.extend(args)
+mmap_args.extend(args)
+cpp_args.extend(args)
+
+execute_command(map_args)
+execute_command(mmap_args)
+execute_command(cpp_args)
+
+programs = ['hashmap.exe', 'hashmultimap.exe', 'unorderedmap.exe']
+
+for prog in programs:
+ total = 0
+ for i in range(ITERATIONS):
+ print(f'{i}...', end='')
+ sys.stdout.flush()
+ start_time = time.time()
+ subprocess.run(prog, shell=True)
+
+ delta = time.time() - start_time
+ total += delta
+
+ if VERBOSE:
+ print(f'({delta})')
+
+ avg = total / ITERATIONS
+ print(f'{"" if VERBOSE else NL}{avg} seconds for {COUNT} -> AVG[{int((avg * 1e9) / COUNT)} ns] [{prog}]{NL if VERBOSE else ""}')
diff --git a/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp
new file mode 100644
index 0000000..5f59f00
--- /dev/null
+++ b/benchmarks/C++ Comparison/hashtable/unorderedmap.cpp
@@ -0,0 +1,34 @@
+#ifndef COUNT
+#error "Please define COUNT"
+#endif
+
+#include "murmurhash.h"
+
+#include
+
+#include "../../util/twister.c"
+
+struct IntHasher
+{
+ std::size_t operator()(const uint64_t& k) const
+ {
+ static size_t seed = 211106232532969;
+ return MurMurHash(&k, sizeof(k), seed);
+ }
+};
+
+int main(void)
+{
+ mt_state tw;
+ twist_init(&tw, 50331653);
+
+ std::unordered_map map(COUNT);
+
+ for (uint64_t i = 0; i < COUNT; i++)
+ {
+ uint64_t v = twist_uint64(&tw);
+ map.insert({v, v});
+ }
+
+ return 0;
+}
diff --git a/examples/dfs.c b/examples/dfs.c
new file mode 100644
index 0000000..9bb181a
--- /dev/null
+++ b/examples/dfs.c
@@ -0,0 +1,87 @@
+/**
+ * Example of In-Order Depth-First Search using:
+ * - A Stack
+ * - Recursion
+ * - Without both
+ */
+
+#define CMC_CAMEL_CASE
+
+#include "macro_collections.h"
+
+C_MACRO_COLLECTIONS_GEN(CMC, TREESET, (tree, BinaryTree, , , int32_t), (ITER, STR))
+
+#define MYSTACK (stk, Stack, , , struct BinaryTreeNode *)
+
+C_MACRO_COLLECTIONS(CMC, STACK, CORE, STRUCT, MYSTACK)
+C_MACRO_COLLECTIONS(CMC, STACK, CORE, HEADER, MYSTACK)
+C_MACRO_COLLECTIONS(CMC, STACK, CORE, SOURCE, MYSTACK)
+
+void DFS(struct BinaryTreeNode *root)
+{
+ if (!root)
+ return;
+
+ DFS(root->left);
+
+ fprintf(stdout, "%d ", root->value);
+
+ DFS(root->right);
+}
+
+int main(void)
+{
+ struct BinaryTree *tree = tree_new(&(struct BinaryTreeFVal){ .cmp = cmc_i32_cmp, .str = cmc_i32_str, NULL });
+
+ for (int i = 1; i <= 10; i++)
+ tree_insert(tree, i);
+
+ int32_t result = 1;
+
+ cmc_assert(tree_min(tree, &result));
+ cmc_assert_equals(int32_t, 1, result);
+
+ cmc_assert(tree_max(tree, &result));
+ cmc_assert_equals(int32_t, 10, result);
+
+ printf("Without Recursion or Stack:\n");
+ tree_print(tree, stdout, "[ ", " ", " ]\n");
+
+ printf("Recursion:\n");
+ fprintf(stdout, "[ ");
+ DFS(tree->root);
+ fprintf(stdout, "]\n");
+
+ printf("Stack:\n");
+ fprintf(stdout, "[ ");
+ struct Stack *stack = stk_new(100, &(struct StackFVal){ NULL });
+
+ struct BinaryTreeNode *node = tree->root;
+
+ while (node || !stk_empty(stack))
+ {
+ if (node)
+ {
+ if (!stk_push(stack, node))
+ cmc_log_error("Could not push to stack %d\n", cmc_flags_to_str[stk_flag(stack)]);
+
+ node = node->left;
+ }
+ else
+ {
+ node = stk_top(stack);
+
+ if (!stk_pop(stack))
+ cmc_log_error("Could not pop from the stack %s\n", cmc_flags_to_str[stk_flag(stack)]);
+
+ fprintf(stdout, "%d ", node->value);
+
+ node = node->right;
+ }
+ }
+
+ stk_free(stack);
+ fprintf(stdout, "]\n");
+
+ tree_free(tree);
+}
diff --git a/examples/example.c b/examples/example.c
new file mode 100644
index 0000000..527d78d
--- /dev/null
+++ b/examples/example.c
@@ -0,0 +1,67 @@
+// This is the master header. This will include every feature of the library.
+// This comes with many helper macros (high level API) and utility functions.
+#include "macro_collections.h"
+
+// A PARAM is a standard way to pass required parameters to the lower level API.
+// It is a tuple of form (PFX, SNAME, SIZE, K, V). In this case, not all of them
+// are used, so we can leave them empty. We are creating a list of value int.
+#define MY_LIST_PARAMS (intl, int_list, , , int)
+
+// High level API. Generate a LIST from the CMC library with the STR extension
+// using our previously defined PARAMs. Every collections has a CORE part that
+// needs to be generated first. Then, we can add other parts after. This macro
+// does all of that for us. The STR part will provide us with a function that
+// will be used later.
+C_MACRO_COLLECTIONS_GEN(CMC, LIST, MY_LIST_PARAMS, (STR))
+
+int main(void)
+{
+ // Our list type is defined by SNAME and all functions are prefixed by PFX
+ // (PFX can also be thought as the function's namespace). Also, nodes,
+ // entries, iterators and other structures are prefixed by SNAME. So PFX is
+ // for functions and SNAME is for structs, where the main one is simply
+ // 'struct SNAME'.
+ // To initialize a list we need to pass in an initial capacity and something
+ // that is called a function table for the V type.
+ // This function table is a struct with methods that will extract some
+ // (sometimes) necessary behaviour from your custom data type. Things like
+ // hash, comparison and printing. A list doesn't require any of these
+ // functions. That is, the CORE module doesn't use any of them.
+ // But since we are using the STR module, we will need to define the 'str'
+ // function. luckily, for the 'int' type, the library already provides such
+ // function (cmc_i32_str), provided by the /utl/futils.h header file.
+ struct int_list *list = intl_new(32, &(struct int_list_fval){ .str = cmc_i32_str, NULL });
+
+ // Check if the list was successfully initialized. It could fail if the
+ // initial capacity is too big or if 'struct int_list_fval *' is NULL,
+ // because every data structure must have a valid function table.
+ if (!list)
+ return 1;
+
+ // Add some items to the list. The CMC data structures are all dynamically
+ // sized. So there can be as many items as you want as long as you have
+ // enough memory.
+ for (int i = 0; i < 100; i++)
+ {
+ // Try to add an element to the list. If it fails you can check what
+ // caused it by getting its flag.
+ if (!intl_push_back(list, i))
+ {
+ enum cmc_flags flag = intl_flag(list);
+ // Use cmc_flags_to_str to map the enum error to a string.
+ fprintf(stderr, "%s : push_back failed\n", cmc_flags_to_str[flag]);
+ }
+ }
+
+ // Now we will use the STR module, the _print() function. This is where the
+ // '.str' from the function table comes into play. If we haven't defined it,
+ // the program would've crashed. We also need to define to which file we
+ // will be printing the list's content. In this case, the terminal. Also,
+ // some strings need to be defined. They will be printed: before all elements,
+ // between each one, and after all elements. This is very usefull and can
+ // print a data structure very nicely.
+ intl_print(list, stdout, "[ ", ", ", " ]\n");
+
+ // Free all of its resources
+ intl_free(list);
+}
diff --git a/examples/hanoi.c b/examples/hanoi.c
index bc5504b..e4053b0 100644
--- a/examples/hanoi.c
+++ b/examples/hanoi.c
@@ -1,14 +1,17 @@
-#include
-#include
+#include "macro_collections.h"
-CMC_GENERATE_STACK(stk, stack, int)
+#define MYSTACK (stk, stack, , , int)
+
+C_MACRO_COLLECTIONS(CMC, STACK, CORE, STRUCT, MYSTACK)
+C_MACRO_COLLECTIONS(CMC, STACK, CORE, HEADER, MYSTACK)
+C_MACRO_COLLECTIONS(CMC, STACK, CORE, SOURCE, MYSTACK)
struct
{
struct stack *from;
struct stack *aux;
struct stack *to;
-} print_aux = {NULL};
+} print_aux = { NULL };
void print_stacks()
{
@@ -18,10 +21,7 @@ void print_stacks()
int ib = print_aux.aux->buffer[i];
int ic = print_aux.to->buffer[i];
- printf("| %c | %c | %c |\n",
- ia == 0 ? 32 : ia + 48,
- ib == 0 ? 32 : ib + 48,
- ic == 0 ? 32 : ic + 48);
+ printf("| %c | %c | %c |\n", ia == 0 ? 32 : ia + 48, ib == 0 ? 32 : ib + 48, ic == 0 ? 32 : ic + 48);
}
printf("+---+---+---+\n\n");
@@ -50,9 +50,9 @@ void hanoi(int n, struct stack *from, struct stack *aux, struct stack *to)
int main(int argc, char const *argv[])
{
- struct stack *from = stk_new(10);
- struct stack *to = stk_new(10);
- struct stack *aux = stk_new(10);
+ struct stack *from = stk_new(10, &(struct stack_fval){ NULL });
+ struct stack *to = stk_new(10, &(struct stack_fval){ NULL });
+ struct stack *aux = stk_new(10, &(struct stack_fval){ NULL });
for (int i = 4; i >= 1; i--)
stk_push(from, i);
@@ -65,9 +65,9 @@ int main(int argc, char const *argv[])
hanoi(stk_count(from), from, aux, to);
- stk_free(from, NULL);
- stk_free(to, NULL);
- stk_free(aux, NULL);
+ stk_free(from);
+ stk_free(to);
+ stk_free(aux);
return 0;
}
diff --git a/examples/printer.c b/examples/printer.c
index 2b016cd..16667b7 100644
--- a/examples/printer.c
+++ b/examples/printer.c
@@ -1,5 +1,6 @@
-#include
-#include
+// Prints a file in the terminal separated by pages
+
+#include "macro_collections.h"
#define TAB_SIZE 4
#define ROW_INI_CAP DOC_LETTERS_IN_ROW
@@ -7,13 +8,11 @@
#define DOC_ROWS_IN_PAGE 50
#define DOC_MARGIN 4
-CMC_GENERATE_LIST(row, row, char)
-CMC_GENERATE_LIST(doc, document, struct row *)
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (row, row, , , char))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (doc, document, , , struct row *))
-void row_deallocator(struct row *r)
-{
- row_free(r, NULL);
-}
+struct row_fval *row_funcs = &(struct row_fval){ NULL };
+struct document_fval *doc_funcs = &(struct document_fval){ .free = row_free };
struct document *document_load(const char *file_name);
void document_empty_line(FILE *fptr);
@@ -31,9 +30,9 @@ struct document *document_load(const char *file_name)
return NULL;
}
- struct row *initial_row = row_new(ROW_INI_CAP);
+ struct row *initial_row = row_new(ROW_INI_CAP, row_funcs);
- struct document *doc = doc_new(100);
+ struct document *doc = doc_new(100, doc_funcs);
doc_push_back(doc, initial_row);
int ch;
@@ -46,7 +45,7 @@ struct document *document_load(const char *file_name)
if (c == '\n')
{
- struct row *new_row = row_new(ROW_INI_CAP);
+ struct row *new_row = row_new(ROW_INI_CAP, row_funcs);
doc_push_back(doc, new_row);
}
else if (c == '\t')
@@ -61,7 +60,7 @@ struct document *document_load(const char *file_name)
if (left > 0)
{
- struct row *new_row = row_new(ROW_INI_CAP);
+ struct row *new_row = row_new(ROW_INI_CAP, row_funcs);
doc_push_back(doc, new_row);
while (left > 0)
@@ -73,7 +72,7 @@ struct document *document_load(const char *file_name)
}
else if (DOC_LETTERS_IN_ROW == row_count(current_row))
{
- struct row *new_row = row_new(ROW_INI_CAP);
+ struct row *new_row = row_new(ROW_INI_CAP, row_funcs);
row_push_back(new_row, c);
doc_push_back(doc, new_row);
}
@@ -86,12 +85,12 @@ struct document *document_load(const char *file_name)
void document_empty_line(FILE *fptr)
{
- fputs("|", fptr);
+ fputs("\t|", fptr);
for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++)
{
fputc(' ', fptr);
}
- fputs("|\n", fptr);
+ fputs("\t|\n", fptr);
}
void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */)
@@ -102,7 +101,7 @@ void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */)
#ifdef DOC_PAGE_NUMBER
static intmax_t page = 1;
- fputs("|", fptr);
+ fputs("\t|", fptr);
for (size_t i = 0; i < (DOC_LETTERS_IN_ROW + DOC_MARGIN) - 8; i++)
{
fputc(' ', fptr);
@@ -116,8 +115,8 @@ void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */)
#endif
}
- fputs("+", fptr);
- for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2; i++)
+ fputs("\t+", fptr);
+ for (size_t i = 0; i < DOC_LETTERS_IN_ROW + DOC_MARGIN * 2 + 3; i++)
{
fputc('-', fptr);
}
@@ -130,7 +129,7 @@ void document_page_outline(FILE *fptr, int outline /* 0 - header, 1 - footer */)
void document_page_margin(FILE *fptr, int margin /* 0 - first margin, 1 - second margin */)
{
if (margin == 0)
- fputs("|", fptr);
+ fputs("\t|", fptr);
for (size_t i = 0; i < DOC_MARGIN; i++)
{
@@ -138,7 +137,7 @@ void document_page_margin(FILE *fptr, int margin /* 0 - first margin, 1 - second
}
if (margin == 1)
- fputs("|\n", fptr);
+ fputs("\t|\n", fptr);
}
void document_print(struct document *doc, FILE *fptr)
@@ -202,7 +201,7 @@ int main(int argc, char const *argv[])
document_print(doc, stdout);
- doc_free(doc, row_deallocator);
+ doc_free(doc);
return 0;
}
diff --git a/examples/sieve.c b/examples/sieve.c
new file mode 100644
index 0000000..12f681a
--- /dev/null
+++ b/examples/sieve.c
@@ -0,0 +1,42 @@
+#include "cmc/bitset.h"
+#include
+
+CMC_CMC_BITSET_CORE(PUBLIC, HEADER, (bs, bitset))
+CMC_CMC_BITSET_CORE(PUBLIC, SOURCE, (bs, bitset))
+
+// All the prime numbers up to 1 billion
+// With -O3:
+// 28.583 s runtime
+// 120 MB RAM
+// 490 MB file size
+int main(void)
+{
+ const size_t n = 1000000000;
+
+ struct bitset *set = bs_new(n);
+
+ if (!set)
+ return 1;
+
+ bs_set_range(set, 0, n);
+
+ size_t up_to = sqrt((double)n) + 1;
+ for (size_t i = 2; i < up_to; ++i)
+ {
+ if (bs_get(set, i))
+ {
+ for (size_t j = 2 * i; j < n; j += i)
+ bs_clear(set, j);
+ }
+ }
+
+ FILE *file = fopen("primes.txt", "w");
+
+ for (size_t i = 2; i < n; i++)
+ {
+ if (bs_get(set, i))
+ fprintf(file, "%" PRIuMAX " ", i);
+ }
+
+ fclose(file);
+}
diff --git a/src/cmc/bitset.h b/src/cmc/bitset.h
index a4369ac..796d016 100644
--- a/src/cmc/bitset.h
+++ b/src/cmc/bitset.h
@@ -1,5 +1,5 @@
/**
- * bitset.h
+ * cmc/bitset.h
*
* Creation Date: 30/04/2020
*
@@ -28,8 +28,8 @@
* as there is enough memory.
*/
-#ifndef CMC_BITSET_H
-#define CMC_BITSET_H
+#ifndef CMC_CMC_BITSET_H
+#define CMC_CMC_BITSET_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -41,544 +41,534 @@
* ------------------------------------------------------------------------- */
#include "../cor/bitset.h"
+/**
+ * Core BitSet implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_BITSET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_BITSET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_BITSET_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_BITSET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_BITSET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_BITSET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_BITSET_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_BITSET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_BITSET_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_BITSET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_BITSET_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_BITSET_CORE_STRUCT(PARAMS) CMC_CMC_BITSET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS))
+
+#define CMC_CMC_BITSET_CORE_HEADER(PARAMS) CMC_CMC_BITSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS))
+
+#define CMC_CMC_BITSET_CORE_SOURCE(PARAMS) CMC_CMC_BITSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS))
+
/* -------------------------------------------------------------------------
- * BitSet specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_bitset = "struct %s "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "flag:%d, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_BITSET(PFX, SNAME) \
- CMC_GENERATE_BITSET_HEADER(PFX, SNAME) \
- CMC_GENERATE_BITSET_SOURCE(PFX, SNAME)
-
-#define CMC_WRAPGEN_BITSET_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_BITSET_HEADER(PFX, SNAME)
-
-#define CMC_WRAPGEN_BITSET_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_BITSET_SOURCE(PFX, SNAME)
+#define CMC_CMC_BITSET_CORE_STRUCT_(PFX, SNAME) \
+\
+ /* 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_BITSET_HEADER(PFX, SNAME) \
- \
- /* BitSet Structure */ \
- struct SNAME \
- { \
- /* Dynamic Array of Bits */ \
- cmc_bitset_word *buffer; \
- \
- /* Current array capacity */ \
- size_t capacity; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* BitSet Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target bitset */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- cmc_bitset_word 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; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t n_bits); \
- struct SNAME *PFX##_new_custom(size_t n_bits, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- struct SNAME PFX##_init(size_t n_bits); \
- struct SNAME PFX##_init_custom(size_t n_bits, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- void PFX##_free(struct SNAME *_bitset_); \
- void PFX##_release(struct SNAME _bitset_); \
- void PFX##_customize(struct SNAME *_bitset_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_set(struct SNAME *_bitset_, size_t bit_index); \
- bool PFX##_set_range(struct SNAME *_bitset_, size_t from, size_t to); \
- bool PFX##_clear(struct SNAME *_bitset_, size_t bit_index); \
- bool PFX##_clear_range(struct SNAME *_bitset_, size_t from, size_t to); \
- bool PFX##_flip(struct SNAME *_bitset_, size_t bit_index); \
- bool PFX##_flip_range(struct SNAME *_bitset_, size_t from, size_t to); \
- bool PFX##_put(struct SNAME *_bitset_, size_t bit_index, bool state); \
- bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to, \
- bool state); \
- bool PFX##_set_all(struct SNAME *_bitset_); \
- bool PFX##_clear_all(struct SNAME *_bitset_); \
- bool PFX##_flip_all(struct SNAME *_bitset_); \
- /* Element Access */ \
- bool PFX##_get(struct SNAME *_bitset_, size_t bit_index); \
- /* Collection State */ \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_bitset_, size_t n_bits); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- /* Iterator State */ \
- /* Iterator Movement */ \
- /* Iterator Access */ \
- \
- /* Utility Methods */ \
- /* Translates a bit index to a word index */ \
- static inline size_t PFX##_bit_to_index(size_t idx) \
- { \
- /* Calculate how many shifts based on the size of cmc_bitset_word */ \
- static const size_t shift = \
- ((sizeof(cmc_bitset_word) * 8) >> 6) > 0 \
- ? 6 \
- : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 \
- ? 5 \
- : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3; \
- \
- return idx >> shift; \
- }
+#define CMC_CMC_BITSET_CORE_HEADER_(PFX, SNAME) \
+\
+ /* 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; \
+ }; \
+\
+ /* Collection Functions */ \
+ /* 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); \
+\
+ /* Iterator Functions */ \
+ /* Iterator Initialization */ \
+ /* Iterator State */ \
+ /* Iterator Movement */ \
+ /* Iterator Access */ \
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_BITSET_SOURCE(PFX, SNAME) \
- \
- /* Implementation Detail Functions */ \
- bool PFX##_impl_resize(struct SNAME *_bitset_, size_t n_bits, \
- bool do_resize); \
- \
- struct SNAME *PFX##_new(size_t n_bits) \
- { \
- return PFX##_new_custom(n_bits, NULL, NULL); \
- } \
- \
- struct SNAME *PFX##_new_custom(size_t n_bits, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (n_bits < 1) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- size_t capacity = PFX##_bit_to_index(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_flags.OK; \
- _bitset_->alloc = alloc; \
- _bitset_->callbacks = callbacks; \
- \
- return _bitset_; \
- } \
- \
- struct SNAME PFX##_init(size_t n_bits) \
- { \
- return PFX##_init_custom(n_bits, NULL, NULL); \
- } \
- \
- struct SNAME PFX##_init_custom(size_t n_bits, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- struct SNAME _bitset_ = { 0 }; \
- \
- if (n_bits < 1) \
- return _bitset_; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- size_t capacity = PFX##_bit_to_index(n_bits - 1) + 1; \
- \
- _bitset_.buffer = alloc->calloc(capacity, sizeof(cmc_bitset_word)); \
- \
- if (!_bitset_.buffer) \
- return _bitset_; \
- \
- _bitset_.capacity = capacity; \
- _bitset_.flag = cmc_flags.OK; \
- _bitset_.alloc = alloc; \
- _bitset_.callbacks = callbacks; \
- \
- return _bitset_; \
- } \
- \
- void PFX##_free(struct SNAME *_bitset_) \
- { \
- free(_bitset_->buffer); \
- free(_bitset_); \
- } \
- \
- void PFX##_release(struct SNAME _bitset_) \
- { \
- free(_bitset_.buffer); \
- } \
- \
- void PFX##_customize(struct SNAME *_bitset_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _bitset_->alloc = &cmc_alloc_node_default; \
- else \
- _bitset_->alloc = alloc; \
- \
- _bitset_->callbacks = callbacks; \
- \
- _bitset_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_set(struct SNAME *_bitset_, size_t bit_index) \
- { \
- if (!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 = PFX##_bit_to_index(bit_index); \
- \
- _bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits); \
- \
- _bitset_->flag = cmc_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->create) \
- _bitset_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_set_range(struct SNAME *_bitset_, size_t from, size_t to) \
- { \
- if (to < from) \
- { \
- _bitset_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (!PFX##_impl_resize(_bitset_, to + 1, false)) \
- return false; \
- \
- size_t start_index = PFX##_bit_to_index(from); \
- size_t end_index = PFX##_bit_to_index(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_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->create) \
- _bitset_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_clear(struct SNAME *_bitset_, size_t bit_index) \
- { \
- if (!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 = PFX##_bit_to_index(bit_index); \
- \
- _bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits)); \
- \
- _bitset_->flag = cmc_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->delete) \
- _bitset_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_clear_range(struct SNAME *_bitset_, size_t from, size_t to) \
- { \
- if (to < from) \
- { \
- _bitset_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (!PFX##_impl_resize(_bitset_, to + 1, false)) \
- return false; \
- \
- size_t start_index = PFX##_bit_to_index(from); \
- size_t end_index = PFX##_bit_to_index(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_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->delete) \
- _bitset_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_flip(struct SNAME *_bitset_, size_t bit_index) \
- { \
- if (!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 = PFX##_bit_to_index(bit_index); \
- \
- _bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits); \
- \
- _bitset_->flag = cmc_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->update) \
- _bitset_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_flip_range(struct SNAME *_bitset_, size_t from, size_t to) \
- { \
- if (to < from) \
- { \
- _bitset_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (!PFX##_impl_resize(_bitset_, to + 1, false)) \
- return false; \
- \
- size_t start_index = PFX##_bit_to_index(from); \
- size_t end_index = PFX##_bit_to_index(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_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->update) \
- _bitset_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_put(struct SNAME *_bitset_, size_t bit_index, bool state) \
- { \
- if (state) \
- return PFX##_set(_bitset_, bit_index); \
- else \
- return PFX##_clear(_bitset_, bit_index); \
- } \
- \
- bool PFX##_put_range(struct SNAME *_bitset_, size_t from, size_t to, \
- bool state) \
- { \
- if (state) \
- return PFX##_set_range(_bitset_, from, to); \
- else \
- return PFX##_clear_range(_bitset_, from, to); \
- } \
- \
- bool 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_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->create) \
- _bitset_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_clear_all(struct SNAME *_bitset_) \
- { \
- for (size_t i = 0; i < _bitset_->capacity; i++) \
- _bitset_->buffer[i] = 0; \
- \
- _bitset_->flag = cmc_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->delete) \
- _bitset_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool 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_flags.OK; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->create) \
- _bitset_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool 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[PFX##_bit_to_index(bit_index)]; \
- \
- return w & ((cmc_bitset_word)1 << (bit_index % bits)); \
- } \
- \
- bool PFX##_resize(struct SNAME *_bitset_, size_t n_bits) \
- { \
- return PFX##_impl_resize(_bitset_, n_bits, true); \
- } \
- \
+#define CMC_CMC_BITSET_CORE_SOURCE_(PFX, SNAME) \
+\
+ /* 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 PFX##_impl_resize(struct SNAME *_bitset_, size_t n_bits, \
- bool do_resize) \
- { \
- if (n_bits == 0) \
- { \
- _bitset_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
+ /* 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 = PFX##_bit_to_index(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_flags.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; \
- \
- if (_bitset_->callbacks && _bitset_->callbacks->resize) \
- _bitset_->callbacks->resize(); \
- \
- _bitset_->flag = cmc_flags.OK; \
- \
- return true; \
+ /* +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; \
}
-#endif /* CMC_BITSET_H */
+#endif /* CMC_CMC_BITSET_H */
diff --git a/src/cmc/deque.h b/src/cmc/deque.h
index bea757e..07c78ec 100644
--- a/src/cmc/deque.h
+++ b/src/cmc/deque.h
@@ -1,5 +1,5 @@
/**
- * deque.h
+ * cmc/deque.h
*
* Creation Date: 20/03/2019
*
@@ -28,837 +28,501 @@
* would take O(N) due to the need to shift all elements in the deque.
*/
-#ifndef CMC_DEQUE_H
-#define CMC_DEQUE_H
+#ifndef CMC_CMC_DEQUE_H
+#define CMC_CMC_DEQUE_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core Deque implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_DEQUE_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_DEQUE_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_DEQUE_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \
+ CMC_CMC_DEQUE_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_DEQUE_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_DEQUE_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_DEQUE_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_DEQUE_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_DEQUE_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \
+ CMC_CMC_DEQUE_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_DEQUE_CORE_STRUCT(PARAMS) \
+ CMC_CMC_DEQUE_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_DEQUE_CORE_HEADER(PARAMS) \
+ CMC_CMC_DEQUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_DEQUE_CORE_SOURCE(PARAMS) \
+ CMC_CMC_DEQUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * Deque Specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_deque = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "front:%" PRIuMAX ", "
- "back:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_DEQUE(PFX, SNAME, V) \
- CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_DEQUE_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_DEQUE_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_DEQUE_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Deque Structure */ \
+ struct SNAME \
+ { \
+ /* Dynamic circular array of elements */ \
+ V *buffer; \
+\
+ /* Current circular array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of elements */ \
+ size_t count; \
+\
+ /* Index representing the front of the deque */ \
+ size_t front; \
+\
+ /* Index representing the back of the deque */ \
+ size_t back; \
+\
+ /* Flags indicating errors or success */ \
+ int flag; \
+\
+ struct CMC_DEF_FVAL(SNAME) * f_val; \
+\
+ /* Custom allocation functions */ \
+ struct CMC_ALLOC_NODE_NAME *alloc; \
+\
+ /* Custom callback functions */ \
+ CMC_CALLBACKS_DECL; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \
- \
- /* Deque Structure */ \
- struct SNAME \
- { \
- /* Dynamic circular array of elements */ \
- V *buffer; \
- \
- /* Current circular array capacity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Index representing the front of the deque */ \
- size_t front; \
- \
- /* Index representing the back of the deque */ \
- size_t back; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Deque Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target deque */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME PFX##_init_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_deque_); \
- void PFX##_free(struct SNAME *_deque_); \
- void PFX##_release(struct SNAME _deque_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_deque_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_push_front(struct SNAME *_deque_, V value); \
- bool PFX##_push_back(struct SNAME *_deque_, V value); \
- bool PFX##_pop_front(struct SNAME *_deque_); \
- bool PFX##_pop_back(struct SNAME *_deque_); \
- /* Element Access */ \
- V PFX##_front(struct SNAME *_deque_); \
- V PFX##_back(struct SNAME *_deque_); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_deque_, V value); \
- bool PFX##_empty(struct SNAME *_deque_); \
- bool PFX##_full(struct SNAME *_deque_); \
- size_t PFX##_count(struct SNAME *_deque_); \
- size_t PFX##_capacity(struct SNAME *_deque_); \
- int PFX##_flag(struct SNAME *_deque_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_deque_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_deque_); \
- bool PFX##_equals(struct SNAME *_deque1_, struct SNAME *_deque2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_deque_); \
- bool PFX##_print(struct SNAME *_deque_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_DEQUE_CORE_HEADER_(PFX, SNAME, V) \
+\
+ 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 * _deque_); \
+ void CMC_(PFX, _free)(struct SNAME * _deque_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value); \
+ bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value); \
+ bool CMC_(PFX, _pop_front)(struct SNAME * _deque_); \
+ bool CMC_(PFX, _pop_back)(struct SNAME * _deque_); \
+ /* Element Access */ \
+ V CMC_(PFX, _front)(struct SNAME * _deque_); \
+ V CMC_(PFX, _back)(struct SNAME * _deque_); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _deque_); \
+ bool CMC_(PFX, _full)(struct SNAME * _deque_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _deque_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _deque_); \
+ int CMC_(PFX, _flag)(struct SNAME * _deque_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- /* None */ \
- \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- return PFX##_new_custom(capacity, f_val, NULL, NULL); \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity < 1) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_deque_) \
- return NULL; \
- \
- _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_deque_->buffer) \
- { \
- alloc->free(_deque_); \
- return NULL; \
- } \
- \
- _deque_->capacity = capacity; \
- _deque_->count = 0; \
- _deque_->front = 0; \
- _deque_->back = 0; \
- _deque_->flag = cmc_flags.OK; \
- _deque_->f_val = f_val; \
- _deque_->alloc = alloc; \
- _deque_->callbacks = callbacks; \
- \
- return _deque_; \
- } \
- \
- struct SNAME PFX##_init(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- return PFX##_init_custom(capacity, f_val, NULL, NULL); \
- } \
- \
- struct SNAME PFX##_init_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- struct SNAME _deque_ = { 0 }; \
- \
- if (capacity < 1) \
- return _deque_; \
- \
- if (!f_val) \
- return _deque_; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_deque_.buffer) \
- return _deque_; \
- \
- _deque_.capacity = capacity; \
- _deque_.count = 0; \
- _deque_.front = 0; \
- _deque_.back = 0; \
- _deque_.flag = cmc_flags.OK; \
- _deque_.f_val = f_val; \
- _deque_.alloc = alloc; \
- _deque_.callbacks = callbacks; \
- \
- return _deque_; \
- } \
- \
- void PFX##_clear(struct SNAME *_deque_) \
- { \
- if (_deque_->f_val->free) \
- { \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- _deque_->f_val->free(_deque_->buffer[i]); \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- } \
- \
- memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
- \
- _deque_->count = 0; \
- _deque_->front = 0; \
- _deque_->back = 0; \
- \
- _deque_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_deque_) \
- { \
- if (_deque_->f_val->free) \
- { \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- _deque_->f_val->free(_deque_->buffer[i]); \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- } \
- \
- _deque_->alloc->free(_deque_->buffer); \
- _deque_->alloc->free(_deque_); \
- } \
- \
- void PFX##_release(struct SNAME _deque_) \
- { \
- if (_deque_.f_val->free) \
- { \
- for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \
- { \
- _deque_.f_val->free(_deque_.buffer[i]); \
- \
- i = (i + 1) % _deque_.capacity; \
- } \
- } \
- \
- _deque_.alloc->free(_deque_.buffer); \
- } \
- \
- void PFX##_customize(struct SNAME *_deque_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _deque_->alloc = &cmc_alloc_node_default; \
- else \
- _deque_->alloc = alloc; \
- \
- _deque_->callbacks = callbacks; \
- \
- _deque_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_push_front(struct SNAME *_deque_, V value) \
- { \
- if (PFX##_full(_deque_)) \
- { \
- if (!PFX##_resize(_deque_, _deque_->capacity * 2)) \
- return false; \
- } \
- \
- _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 \
- : _deque_->front - 1; \
- \
- _deque_->buffer[_deque_->front] = value; \
- \
- _deque_->count++; \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->callbacks && _deque_->callbacks->create) \
- _deque_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_push_back(struct SNAME *_deque_, V value) \
- { \
- if (PFX##_full(_deque_)) \
- { \
- if (!PFX##_resize(_deque_, _deque_->capacity * 2)) \
- return false; \
- } \
- \
- _deque_->buffer[_deque_->back] = value; \
- \
- _deque_->back = \
- (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
- \
- _deque_->count++; \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->callbacks && _deque_->callbacks->create) \
- _deque_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_front(struct SNAME *_deque_) \
- { \
- if (PFX##_empty(_deque_)) \
- { \
- _deque_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- _deque_->buffer[_deque_->front] = (V){ 0 }; \
- \
- _deque_->front = (_deque_->front == _deque_->capacity - 1) \
- ? 0 \
- : _deque_->front + 1; \
- \
- _deque_->count--; \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->callbacks && _deque_->callbacks->delete) \
- _deque_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_back(struct SNAME *_deque_) \
- { \
- if (PFX##_empty(_deque_)) \
- { \
- _deque_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- _deque_->back = \
- (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
- \
- _deque_->buffer[_deque_->back] = (V){ 0 }; \
- \
- _deque_->count--; \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->callbacks && _deque_->callbacks->delete) \
- _deque_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- V PFX##_front(struct SNAME *_deque_) \
- { \
- if (PFX##_empty(_deque_)) \
- { \
- _deque_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->callbacks && _deque_->callbacks->read) \
- _deque_->callbacks->read(); \
- \
- return _deque_->buffer[_deque_->front]; \
- } \
- \
- V PFX##_back(struct SNAME *_deque_) \
- { \
- if (PFX##_empty(_deque_)) \
- { \
- _deque_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->callbacks && _deque_->callbacks->read) \
- _deque_->callbacks->read(); \
- \
- return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 \
- : _deque_->back - 1]; \
- } \
- \
- bool PFX##_contains(struct SNAME *_deque_, V value) \
- { \
- _deque_->flag = cmc_flags.OK; \
- \
- bool result = false; \
- \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \
- { \
- result = true; \
- break; \
- } \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- \
- if (_deque_->callbacks && _deque_->callbacks->read) \
- _deque_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_deque_) \
- { \
- return _deque_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_deque_) \
- { \
- return _deque_->count >= _deque_->capacity; \
- } \
- \
- size_t PFX##_count(struct SNAME *_deque_) \
- { \
- return _deque_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_deque_) \
- { \
- return _deque_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_deque_) \
- { \
- return _deque_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_deque_, size_t capacity) \
- { \
- _deque_->flag = cmc_flags.OK; \
- \
- if (_deque_->capacity == capacity) \
- goto success; \
- \
- if (capacity < _deque_->count) \
- { \
- _deque_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \
- \
- if (!new_buffer) \
- { \
- _deque_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- new_buffer[j] = _deque_->buffer[i]; \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- \
- _deque_->alloc->free(_deque_->buffer); \
- \
- _deque_->buffer = new_buffer; \
- _deque_->capacity = capacity; \
- _deque_->front = 0; \
- _deque_->back = _deque_->count; \
- \
- success: \
- \
- if (_deque_->callbacks && _deque_->callbacks->resize) \
- _deque_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_deque_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_deque_->capacity, _deque_->f_val, \
- _deque_->alloc, _deque_->callbacks); \
- \
- if (!result) \
- { \
- _deque_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_deque_->f_val->cpy) \
- { \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- } \
- else \
- { \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- result->buffer[j] = _deque_->buffer[i]; \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- } \
- \
- result->count = _deque_->count; \
- result->front = 0; \
- result->back = _deque_->count; \
- \
- _deque_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_deque1_, struct SNAME *_deque2_) \
- { \
- _deque1_->flag = cmc_flags.OK; \
- _deque2_->flag = cmc_flags.OK; \
- \
- if (_deque1_->count != _deque2_->count) \
- return false; \
- \
- size_t i, j, k; \
- for (i = _deque1_->front, j = _deque2_->front, k = 0; \
- k < _deque1_->count; k++) \
- { \
- if (_deque1_->f_val->cmp(_deque1_->buffer[i], \
- _deque2_->buffer[j]) != 0) \
- return false; \
- \
- i = (i + 1) % _deque1_->capacity; \
- j = (j + 1) % _deque2_->capacity; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_deque_) \
- { \
- struct cmc_string str; \
- struct SNAME *d_ = _deque_; \
- \
- int n = \
- snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, #SNAME, #V, \
- d_, d_->buffer, d_->capacity, d_->count, d_->front, \
- d_->back, d_->flag, d_->f_val, d_->alloc, d_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_deque_, FILE *fptr) \
- { \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
- { \
- if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \
- return false; \
- \
- i = (i + 1) % _deque_->capacity; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->front; \
- iter.index = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- \
- if (!PFX##_empty(target)) \
- { \
- if (iter.target->back == 0) \
- iter.cursor = iter.target->capacity - 1; \
- else \
- iter.cursor = iter.target->back - 1; \
- \
- iter.index = iter.target->count - 1; \
- } \
- else \
- { \
- iter.cursor = 0; \
- iter.index = 0; \
- } \
- \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->front; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = false; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- if (iter->target->back == 0) \
- iter->cursor = iter->target->capacity - 1; \
- else \
- iter->cursor = iter->target->back - 1; \
- \
- iter->index = iter->target->count - 1; \
- \
- iter->start = false; \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
- iter->index++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \
- : iter->cursor - 1; \
- iter->index--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->index += steps; \
- iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->index -= steps; \
- \
- /* Prevent underflow */ \
- if (iter->cursor < steps) \
- iter->cursor += iter->target->capacity; \
- \
- iter->cursor -= steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
+#define CMC_CMC_DEQUE_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ /* None */ \
+\
+ 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 < 1) \
+ return NULL; \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_deque_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_deque_) \
+ return NULL; \
+\
+ _deque_->buffer = alloc->calloc(capacity, sizeof(V)); \
+\
+ if (!_deque_->buffer) \
+ { \
+ alloc->free(_deque_); \
+ return NULL; \
+ } \
+\
+ _deque_->capacity = capacity; \
+ _deque_->count = 0; \
+ _deque_->front = 0; \
+ _deque_->back = 0; \
+ _deque_->flag = CMC_FLAG_OK; \
+ _deque_->f_val = f_val; \
+ _deque_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \
+\
+ return _deque_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _deque_) \
+ { \
+ if (_deque_->f_val->free) \
+ { \
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ _deque_->f_val->free(_deque_->buffer[i]); \
+\
+ i = (i + 1) % _deque_->capacity; \
+ } \
+ } \
+\
+ memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
+\
+ _deque_->count = 0; \
+ _deque_->front = 0; \
+ _deque_->back = 0; \
+\
+ _deque_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _deque_) \
+ { \
+ if (_deque_->f_val->free) \
+ { \
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ _deque_->f_val->free(_deque_->buffer[i]); \
+\
+ i = (i + 1) % _deque_->capacity; \
+ } \
+ } \
+\
+ _deque_->alloc->free(_deque_->buffer); \
+ _deque_->alloc->free(_deque_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _deque_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _deque_->alloc = &cmc_alloc_node_default; \
+ else \
+ _deque_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_deque_, callbacks); \
+\
+ _deque_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _push_front)(struct SNAME * _deque_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_deque_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \
+ return false; \
+ } \
+\
+ _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
+\
+ _deque_->buffer[_deque_->front] = value; \
+\
+ _deque_->count++; \
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_deque_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _push_back)(struct SNAME * _deque_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_deque_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_deque_, _deque_->capacity * 2)) \
+ return false; \
+ } \
+\
+ _deque_->buffer[_deque_->back] = value; \
+\
+ _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
+\
+ _deque_->count++; \
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_deque_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_front)(struct SNAME * _deque_) \
+ { \
+ if (CMC_(PFX, _empty)(_deque_)) \
+ { \
+ _deque_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ _deque_->buffer[_deque_->front] = (V){ 0 }; \
+\
+ _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
+\
+ _deque_->count--; \
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_deque_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_back)(struct SNAME * _deque_) \
+ { \
+ if (CMC_(PFX, _empty)(_deque_)) \
+ { \
+ _deque_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
+\
+ _deque_->buffer[_deque_->back] = (V){ 0 }; \
+\
+ _deque_->count--; \
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_deque_, delete); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _front)(struct SNAME * _deque_) \
+ { \
+ if (CMC_(PFX, _empty)(_deque_)) \
+ { \
+ _deque_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_deque_, read); \
+\
+ return _deque_->buffer[_deque_->front]; \
+ } \
+\
+ V CMC_(PFX, _back)(struct SNAME * _deque_) \
+ { \
+ if (CMC_(PFX, _empty)(_deque_)) \
+ { \
+ _deque_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_deque_, read); \
+\
+ return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _deque_, V value) \
+ { \
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ bool result = false; \
+\
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ if (_deque_->f_val->cmp(_deque_->buffer[i], value) == 0) \
+ { \
+ result = true; \
+ break; \
+ } \
+\
+ i = (i + 1) % _deque_->capacity; \
+ } \
+\
+ CMC_CALLBACKS_CALL(_deque_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _deque_) \
+ { \
+ return _deque_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _deque_) \
+ { \
+ return _deque_->count >= _deque_->capacity; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _deque_) \
+ { \
+ return _deque_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _deque_) \
+ { \
+ return _deque_->capacity; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _deque_) \
+ { \
+ return _deque_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _deque_, size_t capacity) \
+ { \
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ if (_deque_->capacity == capacity) \
+ goto success; \
+\
+ if (capacity < _deque_->count) \
+ { \
+ _deque_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ V *new_buffer = _deque_->alloc->malloc(sizeof(V) * capacity); \
+\
+ if (!new_buffer) \
+ { \
+ _deque_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ new_buffer[j] = _deque_->buffer[i]; \
+\
+ i = (i + 1) % _deque_->capacity; \
+ } \
+\
+ _deque_->alloc->free(_deque_->buffer); \
+\
+ _deque_->buffer = new_buffer; \
+ _deque_->capacity = capacity; \
+ _deque_->front = 0; \
+ _deque_->back = _deque_->count; \
+\
+ success: \
+\
+ CMC_CALLBACKS_CALL(_deque_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _deque_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_deque_->capacity, _deque_->f_val, _deque_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _deque_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _deque_->callbacks); \
+\
+ if (_deque_->f_val->cpy) \
+ { \
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ result->buffer[j] = _deque_->f_val->cpy(_deque_->buffer[i]); \
+\
+ i = (i + 1) % _deque_->capacity; \
+ } \
+ } \
+ else \
+ { \
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ result->buffer[j] = _deque_->buffer[i]; \
+\
+ i = (i + 1) % _deque_->capacity; \
+ } \
+ } \
+\
+ result->count = _deque_->count; \
+ result->front = 0; \
+ result->back = _deque_->count; \
+\
+ _deque_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _deque1_, struct SNAME * _deque2_) \
+ { \
+ _deque1_->flag = CMC_FLAG_OK; \
+ _deque2_->flag = CMC_FLAG_OK; \
+\
+ if (_deque1_->count != _deque2_->count) \
+ return false; \
+\
+ size_t i, j, k; \
+ for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++) \
+ { \
+ if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0) \
+ return false; \
+\
+ i = (i + 1) % _deque1_->capacity; \
+ j = (j + 1) % _deque2_->capacity; \
+ } \
+\
+ return true; \
}
-#endif /* CMC_DEQUE_H */
+#endif /* CMC_CMC_DEQUE_H */
diff --git a/src/cmc/hashbidimap.h b/src/cmc/hashbidimap.h
index a0885e8..9edab75 100644
--- a/src/cmc/hashbidimap.h
+++ b/src/cmc/hashbidimap.h
@@ -1,5 +1,5 @@
/**
- * hashbidimap.h
+ * cmc/hashbidimap.h
*
* Creation Date: 26/09/2019
*
@@ -23,8 +23,8 @@
* the key and the value.
*/
-#ifndef CMC_HASHBIDIMAP_H
-#define CMC_HASHBIDIMAP_H
+#ifndef CMC_CMC_HASHBIDIMAP_H
+#define CMC_CMC_HASHBIDIMAP_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -36,1407 +36,1317 @@
* ------------------------------------------------------------------------- */
#include "../cor/hashtable.h"
+/**
+ * Core HashBidiMap implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_HASHBIDIMAP_CORE(ACCESS, FILE, PARAMS) \
+ CMC_(CMC_(CMC_CMC_HASHBIDIMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_HASHBIDIMAP_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHBIDIMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_HASHBIDIMAP_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \
+ CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHBIDIMAP_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_HASHBIDIMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHBIDIMAP_CORE_HEADER(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE(PARAMS) \
+ CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * HashBidimap Specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_hashbidimap = "struct %s<%s, %s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "load:%lf, "
- "flag:%d, "
- "f_key:%p, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_HASHBIDIMAP(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V)
+#define CMC_CMC_HASHBIDIMAP_CORE_STRUCT_(PFX, SNAME, K, V) \
+\
+ /* HashBidiMap Structure */ \
+ struct SNAME \
+ { \
+ /* Array 0 is K -> V and array 1 is V -> K */ \
+ struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \
+\
+ /* Current arrays capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of keys */ \
+ size_t count; \
+\
+ /* Load factor in range (0.0, 1.0) */ \
+ double load; \
+\
+ /* Flags indicating errors or success */ \
+ int flag; \
+\
+ /* Key function table */ \
+ struct CMC_DEF_FKEY(SNAME) * f_key; \
+\
+ /* 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; \
+\
+ /* Methods */ \
+ /* Returns an iterator to the start of the hashbidimap */ \
+ struct CMC_DEF_ITER(SNAME) (*it_start)(struct SNAME *); \
+\
+ /* Returns an iterator to the end of the hashbidimap */ \
+ struct CMC_DEF_ITER(SNAME) (*it_end)(struct SNAME *); \
+ }; \
+\
+ /* HashBidiMap Entry */ \
+ struct CMC_DEF_ENTRY(SNAME) \
+ { \
+ /* Entry Key */ \
+ K key; \
+\
+ /* Entry Value */ \
+ V value; \
+\
+ /* The distance of this node to its original position */ \
+ /* dist[0] is relative to K -> V */ \
+ /* dist[1] is relative to V -> K */ \
+ size_t dist[2]; \
+\
+ /* References to this node in the hashbidimap buffer. Used to */ \
+ /* prevent searching for this node twice for update() and */ \
+ /* remove(). Increases memory overhead but reduces execution time */ \
+ /* ref[0] is relative to K -> V */ \
+ /* ref[1] is relative to V -> K */ \
+ struct CMC_DEF_ENTRY(SNAME) * *ref[2]; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHBIDIMAP_HEADER(PFX, SNAME, K, V) \
- \
- /* HashBidiMap Structure */ \
- struct SNAME \
- { \
- /* Array 0 is K -> V and array 1 is V -> K */ \
- struct SNAME##_entry *(*buffer)[2]; \
- \
- /* Current arrays capacity */ \
- size_t capacity; \
- \
- /* Current amount of keys */ \
- size_t count; \
- \
- /* Load factor in range (0.0, 1.0) */ \
- double load; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Key function table */ \
- struct SNAME##_fkey *f_key; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- \
- /* Methods */ \
- /* Returns an iterator to the start of the hashbidimap */ \
- struct SNAME##_iter (*it_start)(struct SNAME *); \
- \
- /* Returns an iterator to the end of the hashbidimap */ \
- struct SNAME##_iter (*it_end)(struct SNAME *); \
- }; \
- \
- /* HashBidiMap Entry */ \
- struct SNAME##_entry \
- { \
- /* Entry Key */ \
- K key; \
- \
- /* Entry Value */ \
- V value; \
- \
- /* The distance of this node to its original position */ \
- /* dist[0] is relative to K -> V */ \
- /* dist[1] is relative to V -> K */ \
- size_t dist[2]; \
- \
- /* References to this node in the hashbidimap buffer. Used to */ \
- /* prevent searching for this node twice for update() and */ \
- /* remove(). Increases memory overhead but reduces execution time */ \
- /* ref[0] is relative to K -> V */ \
- /* ref[1] is relative to V -> K */ \
- struct SNAME##_entry **ref[2]; \
- }; \
- \
- /* Key struct function table */ \
- struct SNAME##_fkey \
- { \
- /* Comparator function */ \
- int (*cmp)(K, K); \
- \
- /* Copy function */ \
- K (*cpy)(K); \
- \
- /* To string function */ \
- bool (*str)(FILE *, K); \
- \
- /* Free from memory function */ \
- void (*free)(K); \
- \
- /* Hash function */ \
- size_t (*hash)(K); \
- \
- /* Priority function */ \
- int (*pri)(K, K); \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* HashBidiMap Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target hashbidimap */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* The index of the first element */ \
- size_t first; \
- \
- /* The index of the last element */ \
- size_t last; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_map_); \
- void PFX##_free(struct SNAME *_map_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_map_, K key, V value); \
- bool PFX##_update_key(struct SNAME *_map_, V val, K new_key); \
- bool PFX##_update_val(struct SNAME *_map_, K key, V new_val); \
- bool PFX##_remove_by_key(struct SNAME *_map_, K key, K *out_key, \
- V *out_val); \
- bool PFX##_remove_by_val(struct SNAME *_map_, V val, K *out_key, \
- V *out_val); \
- /* Element Access */ \
- K PFX##_get_key(struct SNAME *_map_, V val); \
- V PFX##_get_val(struct SNAME *_map_, K key); \
- /* Collection State */ \
- bool PFX##_contains_key(struct SNAME *_map_, K key); \
- bool PFX##_contains_val(struct SNAME *_map_, V val); \
- bool PFX##_empty(struct SNAME *_map_); \
- bool PFX##_full(struct SNAME *_map_); \
- size_t PFX##_count(struct SNAME *_map_); \
- size_t PFX##_capacity(struct SNAME *_map_); \
- double PFX##_load(struct SNAME *_map_); \
- int PFX##_flag(struct SNAME *_map_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_map_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_); \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_map_); \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Allocation and Deallocation */ \
- struct SNAME##_iter *PFX##_iter_new(struct SNAME *target); \
- void PFX##_iter_free(struct SNAME##_iter *iter); \
- /* Iterator Initialization */ \
- void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- void PFX##_iter_to_start(struct SNAME##_iter *iter); \
- void PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- K PFX##_iter_key(struct SNAME##_iter *iter); \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_HASHBIDIMAP_CORE_HEADER_(PFX, SNAME, K, V) \
+\
+ /* Key struct function table */ \
+ struct CMC_DEF_FKEY(SNAME) \
+ { \
+ /* Comparator function */ \
+ CMC_DEF_FTAB_CMP(K); \
+\
+ /* Copy function */ \
+ CMC_DEF_FTAB_CPY(K); \
+\
+ /* To string function */ \
+ CMC_DEF_FTAB_STR(K); \
+\
+ /* Free from memory function */ \
+ CMC_DEF_FTAB_FREE(K); \
+\
+ /* Hash function */ \
+ CMC_DEF_FTAB_HASH(K); \
+\
+ /* Priority function */ \
+ CMC_DEF_FTAB_PRI(K); \
+ }; \
+\
+ /* 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); \
+ }; \
+\
+ /* HashBidiMap Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target hashbidimap */ \
+ struct SNAME *target; \
+\
+ /* Cursor's position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* The index of the first element */ \
+ size_t first; \
+\
+ /* The index of the last element */ \
+ size_t last; \
+\
+ /* If the iterator has reached the start of the iteration */ \
+ bool start; \
+\
+ /* If the iterator has reached the end of the iteration */ \
+ bool end; \
+ }; \
+\
+ /* Collection Functions */ \
+ /* Collection Allocation and Deallocation */ \
+ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _map_); \
+ void CMC_(PFX, _free)(struct SNAME * _map_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \
+ bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key); \
+ bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val); \
+ bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, V * out_val); \
+ bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, V * out_val); \
+ /* Element Access */ \
+ K CMC_(PFX, _get_key)(struct SNAME * _map_, V val); \
+ V CMC_(PFX, _get_val)(struct SNAME * _map_, K key); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key); \
+ bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val); \
+ bool CMC_(PFX, _empty)(struct SNAME * _map_); \
+ bool CMC_(PFX, _full)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \
+ double CMC_(PFX, _load)(struct SNAME * _map_); \
+ int CMC_(PFX, _flag)(struct SNAME * _map_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_); \
+\
+ /* Iterator Functions */ \
+ /* Iterator Allocation and Deallocation */ \
+ struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target); \
+ void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter); \
+ /* Iterator Initialization */ \
+ void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, struct SNAME * target); \
+ /* Iterator State */ \
+ bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter); \
+ bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter); \
+ /* Iterator Movement */ \
+ void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter); \
+ void 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 */ \
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHBIDIMAP_SOURCE(PFX, SNAME, K, V) \
- \
- /* Implementation Detail Functions */ \
- static struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, \
- K key, V value); \
- static struct SNAME##_entry **PFX##_impl_get_entry_by_key( \
- struct SNAME *_map_, K key); \
- static struct SNAME##_entry **PFX##_impl_get_entry_by_val( \
- struct SNAME *_map_, V val); \
- static struct SNAME##_entry **PFX##_impl_add_entry_to_key( \
- struct SNAME *_map_, struct SNAME##_entry *entry); \
- static struct SNAME##_entry **PFX##_impl_add_entry_to_val( \
- struct SNAME *_map_, struct SNAME##_entry *entry); \
- static size_t PFX##_impl_calculate_size(size_t required); \
- static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_map_); \
- static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_); \
- \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_key || !f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \
- \
- if (!_map_->buffer) \
- { \
- alloc->free(_map_->buffer); \
- alloc->free(_map_); \
- return NULL; \
- } \
- \
- _map_->count = 0; \
- _map_->capacity = real_capacity; \
- _map_->load = load; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->alloc = alloc; \
- _map_->callbacks = NULL; \
- _map_->it_start = PFX##_impl_it_start; \
- _map_->it_end = PFX##_impl_it_end; \
- \
- return _map_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_key || !f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \
- \
- if (!_map_->buffer) \
- { \
- alloc->free(_map_->buffer); \
- alloc->free(_map_); \
- return NULL; \
- } \
- \
- _map_->count = 0; \
- _map_->capacity = real_capacity; \
- _map_->load = load; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->flag = cmc_flags.OK; \
- _map_->alloc = alloc; \
- _map_->callbacks = callbacks; \
- _map_->it_start = PFX##_impl_it_start; \
- _map_->it_end = PFX##_impl_it_end; \
- \
- return _map_; \
- } \
- \
- void PFX##_clear(struct SNAME *_map_) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = _map_->buffer[i][0]; \
- \
- if (entry && entry != CMC_ENTRY_DELETED) \
- { \
- if (_map_->f_key->free) \
- _map_->f_key->free(entry->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(entry->value); \
- \
- _map_->alloc->free(entry); \
- } \
- \
- _map_->buffer[i][0] = NULL; \
- _map_->buffer[i][1] = NULL; \
- } \
- \
- _map_->count = 0; \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_map_) \
- { \
- PFX##_clear(_map_); \
- \
- _map_->alloc->free(_map_->buffer); \
- _map_->alloc->free(_map_); \
- } \
- \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _map_->alloc = &cmc_alloc_node_default; \
- else \
- _map_->alloc = alloc; \
- \
- _map_->callbacks = callbacks; \
- \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_map_, K key, V value) \
- { \
- if (PFX##_full(_map_)) \
- { \
- if (!PFX##_resize(_map_, _map_->capacity + 1)) \
- return false; \
- } \
- \
- if (PFX##_impl_get_entry_by_key(_map_, key) != NULL || \
- PFX##_impl_get_entry_by_val(_map_, value) != NULL) \
- { \
- _map_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \
- \
- struct SNAME##_entry **key_entry = \
- PFX##_impl_add_entry_to_key(_map_, entry); \
- struct SNAME##_entry **val_entry = \
- PFX##_impl_add_entry_to_val(_map_, entry); \
- \
- if (!key_entry || !val_entry) \
- { \
- if (key_entry) \
- *key_entry = CMC_ENTRY_DELETED; \
- if (val_entry) \
- *val_entry = CMC_ENTRY_DELETED; \
- \
- _map_->alloc->free(entry); \
- \
- _map_->flag = cmc_flags.ERROR; \
- \
- return false; \
- } \
- \
- _map_->count++; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->create) \
- _map_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_update_key(struct SNAME *_map_, V val, K new_key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry **key_entry, **val_entry; \
- \
- val_entry = PFX##_impl_get_entry_by_val(_map_, val); \
- \
- if (!val_entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- /* The mapping val -> new_key is already true */ \
- if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) \
- goto success; \
- \
- if (PFX##_impl_get_entry_by_key(_map_, new_key) != NULL) \
- { \
- _map_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- \
- key_entry = (*val_entry)->ref[0]; \
- \
- if (!key_entry || *key_entry != *val_entry) \
- { \
- /* Should never happen */ \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Remove entry from key buffer and add it again with new key */ \
- struct SNAME##_entry *to_add = *key_entry; \
- K tmp_key = to_add->key; \
- to_add->key = new_key; \
- \
- *key_entry = CMC_ENTRY_DELETED; \
- \
- if (!PFX##_impl_add_entry_to_key(_map_, to_add)) \
- { \
- /* Revert changes */ \
- to_add->key = tmp_key; \
- *key_entry = to_add; \
- \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- success: \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->update) \
- _map_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_update_val(struct SNAME *_map_, K key, V new_val) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry **key_entry, **val_entry; \
- \
- key_entry = PFX##_impl_get_entry_by_key(_map_, key); \
- \
- if (!key_entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- /* The mapping key -> new_val is already true */ \
- if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) \
- goto success; \
- \
- if (PFX##_impl_get_entry_by_val(_map_, new_val) != NULL) \
- { \
- _map_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- \
- val_entry = (*key_entry)->ref[1]; \
- \
- if (!val_entry || *val_entry != *key_entry) \
- { \
- /* Should never happen */ \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Remove entry from value buffer and add it again with new value */ \
- struct SNAME##_entry *to_add = *val_entry; \
- V tmp_val = to_add->value; \
- to_add->value = new_val; \
- \
- *val_entry = CMC_ENTRY_DELETED; \
- \
- if (!PFX##_impl_add_entry_to_val(_map_, to_add)) \
- { \
- /* Revert changes */ \
- to_add->value = tmp_val; \
- *val_entry = to_add; \
- \
- _map_->flag = cmc_flags.ERROR; \
- \
- return false; \
- } \
- \
- success: \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->update) \
- _map_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove_by_key(struct SNAME *_map_, K key, K *out_key, \
- V *out_val) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry **key_entry, **val_entry; \
- \
- key_entry = PFX##_impl_get_entry_by_key(_map_, key); \
- \
- if (!key_entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- val_entry = (*key_entry)->ref[1]; \
- \
- if (!val_entry || *val_entry != *key_entry) \
- { \
- /* Should never happen */ \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- if (out_key) \
- *out_key = (*key_entry)->key; \
- if (out_val) \
- *out_val = (*key_entry)->value; \
- \
- _map_->alloc->free(*key_entry); \
- \
- *key_entry = CMC_ENTRY_DELETED; \
- *val_entry = CMC_ENTRY_DELETED; \
- \
- _map_->count--; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->delete) \
- _map_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_remove_by_val(struct SNAME *_map_, V val, K *out_key, \
- V *out_val) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry **key_entry, **val_entry; \
- \
- val_entry = PFX##_impl_get_entry_by_val(_map_, val); \
- \
- if (!val_entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- key_entry = (*val_entry)->ref[0]; \
- \
- if (!key_entry || *key_entry != *val_entry) \
- { \
- /* Should never happen */ \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- if (out_key) \
- *out_key = (*val_entry)->key; \
- if (out_val) \
- *out_val = (*val_entry)->value; \
- \
- _map_->alloc->free(*val_entry); \
- \
- *key_entry = CMC_ENTRY_DELETED; \
- *val_entry = CMC_ENTRY_DELETED; \
- \
- _map_->count--; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->delete) \
- _map_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- K PFX##_get_key(struct SNAME *_map_, V val) \
- { \
- struct SNAME##_entry **entry = \
- PFX##_impl_get_entry_by_val(_map_, val); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return (V){ 0 }; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return (*entry)->key; \
- } \
- \
- V PFX##_get_val(struct SNAME *_map_, K key) \
- { \
- struct SNAME##_entry **entry = \
- PFX##_impl_get_entry_by_key(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return (V){ 0 }; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return (*entry)->value; \
- } \
- \
- bool PFX##_contains_key(struct SNAME *_map_, K key) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- bool result = PFX##_impl_get_entry_by_key(_map_, key) != NULL; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_contains_val(struct SNAME *_map_, V val) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- bool result = PFX##_impl_get_entry_by_val(_map_, val) != NULL; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_map_) \
- { \
- return _map_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_map_) \
- { \
- return (double)_map_->capacity * _map_->load <= (double)_map_->count; \
- } \
- \
- size_t PFX##_count(struct SNAME *_map_) \
- { \
- return _map_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_map_) \
- { \
- return _map_->capacity; \
- } \
- \
- double PFX##_load(struct SNAME *_map_) \
- { \
- return _map_->load; \
- } \
- \
- int PFX##_flag(struct SNAME *_map_) \
- { \
- return _map_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_map_, size_t capacity) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->capacity == capacity) \
- goto success; \
- \
- if (_map_->capacity > capacity / _map_->load) \
- goto success; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * _map_->load) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Calculate required capacity based on the prime numbers */ \
- size_t new_cap = PFX##_impl_calculate_size(capacity); \
- \
- /* Not possible to shrink with current available prime numbers */ \
- if (new_cap < _map_->count / _map_->load) \
- { \
- _map_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- /* No callbacks since _new_map_ is just a temporary hashtable */ \
- struct SNAME *_new_map_ = \
- PFX##_new_custom(capacity, _map_->load, _map_->f_key, \
- _map_->f_val, _map_->alloc, NULL); \
- \
- if (!_new_map_) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = _map_->buffer[i][0]; \
- \
- if (scan && scan != CMC_ENTRY_DELETED) \
- { \
- struct SNAME##_entry **e1 = \
- PFX##_impl_add_entry_to_key(_new_map_, scan); \
- struct SNAME##_entry **e2 = \
- PFX##_impl_add_entry_to_val(_new_map_, scan); \
- \
- if (!e1 || !e2) \
- { \
- /* Prevent the map from freeing the data */ \
- _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
- _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
- \
- _map_->alloc->free(_new_map_->buffer); \
- _map_->alloc->free(_new_map_); \
- \
- _map_->flag = cmc_flags.ERROR; \
- \
- return false; \
- } \
- \
- _new_map_->count++; \
- } \
- } \
- \
- if (_map_->count != _new_map_->count) \
- { \
- /* Prevent the map from freeing the data */ \
- _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
- _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
- \
- _map_->alloc->free(_new_map_->buffer); \
- _map_->alloc->free(_new_map_); \
- \
- _map_->flag = cmc_flags.ERROR; \
- \
- return false; \
- } \
- \
- struct SNAME##_entry *(*tmp_buff)[2] = _map_->buffer; \
- \
- _map_->buffer = _new_map_->buffer; \
- _map_->capacity = _new_map_->capacity; \
- \
- _map_->alloc->free(tmp_buff); \
- _map_->alloc->free(_new_map_); \
- \
- success: \
- \
- if (_map_->callbacks && _map_->callbacks->resize) \
- _map_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_) \
- { \
- /* TODO this function can be optimized */ \
- struct SNAME *result = PFX##_new_custom( \
- _map_->capacity * _map_->load, _map_->load, _map_->f_key, \
- _map_->f_val, _map_->alloc, _map_->callbacks); \
- \
- if (!result) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = _map_->buffer[i][0]; \
- \
- if (scan && scan != CMC_ENTRY_DELETED) \
- { \
- K tmp_key; \
- V tmp_val; \
- \
- if (_map_->f_key->cpy) \
- tmp_key = _map_->f_key->cpy(scan->key); \
- else \
- tmp_key = scan->key; \
- \
- if (_map_->f_val->cpy) \
- tmp_val = _map_->f_val->cpy(scan->value); \
- else \
- tmp_val = scan->value; \
- \
- /* TODO treat the possible errors */ \
- struct SNAME##_entry *entry = \
- PFX##_impl_new_entry(result, tmp_key, tmp_val); \
- \
- PFX##_impl_add_entry_to_key(result, entry); \
- PFX##_impl_add_entry_to_val(result, entry); \
- \
- result->count++; \
- } \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \
- { \
- _map1_->flag = cmc_flags.OK; \
- _map2_->flag = cmc_flags.OK; \
- \
- if (_map1_->count != _map2_->count) \
- return false; \
- \
- struct SNAME *_mapA_; \
- struct SNAME *_mapB_; \
- \
- if (_map1_->capacity < _map2_->capacity) \
- { \
- _mapA_ = _map1_; \
- _mapB_ = _map2_; \
- } \
- else \
- { \
- _mapA_ = _map2_; \
- _mapB_ = _map1_; \
- } \
- \
- for (size_t i = 0; i < _mapA_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = _mapA_->buffer[i][0]; \
- \
- if (scan && scan != CMC_ENTRY_DELETED) \
- { \
- struct SNAME##_entry **entry_B = \
- PFX##_impl_get_entry_by_key(_mapB_, scan->key); \
- \
- if (!entry_B) \
- return false; \
- \
- if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) \
- return false; \
- } \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_map_) \
- { \
- struct cmc_string str; \
- struct SNAME *m_ = _map_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashbidimap, \
- #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \
- m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \
- m_->alloc, m_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *target = _map_->buffer[i][0]; \
- \
- if (target && target != CMC_ENTRY_DELETED) \
- { \
- if (!_map_->f_key->str(fptr, target->key) || \
- !_map_->f_val->str(fptr, target->value)) \
- return false; \
- } \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter *PFX##_iter_new(struct SNAME *target) \
- { \
- struct SNAME##_iter *iter = \
- target->alloc->malloc(sizeof(struct SNAME##_iter)); \
- \
- if (!iter) \
- return NULL; \
- \
- PFX##_iter_init(iter, target); \
- \
- return iter; \
- } \
- \
- void PFX##_iter_free(struct SNAME##_iter *iter) \
- { \
- iter->target->alloc->free(iter); \
- } \
- \
- void PFX##_iter_init(struct SNAME##_iter *iter, struct SNAME *target) \
- { \
- memset(iter, 0, sizeof(struct SNAME##_iter)); \
- \
- iter->target = target; \
- iter->start = true; \
- iter->end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- struct SNAME##_entry *tmp = target->buffer[i][0]; \
- \
- if (tmp != NULL && tmp != CMC_ENTRY_DELETED) \
- { \
- iter->first = i; \
- break; \
- } \
- } \
- \
- iter->cursor = iter->first; \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- struct SNAME##_entry *tmp = target->buffer[i - 1][0]; \
- \
- if (tmp != NULL && tmp != CMC_ENTRY_DELETED) \
- { \
- iter->last = i - 1; \
- break; \
- } \
- } \
- } \
- } \
- \
- bool PFX##_iter_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- void PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->first; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = false; \
- } \
- } \
- \
- void PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->last; \
- iter->index = iter->target->count - 1; \
- iter->start = false; \
- iter->end = true; \
- } \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = iter->target->buffer[iter->cursor][0]; \
- \
- iter->index++; \
- \
- while (1) \
- { \
- iter->cursor++; \
- scan = iter->target->buffer[iter->cursor][0]; \
- \
- if (scan != NULL && scan != CMC_ENTRY_DELETED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = iter->target->buffer[iter->cursor][0]; \
- \
- iter->index--; \
- \
- while (1) \
- { \
- iter->cursor--; \
- scan = iter->target->buffer[iter->cursor][0]; \
- \
- if (scan != NULL && scan != CMC_ENTRY_DELETED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at */ \
- /* the given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- K PFX##_iter_key(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- { \
- iter->target->flag = cmc_flags.EMPTY; \
- return (K){ 0 }; \
- } \
- \
- return iter->target->buffer[iter->cursor][0]->key; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- { \
- iter->target->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- return iter->target->buffer[iter->cursor][0]->value; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, \
- K key, V value) \
- { \
- struct SNAME##_entry *entry = \
- _map_->alloc->malloc(sizeof(struct SNAME##_entry)); \
- \
- if (!entry) \
- return NULL; \
- \
- entry->key = key; \
- entry->value = value; \
- entry->dist[0] = 0; \
- entry->dist[1] = 0; \
- entry->ref[0] = NULL; \
- entry->ref[1] = NULL; \
- \
- return entry; \
- } \
- \
- static struct SNAME##_entry **PFX##_impl_get_entry_by_key( \
- struct SNAME *_map_, K key) \
- { \
- size_t hash = _map_->f_key->hash(key); \
- size_t pos = hash % _map_->capacity; \
- \
- struct SNAME##_entry *target = _map_->buffer[pos][0]; \
- \
- while (target != NULL) \
- { \
- if (target != CMC_ENTRY_DELETED && \
- _map_->f_key->cmp(target->key, key) == 0) \
- return &(_map_->buffer[pos % _map_->capacity][0]); \
- \
- pos++; \
- target = _map_->buffer[pos % _map_->capacity][0]; \
- } \
- \
- return NULL; \
- } \
- \
- static struct SNAME##_entry **PFX##_impl_get_entry_by_val( \
- struct SNAME *_map_, V val) \
- { \
- size_t hash = _map_->f_val->hash(val); \
- size_t pos = hash % _map_->capacity; \
- \
- struct SNAME##_entry *target = _map_->buffer[pos][1]; \
- \
- while (target != NULL) \
- { \
- if (target != CMC_ENTRY_DELETED && \
- _map_->f_val->cmp(target->value, val) == 0) \
- return &(_map_->buffer[pos % _map_->capacity][1]); \
- \
- pos++; \
- target = _map_->buffer[pos % _map_->capacity][1]; \
- } \
- \
- return NULL; \
- } \
- \
- static struct SNAME##_entry **PFX##_impl_add_entry_to_key( \
- struct SNAME *_map_, struct SNAME##_entry *entry) \
- { \
- struct SNAME##_entry **to_return = NULL; \
- \
- size_t hash = _map_->f_key->hash(entry->key); \
- size_t original_pos = hash % _map_->capacity; \
- size_t pos = original_pos; \
- \
- struct SNAME##_entry **scan = \
- &(_map_->buffer[hash % _map_->capacity][0]); \
- \
- if (*scan == NULL) \
- { \
- *scan = entry; \
- \
- entry->ref[0] = scan; \
- \
- return scan; \
- } \
- else \
- { \
- while (true) \
- { \
- pos++; \
- scan = &(_map_->buffer[pos % _map_->capacity][0]); \
- \
- if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \
- { \
- if (!to_return) \
- to_return = scan; \
- \
- *scan = entry; \
- entry->ref[0] = scan; \
- entry->dist[0] = pos - original_pos; \
- \
- return to_return; \
- } \
- else if ((*scan)->dist[0] < pos - original_pos) \
- { \
- if (!to_return) \
- to_return = scan; \
- \
- size_t tmp_dist = (*scan)->dist[0]; \
- entry->dist[0] = pos - original_pos; \
- original_pos = pos - tmp_dist; \
- \
- entry->ref[0] = scan; \
- \
- struct SNAME##_entry *_tmp_ = *scan; \
- *scan = entry; \
- entry = _tmp_; \
- } \
- } \
- } \
- \
- return NULL; \
- } \
- \
- static struct SNAME##_entry **PFX##_impl_add_entry_to_val( \
- struct SNAME *_map_, struct SNAME##_entry *entry) \
- { \
- struct SNAME##_entry **to_return = NULL; \
- \
- size_t hash = _map_->f_val->hash(entry->value); \
- size_t original_pos = hash % _map_->capacity; \
- size_t pos = original_pos; \
- \
- struct SNAME##_entry **scan = \
- &(_map_->buffer[hash % _map_->capacity][1]); \
- \
- if (*scan == NULL) \
- { \
- *scan = entry; \
- \
- entry->ref[1] = scan; \
- \
- return scan; \
- } \
- else \
- { \
- while (true) \
- { \
- pos++; \
- scan = &(_map_->buffer[pos % _map_->capacity][1]); \
- \
- if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \
- { \
- if (!to_return) \
- to_return = scan; \
- \
- *scan = entry; \
- entry->ref[1] = scan; \
- entry->dist[1] = pos - original_pos; \
- \
- return to_return; \
- } \
- else if ((*scan)->dist[1] < pos - original_pos) \
- { \
- if (!to_return) \
- to_return = scan; \
- \
- size_t tmp_dist = (*scan)->dist[1]; \
- entry->dist[1] = pos - original_pos; \
- original_pos = pos - tmp_dist; \
- \
- entry->ref[1] = scan; \
- \
- struct SNAME##_entry *_tmp_ = *scan; \
- *scan = entry; \
- entry = _tmp_; \
- } \
- } \
- } \
- \
- return NULL; \
- } \
- \
- static size_t PFX##_impl_calculate_size(size_t required) \
- { \
- const size_t count = \
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
- \
- if (cmc_hashtable_primes[count - 1] < required) \
- return required; \
- \
- size_t i = 0; \
- while (cmc_hashtable_primes[i] < required) \
- i++; \
- \
- return cmc_hashtable_primes[i]; \
- } \
- \
- static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_map_) \
- { \
- struct SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _map_); \
- \
- return iter; \
- } \
- \
- static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_map_) \
- { \
- struct SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _map_); \
- PFX##_iter_to_end(&iter); \
- \
- return iter; \
+#define CMC_CMC_HASHBIDIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \
+\
+ /* Implementation Detail Functions */ \
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \
+ static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key); \
+ static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val); \
+ static struct CMC_DEF_ENTRY(SNAME) * \
+ *CMC_(PFX, _impl_add_entry_to_key)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \
+ static struct CMC_DEF_ENTRY(SNAME) * \
+ *CMC_(PFX, _impl_add_entry_to_val)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry); \
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \
+ static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_start)(struct SNAME * _map_); \
+ static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_end)(struct SNAME * _map_); \
+\
+ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ 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 || load <= 0 || load >= 1) \
+ return NULL; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * load) \
+ return NULL; \
+\
+ if (!f_key || !f_val) \
+ return NULL; \
+\
+ size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_map_) \
+ return NULL; \
+\
+ _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \
+\
+ if (!_map_->buffer) \
+ { \
+ alloc->free(_map_->buffer); \
+ alloc->free(_map_); \
+ return NULL; \
+ } \
+\
+ _map_->count = 0; \
+ _map_->capacity = real_capacity; \
+ _map_->load = load; \
+ _map_->flag = CMC_FLAG_OK; \
+ _map_->f_key = f_key; \
+ _map_->f_val = f_val; \
+ _map_->flag = CMC_FLAG_OK; \
+ _map_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+ _map_->it_start = CMC_(PFX, _impl_it_start); \
+ _map_->it_end = CMC_(PFX, _impl_it_end); \
+\
+ return _map_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _map_) \
+ { \
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ if (_map_->f_key->free) \
+ _map_->f_key->free(entry->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(entry->value); \
+\
+ _map_->alloc->free(entry); \
+ } \
+\
+ _map_->buffer[i][0] = NULL; \
+ _map_->buffer[i][1] = NULL; \
+ } \
+\
+ _map_->count = 0; \
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _map_) \
+ { \
+ CMC_(PFX, _clear)(_map_); \
+\
+ _map_->alloc->free(_map_->buffer); \
+ _map_->alloc->free(_map_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _map_->alloc = &cmc_alloc_node_default; \
+ else \
+ _map_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \
+ { \
+ if (CMC_(PFX, _full)(_map_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \
+ return false; \
+ } \
+\
+ if (CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL || \
+ CMC_(PFX, _impl_get_entry_by_val)(_map_, value) != NULL) \
+ { \
+ _map_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(_map_, key, value); \
+\
+ struct CMC_DEF_ENTRY(SNAME) **key_entry = CMC_(PFX, _impl_add_entry_to_key)(_map_, entry); \
+ struct CMC_DEF_ENTRY(SNAME) **val_entry = CMC_(PFX, _impl_add_entry_to_val)(_map_, entry); \
+\
+ if (!key_entry || !val_entry) \
+ { \
+ if (key_entry) \
+ *key_entry = CMC_ENTRY_DELETED; \
+ if (val_entry) \
+ *val_entry = CMC_ENTRY_DELETED; \
+\
+ _map_->alloc->free(entry); \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+\
+ return false; \
+ } \
+\
+ _map_->count++; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _update_key)(struct SNAME * _map_, V val, K new_key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \
+\
+ val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \
+\
+ if (!val_entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ /* The mapping val -> new_key is already true */ \
+ if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0) \
+ goto success; \
+\
+ if (CMC_(PFX, _impl_get_entry_by_key)(_map_, new_key) != NULL) \
+ { \
+ _map_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+\
+ key_entry = (*val_entry)->ref[0]; \
+\
+ if (!key_entry || *key_entry != *val_entry) \
+ { \
+ /* Should never happen */ \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Remove entry from key buffer and add it again with new key */ \
+ struct CMC_DEF_ENTRY(SNAME) *to_add = *key_entry; \
+ K tmp_key = to_add->key; \
+ to_add->key = new_key; \
+\
+ *key_entry = CMC_ENTRY_DELETED; \
+\
+ if (!CMC_(PFX, _impl_add_entry_to_key)(_map_, to_add)) \
+ { \
+ /* Revert changes */ \
+ to_add->key = tmp_key; \
+ *key_entry = to_add; \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ success: \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, update); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _update_val)(struct SNAME * _map_, K key, V new_val) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \
+\
+ key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \
+\
+ if (!key_entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ /* The mapping key -> new_val is already true */ \
+ if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0) \
+ goto success; \
+\
+ if (CMC_(PFX, _impl_get_entry_by_val)(_map_, new_val) != NULL) \
+ { \
+ _map_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+\
+ val_entry = (*key_entry)->ref[1]; \
+\
+ if (!val_entry || *val_entry != *key_entry) \
+ { \
+ /* Should never happen */ \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Remove entry from value buffer and add it again with new value */ \
+ struct CMC_DEF_ENTRY(SNAME) *to_add = *val_entry; \
+ V tmp_val = to_add->value; \
+ to_add->value = new_val; \
+\
+ *val_entry = CMC_ENTRY_DELETED; \
+\
+ if (!CMC_(PFX, _impl_add_entry_to_val)(_map_, to_add)) \
+ { \
+ /* Revert changes */ \
+ to_add->value = tmp_val; \
+ *val_entry = to_add; \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+\
+ return false; \
+ } \
+\
+ success: \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, update); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove_by_key)(struct SNAME * _map_, K key, K * out_key, V * out_val) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \
+\
+ key_entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \
+\
+ if (!key_entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ val_entry = (*key_entry)->ref[1]; \
+\
+ if (!val_entry || *val_entry != *key_entry) \
+ { \
+ /* Should never happen */ \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ if (out_key) \
+ *out_key = (*key_entry)->key; \
+ if (out_val) \
+ *out_val = (*key_entry)->value; \
+\
+ _map_->alloc->free(*key_entry); \
+\
+ *key_entry = CMC_ENTRY_DELETED; \
+ *val_entry = CMC_ENTRY_DELETED; \
+\
+ _map_->count--; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove_by_val)(struct SNAME * _map_, V val, K * out_key, V * out_val) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * *key_entry, **val_entry; \
+\
+ val_entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \
+\
+ if (!val_entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ key_entry = (*val_entry)->ref[0]; \
+\
+ if (!key_entry || *key_entry != *val_entry) \
+ { \
+ /* Should never happen */ \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ if (out_key) \
+ *out_key = (*val_entry)->key; \
+ if (out_val) \
+ *out_val = (*val_entry)->value; \
+\
+ _map_->alloc->free(*val_entry); \
+\
+ *key_entry = CMC_ENTRY_DELETED; \
+ *val_entry = CMC_ENTRY_DELETED; \
+\
+ _map_->count--; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, delete); \
+\
+ return true; \
+ } \
+\
+ K CMC_(PFX, _get_key)(struct SNAME * _map_, V val) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) **entry = CMC_(PFX, _impl_get_entry_by_val)(_map_, val); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return (V){ 0 }; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return (*entry)->key; \
+ } \
+\
+ V CMC_(PFX, _get_val)(struct SNAME * _map_, K key) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) **entry = CMC_(PFX, _impl_get_entry_by_key)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return (V){ 0 }; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return (*entry)->value; \
+ } \
+\
+ bool CMC_(PFX, _contains_key)(struct SNAME * _map_, K key) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ bool result = CMC_(PFX, _impl_get_entry_by_key)(_map_, key) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _contains_val)(struct SNAME * _map_, V val) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ bool result = CMC_(PFX, _impl_get_entry_by_val)(_map_, val) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _map_) \
+ { \
+ return _map_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _map_) \
+ { \
+ return (double)_map_->capacity * _map_->load <= (double)_map_->count; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _map_) \
+ { \
+ return _map_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \
+ { \
+ return _map_->capacity; \
+ } \
+\
+ double CMC_(PFX, _load)(struct SNAME * _map_) \
+ { \
+ return _map_->load; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _map_) \
+ { \
+ return _map_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ if (_map_->capacity == capacity) \
+ goto success; \
+\
+ if (_map_->capacity > capacity / _map_->load) \
+ goto success; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * _map_->load) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Calculate required capacity based on the prime numbers */ \
+ size_t new_cap = CMC_(PFX, _impl_calculate_size)(capacity); \
+\
+ /* Not possible to shrink with current available prime numbers */ \
+ if (new_cap < _map_->count / _map_->load) \
+ { \
+ _map_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ /* No callbacks since _new_map_ is just a temporary hashtable */ \
+ struct SNAME *_new_map_ = \
+ CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!_new_map_) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \
+\
+ if (scan && scan != CMC_ENTRY_DELETED) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) **e1 = CMC_(PFX, _impl_add_entry_to_key)(_new_map_, scan); \
+ struct CMC_DEF_ENTRY(SNAME) **e2 = CMC_(PFX, _impl_add_entry_to_val)(_new_map_, scan); \
+\
+ if (!e1 || !e2) \
+ { \
+ /* Prevent the map from freeing the data */ \
+ _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \
+ _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \
+\
+ _map_->alloc->free(_new_map_->buffer); \
+ _map_->alloc->free(_new_map_); \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+\
+ return false; \
+ } \
+\
+ _new_map_->count++; \
+ } \
+ } \
+\
+ if (_map_->count != _new_map_->count) \
+ { \
+ /* Prevent the map from freeing the data */ \
+ _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \
+ _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \
+\
+ _map_->alloc->free(_new_map_->buffer); \
+ _map_->alloc->free(_new_map_); \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+\
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * (*tmp_buff)[2] = _map_->buffer; \
+\
+ _map_->buffer = _new_map_->buffer; \
+ _map_->capacity = _new_map_->capacity; \
+\
+ _map_->alloc->free(tmp_buff); \
+ _map_->alloc->free(_new_map_); \
+\
+ success: \
+\
+ CMC_CALLBACKS_CALL(_map_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \
+ { \
+ /* TODO this function can be optimized */ \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \
+ _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \
+\
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \
+\
+ if (scan && scan != CMC_ENTRY_DELETED) \
+ { \
+ K tmp_key; \
+ V tmp_val; \
+\
+ if (_map_->f_key->cpy) \
+ tmp_key = _map_->f_key->cpy(scan->key); \
+ else \
+ tmp_key = scan->key; \
+\
+ if (_map_->f_val->cpy) \
+ tmp_val = _map_->f_val->cpy(scan->value); \
+ else \
+ tmp_val = scan->value; \
+\
+ /* TODO treat the possible errors */ \
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(result, tmp_key, tmp_val); \
+\
+ CMC_(PFX, _impl_add_entry_to_key)(result, entry); \
+ CMC_(PFX, _impl_add_entry_to_val)(result, entry); \
+\
+ result->count++; \
+ } \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \
+ { \
+ _map1_->flag = CMC_FLAG_OK; \
+ _map2_->flag = CMC_FLAG_OK; \
+\
+ if (_map1_->count != _map2_->count) \
+ return false; \
+\
+ struct SNAME *_mapA_; \
+ struct SNAME *_mapB_; \
+\
+ if (_map1_->capacity < _map2_->capacity) \
+ { \
+ _mapA_ = _map1_; \
+ _mapB_ = _map2_; \
+ } \
+ else \
+ { \
+ _mapA_ = _map2_; \
+ _mapB_ = _map1_; \
+ } \
+\
+ for (size_t i = 0; i < _mapA_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = _mapA_->buffer[i][0]; \
+\
+ if (scan && scan != CMC_ENTRY_DELETED) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) **entry_B = CMC_(PFX, _impl_get_entry_by_key)(_mapB_, scan->key); \
+\
+ if (!entry_B) \
+ return false; \
+\
+ if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0) \
+ return false; \
+ } \
+ } \
+\
+ return true; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) * CMC_(PFX, _iter_new)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) *iter = target->alloc->malloc(sizeof(struct CMC_DEF_ITER(SNAME))); \
+\
+ if (!iter) \
+ return NULL; \
+\
+ CMC_(PFX, _iter_init)(iter, target); \
+\
+ return iter; \
+ } \
+\
+ void CMC_(PFX, _iter_free)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ iter->target->alloc->free(iter); \
+ } \
+\
+ void CMC_(PFX, _iter_init)(struct CMC_DEF_ITER(SNAME) * iter, struct SNAME * target) \
+ { \
+ memset(iter, 0, sizeof(struct CMC_DEF_ITER(SNAME))); \
+\
+ iter->target = target; \
+ iter->start = true; \
+ iter->end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ iter->first = i; \
+ break; \
+ } \
+ } \
+\
+ iter->cursor = iter->first; \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ iter->last = i - 1; \
+ break; \
+ } \
+ } \
+ } \
+ } \
+\
+ bool CMC_(PFX, _iter_start)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return CMC_(PFX, _empty)(iter->target) || iter->start; \
+ } \
+\
+ bool CMC_(PFX, _iter_end)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return CMC_(PFX, _empty)(iter->target) || iter->end; \
+ } \
+\
+ void CMC_(PFX, _iter_to_start)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (!CMC_(PFX, _empty)(iter->target)) \
+ { \
+ iter->cursor = iter->first; \
+ iter->index = 0; \
+ iter->start = true; \
+ iter->end = false; \
+ } \
+ } \
+\
+ void CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (!CMC_(PFX, _empty)(iter->target)) \
+ { \
+ iter->cursor = iter->last; \
+ iter->index = iter->target->count - 1; \
+ iter->start = false; \
+ iter->end = true; \
+ } \
+ } \
+\
+ bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->end) \
+ return false; \
+\
+ if (iter->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = iter->target->buffer[iter->cursor][0]; \
+\
+ iter->index++; \
+\
+ while (1) \
+ { \
+ iter->cursor++; \
+ scan = iter->target->buffer[iter->cursor][0]; \
+\
+ if (scan != NULL && scan != CMC_ENTRY_DELETED) \
+ break; \
+ } \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = iter->target->buffer[iter->cursor][0]; \
+\
+ iter->index--; \
+\
+ while (1) \
+ { \
+ iter->cursor--; \
+ scan = iter->target->buffer[iter->cursor][0]; \
+\
+ if (scan != NULL && scan != CMC_ENTRY_DELETED) \
+ break; \
+ } \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ return true; \
+ } \
+\
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ { \
+ iter->target->flag = CMC_FLAG_EMPTY; \
+ return (K){ 0 }; \
+ } \
+\
+ return iter->target->buffer[iter->cursor][0]->key; \
+ } \
+\
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ { \
+ iter->target->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ return iter->target->buffer[iter->cursor][0]->value; \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \
+\
+ if (!entry) \
+ return NULL; \
+\
+ entry->key = key; \
+ entry->value = value; \
+ entry->dist[0] = 0; \
+ entry->dist[1] = 0; \
+ entry->ref[0] = NULL; \
+ entry->ref[1] = NULL; \
+\
+ return entry; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_key)(struct SNAME * _map_, K key) \
+ { \
+ size_t hash = _map_->f_key->hash(key); \
+ size_t pos = hash % _map_->capacity; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][0]; \
+\
+ while (target != NULL) \
+ { \
+ if (target != CMC_ENTRY_DELETED && _map_->f_key->cmp(target->key, key) == 0) \
+ return &(_map_->buffer[pos % _map_->capacity][0]); \
+\
+ pos++; \
+ target = _map_->buffer[pos % _map_->capacity][0]; \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * *CMC_(PFX, _impl_get_entry_by_val)(struct SNAME * _map_, V val) \
+ { \
+ size_t hash = _map_->f_val->hash(val); \
+ size_t pos = hash % _map_->capacity; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = _map_->buffer[pos][1]; \
+\
+ while (target != NULL) \
+ { \
+ if (target != CMC_ENTRY_DELETED && _map_->f_val->cmp(target->value, val) == 0) \
+ return &(_map_->buffer[pos % _map_->capacity][1]); \
+\
+ pos++; \
+ target = _map_->buffer[pos % _map_->capacity][1]; \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * \
+ *CMC_(PFX, _impl_add_entry_to_key)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \
+\
+ size_t hash = _map_->f_key->hash(entry->key); \
+ size_t original_pos = hash % _map_->capacity; \
+ size_t pos = original_pos; \
+\
+ struct CMC_DEF_ENTRY(SNAME) **scan = &(_map_->buffer[hash % _map_->capacity][0]); \
+\
+ if (*scan == NULL) \
+ { \
+ *scan = entry; \
+\
+ entry->ref[0] = scan; \
+\
+ return scan; \
+ } \
+ else \
+ { \
+ while (true) \
+ { \
+ pos++; \
+ scan = &(_map_->buffer[pos % _map_->capacity][0]); \
+\
+ if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \
+ { \
+ if (!to_return) \
+ to_return = scan; \
+\
+ *scan = entry; \
+ entry->ref[0] = scan; \
+ entry->dist[0] = pos - original_pos; \
+\
+ return to_return; \
+ } \
+ else if ((*scan)->dist[0] < pos - original_pos) \
+ { \
+ if (!to_return) \
+ to_return = scan; \
+\
+ size_t tmp_dist = (*scan)->dist[0]; \
+ entry->dist[0] = pos - original_pos; \
+ original_pos = pos - tmp_dist; \
+\
+ entry->ref[0] = scan; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \
+ *scan = entry; \
+ entry = _tmp_; \
+ } \
+ } \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * \
+ *CMC_(PFX, _impl_add_entry_to_val)(struct SNAME * _map_, struct CMC_DEF_ENTRY(SNAME) * entry) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) **to_return = NULL; \
+\
+ size_t hash = _map_->f_val->hash(entry->value); \
+ size_t original_pos = hash % _map_->capacity; \
+ size_t pos = original_pos; \
+\
+ struct CMC_DEF_ENTRY(SNAME) **scan = &(_map_->buffer[hash % _map_->capacity][1]); \
+\
+ if (*scan == NULL) \
+ { \
+ *scan = entry; \
+\
+ entry->ref[1] = scan; \
+\
+ return scan; \
+ } \
+ else \
+ { \
+ while (true) \
+ { \
+ pos++; \
+ scan = &(_map_->buffer[pos % _map_->capacity][1]); \
+\
+ if (*scan == NULL || *scan == CMC_ENTRY_DELETED) \
+ { \
+ if (!to_return) \
+ to_return = scan; \
+\
+ *scan = entry; \
+ entry->ref[1] = scan; \
+ entry->dist[1] = pos - original_pos; \
+\
+ return to_return; \
+ } \
+ else if ((*scan)->dist[1] < pos - original_pos) \
+ { \
+ if (!to_return) \
+ to_return = scan; \
+\
+ size_t tmp_dist = (*scan)->dist[1]; \
+ entry->dist[1] = pos - original_pos; \
+ original_pos = pos - tmp_dist; \
+\
+ entry->ref[1] = scan; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *_tmp_ = *scan; \
+ *scan = entry; \
+ entry = _tmp_; \
+ } \
+ } \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \
+ { \
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
+\
+ if (cmc_hashtable_primes[count - 1] < required) \
+ return required; \
+\
+ size_t i = 0; \
+ while (cmc_hashtable_primes[i] < required) \
+ i++; \
+\
+ return cmc_hashtable_primes[i]; \
+ } \
+\
+ static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_start)(struct SNAME * _map_) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ CMC_(PFX, _iter_init)(&iter, _map_); \
+\
+ return iter; \
+ } \
+\
+ static struct CMC_DEF_ITER(SNAME) CMC_(PFX, _impl_it_end)(struct SNAME * _map_) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ CMC_(PFX, _iter_init)(&iter, _map_); \
+ CMC_(PFX, _iter_to_end)(&iter); \
+\
+ return iter; \
}
-#endif /* CMC_HASHBIDIMAP_H */
+#endif /* CMC_CMC_HASHBIDIMAP_H */
diff --git a/src/cmc/hashmap.h b/src/cmc/hashmap.h
index 33bafb3..0406261 100644
--- a/src/cmc/hashmap.h
+++ b/src/cmc/hashmap.h
@@ -1,5 +1,5 @@
/**
- * hashmap.h
+ * cmc/hashmap.h
*
* Creation Date: 03/04/2019
*
@@ -16,8 +16,8 @@
* hashtable with linear probing and robin hood hashing.
*/
-#ifndef CMC_HASHMAP_H
-#define CMC_HASHMAP_H
+#ifndef CMC_CMC_HASHMAP_H
+#define CMC_CMC_HASHMAP_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -29,1196 +29,802 @@
* ------------------------------------------------------------------------- */
#include "../cor/hashtable.h"
+/**
+ * Core HashMap implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_HASHMAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HASHMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_HASHMAP_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_HASHMAP_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \
+ CMC_CMC_HASHMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHMAP_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_HASHMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHMAP_CORE_HEADER(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHMAP_CORE_SOURCE(PARAMS) \
+ CMC_CMC_HASHMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * HashMap Specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_hashmap = "struct %s<%s, %s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "load:%lf, "
- "flag:%d, "
- "f_key:%p, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_HASHMAP(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMAP_SOURCE(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_HASHMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMAP_HEADER(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_HASHMAP_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMAP_SOURCE(PFX, SNAME, K, V)
+#define CMC_CMC_HASHMAP_CORE_STRUCT_(PFX, SNAME, K, V) \
+\
+ /* HashMap Structure */ \
+ struct SNAME \
+ { \
+ /* Array of Entries */ \
+ struct CMC_DEF_ENTRY(SNAME) * buffer; \
+\
+ /* Current array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of keys */ \
+ size_t count; \
+\
+ /* Load factor in range (0.0, 1.0) */ \
+ double load; \
+\
+ /* Flags indicating errors or success */ \
+ int flag; \
+\
+ /* Key function table */ \
+ struct CMC_DEF_FKEY(SNAME) * f_key; \
+\
+ /* 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; \
+ }; \
+\
+ /* HashMap Entry */ \
+ struct CMC_DEF_ENTRY(SNAME) \
+ { \
+ /* Entry Key */ \
+ K key; \
+\
+ /* Entry Value */ \
+ V value; \
+\
+ /* The distance of this node to its original position, used by */ \
+ /* robin-hood hashing */ \
+ size_t dist; \
+\
+ /* The sate of this node (DELETED, EMPTY, FILLED) */ \
+ enum cmc_entry_state state; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHMAP_HEADER(PFX, SNAME, K, V) \
- \
- /* Hashmap Structure */ \
- struct SNAME \
- { \
- /* Array of Entries */ \
- struct SNAME##_entry *buffer; \
- \
- /* Current array capacity */ \
- size_t capacity; \
- \
- /* Current amount of keys */ \
- size_t count; \
- \
- /* Load factor in range (0.0, 1.0) */ \
- double load; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Key function table */ \
- struct SNAME##_fkey *f_key; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Hashmap Entry */ \
- struct SNAME##_entry \
- { \
- /* Entry Key */ \
- K key; \
- \
- /* Entry Value */ \
- V value; \
- \
- /* The distance of this node to its original position, used by */ \
- /* robin-hood hashing */ \
- size_t dist; \
- \
- /* The sate of this node (DELETED, EMPTY, FILLED) */ \
- enum cmc_entry_state state; \
- }; \
- \
- /* Key struct function table */ \
- struct SNAME##_fkey \
- { \
- /* Comparator function */ \
- int (*cmp)(K, K); \
- \
- /* Copy function */ \
- K (*cpy)(K); \
- \
- /* To string function */ \
- bool (*str)(FILE *, K); \
- \
- /* Free from memory function */ \
- void (*free)(K); \
- \
- /* Hash function */ \
- size_t (*hash)(K); \
- \
- /* Priority function */ \
- int (*pri)(K, K); \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Hashmap Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target hashmap */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* The index of the first element */ \
- size_t first; \
- \
- /* The index of the last element */ \
- size_t last; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- struct SNAME PFX##_init(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val); \
- struct SNAME PFX##_init_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_map_); \
- void PFX##_free(struct SNAME *_map_); \
- void PFX##_release(struct SNAME _map_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_map_, K key, V value); \
- bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value); \
- bool PFX##_remove(struct SNAME *_map_, K key, V *out_value); \
- /* Element Access */ \
- bool PFX##_max(struct SNAME *_map_, K *key, V *value); \
- bool PFX##_min(struct SNAME *_map_, K *key, V *value); \
- V PFX##_get(struct SNAME *_map_, K key); \
- V *PFX##_get_ref(struct SNAME *_map_, K key); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_map_, K key); \
- bool PFX##_empty(struct SNAME *_map_); \
- bool PFX##_full(struct SNAME *_map_); \
- size_t PFX##_count(struct SNAME *_map_); \
- size_t PFX##_capacity(struct SNAME *_map_); \
- double PFX##_load(struct SNAME *_map_); \
- int PFX##_flag(struct SNAME *_map_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_map_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_); \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_map_); \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- K PFX##_iter_key(struct SNAME##_iter *iter); \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_HASHMAP_CORE_HEADER_(PFX, SNAME, K, V) \
+\
+ /* Key struct function table */ \
+ struct CMC_DEF_FKEY(SNAME) \
+ { \
+ /* Comparator function */ \
+ CMC_DEF_FTAB_CMP(K); \
+\
+ /* Copy function */ \
+ CMC_DEF_FTAB_CPY(K); \
+\
+ /* To string function */ \
+ CMC_DEF_FTAB_STR(K); \
+\
+ /* Free from memory function */ \
+ CMC_DEF_FTAB_FREE(K); \
+\
+ /* Hash function */ \
+ CMC_DEF_FTAB_HASH(K); \
+\
+ /* Priority function */ \
+ CMC_DEF_FTAB_PRI(K); \
+ }; \
+\
+ /* 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, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _map_); \
+ void CMC_(PFX, _free)(struct SNAME * _map_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \
+ bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \
+ bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \
+ /* Element Access */ \
+ bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \
+ bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \
+ V CMC_(PFX, _get)(struct SNAME * _map_, K key); \
+ V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \
+ bool CMC_(PFX, _empty)(struct SNAME * _map_); \
+ bool CMC_(PFX, _full)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \
+ double CMC_(PFX, _load)(struct SNAME * _map_); \
+ int CMC_(PFX, _flag)(struct SNAME * _map_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHMAP_SOURCE(PFX, SNAME, K, V) \
- \
- /* Implementation Detail Functions */ \
- static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, \
- K key); \
- static size_t PFX##_impl_calculate_size(size_t required); \
- \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val) \
- { \
- return PFX##_new_custom(capacity, load, f_key, f_val, NULL, NULL); \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_key || !f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
- \
- if (!_map_->buffer) \
- { \
- alloc->free(_map_); \
- return NULL; \
- } \
- \
- _map_->count = 0; \
- _map_->capacity = real_capacity; \
- _map_->load = load; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->alloc = alloc; \
- _map_->callbacks = callbacks; \
- \
- return _map_; \
- } \
- struct SNAME PFX##_init(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val) \
- { \
- return PFX##_init_custom(capacity, load, f_key, f_val, NULL, NULL); \
- } \
- \
- struct SNAME PFX##_init_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- struct SNAME _map_ = { 0 }; \
- \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return _map_; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return _map_; \
- \
- if (!f_key || !f_val) \
- return _map_; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- _map_.buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
- \
- if (!_map_.buffer) \
- return _map_; \
- \
- _map_.count = 0; \
- _map_.capacity = real_capacity; \
- _map_.load = load; \
- _map_.flag = cmc_flags.OK; \
- _map_.f_key = f_key; \
- _map_.f_val = f_val; \
- _map_.alloc = alloc; \
- _map_.callbacks = callbacks; \
- \
- return _map_; \
- } \
- \
- void PFX##_clear(struct SNAME *_map_) \
- { \
- if (_map_->f_key->free || _map_->f_val->free) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_map_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- if (_map_->f_key->free) \
- _map_->f_key->free(entry->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(entry->value); \
- } \
- } \
- } \
- \
- memset(_map_->buffer, 0, \
- sizeof(struct SNAME##_entry) * _map_->capacity); \
- \
- _map_->count = 0; \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_map_) \
- { \
- if (_map_->f_key->free || _map_->f_val->free) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_map_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- if (_map_->f_key->free) \
- _map_->f_key->free(entry->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(entry->value); \
- } \
- } \
- } \
- \
- _map_->alloc->free(_map_->buffer); \
- _map_->alloc->free(_map_); \
- } \
- \
- void PFX##_release(struct SNAME _map_) \
- { \
- if (_map_.f_key->free || _map_.f_val->free) \
- { \
- for (size_t i = 0; i < _map_.capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_map_.buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- if (_map_.f_key->free) \
- _map_.f_key->free(entry->key); \
- if (_map_.f_val->free) \
- _map_.f_val->free(entry->value); \
- } \
- } \
- } \
- \
- _map_.alloc->free(_map_.buffer); \
- } \
- \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _map_->alloc = &cmc_alloc_node_default; \
- else \
- _map_->alloc = alloc; \
- \
- _map_->callbacks = callbacks; \
- \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_map_, K key, V value) \
- { \
- if (PFX##_full(_map_)) \
- { \
- if (!PFX##_resize(_map_, _map_->capacity + 1)) \
- return false; \
- } \
- \
- if (PFX##_impl_get_entry(_map_, key) != NULL) \
- { \
- _map_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- \
- size_t hash = _map_->f_key->hash(key); \
- size_t original_pos = hash % _map_->capacity; \
- size_t pos = original_pos; \
- \
- struct SNAME##_entry *target = &(_map_->buffer[pos]); \
- \
+#define CMC_CMC_HASHMAP_CORE_SOURCE_(PFX, SNAME, K, V) \
+\
+ /* Implementation Detail Functions */ \
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \
+\
+ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ 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 || load <= 0 || load >= 1) \
+ return NULL; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * load) \
+ return NULL; \
+\
+ if (!f_key || !f_val) \
+ return NULL; \
+\
+ size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_map_) \
+ return NULL; \
+\
+ _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \
+\
+ if (!_map_->buffer) \
+ { \
+ alloc->free(_map_); \
+ return NULL; \
+ } \
+\
+ _map_->count = 0; \
+ _map_->capacity = real_capacity; \
+ _map_->load = load; \
+ _map_->flag = CMC_FLAG_OK; \
+ _map_->f_key = f_key; \
+ _map_->f_val = f_val; \
+ _map_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ return _map_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _map_) \
+ { \
+ if (_map_->f_key->free || _map_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ if (_map_->f_key->free) \
+ _map_->f_key->free(entry->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ memset(_map_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \
+\
+ _map_->count = 0; \
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _map_) \
+ { \
+ if (_map_->f_key->free || _map_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ if (_map_->f_key->free) \
+ _map_->f_key->free(entry->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ _map_->alloc->free(_map_->buffer); \
+ _map_->alloc->free(_map_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _map_->alloc = &cmc_alloc_node_default; \
+ else \
+ _map_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \
+ { \
+ if (CMC_(PFX, _full)(_map_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \
+ return false; \
+ } \
+\
+ if (CMC_(PFX, _impl_get_entry)(_map_, key) != NULL) \
+ { \
+ _map_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+\
+ size_t hash = _map_->f_key->hash(key); \
+ size_t original_pos = hash % _map_->capacity; \
+ size_t pos = original_pos; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \
+\
if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
- { \
- target->key = key; \
- target->value = value; \
- target->dist = 0; \
- target->state = CMC_ES_FILLED; \
- } \
- else \
- { \
- while (true) \
- { \
- pos++; \
- target = &(_map_->buffer[pos % _map_->capacity]); \
- \
- if (target->state == CMC_ES_EMPTY || \
- target->state == CMC_ES_DELETED) \
- { \
- target->key = key; \
- target->value = value; \
- target->dist = pos - original_pos; \
- target->state = CMC_ES_FILLED; \
- \
- break; \
- } \
- else if (target->dist < pos - original_pos) \
- { \
- K tmp_k = target->key; \
- V tmp_v = target->value; \
- size_t tmp_dist = target->dist; \
- \
- target->key = key; \
- target->value = value; \
- target->dist = pos - original_pos; \
- \
- key = tmp_k; \
- value = tmp_v; \
- original_pos = pos - tmp_dist; \
- } \
- } \
- } \
- \
- _map_->count++; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->create) \
- _map_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- if (old_value) \
- *old_value = entry->value; \
- \
- entry->value = new_value; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->update) \
- _map_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *result = PFX##_impl_get_entry(_map_, key); \
- \
- if (result == NULL) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- if (out_value) \
- *out_value = result->value; \
- \
- result->key = (K){ 0 }; \
- result->value = (V){ 0 }; \
- result->dist = 0; \
- result->state = CMC_ES_DELETED; \
- \
- _map_->count--; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->delete) \
- _map_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_max(struct SNAME *_map_, K *key, V *value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- K max_key = PFX##_iter_key(&iter); \
- V max_val = PFX##_iter_value(&iter); \
- \
- PFX##_iter_next(&iter); \
- \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K iter_key = PFX##_iter_key(&iter); \
- V iter_val = PFX##_iter_value(&iter); \
- \
- if (_map_->f_key->cmp(iter_key, max_key) > 0) \
- { \
- max_key = iter_key; \
- max_val = iter_val; \
- } \
- } \
- \
- if (key) \
- *key = max_key; \
- if (value) \
- *value = max_val; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_min(struct SNAME *_map_, K *key, V *value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- K min_key = PFX##_iter_key(&iter); \
- V min_val = PFX##_iter_value(&iter); \
- \
- PFX##_iter_next(&iter); \
- \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K iter_key = PFX##_iter_key(&iter); \
- V iter_val = PFX##_iter_value(&iter); \
- \
- if (_map_->f_key->cmp(iter_key, min_key) < 0) \
- { \
- min_key = iter_key; \
- min_val = iter_val; \
- } \
- } \
- \
- if (key) \
- *key = min_key; \
- if (value) \
- *value = min_val; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return true; \
- } \
- \
- V PFX##_get(struct SNAME *_map_, K key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return (V){ 0 }; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return entry->value; \
- } \
- \
- V *PFX##_get_ref(struct SNAME *_map_, K key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return NULL; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return &(entry->value); \
- } \
- \
- bool PFX##_contains(struct SNAME *_map_, K key) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- bool result = PFX##_impl_get_entry(_map_, key) != NULL; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_map_) \
- { \
- return _map_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_map_) \
- { \
+ { \
+ target->key = key; \
+ target->value = value; \
+ target->dist = 0; \
+ target->state = CMC_ES_FILLED; \
+ } \
+ else \
+ { \
+ while (true) \
+ { \
+ pos++; \
+ target = &(_map_->buffer[pos % _map_->capacity]); \
+\
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
+ { \
+ target->key = key; \
+ target->value = value; \
+ target->dist = pos - original_pos; \
+ target->state = CMC_ES_FILLED; \
+\
+ break; \
+ } \
+ else if (target->dist < pos - original_pos) \
+ { \
+ K tmp_k = target->key; \
+ V tmp_v = target->value; \
+ size_t tmp_dist = target->dist; \
+\
+ target->key = key; \
+ target->value = value; \
+ target->dist = pos - original_pos; \
+\
+ key = tmp_k; \
+ value = tmp_v; \
+ original_pos = pos - tmp_dist; \
+ } \
+ } \
+ } \
+\
+ _map_->count++; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ if (old_value) \
+ *old_value = entry->value; \
+\
+ entry->value = new_value; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, update); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (result == NULL) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ if (out_value) \
+ *out_value = result->value; \
+\
+ result->key = (K){ 0 }; \
+ result->value = (V){ 0 }; \
+ result->dist = 0; \
+ result->state = CMC_ES_DELETED; \
+\
+ _map_->count--; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ K max_key = (K) { 0 }; \
+ V max_val = (V) { 0 }; \
+ size_t first = 0; \
+\
+ for (; first < _map_->capacity; first++) \
+ { \
+ if (_map_->buffer[first].state == CMC_ES_FILLED) \
+ { \
+ max_key = _map_->buffer[first].key; \
+ max_val = _map_->buffer[first].value; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = first + 1; i < _map_->capacity; i++) \
+ { \
+ if (_map_->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0) \
+ { \
+ max_key = _map_->buffer[i].key; \
+ max_val = _map_->buffer[i].value; \
+ } \
+ } \
+ } \
+\
+ if (key) \
+ *key = max_key; \
+ if (value) \
+ *value = max_val; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ K min_key = (K) { 0 }; \
+ V min_val = (V) { 0 }; \
+ size_t first = 0; \
+\
+ for (; first < _map_->capacity; first++) \
+ { \
+ if (_map_->buffer[first].state == CMC_ES_FILLED) \
+ { \
+ min_key = _map_->buffer[first].key; \
+ min_val = _map_->buffer[first].value; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = first + 1; i < _map_->capacity; i++) \
+ { \
+ if (_map_->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0) \
+ { \
+ min_key = _map_->buffer[i].key; \
+ min_val = _map_->buffer[i].value; \
+ } \
+ } \
+ } \
+\
+ if (key) \
+ *key = min_key; \
+ if (value) \
+ *value = min_val; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _get)(struct SNAME * _map_, K key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return (V){ 0 }; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return entry->value; \
+ } \
+\
+ V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return NULL; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return &(entry->value); \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _map_) \
+ { \
+ return _map_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _map_) \
+ { \
return (double)_map_->capacity * _map_->load <= (double)_map_->count; \
- } \
- \
- size_t PFX##_count(struct SNAME *_map_) \
- { \
- return _map_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_map_) \
- { \
- return _map_->capacity; \
- } \
- \
- double PFX##_load(struct SNAME *_map_) \
- { \
- return _map_->load; \
- } \
- \
- int PFX##_flag(struct SNAME *_map_) \
- { \
- return _map_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_map_, size_t capacity) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->capacity == capacity) \
- goto success; \
- \
- if (_map_->capacity > capacity / _map_->load) \
- goto success; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * _map_->load) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Calculate required capacity based on the prime numbers */ \
- size_t theoretical_size = PFX##_impl_calculate_size(capacity); \
- \
- /* Not possible to shrink with current available prime numbers */ \
- if (theoretical_size < _map_->count / _map_->load) \
- { \
- _map_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- /* No callbacks since _new_map_ is just a temporary hashtable */ \
- struct SNAME *_new_map_ = \
- PFX##_new_custom(capacity, _map_->load, _map_->f_key, \
- _map_->f_val, _map_->alloc, NULL); \
- \
- if (!_new_map_) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- /* TODO turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K key = PFX##_iter_key(&iter); \
- V value = PFX##_iter_value(&iter); \
- \
- PFX##_insert(_new_map_, key, value); \
- } \
- \
- /* Unlikely */ \
- if (_map_->count != _new_map_->count) \
- { \
- PFX##_free(_new_map_); \
- \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- struct SNAME##_entry *tmp_b = _map_->buffer; \
- _map_->buffer = _new_map_->buffer; \
- _new_map_->buffer = tmp_b; \
- \
- size_t tmp_c = _map_->capacity; \
- _map_->capacity = _new_map_->capacity; \
- _new_map_->capacity = tmp_c; \
- \
- /* Prevent the map from freeing the data */ \
- _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
- _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
- \
- PFX##_free(_new_map_); \
- \
- success: \
- \
- if (_map_->callbacks && _map_->callbacks->resize) \
- _map_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_) \
- { \
- struct SNAME *result = PFX##_new_custom( \
- _map_->capacity * _map_->load, _map_->load, _map_->f_key, \
- _map_->f_val, _map_->alloc, _map_->callbacks); \
- \
- if (!result) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_map_->f_key->cpy || _map_->f_val->cpy) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = &(_map_->buffer[i]); \
- \
- if (scan->state != CMC_ES_EMPTY) \
- { \
- struct SNAME##_entry *target = &(result->buffer[i]); \
- \
- if (scan->state == CMC_ES_DELETED) \
- target->state = CMC_ES_DELETED; \
- else \
- { \
- target->state = scan->state; \
- target->dist = scan->dist; \
- \
- if (_map_->f_key->cpy) \
- target->key = _map_->f_key->cpy(scan->key); \
- else \
- target->key = scan->key; \
- \
- if (_map_->f_val->cpy) \
- target->value = _map_->f_val->cpy(scan->value); \
- else \
- target->value = scan->value; \
- } \
- } \
- } \
- } \
- else \
- memcpy(result->buffer, _map_->buffer, \
- sizeof(struct SNAME##_entry) * _map_->capacity); \
- \
- result->count = _map_->count; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \
- { \
- _map1_->flag = cmc_flags.OK; \
- _map2_->flag = cmc_flags.OK; \
- \
- if (_map1_->count != _map2_->count) \
- return false; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map1_); \
- \
- /* TODO optimize this loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- struct SNAME##_entry *entry = \
- PFX##_impl_get_entry(_map2_, PFX##_iter_key(&iter)); \
- \
- if (entry == NULL) \
- return false; \
- \
- if (_map1_->f_val->cmp(entry->value, PFX##_iter_value(&iter)) != \
- 0) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_map_) \
- { \
- struct cmc_string str; \
- struct SNAME *m_ = _map_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmap, \
- #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \
- m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \
- m_->alloc, m_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_map_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- if (!_map_->f_key->str(fptr, entry->key) || \
- !_map_->f_val->str(fptr, entry->value)) \
- return false; \
- } \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i].state == CMC_ES_FILLED) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.first; \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1].state == CMC_ES_FILLED) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- } \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i].state == CMC_ES_FILLED) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1].state == CMC_ES_FILLED) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.last; \
- iter.index = target->count - 1; \
- } \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->first; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->last; \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
- \
- iter->index++; \
- \
- while (1) \
- { \
- iter->cursor++; \
- scan = &(iter->target->buffer[iter->cursor]); \
- \
- if (scan->state == CMC_ES_FILLED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
- \
- iter->index--; \
- \
- while (1) \
- { \
- iter->cursor--; \
- scan = &(iter->target->buffer[iter->cursor]); \
- \
- if (scan->state == CMC_ES_FILLED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- K PFX##_iter_key(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (K){ 0 }; \
- \
- return iter->target->buffer[iter->cursor].key; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor].value; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor].value); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, \
- K key) \
- { \
- size_t hash = _map_->f_key->hash(key); \
- size_t pos = hash % _map_->capacity; \
- \
- struct SNAME##_entry *target = &(_map_->buffer[pos]); \
- \
- while (target->state == CMC_ES_FILLED || \
- target->state == CMC_ES_DELETED) \
- { \
- if (_map_->f_key->cmp(target->key, key) == 0) \
- return target; \
- \
- pos++; \
- target = &(_map_->buffer[pos % _map_->capacity]); \
- } \
- \
- return NULL; \
- } \
- \
- static size_t PFX##_impl_calculate_size(size_t required) \
- { \
- const size_t count = \
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
- \
- if (cmc_hashtable_primes[count - 1] < required) \
- return required; \
- \
- size_t i = 0; \
- while (cmc_hashtable_primes[i] < required) \
- i++; \
- \
- return cmc_hashtable_primes[i]; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _map_) \
+ { \
+ return _map_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \
+ { \
+ return _map_->capacity; \
+ } \
+\
+ double CMC_(PFX, _load)(struct SNAME * _map_) \
+ { \
+ return _map_->load; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _map_) \
+ { \
+ return _map_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ if (_map_->capacity == capacity) \
+ goto success; \
+\
+ if (_map_->capacity > capacity / _map_->load) \
+ goto success; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * _map_->load) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Calculate required capacity based on the prime numbers */ \
+ size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \
+\
+ /* Not possible to shrink with current available prime numbers */ \
+ if (theoretical_size < _map_->count / _map_->load) \
+ { \
+ _map_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ /* No callbacks since _new_map_ is just a temporary hashtable */ \
+ struct SNAME *_new_map_ = \
+ CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!_new_map_) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ if (_map_->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ K key = _map_->buffer[i].key; \
+ V value = _map_->buffer[i].value; \
+\
+ /* TODO check this for possible errors */ \
+ CMC_(PFX, _insert)(_new_map_, key, value); \
+ } \
+ } \
+\
+ /* Unlikely */ \
+ if (_map_->count != _new_map_->count) \
+ { \
+ CMC_(PFX, _free)(_new_map_); \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *tmp_b = _map_->buffer; \
+ _map_->buffer = _new_map_->buffer; \
+ _new_map_->buffer = tmp_b; \
+\
+ size_t tmp_c = _map_->capacity; \
+ _map_->capacity = _new_map_->capacity; \
+ _new_map_->capacity = tmp_c; \
+\
+ /* Prevent the map from freeing the data */ \
+ _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \
+ _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \
+\
+ CMC_(PFX, _free)(_new_map_); \
+\
+ success: \
+\
+ CMC_CALLBACKS_CALL(_map_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \
+ _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \
+\
+ if (_map_->f_key->cpy || _map_->f_val->cpy) \
+ { \
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(_map_->buffer[i]); \
+\
+ if (scan->state != CMC_ES_EMPTY) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \
+\
+ if (scan->state == CMC_ES_DELETED) \
+ target->state = CMC_ES_DELETED; \
+ else \
+ { \
+ target->state = scan->state; \
+ target->dist = scan->dist; \
+\
+ if (_map_->f_key->cpy) \
+ target->key = _map_->f_key->cpy(scan->key); \
+ else \
+ target->key = scan->key; \
+\
+ if (_map_->f_val->cpy) \
+ target->value = _map_->f_val->cpy(scan->value); \
+ else \
+ target->value = scan->value; \
+ } \
+ } \
+ } \
+ } \
+ else \
+ memcpy(result->buffer, _map_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _map_->capacity); \
+\
+ result->count = _map_->count; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \
+ { \
+ _map1_->flag = CMC_FLAG_OK; \
+ _map2_->flag = CMC_FLAG_OK; \
+\
+ if (_map1_->count != _map2_->count) \
+ return false; \
+\
+ /* Optimize loop using the smallest hashtable */ \
+ struct SNAME *_map_a_; \
+ struct SNAME *_map_b_; \
+\
+ _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_; \
+ _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_; \
+\
+ for (size_t i = 0; i < _map_a_->capacity; i++) \
+ { \
+ if (_map_a_->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry_a = &(_map_a_->buffer[i]); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry_b = CMC_(PFX, _impl_get_entry)(_map_b_, entry_a->key); \
+\
+ if (!entry_b) \
+ return false; \
+\
+ if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0) \
+ return false; \
+ } \
+ } \
+\
+ return true; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \
+ { \
+ size_t hash = _map_->f_key->hash(key); \
+ size_t pos = hash % _map_->capacity; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = &(_map_->buffer[pos]); \
+\
+ while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \
+ { \
+ if (_map_->f_key->cmp(target->key, key) == 0) \
+ return target; \
+\
+ pos++; \
+ target = &(_map_->buffer[pos % _map_->capacity]); \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \
+ { \
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
+\
+ if (cmc_hashtable_primes[count - 1] < required) \
+ return required; \
+\
+ size_t i = 0; \
+ while (cmc_hashtable_primes[i] < required) \
+ i++; \
+\
+ return cmc_hashtable_primes[i]; \
}
-#endif /* CMC_HASHMAP_H */
+#endif /* CMC_CMC_HASHMAP_H */
diff --git a/src/cmc/hashmultimap.h b/src/cmc/hashmultimap.h
index be8c95e..053f55f 100644
--- a/src/cmc/hashmultimap.h
+++ b/src/cmc/hashmultimap.h
@@ -1,5 +1,5 @@
/**
- * hashmultimap.h
+ * cmc/hashmultimap.h
*
* Creation Date: 26/04/2019
*
@@ -41,8 +41,8 @@
* the first key added will be the first to be removed.
*/
-#ifndef CMC_HASHMULTIMAP_H
-#define CMC_HASHMULTIMAP_H
+#ifndef CMC_CMC_HASHMULTIMAP_H
+#define CMC_CMC_HASHMULTIMAP_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -54,1417 +54,1012 @@
* ------------------------------------------------------------------------- */
#include "../cor/hashtable.h"
+/**
+ * Core HashMultiMap implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_HASHMULTIMAP_CORE(ACCESS, FILE, PARAMS) \
+ CMC_(CMC_(CMC_CMC_HASHMULTIMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_HASHMULTIMAP_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHMULTIMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_HASHMULTIMAP_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \
+ CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHMULTIMAP_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_HASHMULTIMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHMULTIMAP_CORE_HEADER(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE(PARAMS) \
+ CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * HashMultiMap specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_hashmultimap = "struct %s<%s, %s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "load:%lf, "
- "flag:%d, "
- "f_key:%p, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_HASHMULTIMAP(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMULTIMAP_HEADER(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V)
+#define CMC_CMC_HASHMULTIMAP_CORE_STRUCT_(PFX, SNAME, K, V) \
+\
+ /* HashMultimap Structure */ \
+ struct SNAME \
+ { \
+ /* Array of linked list to entries */ \
+ struct CMC_DEF_ENTRY(SNAME) * (*buffer)[2]; \
+\
+ /* Current array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of keys */ \
+ size_t count; \
+\
+ /* Load factor in range (0.0, infinity) */ \
+ double load; \
+\
+ /* Flags indicating errors or success */ \
+ int flag; \
+\
+ /* Key function table */ \
+ struct CMC_DEF_FKEY(SNAME) * f_key; \
+\
+ /* 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; \
+ }; \
+\
+ /* HashMultimap Entry */ \
+ struct CMC_DEF_ENTRY(SNAME) \
+ { \
+ /* Entry Key */ \
+ K key; \
+\
+ /* Entry Value */ \
+ V value; \
+\
+ /* Next entry on the linked list */ \
+ struct CMC_DEF_ENTRY(SNAME) * next; \
+\
+ /* Previous entry on the linked list */ \
+ struct CMC_DEF_ENTRY(SNAME) * prev; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHMULTIMAP_HEADER(PFX, SNAME, K, V) \
- \
- /* HashMultimap Structure */ \
- struct SNAME \
- { \
- /* Array of linked list to entries */ \
- struct SNAME##_entry *(*buffer)[2]; \
- \
- /* Current array capacity */ \
- size_t capacity; \
- \
- /* Current amount of keys */ \
- size_t count; \
- \
- /* Load factor in range (0.0, infinity) */ \
- double load; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Key function table */ \
- struct SNAME##_fkey *f_key; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* HashMultimap Entry */ \
- struct SNAME##_entry \
- { \
- /* Entry Key */ \
- K key; \
- \
- /* Entry Value */ \
- V value; \
- \
- /* Next entry on the linked list */ \
- struct SNAME##_entry *next; \
- \
- /* Previous entry on the linked list */ \
- struct SNAME##_entry *prev; \
- }; \
- \
- /* Key struct function table */ \
- struct SNAME##_fkey \
- { \
- /* Comparator function */ \
- int (*cmp)(K, K); \
- \
- /* Copy function */ \
- K (*cpy)(K); \
- \
- /* To string function */ \
- bool (*str)(FILE *, K); \
- \
- /* Free from memory function */ \
- void (*free)(K); \
- \
- /* Hash function */ \
- size_t (*hash)(K); \
- \
- /* Priority function */ \
- int (*pri)(K, K); \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- struct SNAME##_iter \
- { \
- /* Target hashmultimap */ \
- struct SNAME *target; \
- \
- /* Current entry */ \
- struct SNAME##_entry *curr_entry; \
- \
- /* Cursor`s position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* The index of the first element */ \
- size_t first; \
- \
- /* The index of the last element */ \
- size_t last; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_map_); \
- void PFX##_free(struct SNAME *_map_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_map_, K key, V value); \
- bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value); \
- size_t PFX##_update_all(struct SNAME *_map_, K key, V new_value, \
- V **old_values); \
- bool PFX##_remove(struct SNAME *_map_, K key, V *out_value); \
- size_t PFX##_remove_all(struct SNAME *_map_, K key, V **out_values); \
- /* Element Access */ \
- bool PFX##_max(struct SNAME *_map_, K *key, V *value); \
- bool PFX##_min(struct SNAME *_map_, K *key, V *value); \
- V PFX##_get(struct SNAME *_map_, K key); \
- V *PFX##_get_ref(struct SNAME *_map_, K key); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_map_, K key); \
- bool PFX##_empty(struct SNAME *_map_); \
- bool PFX##_full(struct SNAME *_map_); \
- size_t PFX##_count(struct SNAME *_map_); \
- size_t PFX##_key_count(struct SNAME *_map_, K key); \
- size_t PFX##_capacity(struct SNAME *_map_); \
- double PFX##_load(struct SNAME *_map_); \
- int PFX##_flag(struct SNAME *_map_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_map_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_); \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_map_); \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- K PFX##_iter_key(struct SNAME##_iter *iter); \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_HASHMULTIMAP_CORE_HEADER_(PFX, SNAME, K, V) \
+\
+ /* Key struct function table */ \
+ struct CMC_DEF_FKEY(SNAME) \
+ { \
+ /* Comparator function */ \
+ CMC_DEF_FTAB_CMP(K); \
+\
+ /* Copy function */ \
+ CMC_DEF_FTAB_CPY(K); \
+\
+ /* To string function */ \
+ CMC_DEF_FTAB_STR(K); \
+\
+ /* Free from memory function */ \
+ CMC_DEF_FTAB_FREE(K); \
+\
+ /* Hash function */ \
+ CMC_DEF_FTAB_HASH(K); \
+\
+ /* Priority function */ \
+ CMC_DEF_FTAB_PRI(K); \
+ }; \
+\
+ /* 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, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _map_); \
+ void CMC_(PFX, _free)(struct SNAME * _map_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \
+ bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \
+ size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, V * *old_values); \
+ bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \
+ size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, V * *out_values); \
+ /* Element Access */ \
+ bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \
+ bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \
+ V CMC_(PFX, _get)(struct SNAME * _map_, K key); \
+ V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \
+ bool CMC_(PFX, _empty)(struct SNAME * _map_); \
+ bool CMC_(PFX, _full)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _map_); \
+ double CMC_(PFX, _load)(struct SNAME * _map_); \
+ int CMC_(PFX, _flag)(struct SNAME * _map_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHMULTIMAP_SOURCE(PFX, SNAME, K, V) \
- \
- /* Implementation Detail Functions */ \
- struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, K key, \
- V value); \
- struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, K key); \
- size_t PFX##_impl_key_count(struct SNAME *_map_, K key); \
- size_t PFX##_impl_calculate_size(size_t required); \
- \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity == 0 || load <= 0) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_key || !f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \
- \
- if (!_map_->buffer) \
- { \
- alloc->free(_map_); \
- return NULL; \
- } \
- \
- _map_->count = 0; \
- _map_->capacity = real_capacity; \
- _map_->load = load; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->alloc = alloc; \
- _map_->callbacks = NULL; \
- \
- return _map_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (capacity == 0 || load <= 0) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_key || !f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry *[2])); \
- \
- if (!_map_->buffer) \
- { \
- alloc->free(_map_); \
- return NULL; \
- } \
- \
- _map_->count = 0; \
- _map_->capacity = real_capacity; \
- _map_->load = load; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->alloc = alloc; \
- _map_->callbacks = callbacks; \
- \
- return _map_; \
- } \
- \
- void PFX##_clear(struct SNAME *_map_) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = _map_->buffer[i][0]; \
- \
- while (scan != NULL) \
- { \
- struct SNAME##_entry *next = scan->next; \
- \
- if (_map_->f_key->free) \
- _map_->f_key->free(scan->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(scan->value); \
- \
- _map_->alloc->free(scan); \
- \
- scan = next; \
- } \
- } \
- \
- memset(_map_->buffer, 0, \
- sizeof(struct SNAME##_entry *[2]) * _map_->capacity); \
- \
- _map_->count = 0; \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_map_) \
- { \
- size_t index = 0; \
- \
- while (index < _map_->capacity) \
- { \
- struct SNAME##_entry *scan = _map_->buffer[index][0]; \
- \
- if (scan != NULL) \
- { \
- if (scan->next == NULL && scan->prev == NULL) \
- { \
- if (_map_->f_key->free) \
- _map_->f_key->free(scan->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(scan->value); \
- \
- _map_->alloc->free(scan); \
- } \
- else \
- { \
- while (scan != NULL) \
- { \
- struct SNAME##_entry *tmp = scan; \
- \
- scan = scan->next; \
- \
- if (_map_->f_key->free) \
- _map_->f_key->free(tmp->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(tmp->value); \
- \
- _map_->alloc->free(tmp); \
- } \
- } \
- } \
- \
- index++; \
- } \
- \
- _map_->alloc->free(_map_->buffer); \
- _map_->alloc->free(_map_); \
- } \
- \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _map_->alloc = &cmc_alloc_node_default; \
- else \
- _map_->alloc = alloc; \
- \
- _map_->callbacks = callbacks; \
- \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_map_, K key, V value) \
- { \
- if (PFX##_full(_map_)) \
- { \
- if (!PFX##_resize(_map_, _map_->capacity + 1)) \
- return false; \
- } \
- \
- size_t hash = _map_->f_key->hash(key); \
- size_t pos = hash % _map_->capacity; \
- \
- struct SNAME##_entry *entry = PFX##_impl_new_entry(_map_, key, value); \
- \
- if (_map_->buffer[pos][0] == NULL) \
- { \
- _map_->buffer[pos][0] = entry; \
- _map_->buffer[pos][1] = entry; \
- } \
- else \
- { \
- entry->prev = _map_->buffer[pos][1]; \
- \
- _map_->buffer[pos][1]->next = entry; \
- _map_->buffer[pos][1] = entry; \
- } \
- \
- _map_->count++; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->create) \
- _map_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- if (old_value) \
- *old_value = entry->value; \
- \
- entry->value = new_value; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->update) \
- _map_->callbacks->update(); \
- \
- return true; \
- } \
- \
- size_t PFX##_update_all(struct SNAME *_map_, K key, V new_value, \
- V **old_values) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return 0; \
- } \
- \
- size_t hash = _map_->f_key->hash(key); \
- \
- struct SNAME##_entry *entry = \
- _map_->buffer[hash % _map_->capacity][0]; \
- \
- if (entry == NULL) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return 0; \
- } \
- \
- if (old_values) \
- { \
- size_t total = PFX##_impl_key_count(_map_, key); \
- \
- if (total == 0) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return 0; \
- } \
- \
- *old_values = _map_->alloc->malloc(sizeof(V) * total); \
- \
- if (!(*old_values)) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return 0; \
- } \
- } \
- \
- size_t index = 0; \
- \
- while (entry != NULL) \
- { \
- if (_map_->f_key->cmp(entry->key, key) == 0) \
- { \
- if (old_values) \
- (*old_values)[index] = entry->value; \
- \
- index++; \
- entry->value = new_value; \
- } \
- \
- entry = entry->next; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->update) \
- _map_->callbacks->update(); \
- \
- return index; \
- } \
- \
- bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- size_t hash = _map_->f_key->hash(key); \
- \
- struct SNAME##_entry **head = \
- &(_map_->buffer[hash % _map_->capacity][0]); \
- struct SNAME##_entry **tail = \
- &(_map_->buffer[hash % _map_->capacity][1]); \
- \
- if (*head == NULL) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = *head; \
- \
- if (entry->next == NULL && entry->prev == NULL) \
- { \
- if (_map_->f_key->cmp(entry->key, key) == 0) \
- { \
- *head = NULL; \
- *tail = NULL; \
- \
- if (out_value) \
- *out_value = entry->value; \
- } \
- else \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- } \
- else \
- { \
- bool found = false; \
- \
- while (entry != NULL) \
- { \
- if (_map_->f_key->cmp(entry->key, key) == 0) \
- { \
- if (*head == entry) \
- *head = entry->next; \
- if (*tail == entry) \
- *tail = entry->prev; \
- \
- if (entry->prev != NULL) \
- entry->prev->next = entry->next; \
- if (entry->next != NULL) \
- entry->next->prev = entry->prev; \
- \
- if (out_value) \
- *out_value = entry->value; \
- \
- found = true; \
- \
- break; \
- } \
- else \
- entry = entry->next; \
- } \
- \
- if (!found) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- } \
- \
- _map_->alloc->free(entry); \
- \
- _map_->count--; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->delete) \
- _map_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- size_t PFX##_remove_all(struct SNAME *_map_, K key, V **out_values) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- size_t hash = _map_->f_key->hash(key); \
- \
- struct SNAME##_entry **head = \
- &(_map_->buffer[hash % _map_->capacity][0]); \
- struct SNAME##_entry **tail = \
- &(_map_->buffer[hash % _map_->capacity][1]); \
- \
- if (*head == NULL) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return 0; \
- } \
- \
- if (out_values) \
- { \
- size_t total = PFX##_impl_key_count(_map_, key); \
- \
- if (total == 0) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return 0; \
- } \
- \
- *out_values = _map_->alloc->malloc(sizeof(V) * total); \
- \
- if (!(*out_values)) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return 0; \
- } \
- } \
- \
- size_t index = 0; \
- struct SNAME##_entry *entry = *head; \
- \
- if (entry->next == NULL) \
- { \
- *head = NULL; \
- *tail = NULL; \
- \
- if (out_values) \
- (*out_values)[index] = entry->value; \
- \
- index++; \
- _map_->alloc->free(entry); \
- } \
- else \
- { \
- while (entry != NULL) \
- { \
- if (_map_->f_key->cmp(entry->key, key) == 0) \
- { \
- if (*head == entry) \
- *head = entry->next; \
- if (*tail == entry) \
- *tail = entry->prev; \
- \
- struct SNAME##_entry *next = entry->next; \
- \
- if (entry->prev != NULL) \
- entry->prev->next = entry->next; \
- if (entry->next != NULL) \
- entry->next->prev = entry->prev; \
- \
- if (out_values) \
- (*out_values)[index] = entry->value; \
- \
- index++; \
- _map_->alloc->free(entry); \
- \
- entry = next; \
- } \
- else \
- entry = entry->next; \
- } \
- } \
- \
- _map_->count -= index; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->delete) \
- _map_->callbacks->delete (); \
- \
- return index; \
- } \
- \
- bool PFX##_max(struct SNAME *_map_, K *key, V *value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- K max_key; \
- V max_val; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K result_key = PFX##_iter_key(&iter); \
- V result_value = PFX##_iter_value(&iter); \
- size_t index = PFX##_iter_index(&iter); \
- \
- if (index == 0) \
- { \
- max_key = result_key; \
- max_val = result_value; \
- } \
- else if (_map_->f_key->cmp(result_key, max_key) > 0) \
- { \
- max_key = result_key; \
- max_val = result_value; \
- } \
- } \
- \
- if (key) \
- *key = max_key; \
- if (value) \
- *value = max_val; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_min(struct SNAME *_map_, K *key, V *value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- K min_key; \
- V min_val; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K result_key = PFX##_iter_key(&iter); \
- V result_value = PFX##_iter_value(&iter); \
- size_t index = PFX##_iter_index(&iter); \
- \
- if (index == 0) \
- { \
- min_key = result_key; \
- min_val = result_value; \
- } \
- else if (_map_->f_key->cmp(result_key, min_key) < 0) \
- { \
- min_key = result_key; \
- min_val = result_value; \
- } \
- } \
- \
- if (key) \
- *key = min_key; \
- if (value) \
- *value = min_val; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return true; \
- } \
- \
- V PFX##_get(struct SNAME *_map_, K key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return (V){ 0 }; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return entry->value; \
- } \
- \
- V *PFX##_get_ref(struct SNAME *_map_, K key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_map_, key); \
- \
- if (!entry) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return NULL; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return &(entry->value); \
- } \
- \
- bool PFX##_contains(struct SNAME *_map_, K key) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- bool result = PFX##_impl_get_entry(_map_, key) != NULL; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_map_) \
- { \
- return _map_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_map_) \
- { \
- return (double)_map_->capacity * _map_->load <= (double)_map_->count; \
- } \
- \
- size_t PFX##_count(struct SNAME *_map_) \
- { \
- return _map_->count; \
- } \
- \
- size_t PFX##_key_count(struct SNAME *_map_, K key) \
- { \
- return PFX##_impl_key_count(_map_, key); \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_map_) \
- { \
- return _map_->capacity; \
- } \
- \
- double PFX##_load(struct SNAME *_map_) \
- { \
- return _map_->load; \
- } \
- \
- int PFX##_flag(struct SNAME *_map_) \
- { \
- return _map_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_map_, size_t capacity) \
- { \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->capacity == capacity) \
- goto success; \
- \
- if (_map_->capacity > capacity / _map_->load) \
- goto success; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * _map_->load) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Calculate required capacity based on the prime numbers */ \
- size_t theoretical_size = PFX##_impl_calculate_size(capacity); \
- \
- /* Not possible to shrink with current available prime numbers */ \
- if (theoretical_size < _map_->count / _map_->load) \
- { \
- _map_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- /* No callbacks since _new_map_ is just a temporary hashtable */ \
- struct SNAME *_new_map_ = \
- PFX##_new_custom(capacity, _map_->load, _map_->f_key, \
- _map_->f_val, _map_->alloc, NULL); \
- \
- if (!_new_map_) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K key = PFX##_iter_key(&iter); \
- V value = PFX##_iter_value(&iter); \
- \
- /* TODO check for errors */ \
- PFX##_insert(_new_map_, key, value); \
- } \
- \
- if (_map_->count != _new_map_->count) \
- { \
- PFX##_free(_new_map_); \
- \
- _map_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- struct SNAME##_entry *(*tmp_b)[2] = _map_->buffer; \
- _map_->buffer = _new_map_->buffer; \
- _new_map_->buffer = tmp_b; \
- \
- size_t tmp_c = _map_->capacity; \
- _map_->capacity = _new_map_->capacity; \
- _new_map_->capacity = tmp_c; \
- \
- /* Prevent the map from freeing the data */ \
- _new_map_->f_key = &(struct SNAME##_fkey){ NULL }; \
- _new_map_->f_val = &(struct SNAME##_fval){ NULL }; \
- \
- PFX##_free(_new_map_); \
- \
- success: \
- \
- if (_map_->callbacks && _map_->callbacks->resize) \
- _map_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_) \
- { \
- /* Callback will be added later */ \
- struct SNAME *result = \
- PFX##_new_custom(_map_->capacity * _map_->load, _map_->load, \
- _map_->f_key, _map_->f_val, _map_->alloc, NULL); \
- \
- if (!result) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- if (!PFX##_empty(_map_)) \
- { \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K key = PFX##_iter_key(&iter); \
- V value = PFX##_iter_value(&iter); \
- \
- if (_map_->f_key->cpy) \
- key = _map_->f_key->cpy(key); \
- if (_map_->f_val->cpy) \
- value = _map_->f_val->cpy(value); \
- \
- /* TODO check for errors */ \
- PFX##_insert(result, key, value); \
- } \
- } \
- \
- result->callbacks = _map_->callbacks; \
- _map_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \
- { \
- _map1_->flag = cmc_flags.OK; \
- _map2_->flag = cmc_flags.OK; \
- \
- if (_map1_->count != _map2_->count) \
- return false; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_map1_); \
- \
- /* TODO Turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K key = PFX##_iter_key(&iter); \
- \
- if (PFX##_impl_key_count(_map1_, key) != \
- PFX##_impl_key_count(_map2_, key)) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_map_) \
- { \
- struct cmc_string str; \
- struct SNAME *m_ = _map_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultimap, \
- #SNAME, #K, #V, m_, m_->buffer, m_->capacity, \
- m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, \
- m_->alloc, m_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _map_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = _map_->buffer[i][0]; \
- \
- while (scan != NULL) \
- { \
- if (!_map_->f_key->str(fptr, scan->key) || \
- !_map_->f_val->str(fptr, scan->value)) \
- return false; \
- \
- scan = scan->next; \
- } \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.curr_entry = NULL; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i][0] != NULL) \
- { \
- iter.curr_entry = target->buffer[i][0]; \
- iter.first = i; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.first; \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1][1] != NULL) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- } \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.curr_entry = NULL; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i][0] != NULL) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1][1] != NULL) \
- { \
- iter.curr_entry = target->buffer[i - 1][1]; \
- iter.last = i - 1; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.last; \
- iter.index = target->count - 1; \
- } \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->first; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- iter->curr_entry = iter->target->buffer[iter->first][0]; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->last; \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- iter->curr_entry = iter->target->buffer[iter->last][1]; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->curr_entry->next != NULL) \
- { \
- iter->curr_entry = iter->curr_entry->next; \
- iter->index++; \
- } \
- else \
- { \
- if (iter->cursor == iter->last) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->cursor++; \
- \
- while (iter->target->buffer[iter->cursor][0] == NULL) \
- iter->cursor++; \
- \
- iter->curr_entry = iter->target->buffer[iter->cursor][0]; \
- \
- iter->index++; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->curr_entry->prev != NULL) \
- { \
- iter->curr_entry = iter->curr_entry->prev; \
- iter->index--; \
- } \
- else \
- { \
- if (iter->cursor == iter->first) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->cursor--; \
- \
- while (iter->target->buffer[iter->cursor][1] == NULL) \
- iter->cursor--; \
- \
- iter->curr_entry = iter->target->buffer[iter->cursor][1]; \
- \
- iter->index--; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- K PFX##_iter_key(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (K){ 0 }; \
- \
- return iter->curr_entry->key; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->curr_entry->value; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->curr_entry->value); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- struct SNAME##_entry *PFX##_impl_new_entry(struct SNAME *_map_, K key, \
- V value) \
- { \
- struct SNAME##_entry *entry = \
- _map_->alloc->malloc(sizeof(struct SNAME##_entry)); \
- \
- if (!entry) \
- return NULL; \
- \
- entry->key = key; \
- entry->value = value; \
- entry->next = NULL; \
- entry->prev = NULL; \
- \
- return entry; \
- } \
- \
- struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_map_, K key) \
- { \
- size_t hash = _map_->f_key->hash(key); \
- \
- struct SNAME##_entry *entry = \
- _map_->buffer[hash % _map_->capacity][0]; \
- \
- while (entry != NULL) \
- { \
- if (_map_->f_key->cmp(entry->key, key) == 0) \
- return entry; \
- \
- entry = entry->next; \
- } \
- \
- return NULL; \
- } \
- \
- size_t PFX##_impl_key_count(struct SNAME *_map_, K key) \
- { \
- size_t hash = _map_->f_key->hash(key); \
- \
- struct SNAME##_entry *entry = \
- _map_->buffer[hash % _map_->capacity][0]; \
- \
- size_t total_count = 0; \
- \
- if (!entry) \
- return total_count; \
- \
- while (entry != NULL) \
- { \
- if (_map_->f_key->cmp(entry->key, key) == 0) \
- total_count++; \
- \
- entry = entry->next; \
- } \
- \
- return total_count; \
- } \
- \
- size_t PFX##_impl_calculate_size(size_t required) \
- { \
- const size_t count = \
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
- \
- if (cmc_hashtable_primes[count - 1] < required) \
- return required; \
- \
- size_t i = 0; \
- while (cmc_hashtable_primes[i] < required) \
- i++; \
- \
- return cmc_hashtable_primes[i]; \
+#define CMC_CMC_HASHMULTIMAP_CORE_SOURCE_(PFX, SNAME, K, V) \
+\
+ /* Implementation Detail Functions */ \
+ struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value); \
+ struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key); \
+ size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key); \
+ size_t CMC_(PFX, _impl_calculate_size)(size_t required); \
+\
+ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(capacity, load, f_key, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ 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 || load <= 0) \
+ return NULL; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * load) \
+ return NULL; \
+\
+ if (!f_key || !f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
+\
+ struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_map_) \
+ return NULL; \
+\
+ _map_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2])); \
+\
+ if (!_map_->buffer) \
+ { \
+ alloc->free(_map_); \
+ return NULL; \
+ } \
+\
+ _map_->count = 0; \
+ _map_->capacity = real_capacity; \
+ _map_->load = load; \
+ _map_->flag = CMC_FLAG_OK; \
+ _map_->f_key = f_key; \
+ _map_->f_val = f_val; \
+ _map_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ return _map_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _map_) \
+ { \
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \
+\
+ while (scan != NULL) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *next = scan->next; \
+\
+ if (_map_->f_key->free) \
+ _map_->f_key->free(scan->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(scan->value); \
+\
+ _map_->alloc->free(scan); \
+\
+ scan = next; \
+ } \
+ } \
+\
+ memset(_map_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME) *[2]) * _map_->capacity); \
+\
+ _map_->count = 0; \
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _map_) \
+ { \
+ size_t index = 0; \
+\
+ while (index < _map_->capacity) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[index][0]; \
+\
+ if (scan != NULL) \
+ { \
+ if (scan->next == NULL && scan->prev == NULL) \
+ { \
+ if (_map_->f_key->free) \
+ _map_->f_key->free(scan->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(scan->value); \
+\
+ _map_->alloc->free(scan); \
+ } \
+ else \
+ { \
+ while (scan != NULL) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *tmp = scan; \
+\
+ scan = scan->next; \
+\
+ if (_map_->f_key->free) \
+ _map_->f_key->free(tmp->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(tmp->value); \
+\
+ _map_->alloc->free(tmp); \
+ } \
+ } \
+ } \
+\
+ index++; \
+ } \
+\
+ _map_->alloc->free(_map_->buffer); \
+ _map_->alloc->free(_map_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _map_->alloc = &cmc_alloc_node_default; \
+ else \
+ _map_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \
+ { \
+ if (CMC_(PFX, _full)(_map_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_map_, _map_->capacity + 1)) \
+ return false; \
+ } \
+\
+ size_t hash = _map_->f_key->hash(key); \
+ size_t pos = hash % _map_->capacity; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_new_entry)(_map_, key, value); \
+\
+ if (_map_->buffer[pos][0] == NULL) \
+ { \
+ _map_->buffer[pos][0] = entry; \
+ _map_->buffer[pos][1] = entry; \
+ } \
+ else \
+ { \
+ entry->prev = _map_->buffer[pos][1]; \
+\
+ _map_->buffer[pos][1]->next = entry; \
+ _map_->buffer[pos][1] = entry; \
+ } \
+\
+ _map_->count++; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ if (old_value) \
+ *old_value = entry->value; \
+\
+ entry->value = new_value; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, update); \
+\
+ return true; \
+ } \
+\
+ size_t CMC_(PFX, _update_all)(struct SNAME * _map_, K key, V new_value, V * *old_values) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return 0; \
+ } \
+\
+ size_t hash = _map_->f_key->hash(key); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \
+\
+ if (entry == NULL) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return 0; \
+ } \
+\
+ if (old_values) \
+ { \
+ size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \
+\
+ if (total == 0) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return 0; \
+ } \
+\
+ *old_values = _map_->alloc->malloc(sizeof(V) * total); \
+\
+ if (!(*old_values)) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return 0; \
+ } \
+ } \
+\
+ size_t index = 0; \
+\
+ while (entry != NULL) \
+ { \
+ if (_map_->f_key->cmp(entry->key, key) == 0) \
+ { \
+ if (old_values) \
+ (*old_values)[index] = entry->value; \
+\
+ index++; \
+ entry->value = new_value; \
+ } \
+\
+ entry = entry->next; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, update); \
+\
+ return index; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ size_t hash = _map_->f_key->hash(key); \
+\
+ struct CMC_DEF_ENTRY(SNAME) **head = &(_map_->buffer[hash % _map_->capacity][0]); \
+ struct CMC_DEF_ENTRY(SNAME) **tail = &(_map_->buffer[hash % _map_->capacity][1]); \
+\
+ if (*head == NULL) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = *head; \
+\
+ if (entry->next == NULL && entry->prev == NULL) \
+ { \
+ if (_map_->f_key->cmp(entry->key, key) == 0) \
+ { \
+ *head = NULL; \
+ *tail = NULL; \
+\
+ if (out_value) \
+ *out_value = entry->value; \
+ } \
+ else \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+ } \
+ else \
+ { \
+ bool found = false; \
+\
+ while (entry != NULL) \
+ { \
+ if (_map_->f_key->cmp(entry->key, key) == 0) \
+ { \
+ if (*head == entry) \
+ *head = entry->next; \
+ if (*tail == entry) \
+ *tail = entry->prev; \
+\
+ if (entry->prev != NULL) \
+ entry->prev->next = entry->next; \
+ if (entry->next != NULL) \
+ entry->next->prev = entry->prev; \
+\
+ if (out_value) \
+ *out_value = entry->value; \
+\
+ found = true; \
+\
+ break; \
+ } \
+ else \
+ entry = entry->next; \
+ } \
+\
+ if (!found) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+ } \
+\
+ _map_->alloc->free(entry); \
+\
+ _map_->count--; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, delete); \
+\
+ return true; \
+ } \
+\
+ size_t CMC_(PFX, _remove_all)(struct SNAME * _map_, K key, V * *out_values) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ size_t hash = _map_->f_key->hash(key); \
+\
+ struct CMC_DEF_ENTRY(SNAME) **head = &(_map_->buffer[hash % _map_->capacity][0]); \
+ struct CMC_DEF_ENTRY(SNAME) **tail = &(_map_->buffer[hash % _map_->capacity][1]); \
+\
+ if (*head == NULL) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return 0; \
+ } \
+\
+ if (out_values) \
+ { \
+ size_t total = CMC_(PFX, _impl_key_count)(_map_, key); \
+\
+ if (total == 0) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return 0; \
+ } \
+\
+ *out_values = _map_->alloc->malloc(sizeof(V) * total); \
+\
+ if (!(*out_values)) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return 0; \
+ } \
+ } \
+\
+ size_t index = 0; \
+ struct CMC_DEF_ENTRY(SNAME) *entry = *head; \
+\
+ if (entry->next == NULL) \
+ { \
+ *head = NULL; \
+ *tail = NULL; \
+\
+ if (out_values) \
+ (*out_values)[index] = entry->value; \
+\
+ index++; \
+ _map_->alloc->free(entry); \
+ } \
+ else \
+ { \
+ while (entry != NULL) \
+ { \
+ if (_map_->f_key->cmp(entry->key, key) == 0) \
+ { \
+ if (*head == entry) \
+ *head = entry->next; \
+ if (*tail == entry) \
+ *tail = entry->prev; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *next = entry->next; \
+\
+ if (entry->prev != NULL) \
+ entry->prev->next = entry->next; \
+ if (entry->next != NULL) \
+ entry->next->prev = entry->prev; \
+\
+ if (out_values) \
+ (*out_values)[index] = entry->value; \
+\
+ index++; \
+ _map_->alloc->free(entry); \
+\
+ entry = next; \
+ } \
+ else \
+ entry = entry->next; \
+ } \
+ } \
+\
+ _map_->count -= index; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, delete); \
+\
+ return index; \
+ } \
+\
+ bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ K max_key = (K) { 0 }; \
+ V max_val = (V) { 0 }; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
+\
+ /* TODO Turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ K result_key = CMC_(PFX, _iter_key)(&iter); \
+ V result_value = CMC_(PFX, _iter_value)(&iter); \
+ size_t index = CMC_(PFX, _iter_index)(&iter); \
+\
+ if (index == 0) \
+ { \
+ max_key = result_key; \
+ max_val = result_value; \
+ } \
+ else if (_map_->f_key->cmp(result_key, max_key) > 0) \
+ { \
+ max_key = result_key; \
+ max_val = result_value; \
+ } \
+ } \
+\
+ if (key) \
+ *key = max_key; \
+ if (value) \
+ *value = max_val; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ K min_key = (K) { 0 }; \
+ V min_val = (V) { 0 }; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
+\
+ /* TODO Turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ K result_key = CMC_(PFX, _iter_key)(&iter); \
+ V result_value = CMC_(PFX, _iter_value)(&iter); \
+ size_t index = CMC_(PFX, _iter_index)(&iter); \
+\
+ if (index == 0) \
+ { \
+ min_key = result_key; \
+ min_val = result_value; \
+ } \
+ else if (_map_->f_key->cmp(result_key, min_key) < 0) \
+ { \
+ min_key = result_key; \
+ min_val = result_value; \
+ } \
+ } \
+\
+ if (key) \
+ *key = min_key; \
+ if (value) \
+ *value = min_val; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _get)(struct SNAME * _map_, K key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return (V){ 0 }; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return entry->value; \
+ } \
+\
+ V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_map_, key); \
+\
+ if (!entry) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return NULL; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return &(entry->value); \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ bool result = CMC_(PFX, _impl_get_entry)(_map_, key) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _map_) \
+ { \
+ return _map_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _map_) \
+ { \
+ return (double)_map_->capacity * _map_->load <= (double)_map_->count; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _map_) \
+ { \
+ return _map_->count; \
+ } \
+\
+ size_t CMC_(PFX, _key_count)(struct SNAME * _map_, K key) \
+ { \
+ return CMC_(PFX, _impl_key_count)(_map_, key); \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _map_) \
+ { \
+ return _map_->capacity; \
+ } \
+\
+ double CMC_(PFX, _load)(struct SNAME * _map_) \
+ { \
+ return _map_->load; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _map_) \
+ { \
+ return _map_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _map_, size_t capacity) \
+ { \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ if (_map_->capacity == capacity) \
+ goto success; \
+\
+ if (_map_->capacity > capacity / _map_->load) \
+ goto success; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * _map_->load) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Calculate required capacity based on the prime numbers */ \
+ size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \
+\
+ /* Not possible to shrink with current available prime numbers */ \
+ if (theoretical_size < _map_->count / _map_->load) \
+ { \
+ _map_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ /* No callbacks since _new_map_ is just a temporary hashtable */ \
+ struct SNAME *_new_map_ = \
+ CMC_(PFX, _new_custom)(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!_new_map_) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
+\
+ /* TODO Turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ K key = CMC_(PFX, _iter_key)(&iter); \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ /* TODO check for errors */ \
+ CMC_(PFX, _insert)(_new_map_, key, value); \
+ } \
+\
+ if (_map_->count != _new_map_->count) \
+ { \
+ CMC_(PFX, _free)(_new_map_); \
+\
+ _map_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * (*tmp_b)[2] = _map_->buffer; \
+ _map_->buffer = _new_map_->buffer; \
+ _new_map_->buffer = tmp_b; \
+\
+ size_t tmp_c = _map_->capacity; \
+ _map_->capacity = _new_map_->capacity; \
+ _new_map_->capacity = tmp_c; \
+\
+ /* Prevent the map from freeing the data */ \
+ _new_map_->f_key = &(struct CMC_DEF_FKEY(SNAME)){ NULL }; \
+ _new_map_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \
+\
+ CMC_(PFX, _free)(_new_map_); \
+\
+ success: \
+\
+ CMC_CALLBACKS_CALL(_map_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \
+ { \
+ /* Callback will be added later */ \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_map_->capacity * _map_->load, _map_->load, _map_->f_key, \
+ _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
+\
+ if (!CMC_(PFX, _empty)(_map_)) \
+ { \
+ /* TODO Turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ K key = CMC_(PFX, _iter_key)(&iter); \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (_map_->f_key->cpy) \
+ key = _map_->f_key->cpy(key); \
+ if (_map_->f_val->cpy) \
+ value = _map_->f_val->cpy(value); \
+\
+ /* TODO check for errors */ \
+ CMC_(PFX, _insert)(result, key, value); \
+ } \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \
+ { \
+ _map1_->flag = CMC_FLAG_OK; \
+ _map2_->flag = CMC_FLAG_OK; \
+\
+ if (_map1_->count != _map2_->count) \
+ return false; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \
+\
+ /* TODO Turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ K key = CMC_(PFX, _iter_key)(&iter); \
+\
+ if (CMC_(PFX, _impl_key_count)(_map1_, key) != CMC_(PFX, _impl_key_count)(_map2_, key)) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_new_entry)(struct SNAME * _map_, K key, V value) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->alloc->malloc(sizeof(struct CMC_DEF_ENTRY(SNAME))); \
+\
+ if (!entry) \
+ return NULL; \
+\
+ entry->key = key; \
+ entry->value = value; \
+ entry->next = NULL; \
+ entry->prev = NULL; \
+\
+ return entry; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _map_, K key) \
+ { \
+ size_t hash = _map_->f_key->hash(key); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \
+\
+ while (entry != NULL) \
+ { \
+ if (_map_->f_key->cmp(entry->key, key) == 0) \
+ return entry; \
+\
+ entry = entry->next; \
+ } \
+\
+ return NULL; \
+ } \
+\
+ size_t CMC_(PFX, _impl_key_count)(struct SNAME * _map_, K key) \
+ { \
+ size_t hash = _map_->f_key->hash(key); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[hash % _map_->capacity][0]; \
+\
+ size_t total_count = 0; \
+\
+ if (!entry) \
+ return total_count; \
+\
+ while (entry != NULL) \
+ { \
+ if (_map_->f_key->cmp(entry->key, key) == 0) \
+ total_count++; \
+\
+ entry = entry->next; \
+ } \
+\
+ return total_count; \
+ } \
+\
+ size_t CMC_(PFX, _impl_calculate_size)(size_t required) \
+ { \
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
+\
+ if (cmc_hashtable_primes[count - 1] < required) \
+ return required; \
+\
+ size_t i = 0; \
+ while (cmc_hashtable_primes[i] < required) \
+ i++; \
+\
+ return cmc_hashtable_primes[i]; \
}
-#endif /* CMC_HASHMULTIMAP_H */
+#endif /* CMC_CMC_HASHMULTIMAP_H */
diff --git a/src/cmc/hashmultiset.h b/src/cmc/hashmultiset.h
index 9a92106..be14e5f 100644
--- a/src/cmc/hashmultiset.h
+++ b/src/cmc/hashmultiset.h
@@ -1,5 +1,5 @@
/**
- * hashmultiset.h
+ * cmc/hashmultiset.h
*
* Creation Date: 10/04/2019
*
@@ -23,8 +23,8 @@
* mapped to their multiplicity.
*/
-#ifndef CMC_HASHMULTISET_H
-#define CMC_HASHMULTISET_H
+#ifndef CMC_CMC_HASHMULTISET_H
+#define CMC_CMC_HASHMULTISET_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -36,1492 +36,841 @@
* ------------------------------------------------------------------------- */
#include "../cor/hashtable.h"
+/**
+ * Core HashMultiSet implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_HASHMULTISET_CORE(ACCESS, FILE, PARAMS) \
+ CMC_(CMC_(CMC_CMC_HASHMULTISET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_HASHMULTISET_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHMULTISET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_HASHMULTISET_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \
+ CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHMULTISET_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_HASHMULTISET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHMULTISET_CORE_HEADER(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHMULTISET_CORE_SOURCE(PARAMS) \
+ CMC_CMC_HASHMULTISET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * HashMultiSet specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_hashmultiset = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "cardinality:%" PRIuMAX ", "
- "load:%lf, "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_HASHMULTISET(PFX, SNAME, V) \
- CMC_GENERATE_HASHMULTISET_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_HASHMULTISET_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_HASHMULTISET_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMULTISET_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_HASHMULTISET_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHMULTISET_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_HASHMULTISET_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* HashMultiset Structure */ \
+ struct SNAME \
+ { \
+ /* Array of Entries */ \
+ struct CMC_DEF_ENTRY(SNAME) * buffer; \
+\
+ /* Current Array Capcity */ \
+ size_t capacity; \
+\
+ /* Current amount of unique elements */ \
+ size_t count; \
+\
+ /* Total amount of elements taking into account their multiplicity */ \
+ size_t cardinality; \
+\
+ /* Load factor in range (0.0, 1.0) */ \
+ double load; \
+\
+ /* Flags indicating errors or success */ \
+ int flag; \
+\
+ /* Key function table */ \
+ struct CMC_DEF_FVAL(SNAME) * f_val; \
+\
+ /* Custom allocation functions */ \
+ struct CMC_ALLOC_NODE_NAME *alloc; \
+\
+ /* Custom callback functions */ \
+ CMC_CALLBACKS_DECL; \
+ }; \
+\
+ struct CMC_DEF_ENTRY(SNAME) \
+ { \
+ /* Entry element */ \
+ V value; \
+\
+ /* The element's multiplicity */ \
+ size_t multiplicity; \
+\
+ /* The distance of this node to its original position, used by */ \
+ /* robin-hood hashing */ \
+ size_t dist; \
+\
+ /* The sate of this node (DELETED, EMPTY, FILLED) */ \
+ enum cmc_entry_state state; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHMULTISET_HEADER(PFX, SNAME, V) \
- \
- /* HashMultiset Structure */ \
- struct SNAME \
- { \
- /* Array of Entries */ \
- struct SNAME##_entry *buffer; \
- \
- /* Current Array Capcity */ \
- size_t capacity; \
- \
- /* Current amount of unique elements */ \
- size_t count; \
- \
- /* Total amount of elements taking into account their multiplicity */ \
- size_t cardinality; \
- \
- /* Load factor in range (0.0, 1.0) */ \
- double load; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Key function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- struct SNAME##_entry \
- { \
- /* Entry element */ \
- V value; \
- \
- /* The element's multiplicity */ \
- size_t multiplicity; \
- \
- /* The distance of this node to its original position, used by */ \
- /* robin-hood hashing */ \
- size_t dist; \
- \
- /* The sate of this node (DELETED, EMPTY, FILLED) */ \
- enum cmc_entry_state state; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* HashMultiset Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target HashMultiset */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* The index of the first element */ \
- size_t first; \
- \
- /* The index of the last element */ \
- size_t last; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_set_); \
- void PFX##_free(struct SNAME *_set_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_set_, V value); \
- bool PFX##_insert_many(struct SNAME *_set_, V value, size_t count); \
- bool PFX##_update(struct SNAME *_set_, V value, size_t multiplicity); \
- bool PFX##_remove(struct SNAME *_set_, V value); \
- size_t PFX##_remove_all(struct SNAME *_set_, V value); \
- /* Element Access */ \
- bool PFX##_max(struct SNAME *_set_, V *value); \
- bool PFX##_min(struct SNAME *_set_, V *value); \
- size_t PFX##_multiplicity_of(struct SNAME *_set_, V value); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_set_, V value); \
- bool PFX##_empty(struct SNAME *_set_); \
- bool PFX##_full(struct SNAME *_set_); \
- size_t PFX##_count(struct SNAME *_set_); \
- size_t PFX##_cardinality(struct SNAME *_set_); \
- size_t PFX##_capacity(struct SNAME *_set_); \
- double PFX##_load(struct SNAME *_set_); \
- int PFX##_flag(struct SNAME *_set_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_set_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_); \
- bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_set_); \
- bool PFX##_print(struct SNAME *_set_, FILE *fptr); \
- \
- /* Set Operations */ \
- struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct SNAME *PFX##_intersection(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- struct SNAME *PFX##_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_multiplicity(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_HASHMULTISET_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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, double load, struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \
+ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _set_); \
+ void CMC_(PFX, _free)(struct SNAME * _set_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \
+ bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count); \
+ bool CMC_(PFX, _update)(struct SNAME * _set_, V value, size_t multiplicity); \
+ bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \
+ size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value); \
+ /* Element Access */ \
+ bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \
+ bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \
+ size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _set_); \
+ bool CMC_(PFX, _full)(struct SNAME * _set_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _set_); \
+ size_t CMC_(PFX, _cardinality)(struct SNAME * _set_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \
+ double CMC_(PFX, _load)(struct SNAME * _set_); \
+ int CMC_(PFX, _flag)(struct SNAME * _set_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHMULTISET_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- static size_t PFX##_impl_multiplicity_of(struct SNAME *_set_, V value); \
- static struct SNAME##_entry *PFX##_impl_insert_and_return( \
- struct SNAME *_set_, V value, bool *new_node); \
- static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \
- V value); \
- static size_t PFX##_impl_calculate_size(size_t required); \
- \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_set_) \
- return NULL; \
- \
- _set_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
- \
- if (!_set_->buffer) \
- { \
- alloc->free(_set_); \
- return NULL; \
- } \
- \
- _set_->count = 0; \
- _set_->cardinality = 0; \
- _set_->capacity = real_capacity; \
- _set_->load = load; \
- _set_->flag = cmc_flags.OK; \
- _set_->f_val = f_val; \
- _set_->alloc = alloc; \
- _set_->callbacks = NULL; \
- \
- return _set_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_set_) \
- return NULL; \
- \
- _set_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
- \
- if (!_set_->buffer) \
- { \
- alloc->free(_set_); \
- return NULL; \
- } \
- \
- _set_->count = 0; \
- _set_->cardinality = 0; \
- _set_->capacity = real_capacity; \
- _set_->load = load; \
- _set_->flag = cmc_flags.OK; \
- _set_->f_val = f_val; \
- _set_->alloc = alloc; \
- _set_->callbacks = callbacks; \
- \
- return _set_; \
- } \
- \
- void PFX##_clear(struct SNAME *_set_) \
- { \
- if (_set_->f_val->free) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_set_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- _set_->f_val->free(entry->value); \
- } \
- } \
- } \
- \
- memset(_set_->buffer, 0, \
- sizeof(struct SNAME##_entry) * _set_->capacity); \
- \
- _set_->count = 0; \
- _set_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_set_) \
- { \
- if (_set_->f_val->free) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_set_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- _set_->f_val->free(entry->value); \
- } \
- } \
- } \
- \
- _set_->alloc->free(_set_->buffer); \
- _set_->alloc->free(_set_); \
- } \
- \
- void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _set_->alloc = &cmc_alloc_node_default; \
- else \
- _set_->alloc = alloc; \
- \
- _set_->callbacks = callbacks; \
- \
- _set_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_set_, V value) \
- { \
- bool new_node; \
- \
- struct SNAME##_entry *entry = \
- PFX##_impl_insert_and_return(_set_, value, &new_node); \
- \
- if (!entry) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- if (!new_node) \
- entry->multiplicity++; \
- \
- _set_->cardinality++; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->create) \
- _set_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_insert_many(struct SNAME *_set_, V value, size_t count) \
- { \
- if (count == 0) \
- goto success; \
- \
- bool new_node; \
- \
- struct SNAME##_entry *entry = \
- PFX##_impl_insert_and_return(_set_, value, &new_node); \
- \
- if (!entry) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- if (new_node) \
- entry->multiplicity = count; \
- else \
- entry->multiplicity += count; \
- \
- _set_->cardinality += count; \
- \
- success: \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->create) \
- _set_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_update(struct SNAME *_set_, V value, size_t multiplicity) \
- { \
- if (multiplicity == 0) \
- { \
- /* Effectively delete the entry */ \
- struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \
- \
- if (!result) \
+#define CMC_CMC_HASHMULTISET_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, V value); \
+ static struct CMC_DEF_ENTRY(SNAME) * \
+ CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, bool *new_node); \
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \
+\
+ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(capacity, load, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, 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 || load <= 0 || load >= 1) \
+ return NULL; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * load) \
+ return NULL; \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_set_) \
+ return NULL; \
+\
+ _set_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \
+\
+ if (!_set_->buffer) \
+ { \
+ alloc->free(_set_); \
+ return NULL; \
+ } \
+\
+ _set_->count = 0; \
+ _set_->cardinality = 0; \
+ _set_->capacity = real_capacity; \
+ _set_->load = load; \
+ _set_->flag = CMC_FLAG_OK; \
+ _set_->f_val = f_val; \
+ _set_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_set_, callbacks); \
+\
+ return _set_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _set_) \
+ { \
+ if (_set_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ _set_->f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ memset(_set_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \
+\
+ _set_->count = 0; \
+ _set_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _set_) \
+ { \
+ if (_set_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ _set_->f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ _set_->alloc->free(_set_->buffer); \
+ _set_->alloc->free(_set_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _set_->alloc = &cmc_alloc_node_default; \
+ else \
+ _set_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_set_, callbacks); \
+\
+ _set_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \
+ { \
+ bool new_node; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \
+\
+ if (!entry) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ if (!new_node) \
+ entry->multiplicity++; \
+\
+ _set_->cardinality++; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _insert_many)(struct SNAME * _set_, V value, size_t count) \
+ { \
+ if (count == 0) \
+ goto success; \
+\
+ bool new_node; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \
+\
+ if (!entry) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ if (new_node) \
+ entry->multiplicity = count; \
+ else \
+ entry->multiplicity += count; \
+\
+ _set_->cardinality += count; \
+\
+ success: \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _update)(struct SNAME * _set_, V value, size_t multiplicity) \
+ { \
+ if (multiplicity == 0) \
+ { \
+ /* Effectively delete the entry */ \
+ struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ if (!result) \
/* If no entry was found then its multiplicity is already 0 */ \
- goto success; \
- \
- _set_->count--; \
- _set_->cardinality -= result->multiplicity; \
- \
- result->value = (V){ 0 }; \
- result->multiplicity = 0; \
- result->dist = 0; \
- result->state = CMC_ES_DELETED; \
- \
- goto success; \
- } \
- \
- bool new_node; \
- \
- struct SNAME##_entry *entry = \
- PFX##_impl_insert_and_return(_set_, value, &new_node); \
- \
- if (!entry) \
- return false; \
- \
- if (new_node) \
- _set_->cardinality++; \
- \
- _set_->cardinality = \
- (_set_->cardinality - entry->multiplicity) + multiplicity; \
- \
- entry->multiplicity = multiplicity; \
- \
- success: \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->update) \
- _set_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_set_, V value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \
- \
- if (!result) \
- { \
- _set_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- if (result->multiplicity > 1) \
- result->multiplicity--; \
- else \
- { \
- result->value = (V){ 0 }; \
- result->multiplicity = 0; \
- result->dist = 0; \
- result->state = CMC_ES_DELETED; \
- \
- _set_->count--; \
- } \
- \
- _set_->cardinality--; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->delete) \
- _set_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- size_t PFX##_remove_all(struct SNAME *_set_, V value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \
- \
- if (!result) \
- { \
- _set_->flag = cmc_flags.NOT_FOUND; \
- return 0; \
- } \
- \
- size_t removed = result->multiplicity; \
- \
- result->value = (V){ 0 }; \
- result->multiplicity = 0; \
- result->dist = 0; \
- result->state = CMC_ES_DELETED; \
- \
- _set_->count--; \
- _set_->cardinality -= removed; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->delete) \
- _set_->callbacks->delete (); \
- \
- return removed; \
- } \
- \
- bool PFX##_max(struct SNAME *_set_, V *value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- V max_val; \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- /* TODO transform this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V result = PFX##_iter_value(&iter); \
- size_t index = PFX##_iter_index(&iter); \
- \
- if (index == 0) \
- max_val = result; \
- else if (_set_->f_val->cmp(result, max_val) > 0) \
- max_val = result; \
- } \
- \
- if (value) \
- *value = max_val; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_min(struct SNAME *_set_, V *value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- V min_val; \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- /* TODO transform this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V result = PFX##_iter_value(&iter); \
- size_t index = PFX##_iter_index(&iter); \
- \
- if (index == 0) \
- min_val = result; \
- else if (_set_->f_val->cmp(result, min_val) < 0) \
- min_val = result; \
- } \
- \
- if (value) \
- *value = min_val; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return true; \
- } \
- \
- size_t PFX##_multiplicity_of(struct SNAME *_set_, V value) \
- { \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, value); \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- if (!entry) \
- return 0; \
- \
- return entry->multiplicity; \
- } \
- \
- bool PFX##_contains(struct SNAME *_set_, V value) \
- { \
- _set_->flag = cmc_flags.OK; \
- \
- bool result = PFX##_impl_get_entry(_set_, value) != NULL; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_set_) \
- { \
- return _set_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_set_) \
- { \
- return (double)_set_->capacity * _set_->load <= (double)_set_->count; \
- } \
- \
- size_t PFX##_count(struct SNAME *_set_) \
- { \
- return _set_->count; \
- } \
- \
- size_t PFX##_cardinality(struct SNAME *_set_) \
- { \
- return _set_->cardinality; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_set_) \
- { \
- return _set_->capacity; \
- } \
- \
- double PFX##_load(struct SNAME *_set_) \
- { \
- return _set_->load; \
- } \
- \
- int PFX##_flag(struct SNAME *_set_) \
- { \
- return _set_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_set_, size_t capacity) \
- { \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->capacity == capacity) \
- goto success; \
- \
- if (_set_->capacity > capacity / _set_->load) \
- goto success; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * _set_->load) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Calculate required capacity based on the prime numbers */ \
- size_t theoretical_size = PFX##_impl_calculate_size(capacity); \
- \
- /* Not possible to shrink with current available prime numbers */ \
- if (theoretical_size < _set_->count / _set_->load) \
- { \
- _set_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- /* No callbacks since _new_set_ is just a temporary hashtable */ \
- struct SNAME *_new_set_ = PFX##_new_custom( \
- capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \
- \
- if (!_new_set_) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- /* TODO transform this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- PFX##_insert_many(_new_set_, PFX##_iter_value(&iter), \
- PFX##_iter_multiplicity(&iter)); \
- } \
- \
- if (_set_->count != _new_set_->count) \
- { \
- PFX##_free(_new_set_); \
- \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- struct SNAME##_entry *tmp_b = _set_->buffer; \
- _set_->buffer = _new_set_->buffer; \
- _new_set_->buffer = tmp_b; \
- \
- size_t tmp_c = _set_->capacity; \
- _set_->capacity = _new_set_->capacity; \
- _new_set_->capacity = tmp_c; \
- \
- /* Prevent the set from freeing the data */ \
- _new_set_->f_val = &(struct SNAME##_fval){ NULL }; \
- \
- PFX##_free(_new_set_); \
- \
- success: \
- \
- if (_set_->callbacks && _set_->callbacks->resize) \
- _set_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_set_->capacity * _set_->load, _set_->load, \
- _set_->f_val, _set_->alloc, _set_->callbacks); \
- \
- if (!result) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_set_->f_val->cpy) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = &(_set_->buffer[i]); \
- \
- if (scan->state != CMC_ES_EMPTY) \
- { \
- struct SNAME##_entry *target = &(result->buffer[i]); \
- \
- if (scan->state == CMC_ES_DELETED) \
- target->state = CMC_ES_DELETED; \
- else \
- { \
- target->state = scan->state; \
- target->dist = scan->dist; \
- target->multiplicity = scan->multiplicity; \
- \
- target->value = _set_->f_val->cpy(scan->value); \
- } \
- } \
- } \
- } \
- else \
- memcpy(result->buffer, _set_->buffer, \
- sizeof(struct SNAME##_entry) * _set_->capacity); \
- \
- result->count = _set_->count; \
- result->cardinality = _set_->cardinality; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- _set1_->flag = cmc_flags.OK; \
- _set2_->flag = cmc_flags.OK; \
- \
- if (_set1_->count != _set2_->count) \
- return false; \
- \
- if (_set1_->cardinality != _set2_->cardinality) \
- return false; \
- \
- if (_set1_->count == 0) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- struct SNAME##_entry *entry = \
- PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)); \
- \
- if (!entry) \
- return false; \
- \
- if (entry->multiplicity != PFX##_iter_multiplicity(&iter)) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_set_) \
- { \
- struct cmc_string str; \
- struct SNAME *s_ = _set_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultiset, \
- #SNAME, #V, s_, s_->buffer, s_->capacity, s_->count, \
- s_->cardinality, s_->load, s_->flag, s_->f_val, \
- s_->alloc, s_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_set_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_set_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- if (!_set_->f_val->str(fptr, entry->value)) \
- return false; \
- } \
- } \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- V value = PFX##_iter_value(&iter1); \
- \
- size_t m1 = PFX##_iter_multiplicity(&iter1); \
- size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \
- size_t max_ = m1 > m2 ? m1 : m2; \
- \
- PFX##_update(_set_r_, value, max_); \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- V value = PFX##_iter_value(&iter2); \
- \
- size_t m1 = PFX##_impl_multiplicity_of(_set1_, value); \
- size_t m2 = PFX##_iter_multiplicity(&iter2); \
- size_t max_ = m1 > m2 ? m1 : m2; \
- \
- PFX##_update(_set_r_, value, max_); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_intersection(struct SNAME *_set1_, \
- struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME *_set_A_ = \
- _set1_->count < _set2_->count ? _set1_ : _set2_; \
- struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set_A_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- size_t m1 = PFX##_iter_multiplicity(&iter); \
- size_t m2 = PFX##_impl_multiplicity_of(_set_B_, value); \
- size_t max_ = m1 < m2 ? m1 : m2; \
- \
- PFX##_update(_set_r_, value, max_); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- size_t m1 = PFX##_iter_multiplicity(&iter); \
- size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \
- \
- if (m1 > m2) \
- PFX##_update(_set_r_, value, m1 - m2); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_summation(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- PFX##_insert_many(_set_r_, PFX##_iter_value(&iter1), \
- PFX##_iter_multiplicity(&iter1)); \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- PFX##_insert_many(_set_r_, PFX##_iter_value(&iter2), \
- PFX##_iter_multiplicity(&iter2)); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- return NULL; \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- V value = PFX##_iter_value(&iter1); \
- \
- size_t m1 = PFX##_iter_multiplicity(&iter1); \
- size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \
- \
- if (m1 != m2) \
- { \
- if (m1 > m2) \
- PFX##_update(_set_r_, value, m1 - m2); \
- else \
- PFX##_update(_set_r_, value, m2 - m1); \
- } \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- V value = PFX##_iter_value(&iter2); \
- \
- size_t m1 = PFX##_impl_multiplicity_of(_set1_, value); \
- size_t m2 = PFX##_iter_multiplicity(&iter2); \
- \
- if (m1 != m2) \
- { \
- if (m1 > m2) \
- PFX##_update(_set_r_, value, m1 - m2); \
- else \
- PFX##_update(_set_r_, value, m2 - m1); \
- } \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- if (_set1_->count > _set2_->count) \
- return false; \
- \
- if (PFX##_empty(_set1_)) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- size_t m1 = PFX##_iter_multiplicity(&iter); \
- size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \
- \
- if (m1 > m2) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- return PFX##_is_subset(_set2_, _set1_); \
- } \
- \
- bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- if (_set1_->count >= _set2_->count) \
- return false; \
- \
- if (PFX##_empty(_set1_)) \
- { \
- if (!PFX##_empty(_set2_)) \
- return true; \
- else \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- size_t m1 = PFX##_iter_multiplicity(&iter); \
- size_t m2 = PFX##_impl_multiplicity_of(_set2_, value); \
- \
- if (m1 >= m2) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- return PFX##_is_proper_subset(_set2_, _set1_); \
- } \
- \
- bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- if (PFX##_empty(_set1_)) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_entry(_set2_, value) != NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i].state == CMC_ES_FILLED) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.first; \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1].state == CMC_ES_FILLED) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- } \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i].state == CMC_ES_FILLED) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1].state == CMC_ES_FILLED) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.last; \
- iter.index = target->count - 1; \
- } \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->first; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->last; \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
- \
- iter->index++; \
- \
- while (1) \
- { \
- iter->cursor++; \
- scan = &(iter->target->buffer[iter->cursor]); \
- \
- if (scan->state == CMC_ES_FILLED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
- \
- iter->index--; \
- \
- while (1) \
- { \
- iter->cursor--; \
- scan = &(iter->target->buffer[iter->cursor]); \
- \
- if (scan->state == CMC_ES_FILLED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor].value; \
- } \
- \
- size_t PFX##_iter_multiplicity(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return 0; \
- \
- return iter->target->buffer[iter->cursor].multiplicity; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static size_t PFX##_impl_multiplicity_of(struct SNAME *_set_, V value) \
- { \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, value); \
- \
- if (!entry) \
- return 0; \
- \
- return entry->multiplicity; \
- } \
- \
- static struct SNAME##_entry *PFX##_impl_insert_and_return( \
- struct SNAME *_set_, V value, bool *new_node) \
- { \
- /* If the entry already exists simply return it as we might do */ \
- /* something with it. This function only guarantees that there is */ \
- /* a valid entry for a given value */ \
- \
- *new_node = false; \
- \
- struct SNAME##_entry *entry = PFX##_impl_get_entry(_set_, value); \
- \
- if (entry != NULL) \
- return entry; \
- \
- *new_node = true; \
- \
- if (PFX##_full(_set_)) \
- { \
- if (!PFX##_resize(_set_, _set_->capacity + 1)) \
- return NULL; \
- } \
- \
- size_t hash = _set_->f_val->hash(value); \
- size_t original_pos = hash % _set_->capacity; \
- size_t pos = original_pos; \
- /* Current multiplicity. Might change due to robin hood hashing */ \
- size_t curr_mul = 1; \
- \
- struct SNAME##_entry *target = &(_set_->buffer[pos]); \
- struct SNAME##_entry *to_return = NULL; \
- \
- if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
- { \
- target->value = value; \
- target->multiplicity = curr_mul; \
- target->dist = pos - original_pos; \
- target->state = CMC_ES_FILLED; \
- \
- to_return = target; \
- } \
- else \
- { \
- while (true) \
- { \
- pos++; \
- target = &(_set_->buffer[pos % _set_->capacity]); \
- \
- if (target->state == CMC_ES_EMPTY || \
- target->state == CMC_ES_DELETED) \
- { \
- target->value = value; \
- target->multiplicity = curr_mul; \
- target->dist = pos - original_pos; \
- target->state = CMC_ES_FILLED; \
- \
- if (!to_return) \
- to_return = target; \
- \
- break; \
- } \
- else if (target->dist < pos - original_pos) \
- { \
- /* Swap everything */ \
- V tmp = target->value; \
- size_t tmp_dist = target->dist; \
- size_t tmp_mul = target->multiplicity; \
- \
- target->value = value; \
- target->dist = pos - original_pos; \
- target->multiplicity = curr_mul; \
- \
- value = tmp; \
- original_pos = pos - tmp_dist; \
- curr_mul = tmp_mul; \
- \
- if (!to_return) \
- to_return = target; \
- } \
- } \
- } \
- \
- _set_->count++; \
- \
- return to_return; \
- } \
- \
- static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \
- V value) \
- { \
- size_t hash = _set_->f_val->hash(value); \
- size_t pos = hash % _set_->capacity; \
- \
- struct SNAME##_entry *target = &(_set_->buffer[pos]); \
- \
- while (target->state == CMC_ES_FILLED || \
- target->state == CMC_ES_DELETED) \
- { \
- if (_set_->f_val->cmp(target->value, value) == 0) \
- return target; \
- \
- pos++; \
- target = &(_set_->buffer[pos % _set_->capacity]); \
- } \
- \
- return NULL; \
- } \
- \
- static size_t PFX##_impl_calculate_size(size_t required) \
- { \
- const size_t count = \
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
- \
- if (cmc_hashtable_primes[count - 1] < required) \
- return required; \
- \
- size_t i = 0; \
- while (cmc_hashtable_primes[i] < required) \
- i++; \
- \
- return cmc_hashtable_primes[i]; \
+ goto success; \
+\
+ _set_->count--; \
+ _set_->cardinality -= result->multiplicity; \
+\
+ result->value = (V){ 0 }; \
+ result->multiplicity = 0; \
+ result->dist = 0; \
+ result->state = CMC_ES_DELETED; \
+\
+ goto success; \
+ } \
+\
+ bool new_node; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_insert_and_return)(_set_, value, &new_node); \
+\
+ if (!entry) \
+ return false; \
+\
+ if (new_node) \
+ _set_->cardinality++; \
+\
+ _set_->cardinality = (_set_->cardinality - entry->multiplicity) + multiplicity; \
+\
+ entry->multiplicity = multiplicity; \
+\
+ success: \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, update); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ if (!result) \
+ { \
+ _set_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ if (result->multiplicity > 1) \
+ result->multiplicity--; \
+ else \
+ { \
+ result->value = (V){ 0 }; \
+ result->multiplicity = 0; \
+ result->dist = 0; \
+ result->state = CMC_ES_DELETED; \
+\
+ _set_->count--; \
+ } \
+\
+ _set_->cardinality--; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, delete); \
+\
+ return true; \
+ } \
+\
+ size_t CMC_(PFX, _remove_all)(struct SNAME * _set_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ if (!result) \
+ { \
+ _set_->flag = CMC_FLAG_NOT_FOUND; \
+ return 0; \
+ } \
+\
+ size_t removed = result->multiplicity; \
+\
+ result->value = (V){ 0 }; \
+ result->multiplicity = 0; \
+ result->dist = 0; \
+ result->state = CMC_ES_DELETED; \
+\
+ _set_->count--; \
+ _set_->cardinality -= removed; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, delete); \
+\
+ return removed; \
+ } \
+\
+ bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ V max_val = (V) { 0 }; \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ /* TODO transform this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V result = CMC_(PFX, _iter_value)(&iter); \
+ size_t index = CMC_(PFX, _iter_index)(&iter); \
+\
+ if (index == 0) \
+ max_val = result; \
+ else if (_set_->f_val->cmp(result, max_val) > 0) \
+ max_val = result; \
+ } \
+\
+ if (value) \
+ *value = max_val; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ V min_val = (V) { 0 }; \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ /* TODO transform this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V result = CMC_(PFX, _iter_value)(&iter); \
+ size_t index = CMC_(PFX, _iter_index)(&iter); \
+\
+ if (index == 0) \
+ min_val = result; \
+ else if (_set_->f_val->cmp(result, min_val) < 0) \
+ min_val = result; \
+ } \
+\
+ if (value) \
+ *value = min_val; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return true; \
+ } \
+\
+ size_t CMC_(PFX, _multiplicity_of)(struct SNAME * _set_, V value) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ if (!entry) \
+ return 0; \
+\
+ return entry->multiplicity; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \
+ { \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _set_) \
+ { \
+ return _set_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _set_) \
+ { \
+ return (double)_set_->capacity * _set_->load <= (double)_set_->count; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _set_) \
+ { \
+ return _set_->count; \
+ } \
+\
+ size_t CMC_(PFX, _cardinality)(struct SNAME * _set_) \
+ { \
+ return _set_->cardinality; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \
+ { \
+ return _set_->capacity; \
+ } \
+\
+ double CMC_(PFX, _load)(struct SNAME * _set_) \
+ { \
+ return _set_->load; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _set_) \
+ { \
+ return _set_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \
+ { \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ if (_set_->capacity == capacity) \
+ goto success; \
+\
+ if (_set_->capacity > capacity / _set_->load) \
+ goto success; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * _set_->load) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Calculate required capacity based on the prime numbers */ \
+ size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \
+\
+ /* Not possible to shrink with current available prime numbers */ \
+ if (theoretical_size < _set_->count / _set_->load) \
+ { \
+ _set_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ /* No callbacks since _new_set_ is just a temporary hashtable */ \
+ struct SNAME *_new_set_ = CMC_(PFX, _new_custom)(capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \
+\
+ if (!_new_set_) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ /* TODO transform this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ CMC_(PFX, _insert_many) \
+ (_new_set_, CMC_(PFX, _iter_value)(&iter), CMC_(PFX, _iter_multiplicity)(&iter)); \
+ } \
+\
+ if (_set_->count != _new_set_->count) \
+ { \
+ CMC_(PFX, _free)(_new_set_); \
+\
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \
+ _set_->buffer = _new_set_->buffer; \
+ _new_set_->buffer = tmp_b; \
+\
+ size_t tmp_c = _set_->capacity; \
+ _set_->capacity = _new_set_->capacity; \
+ _new_set_->capacity = tmp_c; \
+\
+ /* Prevent the set from freeing the data */ \
+ _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \
+\
+ CMC_(PFX, _free)(_new_set_); \
+\
+ success: \
+\
+ CMC_CALLBACKS_CALL(_set_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \
+ { \
+ struct SNAME *result = \
+ CMC_(PFX, _new_custom)(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \
+\
+ if (_set_->f_val->cpy) \
+ { \
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \
+\
+ if (scan->state != CMC_ES_EMPTY) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \
+\
+ if (scan->state == CMC_ES_DELETED) \
+ target->state = CMC_ES_DELETED; \
+ else \
+ { \
+ target->state = scan->state; \
+ target->dist = scan->dist; \
+ target->multiplicity = scan->multiplicity; \
+\
+ target->value = _set_->f_val->cpy(scan->value); \
+ } \
+ } \
+ } \
+ } \
+ else \
+ memcpy(result->buffer, _set_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \
+\
+ result->count = _set_->count; \
+ result->cardinality = _set_->cardinality; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ _set1_->flag = CMC_FLAG_OK; \
+ _set2_->flag = CMC_FLAG_OK; \
+\
+ if (_set1_->count != _set2_->count) \
+ return false; \
+\
+ if (_set1_->cardinality != _set2_->cardinality) \
+ return false; \
+\
+ if (_set1_->count == 0) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)); \
+\
+ if (!entry) \
+ return false; \
+\
+ if (entry->multiplicity != CMC_(PFX, _iter_multiplicity)(&iter)) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_multiplicity_of)(struct SNAME * _set_, V value) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ if (!entry) \
+ return 0; \
+\
+ return entry->multiplicity; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * \
+ CMC_(PFX, _impl_insert_and_return)(struct SNAME * _set_, V value, bool *new_node) \
+ { \
+ /* If the entry already exists simply return it as we might do */ \
+ /* something with it. This function only guarantees that there is */ \
+ /* a valid entry for a given value */ \
+\
+ *new_node = false; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *entry = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ if (entry != NULL) \
+ return entry; \
+\
+ *new_node = true; \
+\
+ if (CMC_(PFX, _full)(_set_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \
+ return NULL; \
+ } \
+\
+ size_t hash = _set_->f_val->hash(value); \
+ size_t original_pos = hash % _set_->capacity; \
+ size_t pos = original_pos; \
+ /* Current multiplicity. Might change due to robin hood hashing */ \
+ size_t curr_mul = 1; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \
+ struct CMC_DEF_ENTRY(SNAME) *to_return = NULL; \
+\
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
+ { \
+ target->value = value; \
+ target->multiplicity = curr_mul; \
+ target->dist = pos - original_pos; \
+ target->state = CMC_ES_FILLED; \
+\
+ to_return = target; \
+ } \
+ else \
+ { \
+ while (true) \
+ { \
+ pos++; \
+ target = &(_set_->buffer[pos % _set_->capacity]); \
+\
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
+ { \
+ target->value = value; \
+ target->multiplicity = curr_mul; \
+ target->dist = pos - original_pos; \
+ target->state = CMC_ES_FILLED; \
+\
+ if (!to_return) \
+ to_return = target; \
+\
+ break; \
+ } \
+ else if (target->dist < pos - original_pos) \
+ { \
+ /* Swap everything */ \
+ V tmp = target->value; \
+ size_t tmp_dist = target->dist; \
+ size_t tmp_mul = target->multiplicity; \
+\
+ target->value = value; \
+ target->dist = pos - original_pos; \
+ target->multiplicity = curr_mul; \
+\
+ value = tmp; \
+ original_pos = pos - tmp_dist; \
+ curr_mul = tmp_mul; \
+\
+ if (!to_return) \
+ to_return = target; \
+ } \
+ } \
+ } \
+\
+ _set_->count++; \
+\
+ return to_return; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \
+ { \
+ size_t hash = _set_->f_val->hash(value); \
+ size_t pos = hash % _set_->capacity; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \
+\
+ while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \
+ { \
+ if (_set_->f_val->cmp(target->value, value) == 0) \
+ return target; \
+\
+ pos++; \
+ target = &(_set_->buffer[pos % _set_->capacity]); \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \
+ { \
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
+\
+ if (cmc_hashtable_primes[count - 1] < required) \
+ return required; \
+\
+ size_t i = 0; \
+ while (cmc_hashtable_primes[i] < required) \
+ i++; \
+\
+ return cmc_hashtable_primes[i]; \
}
-#endif /* CMC_HASHMULTISET_H */
+#endif /* CMC_CMC_HASHMULTISET_H */
diff --git a/src/cmc/hashset.h b/src/cmc/hashset.h
index 086bc0e..47bdf4f 100644
--- a/src/cmc/hashset.h
+++ b/src/cmc/hashset.h
@@ -1,5 +1,5 @@
/**
- * hashset.h
+ * cmc/hashset.h
*
* Creation Date: 01/04/2019
*
@@ -16,8 +16,8 @@
* hood hashing.
*/
-#ifndef CMC_HASHSET_H
-#define CMC_HASHSET_H
+#ifndef CMC_CMC_HASHSET_H
+#define CMC_CMC_HASHSET_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -29,1245 +29,629 @@
* ------------------------------------------------------------------------- */
#include "../cor/hashtable.h"
+/**
+ * Core HashSet implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_HASHSET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HASHSET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_HASHSET_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHSET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHSET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HASHSET_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_HASHSET_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ struct CMC_DEF_ENTRY(CMC_PARAM_SNAME(PARAMS)); \
+ CMC_CMC_HASHSET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HASHSET_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHSET_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_HASHSET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HASHSET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHSET_CORE_HEADER(PARAMS) \
+ CMC_CMC_HASHSET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HASHSET_CORE_SOURCE(PARAMS) \
+ CMC_CMC_HASHSET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * HashSet specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_hashset = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "load:%lf, "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks: %p }";
-
-#define CMC_GENERATE_HASHSET(PFX, SNAME, V) \
- CMC_GENERATE_HASHSET_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_HASHSET_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_HASHSET_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHSET_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_HASHSET_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_HASHSET_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_HASHSET_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Hashset Structure */ \
+ struct SNAME \
+ { \
+ /* Array of Entries */ \
+ struct CMC_DEF_ENTRY(SNAME) * buffer; \
+\
+ /* Current Array Capcity */ \
+ size_t capacity; \
+\
+ /* Current amount of elements */ \
+ size_t count; \
+\
+ /* Load factor in range (0.0, 1.0) */ \
+ double load; \
+\
+ /* 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; \
+ }; \
+\
+ struct CMC_DEF_ENTRY(SNAME) \
+ { \
+ /* Entry value */ \
+ V value; \
+\
+ /* The distance of this node to its original position, used by */ \
+ /* robin-hood hashing */ \
+ size_t dist; \
+\
+ /* The sate of this node (DELETED, EMPTY, FILLED) */ \
+ enum cmc_entry_state state; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHSET_HEADER(PFX, SNAME, V) \
- \
- /* Hashset Structure */ \
- struct SNAME \
- { \
- /* Array of Entries */ \
- struct SNAME##_entry *buffer; \
- \
- /* Current Array Capcity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Load factor in range (0.0, 1.0) */ \
- double load; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- struct SNAME##_entry \
- { \
- /* Entry value */ \
- V value; \
- \
- /* The distance of this node to its original position, used by */ \
- /* robin-hood hashing */ \
- size_t dist; \
- \
- /* The sate of this node (DELETED, EMPTY, FILLED) */ \
- enum cmc_entry_state state; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Hashset Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target Hashset */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* The index of the first element */ \
- size_t first; \
- \
- /* The index of the last element */ \
- size_t last; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_set_); \
- void PFX##_free(struct SNAME *_set_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_set_, V value); \
- bool PFX##_remove(struct SNAME *_set_, V value); \
- /* Element Access */ \
- bool PFX##_max(struct SNAME *_set_, V *value); \
- bool PFX##_min(struct SNAME *_set_, V *value); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_set_, V value); \
- bool PFX##_empty(struct SNAME *_set_); \
- bool PFX##_full(struct SNAME *_set_); \
- size_t PFX##_count(struct SNAME *_set_); \
- size_t PFX##_capacity(struct SNAME *_set_); \
- double PFX##_load(struct SNAME *_set_); \
- int PFX##_flag(struct SNAME *_set_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_set_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_); \
- bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_set_); \
- bool PFX##_print(struct SNAME *_set_, FILE *fptr); \
- \
- /* Set Operations */ \
- struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct SNAME *PFX##_intersection(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- struct SNAME *PFX##_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_HASHSET_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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, double load, struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val, \
+ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _set_); \
+ void CMC_(PFX, _free)(struct SNAME * _set_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \
+ bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \
+ /* Element Access */ \
+ bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \
+ bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _set_); \
+ bool CMC_(PFX, _full)(struct SNAME * _set_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _set_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _set_); \
+ double CMC_(PFX, _load)(struct SNAME * _set_); \
+ int CMC_(PFX, _flag)(struct SNAME * _set_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HASHSET_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \
- V value); \
- static size_t PFX##_impl_calculate_size(size_t required); \
- static struct SNAME##_iter PFX##_impl_it_start(struct SNAME *_set_); \
- static struct SNAME##_iter PFX##_impl_it_end(struct SNAME *_set_); \
- \
- struct SNAME *PFX##_new(size_t capacity, double load, \
- struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_set_) \
- return NULL; \
- \
- _set_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
- \
- if (!_set_->buffer) \
- { \
- alloc->free(_set_); \
- return NULL; \
- } \
- \
- _set_->count = 0; \
- _set_->capacity = real_capacity; \
- _set_->load = load; \
- _set_->flag = cmc_flags.OK; \
- _set_->f_val = f_val; \
- _set_->alloc = alloc; \
- _set_->callbacks = NULL; \
- \
- return _set_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, double load, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity == 0 || load <= 0 || load >= 1) \
- return NULL; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * load) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- size_t real_capacity = PFX##_impl_calculate_size(capacity / load); \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_set_) \
- return NULL; \
- \
- _set_->buffer = \
- alloc->calloc(real_capacity, sizeof(struct SNAME##_entry)); \
- \
- if (!_set_->buffer) \
- { \
- alloc->free(_set_); \
- return NULL; \
- } \
- \
- _set_->count = 0; \
- _set_->capacity = real_capacity; \
- _set_->load = load; \
- _set_->flag = cmc_flags.OK; \
- _set_->f_val = f_val; \
- _set_->alloc = alloc; \
- _set_->callbacks = callbacks; \
- \
- return _set_; \
- } \
- \
- void PFX##_clear(struct SNAME *_set_) \
- { \
- if (_set_->f_val->free) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_set_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- _set_->f_val->free(entry->value); \
- } \
- } \
- } \
- \
- memset(_set_->buffer, 0, \
- sizeof(struct SNAME##_entry) * _set_->capacity); \
- \
- _set_->count = 0; \
- _set_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_set_) \
- { \
- if (_set_->f_val->free) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_set_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- _set_->f_val->free(entry->value); \
- } \
- } \
- } \
- \
- _set_->alloc->free(_set_->buffer); \
- _set_->alloc->free(_set_); \
- } \
- \
- void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _set_->alloc = &cmc_alloc_node_default; \
- else \
- _set_->alloc = alloc; \
- \
- _set_->callbacks = callbacks; \
- \
- _set_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_set_, V value) \
- { \
- if (PFX##_full(_set_)) \
- { \
- if (!PFX##_resize(_set_, _set_->capacity + 1)) \
- return false; \
- } \
- \
- if (PFX##_impl_get_entry(_set_, value) != NULL) \
- { \
- _set_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- \
- size_t hash = _set_->f_val->hash(value); \
- size_t original_pos = hash % _set_->capacity; \
- size_t pos = original_pos; \
- \
- struct SNAME##_entry *target = &(_set_->buffer[pos]); \
- \
- if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
- { \
- target->value = value; \
- target->dist = 0; \
- target->state = CMC_ES_FILLED; \
- } \
- else \
- { \
- while (true) \
- { \
- pos++; \
- target = &(_set_->buffer[pos % _set_->capacity]); \
- \
- if (target->state == CMC_ES_EMPTY || \
- target->state == CMC_ES_DELETED) \
- { \
- target->value = value; \
- target->dist = pos - original_pos; \
- target->state = CMC_ES_FILLED; \
- \
- break; \
- } \
- else if (target->dist < pos - original_pos) \
- { \
- V tmp = target->value; \
- size_t tmp_dist = target->dist; \
- \
- target->value = value; \
- target->dist = pos - original_pos; \
- \
- value = tmp; \
- original_pos = pos - tmp_dist; \
- } \
- } \
- } \
- \
- _set_->count++; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->create) \
- _set_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_set_, V value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_entry *result = PFX##_impl_get_entry(_set_, value); \
- \
- if (result == NULL) \
- { \
- _set_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- result->value = (V){ 0 }; \
- result->dist = 0; \
- result->state = CMC_ES_DELETED; \
- \
- _set_->count--; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->delete) \
- _set_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_max(struct SNAME *_set_, V *value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- V max_value; \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- /* TODO turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V result = PFX##_iter_value(&iter); \
- size_t index = PFX##_iter_index(&iter); \
- \
- if (index == 0) \
- max_value = result; \
- else if (_set_->f_val->cmp(result, max_value) > 0) \
- max_value = result; \
- } \
- \
- if (value) \
- *value = max_value; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_min(struct SNAME *_set_, V *value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- V min_value; \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- /* TODO turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V result = PFX##_iter_value(&iter); \
- size_t index = PFX##_iter_index(&iter); \
- \
- if (index == 0) \
- min_value = result; \
- else if (_set_->f_val->cmp(result, min_value) < 0) \
- min_value = result; \
- } \
- \
- if (value) \
- *value = min_value; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_contains(struct SNAME *_set_, V value) \
- { \
- _set_->flag = cmc_flags.OK; \
- \
- bool result = PFX##_impl_get_entry(_set_, value) != NULL; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_set_) \
- { \
- return _set_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_set_) \
- { \
- return (double)_set_->capacity * _set_->load <= (double)_set_->count; \
- } \
- \
- size_t PFX##_count(struct SNAME *_set_) \
- { \
- return _set_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_set_) \
- { \
- return _set_->capacity; \
- } \
- \
- double PFX##_load(struct SNAME *_set_) \
- { \
- return _set_->load; \
- } \
- \
- int PFX##_flag(struct SNAME *_set_) \
- { \
- return _set_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_set_, size_t capacity) \
- { \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->capacity == capacity) \
- goto success; \
- \
- if (_set_->capacity > capacity / _set_->load) \
- goto success; \
- \
- /* Prevent integer overflow */ \
- if (capacity >= UINTMAX_MAX * _set_->load) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- /* Calculate required capacity based on the prime numbers */ \
- size_t theoretical_size = PFX##_impl_calculate_size(capacity); \
- \
- /* Not possible to shrink with current available prime numbers */ \
- if (theoretical_size < _set_->count / _set_->load) \
- { \
- _set_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- /* No callbacks since _new_set_ is just a temporary hashtable */ \
- struct SNAME *_new_set_ = PFX##_new_custom( \
- capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \
- \
- if (!_new_set_) \
- { \
- _set_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- /* TODO turn this into a normal loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- /* TODO check for error */ \
- PFX##_insert(_new_set_, value); \
- } \
- \
- /* Unlikely */ \
- if (_set_->count != _new_set_->count) \
- { \
- PFX##_free(_new_set_); \
- \
- _set_->flag = cmc_flags.ERROR; \
- return false; \
- } \
- \
- struct SNAME##_entry *tmp_b = _set_->buffer; \
- _set_->buffer = _new_set_->buffer; \
- _new_set_->buffer = tmp_b; \
- \
- size_t tmp_c = _set_->capacity; \
- _set_->capacity = _new_set_->capacity; \
- _new_set_->capacity = tmp_c; \
- \
- /* Prevent the set from freeing the data */ \
- _new_set_->f_val = &(struct SNAME##_fval){ NULL }; \
- \
- PFX##_free(_new_set_); \
- \
- success: \
- \
- if (_set_->callbacks && _set_->callbacks->resize) \
- _set_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_set_->capacity * _set_->load, _set_->load, \
- _set_->f_val, _set_->alloc, _set_->callbacks); \
- \
- if (!result) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_set_->f_val->cpy) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *scan = &(_set_->buffer[i]); \
- \
- if (scan->state != CMC_ES_EMPTY) \
- { \
- struct SNAME##_entry *target = &(result->buffer[i]); \
- \
- if (scan->state == CMC_ES_DELETED) \
- target->state = CMC_ES_DELETED; \
- else \
- { \
- target->state = scan->state; \
- target->dist = scan->dist; \
- \
- target->value = _set_->f_val->cpy(scan->value); \
- } \
- } \
- } \
- } \
- else \
- memcpy(result->buffer, _set_->buffer, \
- sizeof(struct SNAME##_entry) * _set_->capacity); \
- \
- result->count = _set_->count; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- _set1_->flag = cmc_flags.OK; \
- _set2_->flag = cmc_flags.OK; \
- \
- if (_set1_->count != _set2_->count) \
- return false; \
- \
- if (_set1_->count == 0) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- /* TODO optimize this loop */ \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- if (PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)) == NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_set_) \
- { \
- struct cmc_string str; \
- struct SNAME *s_ = _set_; \
- \
- int n = \
- snprintf(str.s, cmc_string_len, cmc_string_fmt_hashset, #SNAME, \
- #V, s_, s_->buffer, s_->capacity, s_->count, s_->load, \
- s_->flag, s_->f_val, s_->alloc, s_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_set_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _set_->capacity; i++) \
- { \
- struct SNAME##_entry *entry = &(_set_->buffer[i]); \
- \
- if (entry->state == CMC_ES_FILLED) \
- { \
- if (!_set_->f_val->str(fptr, entry->value)) \
- return false; \
- } \
- } \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- { \
- _set1_->flag = cmc_flags.ALLOC; \
- _set2_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- /* TODO turn this into a normal loop and check for errors */ \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- PFX##_insert(_set_r_, PFX##_iter_value(&iter1)); \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- PFX##_insert(_set_r_, PFX##_iter_value(&iter2)); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_intersection(struct SNAME *_set1_, \
- struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- { \
- _set1_->flag = cmc_flags.ALLOC; \
- _set2_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- struct SNAME *_set_A_ = \
- _set1_->count < _set2_->count ? _set1_ : _set2_; \
- struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set_A_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_entry(_set_B_, value) != NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- { \
- _set1_->flag = cmc_flags.ALLOC; \
- _set2_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_entry(_set2_, value) == NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_) \
- { \
- /* Callbacks are added later */ \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, \
- _set1_->alloc, NULL); \
- \
- if (!_set_r_) \
- { \
- _set1_->flag = cmc_flags.ALLOC; \
- _set2_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- V value = PFX##_iter_value(&iter1); \
- \
- if (PFX##_impl_get_entry(_set2_, value) == NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- V value = PFX##_iter_value(&iter2); \
- \
- if (PFX##_impl_get_entry(_set1_, value) == NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- _set_r_->callbacks = _set1_->callbacks; \
- \
- return _set_r_; \
- } \
- \
- /* Is _set1_ a subset of _set2_ ? */ \
- /* A set X is a subset of a set Y when: X <= Y */ \
- /* If X is a subset of Y, then Y is a superset of X */ \
- bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- _set1_->flag = cmc_flags.OK; \
- _set2_->flag = cmc_flags.OK; \
- \
- /* If the cardinality of _set1_ is greater than that of _set2_, */ \
- /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \
- if (_set1_->count > _set2_->count) \
- return false; \
- \
- /* The empty set is a subset of all sets */ \
- if (PFX##_empty(_set1_)) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_entry(_set2_, value) == NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- /* Is _set1_ a superset of _set2_ ? */ \
- /* A set X is a superset of a set Y when: X >= Y */ \
- /* If X is a superset of Y, then Y is a subset of X */ \
- bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- return PFX##_is_subset(_set2_, _set1_); \
- } \
- \
- /* Is _set1_ a proper subset of _set2_ ? */ \
- /* A set X is a proper subset of a set Y when: X < Y */ \
- /* If X is a proper subset of Y, then Y is a proper superset of X */ \
- bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- _set1_->flag = cmc_flags.OK; \
- _set2_->flag = cmc_flags.OK; \
- \
- /* If the cardinality of _set1_ is greater than or equal to that of */ \
- /* _set2_, then it is safe to say that _set1_ can't be a proper */ \
- /* subset of _set2_ */ \
- if (_set1_->count >= _set2_->count) \
- return false; \
- \
- if (PFX##_empty(_set1_)) \
- { \
- /* The empty set is a proper subset of all non-empty sets */ \
- if (!PFX##_empty(_set2_)) \
- return true; \
- /* The empty set is not a proper subset of itself (this is true */ \
- /* for any set) */ \
- else \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_entry(_set2_, value) == NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- /* Is _set1_ a proper superset of _set2_ ? */ \
- /* A set X is a proper superset of a set Y when: X > Y */ \
- /* If X is a proper superset of Y, then Y is a proper subset of X */ \
- bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- return PFX##_is_proper_subset(_set2_, _set1_); \
- } \
- \
- /* Is _set1_ a disjointset of _set2_ ? */ \
- /* A set X is a disjointset of a set Y if their intersection is empty, */ \
- /* that is, if there are no elements in common between the two */ \
- bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- _set1_->flag = cmc_flags.OK; \
- _set2_->flag = cmc_flags.OK; \
- \
- /* The intersection of an empty set with any other set will result */ \
- /* in an empty set */ \
- if (PFX##_empty(_set1_)) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_entry(_set2_, value) != NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i].state == CMC_ES_FILLED) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.first; \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1].state == CMC_ES_FILLED) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- } \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.index = 0; \
- iter.first = 0; \
- iter.last = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- { \
- for (size_t i = 0; i < target->capacity; i++) \
- { \
- if (target->buffer[i].state == CMC_ES_FILLED) \
- { \
- iter.first = i; \
- break; \
- } \
- } \
- \
- for (size_t i = target->capacity; i > 0; i--) \
- { \
- if (target->buffer[i - 1].state == CMC_ES_FILLED) \
- { \
- iter.last = i - 1; \
- break; \
- } \
- } \
- \
- iter.cursor = iter.last; \
- iter.index = target->count - 1; \
- } \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->first; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->last; \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
- \
- iter->index++; \
- \
- while (1) \
- { \
- iter->cursor++; \
- scan = &(iter->target->buffer[iter->cursor]); \
- \
- if (scan->state == CMC_ES_FILLED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- struct SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
- \
- iter->index--; \
- \
- while (1) \
- { \
- iter->cursor--; \
- scan = &(iter->target->buffer[iter->cursor]); \
- \
- if (scan->state == CMC_ES_FILLED) \
- break; \
- } \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor].value; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static struct SNAME##_entry *PFX##_impl_get_entry(struct SNAME *_set_, \
- V value) \
- { \
- size_t hash = _set_->f_val->hash(value); \
- size_t pos = hash % _set_->capacity; \
- \
- struct SNAME##_entry *target = &(_set_->buffer[pos]); \
- \
- while (target->state == CMC_ES_FILLED || \
- target->state == CMC_ES_DELETED) \
- { \
- if (_set_->f_val->cmp(target->value, value) == 0) \
- return target; \
- \
- pos++; \
- target = &(_set_->buffer[pos % _set_->capacity]); \
- } \
- \
- return NULL; \
- } \
- \
- static size_t PFX##_impl_calculate_size(size_t required) \
- { \
- const size_t count = \
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
- \
- if (cmc_hashtable_primes[count - 1] < required) \
- return required; \
- \
- size_t i = 0; \
- while (cmc_hashtable_primes[i] < required) \
- i++; \
- \
- return cmc_hashtable_primes[i]; \
+#define CMC_CMC_HASHSET_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value); \
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required); \
+\
+ struct SNAME *CMC_(PFX, _new)(size_t capacity, double load, struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(capacity, load, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(size_t capacity, double load, 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 || load <= 0 || load >= 1) \
+ return NULL; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * load) \
+ return NULL; \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_set_) \
+ return NULL; \
+\
+ _set_->buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \
+\
+ if (!_set_->buffer) \
+ { \
+ alloc->free(_set_); \
+ return NULL; \
+ } \
+\
+ _set_->count = 0; \
+ _set_->capacity = real_capacity; \
+ _set_->load = load; \
+ _set_->flag = CMC_FLAG_OK; \
+ _set_->f_val = f_val; \
+ _set_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_set_, callbacks); \
+\
+ return _set_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _set_) \
+ { \
+ if (_set_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ _set_->f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ memset(_set_->buffer, 0, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \
+\
+ _set_->count = 0; \
+ _set_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _set_) \
+ { \
+ if (_set_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ _set_->f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ _set_->alloc->free(_set_->buffer); \
+ _set_->alloc->free(_set_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _set_->alloc = &cmc_alloc_node_default; \
+ else \
+ _set_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_set_, callbacks); \
+\
+ _set_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_set_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_set_, _set_->capacity + 1)) \
+ return false; \
+ } \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set_, value) != NULL) \
+ { \
+ _set_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+\
+ size_t hash = _set_->f_val->hash(value); \
+ size_t original_pos = hash % _set_->capacity; \
+ size_t pos = original_pos; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \
+\
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
+ { \
+ target->value = value; \
+ target->dist = 0; \
+ target->state = CMC_ES_FILLED; \
+ } \
+ else \
+ { \
+ while (true) \
+ { \
+ pos++; \
+ target = &(_set_->buffer[pos % _set_->capacity]); \
+\
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED) \
+ { \
+ target->value = value; \
+ target->dist = pos - original_pos; \
+ target->state = CMC_ES_FILLED; \
+\
+ break; \
+ } \
+ else if (target->dist < pos - original_pos) \
+ { \
+ V tmp = target->value; \
+ size_t tmp_dist = target->dist; \
+\
+ target->value = value; \
+ target->dist = pos - original_pos; \
+\
+ value = tmp; \
+ original_pos = pos - tmp_dist; \
+ } \
+ } \
+ } \
+\
+ _set_->count++; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *result = CMC_(PFX, _impl_get_entry)(_set_, value); \
+\
+ if (result == NULL) \
+ { \
+ _set_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ result->value = (V){ 0 }; \
+ result->dist = 0; \
+ result->state = CMC_ES_DELETED; \
+\
+ _set_->count--; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ V max_val = (V) { 0 }; \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ /* TODO turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V result = CMC_(PFX, _iter_value)(&iter); \
+ size_t index = CMC_(PFX, _iter_index)(&iter); \
+\
+ if (index == 0) \
+ max_val = result; \
+ else if (_set_->f_val->cmp(result, max_val) > 0) \
+ max_val = result; \
+ } \
+\
+ if (value) \
+ *value = max_val; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ V min_val = (V) { 0 }; \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ /* TODO turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V result = CMC_(PFX, _iter_value)(&iter); \
+ size_t index = CMC_(PFX, _iter_index)(&iter); \
+\
+ if (index == 0) \
+ min_val = result; \
+ else if (_set_->f_val->cmp(result, min_val) < 0) \
+ min_val = result; \
+ } \
+\
+ if (value) \
+ *value = min_val; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \
+ { \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ bool result = CMC_(PFX, _impl_get_entry)(_set_, value) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _set_) \
+ { \
+ return _set_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _set_) \
+ { \
+ return (double)_set_->capacity * _set_->load <= (double)_set_->count; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _set_) \
+ { \
+ return _set_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _set_) \
+ { \
+ return _set_->capacity; \
+ } \
+\
+ double CMC_(PFX, _load)(struct SNAME * _set_) \
+ { \
+ return _set_->load; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _set_) \
+ { \
+ return _set_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _set_, size_t capacity) \
+ { \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ if (_set_->capacity == capacity) \
+ goto success; \
+\
+ if (_set_->capacity > capacity / _set_->load) \
+ goto success; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * _set_->load) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ /* Calculate required capacity based on the prime numbers */ \
+ size_t theoretical_size = CMC_(PFX, _impl_calculate_size)(capacity); \
+\
+ /* Not possible to shrink with current available prime numbers */ \
+ if (theoretical_size < _set_->count / _set_->load) \
+ { \
+ _set_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ /* No callbacks since _new_set_ is just a temporary hashtable */ \
+ struct SNAME *_new_set_ = CMC_(PFX, _new_custom)(capacity, _set_->load, _set_->f_val, _set_->alloc, NULL); \
+\
+ if (!_new_set_) \
+ { \
+ _set_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ /* TODO turn this into a normal loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ /* TODO check for error */ \
+ CMC_(PFX, _insert)(_new_set_, value); \
+ } \
+\
+ /* Unlikely */ \
+ if (_set_->count != _new_set_->count) \
+ { \
+ CMC_(PFX, _free)(_new_set_); \
+\
+ _set_->flag = CMC_FLAG_ERROR; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ENTRY(SNAME) *tmp_b = _set_->buffer; \
+ _set_->buffer = _new_set_->buffer; \
+ _new_set_->buffer = tmp_b; \
+\
+ size_t tmp_c = _set_->capacity; \
+ _set_->capacity = _new_set_->capacity; \
+ _new_set_->capacity = tmp_c; \
+\
+ /* Prevent the set from freeing the data */ \
+ _new_set_->f_val = &(struct CMC_DEF_FVAL(SNAME)){ NULL }; \
+\
+ CMC_(PFX, _free)(_new_set_); \
+\
+ success: \
+\
+ CMC_CALLBACKS_CALL(_set_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \
+ { \
+ struct SNAME *result = \
+ CMC_(PFX, _new_custom)(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \
+\
+ if (_set_->f_val->cpy) \
+ { \
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(_set_->buffer[i]); \
+\
+ if (scan->state != CMC_ES_EMPTY) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *target = &(result->buffer[i]); \
+\
+ if (scan->state == CMC_ES_DELETED) \
+ target->state = CMC_ES_DELETED; \
+ else \
+ { \
+ target->state = scan->state; \
+ target->dist = scan->dist; \
+\
+ target->value = _set_->f_val->cpy(scan->value); \
+ } \
+ } \
+ } \
+ } \
+ else \
+ memcpy(result->buffer, _set_->buffer, sizeof(struct CMC_DEF_ENTRY(SNAME)) * _set_->capacity); \
+\
+ result->count = _set_->count; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ _set1_->flag = CMC_FLAG_OK; \
+ _set2_->flag = CMC_FLAG_OK; \
+\
+ if (_set1_->count != _set2_->count) \
+ return false; \
+\
+ if (_set1_->count == 0) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ /* TODO optimize this loop */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ if (CMC_(PFX, _impl_get_entry)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ static struct CMC_DEF_ENTRY(SNAME) * CMC_(PFX, _impl_get_entry)(struct SNAME * _set_, V value) \
+ { \
+ size_t hash = _set_->f_val->hash(value); \
+ size_t pos = hash % _set_->capacity; \
+\
+ struct CMC_DEF_ENTRY(SNAME) *target = &(_set_->buffer[pos]); \
+\
+ while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED) \
+ { \
+ if (_set_->f_val->cmp(target->value, value) == 0) \
+ return target; \
+\
+ pos++; \
+ target = &(_set_->buffer[pos % _set_->capacity]); \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_calculate_size)(size_t required) \
+ { \
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]); \
+\
+ if (cmc_hashtable_primes[count - 1] < required) \
+ return required; \
+\
+ size_t i = 0; \
+ while (cmc_hashtable_primes[i] < required) \
+ i++; \
+\
+ return cmc_hashtable_primes[i]; \
}
-#endif /* CMC_HASHSET_H */
+#endif /* CMC_CMC_HASHSET_H */
diff --git a/src/cmc/heap.h b/src/cmc/heap.h
index 0effac2..aa654d6 100644
--- a/src/cmc/heap.h
+++ b/src/cmc/heap.h
@@ -1,5 +1,5 @@
/**
- * heap.h
+ * cmc/heap.h
*
* Creation Date: 25/03/2019
*
@@ -27,8 +27,8 @@
* - min/max : Accesses the min/max element from the heap
*/
-#ifndef CMC_HEAP_H
-#define CMC_HEAP_H
+#ifndef CMC_CMC_HEAP_H
+#define CMC_CMC_HEAP_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
@@ -38,750 +38,472 @@
/* -------------------------------------------------------------------------
* Heap Implementation
* ------------------------------------------------------------------------- */
+#include "../cor/heap.h"
+
/**
- * enum cmc_heap_order
+ * Core Heap implementation
*
- * Defines the two possible heaps:
- * - Max Heap has the greatest element at the top
- * - Min Heap has the smallest element at the top
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
*/
-enum cmc_heap_order
-{
- cmc_max_heap = 1,
- cmc_min_heap = -1
-};
+#define CMC_CMC_HEAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_HEAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_HEAP_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HEAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HEAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_HEAP_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_HEAP_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_HEAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_HEAP_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HEAP_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_HEAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_HEAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HEAP_CORE_HEADER(PARAMS) \
+ CMC_CMC_HEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_HEAP_CORE_SOURCE(PARAMS) \
+ CMC_CMC_HEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
/* -------------------------------------------------------------------------
- * Heap specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_heap = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "type:%s, "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks: %p}";
-
-#define CMC_GENERATE_HEAP(PFX, SNAME, V) \
- CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_HEAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_HEAP_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_HEAP_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Heap Structure */ \
+ 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
- \
- /* Heap Structure */ \
- 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 SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Heap Iterator */ \
- struct SNAME##_iter \
- { \
- /* 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; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, enum cmc_heap_order HO, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_heap_); \
- void PFX##_free(struct SNAME *_heap_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_heap_, V value); \
- bool PFX##_remove(struct SNAME *_heap_); \
- /* Element Access */ \
- V PFX##_peek(struct SNAME *_heap_); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_heap_, V value); \
- bool PFX##_empty(struct SNAME *_heap_); \
- bool PFX##_full(struct SNAME *_heap_); \
- size_t PFX##_count(struct SNAME *_heap_); \
- size_t PFX##_capacity(struct SNAME *_heap_); \
- int PFX##_flag(struct SNAME *_heap_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_heap_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_heap_); \
- bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_heap_); \
- bool PFX##_print(struct SNAME *_heap_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_HEAP_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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, 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_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- static void PFX##_impl_float_up(struct SNAME *_heap_, size_t index); \
- static void PFX##_impl_float_down(struct SNAME *_heap_, size_t index); \
- \
- struct SNAME *PFX##_new(size_t capacity, enum cmc_heap_order HO, \
- struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity < 1) \
- return NULL; \
- \
- if (HO != cmc_min_heap && HO != cmc_max_heap) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- 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_flags.OK; \
- _heap_->f_val = f_val; \
- _heap_->alloc = alloc; \
- _heap_->callbacks = NULL; \
- \
- return _heap_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, enum cmc_heap_order HO, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *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_flags.OK; \
- _heap_->f_val = f_val; \
- _heap_->alloc = alloc; \
- _heap_->callbacks = callbacks; \
- \
- return _heap_; \
- } \
- \
- void 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_flags.OK; \
- } \
- \
- void 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 PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _heap_->alloc = &cmc_alloc_node_default; \
- else \
- _heap_->alloc = alloc; \
- \
- _heap_->callbacks = callbacks; \
- \
- _heap_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_heap_, V value) \
- { \
- if (PFX##_full(_heap_)) \
- { \
- if (!PFX##_resize(_heap_, _heap_->count * 2)) \
- return false; \
- } \
- \
- _heap_->buffer[_heap_->count++] = value; \
- \
- if (_heap_->count > 1) \
- { \
- PFX##_impl_float_up(_heap_, _heap_->count - 1); \
- } \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->create) \
- _heap_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_heap_) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- _heap_->buffer[0] = _heap_->buffer[_heap_->count - 1]; \
- _heap_->buffer[_heap_->count - 1] = (V){ 0 }; \
- \
- _heap_->count--; \
- \
- PFX##_impl_float_down(_heap_, 0); \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->delete) \
- _heap_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- V PFX##_peek(struct SNAME *_heap_) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->read) \
- _heap_->callbacks->read(); \
- \
- return _heap_->buffer[0]; \
- } \
- \
- bool PFX##_contains(struct SNAME *_heap_, V value) \
- { \
- _heap_->flag = cmc_flags.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; \
- } \
- } \
- \
- if (_heap_->callbacks && _heap_->callbacks->read) \
- _heap_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_heap_) \
- { \
- return _heap_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_heap_) \
- { \
- return _heap_->count >= _heap_->capacity; \
- } \
- \
- size_t PFX##_count(struct SNAME *_heap_) \
- { \
- return _heap_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_heap_) \
- { \
- return _heap_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_heap_) \
- { \
- return _heap_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \
- { \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->capacity == capacity) \
- goto success; \
- \
- if (capacity < _heap_->count) \
- { \
- _heap_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- V *new_buffer = \
- _heap_->alloc->realloc(_heap_->buffer, sizeof(V) * capacity); \
- \
- if (!new_buffer) \
- { \
- _heap_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- /* TODO zero out new slots */ \
- \
- _heap_->buffer = new_buffer; \
- _heap_->capacity = capacity; \
- \
- success: \
- \
- if (_heap_->callbacks && _heap_->callbacks->resize) \
- _heap_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_heap_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, \
- _heap_->alloc, _heap_->callbacks); \
- \
- if (!result) \
- { \
- _heap_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- 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 \
+#define CMC_CMC_HEAP_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* 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_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_) \
- { \
- _heap1_->flag = cmc_flags.OK; \
- _heap2_->flag = cmc_flags.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; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_heap_) \
- { \
- struct cmc_string str; \
- struct SNAME *h_ = _heap_; \
- const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap"; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_heap, #SNAME, \
- #V, h_, h_->buffer, h_->capacity, h_->count, t, \
- h_->flag, h_->f_val, h_->alloc, h_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_heap_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _heap_->count; i++) \
- { \
- if (!_heap_->f_val->str(fptr, _heap_->buffer[i])) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- iter.cursor = target->count - 1; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *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 = PFX##_empty(iter->target); \
- \
- iter->cursor += steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *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 = 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 PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->cursor > index) \
- return PFX##_iter_rewind(iter, iter->cursor - index); \
- else if (iter->cursor < index) \
- return PFX##_iter_advance(iter, index - iter->cursor); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->cursor; \
- } \
- \
- static void 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 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; \
- } \
- \
+\
+ 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; \
- } \
+ if (C != index) \
+ { \
+ V tmp = _heap_->buffer[index]; \
+ _heap_->buffer[index] = _heap_->buffer[C]; \
+ _heap_->buffer[C] = tmp; \
+\
+ index = C; \
+ } \
+ else \
+ break; \
+ } \
}
-#endif /* CMC_HEAP_H */
+#endif /* CMC_CMC_HEAP_H */
diff --git a/src/cmc/intervalheap.h b/src/cmc/intervalheap.h
index 2b99a30..4094108 100644
--- a/src/cmc/intervalheap.h
+++ b/src/cmc/intervalheap.h
@@ -1,5 +1,5 @@
/**
- * intervalheap.h
+ * cmc/intervalheap.h
*
* Creation Date: 06/07/2019
*
@@ -18,1157 +18,883 @@
* - O(log n) - Remove Max
*/
-#ifndef CMC_INTERVALHEAP_H
-#define CMC_INTERVALHEAP_H
+#ifndef CMC_CMC_INTERVALHEAP_H
+#define CMC_CMC_INTERVALHEAP_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core IntervalHeap implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_INTERVALHEAP_CORE(ACCESS, FILE, PARAMS) \
+ CMC_(CMC_(CMC_CMC_INTERVALHEAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_INTERVALHEAP_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_INTERVALHEAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_INTERVALHEAP_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_INTERVALHEAP_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_INTERVALHEAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_INTERVALHEAP_CORE_HEADER(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_INTERVALHEAP_CORE_SOURCE(PARAMS) \
+ CMC_CMC_INTERVALHEAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * IntervalHeap specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_intervalheap = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "size:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_INTERVALHEAP(PFX, SNAME, V) \
- CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_INTERVALHEAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_INTERVALHEAP_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_INTERVALHEAP_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* IntervalHeap Structure */ \
+ 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_INTERVALHEAP_HEADER(PFX, SNAME, V) \
- \
- /* Heap Structure */ \
- 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 SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Heap Iterator */ \
- struct SNAME##_iter \
- { \
- /* 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; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_heap_); \
- void PFX##_free(struct SNAME *_heap_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_heap_, V value); \
- bool PFX##_remove_max(struct SNAME *_heap_); \
- bool PFX##_remove_min(struct SNAME *_heap_); \
- /* Collection Update */ \
- bool PFX##_update_max(struct SNAME *_heap_, V value); \
- bool PFX##_update_min(struct SNAME *_heap_, V value); \
- /* Element Access */ \
- V PFX##_max(struct SNAME *_heap_); \
- V PFX##_min(struct SNAME *_heap_); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_heap_, V value); \
- bool PFX##_empty(struct SNAME *_heap_); \
- bool PFX##_full(struct SNAME *_heap_); \
- size_t PFX##_count(struct SNAME *_heap_); \
- size_t PFX##_capacity(struct SNAME *_heap_); \
- int PFX##_flag(struct SNAME *_heap_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_heap_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_); \
- bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_heap_); \
- bool PFX##_print(struct SNAME *_heap_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_INTERVALHEAP_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_INTERVALHEAP_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- static void PFX##_impl_float_up_max(struct SNAME *_heap_); \
- static void PFX##_impl_float_up_min(struct SNAME *_heap_); \
- static void PFX##_impl_float_down_max(struct SNAME *_heap_); \
- static void PFX##_impl_float_down_min(struct SNAME *_heap_); \
- \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity == 0 || capacity == UINTMAX_MAX) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- 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_flags.OK; \
- _heap_->f_val = f_val; \
- _heap_->alloc = alloc; \
- _heap_->callbacks = NULL; \
- \
- return _heap_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *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_flags.OK; \
- _heap_->f_val = f_val; \
- _heap_->alloc = alloc; \
- _heap_->callbacks = callbacks; \
- \
- return _heap_; \
- } \
- \
- void 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_flags.OK; \
- } \
- \
- void 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 PFX##_customize(struct SNAME *_heap_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _heap_->alloc = &cmc_alloc_node_default; \
- else \
- _heap_->alloc = alloc; \
- \
- _heap_->callbacks = callbacks; \
- \
- _heap_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_heap_, V value) \
- { \
- if (PFX##_full(_heap_)) \
- { \
- if (!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_flags.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) \
- PFX##_impl_float_up_min(_heap_); \
- else if (_heap_->f_val->cmp((*parent)[1], value) < 0) \
- PFX##_impl_float_up_max(_heap_); \
- /* else no float up required */ \
- } \
- \
- if (_heap_->callbacks && _heap_->callbacks->create) \
- _heap_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove_max(struct SNAME *_heap_) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.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 */ \
- PFX##_impl_float_down_max(_heap_); \
- \
- success: \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->delete) \
- _heap_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_remove_min(struct SNAME *_heap_) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.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 */ \
- PFX##_impl_float_down_min(_heap_); \
- \
- success: \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->delete) \
- _heap_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_update_max(struct SNAME *_heap_, V value) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.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; \
- \
- PFX##_impl_float_down_max(_heap_); \
- } \
- else \
- { \
- /* Update Max element and float it down */ \
- _heap_->buffer[0][1] = value; \
- \
- PFX##_impl_float_down_max(_heap_); \
- } \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->update) \
- _heap_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_update_min(struct SNAME *_heap_, V value) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- if (_heap_->count == 1) \
- { \
- _heap_->buffer[0][0] = value; \
- } \
- else if (_heap_->f_val->cmp(value, _heap_->buffer[0][1]) > 0) \
- { \
+#define CMC_CMC_INTERVALHEAP_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* 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; \
- \
- PFX##_impl_float_down_min(_heap_); \
- } \
- else \
- { \
- /* Update Min element and float it down */ \
- _heap_->buffer[0][0] = value; \
- \
- PFX##_impl_float_down_min(_heap_); \
- } \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->update) \
- _heap_->callbacks->update(); \
- \
- return true; \
- } \
- \
- V PFX##_max(struct SNAME *_heap_) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->read) \
- _heap_->callbacks->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 PFX##_min(struct SNAME *_heap_) \
- { \
- if (PFX##_empty(_heap_)) \
- { \
- _heap_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->read) \
- _heap_->callbacks->read(); \
- \
- return _heap_->buffer[0][0]; \
- } \
- \
- bool PFX##_contains(struct SNAME *_heap_, V value) \
- { \
- _heap_->flag = cmc_flags.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; \
- } \
- } \
- \
- if (_heap_->callbacks && _heap_->callbacks->read) \
- _heap_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_heap_) \
- { \
- return _heap_->count == 0; \
- } \
- \
- bool 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 PFX##_count(struct SNAME *_heap_) \
- { \
- return _heap_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_heap_) \
- { \
- return _heap_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_heap_) \
- { \
- return _heap_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_heap_, size_t capacity) \
- { \
- if (_heap_->capacity == capacity) \
- goto success; \
- \
- if (capacity < _heap_->count) \
- { \
- _heap_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- /* Prevent overflow */ \
- if (capacity == UINTMAX_MAX) \
- { \
- _heap_->flag = cmc_flags.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_flags.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_flags.OK; \
- \
- if (_heap_->callbacks && _heap_->callbacks->resize) \
- _heap_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_heap_) \
- { \
- struct SNAME *result = _heap_->alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!result) \
- { \
- _heap_->flag = cmc_flags.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_flags.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_flags.OK; \
- result->f_val = _heap_->f_val; \
- result->alloc = _heap_->alloc; \
- result->callbacks = _heap_->callbacks; \
- \
- _heap_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_heap1_, struct SNAME *_heap2_) \
- { \
- _heap1_->flag = cmc_flags.OK; \
- _heap2_->flag = cmc_flags.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; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_heap_) \
- { \
- struct cmc_string str; \
- struct SNAME *h_ = _heap_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_intervalheap, \
- #SNAME, #V, h_, h_->buffer, h_->capacity, h_->size, \
- h_->count, h_->flag, h_->f_val, h_->alloc, \
- h_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_heap_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _heap_->count; i++) \
- { \
- if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2])) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- iter.cursor = target->count - 1; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *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 = PFX##_empty(iter->target); \
- \
- iter->cursor += steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *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 = 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 PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->cursor > index) \
- return PFX##_iter_rewind(iter, iter->cursor - index); \
- else if (iter->cursor < index) \
- return PFX##_iter_advance(iter, index - iter->cursor); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor / 2][iter->cursor % 2]; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->cursor; \
- } \
- \
- static void 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 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 PFX##_impl_float_down_max(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]); \
- \
- /* 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 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; \
- } \
+ /* 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 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]); \
+\
+ /* 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; \
+ } \
}
-#endif /* CMC_INTERVALHEAP_H */
+#endif /* CMC_CMC_INTERVALHEAP_H */
diff --git a/src/cmc/linkedlist.h b/src/cmc/linkedlist.h
index 02d93fc..88479a0 100644
--- a/src/cmc/linkedlist.h
+++ b/src/cmc/linkedlist.h
@@ -1,5 +1,5 @@
/**
- * linkedlist.h
+ * cmc/linkedlist.h
*
* Creation Date: 22/03/2019
*
@@ -25,1099 +25,602 @@
* and tail points to the last.
*/
-#ifndef CMC_LINKEDLIST_H
-#define CMC_LINKEDLIST_H
+#ifndef CMC_CMC_LINKEDLIST_H
+#define CMC_CMC_LINKEDLIST_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core LinkedList implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_LINKEDLIST_CORE(ACCESS, FILE, PARAMS) \
+ CMC_(CMC_(CMC_CMC_LINKEDLIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_LINKEDLIST_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_LINKEDLIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_LINKEDLIST_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_LINKEDLIST_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_LINKEDLIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_LINKEDLIST_CORE_HEADER(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_LINKEDLIST_CORE_SOURCE(PARAMS) \
+ CMC_CMC_LINKEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * LinkedList specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_linkedlist = "struct %s<%s> "
- "at %p { "
- "count:%" PRIuMAX ", "
- "head:%p, "
- "tail:%p, "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_LINKEDLIST(PFX, SNAME, V) \
- CMC_GENERATE_LINKEDLIST_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_LINKEDLIST_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_LINKEDLIST_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_LINKEDLIST_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_LINKEDLIST_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_LINKEDLIST_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_LINKEDLIST_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Linked List Structure */ \
+ struct SNAME \
+ { \
+ /* First node in the list */ \
+ struct CMC_DEF_NODE(SNAME) * head; \
+\
+ /* Last node in the list */ \
+ struct CMC_DEF_NODE(SNAME) * tail; \
+\
+ /* Current amount of elements in the list */ \
+ 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; \
+ }; \
+\
+ /* Doubly-linked list node */ \
+ struct CMC_DEF_NODE(SNAME) \
+ { \
+ /* Node's value */ \
+ V value; \
+\
+ /* Pointer to the next node on the linked list */ \
+ struct CMC_DEF_NODE(SNAME) * next; \
+\
+ /* Pointer to the previous node on the linked list */ \
+ struct CMC_DEF_NODE(SNAME) * prev; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_LINKEDLIST_HEADER(PFX, SNAME, V) \
- \
- /* Linked List Structure */ \
- struct SNAME \
- { \
- /* First node in the list */ \
- struct SNAME##_node *head; \
- \
- /* Last node in the list */ \
- struct SNAME##_node *tail; \
- \
- /* Current amount of elements in the list */ \
- size_t count; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Doubly-linked list node */ \
- struct SNAME##_node \
- { \
- /* Node's value */ \
- V value; \
- \
- /* Pointer to the next node on the linked list */ \
- struct SNAME##_node *next; \
- \
- /* Pointer to the previous node on the linked list */ \
- struct SNAME##_node *prev; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Linked List Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target Linked List */ \
- struct SNAME *target; \
- \
- /* Cursor's current node */ \
- struct SNAME##_node *cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_list_); \
- void PFX##_free(struct SNAME *_list_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_push_front(struct SNAME *_list_, V value); \
- bool PFX##_push_at(struct SNAME *_list_, V value, size_t index); \
- bool PFX##_push_back(struct SNAME *_list_, V value); \
- bool PFX##_pop_front(struct SNAME *_list_); \
- bool PFX##_pop_at(struct SNAME *_list_, size_t index); \
- bool PFX##_pop_back(struct SNAME *_list_); \
- /* Element Access */ \
- V PFX##_front(struct SNAME *_list_); \
- V PFX##_get(struct SNAME *_list_, size_t index); \
- V *PFX##_get_ref(struct SNAME *_list_, size_t index); \
- V PFX##_back(struct SNAME *_list_); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_list_, V value); \
- bool PFX##_empty(struct SNAME *_list_); \
- size_t PFX##_count(struct SNAME *_list_); \
- int PFX##_flag(struct SNAME *_list_); \
- /* Collection Utility */ \
- struct SNAME *PFX##_copy_of(struct SNAME *_list_); \
- bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_list_); \
- bool PFX##_print(struct SNAME *_list_, FILE *fptr); \
- \
- /* Node Related Functions */ \
- /* Node Allocation and Deallocation */ \
- struct SNAME##_node *PFX##_new_node(struct SNAME *_list_, V value); \
- void PFX##_free_node(struct SNAME *_list_, struct SNAME##_node *_node_); \
- /* Node Access Relative to a Linked List */ \
- struct SNAME##_node *PFX##_head(struct SNAME *_list_); \
- struct SNAME##_node *PFX##_get_node(struct SNAME *_list_, size_t index); \
- struct SNAME##_node *PFX##_tail(struct SNAME *_list_); \
- /* Input and Output Relative to a Node */ \
- bool PFX##_add_next(struct SNAME *_owner_, struct SNAME##_node *_node_, \
- V value); \
- bool PFX##_add_prev(struct SNAME *_owner_, struct SNAME##_node *_node_, \
- V value); \
- bool PFX##_del_next(struct SNAME *_owner_, struct SNAME##_node *_node_); \
- bool PFX##_del_curr(struct SNAME *_owner_, struct SNAME##_node *_node_); \
- bool PFX##_del_prev(struct SNAME *_owner_, struct SNAME##_node *_node_); \
- /* Node Access Relative to a Linked List Node */ \
- struct SNAME##_node *PFX##_next_node(struct SNAME##_node *_node_); \
- struct SNAME##_node *PFX##_prev_node(struct SNAME##_node *_node_); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter); \
- struct SNAME##_node *PFX##_iter_node(struct SNAME##_iter *iter);
+#define CMC_CMC_LINKEDLIST_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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)(struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _list_); \
+ void CMC_(PFX, _free)(struct SNAME * _list_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \
+ bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \
+ bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \
+ bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \
+ /* Element Access */ \
+ V CMC_(PFX, _front)(struct SNAME * _list_); \
+ V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \
+ V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \
+ V CMC_(PFX, _back)(struct SNAME * _list_); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _list_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _list_); \
+ int CMC_(PFX, _flag)(struct SNAME * _list_); \
+ /* Collection Utility */ \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_LINKEDLIST_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- /* None */ \
- \
- struct SNAME *PFX##_new(struct SNAME##_fval *f_val) \
- { \
- if (!f_val) \
- return NULL; \
- \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_list_) \
- return NULL; \
- \
- _list_->count = 0; \
- _list_->head = NULL; \
- _list_->tail = NULL; \
- _list_->flag = cmc_flags.OK; \
- _list_->f_val = f_val; \
- _list_->alloc = alloc; \
- _list_->callbacks = NULL; \
- \
- return _list_; \
- } \
- \
- struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_list_) \
- return NULL; \
- \
- _list_->count = 0; \
- _list_->head = NULL; \
- _list_->tail = NULL; \
- _list_->flag = cmc_flags.OK; \
- _list_->f_val = f_val; \
- _list_->alloc = alloc; \
- _list_->callbacks = callbacks; \
- \
- return _list_; \
- } \
- \
- void PFX##_clear(struct SNAME *_list_) \
- { \
- struct SNAME##_node *scan = _list_->head; \
- \
- while (_list_->head != NULL) \
- { \
- _list_->head = _list_->head->next; \
- \
- if (_list_->f_val->free) \
- { \
- _list_->f_val->free(scan->value); \
- } \
- \
- _list_->alloc->free(scan); \
- \
- scan = _list_->head; \
- } \
- \
- _list_->count = 0; \
- _list_->head = NULL; \
- _list_->tail = NULL; \
- _list_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_list_) \
- { \
- PFX##_clear(_list_); \
- \
- _list_->alloc->free(_list_); \
- } \
- \
- void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _list_->alloc = &cmc_alloc_node_default; \
- else \
- _list_->alloc = alloc; \
- \
- _list_->callbacks = callbacks; \
- \
- _list_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_push_front(struct SNAME *_list_, V value) \
- { \
- struct SNAME##_node *_node_ = PFX##_new_node(_list_, value); \
- \
- if (!_node_) \
- return false; \
- \
- if (PFX##_empty(_list_)) \
- { \
- _list_->head = _node_; \
- _list_->tail = _node_; \
- } \
- else \
- { \
- _node_->next = _list_->head; \
- _list_->head->prev = _node_; \
- _list_->head = _node_; \
- } \
- \
- _list_->count++; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_push_at(struct SNAME *_list_, V value, size_t index) \
- { \
- if (index > _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- if (index == 0) \
- { \
- return PFX##_push_front(_list_, value); \
- } \
- else if (index == _list_->count) \
- { \
- return PFX##_push_back(_list_, value); \
- } \
- \
- struct SNAME##_node *_node_ = PFX##_new_node(_list_, value); \
- \
- if (!_node_) \
- return false; \
- \
- struct SNAME##_node *scan = PFX##_get_node(_list_, index - 1); \
- \
- _node_->next = scan->next; \
- _node_->prev = scan; \
- _node_->next->prev = _node_; \
- _node_->prev->next = _node_; \
- \
- _list_->count++; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_push_back(struct SNAME *_list_, V value) \
- { \
- struct SNAME##_node *_node_ = PFX##_new_node(_list_, value); \
- \
- if (!_node_) \
- return false; \
- \
- if (PFX##_empty(_list_)) \
- { \
- _list_->head = _node_; \
- _list_->tail = _node_; \
- } \
- else \
- { \
- _node_->prev = _list_->tail; \
- _list_->tail->next = _node_; \
- _list_->tail = _node_; \
- } \
- \
- _list_->count++; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_front(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *_node_ = _list_->head; \
- _list_->head = _list_->head->next; \
- \
- _list_->alloc->free(_node_); \
- \
- if (_list_->head == NULL) \
- _list_->tail = NULL; \
- else \
- _list_->head->prev = NULL; \
- \
- _list_->count--; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_at(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- if (index == 0) \
- { \
- return PFX##_pop_front(_list_); \
- } \
- else if (index == _list_->count - 1) \
- { \
- return PFX##_pop_back(_list_); \
- } \
- \
- struct SNAME##_node *_node_ = PFX##_get_node(_list_, index); \
- \
- if (!_node_) \
- return false; \
- \
- _node_->next->prev = _node_->prev; \
- _node_->prev->next = _node_->next; \
- \
- _list_->alloc->free(_node_); \
- \
- _list_->count--; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_back(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *_node_ = _list_->tail; \
- _list_->tail = _list_->tail->prev; \
- \
- _list_->alloc->free(_node_); \
- \
- if (_list_->tail == NULL) \
- _list_->head = NULL; \
- else \
- _list_->tail->next = NULL; \
- \
- _list_->count--; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- V PFX##_front(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->head->value; \
- } \
- \
- V PFX##_get(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return (V){ 0 }; \
- } \
- \
- struct SNAME##_node *scan = PFX##_get_node(_list_, index); \
- \
- if (scan == NULL) \
- return (V){ 0 }; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return scan->value; \
- } \
- \
- V *PFX##_get_ref(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return NULL; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return NULL; \
- } \
- \
- struct SNAME##_node *scan = PFX##_get_node(_list_, index); \
- \
- if (scan == NULL) \
- return NULL; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return &(scan->value); \
- } \
- \
- V PFX##_back(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->tail->value; \
- } \
- \
- bool PFX##_contains(struct SNAME *_list_, V value) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- bool result = false; \
- \
- struct SNAME##_node *scan = _list_->head; \
- \
- while (scan != NULL) \
- { \
- if (_list_->f_val->cmp(scan->value, value) == 0) \
- { \
- result = true; \
- break; \
- } \
- \
- scan = scan->next; \
- } \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_list_) \
- { \
- return _list_->count == 0; \
- } \
- \
- size_t PFX##_count(struct SNAME *_list_) \
- { \
- return _list_->count; \
- } \
- \
- int PFX##_flag(struct SNAME *_list_) \
- { \
- return _list_->flag; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_list_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks); \
- \
- if (!result) \
- return NULL; \
- \
- struct SNAME##_node *scan = _list_->head; \
- \
- while (scan != NULL) \
- { \
- /* This allocation should never fail since it might not be */ \
- /* possible to recover from it. That is why it isn't checked */ \
- struct SNAME##_node *new_node; \
- \
- if (_list_->f_val->cpy) \
- new_node = \
- PFX##_new_node(_list_, _list_->f_val->cpy(scan->value)); \
- else \
- new_node = PFX##_new_node(_list_, scan->value); \
- \
- if (!result->head) \
- { \
- result->head = new_node; \
- result->tail = new_node; \
- } \
- else \
- { \
- new_node->prev = result->tail; \
- result->tail->next = new_node; \
- result->tail = new_node; \
- } \
- \
- scan = scan->next; \
- } \
- \
- result->count = _list_->count; \
- \
- _list_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
- { \
- _list1_->flag = cmc_flags.OK; \
- _list2_->flag = cmc_flags.OK; \
- \
- if (_list1_->count != _list2_->count) \
- return false; \
- \
- struct SNAME##_node *scan1 = _list1_->head; \
- struct SNAME##_node *scan2 = _list2_->head; \
- \
- while (scan1 != NULL && scan2 != NULL) \
- { \
- if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \
- return false; \
- \
- scan1 = scan1->next; \
- scan2 = scan2->next; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_list_) \
- { \
- struct cmc_string str; \
- struct SNAME *l_ = _list_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_linkedlist, \
- #SNAME, #V, l_, l_->count, l_->head, l_->tail, \
- l_->flag, l_->f_val, l_->alloc, l_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_list_, FILE *fptr) \
- { \
- struct SNAME##_node *scan = _list_->head; \
- \
- while (scan != NULL) \
- { \
- if (!_list_->f_val->str(fptr, scan->value)) \
- return false; \
- \
- scan = scan->next; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_node *PFX##_new_node(struct SNAME *_list_, V value) \
- { \
- struct SNAME##_node *_node_ = \
- _list_->alloc->malloc(sizeof(struct SNAME##_node)); \
- \
- if (!_node_) \
- { \
- _list_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- _node_->value = value; \
- _node_->next = NULL; \
- _node_->prev = NULL; \
- \
- return _node_; \
- } \
- \
- void PFX##_free_node(struct SNAME *_list_, struct SNAME##_node *_node_) \
- { \
- _list_->alloc->free(_node_); \
- } \
- \
- struct SNAME##_node *PFX##_head(struct SNAME *_list_) \
- { \
- return _list_->head; \
- } \
- \
- struct SNAME##_node *PFX##_get_node(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return NULL; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return NULL; \
- } \
- \
- struct SNAME##_node *_node_ = NULL; \
- \
- if (index <= _list_->count / 2) \
- { \
- _node_ = _list_->head; \
- for (size_t i = 0; i < index; i++) \
- { \
- _node_ = _node_->next; \
- } \
- } \
- else \
- { \
- _node_ = _list_->tail; \
- for (size_t i = _list_->count - 1; i > index; i--) \
- { \
- _node_ = _node_->prev; \
- } \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- return _node_; \
- } \
- \
- struct SNAME##_node *PFX##_tail(struct SNAME *_list_) \
- { \
- return _list_->tail; \
- } \
- \
- bool PFX##_add_next(struct SNAME *_owner_, struct SNAME##_node *_node_, \
- V value) \
- { \
- struct SNAME##_node *new_node = PFX##_new_node(_owner_, value); \
- \
- if (!new_node) \
- return false; \
- \
- new_node->next = _node_->next; \
- \
- if (_node_->next != NULL) \
- _node_->next->prev = new_node; \
- else \
- _owner_->tail = new_node; \
- \
- new_node->prev = _node_; \
- _node_->next = new_node; \
- \
- _owner_->count++; \
- _owner_->flag = cmc_flags.OK; \
- \
- return true; \
- } \
- \
- bool PFX##_add_prev(struct SNAME *_owner_, struct SNAME##_node *_node_, \
- V value) \
- { \
- struct SNAME##_node *new_node = PFX##_new_node(_owner_, value); \
- \
- if (!new_node) \
- return false; \
- \
- new_node->prev = _node_->prev; \
- \
- if (_node_->prev != NULL) \
- _node_->prev->next = new_node; \
- else \
- _owner_->head = new_node; \
- \
- new_node->next = _node_; \
- _node_->prev = new_node; \
- \
- _owner_->count++; \
- _owner_->flag = cmc_flags.OK; \
- \
- return true; \
- } \
- \
- bool PFX##_del_next(struct SNAME *_owner_, struct SNAME##_node *_node_) \
- { \
- if (_node_->next == NULL) \
- { \
- _owner_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- struct SNAME##_node *tmp = _node_->next; \
- \
- _node_->next = _node_->next->next; \
- \
- if (tmp->next != NULL) \
- tmp->next->prev = _node_; \
- else \
- _owner_->tail = _node_; \
- \
- _owner_->alloc->free(tmp); \
- \
- _owner_->count--; \
- _owner_->flag = cmc_flags.OK; \
- \
- return true; \
- } \
- \
- bool PFX##_del_curr(struct SNAME *_owner_, struct SNAME##_node *_node_) \
- { \
- if (_node_->prev != NULL) \
- _node_->prev->next = _node_->next; \
- else \
- _owner_->head = _node_->next; \
- \
- if (_node_->next != NULL) \
- _node_->next->prev = _node_->prev; \
- else \
- _owner_->tail = _node_->prev; \
- \
- _owner_->alloc->free(_node_); \
- \
- _owner_->count--; \
- _owner_->flag = cmc_flags.OK; \
- \
- return true; \
- } \
- \
- bool PFX##_del_prev(struct SNAME *_owner_, struct SNAME##_node *_node_) \
- { \
- if (_node_->prev == NULL) \
- { \
- _owner_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- struct SNAME##_node *tmp = _node_->prev; \
- \
- _node_->prev = _node_->prev->prev; \
- \
- if (tmp->prev != NULL) \
- tmp->prev->next = _node_; \
- else \
- _owner_->head = _node_; \
- \
- _owner_->alloc->free(tmp); \
- \
- _owner_->count--; \
- _owner_->flag = cmc_flags.OK; \
- \
- return true; \
- } \
- \
- struct SNAME##_node *PFX##_next_node(struct SNAME##_node *_node_) \
- { \
- return _node_->next; \
- } \
- \
- struct SNAME##_node *PFX##_prev_node(struct SNAME##_node *_node_) \
- { \
- return _node_->prev; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->head; \
- iter.index = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->tail; \
- iter.index = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- iter.index = target->count - 1; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->head; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->tail; \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor->next == NULL) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor = iter->cursor->next; \
- iter->index++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor->prev == NULL) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor = iter->cursor->prev; \
- iter->index--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor->next == NULL) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->index += steps; \
- \
- for (size_t i = 0; i < steps; i++) \
- iter->cursor = iter->cursor->next; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor->prev == NULL) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->index -= steps; \
- \
- for (size_t i = 0; i < steps; i++) \
- iter->cursor = iter->cursor->prev; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->cursor->value; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->cursor->value); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- struct SNAME##_node *PFX##_iter_node(struct SNAME##_iter *iter) \
- { \
- return iter->cursor; \
+#define CMC_CMC_LINKEDLIST_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ /* None */ \
+\
+ struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_list_) \
+ return NULL; \
+\
+ _list_->count = 0; \
+ _list_->head = NULL; \
+ _list_->tail = NULL; \
+ _list_->flag = CMC_FLAG_OK; \
+ _list_->f_val = f_val; \
+ _list_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_list_, callbacks); \
+\
+ return _list_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _list_) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \
+\
+ while (_list_->head != NULL) \
+ { \
+ _list_->head = _list_->head->next; \
+\
+ if (_list_->f_val->free) \
+ { \
+ _list_->f_val->free(scan->value); \
+ } \
+\
+ _list_->alloc->free(scan); \
+\
+ scan = _list_->head; \
+ } \
+\
+ _list_->count = 0; \
+ _list_->head = NULL; \
+ _list_->tail = NULL; \
+ _list_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _list_) \
+ { \
+ CMC_(PFX, _clear)(_list_); \
+\
+ _list_->alloc->free(_list_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _list_->alloc = &cmc_alloc_node_default; \
+ else \
+ _list_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_list_, callbacks); \
+\
+ _list_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \
+\
+ if (!_node_) \
+ return false; \
+\
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->head = _node_; \
+ _list_->tail = _node_; \
+ } \
+ else \
+ { \
+ _node_->next = _list_->head; \
+ _list_->head->prev = _node_; \
+ _list_->head = _node_; \
+ } \
+\
+ _list_->count++; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \
+ { \
+ if (index > _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ if (index == 0) \
+ { \
+ return CMC_(PFX, _push_front)(_list_, value); \
+ } \
+ else if (index == _list_->count) \
+ { \
+ return CMC_(PFX, _push_back)(_list_, value); \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \
+\
+ if (!_node_) \
+ return false; \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index - 1); \
+\
+ _node_->next = scan->next; \
+ _node_->prev = scan; \
+ _node_->next->prev = _node_; \
+ _node_->prev->next = _node_; \
+\
+ _list_->count++; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _new_node)(_list_, value); \
+\
+ if (!_node_) \
+ return false; \
+\
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->head = _node_; \
+ _list_->tail = _node_; \
+ } \
+ else \
+ { \
+ _node_->prev = _list_->tail; \
+ _list_->tail->next = _node_; \
+ _list_->tail = _node_; \
+ } \
+\
+ _list_->count++; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *_node_ = _list_->head; \
+ _list_->head = _list_->head->next; \
+\
+ _list_->alloc->free(_node_); \
+\
+ if (_list_->head == NULL) \
+ _list_->tail = NULL; \
+ else \
+ _list_->head->prev = NULL; \
+\
+ _list_->count--; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ if (index == 0) \
+ { \
+ return CMC_(PFX, _pop_front)(_list_); \
+ } \
+ else if (index == _list_->count - 1) \
+ { \
+ return CMC_(PFX, _pop_back)(_list_); \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *_node_ = CMC_(PFX, _get_node)(_list_, index); \
+\
+ if (!_node_) \
+ return false; \
+\
+ _node_->next->prev = _node_->prev; \
+ _node_->prev->next = _node_->next; \
+\
+ _list_->alloc->free(_node_); \
+\
+ _list_->count--; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *_node_ = _list_->tail; \
+ _list_->tail = _list_->tail->prev; \
+\
+ _list_->alloc->free(_node_); \
+\
+ if (_list_->tail == NULL) \
+ _list_->head = NULL; \
+ else \
+ _list_->tail->next = NULL; \
+\
+ _list_->count--; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _front)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->head->value; \
+ } \
+\
+ V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return (V){ 0 }; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index); \
+\
+ if (scan == NULL) \
+ return (V){ 0 }; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return scan->value; \
+ } \
+\
+ V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return NULL; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = CMC_(PFX, _get_node)(_list_, index); \
+\
+ if (scan == NULL) \
+ return NULL; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return &(scan->value); \
+ } \
+\
+ V CMC_(PFX, _back)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->tail->value; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ bool result = false; \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \
+\
+ while (scan != NULL) \
+ { \
+ if (_list_->f_val->cmp(scan->value, value) == 0) \
+ { \
+ result = true; \
+ break; \
+ } \
+\
+ scan = scan->next; \
+ } \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _list_) \
+ { \
+ return _list_->count == 0; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _list_) \
+ { \
+ return _list_->count; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _list_) \
+ { \
+ return _list_->flag; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_list_->f_val, _list_->alloc, NULL); \
+\
+ if (!result) \
+ return NULL; \
+\
+ CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \
+\
+ while (scan != NULL) \
+ { \
+ /* This allocation should never fail since it might not be */ \
+ /* possible to recover from it. That is why it isn't checked */ \
+ struct CMC_DEF_NODE(SNAME) * new_node; \
+\
+ if (_list_->f_val->cpy) \
+ new_node = CMC_(PFX, _new_node)(_list_, _list_->f_val->cpy(scan->value)); \
+ else \
+ new_node = CMC_(PFX, _new_node)(_list_, scan->value); \
+\
+ if (!result->head) \
+ { \
+ result->head = new_node; \
+ result->tail = new_node; \
+ } \
+ else \
+ { \
+ new_node->prev = result->tail; \
+ result->tail->next = new_node; \
+ result->tail = new_node; \
+ } \
+\
+ scan = scan->next; \
+ } \
+\
+ result->count = _list_->count; \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \
+ { \
+ _list1_->flag = CMC_FLAG_OK; \
+ _list2_->flag = CMC_FLAG_OK; \
+\
+ if (_list1_->count != _list2_->count) \
+ return false; \
+\
+ struct CMC_DEF_NODE(SNAME) *scan1 = _list1_->head; \
+ struct CMC_DEF_NODE(SNAME) *scan2 = _list2_->head; \
+\
+ while (scan1 != NULL && scan2 != NULL) \
+ { \
+ if (_list1_->f_val->cmp(scan1->value, scan2->value) != 0) \
+ return false; \
+\
+ scan1 = scan1->next; \
+ scan2 = scan2->next; \
+ } \
+\
+ return true; \
}
-#endif /* CMC_LINKEDLIST_H */
+#endif /* CMC_CMC_LINKEDLIST_H */
diff --git a/src/cmc/list.h b/src/cmc/list.h
index aa7ff78..c98fe87 100644
--- a/src/cmc/list.h
+++ b/src/cmc/list.h
@@ -1,5 +1,5 @@
/**
- * list.h
+ * cmc/list.h
*
* Creation Date: 12/02/2019
*
@@ -40,1026 +40,580 @@
* list.
*/
-#ifndef CMC_LIST_H
-#define CMC_LIST_H
+#ifndef CMC_CMC_LIST_H
+#define CMC_CMC_LIST_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core List implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_LIST_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_LIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_LIST_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_LIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_LIST_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_LIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_LIST_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_LIST_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_LIST_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_LIST_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_LIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_LIST_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_LIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_LIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_LIST_CORE_HEADER(PARAMS) \
+ CMC_CMC_LIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_LIST_CORE_SOURCE(PARAMS) \
+ CMC_CMC_LIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * List specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_list = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_LIST(PFX, SNAME, V) \
- CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_LIST_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_LIST_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_LIST_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_LIST_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* List Structure */ \
+ struct SNAME \
+ { \
+ /* Dynamic array of elements */ \
+ V *buffer; \
+\
+ /* Current array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of elements */ \
+ 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \
- \
- /* List Structure */ \
- struct SNAME \
- { \
- /* Dynamic array of elements */ \
- V *buffer; \
- \
- /* Current array capacity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* List Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target list */ \
- 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; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_list_); \
- void PFX##_free(struct SNAME *_list_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_push_front(struct SNAME *_list_, V value); \
- bool PFX##_push_at(struct SNAME *_list_, V value, size_t index); \
- bool PFX##_push_back(struct SNAME *_list_, V value); \
- bool PFX##_pop_front(struct SNAME *_list_); \
- bool PFX##_pop_at(struct SNAME *_list_, size_t index); \
- bool PFX##_pop_back(struct SNAME *_list_); \
- /* Collection Sequence Input and Output */ \
- bool PFX##_seq_push_front(struct SNAME *_list_, V *values, size_t size); \
- bool PFX##_seq_push_at(struct SNAME *_list_, V *values, size_t size, \
- size_t index); \
- bool PFX##_seq_push_back(struct SNAME *_list_, V *values, size_t size); \
- bool PFX##_seq_pop_at(struct SNAME *_list_, size_t from, size_t to); \
- struct SNAME *PFX##_seq_sublist(struct SNAME *_list_, size_t from, \
- size_t to); \
- /* Element Access */ \
- V PFX##_front(struct SNAME *_list_); \
- V PFX##_get(struct SNAME *_list_, size_t index); \
- V *PFX##_get_ref(struct SNAME *_list_, size_t index); \
- V PFX##_back(struct SNAME *_list_); \
- size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_list_, V value); \
- bool PFX##_empty(struct SNAME *_list_); \
- bool PFX##_full(struct SNAME *_list_); \
- size_t PFX##_count(struct SNAME *_list_); \
- bool PFX##_fits(struct SNAME *_list_, size_t size); \
- size_t PFX##_capacity(struct SNAME *_list_); \
- int PFX##_flag(struct SNAME *_list_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_list_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_list_); \
- bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_list_); \
- bool PFX##_print(struct SNAME *_list_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_LIST_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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 * _list_); \
+ void CMC_(PFX, _free)(struct SNAME * _list_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index); \
+ bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _pop_front)(struct SNAME * _list_); \
+ bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index); \
+ bool CMC_(PFX, _pop_back)(struct SNAME * _list_); \
+ /* Element Access */ \
+ V CMC_(PFX, _front)(struct SNAME * _list_); \
+ V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \
+ V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index); \
+ V CMC_(PFX, _back)(struct SNAME * _list_); \
+ size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _list_); \
+ bool CMC_(PFX, _full)(struct SNAME * _list_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _list_); \
+ bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \
+ int CMC_(PFX, _flag)(struct SNAME * _list_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- /* None */ \
- \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity < 1) \
- return NULL; \
- \
- struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_list_) \
- return NULL; \
- \
- _list_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_list_->buffer) \
- { \
- alloc->free(_list_); \
- return NULL; \
- } \
- \
- _list_->capacity = capacity; \
- _list_->count = 0; \
- _list_->flag = cmc_flags.OK; \
- _list_->f_val = f_val; \
- _list_->alloc = alloc; \
- _list_->callbacks = NULL; \
- \
- return _list_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity < 1) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_list_) \
- return NULL; \
- \
- _list_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_list_->buffer) \
- { \
- alloc->free(_list_); \
- return NULL; \
- } \
- \
- _list_->capacity = capacity; \
- _list_->count = 0; \
- _list_->flag = cmc_flags.OK; \
- _list_->f_val = f_val; \
- _list_->alloc = alloc; \
- _list_->callbacks = callbacks; \
- \
- return _list_; \
- } \
- \
- void PFX##_clear(struct SNAME *_list_) \
- { \
- if (_list_->f_val->free) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- _list_->f_val->free(_list_->buffer[i]); \
- } \
- \
- memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
- \
- _list_->count = 0; \
- _list_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_list_) \
- { \
- if (_list_->f_val->free) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- _list_->f_val->free(_list_->buffer[i]); \
- } \
- \
- _list_->alloc->free(_list_->buffer); \
- _list_->alloc->free(_list_); \
- } \
- \
- void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _list_->alloc = &cmc_alloc_node_default; \
- else \
- _list_->alloc = alloc; \
- \
- _list_->callbacks = callbacks; \
- \
- _list_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_push_front(struct SNAME *_list_, V value) \
- { \
- if (PFX##_full(_list_)) \
- { \
- if (!PFX##_resize(_list_, _list_->count * 2)) \
- return false; \
- } \
- \
- if (!PFX##_empty(_list_)) \
- { \
- memmove(_list_->buffer + 1, _list_->buffer, \
- _list_->count * sizeof(V)); \
- } \
- \
- _list_->buffer[0] = value; \
- \
- _list_->count++; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_push_at(struct SNAME *_list_, V value, size_t index) \
- { \
- if (index > _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- if (PFX##_full(_list_)) \
- { \
- if (!PFX##_resize(_list_, _list_->count * 2)) \
- return false; \
- } \
- \
- memmove(_list_->buffer + index + 1, _list_->buffer + index, \
- (_list_->count - index) * sizeof(V)); \
- \
- _list_->buffer[index] = value; \
- _list_->count++; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_push_back(struct SNAME *_list_, V value) \
- { \
- if (PFX##_full(_list_)) \
- { \
- if (!PFX##_resize(_list_, _list_->count * 2)) \
- return false; \
- } \
- \
- _list_->buffer[_list_->count++] = value; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_front(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- memmove(_list_->buffer, _list_->buffer + 1, \
- (_list_->count - 1) * sizeof(V)); \
- \
- _list_->buffer[--_list_->count] = (V){ 0 }; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_at(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- memmove(_list_->buffer + index, _list_->buffer + index + 1, \
- (_list_->count - index - 1) * sizeof(V)); \
- \
- _list_->buffer[--_list_->count] = (V){ 0 }; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_pop_back(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- return false; \
- \
- _list_->buffer[--_list_->count] = (V){ 0 }; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_seq_push_front(struct SNAME *_list_, V *values, size_t size) \
- { \
- if (size == 0) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (!PFX##_fits(_list_, size)) \
- { \
- if (!PFX##_resize(_list_, _list_->count + size)) \
- return false; \
- } \
- \
- memmove(_list_->buffer + size, _list_->buffer, \
- _list_->count * sizeof(V)); \
- \
- memcpy(_list_->buffer, values, size * sizeof(V)); \
- \
- _list_->count += size; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_seq_push_at(struct SNAME *_list_, V *values, size_t size, \
- size_t index) \
- { \
- if (size == 0) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (index > _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- if (index == 0) \
- return PFX##_seq_push_front(_list_, values, size); \
- else if (index == _list_->count) \
- return PFX##_seq_push_back(_list_, values, size); \
- \
- if (!PFX##_fits(_list_, size)) \
- { \
- if (!PFX##_resize(_list_, _list_->count + size)) \
- return false; \
- } \
- \
- memmove(_list_->buffer + index + size, _list_->buffer + index, \
- (_list_->count - index) * sizeof(V)); \
- \
- memcpy(_list_->buffer + index, values, size * sizeof(V)); \
- \
- _list_->count += size; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_seq_push_back(struct SNAME *_list_, V *values, size_t size) \
- { \
- if (size == 0) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (!PFX##_fits(_list_, size)) \
- { \
- if (!PFX##_resize(_list_, _list_->count + size)) \
- return false; \
- } \
- \
- memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \
- \
- _list_->count += size; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_seq_pop_at(struct SNAME *_list_, size_t from, size_t to) \
- { \
- if (from > to) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- if (to >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- size_t length = (to - from + 1); \
- \
- memmove(_list_->buffer + from, _list_->buffer + to + 1, \
- (_list_->count - to - 1) * sizeof(V)); \
- \
- memset(_list_->buffer + _list_->count - length, 0, \
- length * sizeof(V)); \
- \
- _list_->count -= to - from + 1; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_seq_sublist(struct SNAME *_list_, size_t from, \
- size_t to) \
- { \
- if (from > to) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return NULL; \
- } \
- \
- if (to >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return NULL; \
- } \
- \
- size_t length = to - from + 1; \
- \
- struct SNAME *result = PFX##_new_custom( \
- length, _list_->f_val, _list_->alloc, _list_->callbacks); \
- \
- if (!result) \
- { \
- _list_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \
- \
- memmove(_list_->buffer + from, _list_->buffer + to + 1, \
- (_list_->count - to - 1) * sizeof(V)); \
- \
- memset(_list_->buffer + _list_->count - length, 0, \
- length * sizeof(V)); \
- \
- _list_->count -= length; \
- result->count = length; \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return result; \
- } \
- \
- V PFX##_front(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->buffer[0]; \
- } \
- \
- V PFX##_get(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return (V){ 0 }; \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->buffer[index]; \
- } \
- \
- V *PFX##_get_ref(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return NULL; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return NULL; \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return &(_list_->buffer[index]); \
- } \
- \
- V PFX##_back(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->buffer[_list_->count - 1]; \
- } \
- \
- size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- size_t result = _list_->count; \
- \
- if (from_start) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- { \
- if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \
- { \
- result = i; \
- break; \
- } \
- } \
- } \
- else \
- { \
- for (size_t i = _list_->count; i > 0; i--) \
- { \
- if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) \
- { \
- result = i - 1; \
- break; \
- } \
- } \
- } \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_contains(struct SNAME *_list_, V value) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- bool result = false; \
- \
- for (size_t i = 0; i < _list_->count; i++) \
- { \
- if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \
- { \
- result = true; \
- break; \
- } \
- } \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_list_) \
- { \
- return _list_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_list_) \
- { \
- return _list_->count >= _list_->capacity; \
- } \
- \
- size_t PFX##_count(struct SNAME *_list_) \
- { \
- return _list_->count; \
- } \
- \
- bool PFX##_fits(struct SNAME *_list_, size_t size) \
- { \
- return _list_->count + size <= _list_->capacity; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_list_) \
- { \
- return _list_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_list_) \
- { \
- return _list_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_list_, size_t capacity) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->capacity == capacity) \
- return true; \
- \
- if (capacity < _list_->count) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- V *new_buffer = \
- _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \
- \
- if (!new_buffer) \
- { \
- _list_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- /* TODO zero out new slots */ \
- \
- _list_->buffer = new_buffer; \
- _list_->capacity = capacity; \
- \
- if (_list_->callbacks && _list_->callbacks->resize) \
- _list_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_list_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, \
- _list_->callbacks); \
- \
- if (!result) \
- { \
- _list_->flag = cmc_flags.ALLOC; \
- return NULL; \
- } \
- \
- if (_list_->f_val->cpy) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \
- } \
- else \
+#define CMC_CMC_LIST_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ /* None */ \
+\
+ 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 < 1) \
+ return NULL; \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_list_) \
+ return NULL; \
+\
+ _list_->buffer = alloc->calloc(capacity, sizeof(V)); \
+\
+ if (!_list_->buffer) \
+ { \
+ alloc->free(_list_); \
+ return NULL; \
+ } \
+\
+ _list_->capacity = capacity; \
+ _list_->count = 0; \
+ _list_->flag = CMC_FLAG_OK; \
+ _list_->f_val = f_val; \
+ _list_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_list_, callbacks); \
+\
+ return _list_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _list_) \
+ { \
+ if (_list_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ _list_->f_val->free(_list_->buffer[i]); \
+ } \
+\
+ memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
+\
+ _list_->count = 0; \
+ _list_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _list_) \
+ { \
+ if (_list_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ _list_->f_val->free(_list_->buffer[i]); \
+ } \
+\
+ _list_->alloc->free(_list_->buffer); \
+ _list_->alloc->free(_list_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _list_->alloc = &cmc_alloc_node_default; \
+ else \
+ _list_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_list_, callbacks); \
+\
+ _list_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _push_front)(struct SNAME * _list_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_list_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \
+ return false; \
+ } \
+\
+ if (!CMC_(PFX, _empty)(_list_)) \
+ { \
+ memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(V)); \
+ } \
+\
+ _list_->buffer[0] = value; \
+\
+ _list_->count++; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _push_at)(struct SNAME * _list_, V value, size_t index) \
+ { \
+ if (index > _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ if (CMC_(PFX, _full)(_list_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \
+ return false; \
+ } \
+\
+ memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \
+\
+ _list_->buffer[index] = value; \
+ _list_->count++; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _push_back)(struct SNAME * _list_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_list_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->count * 2)) \
+ return false; \
+ } \
+\
+ _list_->buffer[_list_->count++] = value; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_front)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(V)); \
+\
+ _list_->buffer[--_list_->count] = (V){ 0 }; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_at)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(V)); \
+\
+ _list_->buffer[--_list_->count] = (V){ 0 }; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop_back)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ return false; \
+\
+ _list_->buffer[--_list_->count] = (V){ 0 }; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _front)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->buffer[0]; \
+ } \
+\
+ V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return (V){ 0 }; \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->buffer[index]; \
+ } \
+\
+ V *CMC_(PFX, _get_ref)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return NULL; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return NULL; \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return &(_list_->buffer[index]); \
+ } \
+\
+ V CMC_(PFX, _back)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->buffer[_list_->count - 1]; \
+ } \
+\
+ size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ size_t result = _list_->count; \
+\
+ if (from_start) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ { \
+ if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \
+ { \
+ result = i; \
+ break; \
+ } \
+ } \
+ } \
+ else \
+ { \
+ for (size_t i = _list_->count; i > 0; i--) \
+ { \
+ if (_list_->f_val->cmp(_list_->buffer[i - 1], value) == 0) \
+ { \
+ result = i - 1; \
+ break; \
+ } \
+ } \
+ } \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ bool result = false; \
+\
+ for (size_t i = 0; i < _list_->count; i++) \
+ { \
+ if (_list_->f_val->cmp(_list_->buffer[i], value) == 0) \
+ { \
+ result = true; \
+ break; \
+ } \
+ } \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _list_) \
+ { \
+ return _list_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _list_) \
+ { \
+ return _list_->count >= _list_->capacity; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _list_) \
+ { \
+ return _list_->count; \
+ } \
+\
+ bool CMC_(PFX, _fits)(struct SNAME * _list_, size_t size) \
+ { \
+ return _list_->count + size <= _list_->capacity; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \
+ { \
+ return _list_->capacity; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _list_) \
+ { \
+ return _list_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ if (_list_->capacity == capacity) \
+ return true; \
+\
+ if (capacity < _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \
+\
+ if (!new_buffer) \
+ { \
+ _list_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ /* TODO zero out new slots */ \
+\
+ _list_->buffer = new_buffer; \
+ _list_->capacity = capacity; \
+\
+ CMC_CALLBACKS_CALL(_list_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _list_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \
+\
+ if (_list_->f_val->cpy) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \
+ } \
+ else \
memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \
- \
- result->count = _list_->count; \
- \
- _list_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
- { \
- _list1_->flag = cmc_flags.OK; \
- _list2_->flag = cmc_flags.OK; \
- \
- if (_list1_->count != _list2_->count) \
- return false; \
- \
- for (size_t i = 0; i < _list1_->count; i++) \
- { \
- if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \
- 0) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_list_) \
- { \
- struct cmc_string str; \
- struct SNAME *l_ = _list_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_list, #SNAME, \
- #V, l_, l_->buffer, l_->capacity, l_->count, \
- l_->flag, l_->f_val, l_->alloc, l_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_list_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- { \
- if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- iter.cursor = target->count - 1; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->start = PFX##_empty(iter->target); \
- iter->cursor = iter->target->count - 1; \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *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; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor += steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *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 = 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 PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->cursor > index) \
- return PFX##_iter_rewind(iter, iter->cursor - index); \
- else if (iter->cursor < index) \
- return PFX##_iter_advance(iter, index - iter->cursor); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->cursor; \
+\
+ result->count = _list_->count; \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \
+ { \
+ _list1_->flag = CMC_FLAG_OK; \
+ _list2_->flag = CMC_FLAG_OK; \
+\
+ if (_list1_->count != _list2_->count) \
+ return false; \
+\
+ for (size_t i = 0; i < _list1_->count; i++) \
+ { \
+ if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i])) \
+ return false; \
+ } \
+\
+ return true; \
}
-#endif /* CMC_LIST_H */
+#endif /* CMC_CMC_LIST_H */
diff --git a/src/cmc/queue.h b/src/cmc/queue.h
index 10f3fb0..acb73c3 100644
--- a/src/cmc/queue.h
+++ b/src/cmc/queue.h
@@ -1,5 +1,5 @@
/**
- * queue.h
+ * cmc/queue.h
*
* Creation Date: 15/02/2019
*
@@ -40,745 +40,442 @@
* the resource.
*/
-#ifndef CMC_QUEUE_H
-#define CMC_QUEUE_H
+#ifndef CMC_CMC_QUEUE_H
+#define CMC_CMC_QUEUE_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core Queue implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_QUEUE_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_QUEUE_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_QUEUE_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \
+ CMC_CMC_QUEUE_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_QUEUE_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_QUEUE_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_QUEUE_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_QUEUE_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_QUEUE_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \
+ CMC_CMC_QUEUE_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_QUEUE_CORE_STRUCT(PARAMS) \
+ CMC_CMC_QUEUE_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_QUEUE_CORE_HEADER(PARAMS) \
+ CMC_CMC_QUEUE_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_QUEUE_CORE_SOURCE(PARAMS) \
+ CMC_CMC_QUEUE_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * Queue specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_queue = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "front:%" PRIuMAX ", "
- "back:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_QUEUE(PFX, SNAME, V) \
- CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_QUEUE_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_QUEUE_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_QUEUE_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Queue Structure */ \
+ struct SNAME \
+ { \
+ /* Dynamic circular array of elements */ \
+ V *buffer; \
+\
+ /* Current circular array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of elements */ \
+ size_t count; \
+\
+ /* Index representing the front of the queue */ \
+ size_t front; \
+\
+ /* Index representing the back of the queue */ \
+ size_t back; \
+\
+ /* 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \
- \
- /* Queue Structure */ \
- struct SNAME \
- { \
- /* Dynamic circular array of elements */ \
- V *buffer; \
- \
- /* Current circular array capacity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Index representing the front of the queue */ \
- size_t front; \
- \
- /* Index representing the back of the queue */ \
- size_t back; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Queue Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target queue */ \
- struct SNAME *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_queue_); \
- void PFX##_free(struct SNAME *_queue_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_queue_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_enqueue(struct SNAME *_queue_, V value); \
- bool PFX##_dequeue(struct SNAME *_queue_); \
- /* Element Access */ \
- V PFX##_peek(struct SNAME *_queue_); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_queue_, V value); \
- bool PFX##_empty(struct SNAME *_queue_); \
- bool PFX##_full(struct SNAME *_queue_); \
- size_t PFX##_count(struct SNAME *_queue_); \
- size_t PFX##_capacity(struct SNAME *_queue_); \
- int PFX##_flag(struct SNAME *_queue_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_queue_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_queue_); \
- bool PFX##_equals(struct SNAME *_queue1_, struct SNAME *_queue2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_queue_); \
- bool PFX##_print(struct SNAME *_queue_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_QUEUE_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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 * _queue_); \
+ void CMC_(PFX, _free)(struct SNAME * _queue_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value); \
+ bool CMC_(PFX, _dequeue)(struct SNAME * _queue_); \
+ /* Element Access */ \
+ V CMC_(PFX, _peek)(struct SNAME * _queue_); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _queue_); \
+ bool CMC_(PFX, _full)(struct SNAME * _queue_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _queue_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _queue_); \
+ int CMC_(PFX, _flag)(struct SNAME * _queue_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- /* None */ \
- \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity < 1) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_queue_) \
- return NULL; \
- \
- _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_queue_->buffer) \
- { \
- alloc->free(_queue_); \
- return NULL; \
- } \
- \
- _queue_->capacity = capacity; \
- _queue_->count = 0; \
- _queue_->front = 0; \
- _queue_->back = 0; \
- _queue_->flag = cmc_flags.OK; \
- _queue_->f_val = f_val; \
- _queue_->alloc = alloc; \
- _queue_->callbacks = NULL; \
- \
- return _queue_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity < 1) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_queue_) \
- return NULL; \
- \
- _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_queue_->buffer) \
- { \
- alloc->free(_queue_); \
- return NULL; \
- } \
- \
- _queue_->capacity = capacity; \
- _queue_->count = 0; \
- _queue_->front = 0; \
- _queue_->back = 0; \
- _queue_->flag = cmc_flags.OK; \
- _queue_->f_val = f_val; \
- _queue_->alloc = alloc; \
- _queue_->callbacks = callbacks; \
- \
- return _queue_; \
- } \
- \
- void PFX##_clear(struct SNAME *_queue_) \
- { \
- if (_queue_->f_val->free) \
- { \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- _queue_->f_val->free(_queue_->buffer[i]); \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- } \
- \
- memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
- \
- _queue_->count = 0; \
- _queue_->front = 0; \
- _queue_->back = 0; \
- _queue_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_queue_) \
- { \
- if (_queue_->f_val->free) \
- { \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- _queue_->f_val->free(_queue_->buffer[i]); \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- } \
- \
- _queue_->alloc->free(_queue_->buffer); \
- _queue_->alloc->free(_queue_); \
- } \
- \
- void PFX##_customize(struct SNAME *_queue_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _queue_->alloc = &cmc_alloc_node_default; \
- else \
- _queue_->alloc = alloc; \
- \
- _queue_->callbacks = callbacks; \
- \
- _queue_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_enqueue(struct SNAME *_queue_, V value) \
- { \
- if (PFX##_full(_queue_)) \
- { \
- if (!PFX##_resize(_queue_, _queue_->capacity * 2)) \
- return false; \
- } \
- \
- _queue_->buffer[_queue_->back] = value; \
- \
- _queue_->back = \
- (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \
- _queue_->count++; \
- _queue_->flag = cmc_flags.OK; \
- \
- if (_queue_->callbacks && _queue_->callbacks->create) \
- _queue_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_dequeue(struct SNAME *_queue_) \
- { \
- if (PFX##_empty(_queue_)) \
- { \
- _queue_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- _queue_->buffer[_queue_->front] = (V){ 0 }; \
- \
- _queue_->front = (_queue_->front == _queue_->capacity - 1) \
- ? 0 \
- : _queue_->front + 1; \
- _queue_->count--; \
- _queue_->flag = cmc_flags.OK; \
- \
- if (_queue_->callbacks && _queue_->callbacks->delete) \
- _queue_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- V PFX##_peek(struct SNAME *_queue_) \
- { \
- if (PFX##_empty(_queue_)) \
- { \
- _queue_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _queue_->flag = cmc_flags.OK; \
- \
- if (_queue_->callbacks && _queue_->callbacks->read) \
- _queue_->callbacks->read(); \
- \
- return _queue_->buffer[_queue_->front]; \
- } \
- \
- bool PFX##_contains(struct SNAME *_queue_, V value) \
- { \
- _queue_->flag = cmc_flags.OK; \
- \
- bool result = false; \
- \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) \
- { \
- result = true; \
- break; \
- } \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- \
- if (_queue_->callbacks && _queue_->callbacks->read) \
- _queue_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_queue_) \
- { \
- return _queue_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_queue_) \
- { \
- return _queue_->count >= _queue_->capacity; \
- } \
- \
- size_t PFX##_count(struct SNAME *_queue_) \
- { \
- return _queue_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_queue_) \
- { \
- return _queue_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_queue_) \
- { \
- return _queue_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_queue_, size_t capacity) \
- { \
- if (_queue_->capacity == capacity) \
- goto success; \
- \
- if (capacity < _queue_->count) \
- { \
- _queue_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \
- \
- if (!new_buffer) \
- { \
- _queue_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- new_buffer[j] = _queue_->buffer[i]; \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- \
- _queue_->alloc->free(_queue_->buffer); \
- \
- _queue_->buffer = new_buffer; \
- _queue_->capacity = capacity; \
- _queue_->front = 0; \
- _queue_->back = _queue_->count; \
- \
- success: \
- \
- _queue_->flag = cmc_flags.OK; \
- \
- if (_queue_->callbacks && _queue_->callbacks->resize) \
- _queue_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_queue_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_queue_->capacity, _queue_->f_val, \
- _queue_->alloc, _queue_->callbacks); \
- \
- if (!result) \
- { \
- _queue_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_queue_->f_val->cpy) \
- { \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- } \
- else \
- { \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- result->buffer[j] = _queue_->buffer[i]; \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- } \
- \
- result->count = _queue_->count; \
- result->front = 0; \
- result->back = _queue_->count; \
- \
- _queue_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_queue1_, struct SNAME *_queue2_) \
- { \
- _queue1_->flag = cmc_flags.OK; \
- _queue2_->flag = cmc_flags.OK; \
- \
- if (_queue1_->count != _queue2_->count) \
- return false; \
- \
- size_t i, j, k; \
- for (i = _queue1_->front, j = _queue2_->front, k = 0; \
- k < _queue1_->count; k++) \
- { \
- if (_queue1_->f_val->cmp(_queue1_->buffer[i], \
- _queue2_->buffer[j]) != 0) \
- return false; \
- \
- i = (i + 1) % _queue1_->capacity; \
- j = (j + 1) % _queue2_->capacity; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_queue_) \
- { \
- struct cmc_string str; \
- struct SNAME *q_ = _queue_; \
- \
- int n = \
- snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, #SNAME, #V, \
- q_, q_->buffer, q_->capacity, q_->count, q_->front, \
- q_->back, q_->flag, q_->f_val, q_->alloc, q_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_queue_, FILE *fptr) \
- { \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
- { \
- if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \
- return false; \
- \
- i = (i + 1) % _queue_->capacity; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->front; \
- iter.index = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- \
- if (!PFX##_empty(target)) \
- { \
- if (iter.target->back == 0) \
- iter.cursor = iter.target->capacity - 1; \
- else \
- iter.cursor = iter.target->back - 1; \
- \
- iter.index = iter.target->count - 1; \
- } \
- else \
- { \
- iter.cursor = 0; \
- iter.index = 0; \
- } \
- \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->front; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = false; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- if (iter->target->back == 0) \
- iter->cursor = iter->target->capacity - 1; \
- else \
- iter->cursor = iter->target->back - 1; \
- \
- iter->index = iter->target->count - 1; \
- \
- iter->start = false; \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
- iter->index++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 \
- : iter->cursor - 1; \
- iter->index--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->index + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->index += steps; \
- iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->index == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->index -= steps; \
- \
- /* Prevent underflow */ \
- if (iter->cursor < steps) \
- iter->cursor += iter->target->capacity; \
- \
- iter->cursor -= steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
+#define CMC_CMC_QUEUE_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ /* None */ \
+\
+ 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 < 1) \
+ return NULL; \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_queue_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_queue_) \
+ return NULL; \
+\
+ _queue_->buffer = alloc->calloc(capacity, sizeof(V)); \
+\
+ if (!_queue_->buffer) \
+ { \
+ alloc->free(_queue_); \
+ return NULL; \
+ } \
+\
+ _queue_->capacity = capacity; \
+ _queue_->count = 0; \
+ _queue_->front = 0; \
+ _queue_->back = 0; \
+ _queue_->flag = CMC_FLAG_OK; \
+ _queue_->f_val = f_val; \
+ _queue_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_queue_, callbacks); \
+\
+ return _queue_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _queue_) \
+ { \
+ if (_queue_->f_val->free) \
+ { \
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ _queue_->f_val->free(_queue_->buffer[i]); \
+\
+ i = (i + 1) % _queue_->capacity; \
+ } \
+ } \
+\
+ memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
+\
+ _queue_->count = 0; \
+ _queue_->front = 0; \
+ _queue_->back = 0; \
+ _queue_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _queue_) \
+ { \
+ if (_queue_->f_val->free) \
+ { \
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ _queue_->f_val->free(_queue_->buffer[i]); \
+\
+ i = (i + 1) % _queue_->capacity; \
+ } \
+ } \
+\
+ _queue_->alloc->free(_queue_->buffer); \
+ _queue_->alloc->free(_queue_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _queue_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _queue_->alloc = &cmc_alloc_node_default; \
+ else \
+ _queue_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_queue_, callbacks); \
+\
+ _queue_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _enqueue)(struct SNAME * _queue_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_queue_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_queue_, _queue_->capacity * 2)) \
+ return false; \
+ } \
+\
+ _queue_->buffer[_queue_->back] = value; \
+\
+ _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \
+ _queue_->count++; \
+ _queue_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_queue_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _dequeue)(struct SNAME * _queue_) \
+ { \
+ if (CMC_(PFX, _empty)(_queue_)) \
+ { \
+ _queue_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ _queue_->buffer[_queue_->front] = (V){ 0 }; \
+\
+ _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \
+ _queue_->count--; \
+ _queue_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_queue_, delete); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _peek)(struct SNAME * _queue_) \
+ { \
+ if (CMC_(PFX, _empty)(_queue_)) \
+ { \
+ _queue_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _queue_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_queue_, read); \
+\
+ return _queue_->buffer[_queue_->front]; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _queue_, V value) \
+ { \
+ _queue_->flag = CMC_FLAG_OK; \
+\
+ bool result = false; \
+\
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ if (_queue_->f_val->cmp(_queue_->buffer[i], value) == 0) \
+ { \
+ result = true; \
+ break; \
+ } \
+\
+ i = (i + 1) % _queue_->capacity; \
+ } \
+\
+ CMC_CALLBACKS_CALL(_queue_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _queue_) \
+ { \
+ return _queue_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _queue_) \
+ { \
+ return _queue_->count >= _queue_->capacity; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _queue_) \
+ { \
+ return _queue_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _queue_) \
+ { \
+ return _queue_->capacity; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _queue_) \
+ { \
+ return _queue_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _queue_, size_t capacity) \
+ { \
+ if (_queue_->capacity == capacity) \
+ goto success; \
+\
+ if (capacity < _queue_->count) \
+ { \
+ _queue_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ V *new_buffer = _queue_->alloc->malloc(sizeof(V) * capacity); \
+\
+ if (!new_buffer) \
+ { \
+ _queue_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ new_buffer[j] = _queue_->buffer[i]; \
+\
+ i = (i + 1) % _queue_->capacity; \
+ } \
+\
+ _queue_->alloc->free(_queue_->buffer); \
+\
+ _queue_->buffer = new_buffer; \
+ _queue_->capacity = capacity; \
+ _queue_->front = 0; \
+ _queue_->back = _queue_->count; \
+\
+ success: \
+\
+ _queue_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_queue_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _queue_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_queue_->capacity, _queue_->f_val, _queue_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _queue_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _queue_->callbacks); \
+\
+ if (_queue_->f_val->cpy) \
+ { \
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ result->buffer[j] = _queue_->f_val->cpy(_queue_->buffer[i]); \
+\
+ i = (i + 1) % _queue_->capacity; \
+ } \
+ } \
+ else \
+ { \
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ result->buffer[j] = _queue_->buffer[i]; \
+\
+ i = (i + 1) % _queue_->capacity; \
+ } \
+ } \
+\
+ result->count = _queue_->count; \
+ result->front = 0; \
+ result->back = _queue_->count; \
+\
+ _queue_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _queue1_, struct SNAME * _queue2_) \
+ { \
+ _queue1_->flag = CMC_FLAG_OK; \
+ _queue2_->flag = CMC_FLAG_OK; \
+\
+ if (_queue1_->count != _queue2_->count) \
+ return false; \
+\
+ size_t i, j, k; \
+ for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; k++) \
+ { \
+ if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0) \
+ return false; \
+\
+ i = (i + 1) % _queue1_->capacity; \
+ j = (j + 1) % _queue2_->capacity; \
+ } \
+\
+ return true; \
}
-#endif /* CMC_QUEUE_H */
+#endif /* CMC_CMC_QUEUE_H */
diff --git a/src/cmc/sortedlist.h b/src/cmc/sortedlist.h
index 47edbc7..5f36f32 100644
--- a/src/cmc/sortedlist.h
+++ b/src/cmc/sortedlist.h
@@ -1,5 +1,5 @@
/**
- * sortedlist.h
+ * cmc/sortedlist.h
*
* Creation Date: 17/09/2019
*
@@ -19,867 +19,599 @@
* variation of quick sort that uses insertion sort for small partitions.
*/
-#ifndef CMC_SORTEDLIST_H
-#define CMC_SORTEDLIST_H
+#ifndef CMC_CMC_SORTEDLIST_H
+#define CMC_CMC_SORTEDLIST_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core SortedList implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_SORTEDLIST_CORE(ACCESS, FILE, PARAMS) \
+ CMC_(CMC_(CMC_CMC_SORTEDLIST_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_SORTEDLIST_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_SORTEDLIST_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_SORTEDLIST_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_SORTEDLIST_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_SORTEDLIST_CORE_STRUCT(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_SORTEDLIST_CORE_HEADER(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_SORTEDLIST_CORE_SOURCE(PARAMS) \
+ CMC_CMC_SORTEDLIST_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * SortedList specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_sortedlist = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "is_sorted:%s, "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_SORTEDLIST(PFX, SNAME, V) \
- CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_SORTEDLIST_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_SORTEDLIST_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_SORTEDLIST_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* List Structure */ \
+ struct SNAME \
+ { \
+ /* Dynamic array of elements */ \
+ V *buffer; \
+\
+ /* Current array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of elements */ \
+ size_t count; \
+\
+ /* Flag if the list is sorted or not, used by lazy evaluation */ \
+ bool is_sorted; \
+\
+ /* 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_SORTEDLIST_HEADER(PFX, SNAME, V) \
- \
- /* List Structure */ \
- struct SNAME \
- { \
- /* Dynamic array of elements */ \
- V *buffer; \
- \
- /* Current array capacity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Flag if the list is sorted or not, used by lazy evaluation */ \
- bool is_sorted; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* List Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target list */ \
- 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; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_list_); \
- void PFX##_free(struct SNAME *_list_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_list_, V value); \
- bool PFX##_remove(struct SNAME *_list_, size_t index); \
- /* Element Access */ \
- V PFX##_max(struct SNAME *_list_); \
- V PFX##_min(struct SNAME *_list_); \
- V PFX##_get(struct SNAME *_list_, size_t index); \
- size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_list_, V value); \
- bool PFX##_empty(struct SNAME *_list_); \
- bool PFX##_full(struct SNAME *_list_); \
- size_t PFX##_count(struct SNAME *_list_); \
- size_t PFX##_capacity(struct SNAME *_list_); \
- int PFX##_flag(struct SNAME *_list_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_list_, size_t capacity); \
- void PFX##_sort(struct SNAME *_list_); \
- struct SNAME *PFX##_copy_of(struct SNAME *_list_); \
- bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_list_); \
- bool PFX##_print(struct SNAME *_list_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_SORTEDLIST_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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 * _list_); \
+ void CMC_(PFX, _free)(struct SNAME * _list_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index); \
+ /* Element Access */ \
+ V CMC_(PFX, _max)(struct SNAME * _list_); \
+ V CMC_(PFX, _min)(struct SNAME * _list_); \
+ V CMC_(PFX, _get)(struct SNAME * _list_, size_t index); \
+ size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _list_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _list_); \
+ bool CMC_(PFX, _full)(struct SNAME * _list_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _list_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _list_); \
+ int CMC_(PFX, _flag)(struct SNAME * _list_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity); \
+ void CMC_(PFX, _sort)(struct SNAME * _list_); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_SORTEDLIST_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- static size_t PFX##_impl_binary_search_first(struct SNAME *_list_, \
- V value); \
- static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, \
- V value); \
- void PFX##_impl_sort_quicksort(V *array, int (*cmp)(V, V), size_t low, \
- size_t high); \
- void PFX##_impl_sort_insertion(V *array, int (*cmp)(V, V), size_t low, \
- size_t high); \
- \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity < 1) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_list_) \
- return NULL; \
- \
- _list_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_list_->buffer) \
- { \
- alloc->free(_list_); \
- return NULL; \
- } \
- \
- _list_->capacity = capacity; \
- _list_->count = 0; \
- _list_->is_sorted = false; \
- _list_->flag = cmc_flags.OK; \
- _list_->f_val = f_val; \
- _list_->alloc = alloc; \
- _list_->callbacks = NULL; \
- \
- return _list_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity < 1) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_list_) \
- return NULL; \
- \
- _list_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_list_->buffer) \
- { \
- alloc->free(_list_); \
- return NULL; \
- } \
- \
- _list_->capacity = capacity; \
- _list_->count = 0; \
- _list_->is_sorted = false; \
- _list_->flag = cmc_flags.OK; \
- _list_->f_val = f_val; \
- _list_->alloc = alloc; \
- _list_->callbacks = callbacks; \
- \
- return _list_; \
- } \
- \
- void PFX##_clear(struct SNAME *_list_) \
- { \
- if (_list_->f_val->free) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- _list_->f_val->free(_list_->buffer[i]); \
- } \
- \
- memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
- \
- _list_->count = 0; \
- _list_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_list_) \
- { \
- if (_list_->f_val->free) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- _list_->f_val->free(_list_->buffer[i]); \
- } \
- \
- _list_->alloc->free(_list_->buffer); \
- _list_->alloc->free(_list_); \
- } \
- \
- void PFX##_customize(struct SNAME *_list_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _list_->alloc = &cmc_alloc_node_default; \
- else \
- _list_->alloc = alloc; \
- \
- _list_->callbacks = callbacks; \
- \
- _list_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_list_, V value) \
- { \
- if (PFX##_full(_list_)) \
- { \
- if (!PFX##_resize(_list_, _list_->capacity * 2)) \
- return false; \
- } \
- \
- _list_->buffer[_list_->count++] = value; \
- \
- _list_->is_sorted = false; \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->create) \
- _list_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return false; \
- } \
- \
- memmove(_list_->buffer + index, _list_->buffer + index + 1, \
- (_list_->count - index) * sizeof(V)); \
- \
- _list_->buffer[--_list_->count] = (V){ 0 }; \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->delete) \
- _list_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- V PFX##_max(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- PFX##_sort(_list_); \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->buffer[_list_->count - 1]; \
- } \
- \
- V PFX##_min(struct SNAME *_list_) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- PFX##_sort(_list_); \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->buffer[0]; \
- } \
- \
- V PFX##_get(struct SNAME *_list_, size_t index) \
- { \
- if (PFX##_empty(_list_)) \
- { \
- _list_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- if (index >= _list_->count) \
- { \
- _list_->flag = cmc_flags.RANGE; \
- return (V){ 0 }; \
- } \
- \
- PFX##_sort(_list_); \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return _list_->buffer[index]; \
- } \
- \
- size_t PFX##_index_of(struct SNAME *_list_, V value, bool from_start) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- PFX##_sort(_list_); \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- if (from_start) \
- { \
- return PFX##_impl_binary_search_first(_list_, value); \
- } \
- \
- return PFX##_impl_binary_search_last(_list_, value); \
- } \
- \
- bool PFX##_contains(struct SNAME *_list_, V value) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- if (PFX##_empty(_list_)) \
- return false; \
- \
- PFX##_sort(_list_); \
- \
- if (_list_->callbacks && _list_->callbacks->read) \
- _list_->callbacks->read(); \
- \
- return PFX##_impl_binary_search_first(_list_, value) < _list_->count; \
- } \
- \
- bool PFX##_empty(struct SNAME *_list_) \
- { \
- return _list_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_list_) \
- { \
- return _list_->count >= _list_->capacity; \
- } \
- \
- size_t PFX##_count(struct SNAME *_list_) \
- { \
- return _list_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_list_) \
- { \
- return _list_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_list_) \
- { \
- return _list_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_list_, size_t capacity) \
- { \
- if (_list_->capacity == capacity) \
- goto success; \
- \
- if (capacity < _list_->count) \
- { \
- _list_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- V *new_buffer = \
- _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \
- \
- if (!new_buffer) \
- { \
- _list_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- /* TODO zero out remaining slots */ \
- \
- _list_->buffer = new_buffer; \
- _list_->capacity = capacity; \
- \
- success: \
- \
- _list_->flag = cmc_flags.OK; \
- \
- if (_list_->callbacks && _list_->callbacks->resize) \
- _list_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- void PFX##_sort(struct SNAME *_list_) \
- { \
- _list_->flag = cmc_flags.OK; \
- \
- if (!_list_->is_sorted && _list_->count > 1) \
- { \
- PFX##_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, \
- _list_->count - 1); \
- \
- _list_->is_sorted = true; \
- } \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_list_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, \
- _list_->callbacks); \
- \
- if (!result) \
- { \
- _list_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_list_->f_val->cpy) \
- { \
- for (size_t i = 0; i < _list_->count; i++) \
- result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \
- } \
- else \
+#define CMC_CMC_SORTEDLIST_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value); \
+ static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, V value); \
+ void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), size_t low, size_t high); \
+ void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), size_t low, size_t high); \
+\
+ 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 < 1) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_list_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_list_) \
+ return NULL; \
+\
+ _list_->buffer = alloc->calloc(capacity, sizeof(V)); \
+\
+ if (!_list_->buffer) \
+ { \
+ alloc->free(_list_); \
+ return NULL; \
+ } \
+\
+ _list_->capacity = capacity; \
+ _list_->count = 0; \
+ _list_->is_sorted = false; \
+ _list_->flag = CMC_FLAG_OK; \
+ _list_->f_val = f_val; \
+ _list_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_list_, callbacks); \
+\
+ return _list_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _list_) \
+ { \
+ if (_list_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ _list_->f_val->free(_list_->buffer[i]); \
+ } \
+\
+ memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
+\
+ _list_->count = 0; \
+ _list_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _list_) \
+ { \
+ if (_list_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ _list_->f_val->free(_list_->buffer[i]); \
+ } \
+\
+ _list_->alloc->free(_list_->buffer); \
+ _list_->alloc->free(_list_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _list_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _list_->alloc = &cmc_alloc_node_default; \
+ else \
+ _list_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_list_, callbacks); \
+\
+ _list_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _list_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_list_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->capacity * 2)) \
+ return false; \
+ } \
+\
+ _list_->buffer[_list_->count++] = value; \
+\
+ _list_->is_sorted = false; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(V)); \
+\
+ _list_->buffer[--_list_->count] = (V){ 0 }; \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _max)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ CMC_(PFX, _sort)(_list_); \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->buffer[_list_->count - 1]; \
+ } \
+\
+ V CMC_(PFX, _min)(struct SNAME * _list_) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ CMC_(PFX, _sort)(_list_); \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->buffer[0]; \
+ } \
+\
+ V CMC_(PFX, _get)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return (V){ 0 }; \
+ } \
+\
+ CMC_(PFX, _sort)(_list_); \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return _list_->buffer[index]; \
+ } \
+\
+ size_t CMC_(PFX, _index_of)(struct SNAME * _list_, V value, bool from_start) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_(PFX, _sort)(_list_); \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ if (from_start) \
+ { \
+ return CMC_(PFX, _impl_binary_search_first)(_list_, value); \
+ } \
+\
+ return CMC_(PFX, _impl_binary_search_last)(_list_, value); \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _list_, V value) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ if (CMC_(PFX, _empty)(_list_)) \
+ return false; \
+\
+ CMC_(PFX, _sort)(_list_); \
+\
+ CMC_CALLBACKS_CALL(_list_, read); \
+\
+ return CMC_(PFX, _impl_binary_search_first)(_list_, value) < _list_->count; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _list_) \
+ { \
+ return _list_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _list_) \
+ { \
+ return _list_->count >= _list_->capacity; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _list_) \
+ { \
+ return _list_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _list_) \
+ { \
+ return _list_->capacity; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _list_) \
+ { \
+ return _list_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _list_, size_t capacity) \
+ { \
+ if (_list_->capacity == capacity) \
+ goto success; \
+\
+ if (capacity < _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ V *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(V) * capacity); \
+\
+ if (!new_buffer) \
+ { \
+ _list_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ /* TODO zero out remaining slots */ \
+\
+ _list_->buffer = new_buffer; \
+ _list_->capacity = capacity; \
+\
+ success: \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, resize); \
+\
+ return true; \
+ } \
+\
+ void CMC_(PFX, _sort)(struct SNAME * _list_) \
+ { \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ if (!_list_->is_sorted && _list_->count > 1) \
+ { \
+ CMC_(PFX, _impl_sort_quicksort) \
+ (_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1); \
+\
+ _list_->is_sorted = true; \
+ } \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _list_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_list_->capacity, _list_->f_val, _list_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _list_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _list_->callbacks); \
+\
+ if (_list_->f_val->cpy) \
+ { \
+ for (size_t i = 0; i < _list_->count; i++) \
+ result->buffer[i] = _list_->f_val->cpy(_list_->buffer[i]); \
+ } \
+ else \
memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \
- \
- result->count = _list_->count; \
- \
- _list_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_list1_, struct SNAME *_list2_) \
- { \
- if (_list1_->count != _list2_->count) \
- return false; \
- \
- PFX##_sort(_list1_); \
- PFX##_sort(_list2_); \
- \
- for (size_t i = 0; i < _list1_->count; i++) \
- { \
- if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != \
- 0) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_list_) \
- { \
- struct cmc_string str; \
- struct SNAME *l_ = _list_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist, \
- #SNAME, #V, l_, l_->buffer, l_->capacity, l_->count, \
- l_->is_sorted ? "true" : "false", l_->flag, \
- l_->f_val, l_->alloc, l_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_list_, FILE *fptr) \
- { \
- PFX##_sort(_list_); \
- \
- for (size_t i = 0; i < _list_->count; i++) \
- { \
- if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- PFX##_sort(target); \
- \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- PFX##_sort(target); \
- \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- iter.cursor = target->count - 1; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->start = PFX##_empty(iter->target); \
- iter->cursor = iter->target->count - 1; \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor + 1 == iter->target->count) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor++; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == 0) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor--; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *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; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor += steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *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 = 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 PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->cursor > index) \
- return PFX##_iter_rewind(iter, iter->cursor - index); \
- else if (iter->cursor < index) \
- return PFX##_iter_advance(iter, index - iter->cursor); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->cursor; \
- } \
- \
- static size_t PFX##_impl_binary_search_first(struct SNAME *_list_, \
- V value) \
- { \
- if (PFX##_empty(_list_)) \
- return 1; \
- \
- size_t L = 0; \
- size_t R = _list_->count; \
- \
- while (L < R) \
- { \
- size_t M = L + (R - L) / 2; \
- \
- if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \
- L = M + 1; \
- else \
- R = M; \
- } \
- \
- if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \
- return L; \
- \
- /* Not found */ \
- return _list_->count; \
- } \
- \
- static size_t PFX##_impl_binary_search_last(struct SNAME *_list_, V value) \
- { \
- if (PFX##_empty(_list_)) \
- return 1; \
- \
- size_t L = 0; \
- size_t R = _list_->count; \
- \
- while (L < R) \
- { \
- size_t M = L + (R - L) / 2; \
- \
- if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \
- R = M; \
- else \
- L = M + 1; \
- } \
- \
- if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \
- return L - 1; \
- \
- /* Not found */ \
- return _list_->count; \
- } \
- \
- /* Characteristics of this quicksort implementation: */ \
- /* - Hybrid: uses insertion sort for small arrays */ \
- /* - Partition: Lomuto's Method */ \
- /* - Tail recursion: minimize recursion depth */ \
- void PFX##_impl_sort_quicksort(V *array, int (*cmp)(V, V), size_t low, \
- size_t high) \
- { \
- while (low < high) \
- { \
- /* Quicksort performs poorly for smaller arrays so let */ \
- /* insertion sort do the job */ \
- if (high - low < 10) \
- { \
- PFX##_impl_sort_insertion(array, cmp, low, high); \
- break; \
- } \
- else \
- { \
- /* Partition */ \
- V pivot = array[high]; \
- \
- size_t pindex = low; \
- \
- for (size_t i = low; i < high; i++) \
- { \
- if (cmp(array[i], pivot) <= 0) \
- { \
- V _tmp_ = array[i]; \
- array[i] = array[pindex]; \
- array[pindex] = _tmp_; \
- \
- pindex++; \
- } \
- } \
- \
- V _tmp_ = array[pindex]; \
- array[pindex] = array[high]; \
- array[high] = _tmp_; \
- \
- /* Tail recursion */ \
- if (pindex - low < high - pindex) \
- { \
- PFX##_impl_sort_quicksort(array, cmp, low, pindex - 1); \
- \
- low = pindex + 1; \
- } \
- else \
- { \
- PFX##_impl_sort_quicksort(array, cmp, pindex + 1, high); \
- \
- high = pindex - 1; \
- } \
- } \
- } \
- } \
- \
- void PFX##_impl_sort_insertion(V *array, int (*cmp)(V, V), size_t low, \
- size_t high) \
- { \
- for (size_t i = low + 1; i <= high; i++) \
- { \
- V _tmp_ = array[i]; \
- size_t j = i; \
- \
- while (j > low && cmp(array[j - 1], _tmp_) > 0) \
- { \
- array[j] = array[j - 1]; \
- j--; \
- } \
- \
- array[j] = _tmp_; \
- } \
+\
+ result->count = _list_->count; \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _list1_, struct SNAME * _list2_) \
+ { \
+ if (_list1_->count != _list2_->count) \
+ return false; \
+\
+ CMC_(PFX, _sort)(_list1_); \
+ CMC_(PFX, _sort)(_list2_); \
+\
+ for (size_t i = 0; i < _list1_->count; i++) \
+ { \
+ if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_binary_search_first)(struct SNAME * _list_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ return 1; \
+\
+ size_t L = 0; \
+ size_t R = _list_->count; \
+\
+ while (L < R) \
+ { \
+ size_t M = L + (R - L) / 2; \
+\
+ if (_list_->f_val->cmp(_list_->buffer[M], value) < 0) \
+ L = M + 1; \
+ else \
+ R = M; \
+ } \
+\
+ if (_list_->f_val->cmp(_list_->buffer[L], value) == 0) \
+ return L; \
+\
+ /* Not found */ \
+ return _list_->count; \
+ } \
+\
+ static size_t CMC_(PFX, _impl_binary_search_last)(struct SNAME * _list_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ return 1; \
+\
+ size_t L = 0; \
+ size_t R = _list_->count; \
+\
+ while (L < R) \
+ { \
+ size_t M = L + (R - L) / 2; \
+\
+ if (_list_->f_val->cmp(_list_->buffer[M], value) > 0) \
+ R = M; \
+ else \
+ L = M + 1; \
+ } \
+\
+ if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0) \
+ return L - 1; \
+\
+ /* Not found */ \
+ return _list_->count; \
+ } \
+\
+ /* Characteristics of this quicksort implementation: */ \
+ /* - Hybrid: uses insertion sort for small arrays */ \
+ /* - Partition: Lomuto's Method */ \
+ /* - Tail recursion: minimize recursion depth */ \
+ void CMC_(PFX, _impl_sort_quicksort)(V * array, int (*cmp)(V, V), size_t low, size_t high) \
+ { \
+ while (low < high) \
+ { \
+ /* Quicksort performs poorly for smaller arrays so let */ \
+ /* insertion sort do the job */ \
+ if (high - low < 10) \
+ { \
+ CMC_(PFX, _impl_sort_insertion)(array, cmp, low, high); \
+ break; \
+ } \
+ else \
+ { \
+ /* Partition */ \
+ V pivot = array[high]; \
+\
+ size_t pindex = low; \
+\
+ for (size_t i = low; i < high; i++) \
+ { \
+ if (cmp(array[i], pivot) <= 0) \
+ { \
+ V _tmp_ = array[i]; \
+ array[i] = array[pindex]; \
+ array[pindex] = _tmp_; \
+\
+ pindex++; \
+ } \
+ } \
+\
+ V _tmp_ = array[pindex]; \
+ array[pindex] = array[high]; \
+ array[high] = _tmp_; \
+\
+ /* Tail recursion */ \
+ if (pindex - low < high - pindex) \
+ { \
+ CMC_(PFX, _impl_sort_quicksort) \
+ (array, cmp, low, pindex - 1); \
+\
+ low = pindex + 1; \
+ } \
+ else \
+ { \
+ CMC_(PFX, _impl_sort_quicksort) \
+ (array, cmp, pindex + 1, high); \
+\
+ high = pindex - 1; \
+ } \
+ } \
+ } \
+ } \
+\
+ void CMC_(PFX, _impl_sort_insertion)(V * array, int (*cmp)(V, V), size_t low, size_t high) \
+ { \
+ for (size_t i = low + 1; i <= high; i++) \
+ { \
+ V _tmp_ = array[i]; \
+ size_t j = i; \
+\
+ while (j > low && cmp(array[j - 1], _tmp_) > 0) \
+ { \
+ array[j] = array[j - 1]; \
+ j--; \
+ } \
+\
+ array[j] = _tmp_; \
+ } \
}
-#endif /* CMC_SORTEDLIST_H */
+#endif /* CMC_CMC_SORTEDLIST_H */
diff --git a/src/cmc/stack.h b/src/cmc/stack.h
index 1efa5f0..cb60b1e 100644
--- a/src/cmc/stack.h
+++ b/src/cmc/stack.h
@@ -1,5 +1,5 @@
/**
- * stack.h
+ * cmc/stack.h
*
* Creation Date: 14/02/2019
*
@@ -25,655 +25,391 @@
* expression evaluation, syntax parsing and many more.
*/
-#ifndef CMC_STACK_H
-#define CMC_STACK_H
+#ifndef CMC_CMC_STACK_H
+#define CMC_CMC_STACK_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core Stack implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_STACK_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_STACK_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_STACK_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_STACK_CORE_STRUCT(PARAMS) \
+ CMC_CMC_STACK_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_STACK_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_STACK_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_STACK_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_STACK_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_STACK_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_STACK_CORE_STRUCT(PARAMS) \
+ CMC_CMC_STACK_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_STACK_CORE_STRUCT(PARAMS) \
+ CMC_CMC_STACK_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_STACK_CORE_HEADER(PARAMS) \
+ CMC_CMC_STACK_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_STACK_CORE_SOURCE(PARAMS) \
+ CMC_CMC_STACK_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * Stack specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_stack = "struct %s<%s> "
- "at %p { "
- "buffer:%p, "
- "capacity:%" PRIuMAX ", "
- "count:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_STACK(PFX, SNAME, V) \
- CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_STACK_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_STACK_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_STACK_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_STACK_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Stack Structure */ \
+ struct SNAME \
+ { \
+ /* Dynamic array of elements */ \
+ V *buffer; \
+\
+ /* Current array capacity */ \
+ size_t capacity; \
+\
+ /* Current amount of elements */ \
+ 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; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
- \
- /* Stack Structure */ \
- struct SNAME \
- { \
- /* Dynamic array of elements */ \
- V *buffer; \
- \
- /* Current array capacity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Stack Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target stack */ \
- 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; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_stack_); \
- void PFX##_free(struct SNAME *_stack_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_stack_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_push(struct SNAME *_stack_, V value); \
- bool PFX##_pop(struct SNAME *_stack_); \
- /* Element Access */ \
- V PFX##_top(struct SNAME *_stack_); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_stack_, V value); \
- bool PFX##_empty(struct SNAME *_stack_); \
- bool PFX##_full(struct SNAME *_stack_); \
- size_t PFX##_count(struct SNAME *_stack_); \
- size_t PFX##_capacity(struct SNAME *_stack_); \
- int PFX##_flag(struct SNAME *_stack_); \
- /* Collection Utility */ \
- bool PFX##_resize(struct SNAME *_stack_, size_t capacity); \
- struct SNAME *PFX##_copy_of(struct SNAME *_stack_); \
- bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_stack_); \
- bool PFX##_print(struct SNAME *_stack_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_STACK_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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 * _stack_); \
+ void CMC_(PFX, _free)(struct SNAME * _stack_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _push)(struct SNAME * _stack_, V value); \
+ bool CMC_(PFX, _pop)(struct SNAME * _stack_); \
+ /* Element Access */ \
+ V CMC_(PFX, _top)(struct SNAME * _stack_); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _stack_); \
+ bool CMC_(PFX, _full)(struct SNAME * _stack_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _stack_); \
+ size_t CMC_(PFX, _capacity)(struct SNAME * _stack_); \
+ int CMC_(PFX, _flag)(struct SNAME * _stack_); \
+ /* Collection Utility */ \
+ bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity); \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- /* None */ \
- \
- struct SNAME *PFX##_new(size_t capacity, struct SNAME##_fval *f_val) \
- { \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- if (capacity < 1) \
- return NULL; \
- \
- if (!f_val) \
- return NULL; \
- \
- struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_stack_) \
- return NULL; \
- \
- _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_stack_->buffer) \
- { \
- alloc->free(_stack_); \
- return NULL; \
- } \
- \
- _stack_->capacity = capacity; \
- _stack_->count = 0; \
- _stack_->flag = cmc_flags.OK; \
- _stack_->f_val = f_val; \
- _stack_->alloc = alloc; \
- _stack_->callbacks = NULL; \
- \
- return _stack_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- size_t capacity, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (capacity < 1) \
- return NULL; \
- if (!f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_stack_) \
- return NULL; \
- \
- _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \
- \
- if (!_stack_->buffer) \
- { \
- alloc->free(_stack_); \
- return NULL; \
- } \
- \
- _stack_->capacity = capacity; \
- _stack_->count = 0; \
- _stack_->flag = cmc_flags.OK; \
- _stack_->f_val = f_val; \
- _stack_->alloc = alloc; \
- _stack_->callbacks = callbacks; \
- \
- return _stack_; \
- } \
- \
- void PFX##_clear(struct SNAME *_stack_) \
- { \
- if (_stack_->f_val->free) \
- { \
- for (size_t i = 0; i < _stack_->count; i++) \
- _stack_->f_val->free(_stack_->buffer[i]); \
- } \
- \
- memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
- \
- _stack_->count = 0; \
- _stack_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_stack_) \
- { \
- if (_stack_->f_val->free) \
- { \
- for (size_t i = 0; i < _stack_->count; i++) \
- _stack_->f_val->free(_stack_->buffer[i]); \
- } \
- \
- _stack_->alloc->free(_stack_->buffer); \
- _stack_->alloc->free(_stack_); \
- } \
- \
- void PFX##_customize(struct SNAME *_stack_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _stack_->alloc = &cmc_alloc_node_default; \
- else \
- _stack_->alloc = alloc; \
- \
- _stack_->callbacks = callbacks; \
- \
- _stack_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_push(struct SNAME *_stack_, V value) \
- { \
- if (PFX##_full(_stack_)) \
- { \
- if (!PFX##_resize(_stack_, _stack_->capacity * 2)) \
- return false; \
- } \
- \
- _stack_->buffer[_stack_->count++] = value; \
- \
- _stack_->flag = cmc_flags.OK; \
- \
- if (_stack_->callbacks && _stack_->callbacks->create) \
- _stack_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_pop(struct SNAME *_stack_) \
- { \
- if (PFX##_empty(_stack_)) \
- { \
- _stack_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- _stack_->buffer[--_stack_->count] = (V){ 0 }; \
- \
- _stack_->flag = cmc_flags.OK; \
- \
- if (_stack_->callbacks && _stack_->callbacks->delete) \
- _stack_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- V PFX##_top(struct SNAME *_stack_) \
- { \
- if (PFX##_empty(_stack_)) \
- { \
- _stack_->flag = cmc_flags.EMPTY; \
- return (V){ 0 }; \
- } \
- \
- _stack_->flag = cmc_flags.OK; \
- \
- if (_stack_->callbacks && _stack_->callbacks->read) \
- _stack_->callbacks->read(); \
- \
- return _stack_->buffer[_stack_->count - 1]; \
- } \
- \
- bool PFX##_contains(struct SNAME *_stack_, V value) \
- { \
- _stack_->flag = cmc_flags.OK; \
- \
- bool result = false; \
- \
- for (size_t i = 0; i < _stack_->count; i++) \
- { \
- if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) \
- { \
- result = true; \
- break; \
- } \
- } \
- \
- if (_stack_->callbacks && _stack_->callbacks->read) \
- _stack_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_stack_) \
- { \
- return _stack_->count == 0; \
- } \
- \
- bool PFX##_full(struct SNAME *_stack_) \
- { \
- return _stack_->count >= _stack_->capacity; \
- } \
- \
- size_t PFX##_count(struct SNAME *_stack_) \
- { \
- return _stack_->count; \
- } \
- \
- size_t PFX##_capacity(struct SNAME *_stack_) \
- { \
- return _stack_->capacity; \
- } \
- \
- int PFX##_flag(struct SNAME *_stack_) \
- { \
- return _stack_->flag; \
- } \
- \
- bool PFX##_resize(struct SNAME *_stack_, size_t capacity) \
- { \
- if (_stack_->capacity == capacity) \
- goto success; \
- \
- if (capacity < _stack_->count) \
- { \
- _stack_->flag = cmc_flags.INVALID; \
- return false; \
- } \
- \
- V *new_buffer = \
- _stack_->alloc->realloc(_stack_->buffer, sizeof(V) * capacity); \
- \
- if (!new_buffer) \
- { \
- _stack_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- /* TODO zero out new slots */ \
- \
- _stack_->buffer = new_buffer; \
- _stack_->capacity = capacity; \
- \
- success: \
- \
- _stack_->flag = cmc_flags.OK; \
- \
- if (_stack_->callbacks && _stack_->callbacks->resize) \
- _stack_->callbacks->resize(); \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_stack_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_stack_->capacity, _stack_->f_val, \
- _stack_->alloc, _stack_->callbacks); \
- \
- if (!result) \
- { \
- _stack_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (_stack_->f_val->cpy) \
- { \
- for (size_t i = 0; i < _stack_->count; i++) \
- result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \
- } \
- else \
- memcpy(result->buffer, _stack_->buffer, \
- sizeof(V) * _stack_->count); \
- \
- result->count = _stack_->count; \
- \
- _stack_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_stack1_, struct SNAME *_stack2_) \
- { \
- _stack1_->flag = cmc_flags.OK; \
- _stack2_->flag = cmc_flags.OK; \
- \
- if (_stack1_->count != _stack2_->count) \
- return false; \
- \
- for (size_t i = 0; i < _stack1_->count; i++) \
- { \
- if (_stack1_->f_val->cmp(_stack1_->buffer[i], \
- _stack2_->buffer[i]) != 0) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_stack_) \
- { \
- struct cmc_string str; \
- struct SNAME *s_ = _stack_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, #SNAME, \
- #V, s_, s_->buffer, s_->capacity, s_->count, \
- s_->flag, s_->f_val, s_->alloc, s_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_stack_, FILE *fptr) \
- { \
- for (size_t i = 0; i < _stack_->count; i++) \
- { \
- if (!_stack_->f_val->str(fptr, _stack_->buffer[i])) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- iter.cursor = target->count - 1; \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = iter->target->count - 1; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->cursor = 0; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor == 0) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor--; \
- \
- return true; \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor + 1 == iter->target->count) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- iter->cursor++; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor == 0) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->cursor < steps) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- iter->cursor -= steps; \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor + 1 == iter->target->count) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->cursor + steps >= iter->target->count) \
- return false; \
- \
- iter->end = 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 PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->cursor > index) \
- return PFX##_iter_advance(iter, iter->cursor - index); \
- else if (iter->cursor < index) \
- return PFX##_iter_rewind(iter, index - iter->cursor); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return 0; \
- \
- return iter->target->count - 1 - iter->cursor; \
+#define CMC_CMC_STACK_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ /* None */ \
+\
+ 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 < 1) \
+ return NULL; \
+ if (!f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_stack_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_stack_) \
+ return NULL; \
+\
+ _stack_->buffer = alloc->calloc(capacity, sizeof(V)); \
+\
+ if (!_stack_->buffer) \
+ { \
+ alloc->free(_stack_); \
+ return NULL; \
+ } \
+\
+ _stack_->capacity = capacity; \
+ _stack_->count = 0; \
+ _stack_->flag = CMC_FLAG_OK; \
+ _stack_->f_val = f_val; \
+ _stack_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \
+\
+ return _stack_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _stack_) \
+ { \
+ if (_stack_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _stack_->count; i++) \
+ _stack_->f_val->free(_stack_->buffer[i]); \
+ } \
+\
+ memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
+\
+ _stack_->count = 0; \
+ _stack_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _stack_) \
+ { \
+ if (_stack_->f_val->free) \
+ { \
+ for (size_t i = 0; i < _stack_->count; i++) \
+ _stack_->f_val->free(_stack_->buffer[i]); \
+ } \
+\
+ _stack_->alloc->free(_stack_->buffer); \
+ _stack_->alloc->free(_stack_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _stack_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _stack_->alloc = &cmc_alloc_node_default; \
+ else \
+ _stack_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_stack_, callbacks); \
+\
+ _stack_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _push)(struct SNAME * _stack_, V value) \
+ { \
+ if (CMC_(PFX, _full)(_stack_)) \
+ { \
+ if (!CMC_(PFX, _resize)(_stack_, _stack_->capacity * 2)) \
+ return false; \
+ } \
+\
+ _stack_->buffer[_stack_->count++] = value; \
+\
+ _stack_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_stack_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _pop)(struct SNAME * _stack_) \
+ { \
+ if (CMC_(PFX, _empty)(_stack_)) \
+ { \
+ _stack_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ _stack_->buffer[--_stack_->count] = (V){ 0 }; \
+\
+ _stack_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_stack_, delete); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _top)(struct SNAME * _stack_) \
+ { \
+ if (CMC_(PFX, _empty)(_stack_)) \
+ { \
+ _stack_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ _stack_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_stack_, read); \
+\
+ return _stack_->buffer[_stack_->count - 1]; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _stack_, V value) \
+ { \
+ _stack_->flag = CMC_FLAG_OK; \
+\
+ bool result = false; \
+\
+ for (size_t i = 0; i < _stack_->count; i++) \
+ { \
+ if (_stack_->f_val->cmp(_stack_->buffer[i], value) == 0) \
+ { \
+ result = true; \
+ break; \
+ } \
+ } \
+\
+ CMC_CALLBACKS_CALL(_stack_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _stack_) \
+ { \
+ return _stack_->count == 0; \
+ } \
+\
+ bool CMC_(PFX, _full)(struct SNAME * _stack_) \
+ { \
+ return _stack_->count >= _stack_->capacity; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _stack_) \
+ { \
+ return _stack_->count; \
+ } \
+\
+ size_t CMC_(PFX, _capacity)(struct SNAME * _stack_) \
+ { \
+ return _stack_->capacity; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _stack_) \
+ { \
+ return _stack_->flag; \
+ } \
+\
+ bool CMC_(PFX, _resize)(struct SNAME * _stack_, size_t capacity) \
+ { \
+ if (_stack_->capacity == capacity) \
+ goto success; \
+\
+ if (capacity < _stack_->count) \
+ { \
+ _stack_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ V *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(V) * capacity); \
+\
+ if (!new_buffer) \
+ { \
+ _stack_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ /* TODO zero out new slots */ \
+\
+ _stack_->buffer = new_buffer; \
+ _stack_->capacity = capacity; \
+\
+ success: \
+\
+ _stack_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_stack_, resize); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _stack_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_stack_->capacity, _stack_->f_val, _stack_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _stack_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _stack_->callbacks); \
+\
+ if (_stack_->f_val->cpy) \
+ { \
+ for (size_t i = 0; i < _stack_->count; i++) \
+ result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]); \
+ } \
+ else \
+ memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); \
+\
+ result->count = _stack_->count; \
+\
+ _stack_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _stack1_, struct SNAME * _stack2_) \
+ { \
+ _stack1_->flag = CMC_FLAG_OK; \
+ _stack2_->flag = CMC_FLAG_OK; \
+\
+ if (_stack1_->count != _stack2_->count) \
+ return false; \
+\
+ for (size_t i = 0; i < _stack1_->count; i++) \
+ { \
+ if (_stack1_->f_val->cmp(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \
+ return false; \
+ } \
+\
+ return true; \
}
-#endif /* CMC_STACK_H */
+#endif /* CMC_CMC_STACK_H */
diff --git a/src/cmc/treemap.h b/src/cmc/treemap.h
index ebc1474..9f93cfb 100644
--- a/src/cmc/treemap.h
+++ b/src/cmc/treemap.h
@@ -1,5 +1,5 @@
/**
- * treemap.h
+ * cmc/treemap.h
*
* Creation Date: 28/03/2019
*
@@ -16,1259 +16,879 @@
* tree called AVL Tree that uses the height of nodes to keep its keys balanced.
*/
-#ifndef CMC_TREEMAP_H
-#define CMC_TREEMAP_H
+#ifndef CMC_CMC_TREEMAP_H
+#define CMC_CMC_TREEMAP_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core TreeMap implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_TREEMAP_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_TREEMAP_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_TREEMAP_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_TREEMAP_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_TREEMAP_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ struct CMC_DEF_NODE(CMC_PARAM_SNAME(PARAMS)); \
+ CMC_CMC_TREEMAP_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_TREEMAP_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_TREEMAP_CORE_STRUCT(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_TREEMAP_CORE_HEADER(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_TREEMAP_CORE_SOURCE(PARAMS) \
+ CMC_CMC_TREEMAP_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * TreeMap specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_treemap = "struct %s<%s, %s> "
- "at %p { "
- "root:%p, "
- "count:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "f_key:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_TREEMAP(PFX, SNAME, K, V) \
- CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_TREEMAP_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V)
-
-#define CMC_WRAPGEN_TREEMAP_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V)
+#define CMC_CMC_TREEMAP_CORE_STRUCT_(PFX, SNAME, K, V) \
+\
+ /* Treemap Structure */ \
+ struct SNAME \
+ { \
+ /* Root node */ \
+ struct CMC_DEF_NODE(SNAME) * root; \
+\
+ /* Current amount of keys */ \
+ size_t count; \
+\
+ /* Flags indicating errors or success */ \
+ int flag; \
+\
+ /* Key function table */ \
+ struct CMC_DEF_FKEY(SNAME) * f_key; \
+\
+ /* 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; \
+ }; \
+\
+ /* Treemap Node */ \
+ struct CMC_DEF_NODE(SNAME) \
+ { \
+ /* Node Key */ \
+ K key; \
+\
+ /* Node Value */ \
+ V value; \
+\
+ /* Node height used by the AVL tree to keep it strictly balanced */ \
+ unsigned char height; \
+\
+ /* Right child node or subtree */ \
+ struct CMC_DEF_NODE(SNAME) * right; \
+\
+ /* Left child node or subtree */ \
+ struct CMC_DEF_NODE(SNAME) * left; \
+\
+ /* Parent node */ \
+ struct CMC_DEF_NODE(SNAME) * parent; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_TREEMAP_HEADER(PFX, SNAME, K, V) \
- \
- /* Treemap Structure */ \
- struct SNAME \
- { \
- /* Root node */ \
- struct SNAME##_node *root; \
- \
- /* Current amount of keys */ \
- size_t count; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Key function table */ \
- struct SNAME##_fkey *f_key; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Treemap Node */ \
- struct SNAME##_node \
- { \
- /* Node Key */ \
- K key; \
- \
- /* Node Value */ \
- V value; \
- \
- /* Node height used by the AVL tree to keep it strictly balanced */ \
- unsigned char height; \
- \
- /* Right child node or subtree */ \
- struct SNAME##_node *right; \
- \
- /* Left child node or subtree */ \
- struct SNAME##_node *left; \
- \
- /* Parent node */ \
- struct SNAME##_node *parent; \
- }; \
- \
- /* Key struct function table */ \
- struct SNAME##_fkey \
- { \
- /* Comparator function */ \
- int (*cmp)(K, K); \
- \
- /* Copy function */ \
- K (*cpy)(K); \
- \
- /* To string function */ \
- bool (*str)(FILE *, K); \
- \
- /* Free from memory function */ \
- void (*free)(K); \
- \
- /* Hash function */ \
- size_t (*hash)(K); \
- \
- /* Priority function */ \
- int (*pri)(K, K); \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Treemap Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target treemap */ \
- struct SNAME *target; \
- \
- /* Cursor's current node */ \
- struct SNAME##_node *cursor; \
- \
- /* The first node in the iteration */ \
- struct SNAME##_node *first; \
- \
- /* The last node in the iteration */ \
- struct SNAME##_node *last; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom( \
- struct SNAME##_fkey *f_key, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_map_); \
- void PFX##_free(struct SNAME *_map_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_map_, K key, V value); \
- bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value); \
- bool PFX##_remove(struct SNAME *_map_, K key, V *out_value); \
- /* Element Access */ \
- bool PFX##_max(struct SNAME *_map_, K *key, V *value); \
- bool PFX##_min(struct SNAME *_map_, K *key, V *value); \
- V PFX##_get(struct SNAME *_map_, K key); \
- V *PFX##_get_ref(struct SNAME *_map_, K key); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_map_, K key); \
- bool PFX##_empty(struct SNAME *_map_); \
- size_t PFX##_count(struct SNAME *_map_); \
- int PFX##_flag(struct SNAME *_map_); \
- /* Collection Utility */ \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_); \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_map_); \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- K PFX##_iter_key(struct SNAME##_iter *iter); \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter);
+#define CMC_CMC_TREEMAP_CORE_HEADER_(PFX, SNAME, K, V) \
+\
+ /* Key struct function table */ \
+ struct CMC_DEF_FKEY(SNAME) \
+ { \
+ /* Comparator function */ \
+ CMC_DEF_FTAB_CMP(K); \
+\
+ /* Copy function */ \
+ CMC_DEF_FTAB_CPY(K); \
+\
+ /* To string function */ \
+ CMC_DEF_FTAB_STR(K); \
+\
+ /* Free from memory function */ \
+ CMC_DEF_FTAB_FREE(K); \
+\
+ /* Hash function */ \
+ CMC_DEF_FTAB_HASH(K); \
+\
+ /* Priority function */ \
+ CMC_DEF_FTAB_PRI(K); \
+ }; \
+\
+ /* 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)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \
+ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _map_); \
+ void CMC_(PFX, _free)(struct SNAME * _map_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value); \
+ bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value); \
+ bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value); \
+ /* Element Access */ \
+ bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value); \
+ bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value); \
+ V CMC_(PFX, _get)(struct SNAME * _map_, K key); \
+ V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _map_, K key); \
+ bool CMC_(PFX, _empty)(struct SNAME * _map_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _map_); \
+ int CMC_(PFX, _flag)(struct SNAME * _map_); \
+ /* Collection Utility */ \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_TREEMAP_SOURCE(PFX, SNAME, K, V) \
- \
- /* Implementation Detail Functions */ \
- static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_map_, \
- K key, V value); \
- static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_map_, \
- K key); \
- static unsigned char PFX##_impl_h(struct SNAME##_node *node); \
- static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node); \
- static void PFX##_impl_rotate_right(struct SNAME##_node **Z); \
- static void PFX##_impl_rotate_left(struct SNAME##_node **Z); \
- static void PFX##_impl_rebalance(struct SNAME *_map_, \
- struct SNAME##_node *node); \
- \
- struct SNAME *PFX##_new(struct SNAME##_fkey *f_key, \
- struct SNAME##_fval *f_val) \
- { \
- if (!f_key || !f_val) \
- return NULL; \
- \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->count = 0; \
- _map_->root = NULL; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->alloc = alloc; \
- _map_->callbacks = NULL; \
- \
- return _map_; \
- } \
- \
- struct SNAME *PFX##_new_custom( \
- struct SNAME##_fkey *f_key, struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks) \
- { \
- if (!f_key || !f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_map_) \
- return NULL; \
- \
- _map_->count = 0; \
- _map_->root = NULL; \
- _map_->flag = cmc_flags.OK; \
- _map_->f_key = f_key; \
- _map_->f_val = f_val; \
- _map_->alloc = alloc; \
- _map_->callbacks = callbacks; \
- \
- return _map_; \
- } \
- \
- void PFX##_clear(struct SNAME *_map_) \
- { \
- struct SNAME##_node *scan = _map_->root; \
- struct SNAME##_node *up = NULL; \
- \
- while (scan != NULL) \
- { \
- if (scan->left != NULL) \
- { \
- struct SNAME##_node *left = scan->left; \
- \
- scan->left = up; \
- up = scan; \
- scan = left; \
- } \
- else if (scan->right != NULL) \
- { \
- struct SNAME##_node *right = scan->right; \
- \
- scan->left = up; \
- scan->right = NULL; \
- up = scan; \
- scan = right; \
- } \
- else \
- { \
- if (up == NULL) \
- { \
- if (_map_->f_key->free) \
- _map_->f_key->free(scan->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(scan->value); \
- \
- _map_->alloc->free(scan); \
- scan = NULL; \
- } \
- \
- while (up != NULL) \
- { \
- if (_map_->f_key->free) \
- _map_->f_key->free(scan->key); \
- if (_map_->f_val->free) \
- _map_->f_val->free(scan->value); \
- \
- _map_->alloc->free(scan); \
- \
- if (up->right != NULL) \
- { \
- scan = up->right; \
- up->right = NULL; \
- break; \
- } \
- else \
- { \
- scan = up; \
- up = up->left; \
- } \
- } \
- } \
- } \
- \
- _map_->count = 0; \
- _map_->root = NULL; \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_map_) \
- { \
- PFX##_clear(_map_); \
- \
- _map_->alloc->free(_map_); \
- } \
- \
- void PFX##_customize(struct SNAME *_map_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _map_->alloc = &cmc_alloc_node_default; \
- else \
- _map_->alloc = alloc; \
- \
- _map_->callbacks = callbacks; \
- \
- _map_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_map_, K key, V value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->root = PFX##_impl_new_node(_map_, key, value); \
- \
- if (!_map_->root) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- } \
- else \
- { \
- struct SNAME##_node *scan = _map_->root; \
- struct SNAME##_node *parent = scan; \
- \
- while (scan != NULL) \
- { \
- parent = scan; \
- \
- if (_map_->f_key->cmp(scan->key, key) > 0) \
- scan = scan->left; \
- else if (_map_->f_key->cmp(scan->key, key) < 0) \
- scan = scan->right; \
- else \
- { \
- _map_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- } \
- \
- struct SNAME##_node *node; \
- \
- if (_map_->f_key->cmp(parent->key, key) > 0) \
- { \
- parent->left = PFX##_impl_new_node(_map_, key, value); \
- \
- if (!parent->left) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- parent->left->parent = parent; \
- node = parent->left; \
- } \
- else \
- { \
- parent->right = PFX##_impl_new_node(_map_, key, value); \
- \
- if (!parent->right) \
- { \
- _map_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- parent->right->parent = parent; \
- node = parent->right; \
- } \
- \
- PFX##_impl_rebalance(_map_, node); \
- } \
- \
- _map_->count++; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->create) \
- _map_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_update(struct SNAME *_map_, K key, V new_value, V *old_value) \
- { \
- struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
- \
- if (!node) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- if (old_value) \
- *old_value = node->value; \
- \
- node->value = new_value; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->update) \
- _map_->callbacks->update(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_map_, K key, V *out_value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
- \
- if (!node) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- if (out_value) \
- *out_value = node->value; \
- \
- struct SNAME##_node *temp = NULL, *unbalanced = NULL; \
- \
- bool is_root = node->parent == NULL; \
- \
- if (node->left == NULL && node->right == NULL) \
- { \
- if (is_root) \
- _map_->root = NULL; \
- else \
- { \
- unbalanced = node->parent; \
- \
- if (node->parent->right == node) \
- node->parent->right = NULL; \
- else \
- node->parent->left = NULL; \
- } \
- \
- _map_->alloc->free(node); \
- } \
- else if (node->left == NULL) \
- { \
- if (is_root) \
- { \
- _map_->root = node->right; \
- _map_->root->parent = NULL; \
- } \
- else \
- { \
- unbalanced = node->parent; \
- \
- node->right->parent = node->parent; \
- \
- if (node->parent->right == node) \
- node->parent->right = node->right; \
- else \
- node->parent->left = node->right; \
- } \
- \
- _map_->alloc->free(node); \
- } \
- else if (node->right == NULL) \
- { \
- if (is_root) \
- { \
- _map_->root = node->left; \
- _map_->root->parent = NULL; \
- } \
- else \
- { \
- unbalanced = node->parent; \
- \
- node->left->parent = node->parent; \
- \
- if (node->parent->right == node) \
- node->parent->right = node->left; \
- else \
- node->parent->left = node->left; \
- } \
- \
- _map_->alloc->free(node); \
- } \
- else \
- { \
- temp = node->right; \
- while (temp->left != NULL) \
- temp = temp->left; \
- \
- K temp_key = temp->key; \
- V temp_val = temp->value; \
- \
- unbalanced = temp->parent; \
- \
- if (temp->left == NULL && temp->right == NULL) \
- { \
- if (temp->parent->right == temp) \
- temp->parent->right = NULL; \
- else \
- temp->parent->left = NULL; \
- } \
- else if (temp->left == NULL) \
- { \
- temp->right->parent = temp->parent; \
- \
- if (temp->parent->right == temp) \
- temp->parent->right = temp->right; \
- else \
- temp->parent->left = temp->right; \
- } \
- else if (temp->right == NULL) \
- { \
- temp->left->parent = temp->parent; \
- \
- if (temp->parent->right == temp) \
- temp->parent->right = temp->left; \
- else \
- temp->parent->left = temp->left; \
- } \
- \
- _map_->alloc->free(temp); \
- \
- node->key = temp_key; \
- node->value = temp_val; \
- } \
- \
- if (unbalanced != NULL) \
- PFX##_impl_rebalance(_map_, unbalanced); \
- \
- if (_map_->count == 0) \
- _map_->root = NULL; \
- \
- _map_->count--; \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->delete) \
- _map_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_max(struct SNAME *_map_, K *key, V *value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *scan = _map_->root; \
- \
- while (scan->right != NULL) \
- scan = scan->right; \
- \
- if (key) \
- *key = scan->key; \
- if (value) \
- *value = scan->value; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_min(struct SNAME *_map_, K *key, V *value) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *scan = _map_->root; \
- \
- while (scan->left != NULL) \
- scan = scan->left; \
- \
- if (key) \
- *key = scan->key; \
- if (value) \
- *value = scan->value; \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return true; \
- } \
- \
- V PFX##_get(struct SNAME *_map_, K key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
- \
- if (!node) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return (V){ 0 }; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return node->value; \
- } \
- \
- V *PFX##_get_ref(struct SNAME *_map_, K key) \
- { \
- if (PFX##_empty(_map_)) \
- { \
- _map_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *node = PFX##_impl_get_node(_map_, key); \
- \
- if (!node) \
- { \
- _map_->flag = cmc_flags.NOT_FOUND; \
- return NULL; \
- } \
- \
- _map_->flag = cmc_flags.OK; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return &(node->value); \
- } \
- \
- bool PFX##_contains(struct SNAME *_map_, K key) \
- { \
- bool result = PFX##_impl_get_node(_map_, key) != NULL; \
- \
- if (_map_->callbacks && _map_->callbacks->read) \
- _map_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_map_) \
- { \
- return _map_->count == 0; \
- } \
- \
- size_t PFX##_count(struct SNAME *_map_) \
- { \
- return _map_->count; \
- } \
- \
- int PFX##_flag(struct SNAME *_map_) \
- { \
- return _map_->flag; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_map_) \
- { \
- /* Callback will be added later */ \
- struct SNAME *result = \
- PFX##_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, NULL); \
- \
- if (!result) \
- { \
- _map_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- /* TODO turn this into a normal loop */ \
- struct SNAME##_iter iter = PFX##_iter_start(_map_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- K key = PFX##_iter_key(&iter); \
- V value = PFX##_iter_value(&iter); \
- \
- if (_map_->f_key->cpy) \
- key = _map_->f_key->cpy(key); \
- if (_map_->f_val->cpy) \
- value = _map_->f_val->cpy(value); \
- \
- /* TODO check this for errors */ \
- PFX##_insert(result, key, value); \
- } \
- \
- result->callbacks = _map_->callbacks; \
- _map_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_map1_, struct SNAME *_map2_) \
- { \
- _map1_->flag = cmc_flags.OK; \
- _map2_->flag = cmc_flags.OK; \
- \
- if (_map1_->count != _map2_->count) \
- return false; \
- \
- /* TODO turn this into a normal loop */ \
- struct SNAME##_iter iter = PFX##_iter_start(_map1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- struct SNAME##_node *node = \
- PFX##_impl_get_node(_map2_, PFX##_iter_key(&iter)); \
- \
- if (node == NULL) \
- return false; \
- \
- if (_map1_->f_val->cmp(node->value, PFX##_iter_value(&iter)) != 0) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_map_) \
- { \
- struct cmc_string str; \
- struct SNAME *m_ = _map_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treemap, \
- #SNAME, #K, #V, m_, m_->root, m_->count, m_->flag, \
- m_->f_key, m_->f_val, m_->alloc, m_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_map_, FILE *fptr) \
- { \
- struct SNAME##_node *root = _map_->root; \
- \
- bool left_done = false; \
- \
- while (root) \
- { \
- if (!left_done) \
- { \
- while (root->left) \
- root = root->left; \
- } \
- \
- if (!_map_->f_key->str(fptr, root->key) && \
- !_map_->f_val->str(fptr, root->value)) \
- return false; \
- \
- left_done = true; \
- \
- if (root->right) \
- { \
- left_done = false; \
- root = root->right; \
- } \
- else if (root->parent) \
- { \
- while (root->parent && root == root->parent->right) \
- root = root->parent; \
- \
- if (!root->parent) \
- break; \
- \
- root = root->parent; \
- } \
- else \
- break; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->root; \
- iter.first = NULL; \
- iter.last = NULL; \
- iter.index = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- while (iter.cursor->left != NULL) \
- iter.cursor = iter.cursor->left; \
- \
- iter.first = iter.cursor; \
- \
- iter.last = target->root; \
- while (iter.last->right != NULL) \
- iter.last = iter.last->right; \
- } \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->root; \
- iter.first = NULL; \
- iter.last = NULL; \
- iter.index = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- { \
- while (iter.cursor->right != NULL) \
- iter.cursor = iter.cursor->right; \
- \
- iter.last = iter.cursor; \
- \
- iter.first = target->root; \
- while (iter.first->left != NULL) \
- iter.first = iter.first->left; \
- \
- iter.index = target->count - 1; \
- } \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- iter->cursor = iter->first; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- iter->cursor = iter->last; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor == iter->last) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- if (iter->cursor->right != NULL) \
- { \
- iter->cursor = iter->cursor->right; \
- \
- while (iter->cursor->left != NULL) \
- iter->cursor = iter->cursor->left; \
- \
- iter->index++; \
- \
- return true; \
- } \
- \
- while (true) \
- { \
- if (iter->cursor->parent->left == iter->cursor) \
- { \
- iter->cursor = iter->cursor->parent; \
- \
- iter->index++; \
- \
- return true; \
- } \
- \
- iter->cursor = iter->cursor->parent; \
- } \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == iter->first) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- if (iter->cursor->left != NULL) \
- { \
- iter->cursor = iter->cursor->left; \
- \
- while (iter->cursor->right != NULL) \
- iter->cursor = iter->cursor->right; \
- \
- iter->index--; \
- \
- return true; \
- } \
- \
- while (true) \
- { \
- if (iter->cursor->parent->right == iter->cursor) \
- { \
- iter->cursor = iter->cursor->parent; \
- \
- iter->index--; \
- \
- return true; \
- } \
- \
- iter->cursor = iter->cursor->parent; \
- } \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor == iter->last) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == iter->first) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- K PFX##_iter_key(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (K){ 0 }; \
- \
- return iter->cursor->key; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->cursor->value; \
- } \
- \
- V *PFX##_iter_rvalue(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->cursor->value); \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_map_, \
- K key, V value) \
- { \
- struct SNAME##_node *node = \
- _map_->alloc->malloc(sizeof(struct SNAME##_node)); \
- \
- if (!node) \
- return NULL; \
- \
- node->key = key; \
- node->value = value; \
- node->right = NULL; \
- node->left = NULL; \
- node->parent = NULL; \
- node->height = 0; \
- \
- return node; \
- } \
- \
- static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_map_, \
- K key) \
- { \
- struct SNAME##_node *scan = _map_->root; \
- \
- while (scan != NULL) \
- { \
- if (_map_->f_key->cmp(scan->key, key) > 0) \
- scan = scan->left; \
- else if (_map_->f_key->cmp(scan->key, key) < 0) \
- scan = scan->right; \
- else \
- return scan; \
- } \
- \
- return NULL; \
- } \
- \
- static unsigned char PFX##_impl_h(struct SNAME##_node *node) \
- { \
- if (node == NULL) \
- return 0; \
- \
- return node->height; \
- } \
- \
- static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node) \
- { \
- if (node == NULL) \
- return 0; \
- \
- unsigned char h_l = PFX##_impl_h(node->left); \
- unsigned char h_r = PFX##_impl_h(node->right); \
- \
- return 1 + (h_l > h_r ? h_l : h_r); \
- } \
- \
- static void PFX##_impl_rotate_right(struct SNAME##_node **Z) \
- { \
- struct SNAME##_node *root = *Z; \
- struct SNAME##_node *new_root = root->left; \
- \
- if (root->parent != NULL) \
- { \
- if (root->parent->left == root) \
- root->parent->left = new_root; \
- else \
- root->parent->right = new_root; \
- } \
- \
- new_root->parent = root->parent; \
- \
- root->parent = new_root; \
- root->left = new_root->right; \
- \
- if (root->left) \
- root->left->parent = root; \
- \
- new_root->right = root; \
- \
- root->height = PFX##_impl_hupdate(root); \
- new_root->height = PFX##_impl_hupdate(new_root); \
- \
- *Z = new_root; \
- } \
- \
- static void PFX##_impl_rotate_left(struct SNAME##_node **Z) \
- { \
- struct SNAME##_node *root = *Z; \
- struct SNAME##_node *new_root = root->right; \
- \
- if (root->parent != NULL) \
- { \
- if (root->parent->right == root) \
- root->parent->right = new_root; \
- else \
- root->parent->left = new_root; \
- } \
- \
- new_root->parent = root->parent; \
- \
- root->parent = new_root; \
- root->right = new_root->left; \
- \
- if (root->right) \
- root->right->parent = root; \
- \
- new_root->left = root; \
- \
- root->height = PFX##_impl_hupdate(root); \
- new_root->height = PFX##_impl_hupdate(new_root); \
- \
- *Z = new_root; \
- } \
- \
- static void PFX##_impl_rebalance(struct SNAME *_map_, \
- struct SNAME##_node *node) \
- { \
- struct SNAME##_node *scan = node, *child = NULL; \
- \
- int balance; \
- bool is_root = false; \
- \
- while (scan != NULL) \
- { \
- if (scan->parent == NULL) \
- is_root = true; \
- \
- scan->height = PFX##_impl_hupdate(scan); \
- balance = PFX##_impl_h(scan->right) - PFX##_impl_h(scan->left); \
- \
- if (balance >= 2) \
- { \
- child = scan->right; \
- \
- if (PFX##_impl_h(child->right) < PFX##_impl_h(child->left)) \
- PFX##_impl_rotate_right(&(scan->right)); \
- \
- PFX##_impl_rotate_left(&scan); \
- } \
- else if (balance <= -2) \
- { \
- child = scan->left; \
- \
- if (PFX##_impl_h(child->left) < PFX##_impl_h(child->right)) \
- PFX##_impl_rotate_left(&(scan->left)); \
- \
- PFX##_impl_rotate_right(&scan); \
- } \
- \
- if (is_root) \
- { \
- _map_->root = scan; \
- is_root = false; \
- } \
- \
- scan = scan->parent; \
- } \
+#define CMC_CMC_TREEMAP_CORE_SOURCE_(PFX, SNAME, K, V) \
+\
+ /* Implementation Detail Functions */ \
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value); \
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key); \
+ static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \
+ static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node); \
+ static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \
+ static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \
+ static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, struct CMC_DEF_NODE(SNAME) * node); \
+\
+ struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(f_key, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FKEY(SNAME) * f_key, struct CMC_DEF_FVAL(SNAME) * f_val, \
+ struct CMC_ALLOC_NODE_NAME * alloc, struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!f_key || !f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_map_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_map_) \
+ return NULL; \
+\
+ _map_->count = 0; \
+ _map_->root = NULL; \
+ _map_->flag = CMC_FLAG_OK; \
+ _map_->f_key = f_key; \
+ _map_->f_val = f_val; \
+ _map_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ return _map_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _map_) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \
+ struct CMC_DEF_NODE(SNAME) *up = NULL; \
+\
+ while (scan != NULL) \
+ { \
+ if (scan->left != NULL) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *left = scan->left; \
+\
+ scan->left = up; \
+ up = scan; \
+ scan = left; \
+ } \
+ else if (scan->right != NULL) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *right = scan->right; \
+\
+ scan->left = up; \
+ scan->right = NULL; \
+ up = scan; \
+ scan = right; \
+ } \
+ else \
+ { \
+ if (up == NULL) \
+ { \
+ if (_map_->f_key->free) \
+ _map_->f_key->free(scan->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(scan->value); \
+\
+ _map_->alloc->free(scan); \
+ scan = NULL; \
+ } \
+\
+ while (up != NULL) \
+ { \
+ if (_map_->f_key->free) \
+ _map_->f_key->free(scan->key); \
+ if (_map_->f_val->free) \
+ _map_->f_val->free(scan->value); \
+\
+ _map_->alloc->free(scan); \
+\
+ if (up->right != NULL) \
+ { \
+ scan = up->right; \
+ up->right = NULL; \
+ break; \
+ } \
+ else \
+ { \
+ scan = up; \
+ up = up->left; \
+ } \
+ } \
+ } \
+ } \
+\
+ _map_->count = 0; \
+ _map_->root = NULL; \
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _map_) \
+ { \
+ CMC_(PFX, _clear)(_map_); \
+\
+ _map_->alloc->free(_map_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _map_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _map_->alloc = &cmc_alloc_node_default; \
+ else \
+ _map_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_map_, callbacks); \
+\
+ _map_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _map_, K key, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->root = CMC_(PFX, _impl_new_node)(_map_, key, value); \
+\
+ if (!_map_->root) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+ } \
+ else \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \
+ struct CMC_DEF_NODE(SNAME) *parent = scan; \
+\
+ while (scan != NULL) \
+ { \
+ parent = scan; \
+\
+ if (_map_->f_key->cmp(scan->key, key) > 0) \
+ scan = scan->left; \
+ else if (_map_->f_key->cmp(scan->key, key) < 0) \
+ scan = scan->right; \
+ else \
+ { \
+ _map_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * node; \
+\
+ if (_map_->f_key->cmp(parent->key, key) > 0) \
+ { \
+ parent->left = CMC_(PFX, _impl_new_node)(_map_, key, value); \
+\
+ if (!parent->left) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ parent->left->parent = parent; \
+ node = parent->left; \
+ } \
+ else \
+ { \
+ parent->right = CMC_(PFX, _impl_new_node)(_map_, key, value); \
+\
+ if (!parent->right) \
+ { \
+ _map_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ parent->right->parent = parent; \
+ node = parent->right; \
+ } \
+\
+ CMC_(PFX, _impl_rebalance)(_map_, node); \
+ } \
+\
+ _map_->count++; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _update)(struct SNAME * _map_, K key, V new_value, V * old_value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \
+\
+ if (!node) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ if (old_value) \
+ *old_value = node->value; \
+\
+ node->value = new_value; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, update); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _map_, K key, V * out_value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \
+\
+ if (!node) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ if (out_value) \
+ *out_value = node->value; \
+\
+ struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \
+\
+ bool is_root = node->parent == NULL; \
+\
+ if (node->left == NULL && node->right == NULL) \
+ { \
+ if (is_root) \
+ _map_->root = NULL; \
+ else \
+ { \
+ unbalanced = node->parent; \
+\
+ if (node->parent->right == node) \
+ node->parent->right = NULL; \
+ else \
+ node->parent->left = NULL; \
+ } \
+\
+ _map_->alloc->free(node); \
+ } \
+ else if (node->left == NULL) \
+ { \
+ if (is_root) \
+ { \
+ _map_->root = node->right; \
+ _map_->root->parent = NULL; \
+ } \
+ else \
+ { \
+ unbalanced = node->parent; \
+\
+ node->right->parent = node->parent; \
+\
+ if (node->parent->right == node) \
+ node->parent->right = node->right; \
+ else \
+ node->parent->left = node->right; \
+ } \
+\
+ _map_->alloc->free(node); \
+ } \
+ else if (node->right == NULL) \
+ { \
+ if (is_root) \
+ { \
+ _map_->root = node->left; \
+ _map_->root->parent = NULL; \
+ } \
+ else \
+ { \
+ unbalanced = node->parent; \
+\
+ node->left->parent = node->parent; \
+\
+ if (node->parent->right == node) \
+ node->parent->right = node->left; \
+ else \
+ node->parent->left = node->left; \
+ } \
+\
+ _map_->alloc->free(node); \
+ } \
+ else \
+ { \
+ temp = node->right; \
+ while (temp->left != NULL) \
+ temp = temp->left; \
+\
+ K temp_key = temp->key; \
+ V temp_val = temp->value; \
+\
+ unbalanced = temp->parent; \
+\
+ if (temp->left == NULL && temp->right == NULL) \
+ { \
+ if (temp->parent->right == temp) \
+ temp->parent->right = NULL; \
+ else \
+ temp->parent->left = NULL; \
+ } \
+ else if (temp->left == NULL) \
+ { \
+ temp->right->parent = temp->parent; \
+\
+ if (temp->parent->right == temp) \
+ temp->parent->right = temp->right; \
+ else \
+ temp->parent->left = temp->right; \
+ } \
+ else if (temp->right == NULL) \
+ { \
+ temp->left->parent = temp->parent; \
+\
+ if (temp->parent->right == temp) \
+ temp->parent->right = temp->left; \
+ else \
+ temp->parent->left = temp->left; \
+ } \
+\
+ _map_->alloc->free(temp); \
+\
+ node->key = temp_key; \
+ node->value = temp_val; \
+ } \
+\
+ if (unbalanced != NULL) \
+ CMC_(PFX, _impl_rebalance)(_map_, unbalanced); \
+\
+ if (_map_->count == 0) \
+ _map_->root = NULL; \
+\
+ _map_->count--; \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _max)(struct SNAME * _map_, K * key, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \
+\
+ while (scan->right != NULL) \
+ scan = scan->right; \
+\
+ if (key) \
+ *key = scan->key; \
+ if (value) \
+ *value = scan->value; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _min)(struct SNAME * _map_, K * key, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \
+\
+ while (scan->left != NULL) \
+ scan = scan->left; \
+\
+ if (key) \
+ *key = scan->key; \
+ if (value) \
+ *value = scan->value; \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _get)(struct SNAME * _map_, K key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return (V){ 0 }; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \
+\
+ if (!node) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return (V){ 0 }; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return node->value; \
+ } \
+\
+ V *CMC_(PFX, _get_ref)(struct SNAME * _map_, K key) \
+ { \
+ if (CMC_(PFX, _empty)(_map_)) \
+ { \
+ _map_->flag = CMC_FLAG_EMPTY; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map_, key); \
+\
+ if (!node) \
+ { \
+ _map_->flag = CMC_FLAG_NOT_FOUND; \
+ return NULL; \
+ } \
+\
+ _map_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return &(node->value); \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _map_, K key) \
+ { \
+ bool result = CMC_(PFX, _impl_get_node)(_map_, key) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_map_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _map_) \
+ { \
+ return _map_->count == 0; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _map_) \
+ { \
+ return _map_->count; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _map_) \
+ { \
+ return _map_->flag; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _map_) \
+ { \
+ /* Callback will be added later */ \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_map_->f_key, _map_->f_val, _map_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _map_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ /* TODO turn this into a normal loop */ \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ K key = CMC_(PFX, _iter_key)(&iter); \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (_map_->f_key->cpy) \
+ key = _map_->f_key->cpy(key); \
+ if (_map_->f_val->cpy) \
+ value = _map_->f_val->cpy(value); \
+\
+ /* TODO check this for errors */ \
+ CMC_(PFX, _insert)(result, key, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _map_->callbacks); \
+ _map_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _map1_, struct SNAME * _map2_) \
+ { \
+ _map1_->flag = CMC_FLAG_OK; \
+ _map2_->flag = CMC_FLAG_OK; \
+\
+ if (_map1_->count != _map2_->count) \
+ return false; \
+\
+ /* TODO turn this into a normal loop */ \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_map1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_map2_, CMC_(PFX, _iter_key)(&iter)); \
+\
+ if (node == NULL) \
+ return false; \
+\
+ if (_map1_->f_val->cmp(node->value, CMC_(PFX, _iter_value)(&iter)) != 0) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _map_, K key, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *node = _map_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \
+\
+ if (!node) \
+ return NULL; \
+\
+ node->key = key; \
+ node->value = value; \
+ node->right = NULL; \
+ node->left = NULL; \
+ node->parent = NULL; \
+ node->height = 0; \
+\
+ return node; \
+ } \
+\
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _map_, K key) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _map_->root; \
+\
+ while (scan != NULL) \
+ { \
+ if (_map_->f_key->cmp(scan->key, key) > 0) \
+ scan = scan->left; \
+ else if (_map_->f_key->cmp(scan->key, key) < 0) \
+ scan = scan->right; \
+ else \
+ return scan; \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \
+ { \
+ if (node == NULL) \
+ return 0; \
+\
+ return node->height; \
+ } \
+\
+ static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node) \
+ { \
+ if (node == NULL) \
+ return 0; \
+\
+ unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \
+ unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \
+\
+ return 1 + (h_l > h_r ? h_l : h_r); \
+ } \
+\
+ static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *root = *Z; \
+ struct CMC_DEF_NODE(SNAME) *new_root = root->left; \
+\
+ if (root->parent != NULL) \
+ { \
+ if (root->parent->left == root) \
+ root->parent->left = new_root; \
+ else \
+ root->parent->right = new_root; \
+ } \
+\
+ new_root->parent = root->parent; \
+\
+ root->parent = new_root; \
+ root->left = new_root->right; \
+\
+ if (root->left) \
+ root->left->parent = root; \
+\
+ new_root->right = root; \
+\
+ root->height = CMC_(PFX, _impl_hupdate)(root); \
+ new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \
+\
+ *Z = new_root; \
+ } \
+\
+ static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *root = *Z; \
+ struct CMC_DEF_NODE(SNAME) *new_root = root->right; \
+\
+ if (root->parent != NULL) \
+ { \
+ if (root->parent->right == root) \
+ root->parent->right = new_root; \
+ else \
+ root->parent->left = new_root; \
+ } \
+\
+ new_root->parent = root->parent; \
+\
+ root->parent = new_root; \
+ root->right = new_root->left; \
+\
+ if (root->right) \
+ root->right->parent = root; \
+\
+ new_root->left = root; \
+\
+ root->height = CMC_(PFX, _impl_hupdate)(root); \
+ new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \
+\
+ *Z = new_root; \
+ } \
+\
+ static void CMC_(PFX, _impl_rebalance)(struct SNAME * _map_, struct CMC_DEF_NODE(SNAME) * node) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \
+\
+ int balance; \
+ bool is_root = false; \
+\
+ while (scan != NULL) \
+ { \
+ if (scan->parent == NULL) \
+ is_root = true; \
+\
+ scan->height = CMC_(PFX, _impl_hupdate)(scan); \
+ balance = CMC_(PFX, _impl_h)(scan->right) - CMC_(PFX, _impl_h)(scan->left); \
+\
+ if (balance >= 2) \
+ { \
+ child = scan->right; \
+\
+ if (CMC_(PFX, _impl_h)(child->right) < CMC_(PFX, _impl_h)(child->left)) \
+ CMC_(PFX, _impl_rotate_right)(&(scan->right)); \
+\
+ CMC_(PFX, _impl_rotate_left)(&scan); \
+ } \
+ else if (balance <= -2) \
+ { \
+ child = scan->left; \
+\
+ if (CMC_(PFX, _impl_h)(child->left) < CMC_(PFX, _impl_h)(child->right)) \
+ CMC_(PFX, _impl_rotate_left)(&(scan->left)); \
+\
+ CMC_(PFX, _impl_rotate_right)(&scan); \
+ } \
+\
+ if (is_root) \
+ { \
+ _map_->root = scan; \
+ is_root = false; \
+ } \
+\
+ scan = scan->parent; \
+ } \
}
-#endif /* CMC_TREEMAP_H */
+#endif /* CMC_CMC_TREEMAP_H */
diff --git a/src/cmc/treeset.h b/src/cmc/treeset.h
index 2c2a103..be3ffd4 100644
--- a/src/cmc/treeset.h
+++ b/src/cmc/treeset.h
@@ -1,5 +1,5 @@
/**
- * treeset.h
+ * cmc/treeset.h
*
* Creation Date: 27/03/2019
*
@@ -16,1335 +16,751 @@
* tree called AVL Tree that uses the height of nodes to keep its keys balanced.
*/
-#ifndef CMC_TREESET_H
-#define CMC_TREESET_H
+#ifndef CMC_CMC_TREESET_H
+#define CMC_CMC_TREESET_H
/* -------------------------------------------------------------------------
* Core functionalities of the C Macro Collections Library
* ------------------------------------------------------------------------- */
#include "../cor/core.h"
+/**
+ * Core TreeSet implementation
+ *
+ * \param ACCESS Either PUBLIC or PRIVATE
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define CMC_CMC_TREESET_CORE(ACCESS, FILE, PARAMS) CMC_(CMC_(CMC_CMC_TREESET_CORE_, ACCESS), CMC_(_, FILE))(PARAMS)
+
+/* PRIVATE or PUBLIC solver */
+#define CMC_CMC_TREESET_CORE_PUBLIC_HEADER(PARAMS) \
+ CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_TREESET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_TREESET_CORE_PUBLIC_SOURCE(PARAMS) CMC_CMC_TREESET_CORE_SOURCE(PARAMS)
+
+#define CMC_CMC_TREESET_CORE_PRIVATE_HEADER(PARAMS) \
+ struct CMC_PARAM_SNAME(PARAMS); \
+ CMC_CMC_TREESET_CORE_HEADER(PARAMS)
+
+#define CMC_CMC_TREESET_CORE_PRIVATE_SOURCE(PARAMS) \
+ CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_TREESET_CORE_SOURCE(PARAMS)
+
+/* Lowest level API */
+#define CMC_CMC_TREESET_CORE_STRUCT(PARAMS) \
+ CMC_CMC_TREESET_CORE_STRUCT_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_TREESET_CORE_HEADER(PARAMS) \
+ CMC_CMC_TREESET_CORE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_CMC_TREESET_CORE_SOURCE(PARAMS) \
+ CMC_CMC_TREESET_CORE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
/* -------------------------------------------------------------------------
- * TreeSet specific
+ * Struct
* ------------------------------------------------------------------------- */
-/* to_string format */
-static const char *cmc_string_fmt_treeset = "struct %s<%s> "
- "at %p { "
- "root:%p, "
- "count:%" PRIuMAX ", "
- "flag:%d, "
- "f_val:%p, "
- "alloc:%p, "
- "callbacks:%p }";
-
-#define CMC_GENERATE_TREESET(PFX, SNAME, V) \
- CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \
- CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_TREESET_HEADER(PFX, SNAME, K, V) \
- CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V)
-
-#define CMC_WRAPGEN_TREESET_SOURCE(PFX, SNAME, K, V) \
- CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V)
+#define CMC_CMC_TREESET_CORE_STRUCT_(PFX, SNAME, V) \
+\
+ /* Treeset Structure */ \
+ struct SNAME \
+ { \
+ /* Root node */ \
+ struct CMC_DEF_NODE(SNAME) * root; \
+\
+ /* Current amount of elements */ \
+ 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; \
+ }; \
+\
+ /* Treeset Node */ \
+ struct CMC_DEF_NODE(SNAME) \
+ { \
+ /* Node element */ \
+ V value; \
+\
+ /* Node height used by the AVL tree to keep it strictly balanced */ \
+ unsigned char height; \
+\
+ /* Right child node or subtree */ \
+ struct CMC_DEF_NODE(SNAME) * right; \
+\
+ /* Left child node or subtree */ \
+ struct CMC_DEF_NODE(SNAME) * left; \
+\
+ /* Parent node */ \
+ struct CMC_DEF_NODE(SNAME) * parent; \
+ };
/* -------------------------------------------------------------------------
* Header
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_TREESET_HEADER(PFX, SNAME, V) \
- \
- /* Treeset Structure */ \
- struct SNAME \
- { \
- /* Root node */ \
- struct SNAME##_node *root; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Flags indicating errors or success */ \
- int flag; \
- \
- /* Value function table */ \
- struct SNAME##_fval *f_val; \
- \
- /* Custom allocation functions */ \
- struct cmc_alloc_node *alloc; \
- \
- /* Custom callback functions */ \
- struct cmc_callbacks *callbacks; \
- }; \
- \
- /* Treeset Node */ \
- struct SNAME##_node \
- { \
- /* Node element */ \
- V value; \
- \
- /* Node height used by the AVL tree to keep it strictly balanced */ \
- unsigned char height; \
- \
- /* Right child node or subtree */ \
- struct SNAME##_node *right; \
- \
- /* Left child node or subtree */ \
- struct SNAME##_node *left; \
- \
- /* Parent node */ \
- struct SNAME##_node *parent; \
- }; \
- \
- /* Value struct function table */ \
- struct SNAME##_fval \
- { \
- /* Comparator function */ \
- int (*cmp)(V, V); \
- \
- /* Copy function */ \
- V (*cpy)(V); \
- \
- /* To string function */ \
- bool (*str)(FILE *, V); \
- \
- /* Free from memory function */ \
- void (*free)(V); \
- \
- /* Hash function */ \
- size_t (*hash)(V); \
- \
- /* Priority function */ \
- int (*pri)(V, V); \
- }; \
- \
- /* Treeset Iterator */ \
- struct SNAME##_iter \
- { \
- /* Target treeset */ \
- struct SNAME *target; \
- \
- /* Cursor's current node */ \
- struct SNAME##_node *cursor; \
- \
- /* The first node in the iteration */ \
- struct SNAME##_node *first; \
- \
- /* The last node in the iteration */ \
- struct SNAME##_node *last; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- }; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- struct SNAME *PFX##_new(struct SNAME##_fval *f_val); \
- struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- void PFX##_clear(struct SNAME *_set_); \
- void PFX##_free(struct SNAME *_set_); \
- /* Customization of Allocation and Callbacks */ \
- void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks); \
- /* Collection Input and Output */ \
- bool PFX##_insert(struct SNAME *_set_, V value); \
- bool PFX##_remove(struct SNAME *_set_, V value); \
- /* Element Access */ \
- bool PFX##_max(struct SNAME *_set_, V *value); \
- bool PFX##_min(struct SNAME *_set_, V *value); \
- /* Collection State */ \
- bool PFX##_contains(struct SNAME *_set_, V value); \
- bool PFX##_empty(struct SNAME *_set_); \
- size_t PFX##_count(struct SNAME *_set_); \
- int PFX##_flag(struct SNAME *_set_); \
- /* Collection Utility */ \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_); \
- bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct cmc_string PFX##_to_string(struct SNAME *_set_); \
- bool PFX##_print(struct SNAME *_set_, FILE *fptr); \
- \
- /* Set Operations */ \
- struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_); \
- struct SNAME *PFX##_intersection(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- struct SNAME *PFX##_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_); \
- bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_); \
- bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target); \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target); \
- /* Iterator State */ \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter); \
- /* Iterator Movement */ \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter); \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter); \
- bool PFX##_iter_next(struct SNAME##_iter *iter); \
- bool PFX##_iter_prev(struct SNAME##_iter *iter); \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps); \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index); \
- /* Iterator Access */ \
- V PFX##_iter_value(struct SNAME##_iter *iter); \
- size_t PFX##_iter_index(struct SNAME##_iter *iter); \
- \
- /* Default Value */ \
- static inline V PFX##_impl_default_value(void) \
- { \
- V _empty_value_; \
- \
- memset(&_empty_value_, 0, sizeof(V)); \
- \
- return _empty_value_; \
- }
+#define CMC_CMC_TREESET_CORE_HEADER_(PFX, SNAME, V) \
+\
+ /* 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)(struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _clear)(struct SNAME * _set_); \
+ void CMC_(PFX, _free)(struct SNAME * _set_); \
+ /* Customization of Allocation and Callbacks */ \
+ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ /* Collection Input and Output */ \
+ bool CMC_(PFX, _insert)(struct SNAME * _set_, V value); \
+ bool CMC_(PFX, _remove)(struct SNAME * _set_, V value); \
+ /* Element Access */ \
+ bool CMC_(PFX, _max)(struct SNAME * _set_, V * value); \
+ bool CMC_(PFX, _min)(struct SNAME * _set_, V * value); \
+ /* Collection State */ \
+ bool CMC_(PFX, _contains)(struct SNAME * _set_, V value); \
+ bool CMC_(PFX, _empty)(struct SNAME * _set_); \
+ size_t CMC_(PFX, _count)(struct SNAME * _set_); \
+ int CMC_(PFX, _flag)(struct SNAME * _set_); \
+ /* Collection Utility */ \
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_); \
+ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_);
/* -------------------------------------------------------------------------
* Source
* ------------------------------------------------------------------------- */
-#define CMC_GENERATE_TREESET_SOURCE(PFX, SNAME, V) \
- \
- /* Implementation Detail Functions */ \
- static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_set_, \
- V value); \
- static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_set_, \
- V value); \
- static unsigned char PFX##_impl_h(struct SNAME##_node *node); \
- static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node); \
- static void PFX##_impl_rotate_right(struct SNAME##_node **Z); \
- static void PFX##_impl_rotate_left(struct SNAME##_node **Z); \
- static void PFX##_impl_rebalance(struct SNAME *_set_, \
- struct SNAME##_node *node); \
- \
- struct SNAME *PFX##_new(struct SNAME##_fval *f_val) \
- { \
- if (!f_val) \
- return NULL; \
- \
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_set_) \
- return NULL; \
- \
- _set_->count = 0; \
- _set_->root = NULL; \
- _set_->flag = cmc_flags.OK; \
- _set_->f_val = f_val; \
- _set_->alloc = alloc; \
- _set_->callbacks = NULL; \
- \
- return _set_; \
- } \
- \
- struct SNAME *PFX##_new_custom(struct SNAME##_fval *f_val, \
- struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!f_val) \
- return NULL; \
- \
- if (!alloc) \
- alloc = &cmc_alloc_node_default; \
- \
- struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
- \
- if (!_set_) \
- return NULL; \
- \
- _set_->count = 0; \
- _set_->root = NULL; \
- _set_->flag = cmc_flags.OK; \
- _set_->f_val = f_val; \
- _set_->alloc = alloc; \
- _set_->callbacks = callbacks; \
- \
- return _set_; \
- } \
- \
- void PFX##_clear(struct SNAME *_set_) \
- { \
- struct SNAME##_node *scan = _set_->root; \
- struct SNAME##_node *up = NULL; \
- \
- while (scan != NULL) \
- { \
- if (scan->left != NULL) \
- { \
- struct SNAME##_node *left = scan->left; \
- \
- scan->left = up; \
- up = scan; \
- scan = left; \
- } \
- else if (scan->right != NULL) \
- { \
- struct SNAME##_node *right = scan->right; \
- \
- scan->left = up; \
- scan->right = NULL; \
- up = scan; \
- scan = right; \
- } \
- else \
- { \
- if (up == NULL) \
- { \
- if (_set_->f_val->free) \
- _set_->f_val->free(scan->value); \
- \
- _set_->alloc->free(scan); \
- scan = NULL; \
- } \
- \
- while (up != NULL) \
- { \
- if (_set_->f_val->free) \
- _set_->f_val->free(scan->value); \
- \
- _set_->alloc->free(scan); \
- \
- if (up->right != NULL) \
- { \
- scan = up->right; \
- up->right = NULL; \
- break; \
- } \
- else \
- { \
- scan = up; \
- up = up->left; \
- } \
- } \
- } \
- } \
- \
- _set_->count = 0; \
- _set_->root = NULL; \
- _set_->flag = cmc_flags.OK; \
- } \
- \
- void PFX##_free(struct SNAME *_set_) \
- { \
- PFX##_clear(_set_); \
- \
- _set_->alloc->free(_set_); \
- } \
- \
- void PFX##_customize(struct SNAME *_set_, struct cmc_alloc_node *alloc, \
- struct cmc_callbacks *callbacks) \
- { \
- if (!alloc) \
- _set_->alloc = &cmc_alloc_node_default; \
- else \
- _set_->alloc = alloc; \
- \
- _set_->callbacks = callbacks; \
- \
- _set_->flag = cmc_flags.OK; \
- } \
- \
- bool PFX##_insert(struct SNAME *_set_, V value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->root = PFX##_impl_new_node(_set_, value); \
- \
- if (!_set_->root) \
- { \
- _set_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- } \
- else \
- { \
- struct SNAME##_node *scan = _set_->root; \
- struct SNAME##_node *parent = scan; \
- \
- while (scan != NULL) \
- { \
- parent = scan; \
- \
- if (_set_->f_val->cmp(scan->value, value) > 0) \
- scan = scan->left; \
- else if (_set_->f_val->cmp(scan->value, value) < 0) \
- scan = scan->right; \
- else \
- { \
- _set_->flag = cmc_flags.DUPLICATE; \
- return false; \
- } \
- } \
- \
- struct SNAME##_node *node; \
- \
- if (_set_->f_val->cmp(parent->value, value) > 0) \
- { \
- parent->left = PFX##_impl_new_node(_set_, value); \
- \
- if (!parent->left) \
- { \
- _set_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- parent->left->parent = parent; \
- node = parent->left; \
- } \
- else \
- { \
- parent->right = PFX##_impl_new_node(_set_, value); \
- \
- if (!parent->right) \
- { \
- _set_->flag = cmc_flags.ALLOC; \
- return false; \
- } \
- \
- parent->right->parent = parent; \
- node = parent->right; \
- } \
- \
- PFX##_impl_rebalance(_set_, node); \
- } \
- \
- _set_->count++; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->create) \
- _set_->callbacks->create(); \
- \
- return true; \
- } \
- \
- bool PFX##_remove(struct SNAME *_set_, V value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *node = PFX##_impl_get_node(_set_, value); \
- \
- if (!node) \
- { \
- _set_->flag = cmc_flags.NOT_FOUND; \
- return false; \
- } \
- \
- struct SNAME##_node *temp = NULL, *unbalanced = NULL; \
- \
- bool is_root = node->parent == NULL; \
- \
- if (node->left == NULL && node->right == NULL) \
- { \
- if (is_root) \
- _set_->root = NULL; \
- else \
- { \
- unbalanced = node->parent; \
- \
- if (node->parent->right == node) \
- node->parent->right = NULL; \
- else \
- node->parent->left = NULL; \
- } \
- \
- _set_->alloc->free(node); \
- } \
- else if (node->left == NULL) \
- { \
- if (is_root) \
- { \
- _set_->root = node->right; \
- _set_->root->parent = NULL; \
- } \
- else \
- { \
- unbalanced = node->parent; \
- \
- node->right->parent = node->parent; \
- \
- if (node->parent->right == node) \
- node->parent->right = node->right; \
- else \
- node->parent->left = node->right; \
- } \
- \
- _set_->alloc->free(node); \
- } \
- else if (node->right == NULL) \
- { \
- if (is_root) \
- { \
- _set_->root = node->left; \
- _set_->root->parent = NULL; \
- } \
- else \
- { \
- unbalanced = node->parent; \
- \
- node->left->parent = node->parent; \
- \
- if (node->parent->right == node) \
- node->parent->right = node->left; \
- else \
- node->parent->left = node->left; \
- } \
- \
- _set_->alloc->free(node); \
- } \
- else \
- { \
- temp = node->right; \
- while (temp->left != NULL) \
- temp = temp->left; \
- \
- V temp_value = temp->value; \
- \
- unbalanced = temp->parent; \
- \
- if (temp->left == NULL && temp->right == NULL) \
- { \
- if (temp->parent->right == temp) \
- temp->parent->right = NULL; \
- else \
- temp->parent->left = NULL; \
- } \
- else if (temp->left == NULL) \
- { \
- temp->right->parent = temp->parent; \
- \
- if (temp->parent->right == temp) \
- temp->parent->right = temp->right; \
- else \
- temp->parent->left = temp->right; \
- } \
- else if (temp->right == NULL) \
- { \
- temp->left->parent = temp->parent; \
- \
- if (temp->parent->right == temp) \
- temp->parent->right = temp->left; \
- else \
- temp->parent->left = temp->left; \
- } \
- \
- _set_->alloc->free(temp); \
- \
- node->value = temp_value; \
- } \
- \
- if (unbalanced != NULL) \
- PFX##_impl_rebalance(_set_, unbalanced); \
- \
- if (_set_->count == 0) \
- _set_->root = NULL; \
- \
- _set_->count--; \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->delete) \
- _set_->callbacks->delete (); \
- \
- return true; \
- } \
- \
- bool PFX##_max(struct SNAME *_set_, V *value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *scan = _set_->root; \
- \
- while (scan->right != NULL) \
- scan = scan->right; \
- \
- if (value) \
- *value = scan->value; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_min(struct SNAME *_set_, V *value) \
- { \
- if (PFX##_empty(_set_)) \
- { \
- _set_->flag = cmc_flags.EMPTY; \
- return false; \
- } \
- \
- struct SNAME##_node *scan = _set_->root; \
- \
- while (scan->left != NULL) \
- scan = scan->left; \
- \
- if (value) \
- *value = scan->value; \
- \
- _set_->flag = cmc_flags.OK; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return true; \
- } \
- \
- bool PFX##_contains(struct SNAME *_set_, V value) \
- { \
- bool result = PFX##_impl_get_node(_set_, value) != NULL; \
- \
- if (_set_->callbacks && _set_->callbacks->read) \
- _set_->callbacks->read(); \
- \
- return result; \
- } \
- \
- bool PFX##_empty(struct SNAME *_set_) \
- { \
- return _set_->count == 0; \
- } \
- \
- size_t PFX##_count(struct SNAME *_set_) \
- { \
- return _set_->count; \
- } \
- \
- int PFX##_flag(struct SNAME *_set_) \
- { \
- return _set_->flag; \
- } \
- \
- struct SNAME *PFX##_copy_of(struct SNAME *_set_) \
- { \
- struct SNAME *result = \
- PFX##_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks); \
- \
- if (!result) \
- { \
- _set_->flag = cmc_flags.ERROR; \
- return NULL; \
- } \
- \
- if (!PFX##_empty(_set_)) \
- { \
- struct SNAME##_iter iter = PFX##_iter_start(_set_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- if (_set_->f_val->cpy) \
- PFX##_insert(result, \
- _set_->f_val->cpy(PFX##_iter_value(&iter))); \
- else \
- PFX##_insert(result, PFX##_iter_value(&iter)); \
- } \
- } \
- \
- _set_->flag = cmc_flags.OK; \
- \
- return result; \
- } \
- \
- bool PFX##_equals(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- _set1_->flag = cmc_flags.OK; \
- _set2_->flag = cmc_flags.OK; \
- \
- if (_set1_->count != _set2_->count) \
- return false; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- if (PFX##_impl_get_node(_set2_, PFX##_iter_value(&iter)) == NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct cmc_string PFX##_to_string(struct SNAME *_set_) \
- { \
- struct cmc_string str; \
- struct SNAME *s_ = _set_; \
- \
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treeset, \
- #SNAME, #V, s_, s_->root, s_->count, s_->flag, \
- s_->f_val, s_->alloc, s_->callbacks); \
- \
- return n >= 0 ? str : (struct cmc_string){ 0 }; \
- } \
- \
- bool PFX##_print(struct SNAME *_set_, FILE *fptr) \
- { \
- struct SNAME##_node *root = _set_->root; \
- \
- bool left_done = false; \
- \
- while (root) \
- { \
- if (!left_done) \
- { \
- while (root->left) \
- root = root->left; \
- } \
- \
- if (!_set_->f_val->str(fptr, root->value)) \
- return false; \
- \
- left_done = true; \
- \
- if (root->right) \
- { \
- left_done = false; \
- root = root->right; \
- } \
- else if (root->parent) \
- { \
- while (root->parent && root == root->parent->right) \
- root = root->parent; \
- \
- if (!root->parent) \
- break; \
- \
- root = root->parent; \
- } \
- else \
- break; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME *PFX##_union(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- PFX##_insert(_set_r_, PFX##_iter_value(&iter1)); \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- PFX##_insert(_set_r_, PFX##_iter_value(&iter2)); \
- } \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_intersection(struct SNAME *_set1_, \
- struct SNAME *_set2_) \
- { \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- /** TODO Should this compare count or capacity? */ \
- struct SNAME *_set_A_ = \
- _set1_->count < _set2_->count ? _set1_ : _set2_; \
- struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set_A_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_node(_set_B_, value) != NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_difference(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_node(_set2_, value) == NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- return _set_r_; \
- } \
- \
- struct SNAME *PFX##_symmetric_difference(struct SNAME *_set1_, \
- struct SNAME *_set2_) \
- { \
- struct SNAME *_set_r_ = \
- PFX##_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks); \
- \
- if (!_set_r_) \
- return NULL; \
- \
- struct SNAME##_iter iter1 = PFX##_iter_start(_set1_); \
- struct SNAME##_iter iter2 = PFX##_iter_start(_set2_); \
- \
- for (; !PFX##_iter_at_end(&iter1); PFX##_iter_next(&iter1)) \
- { \
- V value = PFX##_iter_value(&iter1); \
- \
- if (PFX##_impl_get_node(_set2_, value) == NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- for (; !PFX##_iter_at_end(&iter2); PFX##_iter_next(&iter2)) \
- { \
- V value = PFX##_iter_value(&iter2); \
- \
- if (PFX##_impl_get_node(_set1_, value) == NULL) \
- PFX##_insert(_set_r_, value); \
- } \
- \
- return _set_r_; \
- } \
- \
- /* Is _set1_ a subset of _set2_ ? */ \
- /* A set X is a subset of a set Y when: X <= Y */ \
- /* If X is a subset of Y, then Y is a superset of X */ \
- bool PFX##_is_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* If the cardinality of _set1_ is greater than that of _set2_ */ \
- /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \
- if (_set1_->count > _set2_->count) \
- return false; \
- \
- /* The empty set is a subset of all sets */ \
- if (PFX##_empty(_set1_)) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_node(_set2_, value) == NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- /* Is _set1_ a superset of _set2_ ? */ \
- /* A set X is a superset of a set Y when: X >= Y */ \
- /* If X is a superset of Y, then Y is a subset of X */ \
- bool PFX##_is_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- return PFX##_is_subset(_set2_, _set1_); \
- } \
- \
- /* Is _set1_ a proper subset of _set2_ ? */ \
- /* A set X is a proper subset of a set Y when: X < Y */ \
- /* If X is a proper subset of Y, then Y is a proper superset of X */ \
- bool PFX##_is_proper_subset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* If the cardinality of _set1_ is greater than or equal to that */ \
- /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \
- /* subset of _set2_ */ \
- if (_set1_->count >= _set2_->count) \
- return false; \
- \
- if (PFX##_empty(_set1_)) \
- { \
- /* The empty set is a proper subset of all non-empty sets */ \
- if (!PFX##_empty(_set2_)) \
- return true; \
- /* The empty set is not a proper subset of itself (this is true */ \
- /* for any set) */ \
- else \
- return false; \
- } \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_node(_set2_, value) == NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- /* Is _set1_ a proper superset of _set2_ ? */ \
- /* A set X is a proper superset of a set Y when: X > Y */ \
- /* If X is a proper superset of Y, then Y is a proper subset of X */ \
- bool PFX##_is_proper_superset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- return PFX##_is_proper_subset(_set2_, _set1_); \
- } \
- \
- /* Is _set1_ a disjointset of _set2_ ? */ \
- /* A set X is a disjointset of a set Y if their intersection is empty, */ \
- /* that is, if there are no elements in common between the two */ \
- bool PFX##_is_disjointset(struct SNAME *_set1_, struct SNAME *_set2_) \
- { \
- /* The intersection of an empty set with any other set will result */ \
- /* in an empty set */ \
- if (PFX##_empty(_set1_)) \
- return true; \
- \
- struct SNAME##_iter iter = PFX##_iter_start(_set1_); \
- \
- for (; !PFX##_iter_at_end(&iter); PFX##_iter_next(&iter)) \
- { \
- V value = PFX##_iter_value(&iter); \
- \
- if (PFX##_impl_get_node(_set2_, value) != NULL) \
- return false; \
- } \
- \
- return true; \
- } \
- \
- struct SNAME##_iter PFX##_iter_start(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->root; \
- iter.first = NULL; \
- iter.last = NULL; \
- iter.index = 0; \
- iter.start = true; \
- iter.end = PFX##_empty(target); \
- \
- if (!PFX##_empty(target)) \
- { \
- while (iter.cursor->left != NULL) \
- iter.cursor = iter.cursor->left; \
- \
- iter.first = iter.cursor; \
- \
- iter.last = target->root; \
- while (iter.last->right != NULL) \
- iter.last = iter.last->right; \
- } \
- \
- return iter; \
- } \
- \
- struct SNAME##_iter PFX##_iter_end(struct SNAME *target) \
- { \
- struct SNAME##_iter iter; \
- \
- iter.target = target; \
- iter.cursor = target->root; \
- iter.first = NULL; \
- iter.last = NULL; \
- iter.index = 0; \
- iter.start = PFX##_empty(target); \
- iter.end = true; \
- \
- if (!PFX##_empty(target)) \
- { \
- while (iter.cursor->right != NULL) \
- iter.cursor = iter.cursor->right; \
- \
- iter.last = iter.cursor; \
- \
- iter.first = target->root; \
- while (iter.first->left != NULL) \
- iter.first = iter.first->left; \
- \
- iter.index = target->count - 1; \
- } \
- \
- return iter; \
- } \
- \
- bool PFX##_iter_at_start(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- bool PFX##_iter_at_end(struct SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- bool PFX##_iter_to_start(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- iter->cursor = iter->first; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_to_end(struct SNAME##_iter *iter) \
- { \
- if (!PFX##_empty(iter->target)) \
- { \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- iter->cursor = iter->last; \
- \
- return true; \
- } \
- \
- return false; \
- } \
- \
- bool PFX##_iter_next(struct SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor == iter->last) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- if (iter->cursor->right != NULL) \
- { \
- iter->cursor = iter->cursor->right; \
- \
- while (iter->cursor->left != NULL) \
- iter->cursor = iter->cursor->left; \
- \
- iter->index++; \
- \
- return true; \
- } \
- \
- while (true) \
- { \
- if (iter->cursor->parent->left == iter->cursor) \
- { \
- iter->cursor = iter->cursor->parent; \
- \
- iter->index++; \
- \
- return true; \
- } \
- \
- iter->cursor = iter->cursor->parent; \
- } \
- } \
- \
- bool PFX##_iter_prev(struct SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == iter->first) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- if (iter->cursor->left != NULL) \
- { \
- iter->cursor = iter->cursor->left; \
- \
- while (iter->cursor->right != NULL) \
- iter->cursor = iter->cursor->right; \
- \
- iter->index--; \
- \
- return true; \
- } \
- \
- while (true) \
- { \
- if (iter->cursor->parent->right == iter->cursor) \
- { \
- iter->cursor = iter->cursor->parent; \
- \
- iter->index--; \
- \
- return true; \
- } \
- \
- iter->cursor = iter->cursor->parent; \
- } \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_advance(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->end) \
- return false; \
- \
- if (iter->cursor == iter->last) \
- { \
- iter->end = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index + steps >= iter->target->count) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_next(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator moved */ \
- bool PFX##_iter_rewind(struct SNAME##_iter *iter, size_t steps) \
- { \
- if (iter->start) \
- return false; \
- \
- if (iter->cursor == iter->first) \
- { \
- iter->start = true; \
- return false; \
- } \
- \
- if (steps == 0 || iter->index < steps) \
- return false; \
- \
- for (size_t i = 0; i < steps; i++) \
- PFX##_iter_prev(iter); \
- \
- return true; \
- } \
- \
- /* Returns true only if the iterator was able to be positioned at the */ \
- /* given index */ \
- bool PFX##_iter_go_to(struct SNAME##_iter *iter, size_t index) \
- { \
- if (index >= iter->target->count) \
- return false; \
- \
- if (iter->index > index) \
- return PFX##_iter_rewind(iter, iter->index - index); \
- else if (iter->index < index) \
- return PFX##_iter_advance(iter, index - iter->index); \
- \
- return true; \
- } \
- \
- V PFX##_iter_value(struct SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return (V){ 0 }; \
- \
- return iter->cursor->value; \
- } \
- \
- size_t PFX##_iter_index(struct SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static struct SNAME##_node *PFX##_impl_new_node(struct SNAME *_set_, \
- V value) \
- { \
- struct SNAME##_node *node = \
- _set_->alloc->malloc(sizeof(struct SNAME##_node)); \
- \
- if (!node) \
- return NULL; \
- \
- node->value = value; \
- node->right = NULL; \
- node->left = NULL; \
- node->parent = NULL; \
- node->height = 0; \
- \
- return node; \
- } \
- \
- static struct SNAME##_node *PFX##_impl_get_node(struct SNAME *_set_, \
- V value) \
- { \
- struct SNAME##_node *scan = _set_->root; \
- \
- while (scan != NULL) \
- { \
- if (_set_->f_val->cmp(scan->value, value) > 0) \
- scan = scan->left; \
- else if (_set_->f_val->cmp(scan->value, value) < 0) \
- scan = scan->right; \
- else \
- return scan; \
- } \
- \
- return NULL; \
- } \
- \
- static unsigned char PFX##_impl_h(struct SNAME##_node *node) \
- { \
- if (node == NULL) \
- return 0; \
- \
- return node->height; \
- } \
- \
- static unsigned char PFX##_impl_hupdate(struct SNAME##_node *node) \
- { \
- if (node == NULL) \
- return 0; \
- \
- unsigned char h_l = PFX##_impl_h(node->left); \
- unsigned char h_r = PFX##_impl_h(node->right); \
- \
- return 1 + (h_l > h_r ? h_l : h_r); \
- } \
- \
- static void PFX##_impl_rotate_right(struct SNAME##_node **Z) \
- { \
- struct SNAME##_node *root = *Z; \
- struct SNAME##_node *new_root = root->left; \
- \
- if (root->parent != NULL) \
- { \
- if (root->parent->left == root) \
- root->parent->left = new_root; \
- else \
- root->parent->right = new_root; \
- } \
- \
- new_root->parent = root->parent; \
- \
- root->parent = new_root; \
- root->left = new_root->right; \
- \
- if (root->left) \
- root->left->parent = root; \
- \
- new_root->right = root; \
- \
- root->height = PFX##_impl_hupdate(root); \
- new_root->height = PFX##_impl_hupdate(new_root); \
- \
- *Z = new_root; \
- } \
- \
- static void PFX##_impl_rotate_left(struct SNAME##_node **Z) \
- { \
- struct SNAME##_node *root = *Z; \
- struct SNAME##_node *new_root = root->right; \
- \
- if (root->parent != NULL) \
- { \
- if (root->parent->right == root) \
- root->parent->right = new_root; \
- else \
- root->parent->left = new_root; \
- } \
- \
- new_root->parent = root->parent; \
- \
- root->parent = new_root; \
- root->right = new_root->left; \
- \
- if (root->right) \
- root->right->parent = root; \
- \
- new_root->left = root; \
- \
- root->height = PFX##_impl_hupdate(root); \
- new_root->height = PFX##_impl_hupdate(new_root); \
- \
- *Z = new_root; \
- } \
- \
- static void PFX##_impl_rebalance(struct SNAME *_set_, \
- struct SNAME##_node *node) \
- { \
- struct SNAME##_node *scan = node, *child = NULL; \
- \
- int balance; \
- bool is_root = false; \
- \
- while (scan != NULL) \
- { \
- if (scan->parent == NULL) \
- is_root = true; \
- \
- scan->height = PFX##_impl_hupdate(scan); \
- balance = PFX##_impl_h(scan->right) - PFX##_impl_h(scan->left); \
- \
- if (balance >= 2) \
- { \
- child = scan->right; \
- \
- if (PFX##_impl_h(child->right) < PFX##_impl_h(child->left)) \
- PFX##_impl_rotate_right(&(scan->right)); \
- \
- PFX##_impl_rotate_left(&scan); \
- } \
- else if (balance <= -2) \
- { \
- child = scan->left; \
- \
- if (PFX##_impl_h(child->left) < PFX##_impl_h(child->right)) \
- PFX##_impl_rotate_left(&(scan->left)); \
- \
- PFX##_impl_rotate_right(&scan); \
- } \
- \
- if (is_root) \
- { \
- _set_->root = scan; \
- is_root = false; \
- } \
- \
- scan = scan->parent; \
- } \
+#define CMC_CMC_TREESET_CORE_SOURCE_(PFX, SNAME, V) \
+\
+ /* Implementation Detail Functions */ \
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value); \
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value); \
+ static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node); \
+ static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node); \
+ static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z); \
+ static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z); \
+ static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, struct CMC_DEF_NODE(SNAME) * node); \
+\
+ struct SNAME *CMC_(PFX, _new)(struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _new_custom)(f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME *CMC_(PFX, _new_custom)(struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!f_val) \
+ return NULL; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ struct SNAME *_set_ = alloc->malloc(sizeof(struct SNAME)); \
+\
+ if (!_set_) \
+ return NULL; \
+\
+ _set_->count = 0; \
+ _set_->root = NULL; \
+ _set_->flag = CMC_FLAG_OK; \
+ _set_->f_val = f_val; \
+ _set_->alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(_set_, callbacks); \
+\
+ return _set_; \
+ } \
+\
+ void CMC_(PFX, _clear)(struct SNAME * _set_) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \
+ struct CMC_DEF_NODE(SNAME) *up = NULL; \
+\
+ while (scan != NULL) \
+ { \
+ if (scan->left != NULL) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *left = scan->left; \
+\
+ scan->left = up; \
+ up = scan; \
+ scan = left; \
+ } \
+ else if (scan->right != NULL) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *right = scan->right; \
+\
+ scan->left = up; \
+ scan->right = NULL; \
+ up = scan; \
+ scan = right; \
+ } \
+ else \
+ { \
+ if (up == NULL) \
+ { \
+ if (_set_->f_val->free) \
+ _set_->f_val->free(scan->value); \
+\
+ _set_->alloc->free(scan); \
+ scan = NULL; \
+ } \
+\
+ while (up != NULL) \
+ { \
+ if (_set_->f_val->free) \
+ _set_->f_val->free(scan->value); \
+\
+ _set_->alloc->free(scan); \
+\
+ if (up->right != NULL) \
+ { \
+ scan = up->right; \
+ up->right = NULL; \
+ break; \
+ } \
+ else \
+ { \
+ scan = up; \
+ up = up->left; \
+ } \
+ } \
+ } \
+ } \
+\
+ _set_->count = 0; \
+ _set_->root = NULL; \
+ _set_->flag = CMC_FLAG_OK; \
+ } \
+\
+ void CMC_(PFX, _free)(struct SNAME * _set_) \
+ { \
+ CMC_(PFX, _clear)(_set_); \
+\
+ _set_->alloc->free(_set_); \
+ } \
+\
+ void CMC_(PFX, _customize)(struct SNAME * _set_, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ if (!alloc) \
+ _set_->alloc = &cmc_alloc_node_default; \
+ else \
+ _set_->alloc = alloc; \
+\
+ CMC_CALLBACKS_ASSIGN(_set_, callbacks); \
+\
+ _set_->flag = CMC_FLAG_OK; \
+ } \
+\
+ bool CMC_(PFX, _insert)(struct SNAME * _set_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->root = CMC_(PFX, _impl_new_node)(_set_, value); \
+\
+ if (!_set_->root) \
+ { \
+ _set_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+ } \
+ else \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \
+ struct CMC_DEF_NODE(SNAME) *parent = scan; \
+\
+ while (scan != NULL) \
+ { \
+ parent = scan; \
+\
+ if (_set_->f_val->cmp(scan->value, value) > 0) \
+ scan = scan->left; \
+ else if (_set_->f_val->cmp(scan->value, value) < 0) \
+ scan = scan->right; \
+ else \
+ { \
+ _set_->flag = CMC_FLAG_DUPLICATE; \
+ return false; \
+ } \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * node; \
+\
+ if (_set_->f_val->cmp(parent->value, value) > 0) \
+ { \
+ parent->left = CMC_(PFX, _impl_new_node)(_set_, value); \
+\
+ if (!parent->left) \
+ { \
+ _set_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ parent->left->parent = parent; \
+ node = parent->left; \
+ } \
+ else \
+ { \
+ parent->right = CMC_(PFX, _impl_new_node)(_set_, value); \
+\
+ if (!parent->right) \
+ { \
+ _set_->flag = CMC_FLAG_ALLOC; \
+ return false; \
+ } \
+\
+ parent->right->parent = parent; \
+ node = parent->right; \
+ } \
+\
+ CMC_(PFX, _impl_rebalance)(_set_, node); \
+ } \
+\
+ _set_->count++; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _remove)(struct SNAME * _set_, V value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *node = CMC_(PFX, _impl_get_node)(_set_, value); \
+\
+ if (!node) \
+ { \
+ _set_->flag = CMC_FLAG_NOT_FOUND; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *temp = NULL, *unbalanced = NULL; \
+\
+ bool is_root = node->parent == NULL; \
+\
+ if (node->left == NULL && node->right == NULL) \
+ { \
+ if (is_root) \
+ _set_->root = NULL; \
+ else \
+ { \
+ unbalanced = node->parent; \
+\
+ if (node->parent->right == node) \
+ node->parent->right = NULL; \
+ else \
+ node->parent->left = NULL; \
+ } \
+\
+ _set_->alloc->free(node); \
+ } \
+ else if (node->left == NULL) \
+ { \
+ if (is_root) \
+ { \
+ _set_->root = node->right; \
+ _set_->root->parent = NULL; \
+ } \
+ else \
+ { \
+ unbalanced = node->parent; \
+\
+ node->right->parent = node->parent; \
+\
+ if (node->parent->right == node) \
+ node->parent->right = node->right; \
+ else \
+ node->parent->left = node->right; \
+ } \
+\
+ _set_->alloc->free(node); \
+ } \
+ else if (node->right == NULL) \
+ { \
+ if (is_root) \
+ { \
+ _set_->root = node->left; \
+ _set_->root->parent = NULL; \
+ } \
+ else \
+ { \
+ unbalanced = node->parent; \
+\
+ node->left->parent = node->parent; \
+\
+ if (node->parent->right == node) \
+ node->parent->right = node->left; \
+ else \
+ node->parent->left = node->left; \
+ } \
+\
+ _set_->alloc->free(node); \
+ } \
+ else \
+ { \
+ temp = node->right; \
+ while (temp->left != NULL) \
+ temp = temp->left; \
+\
+ V temp_value = temp->value; \
+\
+ unbalanced = temp->parent; \
+\
+ if (temp->left == NULL && temp->right == NULL) \
+ { \
+ if (temp->parent->right == temp) \
+ temp->parent->right = NULL; \
+ else \
+ temp->parent->left = NULL; \
+ } \
+ else if (temp->left == NULL) \
+ { \
+ temp->right->parent = temp->parent; \
+\
+ if (temp->parent->right == temp) \
+ temp->parent->right = temp->right; \
+ else \
+ temp->parent->left = temp->right; \
+ } \
+ else if (temp->right == NULL) \
+ { \
+ temp->left->parent = temp->parent; \
+\
+ if (temp->parent->right == temp) \
+ temp->parent->right = temp->left; \
+ else \
+ temp->parent->left = temp->left; \
+ } \
+\
+ _set_->alloc->free(temp); \
+\
+ node->value = temp_value; \
+ } \
+\
+ if (unbalanced != NULL) \
+ CMC_(PFX, _impl_rebalance)(_set_, unbalanced); \
+\
+ if (_set_->count == 0) \
+ _set_->root = NULL; \
+\
+ _set_->count--; \
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, delete); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _max)(struct SNAME * _set_, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \
+\
+ while (scan->right != NULL) \
+ scan = scan->right; \
+\
+ if (value) \
+ *value = scan->value; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _min)(struct SNAME * _set_, V * value) \
+ { \
+ if (CMC_(PFX, _empty)(_set_)) \
+ { \
+ _set_->flag = CMC_FLAG_EMPTY; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \
+\
+ while (scan->left != NULL) \
+ scan = scan->left; \
+\
+ if (value) \
+ *value = scan->value; \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _contains)(struct SNAME * _set_, V value) \
+ { \
+ bool result = CMC_(PFX, _impl_get_node)(_set_, value) != NULL; \
+\
+ CMC_CALLBACKS_CALL(_set_, read); \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _empty)(struct SNAME * _set_) \
+ { \
+ return _set_->count == 0; \
+ } \
+\
+ size_t CMC_(PFX, _count)(struct SNAME * _set_) \
+ { \
+ return _set_->count; \
+ } \
+\
+ int CMC_(PFX, _flag)(struct SNAME * _set_) \
+ { \
+ return _set_->flag; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _copy_of)(struct SNAME * _set_) \
+ { \
+ struct SNAME *result = CMC_(PFX, _new_custom)(_set_->f_val, _set_->alloc, NULL); \
+\
+ if (!result) \
+ { \
+ _set_->flag = CMC_FLAG_ERROR; \
+ return NULL; \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(result, _set_->callbacks); \
+\
+ if (!CMC_(PFX, _empty)(_set_)) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ if (_set_->f_val->cpy) \
+ CMC_(PFX, _insert) \
+ (result, _set_->f_val->cpy(CMC_(PFX, _iter_value)(&iter))); \
+ else CMC_(PFX, _insert)(result, CMC_(PFX, _iter_value)(&iter)); \
+ } \
+ } \
+\
+ _set_->flag = CMC_FLAG_OK; \
+\
+ return result; \
+ } \
+\
+ bool CMC_(PFX, _equals)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ _set1_->flag = CMC_FLAG_OK; \
+ _set2_->flag = CMC_FLAG_OK; \
+\
+ if (_set1_->count != _set2_->count) \
+ return false; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ if (CMC_(PFX, _impl_get_node)(_set2_, CMC_(PFX, _iter_value)(&iter)) == NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_new_node)(struct SNAME * _set_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *node = _set_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \
+\
+ if (!node) \
+ return NULL; \
+\
+ node->value = value; \
+ node->right = NULL; \
+ node->left = NULL; \
+ node->parent = NULL; \
+ node->height = 0; \
+\
+ return node; \
+ } \
+\
+ static struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _impl_get_node)(struct SNAME * _set_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = _set_->root; \
+\
+ while (scan != NULL) \
+ { \
+ if (_set_->f_val->cmp(scan->value, value) > 0) \
+ scan = scan->left; \
+ else if (_set_->f_val->cmp(scan->value, value) < 0) \
+ scan = scan->right; \
+ else \
+ return scan; \
+ } \
+\
+ return NULL; \
+ } \
+\
+ static unsigned char CMC_(PFX, _impl_h)(struct CMC_DEF_NODE(SNAME) * node) \
+ { \
+ if (node == NULL) \
+ return 0; \
+\
+ return node->height; \
+ } \
+\
+ static unsigned char CMC_(PFX, _impl_hupdate)(struct CMC_DEF_NODE(SNAME) * node) \
+ { \
+ if (node == NULL) \
+ return 0; \
+\
+ unsigned char h_l = CMC_(PFX, _impl_h)(node->left); \
+ unsigned char h_r = CMC_(PFX, _impl_h)(node->right); \
+\
+ return 1 + (h_l > h_r ? h_l : h_r); \
+ } \
+\
+ static void CMC_(PFX, _impl_rotate_right)(struct CMC_DEF_NODE(SNAME) * *Z) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *root = *Z; \
+ struct CMC_DEF_NODE(SNAME) *new_root = root->left; \
+\
+ if (root->parent != NULL) \
+ { \
+ if (root->parent->left == root) \
+ root->parent->left = new_root; \
+ else \
+ root->parent->right = new_root; \
+ } \
+\
+ new_root->parent = root->parent; \
+\
+ root->parent = new_root; \
+ root->left = new_root->right; \
+\
+ if (root->left) \
+ root->left->parent = root; \
+\
+ new_root->right = root; \
+\
+ root->height = CMC_(PFX, _impl_hupdate)(root); \
+ new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \
+\
+ *Z = new_root; \
+ } \
+\
+ static void CMC_(PFX, _impl_rotate_left)(struct CMC_DEF_NODE(SNAME) * *Z) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *root = *Z; \
+ struct CMC_DEF_NODE(SNAME) *new_root = root->right; \
+\
+ if (root->parent != NULL) \
+ { \
+ if (root->parent->right == root) \
+ root->parent->right = new_root; \
+ else \
+ root->parent->left = new_root; \
+ } \
+\
+ new_root->parent = root->parent; \
+\
+ root->parent = new_root; \
+ root->right = new_root->left; \
+\
+ if (root->right) \
+ root->right->parent = root; \
+\
+ new_root->left = root; \
+\
+ root->height = CMC_(PFX, _impl_hupdate)(root); \
+ new_root->height = CMC_(PFX, _impl_hupdate)(new_root); \
+\
+ *Z = new_root; \
+ } \
+\
+ static void CMC_(PFX, _impl_rebalance)(struct SNAME * _set_, struct CMC_DEF_NODE(SNAME) * node) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *scan = node, *child = NULL; \
+\
+ int balance; \
+ bool is_root = false; \
+\
+ while (scan != NULL) \
+ { \
+ if (scan->parent == NULL) \
+ is_root = true; \
+\
+ scan->height = CMC_(PFX, _impl_hupdate)(scan); \
+ balance = CMC_(PFX, _impl_h)(scan->right) - CMC_(PFX, _impl_h)(scan->left); \
+\
+ if (balance >= 2) \
+ { \
+ child = scan->right; \
+\
+ if (CMC_(PFX, _impl_h)(child->right) < CMC_(PFX, _impl_h)(child->left)) \
+ CMC_(PFX, _impl_rotate_right)(&(scan->right)); \
+\
+ CMC_(PFX, _impl_rotate_left)(&scan); \
+ } \
+ else if (balance <= -2) \
+ { \
+ child = scan->left; \
+\
+ if (CMC_(PFX, _impl_h)(child->left) < CMC_(PFX, _impl_h)(child->right)) \
+ CMC_(PFX, _impl_rotate_left)(&(scan->left)); \
+\
+ CMC_(PFX, _impl_rotate_right)(&scan); \
+ } \
+\
+ if (is_root) \
+ { \
+ _set_->root = scan; \
+ is_root = false; \
+ } \
+\
+ scan = scan->parent; \
+ } \
}
-#endif /* CMC_TREESET_H */
+#endif /* CMC_CMC_TREESET_H */
diff --git a/src/cor/alloc.h b/src/cor/alloc.h
new file mode 100644
index 0000000..5d3edea
--- /dev/null
+++ b/src/cor/alloc.h
@@ -0,0 +1,37 @@
+/**
+ * cor/alloc.h
+ *
+ * Creation Date: 24/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_COR_ALLOC_H
+#define CMC_COR_ALLOC_H
+
+#ifdef CMC_CAMEL_CASE
+#define CMC_ALLOC_NODE_NAME CMCAllocNode
+#else
+#define CMC_ALLOC_NODE_NAME cmc_alloc_node
+#endif
+
+#include
+
+/**
+ * struct cmc_alloc_node
+ *
+ * Custom allocation node. Allows collections to use custom allocation
+ * functions. The cmc_alloc_node_default is the default heap allocator provided
+ * by the standard library.
+ */
+static struct CMC_ALLOC_NODE_NAME
+{
+ void *(*malloc)(size_t);
+ void *(*calloc)(size_t, size_t);
+ void *(*realloc)(void *, size_t);
+ void (*free)(void *);
+} cmc_alloc_node_default = { malloc, calloc, realloc, free };
+
+#endif /* CMC_COR_ALLOC_H */
diff --git a/src/cor/bitset.h b/src/cor/bitset.h
index cf42e57..9f793af 100644
--- a/src/cor/bitset.h
+++ b/src/cor/bitset.h
@@ -1,5 +1,5 @@
/**
- * bitset.h
+ * cor/bitset.h
*
* Creation Date: 20/05/2020
*
@@ -25,4 +25,20 @@
typedef CMC_BITSET_WORD_TYPE cmc_bitset_word;
+/**
+ * cmc_bit_to_index
+ *
+ * Translates a bit index to a word index
+ */
+static inline size_t cmc_bidx_to_widx(size_t idx)
+{
+ /* Calculate how many shifts based on the size of cmc_bitset_word */
+ static const size_t shift =
+ ((sizeof(cmc_bitset_word) * 8) >> 6) > 0
+ ? 6
+ : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0 ? 5 : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3;
+
+ return idx >> shift;
+}
+
#endif /* CMC_COR_BITSET_H */
diff --git a/src/cor/callbacks.h b/src/cor/callbacks.h
new file mode 100644
index 0000000..0ec86a6
--- /dev/null
+++ b/src/cor/callbacks.h
@@ -0,0 +1,59 @@
+/**
+ * cor/callbacks.h
+ *
+ * Creation Date: 24/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_COR_CALLBACKS_H
+#define CMC_COR_CALLBACKS_H
+
+#ifdef CMC_CAMEL_CASE
+#define CMC_CALLBACKS_NAME CMCCallbacks
+#else
+#define CMC_CALLBACKS_NAME cmc_callbacks
+#endif
+
+#ifdef CMC_NO_CALLBACKS
+
+#define CMC_CALLBACKS_DECL
+#define CMC_CALLBACKS_MAYBE_UNUSED(param) ((void)param) /* Prevent -Wunused-parameter */
+#define CMC_CALLBACKS_GET(ds) NULL /* Helps with compatibility */
+#define CMC_CALLBACKS_ASSIGN(ds, cb)
+#define CMC_CALLBACKS_CALL(ds, cb)
+
+#else
+
+#define CMC_CALLBACKS_DECL struct CMC_CALLBACKS_NAME *callbacks
+#define CMC_CALLBACKS_MAYBE_UNUSED(param)
+#define CMC_CALLBACKS_GET(ds) (ds)->callbacks
+#define CMC_CALLBACKS_ASSIGN(ds, cb) CMC_CALLBACKS_GET(ds) = cb
+#define CMC_CALLBACKS_CALL(ds, cb) \
+ if (CMC_CALLBACKS_GET(ds) && CMC_CALLBACKS_GET(ds)->cb) \
+ CMC_CALLBACKS_GET(ds)->cb();
+
+#endif
+
+/**
+ * struct cmc_callbacks
+ *
+ * Callback node. Each collection will call one of these functions when:
+ * - create : an element was successfully added to the collection
+ * - read : the collection was successfully queried about an element
+ * - update : an element in the collection was successfully updated
+ * - delete : an element was successfully removed from the collection
+ * - resize : the collection was full and successfully resized
+ */
+struct CMC_CALLBACKS_NAME
+{
+ void (*create)(void);
+ void (*read)(void);
+ void (*update)(void);
+ void (*delete)(void);
+ void (*resize)(void);
+};
+
+#endif /* CMC_COR_CALLBACKS_H */
diff --git a/src/cor/core.h b/src/cor/core.h
index 16ba3c6..430d35d 100644
--- a/src/cor/core.h
+++ b/src/cor/core.h
@@ -1,5 +1,5 @@
/**
- * core.h
+ * cor/core.h
*
* Creation Date: 17/03/2020
*
@@ -9,17 +9,24 @@
*/
/**
- * Core includes and structs used in the library.
+ * Core includes and macros for the entire library.
*
- * In here you will find:
- * struct cmc_string
- * struct cmc_alloc_node
- * struct cmc_callbacks
- * cmc_flags
+ * Here you will find:
+ * - CMC_
+ * - CMC_TO_STRING
+ * - CMC_INTERNAL_PREFIX_[ITER|NODE|ENTRY|FKEY|FVAL]
+ * - CMC_DEF_[ITER|NODE|ENTRY|FKEY|FVAL]
+ * - CMC_PARAM_[PFX|SNAME|SIZE|K|V]
*/
-#ifndef CMC_CORE_H
-#define CMC_CORE_H
+#ifndef CMC_COR_CORE_H
+#define CMC_COR_CORE_H
+
+#if defined(__GNUC__) || defined(__clang__)
+#define CMC_UNUSED __attribute__((__unused__))
+#else
+#define CMC_UNUSED
+#endif
#include
#include
@@ -28,54 +35,67 @@
#include
#include
+#include "alloc.h"
+#include "callbacks.h"
#include "flags.h"
+#include "ftable.h"
+
+#define CMC__(A, B) A##B
+#define CMC_(A, B) CMC__(A, B)
#define CMC_TO_STRING_(X) #X
#define CMC_TO_STRING(X) CMC_TO_STRING_(X)
-/**
- * struct cmc_string
- *
- * Used by all collections when calling the to_string function.
- */
-struct cmc_string
-{
- char s[400];
-};
+#if defined(CMC_CAMEL_CASE)
+#define CMC_INTERNAL_PREFIX_ITER Iter
+#define CMC_INTERNAL_PREFIX_NODE Node
+#define CMC_INTERNAL_PREFIX_ENTRY Entry
+#define CMC_INTERNAL_PREFIX_FVAL FVal
+#define CMC_INTERNAL_PREFIX_FKEY FKey
+#else
+#define CMC_INTERNAL_PREFIX_ITER _iter
+#define CMC_INTERNAL_PREFIX_NODE _node
+#define CMC_INTERNAL_PREFIX_ENTRY _entry
+#define CMC_INTERNAL_PREFIX_FVAL _fval
+#define CMC_INTERNAL_PREFIX_FKEY _fkey
+#endif
-static const size_t cmc_string_len = 400;
+#define CMC_DEF_ITER(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_ITER)
+#define CMC_DEF_NODE(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_NODE)
+#define CMC_DEF_ENTRY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_ENTRY)
+#define CMC_DEF_FVAL(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FVAL)
+#define CMC_DEF_FKEY(SNAME) CMC_(SNAME, CMC_INTERNAL_PREFIX_FKEY)
/**
- * struct cmc_alloc_node
- *
- * Custom allocation node. Allows collections to use custom allocation
- * functions.
+ * Code to get specific arguments from tuples.
*/
-static struct cmc_alloc_node
-{
- void *(*malloc)(size_t);
- void *(*calloc)(size_t, size_t);
- void *(*realloc)(void *, size_t);
- void (*free)(void *);
-} cmc_alloc_node_default = { malloc, calloc, realloc, free };
+#define CMC_TUP_0_(A, ...) A
+#define CMC_TUP_0(TUP) CMC_TUP_0_ TUP
+#define CMC_TUP_1_(A, B, ...) B
+#define CMC_TUP_1(TUP) CMC_TUP_1_ TUP
+#define CMC_TUP_2_(A, B, C, ...) C
+#define CMC_TUP_2(TUP) CMC_TUP_2_ TUP
+#define CMC_TUP_3_(A, B, C, D, ...) D
+#define CMC_TUP_3(TUP) CMC_TUP_3_ TUP
+#define CMC_TUP_4_(A, B, C, D, E, ...) E
+#define CMC_TUP_4(TUP) CMC_TUP_4_ TUP
/**
- * struct cmc_callbacks
+ * A PARAM is a unified way to pass arguments to all macros that generate code.
+ * It is a tuple that contains the following parameters in order:
*
- * Callback node. Each collection will call one of these functions when:
- * - create : an element was successfully added to the collection
- * - read : the collection was successfully queried about an element
- * - update : an element in the collection was successfully updated
- * - delete : an element was successfully removed from the collection
- * - resize : the collection was full and successfully resized
+ * PFX - Functions prefix
+ * SNAME - `struct` name
+ * SIZE - Size for SAC library
+ * K - Key type
+ * V - Value type
+ *
+ * PARAMS := (PFX, SNAME, SIZE, K, V)
*/
-struct cmc_callbacks
-{
- void (*create)(void);
- void (*read)(void);
- void (*update)(void);
- void (*delete)(void);
- void (*resize)(void);
-};
+#define CMC_PARAM_PFX CMC_TUP_0
+#define CMC_PARAM_SNAME CMC_TUP_1
+#define CMC_PARAM_SIZE CMC_TUP_2
+#define CMC_PARAM_K CMC_TUP_3
+#define CMC_PARAM_V CMC_TUP_4
-#endif /* CMC_CORE_H */
+#endif /* CMC_COR_CORE_H */
diff --git a/src/cor/flags.h b/src/cor/flags.h
index da41a0b..a9b0407 100644
--- a/src/cor/flags.h
+++ b/src/cor/flags.h
@@ -1,5 +1,5 @@
/**
- * flags.h
+ * cor/flags.h
*
* Creation Date: 14/05/2020
*
@@ -8,36 +8,38 @@
*
*/
-#ifndef CMC_FLAGS_H
-#define CMC_FLAGS_H
+#ifndef CMC_COR_FLAGS_H
+#define CMC_COR_FLAGS_H
+
+#include "core.h"
/**
- * cmc_flags
+ * enum cmc_flags
*
* Defines common error codes used by the entire library.
*/
-static struct
+// clang-format off
+enum cmc_flags
{
- int OK; // No errors
- int ALLOC; // Allocation failed
- int EMPTY; // The collection is empty when it should not
- int NOT_FOUND; // Key or value not found
- int INVALID; // Invalid argument or operation
- int RANGE; // Index out of range
- int DUPLICATE; // Duplicate key or value
- int ERROR; // Generic error, usually caused by algorithm error
- int THREAD; // Generic error regarding threads
- int MUTEX; // Generic error regarding mutexes
-} cmc_flags = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ CMC_FLAG_OK = 0, // No errors
+ CMC_FLAG_ALLOC = 1, // Allocation failed
+ CMC_FLAG_EMPTY = 2, // The collection is empty when it should not
+ CMC_FLAG_NOT_FOUND = 3, // Key or value not found
+ CMC_FLAG_INVALID = 4, // Invalid argument or operation
+ CMC_FLAG_RANGE = 5, // Index out of range
+ CMC_FLAG_DUPLICATE = 6, // Duplicate key or value
+ CMC_FLAG_ERROR = 7, // Generic error, usually caused by algorithm error
+ CMC_FLAG_THREAD = 8, // Generic error regarding threads
+ CMC_FLAG_MUTEX = 9 // Generic error regarding mutexes
+};
+// clang-format on
/**
* cmc_flags_to_str
*
* Maps the error codes to their character representation.
*/
-const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY",
- "NOT_FOUND", "INVALID", "RANGE",
- "DUPLICATE", "ERROR", "THREAD",
- "MUTEX" };
+CMC_UNUSED static const char *cmc_flags_to_str[10] = { "OK", "ALLOC", "EMPTY", "NOT_FOUND", "INVALID",
+ "RANGE", "DUPLICATE", "ERROR", "THREAD", "MUTEX" };
-#endif /* CMC_FLAGS_H */
+#endif /* CMC_COR_FLAGS_H */
diff --git a/src/cor/ftable.h b/src/cor/ftable.h
new file mode 100644
index 0000000..cdeede6
--- /dev/null
+++ b/src/cor/ftable.h
@@ -0,0 +1,28 @@
+/**
+ * cor/ftable.h
+ *
+ * Creation Date: 27/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+/**
+ * Type definitions for Functions Tables.
+ */
+
+#ifndef CMC_COR_FTABLE_H
+#define CMC_COR_FTABLE_H
+
+/**
+ * Where T can either be K or V
+ */
+#define CMC_DEF_FTAB_CMP(T) int (*cmp)(T, T)
+#define CMC_DEF_FTAB_CPY(T) T (*cpy)(T)
+#define CMC_DEF_FTAB_STR(T) bool (*str)(FILE *, T)
+#define CMC_DEF_FTAB_FREE(T) void (*free)(T)
+#define CMC_DEF_FTAB_HASH(T) size_t (*hash)(T)
+#define CMC_DEF_FTAB_PRI(T) int (*pri)(T, T)
+
+#endif /* CMC_COR_FTABLE_H */
diff --git a/src/cor/hashtable.h b/src/cor/hashtable.h
index 877a1e5..08409db 100644
--- a/src/cor/hashtable.h
+++ b/src/cor/hashtable.h
@@ -1,5 +1,5 @@
/**
- * hashtable.h
+ * cor/hashtable.h
*
* Creation Date: 17/03/2020
*
@@ -12,8 +12,8 @@
* Things commonly used by hashtable-based collections.
*/
-#ifndef CMC_IMPL_HASHTABLE_H
-#define CMC_IMPL_HASHTABLE_H
+#ifndef CMC_COR_HASHTABLE_H
+#define CMC_COR_HASHTABLE_H
#include "core.h"
@@ -83,4 +83,4 @@ static const size_t cmc_hashtable_primes[] = {
};
// clang-format on
-#endif /* CMC_IMPL_HASHTABLE_H */
+#endif /* CMC_COR_HASHTABLE_H */
diff --git a/src/cor/heap.h b/src/cor/heap.h
new file mode 100644
index 0000000..923e4e0
--- /dev/null
+++ b/src/cor/heap.h
@@ -0,0 +1,31 @@
+/**
+ * cor/heap.h
+ *
+ * Creation Date: 01/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+/**
+ * Things commonly used by heap collections.
+ */
+
+#ifndef CMC_COR_HEAP_H
+#define CMC_COR_HEAP_H
+
+/**
+ * enum cmc_heap_order
+ *
+ * Defines the two possible heaps:
+ * - Max Heap has the greatest element at the top
+ * - Min Heap has the smallest element at the top
+ */
+enum cmc_heap_order
+{
+ CMC_MAX_HEAP = 1,
+ CMC_MIN_HEAP = -1
+};
+
+#endif /* CMC_COR_HEAP_H */
diff --git a/src/dev/deque.h b/src/dev/deque.h
deleted file mode 100644
index 85841a3..0000000
--- a/src/dev/deque.h
+++ /dev/null
@@ -1,654 +0,0 @@
-/**
- * deque.h
- *
- * Creation Date: 21/06/2019
- *
- * Authors:
- * Leonardo Vencovsky (https://github.com/LeoVen)
- *
- */
-
-/*****************************************************************************/
-/********************************************************************* DEQUE */
-/*****************************************************************************/
-
-#ifndef CMC_DEQUE_H
-#define CMC_DEQUE_H
-
-#include
-#include
-#include
-#include
-#include
-#include "utl/log.h"
-
-#define DEQUE_GENERATE(PFX, SNAME, FMOD, V) \
- DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
- DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
-
-#define DEQUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
- DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
-
-#define DEQUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
- DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
-
-/* HEADER ********************************************************************/
-#define DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
- \
- /* Deque Structure */ \
- typedef struct SNAME##_s \
- { \
- /* Dynamic circular array of elements */ \
- V *buffer; \
- \
- /* Current circular array capacity */ \
- size_t capacity; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Index representing the front of the deque */ \
- size_t front; \
- \
- /* Index representing the back of the deque */ \
- size_t back; \
- \
- /* Function that returns an iterator to the start of the deque */ \
- struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
- \
- /* Function that returns an iterator to the end of the deque */ \
- struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
- \
- } SNAME, *SNAME##_ptr; \
- \
- /* Deque Iterator */ \
- typedef struct SNAME##_iter_s \
- { \
- /* Target deque */ \
- struct SNAME##_s *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- \
- } SNAME##_iter, *SNAME##_iter_ptr; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- FMOD SNAME *PFX##_new(size_t capacity); \
- FMOD void PFX##_clear(SNAME *_deque_); \
- FMOD void PFX##_free(SNAME *_deque_); \
- /* Collection Input and Output */ \
- FMOD bool PFX##_push_front(SNAME *_deque_, V element); \
- FMOD bool PFX##_push_back(SNAME *_deque_, V element); \
- FMOD bool PFX##_pop_front(SNAME *_deque_); \
- FMOD bool PFX##_pop_back(SNAME *_deque_); \
- /* Conditional Input and Output */ \
- FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition); \
- FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition); \
- FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition); \
- FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition); \
- /* Element Access */ \
- FMOD V PFX##_front(SNAME *_deque_); \
- FMOD V PFX##_back(SNAME *_deque_); \
- /* Collection State */ \
- FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)); \
- FMOD bool PFX##_empty(SNAME *_deque_); \
- FMOD bool PFX##_full(SNAME *_deque_); \
- FMOD size_t PFX##_count(SNAME *_deque_); \
- FMOD size_t PFX##_capacity(SNAME *_deque_); \
- \
- /* Iterator Functions */ \
- /* Iterator Allocation and Deallocation */ \
- FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
- FMOD void PFX##_iter_free(SNAME##_iter *iter); \
- /* Iterator Initialization */ \
- FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
- /* Iterator State */ \
- FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
- /* Iterator Movement */ \
- FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
- FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
- /* Iterator Access */ \
- FMOD V PFX##_iter_value(SNAME##_iter *iter); \
- FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
- FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
- \
- /* Default Value */ \
- static inline V PFX##_impl_default_value(void) \
- { \
- V _empty_value_; \
- \
- memset(&_empty_value_, 0, sizeof(V)); \
- \
- return _empty_value_; \
- } \
- \
-/* SOURCE ********************************************************************/
-#define DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
- \
- /* Implementation Detail Functions */ \
- static bool PFX##_impl_grow(SNAME *_deque_); \
- static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_); \
- static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_); \
- \
- FMOD SNAME *PFX##_new(size_t capacity) \
- { \
- if (capacity < 1) \
- { \
- log_warn("Invalid capacity for %s given: %s", "Heap", capacity); \
- return NULL; \
- } \
- \
- SNAME *_deque_ = malloc(sizeof(SNAME)); \
- \
- if (!_deque_) \
- { \
- log_info("%s allocation failed", "Deque"); \
- return NULL; \
- } \
- \
- _deque_->buffer = malloc(sizeof(V) * capacity); \
- \
- if (!_deque_->buffer) \
- { \
- log_info("%s allocation failed", "Deque buffer"); \
- free(_deque_); \
- return NULL; \
- } \
- \
- memset(_deque_->buffer, 0, sizeof(V) * capacity); \
- \
- _deque_->capacity = capacity; \
- _deque_->count = 0; \
- _deque_->front = 0; \
- _deque_->back = 0; \
- \
- _deque_->it_start = PFX##_impl_it_start; \
- _deque_->it_end = PFX##_impl_it_end; \
- \
- log_info("Deque at %p successfully allocated", _deque_); \
- \
- return _deque_; \
- } \
- \
- FMOD void PFX##_clear(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
- \
- _deque_->count = 0; \
- _deque_->front = 0; \
- _deque_->back = 0; \
- \
- log_trace("Deque at %p cleared", _deque_); \
- } \
- \
- FMOD void PFX##_free(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- free(_deque_->buffer); \
- \
- uintptr_t address = (uintptr_t)(void *)_deque_; \
- \
- free(_deque_); \
- \
- log_info("Heap at %p successfully deallocated", address); \
- } \
- \
- FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- if (PFX##_full(_deque_)) \
- { \
- if (!PFX##_impl_grow(_deque_)) \
- { \
- log_info("Deque at %p failed to be reallocated", _deque_); \
- return false; \
- } \
- } \
- \
- _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
- \
- _deque_->buffer[_deque_->front] = element; \
- \
- log_trace("Element added at %" PRIuMAX " to Deque at %p", _deque_->front, _deque_); \
- \
- _deque_->count++; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- if (PFX##_full(_deque_)) \
- { \
- if (!PFX##_impl_grow(_deque_)) \
- { \
- log_info("Deque at %p failed to be reallocated", _deque_); \
- return false; \
- } \
- } \
- \
- _deque_->buffer[_deque_->back] = element; \
- \
- log_trace("Element added at %" PRIuMAX " to Deque at %p", _deque_->back, _deque_); \
- \
- _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
- \
- _deque_->count++; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_pop_front(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- if (PFX##_empty(_deque_)) \
- { \
- log_debug("Attempt of removing an element from empty Deque at %p", _deque_); \
- \
- return false; \
- } \
- \
- _deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \
- \
- log_trace("Element removed from %" PRIuMAX " to Deque at %p", _deque_->front, _deque_); \
- \
- _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
- \
- _deque_->count--; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_pop_back(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- { \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- } \
- \
- if (PFX##_empty(_deque_)) \
- { \
- log_debug("Attempt of removing an element from empty Deque at %p", _deque_); \
- \
- return false; \
- } \
- \
- _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
- \
- _deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \
- \
- log_trace("Element removed from %" PRIuMAX " to Deque at %p", _deque_->back, _deque_); \
- \
- _deque_->count--; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
- { \
- if (condition) \
- return PFX##_push_front(_deque_, element); \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
- { \
- if (condition) \
- return PFX##_push_back(_deque_, element); \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
- { \
- if (condition) \
- return PFX##_pop_front(_deque_); \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
- { \
- if (condition) \
- return PFX##_pop_back(_deque_); \
- \
- return false; \
- } \
- \
- FMOD V PFX##_front(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- if (PFX##_empty(_deque_)) \
- { \
- log_debug("Attempt to access element from empty Deque at %p", _deque_); \
- \
- PFX##_impl_default_value(); \
- } \
- \
- log_trace("Element access at %" PRIuMAX "", _deque_->front); \
- \
- return _deque_->buffer[_deque_->front]; \
- } \
- \
- FMOD V PFX##_back(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- if (PFX##_empty(_deque_)) \
- { \
- log_debug("Attempt to access element from empty Deque at %p", _deque_); \
- \
- PFX##_impl_default_value(); \
- } \
- \
- size_t index = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
- \
- log_trace("Element access at %" PRIuMAX "", index); \
- \
- return _deque_->buffer[index]; \
- } \
- \
- FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- if (comparator == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "comparator"); \
- \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->count, j++) \
- { \
- if (comparator(_deque_->buffer[i], element) == 0) \
- return true; \
- } \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_empty(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- return _deque_->count == 0; \
- } \
- \
- FMOD bool PFX##_full(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- return _deque_->count >= _deque_->capacity; \
- } \
- \
- FMOD size_t PFX##_count(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- return _deque_->count; \
- } \
- \
- FMOD size_t PFX##_capacity(SNAME *_deque_) \
- { \
- if (_deque_ == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "_deque_"); \
- \
- return _deque_->capacity; \
- } \
- \
- FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
- { \
- SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
- \
- if (!iter) \
- { \
- log_info("%s allocation failed", "Deque Iterator"); \
- return NULL; \
- } \
- \
- PFX##_iter_init(iter, target); \
- \
- log_info("Deque Iterator allocated at %p referencing Heap at %p", iter, target); \
- \
- return iter; \
- } \
- \
- FMOD void PFX##_iter_free(SNAME##_iter *iter) \
- { \
- uintptr_t address = (uintptr_t)(void *)iter; \
- \
- free(iter); \
- \
- log_info("Deque Iterator deallocated at %" PRIxPTR "", address); \
- } \
- \
- FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
- { \
- if (target == NULL) \
- log_fatal("Heap Iterator at %p initialized with null pointer target", iter); \
- \
- if (PFX##_empty(target)) \
- log_warn("Deque Iterator at %p initialized with empty target", iter); \
- \
- iter->target = target; \
- iter->cursor = target->front; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(target); \
- } \
- \
- FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- iter->cursor = iter->target->front; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- \
- log_trace("Deque Iterator at %p with cursor at %" PRIuMAX "", iter, iter->cursor); \
- } \
- \
- FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- if (PFX##_empty(iter->target)) \
- iter->cursor = 0; \
- else \
- iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
- \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- \
- log_trace("Deque Iterator at %p with cursor at %" PRIuMAX "", iter, iter->cursor); \
- } \
- \
- FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- if (iter->end) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- if (iter->index == iter->target->count - 1) \
- { \
- log_trace("Deque Iterator at %p reached the end of Deque %p", iter, iter->target); \
- iter->end = true; \
- } \
- else \
- { \
- iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
- iter->index++; \
- \
- log_trace("Deque Iterator at %p moved to %" PRIuMAX "", iter, iter->cursor); \
- } \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- if (iter->start) \
- return false; \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- if (iter->index == 0) \
- { \
- log_trace("Deque Iterator at %p reached the start of Deque %p", iter, iter->target); \
- iter->start = true; \
- } \
- else \
- { \
- iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
- iter->index--; \
- \
- log_trace("Deque Iterator at %p moved to %" PRIuMAX "", iter, iter->cursor); \
- } \
- \
- return true; \
- } \
- \
- FMOD V PFX##_iter_value(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- if (PFX##_empty(iter->target)) \
- { \
- log_debug("Attempt to access element from iterator %p with empty target %p", iter, iter->target); \
- PFX##_impl_default_value(); \
- } \
- \
- log_trace("Element access at %" PRIuMAX "", iter->cursor); \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- if (PFX##_empty(iter->target)) \
- { \
- log_debug("Attempt to access element from iterator %p with empty target %p", iter, iter->target); \
- return NULL; \
- } \
- \
- log_trace("Element access at %" PRIuMAX "", iter->cursor); \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
- { \
- if (iter == NULL) \
- log_fatal("Invalid null pointer parameter: %s", "iter"); \
- \
- return iter->index; \
- } \
- \
- static bool PFX##_impl_grow(SNAME *_deque_) \
- { \
- size_t new_capacity = _deque_->capacity * 2; \
- \
- V *new_buffer = malloc(sizeof(V) * new_capacity); \
- \
- if (!new_buffer) \
- { \
- log_info("%s reallocation failed", "Deque buffer"); \
- return false; \
- } \
- \
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
- { \
- new_buffer[j] = _deque_->buffer[i]; \
- } \
- \
- free(_deque_->buffer); \
- \
- _deque_->buffer = new_buffer; \
- _deque_->capacity = new_capacity; \
- _deque_->front = 0; \
- _deque_->back = _deque_->count; \
- \
- return true; \
- } \
- \
- static SNAME##_iter PFX##_impl_it_start(SNAME *_deque_) \
- { \
- SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _deque_); \
- \
- return iter; \
- } \
- \
- static SNAME##_iter PFX##_impl_it_end(SNAME *_deque_) \
- { \
- SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _deque_); \
- PFX##_iter_to_end(&iter); \
- \
- return iter; \
- }
-
-#endif /* CMC_DEQUE_H */
diff --git a/src/ext/cmc/bitset.h b/src/ext/cmc/bitset.h
new file mode 100644
index 0000000..791abcc
--- /dev/null
+++ b/src/ext/cmc/bitset.h
@@ -0,0 +1,30 @@
+/**
+ * ext/cmc/bitset.h
+ *
+ * Creation Date: 08/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_BITSET_H
+#define CMC_EXT_CMC_BITSET_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC BitSet.
+ */
+#define CMC_EXT_CMC_BITSET_PARTS PLACEHOLDER
+
+#define CMC_EXT_CMC_BITSET_PLACEHOLDER(PARAMS)
+
+#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER(PARAMS)
+
+#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_BITSET_PLACEHOLDER_HEADER_(PFX, SNAME, V)
+#define CMC_EXT_CMC_BITSET_PLACEHOLDER_SOURCE_(PFX, SNAME, V)
+
+#endif /* CMC_EXT_CMC_BITSET_H */
diff --git a/src/ext/cmc/deque.h b/src/ext/cmc/deque.h
new file mode 100644
index 0000000..fb19ec6
--- /dev/null
+++ b/src/ext/cmc/deque.h
@@ -0,0 +1,426 @@
+/**
+ * ext/cmc/deque.h
+ *
+ * Creation Date: 25/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_DEQUE_H
+#define CMC_EXT_CMC_DEQUE_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC Deque.
+ */
+#define CMC_EXT_CMC_DEQUE_PARTS INIT, ITER, STR
+
+/**
+ * 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).
+ */
+#define CMC_EXT_CMC_DEQUE_INIT(PARAMS) \
+ CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_DEQUE_INIT_HEADER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_DEQUE_INIT_SOURCE(PARAMS) \
+ CMC_EXT_CMC_DEQUE_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_DEQUE_INIT_HEADER_(PFX, SNAME, V) \
+\
+ struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME CMC_(PFX, _init_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, _release)(struct SNAME _deque_);
+
+#define CMC_EXT_CMC_DEQUE_INIT_SOURCE_(PFX, SNAME, V) \
+\
+ struct SNAME CMC_(PFX, _init)(size_t capacity, struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _init_custom)(capacity, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME CMC_(PFX, _init_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); \
+\
+ struct SNAME _deque_ = { 0 }; \
+\
+ if (capacity < 1) \
+ return _deque_; \
+\
+ if (!f_val) \
+ return _deque_; \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ _deque_.buffer = alloc->calloc(capacity, sizeof(V)); \
+\
+ if (!_deque_.buffer) \
+ return _deque_; \
+\
+ _deque_.capacity = capacity; \
+ _deque_.count = 0; \
+ _deque_.front = 0; \
+ _deque_.back = 0; \
+ _deque_.flag = CMC_FLAG_OK; \
+ _deque_.f_val = f_val; \
+ _deque_.alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(&_deque_, callbacks); \
+\
+ return _deque_; \
+ } \
+\
+ void CMC_(PFX, _release)(struct SNAME _deque_) \
+ { \
+ if (_deque_.f_val->free) \
+ { \
+ for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++) \
+ { \
+ _deque_.f_val->free(_deque_.buffer[i]); \
+\
+ i = (i + 1) % _deque_.capacity; \
+ } \
+ } \
+\
+ _deque_.alloc->free(_deque_.buffer); \
+ }
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_DEQUE_ITER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_DEQUE_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_DEQUE_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_DEQUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_DEQUE_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* Deque Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target deque */ \
+ struct SNAME *target; \
+\
+ /* Cursor's position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* 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); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_DEQUE_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.cursor = target->front; \
+ iter.index = 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; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ if (iter.target->back == 0) \
+ iter.cursor = iter.target->capacity - 1; \
+ else \
+ iter.cursor = iter.target->back - 1; \
+\
+ iter.index = iter.target->count - 1; \
+ } \
+ else \
+ { \
+ iter.cursor = 0; \
+ iter.index = 0; \
+ } \
+\
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ 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 = iter->target->front; \
+ iter->index = 0; \
+ iter->start = true; \
+ iter->end = false; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (!CMC_(PFX, _empty)(iter->target)) \
+ { \
+ if (iter->target->back == 0) \
+ iter->cursor = iter->target->capacity - 1; \
+ else \
+ iter->cursor = iter->target->back - 1; \
+\
+ iter->index = iter->target->count - 1; \
+\
+ iter->start = false; \
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
+ iter->index--; \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->index += steps; \
+ iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->index -= steps; \
+\
+ /* Prevent underflow */ \
+ if (iter->cursor < steps) \
+ iter->cursor += iter->target->capacity; \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ 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]; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->target->buffer[iter->cursor]); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_DEQUE_STR(PARAMS) \
+ CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_DEQUE_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_DEQUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_DEQUE_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_DEQUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_DEQUE_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_DEQUE_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _deque_, FILE * fptr) \
+ { \
+ struct SNAME *d_ = _deque_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "front:%" PRIuMAX ", " \
+ "back:%" PRIuMAX ", " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), d_, d_->buffer, d_->capacity, d_->count, \
+ d_->front, d_->back, d_->flag, d_->f_val, d_->alloc, CMC_CALLBACKS_GET(d_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _deque_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++) \
+ { \
+ if (!_deque_->f_val->str(fptr, _deque_->buffer[i])) \
+ return false; \
+\
+ i = (i + 1) % _deque_->capacity; \
+\
+ if (j + 1 < _deque_->count) \
+ fprintf(fptr, "%s", separator); \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_DEQUE_H */
diff --git a/src/ext/cmc/hashbidimap.h b/src/ext/cmc/hashbidimap.h
new file mode 100644
index 0000000..bf1e423
--- /dev/null
+++ b/src/ext/cmc/hashbidimap.h
@@ -0,0 +1,105 @@
+/**
+ * ext/cmc/hashbidimap.h
+ *
+ * Creation Date: 26/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_HASHBIDIMAP_H
+#define CMC_EXT_CMC_HASHBIDIMAP_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC HashBidiMap.
+ */
+#define CMC_EXT_CMC_HASHBIDIMAP_PARTS STR
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_HASHBIDIMAP_STR(PARAMS) \
+ CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHBIDIMAP_STR_HEADER_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep);
+
+#define CMC_EXT_CMC_HASHBIDIMAP_STR_SOURCE_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
+ { \
+ struct SNAME *m_ = _map_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s, %s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "load:%lf, " \
+ "flag:%d, " \
+ "f_key:%p, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
+ m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ size_t last = 0; \
+ for (size_t i = _map_->capacity; i > 0; i--) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ if (!_map_->f_key->str(fptr, entry->key)) \
+ return false; \
+\
+ fprintf(fptr, "%s", key_val_sep); \
+\
+ if (!_map_->f_val->str(fptr, entry->value)) \
+ return false; \
+\
+ if (i + 1 < last) \
+ fprintf(fptr, "%s", separator); \
+ } \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_HASHBIDIMAP_H */
diff --git a/src/ext/cmc/hashmap.h b/src/ext/cmc/hashmap.h
new file mode 100644
index 0000000..89a87de
--- /dev/null
+++ b/src/ext/cmc/hashmap.h
@@ -0,0 +1,524 @@
+/**
+ * ext/cmc/hashmap.h
+ *
+ * Creation Date: 25/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_HASHMAP_H
+#define CMC_EXT_CMC_HASHMAP_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC HashMap.
+ */
+#define CMC_EXT_CMC_HASHMAP_PARTS INIT, ITER, STR
+
+/**
+ * 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).
+ */
+#define CMC_EXT_CMC_HASHMAP_INIT(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMAP_INIT_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_INIT_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMAP_INIT_HEADER_(PFX, SNAME, K, V) \
+\
+ struct SNAME CMC_(PFX, _init)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val); \
+ struct SNAME CMC_(PFX, _init_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks); \
+ void CMC_(PFX, _release)(struct SNAME _map_);
+
+#define CMC_EXT_CMC_HASHMAP_INIT_SOURCE_(PFX, SNAME, K, V) \
+\
+ struct SNAME CMC_(PFX, _init)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val) \
+ { \
+ return CMC_(PFX, _init_custom)(capacity, load, f_key, f_val, NULL, NULL); \
+ } \
+\
+ struct SNAME CMC_(PFX, _init_custom)(size_t capacity, double load, struct CMC_DEF_FKEY(SNAME) * f_key, \
+ struct CMC_DEF_FVAL(SNAME) * f_val, struct CMC_ALLOC_NODE_NAME * alloc, \
+ struct CMC_CALLBACKS_NAME * callbacks) \
+ { \
+ CMC_CALLBACKS_MAYBE_UNUSED(callbacks); \
+\
+ struct SNAME _map_ = { 0 }; \
+\
+ if (capacity == 0 || load <= 0 || load >= 1) \
+ return _map_; \
+\
+ /* Prevent integer overflow */ \
+ if (capacity >= UINTMAX_MAX * load) \
+ return _map_; \
+\
+ if (!f_key || !f_val) \
+ return _map_; \
+\
+ size_t real_capacity = CMC_(PFX, _impl_calculate_size)(capacity / load); \
+\
+ if (!alloc) \
+ alloc = &cmc_alloc_node_default; \
+\
+ _map_.buffer = alloc->calloc(real_capacity, sizeof(struct CMC_DEF_ENTRY(SNAME))); \
+\
+ if (!_map_.buffer) \
+ return _map_; \
+\
+ _map_.count = 0; \
+ _map_.capacity = real_capacity; \
+ _map_.load = load; \
+ _map_.flag = CMC_FLAG_OK; \
+ _map_.f_key = f_key; \
+ _map_.f_val = f_val; \
+ _map_.alloc = alloc; \
+ CMC_CALLBACKS_ASSIGN(&_map_, callbacks); \
+\
+ return _map_; \
+ } \
+\
+ void CMC_(PFX, _release)(struct SNAME _map_) \
+ { \
+ if (_map_.f_key->free || _map_.f_val->free) \
+ { \
+ for (size_t i = 0; i < _map_.capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_.buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ if (_map_.f_key->free) \
+ _map_.f_key->free(entry->key); \
+ if (_map_.f_val->free) \
+ _map_.f_val->free(entry->value); \
+ } \
+ } \
+ } \
+\
+ _map_.alloc->free(_map_.buffer); \
+ }
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_HASHMAP_ITER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMAP_ITER_HEADER_(PFX, SNAME, K, V) \
+\
+ /* HashMap Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target hashmap */ \
+ struct SNAME *target; \
+\
+ /* Cursor's position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* The index of the first element */ \
+ size_t first; \
+\
+ /* The index of the last element */ \
+ size_t last; \
+\
+ /* 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 */ \
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_HASHMAP_ITER_SOURCE_(PFX, SNAME, K, V) \
+\
+ 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.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = true; \
+ iter.end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ if (target->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.first; \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ if (target->buffer[i - 1].state == CMC_ES_FILLED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+ } \
+\
+ 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.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ if (target->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ if (target->buffer[i - 1].state == CMC_ES_FILLED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.last; \
+ iter.index = 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 = iter->first; \
+ iter->index = 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->last; \
+ iter->index = 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
+\
+ iter->index++; \
+\
+ while (1) \
+ { \
+ iter->cursor++; \
+ scan = &(iter->target->buffer[iter->cursor]); \
+\
+ if (scan->state == CMC_ES_FILLED) \
+ break; \
+ } \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
+\
+ iter->index--; \
+\
+ while (1) \
+ { \
+ iter->cursor--; \
+ scan = &(iter->target->buffer[iter->cursor]); \
+\
+ if (scan->state == CMC_ES_FILLED) \
+ break; \
+ } \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ return true; \
+ } \
+\
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (K){ 0 }; \
+\
+ return iter->target->buffer[iter->cursor].key; \
+ } \
+\
+ 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].value; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->target->buffer[iter->cursor].value); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_HASHMAP_STR(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMAP_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMAP_STR_HEADER_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep);
+
+#define CMC_EXT_CMC_HASHMAP_STR_SOURCE_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
+ { \
+ struct SNAME *m_ = _map_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s, %s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "load:%lf, " \
+ "flag:%d, " \
+ "f_key:%p, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
+ m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ size_t last = 0; \
+ for (size_t i = _map_->capacity; i > 0; i--) \
+ { \
+ if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED) \
+ { \
+ last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_map_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ if (!_map_->f_key->str(fptr, entry->key)) \
+ return false; \
+\
+ fprintf(fptr, "%s", key_val_sep); \
+\
+ if (!_map_->f_val->str(fptr, entry->value)) \
+ return false; \
+\
+ if (i + 1 < last) \
+ fprintf(fptr, "%s", separator); \
+ } \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_HASHMAP_H */
diff --git a/src/ext/cmc/hashmultimap.h b/src/ext/cmc/hashmultimap.h
new file mode 100644
index 0000000..ac03bd6
--- /dev/null
+++ b/src/ext/cmc/hashmultimap.h
@@ -0,0 +1,457 @@
+/**
+ * ext/cmc/hashmultimap.h
+ *
+ * Creation Date: 29/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_HASHMULTIMAP_H
+#define CMC_EXT_CMC_HASHMULTIMAP_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC HashMultiMap.
+ */
+#define CMC_EXT_CMC_HASHMULTIMAP_PARTS ITER, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_HASHMULTIMAP_ITER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTIMAP_ITER_HEADER_(PFX, SNAME, K, V) \
+\
+ /* HashMultiMap Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target hashmultimap */ \
+ struct SNAME *target; \
+\
+ /* Current entry */ \
+ struct CMC_DEF_ENTRY(SNAME) * curr_entry; \
+\
+ /* Cursor`s position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* The index of the first element */ \
+ size_t first; \
+\
+ /* The index of the last element */ \
+ size_t last; \
+\
+ /* 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 */ \
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_HASHMULTIMAP_ITER_SOURCE_(PFX, SNAME, K, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.curr_entry = NULL; \
+ iter.cursor = 0; \
+ iter.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = true; \
+ iter.end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ iter.curr_entry = target->buffer[i][0]; \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.first; \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+ } \
+\
+ return iter; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_end)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.curr_entry = NULL; \
+ iter.cursor = 0; \
+ iter.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i][0]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = target->buffer[i - 1][1]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ iter.curr_entry = target->buffer[i - 1][1]; \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.last; \
+ iter.index = 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 = iter->first; \
+ iter->index = 0; \
+ iter->start = true; \
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+ iter->curr_entry = iter->target->buffer[iter->first][0]; \
+\
+ 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->last; \
+ iter->index = iter->target->count - 1; \
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+ iter->end = true; \
+ iter->curr_entry = iter->target->buffer[iter->last][1]; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->end) \
+ return false; \
+\
+ if (iter->curr_entry->next != NULL) \
+ { \
+ iter->curr_entry = iter->curr_entry->next; \
+ iter->index++; \
+ } \
+ else \
+ { \
+ if (iter->cursor == iter->last) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->cursor++; \
+\
+ while (iter->target->buffer[iter->cursor][0] == NULL) \
+ iter->cursor++; \
+\
+ iter->curr_entry = iter->target->buffer[iter->cursor][0]; \
+\
+ iter->index++; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->curr_entry->prev != NULL) \
+ { \
+ iter->curr_entry = iter->curr_entry->prev; \
+ iter->index--; \
+ } \
+ else \
+ { \
+ if (iter->cursor == iter->first) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->cursor--; \
+\
+ while (iter->target->buffer[iter->cursor][1] == NULL) \
+ iter->cursor--; \
+\
+ iter->curr_entry = iter->target->buffer[iter->cursor][1]; \
+\
+ iter->index--; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ return true; \
+ } \
+\
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (K){ 0 }; \
+\
+ return iter->curr_entry->key; \
+ } \
+\
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (V){ 0 }; \
+\
+ return iter->curr_entry->value; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->curr_entry->value); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_HASHMULTIMAP_STR(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTIMAP_STR_HEADER_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep);
+
+#define CMC_EXT_CMC_HASHMULTIMAP_STR_SOURCE_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
+ { \
+ struct SNAME *m_ = _map_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s, %s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "load:%lf, " \
+ "flag:%d, " \
+ "f_key:%p, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->buffer, m_->capacity, \
+ m_->count, m_->load, m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ size_t last = 0; \
+ for (size_t i = _map_->capacity; i > 0; i--) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = _map_->buffer[i - 1][1]; \
+\
+ if (entry && entry != CMC_ENTRY_DELETED) \
+ { \
+ last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = 0; i < _map_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *scan = _map_->buffer[i][0]; \
+\
+ while (scan != NULL) \
+ { \
+ if (!_map_->f_key->str(fptr, scan->key)) \
+ return false; \
+\
+ fprintf(fptr, "%s", key_val_sep); \
+\
+ if (!_map_->f_val->str(fptr, scan->value)) \
+ return false; \
+\
+ scan = scan->next; \
+\
+ if (i + 1 < last) \
+ fprintf(fptr, "%s", separator); \
+ } \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_HASHMULTIMAP_H */
diff --git a/src/ext/cmc/hashmultiset.h b/src/ext/cmc/hashmultiset.h
new file mode 100644
index 0000000..2aba7c8
--- /dev/null
+++ b/src/ext/cmc/hashmultiset.h
@@ -0,0 +1,698 @@
+/**
+ * ext/cmc/hashmultiset.h
+ *
+ * Creation Date: 30/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_HASHMULTISET_H
+#define CMC_EXT_CMC_HASHMULTISET_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC HashMultiSet.
+ */
+#define CMC_EXT_CMC_HASHMULTISET_PARTS ITER, SETF, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_HASHMULTISET_ITER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTISET_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* HashMultiSet Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target HashMultiset */ \
+ struct SNAME *target; \
+\
+ /* Cursor's position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* The index of the first element */ \
+ size_t first; \
+\
+ /* The index of the last element */ \
+ size_t last; \
+\
+ /* 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_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_HASHMULTISET_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ 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.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = true; \
+ iter.end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ if (target->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.first; \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ if (target->buffer[i - 1].state == CMC_ES_FILLED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+ } \
+\
+ 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.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ if (target->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ if (target->buffer[i - 1].state == CMC_ES_FILLED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.last; \
+ iter.index = 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 = iter->first; \
+ iter->index = 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->last; \
+ iter->index = 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
+\
+ iter->index++; \
+\
+ while (1) \
+ { \
+ iter->cursor++; \
+ scan = &(iter->target->buffer[iter->cursor]); \
+\
+ if (scan->state == CMC_ES_FILLED) \
+ break; \
+ } \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
+\
+ iter->index--; \
+\
+ while (1) \
+ { \
+ iter->cursor--; \
+ scan = &(iter->target->buffer[iter->cursor]); \
+\
+ if (scan->state == CMC_ES_FILLED) \
+ break; \
+ } \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ 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].value; \
+ } \
+\
+ size_t CMC_(PFX, _iter_multiplicity)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return 0; \
+\
+ return iter->target->buffer[iter->cursor].multiplicity; \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * SETF
+ */
+#define CMC_EXT_CMC_HASHMULTISET_SETF(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTISET_SETF_HEADER_(PFX, SNAME, V) \
+\
+ /* Set Operations */ \
+ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_);
+
+#define CMC_EXT_CMC_HASHMULTISET_SETF_SOURCE_(PFX, SNAME, V) \
+\
+ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter1); \
+\
+ size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \
+ size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
+ size_t max_ = m1 > m2 ? m1 : m2; \
+\
+ CMC_(PFX, _update)(_set_r_, value, max_); \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter2); \
+\
+ size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \
+ size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \
+ size_t max_ = m1 > m2 ? m1 : m2; \
+\
+ CMC_(PFX, _update)(_set_r_, value, max_); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
+ struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
+ size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set_B_, value); \
+ size_t max_ = m1 < m2 ? m1 : m2; \
+\
+ CMC_(PFX, _update)(_set_r_, value, max_); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
+ size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
+\
+ if (m1 > m2) \
+ CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _summation)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ CMC_(PFX, _insert_many) \
+ (_set_r_, CMC_(PFX, _iter_value)(&iter1), CMC_(PFX, _iter_multiplicity)(&iter1)); \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ CMC_(PFX, _insert_many) \
+ (_set_r_, CMC_(PFX, _iter_value)(&iter2), CMC_(PFX, _iter_multiplicity)(&iter2)); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter1); \
+\
+ size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter1); \
+ size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
+\
+ if (m1 != m2) \
+ { \
+ if (m1 > m2) \
+ CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
+ else \
+ CMC_(PFX, _update)(_set_r_, value, m2 - m1); \
+ } \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter2); \
+\
+ size_t m1 = CMC_(PFX, _impl_multiplicity_of)(_set1_, value); \
+ size_t m2 = CMC_(PFX, _iter_multiplicity)(&iter2); \
+\
+ if (m1 != m2) \
+ { \
+ if (m1 > m2) \
+ CMC_(PFX, _update)(_set_r_, value, m1 - m2); \
+ else \
+ CMC_(PFX, _update)(_set_r_, value, m2 - m1); \
+ } \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ if (_set1_->count > _set2_->count) \
+ return false; \
+\
+ if (CMC_(PFX, _empty)(_set1_)) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
+ size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
+\
+ if (m1 > m2) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ return CMC_(PFX, _is_subset)(_set2_, _set1_); \
+ } \
+\
+ bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ if (_set1_->count >= _set2_->count) \
+ return false; \
+\
+ if (CMC_(PFX, _empty)(_set1_)) \
+ { \
+ if (!CMC_(PFX, _empty)(_set2_)) \
+ return true; \
+ else \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ size_t m1 = CMC_(PFX, _iter_multiplicity)(&iter); \
+ size_t m2 = CMC_(PFX, _impl_multiplicity_of)(_set2_, value); \
+\
+ if (m1 >= m2) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \
+ } \
+\
+ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ if (CMC_(PFX, _empty)(_set1_)) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_HASHMULTISET_STR(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHMULTISET_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep);
+
+#define CMC_EXT_CMC_HASHMULTISET_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \
+ { \
+ struct SNAME *s_ = _set_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "cardinality:%" PRIuMAX ", " \
+ "load:%lf, " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, \
+ s_->cardinality, s_->load, s_->flag, s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *val_mul_sep) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ size_t last = 0; \
+ for (size_t i = _set_->capacity; i > 0; i--) \
+ { \
+ if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \
+ { \
+ last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ if (!_set_->f_val->str(fptr, entry->value)) \
+ return false; \
+\
+ fprintf(fptr, "%s", val_mul_sep); \
+\
+ if (fprintf(fptr, "%" PRIuMAX "", entry->multiplicity) < 0) \
+ return false; \
+\
+ if (i + 1 < last) \
+ fprintf(fptr, "%s", separator); \
+ } \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_HASHMULTISET_H */
diff --git a/src/ext/cmc/hashset.h b/src/ext/cmc/hashset.h
new file mode 100644
index 0000000..ac42cba
--- /dev/null
+++ b/src/ext/cmc/hashset.h
@@ -0,0 +1,666 @@
+/**
+ * ext/cmc/hashset.h
+ *
+ * Creation Date: 29/05/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_HASHSET_H
+#define CMC_EXT_CMC_HASHSET_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC HashSet.
+ */
+#define CMC_EXT_CMC_HASHSET_PARTS ITER, SETF, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_HASHSET_ITER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHSET_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHSET_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHSET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHSET_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* HashSet Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target HashSet */ \
+ struct SNAME *target; \
+\
+ /* Cursor's position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* The index of the first element */ \
+ size_t first; \
+\
+ /* The index of the last element */ \
+ size_t last; \
+\
+ /* 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);
+
+#define CMC_EXT_CMC_HASHSET_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ 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.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = true; \
+ iter.end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ if (target->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.first; \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ if (target->buffer[i - 1].state == CMC_ES_FILLED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+ } \
+\
+ 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.index = 0; \
+ iter.first = 0; \
+ iter.last = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ for (size_t i = 0; i < target->capacity; i++) \
+ { \
+ if (target->buffer[i].state == CMC_ES_FILLED) \
+ { \
+ iter.first = i; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = target->capacity; i > 0; i--) \
+ { \
+ if (target->buffer[i - 1].state == CMC_ES_FILLED) \
+ { \
+ iter.last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ iter.cursor = iter.last; \
+ iter.index = 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 = iter->first; \
+ iter->index = 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->last; \
+ iter->index = 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
+\
+ iter->index++; \
+\
+ while (1) \
+ { \
+ iter->cursor++; \
+ scan = &(iter->target->buffer[iter->cursor]); \
+\
+ if (scan->state == CMC_ES_FILLED) \
+ break; \
+ } \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ struct CMC_DEF_ENTRY(SNAME) *scan = &(iter->target->buffer[iter->cursor]); \
+\
+ iter->index--; \
+\
+ while (1) \
+ { \
+ iter->cursor--; \
+ scan = &(iter->target->buffer[iter->cursor]); \
+\
+ if (scan->state == CMC_ES_FILLED) \
+ break; \
+ } \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ 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].value; \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * SETF
+ */
+#define CMC_EXT_CMC_HASHSET_SETF(PARAMS) \
+ CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHSET_SETF_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHSET_SETF_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHSET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHSET_SETF_HEADER_(PFX, SNAME, V) \
+\
+ /* Set Operations */ \
+ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_);
+
+#define CMC_EXT_CMC_HASHSET_SETF_SOURCE_(PFX, SNAME, V) \
+\
+ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ { \
+ _set1_->flag = CMC_FLAG_ALLOC; \
+ _set2_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ /* TODO turn this into a normal loop and check for errors */ \
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ { \
+ _set1_->flag = CMC_FLAG_ALLOC; \
+ _set2_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
+ struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set_B_, value) != NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ { \
+ _set1_->flag = CMC_FLAG_ALLOC; \
+ _set2_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* Callbacks are added later */ \
+ struct SNAME *_set_r_ = \
+ CMC_(PFX, _new_custom)(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ { \
+ _set1_->flag = CMC_FLAG_ALLOC; \
+ _set2_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter1); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter2); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set1_, value) == NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ /* Is _set1_ a subset of _set2_ ? */ \
+ /* A set X is a subset of a set Y when: X <= Y */ \
+ /* If X is a subset of Y, then Y is a superset of X */ \
+ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ _set1_->flag = CMC_FLAG_OK; \
+ _set2_->flag = CMC_FLAG_OK; \
+\
+ /* If the cardinality of _set1_ is greater than that of _set2_, */ \
+ /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \
+ if (_set1_->count > _set2_->count) \
+ return false; \
+\
+ /* The empty set is a subset of all sets */ \
+ if (CMC_(PFX, _empty)(_set1_)) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ /* Is _set1_ a superset of _set2_ ? */ \
+ /* A set X is a superset of a set Y when: X >= Y */ \
+ /* If X is a superset of Y, then Y is a subset of X */ \
+ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ return CMC_(PFX, _is_subset)(_set2_, _set1_); \
+ } \
+\
+ /* Is _set1_ a proper subset of _set2_ ? */ \
+ /* A set X is a proper subset of a set Y when: X < Y */ \
+ /* If X is a proper subset of Y, then Y is a proper superset of X */ \
+ bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ _set1_->flag = CMC_FLAG_OK; \
+ _set2_->flag = CMC_FLAG_OK; \
+\
+ /* If the cardinality of _set1_ is greater than or equal to that of */ \
+ /* _set2_, then it is safe to say that _set1_ can't be a proper */ \
+ /* subset of _set2_ */ \
+ if (_set1_->count >= _set2_->count) \
+ return false; \
+\
+ if (CMC_(PFX, _empty)(_set1_)) \
+ { \
+ /* The empty set is a proper subset of all non-empty sets */ \
+ if (!CMC_(PFX, _empty)(_set2_)) \
+ return true; \
+ /* The empty set is not a proper subset of itself (this is true */ \
+ /* for any set) */ \
+ else \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set2_, value) == NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ /* Is _set1_ a proper superset of _set2_ ? */ \
+ /* A set X is a proper superset of a set Y when: X > Y */ \
+ /* If X is a proper superset of Y, then Y is a proper subset of X */ \
+ bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \
+ } \
+\
+ /* Is _set1_ a disjointset of _set2_ ? */ \
+ /* A set X is a disjointset of a set Y if their intersection is empty, */ \
+ /* that is, if there are no elements in common between the two */ \
+ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ _set1_->flag = CMC_FLAG_OK; \
+ _set2_->flag = CMC_FLAG_OK; \
+\
+ /* The intersection of an empty set with any other set will result */ \
+ /* in an empty set */ \
+ if (CMC_(PFX, _empty)(_set1_)) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_entry)(_set2_, value) != NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_HASHSET_STR(PARAMS) \
+ CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HASHSET_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HASHSET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHSET_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HASHSET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HASHSET_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_HASHSET_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \
+ { \
+ struct SNAME *s_ = _set_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "load:%lf, " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks: %p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->load, \
+ s_->flag, s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ size_t last = 0; \
+ for (size_t i = _set_->capacity; i > 0; i--) \
+ { \
+ if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED) \
+ { \
+ last = i - 1; \
+ break; \
+ } \
+ } \
+\
+ for (size_t i = 0; i < _set_->capacity; i++) \
+ { \
+ struct CMC_DEF_ENTRY(SNAME) *entry = &(_set_->buffer[i]); \
+\
+ if (entry->state == CMC_ES_FILLED) \
+ { \
+ if (!_set_->f_val->str(fptr, entry->value)) \
+ return false; \
+\
+ if (i + 1 < last) \
+ fprintf(fptr, "%s", separator); \
+ } \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_HASHSET_H */
diff --git a/src/ext/cmc/heap.h b/src/ext/cmc/heap.h
new file mode 100644
index 0000000..fa62ad0
--- /dev/null
+++ b/src/ext/cmc/heap.h
@@ -0,0 +1,305 @@
+/**
+ * ext/cmc/heap.h
+ *
+ * Creation Date: 01/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_HEAP_H
+#define CMC_EXT_CMC_HEAP_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC Heap.
+ */
+#define CMC_EXT_CMC_HEAP_PARTS ITER, STR
+
+#define CMC_EXT_CMC_HEAP_ITER(PARAMS) \
+ CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HEAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_HEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HEAP_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HEAP_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* 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; \
+ }; \
+\
+ /* 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);
+
+#define CMC_EXT_CMC_HEAP_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ 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; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_HEAP_STR(PARAMS) \
+ CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_HEAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_HEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HEAP_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_HEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_HEAP_STR_HEADER_(PFX, SNAME, V) \
+\
+ 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);
+
+#define CMC_EXT_CMC_HEAP_STR_SOURCE_(PFX, SNAME, V) \
+\
+ 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_CMC_HEAP_H */
diff --git a/src/ext/cmc/intervalheap.h b/src/ext/cmc/intervalheap.h
new file mode 100644
index 0000000..d1f8ccf
--- /dev/null
+++ b/src/ext/cmc/intervalheap.h
@@ -0,0 +1,307 @@
+/**
+ * ext/cmc/intervalheap.h
+ *
+ * Creation Date: 02/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_INTERVALHEAP_H
+#define CMC_EXT_CMC_INTERVALHEAP_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC IntervalHeap.
+ */
+#define CMC_EXT_CMC_INTERVALHEAP_PARTS ITER, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_INTERVALHEAP_ITER(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_INTERVALHEAP_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* 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);
+
+#define CMC_EXT_CMC_INTERVALHEAP_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ 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; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_INTERVALHEAP_STR(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_INTERVALHEAP_STR_HEADER_(PFX, SNAME, V) \
+\
+ 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);
+
+#define CMC_EXT_CMC_INTERVALHEAP_STR_SOURCE_(PFX, SNAME, V) \
+\
+ 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_CMC_INTERVALHEAP_H */
diff --git a/src/ext/cmc/linkedlist.h b/src/ext/cmc/linkedlist.h
new file mode 100644
index 0000000..0e8982c
--- /dev/null
+++ b/src/ext/cmc/linkedlist.h
@@ -0,0 +1,567 @@
+/**
+ * ext/cmc/linkedlist.h
+ *
+ * Creation Date: 03/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_LINKEDLIST_H
+#define CMC_EXT_CMC_LINKEDLIST_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC LinkedList.
+ */
+#define CMC_EXT_CMC_LINKEDLIST_PARTS ITER, NODE, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_LINKEDLIST_ITER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LINKEDLIST_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* LinkedList Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target Linked List */ \
+ struct SNAME *target; \
+\
+ /* Cursor's current node */ \
+ struct CMC_DEF_NODE(SNAME) * cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* 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); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter); \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_LINKEDLIST_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.cursor = target->head; \
+ iter.index = 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 = target->tail; \
+ iter.index = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ iter.index = 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 = iter->target->head; \
+ iter->index = 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->tail; \
+ iter->index = 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->next == NULL) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->cursor = iter->cursor->next; \
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->cursor->prev == NULL) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->cursor = iter->cursor->prev; \
+ iter->index--; \
+\
+ 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->next == NULL) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->index += steps; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ iter->cursor = iter->cursor->next; \
+\
+ 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->prev == NULL) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->index -= steps; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ iter->cursor = iter->cursor->prev; \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (V){ 0 }; \
+\
+ return iter->cursor->value; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->cursor->value); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _iter_node)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->cursor; \
+ }
+
+/**
+ * NODE
+ */
+#define CMC_EXT_CMC_LINKEDLIST_NODE(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LINKEDLIST_NODE_HEADER_(PFX, SNAME, V) \
+\
+ /* Node Allocation and Deallocation */ \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _new_node)(struct SNAME * _list_, V value); \
+ void CMC_(PFX, _free_node)(struct SNAME * _list_, struct CMC_DEF_NODE(SNAME) * _node_); \
+ /* Node Access Relative to a Linked List */ \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_); \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index); \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_); \
+ /* Input and Output Relative to a Node */ \
+ bool CMC_(PFX, _add_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value); \
+ bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value); \
+ bool CMC_(PFX, _del_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \
+ bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \
+ bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_); \
+ /* Node Access Relative to a Linked List Node */ \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_); \
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_);
+
+#define CMC_EXT_CMC_LINKEDLIST_NODE_SOURCE_(PFX, SNAME, V) \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _new_node)(struct SNAME * _list_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *_node_ = _list_->alloc->malloc(sizeof(struct CMC_DEF_NODE(SNAME))); \
+\
+ if (!_node_) \
+ { \
+ _list_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ _node_->value = value; \
+ _node_->next = NULL; \
+ _node_->prev = NULL; \
+\
+ return _node_; \
+ } \
+\
+ void CMC_(PFX, _free_node)(struct SNAME * _list_, struct CMC_DEF_NODE(SNAME) * _node_) \
+ { \
+ _list_->alloc->free(_node_); \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _head)(struct SNAME * _list_) \
+ { \
+ return _list_->head; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _get_node)(struct SNAME * _list_, size_t index) \
+ { \
+ if (CMC_(PFX, _empty)(_list_)) \
+ { \
+ _list_->flag = CMC_FLAG_EMPTY; \
+ return NULL; \
+ } \
+\
+ if (index >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return NULL; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *_node_ = NULL; \
+\
+ if (index <= _list_->count / 2) \
+ { \
+ _node_ = _list_->head; \
+ for (size_t i = 0; i < index; i++) \
+ { \
+ _node_ = _node_->next; \
+ } \
+ } \
+ else \
+ { \
+ _node_ = _list_->tail; \
+ for (size_t i = _list_->count - 1; i > index; i--) \
+ { \
+ _node_ = _node_->prev; \
+ } \
+ } \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ return _node_; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _tail)(struct SNAME * _list_) \
+ { \
+ return _list_->tail; \
+ } \
+\
+ bool CMC_(PFX, _add_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *new_node = CMC_(PFX, _new_node)(_owner_, value); \
+\
+ if (!new_node) \
+ return false; \
+\
+ new_node->next = _node_->next; \
+\
+ if (_node_->next != NULL) \
+ _node_->next->prev = new_node; \
+ else \
+ _owner_->tail = new_node; \
+\
+ new_node->prev = _node_; \
+ _node_->next = new_node; \
+\
+ _owner_->count++; \
+ _owner_->flag = CMC_FLAG_OK; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _add_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_, V value) \
+ { \
+ struct CMC_DEF_NODE(SNAME) *new_node = CMC_(PFX, _new_node)(_owner_, value); \
+\
+ if (!new_node) \
+ return false; \
+\
+ new_node->prev = _node_->prev; \
+\
+ if (_node_->prev != NULL) \
+ _node_->prev->next = new_node; \
+ else \
+ _owner_->head = new_node; \
+\
+ new_node->next = _node_; \
+ _node_->prev = new_node; \
+\
+ _owner_->count++; \
+ _owner_->flag = CMC_FLAG_OK; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _del_next)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \
+ { \
+ if (_node_->next == NULL) \
+ { \
+ _owner_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *tmp = _node_->next; \
+\
+ _node_->next = _node_->next->next; \
+\
+ if (tmp->next != NULL) \
+ tmp->next->prev = _node_; \
+ else \
+ _owner_->tail = _node_; \
+\
+ _owner_->alloc->free(tmp); \
+\
+ _owner_->count--; \
+ _owner_->flag = CMC_FLAG_OK; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _del_curr)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \
+ { \
+ if (_node_->prev != NULL) \
+ _node_->prev->next = _node_->next; \
+ else \
+ _owner_->head = _node_->next; \
+\
+ if (_node_->next != NULL) \
+ _node_->next->prev = _node_->prev; \
+ else \
+ _owner_->tail = _node_->prev; \
+\
+ _owner_->alloc->free(_node_); \
+\
+ _owner_->count--; \
+ _owner_->flag = CMC_FLAG_OK; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _del_prev)(struct SNAME * _owner_, struct CMC_DEF_NODE(SNAME) * _node_) \
+ { \
+ if (_node_->prev == NULL) \
+ { \
+ _owner_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) *tmp = _node_->prev; \
+\
+ _node_->prev = _node_->prev->prev; \
+\
+ if (tmp->prev != NULL) \
+ tmp->prev->next = _node_; \
+ else \
+ _owner_->head = _node_; \
+\
+ _owner_->alloc->free(tmp); \
+\
+ _owner_->count--; \
+ _owner_->flag = CMC_FLAG_OK; \
+\
+ return true; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _next_node)(struct CMC_DEF_NODE(SNAME) * _node_) \
+ { \
+ return _node_->next; \
+ } \
+\
+ struct CMC_DEF_NODE(SNAME) * CMC_(PFX, _prev_node)(struct CMC_DEF_NODE(SNAME) * _node_) \
+ { \
+ return _node_->prev; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_LINKEDLIST_STR(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LINKEDLIST_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_LINKEDLIST_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \
+ { \
+ struct SNAME *l_ = _list_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "count:%" PRIuMAX ", " \
+ "head:%p, " \
+ "tail:%p, " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->count, l_->head, l_->tail, l_->flag, \
+ l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ struct CMC_DEF_NODE(SNAME) *scan = _list_->head; \
+\
+ while (scan != NULL) \
+ { \
+ if (!_list_->f_val->str(fptr, scan->value)) \
+ return false; \
+\
+ scan = scan->next; \
+\
+ if (scan) \
+ fprintf(fptr, "%s", separator); \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_LINKEDLIST_H */
diff --git a/src/ext/cmc/list.h b/src/ext/cmc/list.h
new file mode 100644
index 0000000..ad971c8
--- /dev/null
+++ b/src/ext/cmc/list.h
@@ -0,0 +1,492 @@
+/**
+ * ext/cmc/list.h
+ *
+ * Creation Date: 04/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_LIST_H
+#define CMC_EXT_CMC_LIST_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC List.
+ */
+#define CMC_EXT_CMC_LIST_PARTS ITER, SEQ, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_LIST_ITER(PARAMS) \
+ CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_LIST_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_LIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LIST_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_LIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LIST_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* List Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target List */ \
+ 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); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_LIST_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ 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->start = CMC_(PFX, _empty)(iter->target); \
+ iter->cursor = iter->target->count - 1; \
+ 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; \
+\
+ 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]; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->target->buffer[iter->cursor]); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->cursor; \
+ }
+
+/**
+ * SEQ
+ */
+#define CMC_EXT_CMC_LIST_SEQ(PARAMS) \
+ CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \
+ CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_LIST_SEQ_HEADER(PARAMS) \
+ CMC_EXT_CMC_LIST_SEQ_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LIST_SEQ_SOURCE(PARAMS) \
+ CMC_EXT_CMC_LIST_SEQ_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LIST_SEQ_HEADER_(PFX, SNAME, V) \
+\
+ /* List Sequence Input and Output */ \
+ bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, size_t size); \
+ bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, size_t size, size_t index); \
+ bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, size_t size); \
+ bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to); \
+ struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, size_t to);
+
+#define CMC_EXT_CMC_LIST_SEQ_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _seq_push_front)(struct SNAME * _list_, V * values, size_t size) \
+ { \
+ if (size == 0) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ if (!CMC_(PFX, _fits)(_list_, size)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
+ return false; \
+ } \
+\
+ memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(V)); \
+\
+ memcpy(_list_->buffer, values, size * sizeof(V)); \
+\
+ _list_->count += size; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _seq_push_at)(struct SNAME * _list_, V * values, size_t size, size_t index) \
+ { \
+ if (size == 0) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ if (index > _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ if (index == 0) \
+ return CMC_(PFX, _seq_push_front)(_list_, values, size); \
+ else if (index == _list_->count) \
+ return CMC_(PFX, _seq_push_back)(_list_, values, size); \
+\
+ if (!CMC_(PFX, _fits)(_list_, size)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
+ return false; \
+ } \
+\
+ memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(V)); \
+\
+ memcpy(_list_->buffer + index, values, size * sizeof(V)); \
+\
+ _list_->count += size; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _seq_push_back)(struct SNAME * _list_, V * values, size_t size) \
+ { \
+ if (size == 0) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ if (!CMC_(PFX, _fits)(_list_, size)) \
+ { \
+ if (!CMC_(PFX, _resize)(_list_, _list_->count + size)) \
+ return false; \
+ } \
+\
+ memcpy(_list_->buffer + _list_->count, values, size * sizeof(V)); \
+\
+ _list_->count += size; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, create); \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _seq_pop_at)(struct SNAME * _list_, size_t from, size_t to) \
+ { \
+ if (from > to) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return false; \
+ } \
+\
+ if (to >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return false; \
+ } \
+\
+ size_t length = (to - from + 1); \
+\
+ memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \
+\
+ memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \
+\
+ _list_->count -= to - from + 1; \
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return true; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _seq_sublist)(struct SNAME * _list_, size_t from, size_t to) \
+ { \
+ if (from > to) \
+ { \
+ _list_->flag = CMC_FLAG_INVALID; \
+ return NULL; \
+ } \
+\
+ if (to >= _list_->count) \
+ { \
+ _list_->flag = CMC_FLAG_RANGE; \
+ return NULL; \
+ } \
+\
+ size_t length = to - from + 1; \
+\
+ struct SNAME *result = \
+ CMC_(PFX, _new_custom)(length, _list_->f_val, _list_->alloc, CMC_CALLBACKS_GET(_list_)); \
+\
+ if (!result) \
+ { \
+ _list_->flag = CMC_FLAG_ALLOC; \
+ return NULL; \
+ } \
+\
+ memcpy(result->buffer, _list_->buffer, length * sizeof(V)); \
+\
+ memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(V)); \
+\
+ memset(_list_->buffer + _list_->count - length, 0, length * sizeof(V)); \
+\
+ _list_->count -= length; \
+ result->count = length; \
+\
+ _list_->flag = CMC_FLAG_OK; \
+\
+ CMC_CALLBACKS_CALL(_list_, delete); \
+\
+ return result; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_LIST_STR(PARAMS) \
+ CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_LIST_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_LIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LIST_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_LIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_LIST_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_LIST_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \
+ { \
+ struct SNAME *l_ = _list_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, l_->flag, \
+ l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ for (size_t i = 0; i < _list_->count; i++) \
+ { \
+ if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
+ return false; \
+\
+ if (i + 1 < _list_->count) \
+ fprintf(fptr, "%s", separator); \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_LIST_H */
diff --git a/src/ext/cmc/queue.h b/src/ext/cmc/queue.h
new file mode 100644
index 0000000..23a0e53
--- /dev/null
+++ b/src/ext/cmc/queue.h
@@ -0,0 +1,348 @@
+/**
+ * ext/cmc/queue.h
+ *
+ * Creation Date: 05/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_QUEUE_H
+#define CMC_EXT_CMC_QUEUE_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC Queue.
+ */
+#define CMC_EXT_CMC_QUEUE_PARTS ITER, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_QUEUE_ITER(PARAMS) \
+ CMC_EXT_CMC_QUEUE_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_QUEUE_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_QUEUE_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_QUEUE_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_QUEUE_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_QUEUE_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_QUEUE_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* Queue Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target queue */ \
+ struct SNAME *target; \
+\
+ /* Cursor's position (index) */ \
+ size_t cursor; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* 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); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_QUEUE_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.cursor = target->front; \
+ iter.index = 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; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ if (iter.target->back == 0) \
+ iter.cursor = iter.target->capacity - 1; \
+ else \
+ iter.cursor = iter.target->back - 1; \
+\
+ iter.index = iter.target->count - 1; \
+ } \
+ else \
+ { \
+ iter.cursor = 0; \
+ iter.index = 0; \
+ } \
+\
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ 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 = iter->target->front; \
+ iter->index = 0; \
+ iter->start = true; \
+ iter->end = false; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (!CMC_(PFX, _empty)(iter->target)) \
+ { \
+ if (iter->target->back == 0) \
+ iter->cursor = iter->target->capacity - 1; \
+ else \
+ iter->cursor = iter->target->back - 1; \
+\
+ iter->index = iter->target->count - 1; \
+\
+ iter->start = false; \
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->cursor = (iter->cursor + 1) % (iter->target->capacity); \
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1; \
+ iter->index--; \
+\
+ 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->index + 1 == iter->target->count) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->index += steps; \
+ iter->cursor = (iter->cursor + steps) % iter->target->capacity; \
+\
+ 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->index == 0) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ iter->index -= steps; \
+\
+ /* Prevent underflow */ \
+ if (iter->cursor < steps) \
+ iter->cursor += iter->target->capacity; \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ 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]; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->target->buffer[iter->cursor]); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_QUEUE_STR(PARAMS) \
+ CMC_EXT_CMC_QUEUE_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_QUEUE_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_QUEUE_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_QUEUE_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_QUEUE_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_QUEUE_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_QUEUE_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _queue_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_QUEUE_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _queue_, FILE * fptr) \
+ { \
+ struct SNAME *q_ = _queue_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "front:%" PRIuMAX ", " \
+ "back:%" PRIuMAX ", " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), q_, q_->buffer, q_->capacity, q_->count, \
+ q_->front, q_->back, q_->flag, q_->f_val, q_->alloc, CMC_CALLBACKS_GET(q_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _queue_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++) \
+ { \
+ if (!_queue_->f_val->str(fptr, _queue_->buffer[i])) \
+ return false; \
+\
+ i = (i + 1) % _queue_->capacity; \
+\
+ if (j + 1 < _queue_->count) \
+ fprintf(fptr, "%s", separator); \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_QUEUE_H */
diff --git a/src/ext/cmc/sortedlist.h b/src/ext/cmc/sortedlist.h
new file mode 100644
index 0000000..fdfe0e4
--- /dev/null
+++ b/src/ext/cmc/sortedlist.h
@@ -0,0 +1,310 @@
+/**
+ * ext/cmc/sortedlist.h
+ *
+ * Creation Date: 06/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_SORTEDLIST_H
+#define CMC_EXT_CMC_SORTEDLIST_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC SortedList.
+ */
+#define CMC_EXT_CMC_SORTEDLIST_PARTS ITER, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_SORTEDLIST_ITER(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_SORTEDLIST_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* List Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target list */ \
+ 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);
+
+#define CMC_EXT_CMC_SORTEDLIST_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ CMC_(PFX, _sort)(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) \
+ { \
+ CMC_(PFX, _sort)(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->start = CMC_(PFX, _empty)(iter->target); \
+ iter->cursor = iter->target->count - 1; \
+ 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; \
+\
+ 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; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_SORTEDLIST_STR(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_SORTEDLIST_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_SORTEDLIST_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_SORTEDLIST_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_SORTEDLIST_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _list_, FILE * fptr) \
+ { \
+ struct SNAME *l_ = _list_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "is_sorted:%s, " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), l_, l_->buffer, l_->capacity, l_->count, \
+ l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, CMC_CALLBACKS_GET(l_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _list_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ CMC_(PFX, _sort)(_list_); \
+\
+ fprintf(fptr, "%s", start); \
+\
+ for (size_t i = 0; i < _list_->count; i++) \
+ { \
+ if (!_list_->f_val->str(fptr, _list_->buffer[i])) \
+ return false; \
+\
+ if (i + 1 < _list_->count) \
+ fprintf(fptr, "%s", separator); \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_SORTEDLIST_H */
diff --git a/src/ext/cmc/stack.h b/src/ext/cmc/stack.h
new file mode 100644
index 0000000..0efdefd
--- /dev/null
+++ b/src/ext/cmc/stack.h
@@ -0,0 +1,315 @@
+/**
+ * ext/cmc/stack.h
+ *
+ * Creation Date: 07/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_STACK_H
+#define CMC_EXT_CMC_STACK_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC Stack.
+ */
+#define CMC_EXT_CMC_STACK_PARTS ITER, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_STACK_ITER(PARAMS) \
+ CMC_EXT_CMC_STACK_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_STACK_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_STACK_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_STACK_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_STACK_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_STACK_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_STACK_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* Stack Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target stack */ \
+ 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); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_STACK_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ 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); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ iter.cursor = target->count - 1; \
+\
+ 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; \
+\
+ 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 = iter->target->count - 1; \
+ 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 = 0; \
+ 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 == 0) \
+ { \
+ 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 + 1 == iter->target->count) \
+ { \
+ 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 == 0) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->cursor < steps) \
+ 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 + 1 == iter->target->count) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->cursor + steps >= iter->target->count) \
+ 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_advance)(iter, iter->cursor - index); \
+ else if (iter->cursor < index) \
+ return CMC_(PFX, _iter_rewind)(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]; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->target->buffer[iter->cursor]); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return 0; \
+\
+ return iter->target->count - 1 - iter->cursor; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_STACK_STR(PARAMS) \
+ CMC_EXT_CMC_STACK_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_STACK_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_STACK_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_STACK_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_STACK_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_STACK_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_STACK_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _stack_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_STACK_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _stack_, FILE * fptr) \
+ { \
+ struct SNAME *s_ = _stack_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "buffer:%p, " \
+ "capacity:%" PRIuMAX ", " \
+ "count:%" PRIuMAX ", " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->buffer, s_->capacity, s_->count, s_->flag, \
+ s_->f_val, s_->alloc, CMC_CALLBACKS_GET(s_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _stack_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ for (size_t i = _stack_->count; i > 0; i--) \
+ { \
+ if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1])) \
+ return false; \
+\
+ if (i - 1 != 0) \
+ fprintf(fptr, "%s", separator); \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_STACK_H */
diff --git a/src/ext/cmc/treemap.h b/src/ext/cmc/treemap.h
new file mode 100644
index 0000000..cf45ad0
--- /dev/null
+++ b/src/ext/cmc/treemap.h
@@ -0,0 +1,443 @@
+/**
+ * ext/cmc/treemap.h
+ *
+ * Creation Date: 08/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_TREEMAP_H
+#define CMC_EXT_CMC_TREEMAP_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC TreeMap.
+ */
+#define CMC_EXT_CMC_TREEMAP_PARTS ITER, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_TREEMAP_ITER(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_TREEMAP_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREEMAP_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREEMAP_ITER_HEADER_(PFX, SNAME, K, V) \
+\
+ /* Treemap Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target treemap */ \
+ struct SNAME *target; \
+\
+ /* Cursor's current node */ \
+ struct CMC_DEF_NODE(SNAME) * cursor; \
+\
+ /* The first node in the iteration */ \
+ struct CMC_DEF_NODE(SNAME) * first; \
+\
+ /* The last node in the iteration */ \
+ struct CMC_DEF_NODE(SNAME) * last; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* 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 */ \
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter); \
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter); \
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter);
+
+#define CMC_EXT_CMC_TREEMAP_ITER_SOURCE_(PFX, SNAME, K, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.cursor = target->root; \
+ iter.first = NULL; \
+ iter.last = NULL; \
+ iter.index = 0; \
+ iter.start = true; \
+ iter.end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ while (iter.cursor->left != NULL) \
+ iter.cursor = iter.cursor->left; \
+\
+ iter.first = iter.cursor; \
+\
+ iter.last = target->root; \
+ while (iter.last->right != NULL) \
+ iter.last = iter.last->right; \
+ } \
+\
+ 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 = target->root; \
+ iter.first = NULL; \
+ iter.last = NULL; \
+ iter.index = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ while (iter.cursor->right != NULL) \
+ iter.cursor = iter.cursor->right; \
+\
+ iter.last = iter.cursor; \
+\
+ iter.first = target->root; \
+ while (iter.first->left != NULL) \
+ iter.first = iter.first->left; \
+\
+ iter.index = 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->index = 0; \
+ iter->start = true; \
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+ iter->cursor = iter->first; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (!CMC_(PFX, _empty)(iter->target)) \
+ { \
+ iter->index = iter->target->count - 1; \
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+ iter->end = true; \
+ iter->cursor = iter->last; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->end) \
+ return false; \
+\
+ if (iter->cursor == iter->last) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ if (iter->cursor->right != NULL) \
+ { \
+ iter->cursor = iter->cursor->right; \
+\
+ while (iter->cursor->left != NULL) \
+ iter->cursor = iter->cursor->left; \
+\
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ while (true) \
+ { \
+ if (iter->cursor->parent->left == iter->cursor) \
+ { \
+ iter->cursor = iter->cursor->parent; \
+\
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ iter->cursor = iter->cursor->parent; \
+ } \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->cursor == iter->first) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ if (iter->cursor->left != NULL) \
+ { \
+ iter->cursor = iter->cursor->left; \
+\
+ while (iter->cursor->right != NULL) \
+ iter->cursor = iter->cursor->right; \
+\
+ iter->index--; \
+\
+ return true; \
+ } \
+\
+ while (true) \
+ { \
+ if (iter->cursor->parent->right == iter->cursor) \
+ { \
+ iter->cursor = iter->cursor->parent; \
+\
+ iter->index--; \
+\
+ return true; \
+ } \
+\
+ iter->cursor = iter->cursor->parent; \
+ } \
+ } \
+\
+ /* 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 == iter->last) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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 == iter->first) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ return true; \
+ } \
+\
+ K CMC_(PFX, _iter_key)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (K){ 0 }; \
+\
+ return iter->cursor->key; \
+ } \
+\
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (V){ 0 }; \
+\
+ return iter->cursor->value; \
+ } \
+\
+ V *CMC_(PFX, _iter_rvalue)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return NULL; \
+\
+ return &(iter->cursor->value); \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_TREEMAP_STR(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_TREEMAP_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREEMAP_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_TREEMAP_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_K(PARAMS), \
+ CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREEMAP_STR_HEADER_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep);
+
+#define CMC_EXT_CMC_TREEMAP_STR_SOURCE_(PFX, SNAME, K, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _map_, FILE * fptr) \
+ { \
+ struct SNAME *m_ = _map_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s, %s> " \
+ "at %p { " \
+ "root:%p, " \
+ "count:%" PRIuMAX ", " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "f_key:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(K), CMC_TO_STRING(V), m_, m_->root, m_->count, \
+ m_->flag, m_->f_key, m_->f_val, m_->alloc, CMC_CALLBACKS_GET(m_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _map_, FILE * fptr, const char *start, const char *separator, \
+ const char *end, const char *key_val_sep) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ struct CMC_DEF_NODE(SNAME) *root = _map_->root; \
+\
+ bool left_done = false; \
+\
+ size_t i = 0; \
+ while (root) \
+ { \
+ if (!left_done) \
+ { \
+ while (root->left) \
+ root = root->left; \
+ } \
+\
+ if (!_map_->f_key->str(fptr, root->key)) \
+ return false; \
+\
+ fprintf(fptr, "%s", key_val_sep); \
+\
+ if (!_map_->f_val->str(fptr, root->value)) \
+ return false; \
+\
+ if (++i < _map_->count) \
+ fprintf(fptr, "%s", separator); \
+\
+ left_done = true; \
+\
+ if (root->right) \
+ { \
+ left_done = false; \
+ root = root->right; \
+ } \
+ else if (root->parent) \
+ { \
+ while (root->parent && root == root->parent->right) \
+ root = root->parent; \
+\
+ if (!root->parent) \
+ break; \
+\
+ root = root->parent; \
+ } \
+ else \
+ break; \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_TREEMAP_H */
diff --git a/src/ext/cmc/treeset.h b/src/ext/cmc/treeset.h
new file mode 100644
index 0000000..674fef4
--- /dev/null
+++ b/src/ext/cmc/treeset.h
@@ -0,0 +1,649 @@
+/**
+ * ext/cmc/treeset.h
+ *
+ * Creation Date: 08/06/2020
+ *
+ * Authors:
+ * Leonardo Vencovsky (https://github.com/LeoVen)
+ *
+ */
+
+#ifndef CMC_EXT_CMC_TREESET_H
+#define CMC_EXT_CMC_TREESET_H
+
+#include "../../cor/core.h"
+
+/**
+ * All the EXT parts of CMC TreeSet.
+ */
+#define CMC_EXT_CMC_TREESET_PARTS ITER, SETF, STR
+
+/**
+ * ITER
+ */
+#define CMC_EXT_CMC_TREESET_ITER(PARAMS) \
+ CMC_EXT_CMC_TREESET_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_TREESET_ITER_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREESET_ITER_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREESET_ITER_SOURCE(PARAMS) \
+ CMC_EXT_CMC_TREESET_ITER_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREESET_ITER_HEADER_(PFX, SNAME, V) \
+\
+ /* Treeset Iterator */ \
+ struct CMC_DEF_ITER(SNAME) \
+ { \
+ /* Target treeset */ \
+ struct SNAME *target; \
+\
+ /* Cursor's current node */ \
+ struct CMC_DEF_NODE(SNAME) * cursor; \
+\
+ /* The first node in the iteration */ \
+ struct CMC_DEF_NODE(SNAME) * first; \
+\
+ /* The last node in the iteration */ \
+ struct CMC_DEF_NODE(SNAME) * last; \
+\
+ /* Keeps track of relative index to the iteration of elements */ \
+ size_t index; \
+\
+ /* 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);
+
+#define CMC_EXT_CMC_TREESET_ITER_SOURCE_(PFX, SNAME, V) \
+\
+ struct CMC_DEF_ITER(SNAME) CMC_(PFX, _iter_start)(struct SNAME * target) \
+ { \
+ struct CMC_DEF_ITER(SNAME) iter; \
+\
+ iter.target = target; \
+ iter.cursor = target->root; \
+ iter.first = NULL; \
+ iter.last = NULL; \
+ iter.index = 0; \
+ iter.start = true; \
+ iter.end = CMC_(PFX, _empty)(target); \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ while (iter.cursor->left != NULL) \
+ iter.cursor = iter.cursor->left; \
+\
+ iter.first = iter.cursor; \
+\
+ iter.last = target->root; \
+ while (iter.last->right != NULL) \
+ iter.last = iter.last->right; \
+ } \
+\
+ 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 = target->root; \
+ iter.first = NULL; \
+ iter.last = NULL; \
+ iter.index = 0; \
+ iter.start = CMC_(PFX, _empty)(target); \
+ iter.end = true; \
+\
+ if (!CMC_(PFX, _empty)(target)) \
+ { \
+ while (iter.cursor->right != NULL) \
+ iter.cursor = iter.cursor->right; \
+\
+ iter.last = iter.cursor; \
+\
+ iter.first = target->root; \
+ while (iter.first->left != NULL) \
+ iter.first = iter.first->left; \
+\
+ iter.index = 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->index = 0; \
+ iter->start = true; \
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+ iter->cursor = iter->first; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_to_end)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (!CMC_(PFX, _empty)(iter->target)) \
+ { \
+ iter->index = iter->target->count - 1; \
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+ iter->end = true; \
+ iter->cursor = iter->last; \
+\
+ return true; \
+ } \
+\
+ return false; \
+ } \
+\
+ bool CMC_(PFX, _iter_next)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->end) \
+ return false; \
+\
+ if (iter->cursor == iter->last) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ iter->start = CMC_(PFX, _empty)(iter->target); \
+\
+ if (iter->cursor->right != NULL) \
+ { \
+ iter->cursor = iter->cursor->right; \
+\
+ while (iter->cursor->left != NULL) \
+ iter->cursor = iter->cursor->left; \
+\
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ while (true) \
+ { \
+ if (iter->cursor->parent->left == iter->cursor) \
+ { \
+ iter->cursor = iter->cursor->parent; \
+\
+ iter->index++; \
+\
+ return true; \
+ } \
+\
+ iter->cursor = iter->cursor->parent; \
+ } \
+ } \
+\
+ bool CMC_(PFX, _iter_prev)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (iter->start) \
+ return false; \
+\
+ if (iter->cursor == iter->first) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ iter->end = CMC_(PFX, _empty)(iter->target); \
+\
+ if (iter->cursor->left != NULL) \
+ { \
+ iter->cursor = iter->cursor->left; \
+\
+ while (iter->cursor->right != NULL) \
+ iter->cursor = iter->cursor->right; \
+\
+ iter->index--; \
+\
+ return true; \
+ } \
+\
+ while (true) \
+ { \
+ if (iter->cursor->parent->right == iter->cursor) \
+ { \
+ iter->cursor = iter->cursor->parent; \
+\
+ iter->index--; \
+\
+ return true; \
+ } \
+\
+ iter->cursor = iter->cursor->parent; \
+ } \
+ } \
+\
+ /* 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 == iter->last) \
+ { \
+ iter->end = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index + steps >= iter->target->count) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_next)(iter); \
+\
+ 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 == iter->first) \
+ { \
+ iter->start = true; \
+ return false; \
+ } \
+\
+ if (steps == 0 || iter->index < steps) \
+ return false; \
+\
+ for (size_t i = 0; i < steps; i++) \
+ CMC_(PFX, _iter_prev)(iter); \
+\
+ 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->index > index) \
+ return CMC_(PFX, _iter_rewind)(iter, iter->index - index); \
+ else if (iter->index < index) \
+ return CMC_(PFX, _iter_advance)(iter, index - iter->index); \
+\
+ return true; \
+ } \
+\
+ V CMC_(PFX, _iter_value)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ if (CMC_(PFX, _empty)(iter->target)) \
+ return (V){ 0 }; \
+\
+ return iter->cursor->value; \
+ } \
+\
+ size_t CMC_(PFX, _iter_index)(struct CMC_DEF_ITER(SNAME) * iter) \
+ { \
+ return iter->index; \
+ }
+
+/**
+ * SETF
+ */
+#define CMC_EXT_CMC_TREESET_SETF(PARAMS) \
+ CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_TREESET_SETF_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREESET_SETF_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREESET_SETF_SOURCE(PARAMS) \
+ CMC_EXT_CMC_TREESET_SETF_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREESET_SETF_HEADER_(PFX, SNAME, V) \
+\
+ /* Set Operations */ \
+ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_); \
+ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_);
+
+#define CMC_EXT_CMC_TREESET_SETF_SOURCE_(PFX, SNAME, V) \
+\
+ struct SNAME *CMC_(PFX, _union)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter1)); \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ CMC_(PFX, _insert)(_set_r_, CMC_(PFX, _iter_value)(&iter2)); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _intersection)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ /** TODO Should this compare count or capacity? */ \
+ struct SNAME *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_; \
+ struct SNAME *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set_A_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set_B_, value) != NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _difference)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ struct SNAME *CMC_(PFX, _symmetric_difference)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ struct SNAME *_set_r_ = CMC_(PFX, _new_custom)(_set1_->f_val, _set1_->alloc, NULL); \
+\
+ if (!_set_r_) \
+ return NULL; \
+\
+ struct CMC_DEF_ITER(SNAME) iter1 = CMC_(PFX, _iter_start)(_set1_); \
+ struct CMC_DEF_ITER(SNAME) iter2 = CMC_(PFX, _iter_start)(_set2_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter1); CMC_(PFX, _iter_next)(&iter1)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter1); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter2); CMC_(PFX, _iter_next)(&iter2)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter2); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set1_, value) == NULL) \
+ CMC_(PFX, _insert)(_set_r_, value); \
+ } \
+\
+ CMC_CALLBACKS_ASSIGN(_set_r_, _set1_->callbacks); \
+\
+ return _set_r_; \
+ } \
+\
+ /* Is _set1_ a subset of _set2_ ? */ \
+ /* A set X is a subset of a set Y when: X <= Y */ \
+ /* If X is a subset of Y, then Y is a superset of X */ \
+ bool CMC_(PFX, _is_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* If the cardinality of _set1_ is greater than that of _set2_ */ \
+ /* then it is safe to say that _set1_ can't be a subset of _set2_ */ \
+ if (_set1_->count > _set2_->count) \
+ return false; \
+\
+ /* The empty set is a subset of all sets */ \
+ if (CMC_(PFX, _empty)(_set1_)) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ /* Is _set1_ a superset of _set2_ ? */ \
+ /* A set X is a superset of a set Y when: X >= Y */ \
+ /* If X is a superset of Y, then Y is a subset of X */ \
+ bool CMC_(PFX, _is_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ return CMC_(PFX, _is_subset)(_set2_, _set1_); \
+ } \
+\
+ /* Is _set1_ a proper subset of _set2_ ? */ \
+ /* A set X is a proper subset of a set Y when: X < Y */ \
+ /* If X is a proper subset of Y, then Y is a proper superset of X */ \
+ bool CMC_(PFX, _is_proper_subset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* If the cardinality of _set1_ is greater than or equal to that */ \
+ /* of _set2_, then it is safe to say that _set1_ can't be a proper */ \
+ /* subset of _set2_ */ \
+ if (_set1_->count >= _set2_->count) \
+ return false; \
+\
+ if (CMC_(PFX, _empty)(_set1_)) \
+ { \
+ /* The empty set is a proper subset of all non-empty sets */ \
+ if (!CMC_(PFX, _empty)(_set2_)) \
+ return true; \
+ /* The empty set is not a proper subset of itself (this is true */ \
+ /* for any set) */ \
+ else \
+ return false; \
+ } \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set2_, value) == NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ } \
+\
+ /* Is _set1_ a proper superset of _set2_ ? */ \
+ /* A set X is a proper superset of a set Y when: X > Y */ \
+ /* If X is a proper superset of Y, then Y is a proper subset of X */ \
+ bool CMC_(PFX, _is_proper_superset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ return CMC_(PFX, _is_proper_subset)(_set2_, _set1_); \
+ } \
+\
+ /* Is _set1_ a disjointset of _set2_ ? */ \
+ /* A set X is a disjointset of a set Y if their intersection is empty, */ \
+ /* that is, if there are no elements in common between the two */ \
+ bool CMC_(PFX, _is_disjointset)(struct SNAME * _set1_, struct SNAME * _set2_) \
+ { \
+ /* The intersection of an empty set with any other set will result */ \
+ /* in an empty set */ \
+ if (CMC_(PFX, _empty)(_set1_)) \
+ return true; \
+\
+ struct CMC_DEF_ITER(SNAME) iter = CMC_(PFX, _iter_start)(_set1_); \
+\
+ for (; !CMC_(PFX, _iter_at_end)(&iter); CMC_(PFX, _iter_next)(&iter)) \
+ { \
+ V value = CMC_(PFX, _iter_value)(&iter); \
+\
+ if (CMC_(PFX, _impl_get_node)(_set2_, value) != NULL) \
+ return false; \
+ } \
+\
+ return true; \
+ }
+
+
+/**
+ * STR
+ */
+#define CMC_EXT_CMC_TREESET_STR(PARAMS) \
+ CMC_EXT_CMC_TREESET_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREESET_STR_SOURCE(PARAMS)
+
+#define CMC_EXT_CMC_TREESET_STR_HEADER(PARAMS) \
+ CMC_EXT_CMC_TREESET_STR_HEADER_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREESET_STR_SOURCE(PARAMS) \
+ CMC_EXT_CMC_TREESET_STR_SOURCE_(CMC_PARAM_PFX(PARAMS), CMC_PARAM_SNAME(PARAMS), CMC_PARAM_V(PARAMS))
+
+#define CMC_EXT_CMC_TREESET_STR_HEADER_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr); \
+ bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \
+ const char *end);
+
+#define CMC_EXT_CMC_TREESET_STR_SOURCE_(PFX, SNAME, V) \
+\
+ bool CMC_(PFX, _to_string)(struct SNAME * _set_, FILE * fptr) \
+ { \
+ struct SNAME *s_ = _set_; \
+\
+ return 0 <= fprintf(fptr, \
+ "struct %s<%s> " \
+ "at %p { " \
+ "root:%p, " \
+ "count:%" PRIuMAX ", " \
+ "flag:%d, " \
+ "f_val:%p, " \
+ "alloc:%p, " \
+ "callbacks:%p }", \
+ CMC_TO_STRING(SNAME), CMC_TO_STRING(V), s_, s_->root, s_->count, s_->flag, s_->f_val, \
+ s_->alloc, CMC_CALLBACKS_GET(s_)); \
+ } \
+\
+ bool CMC_(PFX, _print)(struct SNAME * _set_, FILE * fptr, const char *start, const char *separator, \
+ const char *end) \
+ { \
+ fprintf(fptr, "%s", start); \
+\
+ struct CMC_DEF_NODE(SNAME) *root = _set_->root; \
+\
+ bool left_done = false; \
+\
+ size_t i = 0; \
+ while (root) \
+ { \
+ if (!left_done) \
+ { \
+ while (root->left) \
+ root = root->left; \
+ } \
+\
+ if (!_set_->f_val->str(fptr, root->value)) \
+ return false; \
+\
+ if (++i < _set_->count) \
+ fprintf(fptr, "%s", separator); \
+\
+ left_done = true; \
+\
+ if (root->right) \
+ { \
+ left_done = false; \
+ root = root->right; \
+ } \
+ else if (root->parent) \
+ { \
+ while (root->parent && root == root->parent->right) \
+ root = root->parent; \
+\
+ if (!root->parent) \
+ break; \
+\
+ root = root->parent; \
+ } \
+ else \
+ break; \
+ } \
+\
+ fprintf(fptr, "%s", end); \
+\
+ return true; \
+ }
+
+#endif /* CMC_EXT_CMC_TREESET_H */
diff --git a/src/macro_collections.h b/src/macro_collections.h
index 329d0b2..b6d91c4 100644
--- a/src/macro_collections.h
+++ b/src/macro_collections.h
@@ -8,55 +8,241 @@
*
*/
+/**
+ * This file provides everything from the C Macro Collections library.
+ *
+ * Every data structure and features are available through this header. There is
+ * also three macros that can help you generate whichever Collection you need
+ * from any given sub-library. They are:
+ *
+ * - C_MACRO_COLLECTIONS
+ * - C_MACRO_COLLECTIONS_GEN
+ * - C_MACRO_COLLECTIONS_GEN_HEADER
+ * - C_MACRO_COLLECTIONS_GEN_SOURCE
+ * - C_MACRO_COLLECTIONS_ALL
+ * - C_MACRO_COLLECTIONS_ALL_HEADER
+ * - C_MACRO_COLLECTIONS_ALL_SOURCE
+ */
#ifndef CMC_MACRO_COLLECTIONS_H
#define CMC_MACRO_COLLECTIONS_H
-#define CMC_CONCAT_(C, T) CMC_WRAPGEN_##C##_##T
+// clang-format off
+#include "cmc/bitset.h" /* Added in 30/04/2020 */
+#include "cmc/deque.h" /* Added in 20/03/2019 */
+#include "cmc/hashbidimap.h" /* Added in 26/09/2019 */
+#include "cmc/hashmap.h" /* Added in 03/04/2019 */
+#include "cmc/hashmultimap.h" /* Added in 26/04/2019 */
+#include "cmc/hashmultiset.h" /* Added in 10/04/2019 */
+#include "cmc/hashset.h" /* Added in 01/04/2019 */
+#include "cmc/heap.h" /* Added in 25/03/2019 */
+#include "cmc/intervalheap.h" /* Added in 06/07/2019 */
+#include "cmc/linkedlist.h" /* Added in 22/03/2019 */
+#include "cmc/list.h" /* Added in 12/02/2019 */
+#include "cmc/queue.h" /* Added in 15/02/2019 */
+#include "cmc/sortedlist.h" /* Added in 17/09/2019 */
+#include "cmc/stack.h" /* Added in 14/02/2019 */
+#include "cmc/treemap.h" /* Added in 28/03/2019 */
+#include "cmc/treeset.h" /* Added in 27/03/2019 */
-#define CMC_CONCAT(C, T) CMC_CONCAT_(C, T)
+#include "cor/alloc.h" /* Added in 24/05/2020 */
+#include "cor/bitset.h" /* Added in 20/05/2020 */
+#include "cor/callbacks.h" /* Added in 24/05/2020 */
+#include "cor/core.h" /* Added in 17/03/2020 */
+#include "cor/flags.h" /* Added in 14/05/2020 */
+#include "cor/ftable.h" /* Added in 27/05/2020 */
+#include "cor/hashtable.h" /* Added in 17/03/2020 */
+#include "cor/heap.h" /* Added in 01/06/2020 */
-#define CMC_COLLECTION_GENERATE(C, PFX, SNAME, K, V) \
- CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \
- CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V)
+#include "ext/cmc/bitset.h" /* Added in 08/06/2020 */
+#include "ext/cmc/deque.h" /* Added in 25/05/2020 */
+#include "ext/cmc/hashbidimap.h" /* Added in 26/05/2020 */
+#include "ext/cmc/hashmap.h" /* Added in 25/05/2020 */
+#include "ext/cmc/hashmultimap.h" /* Added in 29/05/2020 */
+#include "ext/cmc/hashmultiset.h" /* Added in 30/05/2020 */
+#include "ext/cmc/hashset.h" /* Added in 31/05/2020 */
+#include "ext/cmc/heap.h" /* Added in 01/06/2020 */
+#include "ext/cmc/intervalheap.h" /* Added in 02/06/2020 */
+#include "ext/cmc/linkedlist.h" /* Added in 03/06/2020 */
+#include "ext/cmc/list.h" /* Added in 04/06/2020 */
+#include "ext/cmc/queue.h" /* Added in 05/06/2020 */
+#include "ext/cmc/sortedlist.h" /* Added in 06/06/2020 */
+#include "ext/cmc/stack.h" /* Added in 07/06/2020 */
+#include "ext/cmc/treemap.h" /* Added in 08/06/2020 */
+#include "ext/cmc/treeset.h" /* Added in 08/06/2020 */
-#define CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \
- CMC_CONCAT(C, HEADER)(PFX, SNAME, K, V)
+#include "utl/assert.h" /* Added in 27/06/2019 */
+#include "utl/foreach.h" /* Added in 25/02/2019 */
+#include "utl/futils.h" /* Added in 15/04/2020 */
+#include "utl/log.h" /* Added in 21/06/2019 */
+#include "utl/mutex.h" /* Added in 14/05/2020 */
+#include "utl/test.h" /* Added in 26/06/2019 */
+#include "utl/thread.h" /* Added in 14/05/2020 */
+#include "utl/timer.h" /* Added in 12/04/2019 */
+// clang-format on
-#define CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V) \
- CMC_CONCAT(C, SOURCE)(PFX, SNAME, K, V)
+/**
+ * C_MACRO_COLLECTIONS
+ *
+ * Generate a specific part of a specific collection from a specific library.
+ *
+ * \param LIB The collection's sub-library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PART The part of the collection (either CORE or one available at EXT)
+ * \param FILE Either HEADER or SOURCE
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ */
+#define C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE)(PARAMS)
+#define C_MACRO_COLLECTIONS_(LIB, COLLECTION, PART, FILE) CMC_##LIB##_##COLLECTION##_##PART##_##FILE
-#include "cor/bitset.h" /* Added in 20/05/2020 */
-#include "cor/core.h" /* Added in 17/03/2020 */
-#include "cor/flags.h" /* Added in 14/05/2020 */
-#include "cor/hashtable.h" /* Added in 17/03/2020 */
+/**
+ * C_MACRO_COLLECTIONS_GEN
+ *
+ * Generate the CORE of a collection along with one or more part from EXT. The
+ * headers are generated first, then the source code.
+ *
+ * \param LIB The collection's sub-library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ * \param PARTS A non-empty tuple of all desired EXT parts
+ */
+#define C_MACRO_COLLECTIONS_GEN(LIB, COLLECTION, PARAMS, PARTS) \
+ C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \
+ C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS)
-#include "cmc/bitset.h" /* Added in 30/04/2020 */
-#include "cmc/deque.h" /* Added in 20/03/2019 */
-#include "cmc/hashbidimap.h" /* Added in 26/09/2019 */
-#include "cmc/hashmap.h" /* Added in 03/04/2019 */
-#include "cmc/hashmultimap.h" /* Added in 26/04/2019 */
-#include "cmc/hashmultiset.h" /* Added in 10/04/2019 */
-#include "cmc/hashset.h" /* Added in 01/04/2019 */
-#include "cmc/heap.h" /* Added in 25/03/2019 */
-#include "cmc/intervalheap.h" /* Added in 06/07/2019 */
-#include "cmc/linkedlist.h" /* Added in 22/03/2019 */
-#include "cmc/list.h" /* Added in 12/02/2019 */
-#include "cmc/queue.h" /* Added in 15/02/2019 */
-#include "cmc/sortedlist.h" /* Added in 17/09/2019 */
-#include "cmc/stack.h" /* Added in 14/02/2019 */
-#include "cmc/treemap.h" /* Added in 28/03/2019 */
-#include "cmc/treeset.h" /* Added in 27/03/2019 */
+/**
+ * C_MACRO_COLLECTIONS_GEN_HEADER
+ *
+ * Generate all headers of CORE and the specified header parts of a collection.
+ *
+ * \param LIB The collection's sub-library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ * \param PARTS A non-empty tuple of all desired EXT parts
+ */
+#define C_MACRO_COLLECTIONS_GEN_HEADER(LIB, COLLECTION, PARAMS, PARTS) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, HEADER, PARAMS) \
+ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, CMC_EVAL PARTS)
-#include "sac/queue.h"
-#include "sac/stack.h"
+/**
+ * C_MACRO_COLLECTIONS_GEN_SOURCE
+ *
+ * Generate all sources of CORE and the specified source parts of a collection.
+ *
+ * \param LIB The collection's sub-library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V)
+ * \param PARTS A non-empty tuple of all desired EXT parts
+ */
+#define C_MACRO_COLLECTIONS_GEN_SOURCE(LIB, COLLECTION, PARAMS, PARTS) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, SOURCE, PARAMS) \
+ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, CMC_EVAL PARTS)
-#include "utl/assert.h" /* Added in 27/06/2019 */
-#include "utl/foreach.h" /* Added in 25/02/2019 */
-#include "utl/futils.h" /* Added in 15/04/2020 */
-#include "utl/log.h" /* Added in 21/06/2019 */
-#include "utl/mutex.h" /* Added in 14/05/2020 */
-#include "utl/test.h" /* Added in 26/06/2019 */
-#include "utl/thread.h" /* Added in 14/05/2020 */
-#include "utl/timer.h" /* Added in 12/04/2019 */
+/**
+ * C_MACRO_COLLECTIONS_ALL
+ *
+ * Generate everything provided by a collection included in the EXT library. The
+ * headers are generated first, then the source code.
+ *
+ * \param LIB The collection's library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
+ */
+#define C_MACRO_COLLECTIONS_ALL(LIB, COLLECTION, PARAMS) \
+ C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \
+ C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS)
+
+/**
+ * C_MACRO_COLLECTIONS_ALL_HEADER
+ *
+ * Generates all headers (CORE and those at EXT) from a given collection.
+ *
+ * \param LIB The collection's library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
+ */
+#define C_MACRO_COLLECTIONS_ALL_HEADER(LIB, COLLECTION, PARAMS) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, HEADER, PARAMS) \
+ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, HEADER, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
+
+/**
+ * C_MACRO_COLLECTIONS_ALL_SOURCE
+ *
+ * Generates all sources (CORE and those at EXT) from a given collection.
+ *
+ * \param LIB The collection's library
+ * \param COLLECTION The name of the collection in all uppercase
+ * \param PARAMS A tuple of form (PFX, SNAME, SIZE, K, V
+ */
+#define C_MACRO_COLLECTIONS_ALL_SOURCE(LIB, COLLECTION, PARAMS) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, CORE_PUBLIC, SOURCE, PARAMS) \
+ CMC_MAP(CMC_(EXT_, LIB), COLLECTION, SOURCE, PARAMS, C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION))
+
+/**
+ * C_MACRO_COLLECTIONS_PARTS
+ *
+ * Gets the macro with all EXT parts of a collection. Every collection has this
+ * macro defined in the EXT libraries.
+ */
+#define C_MACRO_COLLECTIONS_PARTS(LIB, COLLECTION) CMC_EXT_##LIB##_##COLLECTION##_PARTS,
+
+/* Evaluates a tuple so that (A, B) -> A, B, */
+#define CMC_EVAL(...) __VA_ARGS__,
+
+/**
+ * A __VA_ARGS__ argument counter. This argument counter is slightly shifted:
+ *
+ * CMC_NARG(HELLO) -> 0
+ * CMC_NARG(HELLO,) -> 1
+ * CMC_NARG(HELLO, WORLD,) -> 2
+ */
+#define CMC_NARG(...) CMC_NARG_(__VA_ARGS__, CMC_SEQ_N())
+#define CMC_NARG_(...) CMC_ARG_N(__VA_ARGS__)
+#define CMC_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \
+ _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, \
+ _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, \
+ _62, _63, N, ...) \
+ N
+#define CMC_SEQ_N() \
+ 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, \
+ 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, \
+ 7, 6, 5, 4, 3, 2, 1, 0
+
+/* Generates the FILE for each part (__VA_ARGS__) of a collection */
+#define CMC_MAP(LIB, COLLECTION, FILE, PARAMS, ...) \
+ CMC_(CMC_MAP_, CMC_NARG(__VA_ARGS__)) \
+ (LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+
+#define CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, PART, ...)
+#define CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_0(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_1(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_2(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_3(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_4(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_5(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_6(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_7(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_8(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
+#define CMC_MAP_10(LIB, COLLECTION, FILE, PARAMS, PART, ...) \
+ C_MACRO_COLLECTIONS(LIB, COLLECTION, PART, FILE, PARAMS) \
+ CMC_MAP_9(LIB, COLLECTION, FILE, PARAMS, __VA_ARGS__)
#endif /* CMC_MACRO_COLLECTIONS_H */
diff --git a/src/sac/queue.h b/src/sac/queue.h
deleted file mode 100644
index 7567cb7..0000000
--- a/src/sac/queue.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/**
- * queue.h
- *
- * Creation Date: 24/06/2019
- *
- * Authors:
- * Leonardo Vencovsky (https://github.com/LeoVen)
- *
- */
-
-/**
- * A Purely Stack Allocated Queue
- *
- * This means that the Queue has a fixed size, but it also has the advantage of
- * not requiring for manually allocating and deallocating the struct.
- *
- * Generating a collection with too big of a storage can be dangerous and might
- * quickly cause a stack overflow.
- *
- * It is recommended to not generate any Stack Allocated Collection with less
- * than 1000 internal storage.
- */
-
-#ifndef CMC_SAC_QUEUE_H
-#define CMC_SAC_QUEUE_H
-
-#include
-#include
-#include
-
-#define SAC_QUEUE_GENERATE(PFX, SNAME, FMOD, V, SIZE) \
- SAC_QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \
- SAC_QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE)
-
-#define SAC_QUEUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V, SIZE) \
- SAC_QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE)
-
-#define SAC_QUEUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V, SIZE) \
- SAC_QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE)
-
-/* HEADER ********************************************************************/
-#define SAC_QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \
- \
- /* Queue Structure */ \
- typedef struct SNAME##_s \
- { \
- /* Internal Storage */ \
- V buffer[SIZE]; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Index representing the front of the queue */ \
- size_t front; \
- \
- /* Index representing the back of the queue */ \
- size_t rear; \
- \
- /* Function that returns an iterator to the start of the queue */ \
- struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
- \
- /* Function that returns an iterator to the end of the queue */ \
- struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
- \
- } SNAME, *SNAME##_ptr; \
- \
- /* Queue Iterator */ \
- typedef struct SNAME##_iter_s \
- { \
- /* Target queue */ \
- struct SNAME##_s *target; \
- \
- /* Cursor's position (index) */ \
- size_t cursor; \
- \
- /* Keeps track of relative index to the iteration of elements */ \
- size_t index; \
- \
- /* If the iterator has reached the start of the iteration */ \
- bool start; \
- \
- /* If the iterator has reached the end of the iteration */ \
- bool end; \
- \
- } SNAME##_iter, *SNAME##_iter_ptr; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- FMOD SNAME PFX##_new(void); \
- FMOD void PFX##_clear(SNAME *_queue_); \
- /* Collection Input and Output */ \
- FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \
- FMOD bool PFX##_dequeue(SNAME *_queue_); \
- /* Conditional Input and Output */ \
- FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \
- FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \
- /* Element Access */ \
- FMOD V PFX##_peek(SNAME *_queue_); \
- /* Collection State */ \
- FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)); \
- FMOD bool PFX##_empty(SNAME *_queue_); \
- FMOD bool PFX##_full(SNAME *_queue_); \
- FMOD size_t PFX##_count(SNAME *_queue_); \
- FMOD size_t PFX##_capacity(void); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
- /* Iterator State */ \
- FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
- /* Iterator Movement */ \
- FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
- FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
- /* Iterator Access */ \
- FMOD V PFX##_iter_value(SNAME##_iter *iter); \
- FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
- FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
- \
- /* Default Value */ \
- static inline V PFX##_impl_default_value(void) \
- { \
- V _empty_value_; \
- \
- memset(&_empty_value_, 0, sizeof(V)); \
- \
- return _empty_value_; \
- } \
- \
-/* SOURCE ********************************************************************/
-#define SAC_QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) \
- \
- /* Implementation Detail Functions */ \
- static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
- static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
- \
- FMOD SNAME PFX##_new(void) \
- { \
- SNAME result; \
- \
- memset(&result, 0, sizeof(SNAME)); \
- \
- result.it_start = PFX##_impl_it_start; \
- result.it_end = PFX##_impl_it_end; \
- \
- return result; \
- } \
- \
- FMOD void PFX##_clear(SNAME *_queue_) \
- { \
- memset(_queue_->buffer, 0, sizeof(_queue_->buffer)); \
- \
- _queue_->count = 0; \
- _queue_->front = 0; \
- _queue_->rear = 0; \
- } \
- \
- FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
- { \
- if (PFX##_full(_queue_)) \
- return false; \
- \
- _queue_->buffer[_queue_->rear] = element; \
- \
- _queue_->rear = (_queue_->rear == SIZE - 1) ? 0 : _queue_->rear + 1; \
- _queue_->count++; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_dequeue(SNAME *_queue_) \
- { \
- if (PFX##_empty(_queue_)) \
- return false; \
- \
- _queue_->buffer[_queue_->front] = PFX##_impl_default_value(); \
- \
- _queue_->front = (_queue_->front == SIZE - 1) ? 0 : _queue_->front + 1; \
- _queue_->count--; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
- { \
- if (condition) \
- return PFX##_enqueue(_queue_, element); \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
- { \
- if (condition) \
- return PFX##_dequeue(_queue_); \
- \
- return false; \
- } \
- \
- FMOD V PFX##_peek(SNAME *_queue_) \
- { \
- if (PFX##_empty(_queue_)) \
- return PFX##_impl_default_value(); \
- \
- return _queue_->buffer[_queue_->front]; \
- } \
- \
- FMOD bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)) \
- { \
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->count, j++) \
- { \
- if (comparator(_queue_->buffer[i], element) == 0) \
- return true; \
- } \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_empty(SNAME *_queue_) \
- { \
- return _queue_->count == 0; \
- } \
- \
- FMOD bool PFX##_full(SNAME *_queue_) \
- { \
- return _queue_->count >= SIZE; \
- } \
- \
- FMOD size_t PFX##_count(SNAME *_queue_) \
- { \
- return _queue_->count; \
- } \
- \
- FMOD size_t PFX##_capacity(void) \
- { \
- return SIZE; \
- } \
- \
- FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
- { \
- iter->target = target; \
- iter->cursor = target->front; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(target); \
- } \
- \
- FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
- { \
- iter->cursor = iter->target->front; \
- iter->index = 0; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- } \
- \
- FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- iter->cursor = 0; \
- else \
- iter->cursor = (iter->target->rear == 0) ? SIZE - 1 : iter->target->rear - 1; \
- \
- iter->index = iter->target->count - 1; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- } \
- \
- FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- if (iter->index == iter->target->count - 1) \
- iter->end = true; \
- else \
- { \
- iter->cursor = (iter->cursor + 1) % (SIZE); \
- iter->index++; \
- } \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- if (iter->index == 0) \
- iter->start = true; \
- else \
- { \
- iter->cursor = (iter->cursor == 0) ? SIZE - 1 : iter->cursor - 1; \
- iter->index--; \
- } \
- \
- return true; \
- } \
- \
- FMOD V PFX##_iter_value(SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return PFX##_impl_default_value(); \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
- { \
- return iter->index; \
- } \
- \
- static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_) \
- { \
- SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _queue_); \
- PFX##_iter_to_start(&iter); \
- \
- return iter; \
- } \
- \
- static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_) \
- { \
- SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _queue_); \
- PFX##_iter_to_end(&iter); \
- \
- return iter; \
- }
-
-#endif /* CMC_SAC_QUEUE_H */
diff --git a/src/sac/stack.h b/src/sac/stack.h
deleted file mode 100644
index 5567e6c..0000000
--- a/src/sac/stack.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/**
- * stack.h
- *
- * Creation Date: 21/06/2019
- *
- * Authors:
- * Leonardo Vencovsky (https://github.com/LeoVen)
- *
- */
-
-/**
- * A Purely Stack Allocated Stack
- *
- * This means that the Stack has a fixed size, but it also has the advantage of
- * not requiring for manually allocating and deallocating the struct.
- *
- * Generating a collection with too big of a storage can be dangerous and might
- * quickly cause a stack overflow.
- *
- * It is recommended to not generate any Stack Allocated Collection with less
- * than 1000 internal storage.
- */
-
-#ifndef CMC_SAC_STACK_H
-#define CMC_SAC_STACK_H
-
-#include
-#include
-#include
-
-#define SAC_STACK_GENERATE(PFX, SNAME, FMOD, V, SIZE) \
- SAC_STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \
- SAC_STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE)
-
-#define SAC_STACK_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V, SIZE) \
- SAC_STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE)
-
-#define SAC_STACK_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V, SIZE) \
- SAC_STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE)
-
-/* HEADER ********************************************************************/
-#define SAC_STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V, SIZE) \
- \
- /* Stack Structure */ \
- typedef struct SNAME##_s \
- { \
- /* Internal Storage */ \
- V buffer[SIZE]; \
- \
- /* Current amount of elements */ \
- size_t count; \
- \
- /* Function that returns an iterator to the start of the stack */ \
- struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
- \
- /* Function that returns an iterator to the end of the stack */ \
- struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
- \
- } SNAME, *SNAME##_ptr; \
- \
- /* Stack Iterator */ \
- typedef struct SNAME##_iter_s \
- { \
- /* Target stack */ \
- struct SNAME##_s *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; \
- \
- } SNAME##_iter, *SNAME##_iter_ptr; \
- \
- /* Collection Functions */ \
- /* Collection Allocation and Deallocation */ \
- FMOD SNAME PFX##_new(void); \
- FMOD void PFX##_clear(SNAME *_stack_); \
- /* Collection Input and Output */ \
- FMOD bool PFX##_push(SNAME *_stack_, V element); \
- FMOD bool PFX##_pop(SNAME *_stack_); \
- /* Conditional Input and Output */ \
- FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \
- FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition); \
- /* Element Access */ \
- FMOD V PFX##_top(SNAME *_stack_); \
- /* Collection State */ \
- FMOD bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)); \
- FMOD bool PFX##_empty(SNAME *_stack_); \
- FMOD bool PFX##_full(SNAME *_stack_); \
- FMOD size_t PFX##_count(SNAME *_stack_); \
- FMOD size_t PFX##_capacity(void); \
- \
- /* Iterator Functions */ \
- /* Iterator Initialization */ \
- FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
- /* Iterator State */ \
- FMOD bool PFX##_iter_start(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_end(SNAME##_iter *iter); \
- /* Iterator Movement */ \
- FMOD void PFX##_iter_to_start(SNAME##_iter *iter); \
- FMOD void PFX##_iter_to_end(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_next(SNAME##_iter *iter); \
- FMOD bool PFX##_iter_prev(SNAME##_iter *iter); \
- /* Iterator Access */ \
- FMOD V PFX##_iter_value(SNAME##_iter *iter); \
- FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter); \
- FMOD size_t PFX##_iter_index(SNAME##_iter *iter); \
- \
- /* Default Value */ \
- static inline V PFX##_impl_default_value(void) \
- { \
- V _empty_value_; \
- \
- memset(&_empty_value_, 0, sizeof(V)); \
- \
- return _empty_value_; \
- } \
- \
-/* SOURCE ********************************************************************/
-#define SAC_STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V, SIZE) \
- \
- /* Implementation Detail Functions */ \
- static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \
- static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \
- \
- FMOD SNAME PFX##_new(void) \
- { \
- SNAME result; \
- \
- memset(&result, 0, sizeof(SNAME)); \
- \
- result.it_start = PFX##_impl_it_start; \
- result.it_end = PFX##_impl_it_end; \
- \
- return result; \
- } \
- \
- FMOD void PFX##_clear(SNAME *_stack_) \
- { \
- memset(_stack_->buffer, 0, sizeof(_stack_->buffer)); \
- \
- _stack_->count = 0; \
- } \
- \
- FMOD bool PFX##_push(SNAME *_stack_, V element) \
- { \
- if (PFX##_full(_stack_)) \
- return false; \
- \
- _stack_->buffer[_stack_->count++] = element; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_pop(SNAME *_stack_) \
- { \
- if (PFX##_empty(_stack_)) \
- return false; \
- \
- _stack_->buffer[--_stack_->count] = PFX##_impl_default_value(); \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_push_if(SNAME *_stack_, V element, bool condition) \
- { \
- if (condition) \
- return PFX##_push(_stack_, element); \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_pop_if(SNAME *_stack_, bool condition) \
- { \
- if (condition) \
- return PFX##_pop(_stack_); \
- \
- return false; \
- } \
- \
- FMOD V PFX##_top(SNAME *_stack_) \
- { \
- if (PFX##_empty(_stack_)) \
- return PFX##_impl_default_value(); \
- \
- return _stack_->buffer[_stack_->count - 1]; \
- } \
- \
- FMOD bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)) \
- { \
- for (size_t i = 0; i < _stack_->count; i++) \
- { \
- if (comparator(_stack_->buffer[i], element) == 0) \
- return true; \
- } \
- \
- return false; \
- } \
- \
- FMOD bool PFX##_empty(SNAME *_stack_) \
- { \
- return _stack_->count == 0; \
- } \
- \
- FMOD bool PFX##_full(SNAME *_stack_) \
- { \
- return _stack_->count >= SIZE; \
- } \
- \
- FMOD size_t PFX##_count(SNAME *_stack_) \
- { \
- return _stack_->count; \
- } \
- \
- FMOD size_t PFX##_capacity(void) \
- { \
- return SIZE; \
- } \
- \
- FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
- { \
- iter->target = target; \
- iter->cursor = iter->target->count - 1; \
- iter->start = true; \
- iter->end = PFX##_empty(target); \
- } \
- \
- FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->start; \
- } \
- \
- FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
- { \
- return PFX##_empty(iter->target) || iter->end; \
- } \
- \
- FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
- { \
- iter->cursor = iter->target->count - 1; \
- iter->start = true; \
- iter->end = PFX##_empty(iter->target); \
- } \
- \
- FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
- { \
- iter->cursor = 0; \
- iter->start = PFX##_empty(iter->target); \
- iter->end = true; \
- } \
- \
- FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
- { \
- if (iter->end) \
- return false; \
- \
- iter->start = PFX##_empty(iter->target); \
- \
- if (iter->cursor == 0) \
- iter->end = true; \
- else \
- iter->cursor--; \
- \
- return true; \
- } \
- \
- FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
- { \
- if (iter->start) \
- return false; \
- \
- iter->end = PFX##_empty(iter->target); \
- \
- if (iter->cursor == iter->target->count - 1) \
- iter->start = true; \
- else \
- iter->cursor++; \
- \
- return true; \
- } \
- \
- FMOD V PFX##_iter_value(SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return PFX##_impl_default_value(); \
- \
- return iter->target->buffer[iter->cursor]; \
- } \
- \
- FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
- { \
- if (PFX##_empty(iter->target)) \
- return NULL; \
- \
- return &(iter->target->buffer[iter->cursor]); \
- } \
- \
- FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
- { \
- return iter->target->count - 1 - iter->cursor; \
- } \
- \
- static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_) \
- { \
- SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _stack_); \
- PFX##_iter_to_start(&iter); \
- \
- return iter; \
- } \
- \
- static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_) \
- { \
- SNAME##_iter iter; \
- \
- PFX##_iter_init(&iter, _stack_); \
- PFX##_iter_to_end(&iter); \
- \
- return iter; \
- }
-
-#endif /* CMC_SAC_STACK_H */
diff --git a/src/utl/assert.h b/src/utl/assert.h
index 9b0f001..110acb6 100644
--- a/src/utl/assert.h
+++ b/src/utl/assert.h
@@ -1,5 +1,5 @@
/**
- * assert.h
+ * utl/assert.h
*
* Creation Date: 27/06/2019
*
@@ -48,14 +48,16 @@
* - cmc_assert_array_sorted_any
*/
-#ifndef CMC_ASSERT_H
-#define CMC_ASSERT_H
+#ifndef CMC_UTL_ASSERT_H
+#define CMC_UTL_ASSERT_H
#include
#include
#include
#include
+#include "../cor/core.h"
+
#define CMC_ASSERT_GLUE_(dtype, assertion) cmc_assert_##assertion##_##dtype
#define CMC_ASSERT_GLUE(dtype, assertion) CMC_ASSERT_GLUE_(dtype, assertion)
@@ -68,38 +70,37 @@
* This variable is also used in test.h utility to automatically pass or fail a
* unit test. Once the unit test finishes, this variable is set back to true.
*/
-static bool cmc_assert_state = true;
+CMC_UNUSED static bool cmc_assert_state = true;
/**
* cmc_assert_total
*
* Tracks the total calls to any type of assertion.
*/
-static uintmax_t cmc_assert_total = 0;
+CMC_UNUSED static uintmax_t cmc_assert_total = 0;
/**
* cmc_assert_failed
*
* Tracks the total failed assertions.
*/
-static uintmax_t cmc_assert_failed = 0;
+CMC_UNUSED static uintmax_t cmc_assert_failed = 0;
/**
* expression : An expression that is expected to be evaluated to true.
*/
-#define cmc_assert(expression) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #expression; \
- if (!(expression)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }\n", \
- __FILE__, __func__, __LINE__, str); \
- } \
+#define cmc_assert(expression) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #expression; \
+ if (!(expression)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }\n", __FILE__, __func__, __LINE__, str); \
+ } \
} while (0)
/**
@@ -108,7 +109,7 @@ static uintmax_t cmc_assert_failed = 0;
* actual : Actual value tested against 'expected'.
*/
#define cmc_assert_equals(dtype, expected, actual) \
- CMC_ASSERT_GLUE(dtype, equals) \
+ CMC_ASSERT_GLUE(dtype, equals) \
(expected, actual)
/**
@@ -117,7 +118,7 @@ static uintmax_t cmc_assert_failed = 0;
* actual : Actual value tested against 'not_expected'.
*/
#define cmc_assert_not_equals(dtype, not_expected, actual) \
- CMC_ASSERT_GLUE(dtype, not_equals) \
+ CMC_ASSERT_GLUE(dtype, not_equals) \
(not_expected, actual)
/**
@@ -126,7 +127,7 @@ static uintmax_t cmc_assert_failed = 0;
* actual : Actual value tested against the given boundary.
*/
#define cmc_assert_greater(dtype, boundary, actual) \
- CMC_ASSERT_GLUE(dtype, greater) \
+ CMC_ASSERT_GLUE(dtype, greater) \
(boundary, actual)
/**
@@ -135,7 +136,7 @@ static uintmax_t cmc_assert_failed = 0;
* actual : Actual value tested against the given boundary.
*/
#define cmc_assert_greater_equals(dtype, boundary, actual) \
- CMC_ASSERT_GLUE(dtype, greater_equals) \
+ CMC_ASSERT_GLUE(dtype, greater_equals) \
(boundary, actual)
/**
@@ -144,7 +145,7 @@ static uintmax_t cmc_assert_failed = 0;
* actual : Actual value tested against the given boundary.
*/
#define cmc_assert_lesser(dtype, boundary, actual) \
- CMC_ASSERT_GLUE(dtype, lesser) \
+ CMC_ASSERT_GLUE(dtype, lesser) \
(boundary, actual)
/**
@@ -153,7 +154,7 @@ static uintmax_t cmc_assert_failed = 0;
* actual : Actual value tested against the given boundary.
*/
#define cmc_assert_lesser_equals(dtype, boundary, actual) \
- CMC_ASSERT_GLUE(dtype, lesser_equals) \
+ CMC_ASSERT_GLUE(dtype, lesser_equals) \
(boundary, actual)
/**
@@ -165,7 +166,7 @@ static uintmax_t cmc_assert_failed = 0;
* Range is inclusive on both ends.
*/
#define cmc_assert_in_range(dtype, lower_bound, upper_bound, actual) \
- CMC_ASSERT_GLUE(dtype, in_range) \
+ CMC_ASSERT_GLUE(dtype, in_range) \
(lower_bound, upper_bound, actual)
/**
@@ -177,7 +178,7 @@ static uintmax_t cmc_assert_failed = 0;
* Range is inclusive on both ends.
*/
#define cmc_assert_not_in_range(dtype, lower_bound, upper_bound, actual) \
- CMC_ASSERT_GLUE(dtype, not_in_range) \
+ CMC_ASSERT_GLUE(dtype, not_in_range) \
(lower_bound, upper_bound, actual)
/** ---------------------------------------------------------------------------
@@ -200,36 +201,35 @@ static uintmax_t cmc_assert_failed = 0;
*
* This macro can be used for any data type. Both bounds are inclusive.
*/
-#define cmc_assert_array_equals_any(dtype, array1, array2, comparator, \
- from_index, to_index) \
- do \
- { \
- cmc_assert_total++; \
- const char *str1__ = #array1; \
- const char *str2__ = #array2; \
- dtype *arr1__ = array1; \
- dtype *arr2__ = array2; \
- size_t from__ = from_index; \
- size_t to__ = to_index; \
- int (*cmp__)(dtype, dtype) = comparator; \
- \
- for (size_t i__ = from__; i__ <= to__; i__++) \
- { \
- if (cmp__(arr1__[i__], arr2__[i__]) != 0) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
+#define cmc_assert_array_equals_any(dtype, array1, array2, comparator, from_index, to_index) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str1__ = #array1; \
+ const char *str2__ = #array2; \
+ dtype *arr1__ = array1; \
+ dtype *arr2__ = array2; \
+ size_t from__ = from_index; \
+ size_t to__ = to_index; \
+ int (*cmp__)(dtype, dtype) = comparator; \
+\
+ for (size_t i__ = from__; i__ <= to__; i__++) \
+ { \
+ if (cmp__(arr1__[i__], arr2__[i__]) != 0) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf( \
+ stderr, \
"Assertion Failed at %s:%s:%u for { %s and %s }: Arrays values are not equal at index %" PRIuMAX \
- "\n", \
- __FILE__, __func__, __LINE__, str1__, str2__, i__); \
- \
- break; \
- } \
- } \
- \
+ "\n", \
+ __FILE__, __func__, __LINE__, str1__, str2__, i__); \
+\
+ break; \
+ } \
+ } \
+\
} while (0)
/**
@@ -247,37 +247,34 @@ static uintmax_t cmc_assert_failed = 0;
*
* This macro can be used for any data type. Both bounds are inclusive.
*/
-#define cmc_assert_array_within_any(dtype, array, comparator, lower_bound, \
- upper_bound, from_index, to_index) \
- do \
- { \
- cmc_assert_total++; \
- const char *str__ = #array; \
- dtype *arr__ = array; \
- dtype lower_bound___ = lower_bound; \
- dtype upper_bound___ = upper_bound; \
- size_t from__ = from_index; \
- size_t to__ = to_index; \
- int (*cmp__)(dtype, dtype) = comparator; \
- \
- for (size_t i__ = from__; i__ <= to__; i__++) \
- { \
- if (cmp__(arr__[i__], lower_bound___) < 0 || \
- cmp__(arr__[i__], upper_bound___) > 0) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Array value not within bounds at index %" PRIuMAX \
- "\n", \
- __FILE__, __func__, __LINE__, str__, i__); \
- \
- break; \
- } \
- } \
- \
+#define cmc_assert_array_within_any(dtype, array, comparator, lower_bound, upper_bound, from_index, to_index) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str__ = #array; \
+ dtype *arr__ = array; \
+ dtype lower_bound___ = lower_bound; \
+ dtype upper_bound___ = upper_bound; \
+ size_t from__ = from_index; \
+ size_t to__ = to_index; \
+ int (*cmp__)(dtype, dtype) = comparator; \
+\
+ for (size_t i__ = from__; i__ <= to__; i__++) \
+ { \
+ if (cmp__(arr__[i__], lower_bound___) < 0 || cmp__(arr__[i__], upper_bound___) > 0) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Array value not within bounds at index %" PRIuMAX \
+ "\n", \
+ __FILE__, __func__, __LINE__, str__, i__); \
+\
+ break; \
+ } \
+ } \
+\
} while (0)
/**
@@ -295,37 +292,34 @@ static uintmax_t cmc_assert_failed = 0;
*
* This macro can be used for any data type. Both bounds are inclusive.
*/
-#define cmc_assert_array_outside_any(dtype, array, comparator, lower_bound, \
- upper_bound, from_index, to_index) \
- do \
- { \
- cmc_assert_total++; \
- const char *str__ = #array; \
- dtype *arr__ = array; \
- dtype lower_bound___ = lower_bound; \
- dtype upper_bound___ = upper_bound; \
- size_t from__ = from_index; \
- size_t to__ = to_index; \
- int (*cmp__)(dtype, dtype) = comparator; \
- \
- for (size_t i__ = from__; i__ <= to__; i__++) \
- { \
- if (cmp__(arr__[i__], lower_bound___) >= 0 && \
- cmp__(arr__[i__], upper_bound___) <= 0) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Array value not outside bounds at index %" PRIuMAX \
- "\n", \
- __FILE__, __func__, __LINE__, str__, i__); \
- \
- break; \
- } \
- } \
- \
+#define cmc_assert_array_outside_any(dtype, array, comparator, lower_bound, upper_bound, from_index, to_index) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str__ = #array; \
+ dtype *arr__ = array; \
+ dtype lower_bound___ = lower_bound; \
+ dtype upper_bound___ = upper_bound; \
+ size_t from__ = from_index; \
+ size_t to__ = to_index; \
+ int (*cmp__)(dtype, dtype) = comparator; \
+\
+ for (size_t i__ = from__; i__ <= to__; i__++) \
+ { \
+ if (cmp__(arr__[i__], lower_bound___) >= 0 && cmp__(arr__[i__], upper_bound___) <= 0) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Array value not outside bounds at index %" PRIuMAX \
+ "\n", \
+ __FILE__, __func__, __LINE__, str__, i__); \
+\
+ break; \
+ } \
+ } \
+\
} while (0)
/**
@@ -341,38 +335,36 @@ static uintmax_t cmc_assert_failed = 0;
*
* This macro can be used for any data type.
*/
-#define cmc_assert_array_sorted_any(dtype, array, comparator, from_index, \
- to_index) \
- do \
- { \
- cmc_assert_total++; \
- const char *str__ = #array; \
- dtype *arr__ = array; \
- size_t from__ = from_index; \
- size_t to__ = to_index; \
- int (*cmp__)(dtype, dtype) = comparator; \
- \
- size_t iprev__ = from__; \
- \
- for (size_t i__ = from__ + 1; i__ <= to__; i__++) \
- { \
- if (cmp__(arr__[iprev__], arr__[i__]) > 0) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not sorted when comparing indexes %" PRIuMAX \
- " and %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str__, iprev__, i__); \
- \
- break; \
- } \
- \
- iprev__ = i__; \
- } \
- \
+#define cmc_assert_array_sorted_any(dtype, array, comparator, from_index, to_index) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str__ = #array; \
+ dtype *arr__ = array; \
+ size_t from__ = from_index; \
+ size_t to__ = to_index; \
+ int (*cmp__)(dtype, dtype) = comparator; \
+\
+ size_t iprev__ = from__; \
+\
+ for (size_t i__ = from__ + 1; i__ <= to__; i__++) \
+ { \
+ if (cmp__(arr__[iprev__], arr__[i__]) > 0) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not sorted when comparing indexes %" PRIuMAX \
+ " and %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str__, iprev__, i__); \
+\
+ break; \
+ } \
+\
+ iprev__ = i__; \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -381,330 +373,289 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_equals_int8_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t expected__ = (expected); \
- int8_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId8 \
- " Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_int8_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t expected__ = (expected); \
+ int8_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId8 " Actual: %" PRId8 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_int16_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t expected__ = (expected); \
- int16_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId16 \
- " Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_int16_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t expected__ = (expected); \
+ int16_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId16 " Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_int32_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t expected__ = (expected); \
- int32_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId32 \
- " Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_int32_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t expected__ = (expected); \
+ int32_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId32 " Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_int64_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t expected__ = (expected); \
- int64_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId64 \
- " Actual: %" PRId64 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_int64_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t expected__ = (expected); \
+ int64_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId64 " Actual: %" PRId64 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_uint8_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t expected__ = (expected); \
- uint8_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu8 \
- " Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_uint8_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t expected__ = (expected); \
+ uint8_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu8 " Actual: %" PRIu8 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_uint16_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t expected__ = (expected); \
- uint16_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu16 \
- " Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_uint16_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t expected__ = (expected); \
+ uint16_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu16 " Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_uint32_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t expected__ = (expected); \
- uint32_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu32 \
- " Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_uint32_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t expected__ = (expected); \
+ uint32_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu32 " Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_uint64_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t expected__ = (expected); \
- uint64_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu64 \
- " Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_uint64_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t expected__ = (expected); \
+ uint64_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu64 " Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_intmax_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t expected__ = (expected); \
- intmax_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIdMAX \
- " Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_intmax_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t expected__ = (expected); \
+ intmax_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIdMAX " Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_uintmax_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t expected__ = (expected); \
- uintmax_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_uintmax_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t expected__ = (expected); \
+ uintmax_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_size_t(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t expected__ = (expected); \
- size_t actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_size_t(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t expected__ = (expected); \
+ size_t actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_float(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float expected__ = (expected); \
- float actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %f Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_float(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float expected__ = (expected); \
+ float actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %f Actual: %f\n", __FILE__, __func__, \
+ __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_double(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double expected__ = (expected); \
- double actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %lf Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_double(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double expected__ = (expected); \
+ double actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %lf Actual: %lf\n", __FILE__, \
+ __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals_ptr(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- void *expected__ = (expected); \
- void *actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %p Actual: %p\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals_ptr(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ void *expected__ = (expected); \
+ void *actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %p Actual: %p\n", __FILE__, __func__, \
+ __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_equals__Bool(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- bool expected__ = (expected); \
- bool actual__ = (actual); \
- \
- if (expected__ != actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected: %d Actual: %d\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_equals__Bool(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ bool expected__ = (expected); \
+ bool actual__ = (actual); \
+\
+ if (expected__ != actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected: %d Actual: %d\n", __FILE__, __func__, \
+ __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -713,329 +664,297 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_not_equals_int8_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t not_expected__ = (not_expected); \
- int8_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId8 \
- " Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_int8_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t not_expected__ = (not_expected); \
+ int8_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId8 " Actual: %" PRId8 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_int16_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t not_expected__ = (not_expected); \
- int16_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId16 \
- " Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_int16_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t not_expected__ = (not_expected); \
+ int16_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId16 " Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_int32_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t not_expected__ = (not_expected); \
- int32_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId32 \
- " Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_int32_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t not_expected__ = (not_expected); \
+ int32_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId32 " Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_int64_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t not_expected__ = (not_expected); \
- int64_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId64 \
- " Actual: %" PRId64 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_int64_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t not_expected__ = (not_expected); \
+ int64_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId64 " Actual: %" PRId64 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_uint8_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t not_expected__ = (not_expected); \
- uint8_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu8 \
- " Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_uint8_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t not_expected__ = (not_expected); \
+ uint8_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu8 " Actual: %" PRIu8 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_uint16_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t not_expected__ = (not_expected); \
- uint16_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu16 \
- " Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_uint16_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t not_expected__ = (not_expected); \
+ uint16_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu16 " Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_uint32_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t not_expected__ = (not_expected); \
- uint32_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu32 \
- " Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_uint32_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t not_expected__ = (not_expected); \
+ uint32_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu32 " Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_uint64_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t not_expected__ = (not_expected); \
- uint64_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu64 \
- " Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_uint64_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t not_expected__ = (not_expected); \
+ uint64_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu64 " Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_intmax_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t not_expected__ = (not_expected); \
- intmax_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIdMAX \
- " Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_intmax_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t not_expected__ = (not_expected); \
+ intmax_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIdMAX " Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_uintmax_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t not_expected__ = (not_expected); \
- uintmax_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_uintmax_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t not_expected__ = (not_expected); \
+ uintmax_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_size_t(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t not_expected__ = (not_expected); \
- size_t actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_size_t(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t not_expected__ = (not_expected); \
+ size_t actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_float(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float not_expected__ = (not_expected); \
- float actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %f Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_float(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float not_expected__ = (not_expected); \
+ float actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %f Actual: %f\n", __FILE__, \
+ __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_double(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double not_expected__ = (not_expected); \
- double actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %lf Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_double(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double not_expected__ = (not_expected); \
+ double actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %lf Actual: %lf\n", __FILE__, \
+ __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals_ptr(not_expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- void *not_expected__ = (not_expected); \
- void *actual__ = (actual); \
- \
- if (not_expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %p Actual: %p\n", \
- __FILE__, __func__, __LINE__, str, not_expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals_ptr(not_expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ void *not_expected__ = (not_expected); \
+ void *actual__ = (actual); \
+\
+ if (not_expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %p Actual: %p\n", __FILE__, \
+ __func__, __LINE__, str, not_expected__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_equals__Bool(expected, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- bool expected__ = (expected); \
- bool actual__ = (actual); \
- \
- if (expected__ == actual__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %d Actual: %d\n", \
- __FILE__, __func__, __LINE__, str, expected__, actual__); \
- } \
- \
+#define cmc_assert_not_equals__Bool(expected, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ bool expected__ = (expected); \
+ bool actual__ = (actual); \
+\
+ if (expected__ == actual__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected: %d Actual: %d\n", __FILE__, \
+ __func__, __LINE__, str, expected__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -1044,288 +963,262 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_greater_int8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t boundary__ = (boundary); \
- int8_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId8 \
- " Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_int8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t boundary__ = (boundary); \
+ int8_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId8 " Actual: %" PRId8 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_int16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t boundary__ = (boundary); \
- int16_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId16 \
- " Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_int16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t boundary__ = (boundary); \
+ int16_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId16 " Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_int32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t boundary__ = (boundary); \
- int32_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId32 \
- " Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_int32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t boundary__ = (boundary); \
+ int32_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId32 " Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_int64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t boundary__ = (boundary); \
- int64_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId64 \
- " Actual: %" PRId64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_int64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t boundary__ = (boundary); \
+ int64_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRId64 " Actual: %" PRId64 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_uint8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t boundary__ = (boundary); \
- uint8_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu8 \
- " Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_uint8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t boundary__ = (boundary); \
+ uint8_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu8 " Actual: %" PRIu8 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_uint16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t boundary__ = (boundary); \
- uint16_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu16 \
- " Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_uint16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t boundary__ = (boundary); \
+ uint16_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu16 " Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_uint32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t boundary__ = (boundary); \
- uint32_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu32 \
- " Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_uint32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t boundary__ = (boundary); \
+ uint32_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu32 " Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_uint64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t boundary__ = (boundary); \
- uint64_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu64 \
- " Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_uint64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t boundary__ = (boundary); \
+ uint64_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIu64 " Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_intmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t boundary__ = (boundary); \
- intmax_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIdMAX \
- " Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_intmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t boundary__ = (boundary); \
+ intmax_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIdMAX " Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_uintmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t boundary__ = (boundary); \
- uintmax_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_uintmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t boundary__ = (boundary); \
+ uintmax_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_size_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t boundary__ = (boundary); \
- size_t actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_size_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t boundary__ = (boundary); \
+ size_t actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_float(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float boundary__ = (boundary); \
- float actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %f Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_float(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float boundary__ = (boundary); \
+ float actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %f Actual: %f\n", __FILE__, \
+ __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_double(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double boundary__ = (boundary); \
- double actual__ = (actual); \
- \
- if (actual__ <= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %lf Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_double(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double boundary__ = (boundary); \
+ double actual__ = (actual); \
+\
+ if (actual__ <= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater: %lf Actual: %lf\n", __FILE__, \
+ __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -1334,288 +1227,273 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_greater_equals_int8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t boundary__ = (boundary); \
- int8_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId8 \
- " Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_int8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t boundary__ = (boundary); \
+ int8_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId8 " Actual: %" PRId8 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_int16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t boundary__ = (boundary); \
- int16_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId16 \
- " Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_int16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t boundary__ = (boundary); \
+ int16_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId16 \
+ " Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_int32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t boundary__ = (boundary); \
- int32_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId32 \
- " Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_int32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t boundary__ = (boundary); \
+ int32_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId32 \
+ " Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_int64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t boundary__ = (boundary); \
- int64_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId64 \
- " Actual: %" PRId64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_int64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t boundary__ = (boundary); \
+ int64_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRId64 \
+ " Actual: %" PRId64 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_uint8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t boundary__ = (boundary); \
- uint8_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu8 \
- " Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_uint8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t boundary__ = (boundary); \
+ uint8_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu8 " Actual: %" PRIu8 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_uint16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t boundary__ = (boundary); \
- uint16_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu16 \
- " Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_uint16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t boundary__ = (boundary); \
+ uint16_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu16 \
+ " Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_uint32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t boundary__ = (boundary); \
- uint32_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu32 \
- " Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_uint32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t boundary__ = (boundary); \
+ uint32_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu32 \
+ " Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_uint64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t boundary__ = (boundary); \
- uint64_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu64 \
- " Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_uint64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t boundary__ = (boundary); \
+ uint64_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIu64 \
+ " Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_intmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t boundary__ = (boundary); \
- intmax_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIdMAX \
- " Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_intmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t boundary__ = (boundary); \
+ intmax_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIdMAX \
+ " Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_uintmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t boundary__ = (boundary); \
- uintmax_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_uintmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t boundary__ = (boundary); \
+ uintmax_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \
+ " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_size_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t boundary__ = (boundary); \
- size_t actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_size_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t boundary__ = (boundary); \
+ size_t actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %" PRIuMAX \
+ " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_float(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float boundary__ = (boundary); \
- float actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %f Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_float(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float boundary__ = (boundary); \
+ float actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %f Actual: %f\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_greater_equals_double(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double boundary__ = (boundary); \
- double actual__ = (actual); \
- \
- if (actual__ < boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %lf Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_greater_equals_double(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double boundary__ = (boundary); \
+ double actual__ = (actual); \
+\
+ if (actual__ < boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Greater or Equals: %lf Actual: %lf\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -1624,288 +1502,262 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_lesser_int8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t boundary__ = (boundary); \
- int8_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId8 \
- " Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_int8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t boundary__ = (boundary); \
+ int8_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId8 " Actual: %" PRId8 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_int16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t boundary__ = (boundary); \
- int16_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId16 \
- " Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_int16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t boundary__ = (boundary); \
+ int16_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId16 " Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_int32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t boundary__ = (boundary); \
- int32_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId32 \
- " Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_int32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t boundary__ = (boundary); \
+ int32_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId32 " Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_int64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t boundary__ = (boundary); \
- int64_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId64 \
- " Actual: %" PRId64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_int64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t boundary__ = (boundary); \
+ int64_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRId64 " Actual: %" PRId64 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_uint8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t boundary__ = (boundary); \
- uint8_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu8 \
- " Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_uint8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t boundary__ = (boundary); \
+ uint8_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu8 " Actual: %" PRIu8 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_uint16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t boundary__ = (boundary); \
- uint16_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu16 \
- " Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_uint16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t boundary__ = (boundary); \
+ uint16_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu16 " Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_uint32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t boundary__ = (boundary); \
- uint32_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu32 \
- " Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_uint32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t boundary__ = (boundary); \
+ uint32_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu32 " Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_uint64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t boundary__ = (boundary); \
- uint64_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu64 \
- " Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_uint64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t boundary__ = (boundary); \
+ uint64_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIu64 " Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_intmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t boundary__ = (boundary); \
- intmax_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIdMAX \
- " Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_intmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t boundary__ = (boundary); \
+ intmax_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIdMAX " Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_uintmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t boundary__ = (boundary); \
- uintmax_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_uintmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t boundary__ = (boundary); \
+ uintmax_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_size_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t boundary__ = (boundary); \
- size_t actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_size_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t boundary__ = (boundary); \
+ size_t actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_float(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float boundary__ = (boundary); \
- float actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %f Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_float(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float boundary__ = (boundary); \
+ float actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %f Actual: %f\n", __FILE__, \
+ __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_double(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double boundary__ = (boundary); \
- double actual__ = (actual); \
- \
- if (actual__ >= boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %lf Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_double(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double boundary__ = (boundary); \
+ double actual__ = (actual); \
+\
+ if (actual__ >= boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser: %lf Actual: %lf\n", __FILE__, \
+ __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -1914,288 +1766,273 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_lesser_equals_int8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t boundary__ = (boundary); \
- int8_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId8 \
- " Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_int8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t boundary__ = (boundary); \
+ int8_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId8 " Actual: %" PRId8 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_int16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t boundary__ = (boundary); \
- int16_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId16 \
- " Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_int16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t boundary__ = (boundary); \
+ int16_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId16 " Actual: %" PRId16 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_int32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t boundary__ = (boundary); \
- int32_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId32 \
- " Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_int32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t boundary__ = (boundary); \
+ int32_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId32 " Actual: %" PRId32 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_int64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t boundary__ = (boundary); \
- int64_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId64 \
- " Actual: %" PRId64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_int64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t boundary__ = (boundary); \
+ int64_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRId64 " Actual: %" PRId64 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_uint8_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t boundary__ = (boundary); \
- uint8_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu8 \
- " Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_uint8_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t boundary__ = (boundary); \
+ uint8_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu8 " Actual: %" PRIu8 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_uint16_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t boundary__ = (boundary); \
- uint16_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu16 \
- " Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_uint16_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t boundary__ = (boundary); \
+ uint16_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu16 " Actual: %" PRIu16 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_uint32_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t boundary__ = (boundary); \
- uint32_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu32 \
- " Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_uint32_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t boundary__ = (boundary); \
+ uint32_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu32 " Actual: %" PRIu32 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_uint64_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t boundary__ = (boundary); \
- uint64_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu64 \
- " Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_uint64_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t boundary__ = (boundary); \
+ uint64_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIu64 " Actual: %" PRIu64 \
+ "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_intmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t boundary__ = (boundary); \
- intmax_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIdMAX \
- " Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_intmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t boundary__ = (boundary); \
+ intmax_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIdMAX \
+ " Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_uintmax_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t boundary__ = (boundary); \
- uintmax_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_uintmax_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t boundary__ = (boundary); \
+ uintmax_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \
+ " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_size_t(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t boundary__ = (boundary); \
- size_t actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \
- " Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_size_t(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t boundary__ = (boundary); \
+ size_t actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %" PRIuMAX \
+ " Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_float(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float boundary__ = (boundary); \
- float actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %f Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_float(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float boundary__ = (boundary); \
+ float actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %f Actual: %f\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_lesser_equals_double(boundary, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double boundary__ = (boundary); \
- double actual__ = (actual); \
- \
- if (actual__ > boundary__) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %lf Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, boundary__, actual__); \
- } \
- \
+#define cmc_assert_lesser_equals_double(boundary, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double boundary__ = (boundary); \
+ double actual__ = (actual); \
+\
+ if (actual__ > boundary__) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Lesser or Equals: %lf Actual: %lf\n", \
+ __FILE__, __func__, __LINE__, str, boundary__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -2204,314 +2041,286 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_in_range_int8_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t lower_bound__ = (lower_bound); \
- int8_t upper_bound__ = (upper_bound); \
- int8_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId8 \
- ", %" PRId8 "] Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_int8_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t lower_bound__ = (lower_bound); \
+ int8_t upper_bound__ = (upper_bound); \
+ int8_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId8 ", %" PRId8 \
+ "] Actual: %" PRId8 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_int16_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t lower_bound__ = (lower_bound); \
- int16_t upper_bound__ = (upper_bound); \
- int16_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId16 \
- ", %" PRId16 "] Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_int16_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t lower_bound__ = (lower_bound); \
+ int16_t upper_bound__ = (upper_bound); \
+ int16_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId16 ", %" PRId16 \
+ "] Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_int32_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t lower_bound__ = (lower_bound); \
- int32_t upper_bound__ = (upper_bound); \
- int32_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 \
- ", %" PRId32 "] Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_int32_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t lower_bound__ = (lower_bound); \
+ int32_t upper_bound__ = (upper_bound); \
+ int32_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 ", %" PRId32 \
+ "] Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_int64_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t lower_bound__ = (lower_bound); \
- int64_t upper_bound__ = (upper_bound); \
- int64_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 \
- ", %" PRId32 "] Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_int64_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t lower_bound__ = (lower_bound); \
+ int64_t upper_bound__ = (upper_bound); \
+ int64_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRId32 ", %" PRId32 \
+ "] Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_uint8_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t lower_bound__ = (lower_bound); \
- uint8_t upper_bound__ = (upper_bound); \
- uint8_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu8 \
- ", %" PRIu8 "] Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_uint8_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t lower_bound__ = (lower_bound); \
+ uint8_t upper_bound__ = (upper_bound); \
+ uint8_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu8 ", %" PRIu8 \
+ "] Actual: %" PRIu8 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_uint16_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t lower_bound__ = (lower_bound); \
- uint16_t upper_bound__ = (upper_bound); \
- uint16_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu16 \
- ", %" PRIu16 "] Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_uint16_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t lower_bound__ = (lower_bound); \
+ uint16_t upper_bound__ = (upper_bound); \
+ uint16_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu16 ", %" PRIu16 \
+ "] Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_uint32_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t lower_bound__ = (lower_bound); \
- uint32_t upper_bound__ = (upper_bound); \
- uint32_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu32 \
- ", %" PRIu32 "] Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_uint32_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t lower_bound__ = (lower_bound); \
+ uint32_t upper_bound__ = (upper_bound); \
+ uint32_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu32 ", %" PRIu32 \
+ "] Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_uint64_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t lower_bound__ = (lower_bound); \
- uint64_t upper_bound__ = (upper_bound); \
- uint64_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu64 \
- ", %" PRIu64 "] Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_uint64_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t lower_bound__ = (lower_bound); \
+ uint64_t upper_bound__ = (upper_bound); \
+ uint64_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIu64 ", %" PRIu64 \
+ "] Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_intmax_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t lower_bound__ = (lower_bound); \
- intmax_t upper_bound__ = (upper_bound); \
- intmax_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIdMAX \
- ", %" PRIdMAX "] Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_intmax_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t lower_bound__ = (lower_bound); \
+ intmax_t upper_bound__ = (upper_bound); \
+ intmax_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIdMAX ", %" PRIdMAX \
+ "] Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_uintmax_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t lower_bound__ = (lower_bound); \
- uintmax_t upper_bound__ = (upper_bound); \
- uintmax_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX \
- ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_uintmax_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t lower_bound__ = (lower_bound); \
+ uintmax_t upper_bound__ = (upper_bound); \
+ uintmax_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX ", %" PRIuMAX \
+ "] Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_size_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t lower_bound__ = (lower_bound); \
- size_t upper_bound__ = (upper_bound); \
- size_t actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX \
- ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_size_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t lower_bound__ = (lower_bound); \
+ size_t upper_bound__ = (upper_bound); \
+ size_t actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%" PRIuMAX ", %" PRIuMAX \
+ "] Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_float(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float lower_bound__ = (lower_bound); \
- float upper_bound__ = (upper_bound); \
- float actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%f, %f] Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_float(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float lower_bound__ = (lower_bound); \
+ float upper_bound__ = (upper_bound); \
+ float actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%f, %f] Actual: %f\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_in_range_double(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double lower_bound__ = (lower_bound); \
- double upper_bound__ = (upper_bound); \
- double actual__ = (actual); \
- \
- if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%lf, %lf] Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_in_range_double(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double lower_bound__ = (lower_bound); \
+ double upper_bound__ = (upper_bound); \
+ double actual__ = (actual); \
+\
+ if ((actual__) < (lower_bound__) || (actual__) > (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Expected Range: [%lf, %lf] Actual: %lf\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
/** ---------------------------------------------------------------------------
@@ -2520,314 +2329,286 @@ static uintmax_t cmc_assert_failed = 0;
*
* ------------------------------------------------------------------------ **/
-#define cmc_assert_not_in_range_int8_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int8_t lower_bound__ = (lower_bound); \
- int8_t upper_bound__ = (upper_bound); \
- int8_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId8 \
- ", %" PRId8 "] Actual: %" PRId8 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_int8_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int8_t lower_bound__ = (lower_bound); \
+ int8_t upper_bound__ = (upper_bound); \
+ int8_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId8 ", %" PRId8 \
+ "] Actual: %" PRId8 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_int16_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int16_t lower_bound__ = (lower_bound); \
- int16_t upper_bound__ = (upper_bound); \
- int16_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId16 \
- ", %" PRId16 "] Actual: %" PRId16 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_int16_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int16_t lower_bound__ = (lower_bound); \
+ int16_t upper_bound__ = (upper_bound); \
+ int16_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId16 ", %" PRId16 \
+ "] Actual: %" PRId16 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_int32_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int32_t lower_bound__ = (lower_bound); \
- int32_t upper_bound__ = (upper_bound); \
- int32_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 \
- ", %" PRId32 "] Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_int32_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int32_t lower_bound__ = (lower_bound); \
+ int32_t upper_bound__ = (upper_bound); \
+ int32_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 ", %" PRId32 \
+ "] Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_int64_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- int64_t lower_bound__ = (lower_bound); \
- int64_t upper_bound__ = (upper_bound); \
- int64_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 \
- ", %" PRId32 "] Actual: %" PRId32 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_int64_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ int64_t lower_bound__ = (lower_bound); \
+ int64_t upper_bound__ = (upper_bound); \
+ int64_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRId32 ", %" PRId32 \
+ "] Actual: %" PRId32 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_uint8_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint8_t lower_bound__ = (lower_bound); \
- uint8_t upper_bound__ = (upper_bound); \
- uint8_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu8 \
- ", %" PRIu8 "] Actual: %" PRIu8 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_uint8_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint8_t lower_bound__ = (lower_bound); \
+ uint8_t upper_bound__ = (upper_bound); \
+ uint8_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu8 ", %" PRIu8 \
+ "] Actual: %" PRIu8 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_uint16_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint16_t lower_bound__ = (lower_bound); \
- uint16_t upper_bound__ = (upper_bound); \
- uint16_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu16 \
- ", %" PRIu16 "] Actual: %" PRIu16 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_uint16_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint16_t lower_bound__ = (lower_bound); \
+ uint16_t upper_bound__ = (upper_bound); \
+ uint16_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu16 ", %" PRIu16 \
+ "] Actual: %" PRIu16 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_uint32_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint32_t lower_bound__ = (lower_bound); \
- uint32_t upper_bound__ = (upper_bound); \
- uint32_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu32 \
- ", %" PRIu32 "] Actual: %" PRIu32 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_uint32_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint32_t lower_bound__ = (lower_bound); \
+ uint32_t upper_bound__ = (upper_bound); \
+ uint32_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu32 ", %" PRIu32 \
+ "] Actual: %" PRIu32 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_uint64_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uint64_t lower_bound__ = (lower_bound); \
- uint64_t upper_bound__ = (upper_bound); \
- uint64_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu64 \
- ", %" PRIu64 "] Actual: %" PRIu64 "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_uint64_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uint64_t lower_bound__ = (lower_bound); \
+ uint64_t upper_bound__ = (upper_bound); \
+ uint64_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIu64 ", %" PRIu64 \
+ "] Actual: %" PRIu64 "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_intmax_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- intmax_t lower_bound__ = (lower_bound); \
- intmax_t upper_bound__ = (upper_bound); \
- intmax_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIdMAX \
- ", %" PRIdMAX "] Actual: %" PRIdMAX "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_intmax_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ intmax_t lower_bound__ = (lower_bound); \
+ intmax_t upper_bound__ = (upper_bound); \
+ intmax_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIdMAX ", %" PRIdMAX \
+ "] Actual: %" PRIdMAX "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_uintmax_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- uintmax_t lower_bound__ = (lower_bound); \
- uintmax_t upper_bound__ = (upper_bound); \
- uintmax_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX \
- ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_uintmax_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ uintmax_t lower_bound__ = (lower_bound); \
+ uintmax_t upper_bound__ = (upper_bound); \
+ uintmax_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX ", %" PRIuMAX \
+ "] Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_size_t(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- size_t lower_bound__ = (lower_bound); \
- size_t upper_bound__ = (upper_bound); \
- size_t actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX \
- ", %" PRIuMAX "] Actual: %" PRIuMAX "\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_size_t(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ size_t lower_bound__ = (lower_bound); \
+ size_t upper_bound__ = (upper_bound); \
+ size_t actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, \
+ "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%" PRIuMAX ", %" PRIuMAX \
+ "] Actual: %" PRIuMAX "\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_float(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- float lower_bound__ = (lower_bound); \
- float upper_bound__ = (upper_bound); \
- float actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%f, %f] Actual: %f\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_float(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ float lower_bound__ = (lower_bound); \
+ float upper_bound__ = (upper_bound); \
+ float actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%f, %f] Actual: %f\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#define cmc_assert_not_in_range_double(lower_bound, upper_bound, actual) \
- do \
- { \
- cmc_assert_total++; \
- const char *str = #actual; \
- double lower_bound__ = (lower_bound); \
- double upper_bound__ = (upper_bound); \
- double actual__ = (actual); \
- \
- if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
- { \
- cmc_assert_state = false; \
- cmc_assert_failed++; \
- \
- fprintf( \
- stderr, \
- "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%lf, %lf] Actual: %lf\n", \
- __FILE__, __func__, __LINE__, str, lower_bound__, \
- upper_bound__, actual__); \
- } \
- \
+#define cmc_assert_not_in_range_double(lower_bound, upper_bound, actual) \
+ do \
+ { \
+ cmc_assert_total++; \
+ const char *str = #actual; \
+ double lower_bound__ = (lower_bound); \
+ double upper_bound__ = (upper_bound); \
+ double actual__ = (actual); \
+\
+ if ((actual__) >= (lower_bound__) && (actual__) <= (upper_bound__)) \
+ { \
+ cmc_assert_state = false; \
+ cmc_assert_failed++; \
+\
+ fprintf(stderr, "Assertion Failed at %s:%s:%u for { %s }: Not Expected Range: [%lf, %lf] Actual: %lf\n", \
+ __FILE__, __func__, __LINE__, str, lower_bound__, upper_bound__, actual__); \
+ } \
+\
} while (0)
-#endif /* CMC_ASSERT_H */
+#endif /* CMC_UTL_ASSERT_H */
diff --git a/src/utl/foreach.h b/src/utl/foreach.h
index 207758e..d625380 100644
--- a/src/utl/foreach.h
+++ b/src/utl/foreach.h
@@ -1,5 +1,5 @@
/**
- * foreach.h
+ * utl/foreach.h
*
* Creation Date: 25/02/2019
*
@@ -17,15 +17,17 @@
* TARGET - Target variable
*/
-#ifndef CMC_FOREACH_H
-#define CMC_FOREACH_H
+#ifndef CMC_UTL_FOREACH_H
+#define CMC_UTL_FOREACH_H
-#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \
- for (struct SNAME##_iter ITERNAME = PFX##_iter_start(TARGET); \
- !PFX##_iter_at_end(&ITERNAME); PFX##_iter_next(&ITERNAME))
+#include "../cor/core.h"
-#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \
- for (struct SNAME##_iter ITERNAME = PFX##_iter_end(TARGET); \
- !PFX##_iter_at_start(&ITERNAME); PFX##_iter_prev(&ITERNAME))
+#define CMC_FOREACH(PFX, SNAME, ITERNAME, TARGET) \
+ for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_start)(TARGET); !CMC_(PFX, _iter_at_end)(&ITERNAME); \
+ CMC_(PFX, _iter_next)(&ITERNAME))
-#endif /* CMC_FOREACH_H */
+#define CMC_FOREACH_REV(PFX, SNAME, ITERNAME, TARGET) \
+ for (struct CMC_DEF_ITER(SNAME) ITERNAME = CMC_(PFX, _iter_end)(TARGET); !CMC_(PFX, _iter_at_start)(&ITERNAME); \
+ CMC_(PFX, _iter_prev)(&ITERNAME))
+
+#endif /* CMC_UTL_FOREACH_H */
diff --git a/src/utl/futils.h b/src/utl/futils.h
index e9516b1..26726dc 100644
--- a/src/utl/futils.h
+++ b/src/utl/futils.h
@@ -1,5 +1,5 @@
/**
- * futils.h
+ * utl/futils.h
*
* Creation Date: 15/04/2020
*
@@ -13,8 +13,8 @@
* another one every time.
*/
-#ifndef CMC_FUTILS_H
-#define CMC_FUTILS_H
+#ifndef CMC_UTL_FUTILS_H
+#define CMC_UTL_FUTILS_H
#include
#include
@@ -323,7 +323,8 @@ static inline size_t cmc_float_hash(float e)
if (e == 0.0)
e = 0.0; // if e == -0.0, now it is 0.0
- union {
+ union
+ {
float a;
size_t b;
} x;
@@ -342,7 +343,8 @@ static inline size_t cmc_double_hash(double e)
if (e == 0.0)
e = 0.0; // if e == -0.0, now it is 0.0
- union {
+ union
+ {
double a;
size_t b;
} x;
@@ -461,4 +463,4 @@ static inline size_t cmc_u64_hash_mix(uint64_t element)
/* Can simply use cmp for basic data types */
-#endif /* CMC_FUTILS_H */
+#endif /* CMC_UTL_FUTILS_H */
diff --git a/src/utl/log.h b/src/utl/log.h
index abcf609..284f429 100644
--- a/src/utl/log.h
+++ b/src/utl/log.h
@@ -1,5 +1,5 @@
/**
- * log.h
+ * utl/log.h
*
* Creation Date: 21/06/2019
*
@@ -56,20 +56,20 @@
* - If X is less than the level of FATAL, all logs are enabled
*/
-#ifndef CMC_LOG_H
-#define CMC_LOG_H
+#ifndef CMC_UTL_LOG_H
+#define CMC_UTL_LOG_H
#include
#include
#include
#include
-static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO",
- "WARN", "ERROR", "FATAL" };
+#include "../cor/core.h"
+
+static const char *cmc_log_names[] = { "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL" };
#ifdef CMC_LOG_COLOR
-static const char *cmc_log_color[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m",
- "\x1b[33m", "\x1b[31m", "\x1b[35m" };
+static const char *cmc_log_color[] = { "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m" };
#endif
enum cmc_log_type
@@ -93,21 +93,15 @@ static struct
} cmc_log_config = { 0, 0, true, true, true, NULL };
-#define cmc_log_trace(fmt, ...) \
- cmc_log(CMC_LOG_TRACE, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
-#define cmc_log_debug(fmt, ...) \
- cmc_log(CMC_LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
-#define cmc_log_info(fmt, ...) \
- cmc_log(CMC_LOG_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
-#define cmc_log_warn(fmt, ...) \
- cmc_log(CMC_LOG_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
-#define cmc_log_error(fmt, ...) \
- cmc_log(CMC_LOG_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
-#define cmc_log_fatal(fmt, ...) \
- cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
+#define cmc_log_trace(fmt, ...) cmc_log(CMC_LOG_TRACE, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
+#define cmc_log_debug(fmt, ...) cmc_log(CMC_LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
+#define cmc_log_info(fmt, ...) cmc_log(CMC_LOG_INFO, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
+#define cmc_log_warn(fmt, ...) cmc_log(CMC_LOG_WARN, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
+#define cmc_log_error(fmt, ...) cmc_log(CMC_LOG_ERROR, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
+#define cmc_log_fatal(fmt, ...) cmc_log(CMC_LOG_FATAL, __FILE__, __func__, __LINE__, fmt, ##__VA_ARGS__)
-static void cmc_log(enum cmc_log_type log, const char *filename,
- const char *funcname, unsigned line, const char *fmt, ...)
+CMC_UNUSED static void cmc_log(enum cmc_log_type log, const char *filename, const char *funcname, unsigned line,
+ const char *fmt, ...)
{
if (!cmc_log_config.enabled)
return;
@@ -130,11 +124,10 @@ static void cmc_log(enum cmc_log_type log, const char *filename,
time[strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", lt)] = '\0';
#ifdef CMC_LOG_COLOR
- fprintf(stderr, "%s %s%5s\x1b[0m at\x1b[90m %s:%s:%u\x1b[0m | ", time,
- cmc_log_color[i], cmc_log_names[i], filename, funcname, line);
-#else
- fprintf(stderr, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i],
+ fprintf(stderr, "%s %s%5s\x1b[0m at\x1b[90m %s:%s:%u\x1b[0m | ", time, cmc_log_color[i], cmc_log_names[i],
filename, funcname, line);
+#else
+ fprintf(stderr, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], filename, funcname, line);
#endif
va_list args;
@@ -165,8 +158,7 @@ skip:
char time[32];
time[strftime(time, sizeof(time), "%Y-%m-%d %H:%M:%S", lt)] = '\0';
- fprintf(cmc_log_config.file, "%s %5s at %s:%s:%u | ", time,
- cmc_log_names[i], filename, funcname, line);
+ fprintf(cmc_log_config.file, "%s %5s at %s:%s:%u | ", time, cmc_log_names[i], filename, funcname, line);
va_list file_args;
va_start(file_args, fmt);
@@ -178,4 +170,4 @@ skip:
}
}
-#endif /* CMC_LOG_H */
+#endif /* CMC_UTL_LOG_H */
diff --git a/src/utl/mutex.h b/src/utl/mutex.h
index ef5be43..69678e6 100644
--- a/src/utl/mutex.h
+++ b/src/utl/mutex.h
@@ -1,5 +1,5 @@
/**
- * mutex.h
+ * utl/mutex.h
*
* Creation Date: 14/05/2020
*
@@ -22,8 +22,8 @@
* - cmc_mtx_trylock
*/
-#ifndef CMC_MUTEX_H
-#define CMC_MUTEX_H
+#ifndef CMC_UTL_MUTEX_H
+#define CMC_UTL_MUTEX_H
#include
@@ -72,9 +72,9 @@ static inline bool cmc_mtx_init(struct cmc_mutex *mtx)
mtx->mutex = CreateMutex(NULL, FALSE, NULL);
if (mtx->mutex == NULL)
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
else
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return mtx->mutex != NULL;
@@ -82,9 +82,9 @@ static inline bool cmc_mtx_init(struct cmc_mutex *mtx)
int err = pthread_mutex_init(&(mtx->mutex), NULL);
if (err != 0)
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
else
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return err == 0;
#endif
@@ -102,21 +102,21 @@ static inline bool cmc_mtx_destroy(struct cmc_mutex *mtx)
#if defined(CMC_MUTEX_WINDOWS)
if (!CloseHandle(mtx->mutex))
{
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
return false;
}
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return true;
#elif defined(CMC_MUTEX_UNIX)
if (pthread_mutex_destroy(&(mtx->mutex)) != 0)
{
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
return false;
}
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return true;
#endif
}
@@ -135,21 +135,21 @@ static inline bool cmc_mtx_lock(struct cmc_mutex *mtx)
if (result == WAIT_FAILED || result == WAIT_ABANDONED)
{
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
return false;
}
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return true;
#elif defined(CMC_MUTEX_UNIX)
if (pthread_mutex_lock(&mtx->mutex) != 0)
{
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
return false;
}
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return true;
#endif
}
@@ -165,19 +165,19 @@ static inline bool cmc_mtx_unlock(struct cmc_mutex *mtx)
{
#if defined(CMC_MUTEX_WINDOWS)
if (!ReleaseMutex(mtx->mutex))
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
else
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
- return mtx->flag == cmc_flags.OK;
+ return mtx->flag == CMC_FLAG_OK;
#elif defined(CMC_MUTEX_UNIX)
if (pthread_mutex_unlock(&mtx->mutex) != 0)
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
else
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
- return mtx->flag == cmc_flags.OK;
+ return mtx->flag == CMC_FLAG_OK;
#endif
}
@@ -195,23 +195,23 @@ static inline bool cmc_mtx_trylock(struct cmc_mutex *mtx)
if (result == WAIT_FAILED || result == WAIT_ABANDONED)
{
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
return false;
}
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return result != WAIT_TIMEOUT;
#elif defined(CMC_MUTEX_UNIX)
int err = pthread_mutex_trylock(&mtx->mutex);
if (err == EINVAL || err == EFAULT)
- mtx->flag = cmc_flags.MUTEX;
+ mtx->flag = CMC_FLAG_MUTEX;
else
- mtx->flag = cmc_flags.OK;
+ mtx->flag = CMC_FLAG_OK;
return err == 0;
#endif
}
-#endif /* CMC_MUTEX_H */
+#endif /* CMC_UTL_MUTEX_H */
diff --git a/src/utl/test.h b/src/utl/test.h
index d0badb9..07238c2 100644
--- a/src/utl/test.h
+++ b/src/utl/test.h
@@ -1,5 +1,5 @@
/**
- * test.h
+ * utl/test.h
*
* Creation Date: 26/06/2019
*
@@ -34,14 +34,15 @@
* Define this macro to allow colored output.
*/
-#ifndef CMC_TEST_H
-#define CMC_TEST_H
+#ifndef CMC_UTL_TEST_H
+#define CMC_UTL_TEST_H
#include
#include
#include
#include
+#include "../cor/core.h"
#include "assert.h"
#include "timer.h"
@@ -56,27 +57,27 @@ struct cmc_test_info
bool verbose;
};
+#ifdef CMC_TEST_COLOR
static inline const char *cmc_test_color(int i)
{
-#ifdef CMC_TEST_COLOR
// 0 - Default, all off
// 1 - Failed (red)
// 2 - Passed (green)
// 3 - Box (gray)
// 4 - Name (cyan)
// 5 - Total (yellow)
- static const char *cmc_test_colors[] = {
- "\x1b[0m", "\x1b[31m", "\x1b[32m", "\x1b[90m", "\x1b[36m", "\x1b[33m"
- };
+ static const char *cmc_test_colors[] = { "\x1b[0m", "\x1b[31m", "\x1b[32m", "\x1b[90m", "\x1b[36m", "\x1b[33m" };
return cmc_test_colors[i];
#else
+static inline const char *cmc_test_color(int i)
+{
+ (void)i;
return "";
#endif
}
/* Logging function */
-static void cmc_test_log(const char *unit_name, const char *current_test,
- bool aborted, bool passed)
+CMC_UNUSED static void cmc_test_log(const char *unit_name, const char *current_test, bool aborted, bool passed)
{
if (aborted)
{
@@ -105,139 +106,117 @@ static void cmc_test_log(const char *unit_name, const char *current_test,
}
}
-#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \
- uintmax_t UNAME(void) \
- { \
- const char *unit_name = #UNAME; \
- const char *current_test = NULL; \
- \
- struct cmc_test_info tinfo = { 0 }; \
- struct cmc_timer timer = { 0 }; \
- \
- tinfo.verbose = VERBOSE; \
- tinfo.assert_total = cmc_assert_total; \
- tinfo.assert_failed = cmc_assert_failed; \
- \
- printf("%s", cmc_test_color(3)); \
- printf( \
- " +---------------------------------------------------------------+\n"); \
- printf(" | "); \
- printf("%s", cmc_test_color(0)); \
- printf("Unit "); \
- printf("%s", cmc_test_color(4)); \
- printf("%-56s", unit_name); \
- printf("%s", cmc_test_color(3)); \
- printf( \
- " |\n +---------------------------------------------------------------+"); \
- printf("%s\n", cmc_test_color(0)); \
- \
- /* Tests */ \
- cmc_timer_start(timer); \
- \
- BODY; \
- \
- cmc_timer_stop(timer); \
- \
- unittest_abort: \
- if (tinfo.aborted) \
- { \
- cmc_test_log(unit_name, current_test, true, false); \
- } \
- \
- tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \
- tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \
- \
- printf("%s", cmc_test_color(3)); \
- printf( \
- " +---------------------------------------------------------------+\n | "); \
- printf("%s", cmc_test_color(0)); \
- printf("Summary : "); \
- printf("%s", cmc_test_color(4)); \
- printf("%-52s", unit_name); \
- printf("%s|\n", cmc_test_color(3)); \
- printf( \
- " +---------++----------------+-----------------+-----------------+\n | "); \
- printf("%s", cmc_test_color(0)); \
- printf("Tests "); \
- printf("%s", cmc_test_color(3)); \
- printf("||"); \
- printf("%s", cmc_test_color(5)); \
- printf(" Total %8" PRIuMAX "", tinfo.total); \
- printf("%s", cmc_test_color(3)); \
- printf(" | "); \
- printf("%s", cmc_test_color(2)); \
- printf("Passed %8" PRIuMAX "", tinfo.passed); \
- printf("%s", cmc_test_color(3)); \
- printf(" | "); \
- printf("%s", cmc_test_color(1)); \
- printf("Failed %8" PRIuMAX "", tinfo.failed); \
- printf("%s", cmc_test_color(3)); \
- printf(" |\n | "); \
- printf("%s", cmc_test_color(0)); \
- printf("Asserts "); \
- printf("%s", cmc_test_color(3)); \
- printf("||"); \
- printf("%s", cmc_test_color(5)); \
- printf(" Total %8" PRIuMAX "", tinfo.assert_total); \
- printf("%s", cmc_test_color(3)); \
- printf(" | "); \
- printf("%s", cmc_test_color(2)); \
- printf("Passed %8" PRIuMAX "", \
- tinfo.assert_total - tinfo.assert_failed); \
- printf("%s", cmc_test_color(3)); \
- printf(" | "); \
- printf("%s", cmc_test_color(1)); \
- printf("Failed %8" PRIuMAX "", tinfo.assert_failed); \
- printf("%s", cmc_test_color(3)); \
- printf(" |\n"); \
- printf( \
- " +---------++----------------+-----------------+-----------------+\n | "); \
- printf("%s", cmc_test_color(0)); \
- printf("Total Runtime : %32.0f milliseconds", timer.result); \
- printf(" %s|\n", cmc_test_color(3)); \
- printf( \
- " +---------------------------------------------------------------+\n"); \
- printf("%s", cmc_test_color(0)); \
- printf("\n"); \
- \
- return tinfo.failed; \
+#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \
+ uintmax_t UNAME(void) \
+ { \
+ const char *unit_name = #UNAME; \
+ const char *current_test = NULL; \
+\
+ struct cmc_test_info tinfo = { 0 }; \
+ struct cmc_timer timer = { 0 }; \
+\
+ tinfo.verbose = VERBOSE; \
+ tinfo.assert_total = cmc_assert_total; \
+ tinfo.assert_failed = cmc_assert_failed; \
+\
+ printf("%s", cmc_test_color(3)); \
+ printf(" +---------------------------------------------------------------+\n"); \
+ printf(" | "); \
+ printf("%s", cmc_test_color(0)); \
+ printf("Unit "); \
+ printf("%s", cmc_test_color(4)); \
+ printf("%-56s", unit_name); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" |\n +---------------------------------------------------------------+"); \
+ printf("%s\n", cmc_test_color(0)); \
+\
+ /* Tests */ \
+ cmc_timer_start(timer); \
+\
+ BODY; \
+\
+ cmc_timer_stop(timer); \
+\
+ tinfo.assert_total = cmc_assert_total - tinfo.assert_total; \
+ tinfo.assert_failed = cmc_assert_failed - tinfo.assert_failed; \
+\
+ printf("%s", cmc_test_color(3)); \
+ printf(" +---------------------------------------------------------------+\n | "); \
+ printf("%s", cmc_test_color(0)); \
+ printf("Summary : "); \
+ printf("%s", cmc_test_color(4)); \
+ printf("%-52s", unit_name); \
+ printf("%s|\n", cmc_test_color(3)); \
+ printf(" +---------++----------------+-----------------+-----------------+\n | "); \
+ printf("%s", cmc_test_color(0)); \
+ printf("Tests "); \
+ printf("%s", cmc_test_color(3)); \
+ printf("||"); \
+ printf("%s", cmc_test_color(5)); \
+ printf(" Total %8" PRIuMAX "", tinfo.total); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" | "); \
+ printf("%s", cmc_test_color(2)); \
+ printf("Passed %8" PRIuMAX "", tinfo.passed); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" | "); \
+ printf("%s", cmc_test_color(1)); \
+ printf("Failed %8" PRIuMAX "", tinfo.failed); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" |\n | "); \
+ printf("%s", cmc_test_color(0)); \
+ printf("Asserts "); \
+ printf("%s", cmc_test_color(3)); \
+ printf("||"); \
+ printf("%s", cmc_test_color(5)); \
+ printf(" Total %8" PRIuMAX "", tinfo.assert_total); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" | "); \
+ printf("%s", cmc_test_color(2)); \
+ printf("Passed %8" PRIuMAX "", tinfo.assert_total - tinfo.assert_failed); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" | "); \
+ printf("%s", cmc_test_color(1)); \
+ printf("Failed %8" PRIuMAX "", tinfo.assert_failed); \
+ printf("%s", cmc_test_color(3)); \
+ printf(" |\n"); \
+ printf(" +---------++----------------+-----------------+-----------------+\n | "); \
+ printf("%s", cmc_test_color(0)); \
+ printf("Total Runtime : %32.0f milliseconds", timer.result); \
+ printf(" %s|\n", cmc_test_color(3)); \
+ printf(" +---------------------------------------------------------------+\n"); \
+ printf("%s", cmc_test_color(0)); \
+ printf("\n"); \
+\
+ return tinfo.failed; \
}
-#define CMC_CREATE_TEST(TNAME, BODY) \
- do \
- { \
- current_test = #TNAME; \
- \
- tinfo.total += 1; \
- \
- /* Provided by assert.h */ \
- cmc_assert_state = true; \
- \
- BODY; \
- \
- if (tinfo.verbose) \
- { \
- if (!cmc_assert_state) \
- { \
- tinfo.failed += 1; \
+#define CMC_CREATE_TEST(TNAME, BODY) \
+ do \
+ { \
+ current_test = #TNAME; \
+\
+ tinfo.total += 1; \
+\
+ /* Provided by assert.h */ \
+ cmc_assert_state = true; \
+\
+ BODY; \
+\
+ if (tinfo.verbose) \
+ { \
+ if (!cmc_assert_state) \
+ { \
+ tinfo.failed += 1; \
cmc_test_log(unit_name, current_test, false, false); \
- } \
- else \
- { \
- tinfo.passed += 1; \
- cmc_test_log(unit_name, current_test, false, true); \
- } \
- } \
- \
+ } \
+ else \
+ { \
+ tinfo.passed += 1; \
+ cmc_test_log(unit_name, current_test, false, true); \
+ } \
+ } \
+\
} while (0)
-#define CMC_TEST_ABORT() \
- do \
- { \
- tinfo.aborted = true; \
- tinfo.total -= 1; \
- goto unittest_abort; \
- \
- } while (0)
-
-#endif /* CMC_TEST_H */
+#endif /* CMC_UTL_TEST_H */
diff --git a/src/utl/thread.h b/src/utl/thread.h
index bf309fb..22c34e5 100644
--- a/src/utl/thread.h
+++ b/src/utl/thread.h
@@ -1,5 +1,5 @@
/**
- * thread.h
+ * utl/thread.h
*
* Creation Date: 14/05/2020
*
@@ -20,8 +20,8 @@
* - cmc_thrd_join
*/
-#ifndef CMC_THREAD_H
-#define CMC_THREAD_H
+#ifndef CMC_UTL_THREAD_H
+#define CMC_UTL_THREAD_H
#include
#include
@@ -88,8 +88,7 @@ static void *cmc_thread_wrapper(void *arg)
* \param args The arguments passed to the proc function.
* \return True or false if the thread creation was successfull.
*/
-static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc,
- void *args)
+static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc, void *args)
{
#if defined(CMC_THREAD_WINDOWS)
thr->args = args;
@@ -97,21 +96,21 @@ static inline bool cmc_thrd_create(struct cmc_thread *thr, cmc_thread_proc proc,
thr->thread = CreateThread(NULL, 0, cmc_thread_wrapper, thr, 0, NULL);
if (!thr->thread)
- thr->flag = cmc_flags.THREAD;
+ thr->flag = CMC_FLAG_THREAD;
else
- thr->flag = cmc_flags.OK;
+ thr->flag = CMC_FLAG_OK;
- return thr->flag == cmc_flags.OK;
+ return thr->flag == CMC_FLAG_OK;
#elif defined(CMC_THREAD_UNIX)
thr->args = args;
thr->process = proc;
if (pthread_create(&(thr->thread), NULL, cmc_thread_wrapper, thr) != 0)
- thr->flag = cmc_flags.THREAD;
+ thr->flag = CMC_FLAG_THREAD;
else
- thr->flag = cmc_flags.OK;
+ thr->flag = CMC_FLAG_OK;
- return thr->flag == cmc_flags.OK;
+ return thr->flag == CMC_FLAG_OK;
#endif
}
@@ -127,7 +126,7 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result)
#if defined(CMC_THREAD_WINDOWS)
if (WaitForSingleObject(thr->thread, INFINITE) == WAIT_FAILED)
{
- thr->flag = cmc_flags.THREAD;
+ thr->flag = CMC_FLAG_THREAD;
return false;
}
@@ -137,22 +136,22 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result)
{
if (GetExitCodeThread(thr->thread, &exit_code) == 0)
{
- thr->flag = cmc_flags.THREAD;
+ thr->flag = CMC_FLAG_THREAD;
return false;
}
else
*result = (int)exit_code;
}
- thr->flag = cmc_flags.OK;
+ thr->flag = CMC_FLAG_OK;
if (CloseHandle(thr->thread) == 0)
{
- thr->flag = cmc_flags.THREAD;
+ thr->flag = CMC_FLAG_THREAD;
return false;
}
- thr->flag = cmc_flags.OK;
+ thr->flag = CMC_FLAG_OK;
return true;
#elif defined(CMC_THREAD_UNIX)
@@ -160,7 +159,7 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result)
if (pthread_join(thr->thread, &exit_value) != 0)
{
- thr->flag = cmc_flags.THREAD;
+ thr->flag = CMC_FLAG_THREAD;
return false;
}
@@ -169,10 +168,10 @@ static inline bool cmc_thrd_join(struct cmc_thread *thr, int *result)
*result = (int)(intptr_t)exit_value;
}
- thr->flag = cmc_flags.OK;
+ thr->flag = CMC_FLAG_OK;
return true;
#endif
}
-#endif /* CMC_THREAD_H */
+#endif /* CMC_UTL_THREAD_H */
diff --git a/src/utl/timer.h b/src/utl/timer.h
index 45b9990..79857c3 100644
--- a/src/utl/timer.h
+++ b/src/utl/timer.h
@@ -1,5 +1,5 @@
/**
- * timer.h
+ * utl/timer.h
*
* Creation Date: 12/04/2019
*
@@ -12,8 +12,8 @@
* Simple timer macros utility for timing code execution.
*/
-#ifndef CMC_TIMER_H
-#define CMC_TIMER_H
+#ifndef CMC_UTL_TIMER_H
+#define CMC_UTL_TIMER_H
#include
@@ -24,20 +24,19 @@ struct cmc_timer
double result; /* The result is given in milliseconds */
};
-#define cmc_timer_start(timer) \
- do \
- { \
+#define cmc_timer_start(timer) \
+ do \
+ { \
struct cmc_timer *t__ = &(timer); \
- t__->start = clock(); \
+ t__->start = clock(); \
} while (0)
-#define cmc_timer_stop(timer) \
- do \
- { \
- struct cmc_timer *t__ = &(timer); \
- t__->stop = clock(); \
- t__->result = \
- (double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \
+#define cmc_timer_stop(timer) \
+ do \
+ { \
+ struct cmc_timer *t__ = &(timer); \
+ t__->stop = clock(); \
+ t__->result = (double)(t__->stop - t__->start) * 1000.0 / CLOCKS_PER_SEC; \
} while (0)
-#endif /* CMC_TIMER_H */
+#endif /* CMC_UTL_TIMER_H */
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
index 63d94a4..0000000
--- a/tests/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-CC = gcc
-CFLAGS = -std=c11 -Wall -Wextra
-CFLAGS += -Wno-unused -Wno-missing-braces
-
-main: FORCE
- $(CC) foreach.c -o foreach.exe $(CFLAGS)
- ./foreach.exe
- $(CC) iterators.c -o iterators.exe $(CFLAGS)
- ./iterators.exe
- $(CC) contains.c -o contains.exe $(CFLAGS)
- ./contains.exe
- $(CC) types.c -o types.exe $(CFLAGS)
- ./types.exe
- make -C ./sep
-
-dev: main
- rm *.exe ./sep/*.o ./sep/*.exe
-
-windev: main
- del *.exe .\\sep\\*.o .\\sep\\*.exe
-
-FORCE:
diff --git a/tests/README.md b/tests/README.md
deleted file mode 100644
index 0755797..0000000
--- a/tests/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Tests
-
-* `codecov` - A stalled version for codecov;
-* `main` - Unit tests for the main C Macro Collections library;
-* `sep/main.c`, `sep/sep.c` and `sep/sep.h` - Tests separate header and source compilation;
-* `contains.c` - Tests the `contains` function for all collections;
-* `foreach.c` - Tests the ForEach macros for all collections;
-* `iterators.c` - Tests all collection's iterators;
-* `types.c` - Tests if all containers accept all possible C data types (struct, union, enum, pointers, function pointers)
diff --git a/tests/contains.c b/tests/contains.c
deleted file mode 100644
index 730bfba..0000000
--- a/tests/contains.c
+++ /dev/null
@@ -1,260 +0,0 @@
-#include "../src/macro_collections.h"
-#include
-#include
-#include
-
-int intcmp(int a, int b)
-{
- return (a > b) - (a < b);
-}
-
-size_t inthash(int t)
-{
- size_t a = t;
- a += ~(a << 15);
- a ^= (a >> 10);
- a += (a << 3);
- a ^= (a >> 6);
- a += ~(a << 11);
- a ^= (a >> 16);
- return a;
-}
-
-CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
-CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
-CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
-CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
-CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
-CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
-CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int)
-CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
-CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int)
-
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, , int)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int)
-CMC_COLLECTION_GENERATE(MULTISET, ms, mset, , int)
-
-int main(void)
-{
- struct list *l = l_new(1000);
- struct stack *s = s_new(1000);
- struct queue *q = q_new(1000);
- struct deque *d = d_new(1000);
- struct linked *ll = ll_new();
- struct heap *h = h_new(1000, cmc_max_heap, intcmp);
- struct tset *ts = ts_new(intcmp);
- struct tmap *tm = tm_new(intcmp);
- struct hset *hs = hs_new(1000, 0.6, intcmp, inthash);
- struct hmap *hm = hm_new(1000, 0.6, intcmp, inthash);
- struct iheap *ih = ih_new(1000, intcmp);
- struct mmap *mm = mm_new(1000, 0.8, intcmp, inthash);
- struct mset *ms = ms_new(1000, 0.6, intcmp, inthash);
-
- bool a[13] = { false, false, false, false, false, false, false,
- false, false, false, false, false, false },
- b[13] = { false, false, false, false, false, false, false,
- false, false, false, false, false, false },
- c[13] = { true, true, true, true, true, true, true,
- true, true, true, true, true, true };
-
- b[0] = d_contains(d, 1, intcmp);
- b[1] = hm_contains(hm, 1);
- b[2] = hs_contains(hs, 1);
- b[3] = h_contains(h, 1);
- b[4] = ll_contains(ll, 1, intcmp);
- b[5] = l_contains(l, 1, intcmp);
- b[6] = q_contains(q, 1, intcmp);
- b[7] = s_contains(s, 1, intcmp);
- b[8] = tm_contains(tm, 1);
- b[9] = ts_contains(ts, 1);
-
- b[10] = ih_contains(ih, 1);
- b[11] = mm_contains(mm, 1);
- b[12] = ms_contains(ms, 1);
-
- for (int i = 1; i < 1001; i++)
- {
- if (i % 2 == 0)
- {
- d_push_front(d, i);
- l_push_front(l, i);
- ll_push_front(ll, i);
- }
- else
- {
- d_push_back(d, i);
- l_push_back(l, i);
- ll_push_back(ll, i);
- }
-
- s_push(s, i);
- q_enqueue(q, i);
- h_insert(h, i);
- ts_insert(ts, i);
- tm_insert(tm, i, i);
- hs_insert(hs, i);
- hm_insert(hm, i, i);
-
- ih_insert(ih, i);
- mm_insert(mm, i, i);
- ms_insert(ms, i);
- }
-
- for (int i = 1; i < 1001; i++)
- {
- c[0] = c[0] && d_contains(d, i, intcmp);
- c[1] = c[1] && hm_contains(hm, i);
- c[2] = c[2] && hs_contains(hs, i);
- c[3] = c[3] && h_contains(h, i);
- c[4] = c[4] && ll_contains(ll, i, intcmp);
- c[5] = c[5] && l_contains(l, i, intcmp);
- c[6] = c[6] && q_contains(q, i, intcmp);
- c[7] = c[7] && s_contains(s, i, intcmp);
- c[8] = c[8] && tm_contains(tm, i);
- c[9] = c[9] && ts_contains(ts, i);
-
- c[10] = c[10] && ih_contains(ih, i);
- c[11] = c[11] && mm_contains(mm, i);
- c[12] = c[12] && ms_contains(ms, i);
- }
-
- for (int i = -500; i < 1; i++)
- {
- a[0] = a[0] || d_contains(d, i, intcmp);
- a[1] = a[1] || hm_contains(hm, i);
- a[2] = a[2] || hs_contains(hs, i);
- a[3] = a[3] || h_contains(h, i);
- a[4] = a[4] || ll_contains(ll, i, intcmp);
- a[5] = a[5] || l_contains(l, i, intcmp);
- a[6] = a[6] || q_contains(q, i, intcmp);
- a[7] = a[7] || s_contains(s, i, intcmp);
- a[8] = a[8] || tm_contains(tm, i);
- a[9] = a[9] || ts_contains(ts, i);
-
- a[10] = a[10] || ih_contains(ih, i);
- a[11] = a[11] || mm_contains(mm, i);
- a[12] = a[12] || ms_contains(ms, i);
- }
-
- for (int i = 1001; i < 1500; i++)
- {
- a[0] = a[0] || d_contains(d, i, intcmp);
- a[1] = a[1] || hm_contains(hm, i);
- a[2] = a[2] || hs_contains(hs, i);
- a[3] = a[3] || h_contains(h, i);
- a[4] = a[4] || ll_contains(ll, i, intcmp);
- a[5] = a[5] || l_contains(l, i, intcmp);
- a[6] = a[6] || q_contains(q, i, intcmp);
- a[7] = a[7] || s_contains(s, i, intcmp);
- a[8] = a[8] || tm_contains(tm, i);
- a[9] = a[9] || ts_contains(ts, i);
-
- a[10] = a[10] || ih_contains(ih, i);
- a[11] = a[11] || mm_contains(mm, i);
- a[12] = a[12] || ms_contains(ms, i);
- }
-
- d_clear(d, NULL);
- hm_clear(hm, NULL);
- hs_clear(hs, NULL);
- h_clear(h, NULL);
- ll_clear(ll, NULL);
- l_clear(l, NULL);
- q_clear(q, NULL);
- s_clear(s, NULL);
- tm_clear(tm, NULL);
- ts_clear(ts, NULL);
-
- ih_clear(ih, NULL);
- mm_clear(mm, NULL);
- ms_clear(ms, NULL);
-
- b[0] = b[0] || d_contains(d, 1, intcmp);
- b[1] = b[1] || hm_contains(hm, 1);
- b[2] = b[2] || hs_contains(hs, 1);
- b[3] = b[3] || h_contains(h, 1);
- b[4] = b[4] || ll_contains(ll, 1, intcmp);
- b[5] = b[5] || l_contains(l, 1, intcmp);
- b[6] = b[6] || q_contains(q, 1, intcmp);
- b[7] = b[7] || s_contains(s, 1, intcmp);
- b[8] = b[8] || tm_contains(tm, 1);
- b[9] = b[9] || ts_contains(ts, 1);
-
- b[10] = b[10] || ih_contains(ih, 1);
- b[11] = b[11] || mm_contains(mm, 1);
- b[12] = b[12] || ms_contains(ms, 1);
-
- printf("-------------------- CONTAINS --------------------\n");
- if (c[0] && !a[0] && !b[0])
- printf("%12s PASSED\n", "DEQUE");
- else
- printf("%12s FAILED\n", "DEQUE");
- if (c[1] && !a[1] && !b[1])
- printf("%12s PASSED\n", "HASHMAP");
- else
- printf("%12s FAILED\n", "HASHMAP");
- if (c[2] && !a[2] && !b[2])
- printf("%12s PASSED\n", "HASHSET");
- else
- printf("%12s FAILED\n", "HASHSET");
- if (c[3] && !a[3] && !b[3])
- printf("%12s PASSED\n", "HEAP");
- else
- printf("%12s FAILED\n", "HEAP");
- if (c[4] && !a[4] && !b[4])
- printf("%12s PASSED\n", "LINKEDLIST");
- else
- printf("%12s FAILED\n", "LINKEDLIST");
- if (c[5] && !a[5] && !b[5])
- printf("%12s PASSED\n", "LIST");
- else
- printf("%12s FAILED\n", "LIST");
- if (c[6] && !a[6] && !b[6])
- printf("%12s PASSED\n", "QUEUE");
- else
- printf("%12s FAILED\n", "QUEUE");
- if (c[7] && !a[7] && !b[7])
- printf("%12s PASSED\n", "STACK");
- else
- printf("%12s FAILED\n", "STACK");
- if (c[8] && !a[8] && !b[8])
- printf("%12s PASSED\n", "TREEMAP");
- else
- printf("%12s FAILED\n", "TREEMAP");
- if (c[9] && !a[9] && !b[9])
- printf("%12s PASSED\n", "TREESET");
- else
- printf("%12s FAILED\n", "TREESET");
- if (c[10] && !a[10] && !b[10])
- printf("%12s PASSED\n", "INTERVALHEAP");
- else
- printf("%12s FAILED\n", "INTERVALHEAP");
- if (c[11] && !a[11] && !b[11])
- printf("%12s PASSED\n", "MULTIMAP");
- else
- printf("%12s FAILED\n", "MULTIMAP");
- if (c[12] && !a[12] && !b[12])
- printf("%12s PASSED\n", "MULTISET");
- else
- printf("%12s FAILED\n", "MULTISET");
-
- printf("\n\n");
-
- l_free(l, NULL);
- ll_free(ll, NULL);
- s_free(s, NULL);
- q_free(q, NULL);
- d_free(d, NULL);
- h_free(h, NULL);
- ts_free(ts, NULL);
- tm_free(tm, NULL);
- hs_free(hs, NULL);
- hm_free(hm, NULL);
-
- ih_free(ih, NULL);
- mm_free(mm, NULL);
- ms_free(ms, NULL);
-
- return 0;
-}
diff --git a/tests/foreach.c b/tests/foreach.c
deleted file mode 100644
index 120d249..0000000
--- a/tests/foreach.c
+++ /dev/null
@@ -1,286 +0,0 @@
-#include "../src/macro_collections.h"
-#include
-#include
-#include
-
-int intcmp(int a, int b)
-{
- return (a > b) - (a < b);
-}
-
-size_t inthash(int t)
-{
- size_t a = t;
- a += ~(a << 15);
- a ^= (a >> 10);
- a += (a << 3);
- a ^= (a >> 6);
- a += ~(a << 11);
- a ^= (a >> 16);
- return a;
-}
-
-CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
-CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
-CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
-CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
-CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
-CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
-CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int)
-CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
-CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int)
-
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, , int)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int)
-CMC_COLLECTION_GENERATE(MULTISET, ms, mset, , int)
-
-int main(void)
-{
- struct list *l = l_new(1000);
- struct stack *s = s_new(1000);
- struct queue *q = q_new(1000);
- struct deque *d = d_new(1000);
- struct linked *ll = ll_new();
- struct heap *h = h_new(1000, cmc_max_heap, intcmp);
- struct tset *ts = ts_new(intcmp);
- struct tmap *tm = tm_new(intcmp);
- struct hset *hs = hs_new(1000, 0.6, intcmp, inthash);
- struct hmap *hm = hm_new(1000, 0.6, intcmp, inthash);
- struct iheap *ih = ih_new(1000, intcmp);
- struct mmap *mm = mm_new(1000, 0.8, intcmp, inthash);
- struct mset *ms = ms_new(1000, 0.6, intcmp, inthash);
-
- bool p = true;
-
- for (int i = 1; i < 10001; i++)
- {
- if (i % 2 == 0)
- {
- assert(d_push_front(d, i));
- assert(l_push_front(l, i));
- assert(ll_push_front(ll, i));
- }
- else
- {
- assert(d_push_back(d, i));
- assert(l_push_back(l, i));
- assert(ll_push_back(ll, i));
- }
-
- assert(s_push(s, i));
- assert(q_enqueue(q, i));
- assert(h_insert(h, i));
- assert(ts_insert(ts, i));
- assert(tm_insert(tm, i, i));
- assert(hs_insert(hs, i));
- assert(hm_insert(hm, i, i));
-
- assert(ih_insert(ih, i));
- assert(mm_insert(mm, i, i));
- assert(ms_insert(ms, i));
- }
-
- int sums[16] = { 0 };
-
- CMC_FOR_EACH(d, deque, d, { sums[0] += d_iter_value(&iter); });
-
- CMC_FOR_EACH(hm, hmap, hm, {
- sums[1] += hm_iter_key(&iter);
- sums[2] += hm_iter_value(&iter);
- });
-
- CMC_FOR_EACH(hs, hset, hs, { sums[3] += hs_iter_value(&iter); });
-
- CMC_FOR_EACH(h, heap, h, { sums[4] += h_iter_value(&iter); });
-
- CMC_FOR_EACH(ll, linked, ll, { sums[5] += ll_iter_value(&iter); });
-
- CMC_FOR_EACH(l, list, l, { sums[6] += l_iter_value(&iter); });
-
- CMC_FOR_EACH(q, queue, q, { sums[7] += q_iter_value(&iter); });
-
- CMC_FOR_EACH(s, stack, s, { sums[8] += s_iter_value(&iter); });
-
- CMC_FOR_EACH(tm, tmap, tm, {
- sums[9] += tm_iter_key(&iter);
- sums[10] += tm_iter_value(&iter);
- });
-
- CMC_FOR_EACH(ts, tset, ts, { sums[11] += ts_iter_value(&iter); });
-
- CMC_FOR_EACH(ih, iheap, ih, { sums[12] += ih_iter_value(&iter); });
-
- CMC_FOR_EACH(mm, mmap, mm, {
- sums[13] += mm_iter_key(&iter);
- sums[14] += mm_iter_value(&iter);
- });
-
- CMC_FOR_EACH(ms, mset, ms, { sums[15] += ms_iter_value(&iter); });
-
- printf("\n-------------------- CMC_FOR_EACH --------------------\n");
- if (sums[0] == 50005000)
- printf("%12s PASSED\n", "DEQUE");
- else
- printf("%12s FAILED\n", "DEQUE");
- if (sums[1] == 50005000 && sums[2] == 50005000)
- printf("%12s PASSED\n", "HASHMAP");
- else
- printf("%12s FAILED\n", "HASHMAP");
- if (sums[3] == 50005000)
- printf("%12s PASSED\n", "HASHSET");
- else
- printf("%12s FAILED\n", "HASHSET");
- if (sums[4] == 50005000)
- printf("%12s PASSED\n", "HEAP");
- else
- printf("%12s FAILED\n", "HEAP");
- if (sums[5] == 50005000)
- printf("%12s PASSED\n", "LINKEDLIST");
- else
- printf("%12s FAILED\n", "LINKEDLIST");
- if (sums[6] == 50005000)
- printf("%12s PASSED\n", "LIST");
- else
- printf("%12s FAILED\n", "LIST");
- if (sums[7] == 50005000)
- printf("%12s PASSED\n", "QUEUE");
- else
- printf("%12s FAILED\n", "QUEUE");
- if (sums[8] == 50005000)
- printf("%12s PASSED\n", "STACK");
- else
- printf("%12s FAILED\n", "STACK");
- if (sums[9] == 50005000 && sums[10] == 50005000)
- printf("%12s PASSED\n", "TREEMAP");
- else
- printf("%12s FAILED\n", "TREEMAP");
- if (sums[11] == 50005000)
- printf("%12s PASSED\n", "TREESET");
- else
- printf("%12s FAILED\n", "TREESET");
- if (sums[12] == 50005000)
- printf("%12s PASSED\n", "INTERVALHEAP");
- else
- printf("%12s FAILED\n", "INTERVALHEAP");
- if (sums[13] == 50005000 && sums[14] == 50005000)
- printf("%12s PASSED\n", "MULTIMAP");
- else
- printf("%12s FAILED\n", "MULTIMAP");
- if (sums[15] == 50005000)
- printf("%12s PASSED\n", "MULTISET");
- else
- printf("%12s FAILED\n", "MULTISET");
-
- printf("\n\n");
-
- memset(sums, 0, sizeof sums);
-
- CMC_FOR_EACH_REV(d, deque, d, { sums[0] += d_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(hm, hmap, hm, {
- sums[1] += hm_iter_key(&iter);
- sums[2] += hm_iter_value(&iter);
- });
-
- CMC_FOR_EACH_REV(hs, hset, hs, { sums[3] += hs_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(h, heap, h, { sums[4] += h_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(ll, linked, ll, { sums[5] += ll_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(l, list, l, { sums[6] += l_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(q, queue, q, { sums[7] += q_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(s, stack, s, { sums[8] += s_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(tm, tmap, tm, {
- sums[9] += tm_iter_key(&iter);
- sums[10] += tm_iter_value(&iter);
- });
-
- CMC_FOR_EACH_REV(ts, tset, ts, { sums[11] += ts_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(ih, iheap, ih, { sums[12] += ih_iter_value(&iter); });
-
- CMC_FOR_EACH_REV(mm, mmap, mm, {
- sums[13] += mm_iter_key(&iter);
- sums[14] += mm_iter_value(&iter);
- });
-
- CMC_FOR_EACH_REV(ms, mset, ms, { sums[15] += ms_iter_value(&iter); });
-
- printf("-------------------- CMC_FOR_EACH_REV --------------------\n");
- if (sums[0] == 50005000)
- printf("%12s PASSED\n", "DEQUE");
- else
- printf("%12s FAILED\n", "DEQUE");
- if (sums[1] == 50005000 && sums[2] == 50005000)
- printf("%12s PASSED\n", "HASHMAP");
- else
- printf("%12s FAILED\n", "HASHMAP");
- if (sums[3] == 50005000)
- printf("%12s PASSED\n", "HASHSET");
- else
- printf("%12s FAILED\n", "HASHSET");
- if (sums[4] == 50005000)
- printf("%12s PASSED\n", "HEAP");
- else
- printf("%12s FAILED\n", "HEAP");
- if (sums[5] == 50005000)
- printf("%12s PASSED\n", "LINKEDLIST");
- else
- printf("%12s FAILED\n", "LINKEDLIST");
- if (sums[6] == 50005000)
- printf("%12s PASSED\n", "LIST");
- else
- printf("%12s FAILED\n", "LIST");
- if (sums[7] == 50005000)
- printf("%12s PASSED\n", "QUEUE");
- else
- printf("%12s FAILED\n", "QUEUE");
- if (sums[8] == 50005000)
- printf("%12s PASSED\n", "STACK");
- else
- printf("%12s FAILED\n", "STACK");
- if (sums[9] == 50005000 && sums[10] == 50005000)
- printf("%12s PASSED\n", "TREEMAP");
- else
- printf("%12s FAILED\n", "TREEMAP");
- if (sums[11] == 50005000)
- printf("%12s PASSED\n", "TREESET");
- else
- printf("%12s FAILED\n", "TREESET");
- if (sums[12] == 50005000)
- printf("%12s PASSED\n", "INTERVALHEAP");
- else
- printf("%12s FAILED\n", "INTERVALHEAP");
- if (sums[13] == 50005000 && sums[14] == 50005000)
- printf("%12s PASSED\n", "MULTIMAP");
- else
- printf("%12s FAILED\n", "MULTIMAP");
- if (sums[15] == 50005000)
- printf("%12s PASSED\n", "MULTISET");
- else
- printf("%12s FAILED\n", "MULTISET");
-
- printf("\n\n");
-
- l_free(l, NULL);
- ll_free(ll, NULL);
- s_free(s, NULL);
- q_free(q, NULL);
- d_free(d, NULL);
- h_free(h, NULL);
- ts_free(ts, NULL);
- tm_free(tm, NULL);
- hs_free(hs, NULL);
- hm_free(hm, NULL);
-
- ih_free(ih, NULL);
- mm_free(mm, NULL);
- ms_free(ms, NULL);
-
- return 0;
-}
diff --git a/tests/include/cmc/bitset.h b/tests/include/cmc/bitset.h
new file mode 100644
index 0000000..0c693e0
--- /dev/null
+++ b/tests/include/cmc/bitset.h
@@ -0,0 +1,44 @@
+
+#ifndef CMC_CMC_BITSET_TEST_H
+#define CMC_CMC_BITSET_TEST_H
+
+#include "macro_collections.h"
+
+struct bitset
+{
+ cmc_bitset_word *buffer;
+ size_t capacity;
+ size_t count;
+ int flag;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct bitset_iter
+{
+ struct bitset *target;
+ size_t cursor;
+ _Bool start;
+ _Bool end;
+};
+struct bitset *bs_new(size_t n_bits);
+struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+struct bitset bs_init(size_t n_bits);
+struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+void bs_free(struct bitset *_bitset_);
+void bs_release(struct bitset _bitset_);
+void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool bs_set(struct bitset *_bitset_, size_t bit_index);
+_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to);
+_Bool bs_clear(struct bitset *_bitset_, size_t bit_index);
+_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to);
+_Bool bs_flip(struct bitset *_bitset_, size_t bit_index);
+_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to);
+_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state);
+_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to, _Bool state);
+_Bool bs_set_all(struct bitset *_bitset_);
+_Bool bs_clear_all(struct bitset *_bitset_);
+_Bool bs_flip_all(struct bitset *_bitset_);
+_Bool bs_get(struct bitset *_bitset_, size_t bit_index);
+_Bool bs_resize(struct bitset *_bitset_, size_t n_bits);
+
+#endif /* CMC_CMC_BITSET_TEST_H */
diff --git a/tests/include/cmc/deque.h b/tests/include/cmc/deque.h
new file mode 100644
index 0000000..b664e2a
--- /dev/null
+++ b/tests/include/cmc/deque.h
@@ -0,0 +1,78 @@
+
+#ifndef CMC_CMC_DEQUE_TEST_H
+#define CMC_CMC_DEQUE_TEST_H
+
+#include "macro_collections.h"
+
+struct deque
+{
+ size_t *buffer;
+ size_t capacity;
+ size_t count;
+ size_t front;
+ size_t back;
+ int flag;
+ struct deque_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct deque_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct deque *d_new(size_t capacity, struct deque_fval *f_val);
+struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void d_clear(struct deque *_deque_);
+void d_free(struct deque *_deque_);
+void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool d_push_front(struct deque *_deque_, size_t value);
+_Bool d_push_back(struct deque *_deque_, size_t value);
+_Bool d_pop_front(struct deque *_deque_);
+_Bool d_pop_back(struct deque *_deque_);
+size_t d_front(struct deque *_deque_);
+size_t d_back(struct deque *_deque_);
+_Bool d_contains(struct deque *_deque_, size_t value);
+_Bool d_empty(struct deque *_deque_);
+_Bool d_full(struct deque *_deque_);
+size_t d_count(struct deque *_deque_);
+size_t d_capacity(struct deque *_deque_);
+int d_flag(struct deque *_deque_);
+_Bool d_resize(struct deque *_deque_, size_t capacity);
+struct deque *d_copy_of(struct deque *_deque_);
+_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_);
+struct deque d_init(size_t capacity, struct deque_fval *f_val);
+struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void d_release(struct deque _deque_);
+struct deque_iter
+{
+ struct deque *target;
+ size_t cursor;
+ size_t index;
+ _Bool start;
+ _Bool end;
+};
+struct deque_iter d_iter_start(struct deque *target);
+struct deque_iter d_iter_end(struct deque *target);
+_Bool d_iter_at_start(struct deque_iter *iter);
+_Bool d_iter_at_end(struct deque_iter *iter);
+_Bool d_iter_to_start(struct deque_iter *iter);
+_Bool d_iter_to_end(struct deque_iter *iter);
+_Bool d_iter_next(struct deque_iter *iter);
+_Bool d_iter_prev(struct deque_iter *iter);
+_Bool d_iter_advance(struct deque_iter *iter, size_t steps);
+_Bool d_iter_rewind(struct deque_iter *iter, size_t steps);
+_Bool d_iter_go_to(struct deque_iter *iter, size_t index);
+size_t d_iter_value(struct deque_iter *iter);
+size_t *d_iter_rvalue(struct deque_iter *iter);
+size_t d_iter_index(struct deque_iter *iter);
+_Bool d_to_string(struct deque *_deque_, FILE *fptr);
+_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_DEQUE_TEST_H */
diff --git a/tests/include/cmc/hashbidimap.h b/tests/include/cmc/hashbidimap.h
new file mode 100644
index 0000000..c574437
--- /dev/null
+++ b/tests/include/cmc/hashbidimap.h
@@ -0,0 +1,101 @@
+
+#ifndef CMC_CMC_HASHBIDIMAP_TEST_H
+#define CMC_CMC_HASHBIDIMAP_TEST_H
+
+#include "macro_collections.h"
+
+struct hashbidimap
+{
+ struct hashbidimap_entry *(*buffer)[2];
+ size_t capacity;
+ size_t count;
+ double load;
+ int flag;
+ struct hashbidimap_fkey *f_key;
+ struct hashbidimap_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+ struct hashbidimap_iter (*it_start)(struct hashbidimap *);
+ struct hashbidimap_iter (*it_end)(struct hashbidimap *);
+};
+struct hashbidimap_entry
+{
+ size_t key;
+ size_t value;
+ size_t dist[2];
+ struct hashbidimap_entry **ref[2];
+};
+struct hashbidimap_fkey
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashbidimap_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashbidimap_iter
+{
+ struct hashbidimap *target;
+ size_t cursor;
+ size_t index;
+ size_t first;
+ size_t last;
+ _Bool start;
+ _Bool end;
+};
+struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key,
+ struct hashbidimap_fval *f_val);
+struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key,
+ struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void hbm_clear(struct hashbidimap *_map_);
+void hbm_free(struct hashbidimap *_map_);
+void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value);
+_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key);
+_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val);
+_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val);
+_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val);
+size_t hbm_get_key(struct hashbidimap *_map_, size_t val);
+size_t hbm_get_val(struct hashbidimap *_map_, size_t key);
+_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key);
+_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val);
+_Bool hbm_empty(struct hashbidimap *_map_);
+_Bool hbm_full(struct hashbidimap *_map_);
+size_t hbm_count(struct hashbidimap *_map_);
+size_t hbm_capacity(struct hashbidimap *_map_);
+double hbm_load(struct hashbidimap *_map_);
+int hbm_flag(struct hashbidimap *_map_);
+_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity);
+struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_);
+_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_);
+struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target);
+void hbm_iter_free(struct hashbidimap_iter *iter);
+void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target);
+_Bool hbm_iter_start(struct hashbidimap_iter *iter);
+_Bool hbm_iter_end(struct hashbidimap_iter *iter);
+void hbm_iter_to_start(struct hashbidimap_iter *iter);
+void hbm_iter_to_end(struct hashbidimap_iter *iter);
+_Bool hbm_iter_next(struct hashbidimap_iter *iter);
+_Bool hbm_iter_prev(struct hashbidimap_iter *iter);
+_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps);
+_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps);
+_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index);
+size_t hbm_iter_key(struct hashbidimap_iter *iter);
+size_t hbm_iter_value(struct hashbidimap_iter *iter);
+size_t hbm_iter_index(struct hashbidimap_iter *iter);
+_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr);
+_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep);
+
+#endif /* CMC_CMC_HASHBIDIMAP_TEST_H */
diff --git a/tests/include/cmc/hashmap.h b/tests/include/cmc/hashmap.h
new file mode 100644
index 0000000..5bb61eb
--- /dev/null
+++ b/tests/include/cmc/hashmap.h
@@ -0,0 +1,100 @@
+
+#ifndef CMC_CMC_HASHMAP_TEST_H
+#define CMC_CMC_HASHMAP_TEST_H
+
+#include "macro_collections.h"
+
+struct hashmap
+{
+ struct hashmap_entry *buffer;
+ size_t capacity;
+ size_t count;
+ double load;
+ int flag;
+ struct hashmap_fkey *f_key;
+ struct hashmap_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct hashmap_entry
+{
+ size_t key;
+ size_t value;
+ size_t dist;
+ enum cmc_entry_state state;
+};
+struct hashmap_fkey
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashmap_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val);
+struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+void hm_clear(struct hashmap *_map_);
+void hm_free(struct hashmap *_map_);
+void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value);
+_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value);
+_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value);
+_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value);
+_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value);
+size_t hm_get(struct hashmap *_map_, size_t key);
+size_t *hm_get_ref(struct hashmap *_map_, size_t key);
+_Bool hm_contains(struct hashmap *_map_, size_t key);
+_Bool hm_empty(struct hashmap *_map_);
+_Bool hm_full(struct hashmap *_map_);
+size_t hm_count(struct hashmap *_map_);
+size_t hm_capacity(struct hashmap *_map_);
+double hm_load(struct hashmap *_map_);
+int hm_flag(struct hashmap *_map_);
+_Bool hm_resize(struct hashmap *_map_, size_t capacity);
+struct hashmap *hm_copy_of(struct hashmap *_map_);
+_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_);
+struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val);
+struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+void hm_release(struct hashmap _map_);
+struct hashmap_iter
+{
+ struct hashmap *target;
+ size_t cursor;
+ size_t index;
+ size_t first;
+ size_t last;
+ _Bool start;
+ _Bool end;
+};
+struct hashmap_iter hm_iter_start(struct hashmap *target);
+struct hashmap_iter hm_iter_end(struct hashmap *target);
+_Bool hm_iter_at_start(struct hashmap_iter *iter);
+_Bool hm_iter_at_end(struct hashmap_iter *iter);
+_Bool hm_iter_to_start(struct hashmap_iter *iter);
+_Bool hm_iter_to_end(struct hashmap_iter *iter);
+_Bool hm_iter_next(struct hashmap_iter *iter);
+_Bool hm_iter_prev(struct hashmap_iter *iter);
+_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps);
+_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps);
+_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index);
+size_t hm_iter_key(struct hashmap_iter *iter);
+size_t hm_iter_value(struct hashmap_iter *iter);
+size_t *hm_iter_rvalue(struct hashmap_iter *iter);
+size_t hm_iter_index(struct hashmap_iter *iter);
+_Bool hm_to_string(struct hashmap *_map_, FILE *fptr);
+_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep);
+
+#endif /* CMC_CMC_HASHMAP_TEST_H */
diff --git a/tests/include/cmc/hashmultimap.h b/tests/include/cmc/hashmultimap.h
new file mode 100644
index 0000000..7b44266
--- /dev/null
+++ b/tests/include/cmc/hashmultimap.h
@@ -0,0 +1,102 @@
+
+#ifndef CMC_CMC_HASHMULTIMAP_TEST_H
+#define CMC_CMC_HASHMULTIMAP_TEST_H
+
+#include "macro_collections.h"
+
+struct hashmultimap
+{
+ struct hashmultimap_entry *(*buffer)[2];
+ size_t capacity;
+ size_t count;
+ double load;
+ int flag;
+ struct hashmultimap_fkey *f_key;
+ struct hashmultimap_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct hashmultimap_entry
+{
+ size_t key;
+ size_t value;
+ struct hashmultimap_entry *next;
+ struct hashmultimap_entry *prev;
+};
+struct hashmultimap_fkey
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashmultimap_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key,
+ struct hashmultimap_fval *f_val);
+struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key,
+ struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void hmm_clear(struct hashmultimap *_map_);
+void hmm_free(struct hashmultimap *_map_);
+void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value);
+_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value);
+size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values);
+_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value);
+size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values);
+_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value);
+_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value);
+size_t hmm_get(struct hashmultimap *_map_, size_t key);
+size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key);
+_Bool hmm_contains(struct hashmultimap *_map_, size_t key);
+_Bool hmm_empty(struct hashmultimap *_map_);
+_Bool hmm_full(struct hashmultimap *_map_);
+size_t hmm_count(struct hashmultimap *_map_);
+size_t hmm_key_count(struct hashmultimap *_map_, size_t key);
+size_t hmm_capacity(struct hashmultimap *_map_);
+double hmm_load(struct hashmultimap *_map_);
+int hmm_flag(struct hashmultimap *_map_);
+_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity);
+struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_);
+_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_);
+struct hashmultimap_iter
+{
+ struct hashmultimap *target;
+ struct hashmultimap_entry *curr_entry;
+ size_t cursor;
+ size_t index;
+ size_t first;
+ size_t last;
+ _Bool start;
+ _Bool end;
+};
+struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target);
+struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target);
+_Bool hmm_iter_at_start(struct hashmultimap_iter *iter);
+_Bool hmm_iter_at_end(struct hashmultimap_iter *iter);
+_Bool hmm_iter_to_start(struct hashmultimap_iter *iter);
+_Bool hmm_iter_to_end(struct hashmultimap_iter *iter);
+_Bool hmm_iter_next(struct hashmultimap_iter *iter);
+_Bool hmm_iter_prev(struct hashmultimap_iter *iter);
+_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps);
+_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps);
+_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index);
+size_t hmm_iter_key(struct hashmultimap_iter *iter);
+size_t hmm_iter_value(struct hashmultimap_iter *iter);
+size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter);
+size_t hmm_iter_index(struct hashmultimap_iter *iter);
+_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr);
+_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep);
+
+#endif /* CMC_CMC_HASHMULTIMAP_TEST_H */
diff --git a/tests/include/cmc/hashmultiset.h b/tests/include/cmc/hashmultiset.h
new file mode 100644
index 0000000..6ab4627
--- /dev/null
+++ b/tests/include/cmc/hashmultiset.h
@@ -0,0 +1,98 @@
+
+#ifndef CMC_CMC_HASHMULTISET_TEST_H
+#define CMC_CMC_HASHMULTISET_TEST_H
+
+#include "macro_collections.h"
+
+struct hashmultiset
+{
+ struct hashmultiset_entry *buffer;
+ size_t capacity;
+ size_t count;
+ size_t cardinality;
+ double load;
+ int flag;
+ struct hashmultiset_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct hashmultiset_entry
+{
+ size_t value;
+ size_t multiplicity;
+ size_t dist;
+ enum cmc_entry_state state;
+};
+struct hashmultiset_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val);
+struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+void hms_clear(struct hashmultiset *_set_);
+void hms_free(struct hashmultiset *_set_);
+void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool hms_insert(struct hashmultiset *_set_, size_t value);
+_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count);
+_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity);
+_Bool hms_remove(struct hashmultiset *_set_, size_t value);
+size_t hms_remove_all(struct hashmultiset *_set_, size_t value);
+_Bool hms_max(struct hashmultiset *_set_, size_t *value);
+_Bool hms_min(struct hashmultiset *_set_, size_t *value);
+size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value);
+_Bool hms_contains(struct hashmultiset *_set_, size_t value);
+_Bool hms_empty(struct hashmultiset *_set_);
+_Bool hms_full(struct hashmultiset *_set_);
+size_t hms_count(struct hashmultiset *_set_);
+size_t hms_cardinality(struct hashmultiset *_set_);
+size_t hms_capacity(struct hashmultiset *_set_);
+double hms_load(struct hashmultiset *_set_);
+int hms_flag(struct hashmultiset *_set_);
+_Bool hms_resize(struct hashmultiset *_set_, size_t capacity);
+struct hashmultiset *hms_copy_of(struct hashmultiset *_set_);
+_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+struct hashmultiset_iter
+{
+ struct hashmultiset *target;
+ size_t cursor;
+ size_t index;
+ size_t first;
+ size_t last;
+ _Bool start;
+ _Bool end;
+};
+struct hashmultiset_iter hms_iter_start(struct hashmultiset *target);
+struct hashmultiset_iter hms_iter_end(struct hashmultiset *target);
+_Bool hms_iter_at_start(struct hashmultiset_iter *iter);
+_Bool hms_iter_at_end(struct hashmultiset_iter *iter);
+_Bool hms_iter_to_start(struct hashmultiset_iter *iter);
+_Bool hms_iter_to_end(struct hashmultiset_iter *iter);
+_Bool hms_iter_next(struct hashmultiset_iter *iter);
+_Bool hms_iter_prev(struct hashmultiset_iter *iter);
+_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps);
+_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps);
+_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index);
+size_t hms_iter_value(struct hashmultiset_iter *iter);
+size_t hms_iter_multiplicity(struct hashmultiset_iter *iter);
+size_t hms_iter_index(struct hashmultiset_iter *iter);
+struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
+_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr);
+_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep);
+
+#endif /* CMC_CMC_HASHMULTISET_TEST_H */
diff --git a/tests/include/cmc/hashset.h b/tests/include/cmc/hashset.h
new file mode 100644
index 0000000..a9ab75c
--- /dev/null
+++ b/tests/include/cmc/hashset.h
@@ -0,0 +1,88 @@
+
+#ifndef CMC_CMC_HASHSET_TEST_H
+#define CMC_CMC_HASHSET_TEST_H
+
+#include "macro_collections.h"
+
+struct hashset
+{
+ struct hashset_entry *buffer;
+ size_t capacity;
+ size_t count;
+ double load;
+ int flag;
+ struct hashset_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct hashset_entry
+{
+ size_t value;
+ size_t dist;
+ enum cmc_entry_state state;
+};
+struct hashset_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val);
+struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void hs_clear(struct hashset *_set_);
+void hs_free(struct hashset *_set_);
+void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool hs_insert(struct hashset *_set_, size_t value);
+_Bool hs_remove(struct hashset *_set_, size_t value);
+_Bool hs_max(struct hashset *_set_, size_t *value);
+_Bool hs_min(struct hashset *_set_, size_t *value);
+_Bool hs_contains(struct hashset *_set_, size_t value);
+_Bool hs_empty(struct hashset *_set_);
+_Bool hs_full(struct hashset *_set_);
+size_t hs_count(struct hashset *_set_);
+size_t hs_capacity(struct hashset *_set_);
+double hs_load(struct hashset *_set_);
+int hs_flag(struct hashset *_set_);
+_Bool hs_resize(struct hashset *_set_, size_t capacity);
+struct hashset *hs_copy_of(struct hashset *_set_);
+_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_);
+struct hashset_iter
+{
+ struct hashset *target;
+ size_t cursor;
+ size_t index;
+ size_t first;
+ size_t last;
+ _Bool start;
+ _Bool end;
+};
+struct hashset_iter hs_iter_start(struct hashset *target);
+struct hashset_iter hs_iter_end(struct hashset *target);
+_Bool hs_iter_at_start(struct hashset_iter *iter);
+_Bool hs_iter_at_end(struct hashset_iter *iter);
+_Bool hs_iter_to_start(struct hashset_iter *iter);
+_Bool hs_iter_to_end(struct hashset_iter *iter);
+_Bool hs_iter_next(struct hashset_iter *iter);
+_Bool hs_iter_prev(struct hashset_iter *iter);
+_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps);
+_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps);
+_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index);
+size_t hs_iter_value(struct hashset_iter *iter);
+size_t hs_iter_index(struct hashset_iter *iter);
+struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_);
+struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_);
+struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_);
+struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_);
+_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_);
+_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_);
+_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_);
+_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_);
+_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_);
+_Bool hs_to_string(struct hashset *_set_, FILE *fptr);
+_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_HASHSET_TEST_H */
diff --git a/tests/include/cmc/heap.h b/tests/include/cmc/heap.h
new file mode 100644
index 0000000..8b062f1
--- /dev/null
+++ b/tests/include/cmc/heap.h
@@ -0,0 +1,68 @@
+
+#ifndef CMC_CMC_HEAP_TEST_H
+#define CMC_CMC_HEAP_TEST_H
+
+#include "macro_collections.h"
+
+struct heap
+{
+ size_t *buffer;
+ size_t capacity;
+ size_t count;
+ enum cmc_heap_order HO;
+ int flag;
+ struct heap_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct heap_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val);
+struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+void h_clear(struct heap *_heap_);
+void h_free(struct heap *_heap_);
+void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool h_insert(struct heap *_heap_, size_t value);
+_Bool h_remove(struct heap *_heap_);
+size_t h_peek(struct heap *_heap_);
+_Bool h_contains(struct heap *_heap_, size_t value);
+_Bool h_empty(struct heap *_heap_);
+_Bool h_full(struct heap *_heap_);
+size_t h_count(struct heap *_heap_);
+size_t h_capacity(struct heap *_heap_);
+int h_flag(struct heap *_heap_);
+_Bool h_resize(struct heap *_heap_, size_t capacity);
+struct heap *h_copy_of(struct heap *_heap_);
+_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_);
+struct heap_iter
+{
+ struct heap *target;
+ size_t cursor;
+ _Bool start;
+ _Bool end;
+};
+struct heap_iter h_iter_start(struct heap *target);
+struct heap_iter h_iter_end(struct heap *target);
+_Bool h_iter_at_start(struct heap_iter *iter);
+_Bool h_iter_at_end(struct heap_iter *iter);
+_Bool h_iter_to_start(struct heap_iter *iter);
+_Bool h_iter_to_end(struct heap_iter *iter);
+_Bool h_iter_next(struct heap_iter *iter);
+_Bool h_iter_prev(struct heap_iter *iter);
+_Bool h_iter_advance(struct heap_iter *iter, size_t steps);
+_Bool h_iter_rewind(struct heap_iter *iter, size_t steps);
+_Bool h_iter_go_to(struct heap_iter *iter, size_t index);
+size_t h_iter_value(struct heap_iter *iter);
+size_t h_iter_index(struct heap_iter *iter);
+_Bool h_to_string(struct heap *_heap_, FILE *fptr);
+_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_HEAP_TEST_H */
diff --git a/tests/include/cmc/intervalheap.h b/tests/include/cmc/intervalheap.h
new file mode 100644
index 0000000..5bc4fb2
--- /dev/null
+++ b/tests/include/cmc/intervalheap.h
@@ -0,0 +1,72 @@
+
+#ifndef CMC_CMC_INTERVALHEAP_TEST_H
+#define CMC_CMC_INTERVALHEAP_TEST_H
+
+#include "macro_collections.h"
+
+struct intervalheap
+{
+ size_t (*buffer)[2];
+ size_t capacity;
+ size_t size;
+ size_t count;
+ int flag;
+ struct intervalheap_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct intervalheap_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val);
+struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void ih_clear(struct intervalheap *_heap_);
+void ih_free(struct intervalheap *_heap_);
+void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool ih_insert(struct intervalheap *_heap_, size_t value);
+_Bool ih_remove_max(struct intervalheap *_heap_);
+_Bool ih_remove_min(struct intervalheap *_heap_);
+_Bool ih_update_max(struct intervalheap *_heap_, size_t value);
+_Bool ih_update_min(struct intervalheap *_heap_, size_t value);
+size_t ih_max(struct intervalheap *_heap_);
+size_t ih_min(struct intervalheap *_heap_);
+_Bool ih_contains(struct intervalheap *_heap_, size_t value);
+_Bool ih_empty(struct intervalheap *_heap_);
+_Bool ih_full(struct intervalheap *_heap_);
+size_t ih_count(struct intervalheap *_heap_);
+size_t ih_capacity(struct intervalheap *_heap_);
+int ih_flag(struct intervalheap *_heap_);
+_Bool ih_resize(struct intervalheap *_heap_, size_t capacity);
+struct intervalheap *ih_copy_of(struct intervalheap *_heap_);
+_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_);
+struct intervalheap_iter
+{
+ struct intervalheap *target;
+ size_t cursor;
+ _Bool start;
+ _Bool end;
+};
+struct intervalheap_iter ih_iter_start(struct intervalheap *target);
+struct intervalheap_iter ih_iter_end(struct intervalheap *target);
+_Bool ih_iter_at_start(struct intervalheap_iter *iter);
+_Bool ih_iter_at_end(struct intervalheap_iter *iter);
+_Bool ih_iter_to_start(struct intervalheap_iter *iter);
+_Bool ih_iter_to_end(struct intervalheap_iter *iter);
+_Bool ih_iter_next(struct intervalheap_iter *iter);
+_Bool ih_iter_prev(struct intervalheap_iter *iter);
+_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps);
+_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps);
+_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index);
+size_t ih_iter_value(struct intervalheap_iter *iter);
+size_t ih_iter_index(struct intervalheap_iter *iter);
+_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr);
+_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_INTERVALHEAP_TEST_H */
diff --git a/tests/include/cmc/linkedlist.h b/tests/include/cmc/linkedlist.h
new file mode 100644
index 0000000..c06925d
--- /dev/null
+++ b/tests/include/cmc/linkedlist.h
@@ -0,0 +1,92 @@
+
+#ifndef CMC_CMC_LINKEDLIST_TEST_H
+#define CMC_CMC_LINKEDLIST_TEST_H
+
+#include "macro_collections.h"
+
+struct linkedlist
+{
+ struct linkedlist_node *head;
+ struct linkedlist_node *tail;
+ size_t count;
+ int flag;
+ struct linkedlist_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct linkedlist_node
+{
+ size_t value;
+ struct linkedlist_node *next;
+ struct linkedlist_node *prev;
+};
+struct linkedlist_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct linkedlist *ll_new(struct linkedlist_fval *f_val);
+struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void ll_clear(struct linkedlist *_list_);
+void ll_free(struct linkedlist *_list_);
+void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool ll_push_front(struct linkedlist *_list_, size_t value);
+_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index);
+_Bool ll_push_back(struct linkedlist *_list_, size_t value);
+_Bool ll_pop_front(struct linkedlist *_list_);
+_Bool ll_pop_at(struct linkedlist *_list_, size_t index);
+_Bool ll_pop_back(struct linkedlist *_list_);
+size_t ll_front(struct linkedlist *_list_);
+size_t ll_get(struct linkedlist *_list_, size_t index);
+size_t *ll_get_ref(struct linkedlist *_list_, size_t index);
+size_t ll_back(struct linkedlist *_list_);
+_Bool ll_contains(struct linkedlist *_list_, size_t value);
+_Bool ll_empty(struct linkedlist *_list_);
+size_t ll_count(struct linkedlist *_list_);
+int ll_flag(struct linkedlist *_list_);
+struct linkedlist *ll_copy_of(struct linkedlist *_list_);
+_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_);
+struct linkedlist_iter
+{
+ struct linkedlist *target;
+ struct linkedlist_node *cursor;
+ size_t index;
+ _Bool start;
+ _Bool end;
+};
+struct linkedlist_iter ll_iter_start(struct linkedlist *target);
+struct linkedlist_iter ll_iter_end(struct linkedlist *target);
+_Bool ll_iter_at_start(struct linkedlist_iter *iter);
+_Bool ll_iter_at_end(struct linkedlist_iter *iter);
+_Bool ll_iter_to_start(struct linkedlist_iter *iter);
+_Bool ll_iter_to_end(struct linkedlist_iter *iter);
+_Bool ll_iter_next(struct linkedlist_iter *iter);
+_Bool ll_iter_prev(struct linkedlist_iter *iter);
+_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps);
+_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps);
+_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index);
+size_t ll_iter_value(struct linkedlist_iter *iter);
+size_t *ll_iter_rvalue(struct linkedlist_iter *iter);
+size_t ll_iter_index(struct linkedlist_iter *iter);
+struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter);
+struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value);
+void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_);
+struct linkedlist_node *ll_head(struct linkedlist *_list_);
+struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index);
+struct linkedlist_node *ll_tail(struct linkedlist *_list_);
+_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value);
+_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value);
+_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_);
+_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_);
+_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_);
+struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_);
+struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_);
+_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr);
+_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_LINKEDLIST_TEST_H */
diff --git a/tests/include/cmc/list.h b/tests/include/cmc/list.h
new file mode 100644
index 0000000..3a1043d
--- /dev/null
+++ b/tests/include/cmc/list.h
@@ -0,0 +1,82 @@
+
+#ifndef CMC_CMC_LIST_TEST_H
+#define CMC_CMC_LIST_TEST_H
+
+#include "macro_collections.h"
+
+struct list
+{
+ size_t *buffer;
+ size_t capacity;
+ size_t count;
+ int flag;
+ struct list_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct list_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct list *l_new(size_t capacity, struct list_fval *f_val);
+struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void l_clear(struct list *_list_);
+void l_free(struct list *_list_);
+void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool l_push_front(struct list *_list_, size_t value);
+_Bool l_push_at(struct list *_list_, size_t value, size_t index);
+_Bool l_push_back(struct list *_list_, size_t value);
+_Bool l_pop_front(struct list *_list_);
+_Bool l_pop_at(struct list *_list_, size_t index);
+_Bool l_pop_back(struct list *_list_);
+size_t l_front(struct list *_list_);
+size_t l_get(struct list *_list_, size_t index);
+size_t *l_get_ref(struct list *_list_, size_t index);
+size_t l_back(struct list *_list_);
+size_t l_index_of(struct list *_list_, size_t value, _Bool from_start);
+_Bool l_contains(struct list *_list_, size_t value);
+_Bool l_empty(struct list *_list_);
+_Bool l_full(struct list *_list_);
+size_t l_count(struct list *_list_);
+_Bool l_fits(struct list *_list_, size_t size);
+size_t l_capacity(struct list *_list_);
+int l_flag(struct list *_list_);
+_Bool l_resize(struct list *_list_, size_t capacity);
+struct list *l_copy_of(struct list *_list_);
+_Bool l_equals(struct list *_list1_, struct list *_list2_);
+struct list_iter
+{
+ struct list *target;
+ size_t cursor;
+ _Bool start;
+ _Bool end;
+};
+struct list_iter l_iter_start(struct list *target);
+struct list_iter l_iter_end(struct list *target);
+_Bool l_iter_at_start(struct list_iter *iter);
+_Bool l_iter_at_end(struct list_iter *iter);
+_Bool l_iter_to_start(struct list_iter *iter);
+_Bool l_iter_to_end(struct list_iter *iter);
+_Bool l_iter_next(struct list_iter *iter);
+_Bool l_iter_prev(struct list_iter *iter);
+_Bool l_iter_advance(struct list_iter *iter, size_t steps);
+_Bool l_iter_rewind(struct list_iter *iter, size_t steps);
+_Bool l_iter_go_to(struct list_iter *iter, size_t index);
+size_t l_iter_value(struct list_iter *iter);
+size_t *l_iter_rvalue(struct list_iter *iter);
+size_t l_iter_index(struct list_iter *iter);
+_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size);
+_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index);
+_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size);
+_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to);
+struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to);
+_Bool l_to_string(struct list *_list_, FILE *fptr);
+_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_LIST_TEST_H */
diff --git a/tests/include/cmc/queue.h b/tests/include/cmc/queue.h
new file mode 100644
index 0000000..1fcd7b1
--- /dev/null
+++ b/tests/include/cmc/queue.h
@@ -0,0 +1,71 @@
+
+#ifndef CMC_CMC_QUEUE_TEST_H
+#define CMC_CMC_QUEUE_TEST_H
+
+#include "macro_collections.h"
+
+struct queue
+{
+ size_t *buffer;
+ size_t capacity;
+ size_t count;
+ size_t front;
+ size_t back;
+ int flag;
+ struct queue_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct queue_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct queue *q_new(size_t capacity, struct queue_fval *f_val);
+struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void q_clear(struct queue *_queue_);
+void q_free(struct queue *_queue_);
+void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool q_enqueue(struct queue *_queue_, size_t value);
+_Bool q_dequeue(struct queue *_queue_);
+size_t q_peek(struct queue *_queue_);
+_Bool q_contains(struct queue *_queue_, size_t value);
+_Bool q_empty(struct queue *_queue_);
+_Bool q_full(struct queue *_queue_);
+size_t q_count(struct queue *_queue_);
+size_t q_capacity(struct queue *_queue_);
+int q_flag(struct queue *_queue_);
+_Bool q_resize(struct queue *_queue_, size_t capacity);
+struct queue *q_copy_of(struct queue *_queue_);
+_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_);
+struct queue_iter
+{
+ struct queue *target;
+ size_t cursor;
+ size_t index;
+ _Bool start;
+ _Bool end;
+};
+struct queue_iter q_iter_start(struct queue *target);
+struct queue_iter q_iter_end(struct queue *target);
+_Bool q_iter_at_start(struct queue_iter *iter);
+_Bool q_iter_at_end(struct queue_iter *iter);
+_Bool q_iter_to_start(struct queue_iter *iter);
+_Bool q_iter_to_end(struct queue_iter *iter);
+_Bool q_iter_next(struct queue_iter *iter);
+_Bool q_iter_prev(struct queue_iter *iter);
+_Bool q_iter_advance(struct queue_iter *iter, size_t steps);
+_Bool q_iter_rewind(struct queue_iter *iter, size_t steps);
+_Bool q_iter_go_to(struct queue_iter *iter, size_t index);
+size_t q_iter_value(struct queue_iter *iter);
+size_t *q_iter_rvalue(struct queue_iter *iter);
+size_t q_iter_index(struct queue_iter *iter);
+_Bool q_to_string(struct queue *_queue_, FILE *fptr);
+_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_QUEUE_TEST_H */
diff --git a/tests/include/cmc/sortedlist.h b/tests/include/cmc/sortedlist.h
new file mode 100644
index 0000000..a34b155
--- /dev/null
+++ b/tests/include/cmc/sortedlist.h
@@ -0,0 +1,72 @@
+
+#ifndef CMC_CMC_SORTEDLIST_TEST_H
+#define CMC_CMC_SORTEDLIST_TEST_H
+
+#include "macro_collections.h"
+
+struct sortedlist
+{
+ size_t *buffer;
+ size_t capacity;
+ size_t count;
+ _Bool is_sorted;
+ int flag;
+ struct sortedlist_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct sortedlist_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val);
+struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void sl_clear(struct sortedlist *_list_);
+void sl_free(struct sortedlist *_list_);
+void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool sl_insert(struct sortedlist *_list_, size_t value);
+_Bool sl_remove(struct sortedlist *_list_, size_t index);
+size_t sl_max(struct sortedlist *_list_);
+size_t sl_min(struct sortedlist *_list_);
+size_t sl_get(struct sortedlist *_list_, size_t index);
+size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start);
+_Bool sl_contains(struct sortedlist *_list_, size_t value);
+_Bool sl_empty(struct sortedlist *_list_);
+_Bool sl_full(struct sortedlist *_list_);
+size_t sl_count(struct sortedlist *_list_);
+size_t sl_capacity(struct sortedlist *_list_);
+int sl_flag(struct sortedlist *_list_);
+_Bool sl_resize(struct sortedlist *_list_, size_t capacity);
+void sl_sort(struct sortedlist *_list_);
+struct sortedlist *sl_copy_of(struct sortedlist *_list_);
+_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_);
+struct sortedlist_iter
+{
+ struct sortedlist *target;
+ size_t cursor;
+ _Bool start;
+ _Bool end;
+};
+struct sortedlist_iter sl_iter_start(struct sortedlist *target);
+struct sortedlist_iter sl_iter_end(struct sortedlist *target);
+_Bool sl_iter_at_start(struct sortedlist_iter *iter);
+_Bool sl_iter_at_end(struct sortedlist_iter *iter);
+_Bool sl_iter_to_start(struct sortedlist_iter *iter);
+_Bool sl_iter_to_end(struct sortedlist_iter *iter);
+_Bool sl_iter_next(struct sortedlist_iter *iter);
+_Bool sl_iter_prev(struct sortedlist_iter *iter);
+_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps);
+_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps);
+_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index);
+size_t sl_iter_value(struct sortedlist_iter *iter);
+size_t sl_iter_index(struct sortedlist_iter *iter);
+_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr);
+_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_SORTEDLIST_TEST_H */
diff --git a/tests/include/cmc/stack.h b/tests/include/cmc/stack.h
new file mode 100644
index 0000000..6f510d0
--- /dev/null
+++ b/tests/include/cmc/stack.h
@@ -0,0 +1,68 @@
+
+#ifndef CMC_CMC_STACK_TEST_H
+#define CMC_CMC_STACK_TEST_H
+
+#include "macro_collections.h"
+
+struct stack
+{
+ size_t *buffer;
+ size_t capacity;
+ size_t count;
+ int flag;
+ struct stack_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct stack_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct stack *s_new(size_t capacity, struct stack_fval *f_val);
+struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void s_clear(struct stack *_stack_);
+void s_free(struct stack *_stack_);
+void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool s_push(struct stack *_stack_, size_t value);
+_Bool s_pop(struct stack *_stack_);
+size_t s_top(struct stack *_stack_);
+_Bool s_contains(struct stack *_stack_, size_t value);
+_Bool s_empty(struct stack *_stack_);
+_Bool s_full(struct stack *_stack_);
+size_t s_count(struct stack *_stack_);
+size_t s_capacity(struct stack *_stack_);
+int s_flag(struct stack *_stack_);
+_Bool s_resize(struct stack *_stack_, size_t capacity);
+struct stack *s_copy_of(struct stack *_stack_);
+_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_);
+struct stack_iter
+{
+ struct stack *target;
+ size_t cursor;
+ _Bool start;
+ _Bool end;
+};
+struct stack_iter s_iter_start(struct stack *target);
+struct stack_iter s_iter_end(struct stack *target);
+_Bool s_iter_at_start(struct stack_iter *iter);
+_Bool s_iter_at_end(struct stack_iter *iter);
+_Bool s_iter_to_start(struct stack_iter *iter);
+_Bool s_iter_to_end(struct stack_iter *iter);
+_Bool s_iter_next(struct stack_iter *iter);
+_Bool s_iter_prev(struct stack_iter *iter);
+_Bool s_iter_advance(struct stack_iter *iter, size_t steps);
+_Bool s_iter_rewind(struct stack_iter *iter, size_t steps);
+_Bool s_iter_go_to(struct stack_iter *iter, size_t index);
+size_t s_iter_value(struct stack_iter *iter);
+size_t *s_iter_rvalue(struct stack_iter *iter);
+size_t s_iter_index(struct stack_iter *iter);
+_Bool s_to_string(struct stack *_stack_, FILE *fptr);
+_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_STACK_TEST_H */
diff --git a/tests/include/cmc/treemap.h b/tests/include/cmc/treemap.h
new file mode 100644
index 0000000..005ad91
--- /dev/null
+++ b/tests/include/cmc/treemap.h
@@ -0,0 +1,92 @@
+
+#ifndef CMC_CMC_TREEMAP_TEST_H
+#define CMC_CMC_TREEMAP_TEST_H
+
+#include "macro_collections.h"
+
+struct treemap
+{
+ struct treemap_node *root;
+ size_t count;
+ int flag;
+ struct treemap_fkey *f_key;
+ struct treemap_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct treemap_node
+{
+ size_t key;
+ size_t value;
+ unsigned char height;
+ struct treemap_node *right;
+ struct treemap_node *left;
+ struct treemap_node *parent;
+};
+struct treemap_fkey
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct treemap_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val);
+struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void tm_clear(struct treemap *_map_);
+void tm_free(struct treemap *_map_);
+void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool tm_insert(struct treemap *_map_, size_t key, size_t value);
+_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value);
+_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value);
+_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value);
+_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value);
+size_t tm_get(struct treemap *_map_, size_t key);
+size_t *tm_get_ref(struct treemap *_map_, size_t key);
+_Bool tm_contains(struct treemap *_map_, size_t key);
+_Bool tm_empty(struct treemap *_map_);
+size_t tm_count(struct treemap *_map_);
+int tm_flag(struct treemap *_map_);
+struct treemap *tm_copy_of(struct treemap *_map_);
+_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_);
+struct treemap_iter
+{
+ struct treemap *target;
+ struct treemap_node *cursor;
+ struct treemap_node *first;
+ struct treemap_node *last;
+ size_t index;
+ _Bool start;
+ _Bool end;
+};
+struct treemap_iter tm_iter_start(struct treemap *target);
+struct treemap_iter tm_iter_end(struct treemap *target);
+_Bool tm_iter_at_start(struct treemap_iter *iter);
+_Bool tm_iter_at_end(struct treemap_iter *iter);
+_Bool tm_iter_to_start(struct treemap_iter *iter);
+_Bool tm_iter_to_end(struct treemap_iter *iter);
+_Bool tm_iter_next(struct treemap_iter *iter);
+_Bool tm_iter_prev(struct treemap_iter *iter);
+_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps);
+_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps);
+_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index);
+size_t tm_iter_key(struct treemap_iter *iter);
+size_t tm_iter_value(struct treemap_iter *iter);
+size_t *tm_iter_rvalue(struct treemap_iter *iter);
+size_t tm_iter_index(struct treemap_iter *iter);
+_Bool tm_to_string(struct treemap *_map_, FILE *fptr);
+_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep);
+
+#endif /* CMC_CMC_TREEMAP_TEST_H */
diff --git a/tests/include/cmc/treeset.h b/tests/include/cmc/treeset.h
new file mode 100644
index 0000000..9bca697
--- /dev/null
+++ b/tests/include/cmc/treeset.h
@@ -0,0 +1,84 @@
+
+#ifndef CMC_CMC_TREESET_TEST_H
+#define CMC_CMC_TREESET_TEST_H
+
+#include "macro_collections.h"
+
+struct treeset
+{
+ struct treeset_node *root;
+ size_t count;
+ int flag;
+ struct treeset_fval *f_val;
+ struct cmc_alloc_node *alloc;
+ struct cmc_callbacks *callbacks;
+};
+struct treeset_node
+{
+ size_t value;
+ unsigned char height;
+ struct treeset_node *right;
+ struct treeset_node *left;
+ struct treeset_node *parent;
+};
+struct treeset_fval
+{
+ int (*cmp)(size_t, size_t);
+ size_t (*cpy)(size_t);
+ _Bool (*str)(FILE *, size_t);
+ void (*free)(size_t);
+ size_t (*hash)(size_t);
+ int (*pri)(size_t, size_t);
+};
+struct treeset *ts_new(struct treeset_fval *f_val);
+struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks);
+void ts_clear(struct treeset *_set_);
+void ts_free(struct treeset *_set_);
+void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks);
+_Bool ts_insert(struct treeset *_set_, size_t value);
+_Bool ts_remove(struct treeset *_set_, size_t value);
+_Bool ts_max(struct treeset *_set_, size_t *value);
+_Bool ts_min(struct treeset *_set_, size_t *value);
+_Bool ts_contains(struct treeset *_set_, size_t value);
+_Bool ts_empty(struct treeset *_set_);
+size_t ts_count(struct treeset *_set_);
+int ts_flag(struct treeset *_set_);
+struct treeset *ts_copy_of(struct treeset *_set_);
+_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_);
+struct treeset_iter
+{
+ struct treeset *target;
+ struct treeset_node *cursor;
+ struct treeset_node *first;
+ struct treeset_node *last;
+ size_t index;
+ _Bool start;
+ _Bool end;
+};
+struct treeset_iter ts_iter_start(struct treeset *target);
+struct treeset_iter ts_iter_end(struct treeset *target);
+_Bool ts_iter_at_start(struct treeset_iter *iter);
+_Bool ts_iter_at_end(struct treeset_iter *iter);
+_Bool ts_iter_to_start(struct treeset_iter *iter);
+_Bool ts_iter_to_end(struct treeset_iter *iter);
+_Bool ts_iter_next(struct treeset_iter *iter);
+_Bool ts_iter_prev(struct treeset_iter *iter);
+_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps);
+_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps);
+_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index);
+size_t ts_iter_value(struct treeset_iter *iter);
+size_t ts_iter_index(struct treeset_iter *iter);
+struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_);
+struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_);
+struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_);
+struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_);
+_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_);
+_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_);
+_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_);
+_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_);
+_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_);
+_Bool ts_to_string(struct treeset *_set_, FILE *fptr);
+_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end);
+
+#endif /* CMC_CMC_TREESET_TEST_H */
diff --git a/tests/iterators.c b/tests/iterators.c
deleted file mode 100644
index dc51442..0000000
--- a/tests/iterators.c
+++ /dev/null
@@ -1,139 +0,0 @@
-#include "../src/macro_collections.h"
-#include
-
-int intcmp(int a, int b)
-{
- return (a > b) - (a < b);
-}
-
-size_t inthash(int t)
-{
- size_t a = t;
- a += ~(a << 15);
- a ^= (a >> 10);
- a += (a << 3);
- a ^= (a >> 6);
- a += ~(a << 11);
- a ^= (a >> 16);
- return a;
-}
-
-CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
-CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
-CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
-CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
-CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
-CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
-CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, double)
-CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
-CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, double)
-
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* K */, int)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, double)
-CMC_COLLECTION_GENERATE(MULTISET, ms, mset, /* K */, int)
-
-#define ITERATOR_TEST(NAME, PFX, sname, initfunc, insertbody, sumbody, \
- validation1, validation2) \
- void NAME##_iterator_test(void) \
- { \
- int sum1 = 0; \
- double sum2 = 0.0; \
- \
- struct sname *coll = initfunc; \
- for (int i = 0; i < 10; i++) \
- { \
- insertbody; \
- } \
- \
- struct sname##_iter iter; \
- PFX##_iter_init(&iter, coll); \
- \
- for (int j = 0; j < 4; j++) \
- { \
- while (!PFX##_iter_end(&iter)) \
- { \
- sumbody; \
- PFX##_iter_next(&iter); \
- } \
- while (!PFX##_iter_start(&iter)) \
- { \
- sumbody; \
- PFX##_iter_prev(&iter); \
- } \
- } \
- \
- for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); \
- PFX##_iter_next(&iter)) \
- { \
- sumbody; \
- } \
- \
- for (PFX##_iter_to_end(&iter); !PFX##_iter_start(&iter); \
- PFX##_iter_prev(&iter)) \
- { \
- sumbody; \
- } \
- \
- PFX##_free(coll, NULL); \
- \
- if ((validation1) && (validation2)) \
- printf("%12s PASSED\n", #NAME); \
- else \
- printf("%12s FAILED\n", #NAME); \
- }
-
-ITERATOR_TEST(DEQUE, d, deque, d_new(20), d_push_front(coll, i),
- sum1 += d_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(HASHMAP, hm, hmap, hm_new(50, 0.6, intcmp, inthash),
- hm_insert(coll, i, (double)i / 10.0), sum1 += hm_iter_key(&iter);
- sum2 += hm_iter_value(&iter), sum1 == 450, (int)sum2 == (int)45)
-ITERATOR_TEST(HASHSET, hs, hset, hs_new(50, 0.6, intcmp, inthash),
- hs_insert(coll, i), sum1 += hs_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(HEAP, h, heap, h_new(20, cmc_max_heap, intcmp), h_insert(coll, i),
- sum1 += h_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(LINKEDLIST, ll, linked, ll_new(), ll_push_back(coll, i),
- sum1 += ll_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(LIST, l, list, l_new(20), l_push_back(coll, i),
- sum1 += l_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(QUEUE, q, queue, q_new(20), q_enqueue(coll, i),
- sum1 += q_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(STACK, s, stack, s_new(20), s_push(coll, i),
- sum1 += s_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(TREEMAP, tm, tmap, tm_new(intcmp),
- tm_insert(coll, i, (double)i / 10.0), sum1 += tm_iter_key(&iter);
- sum2 += tm_iter_value(&iter), sum1 == 450, (int)sum2 == (int)45)
-ITERATOR_TEST(TREESET, ts, tset, ts_new(intcmp), ts_insert(coll, i),
- sum1 += ts_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(INTERVALHEAP, ih, iheap, ih_new(20, intcmp), ih_insert(coll, i),
- sum1 += ih_iter_value(&iter), sum1 == 450, 1)
-ITERATOR_TEST(MULTIMAP, mm, mmap, mm_new(50, 0.8, intcmp, inthash),
- mm_insert(coll, i, (double)i / 10.0), sum1 += mm_iter_key(&iter);
- sum2 += mm_iter_value(&iter), sum1 == 450, (int)sum2 == (int)45)
-ITERATOR_TEST(MULTISET, ms, mset, ms_new(50, 0.6, intcmp, inthash),
- ms_insert(coll, i), sum1 += ms_iter_value(&iter);
- sum2 += ms_iter_multiplicity(&iter), sum1 == 450,
- (size_t)sum2 == 100)
-
-int main(void)
-{
- printf("\n-------------------- ITERATORS --------------------\n");
- DEQUE_iterator_test();
- HASHMAP_iterator_test();
- HASHSET_iterator_test();
- HEAP_iterator_test();
- LINKEDLIST_iterator_test();
- LIST_iterator_test();
- QUEUE_iterator_test();
- STACK_iterator_test();
- TREEMAP_iterator_test();
- TREESET_iterator_test();
-
- INTERVALHEAP_iterator_test();
- MULTIMAP_iterator_test();
- MULTISET_iterator_test();
-
- printf("\n\n");
-
- return 0;
-}
diff --git a/tests/main.c b/tests/main.c
new file mode 100644
index 0000000..4007f43
--- /dev/null
+++ b/tests/main.c
@@ -0,0 +1,102 @@
+#include
+#include
+
+#include "unt/cmc/bitset.h"
+#include "unt/cmc/deque.h"
+#include "unt/cmc/hashbidimap.h"
+#include "unt/cmc/hashmap.h"
+#include "unt/cmc/hashmultimap.h"
+#include "unt/cmc/hashmultiset.h"
+#include "unt/cmc/hashset.h"
+#include "unt/cmc/heap.h"
+#include "unt/cmc/intervalheap.h"
+#include "unt/cmc/linkedlist.h"
+#include "unt/cmc/list.h"
+#include "unt/cmc/queue.h"
+#include "unt/cmc/sortedlist.h"
+#include "unt/cmc/stack.h"
+#include "unt/cmc/treemap.h"
+#include "unt/cmc/treeset.h"
+
+#include "unt/utl/foreach.h"
+
+#include "utl/assert.h"
+#include "utl/timer.h"
+
+#include "./unt/utl.h"
+
+#define cmc_run(unit, unit_fails, test_fails) \
+ do \
+ { \
+ uintmax_t f = unit(); \
+ if (f != 0) \
+ unit_fails += 1; \
+ test_fails += f; \
+ } while (0)
+
+int main(void)
+{
+ // clang-format off
+ printf(" +---------------------------------------------------------------+\n");
+ printf(" | C Macro Collections Library |\n");
+ printf(" | |\n");
+ printf(" | Test Suite |\n");
+ printf(" | |\n");
+ printf(" | https://github.com/LeoVen/C-Macro-Collections |\n");
+ printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n");
+ printf(" +---------------------------------------------------------------+\n\n");
+ // clang-format on
+
+ struct cmc_timer timer;
+
+ cmc_timer_start(timer);
+ uintmax_t tests = 0, units = 0;
+
+ 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);
+ cmc_run(CMCHashBidiMapIter, units, tests);
+ cmc_run(CMCHashMap, units, tests);
+ cmc_run(CMCHashMapIter, units, tests);
+ cmc_run(CMCHashMultiMap, units, tests);
+ cmc_run(CMCHashMultiMapIter, units, tests);
+ cmc_run(CMCHashMultiSet, units, tests);
+ 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(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(CMCSortedList, units, tests);
+ cmc_run(CMCSortedListIter, units, tests);
+ cmc_run(CMCStack, units, tests);
+ cmc_run(CMCStackIter, units, tests);
+ cmc_run(CMCTreeMap, units, tests);
+ cmc_run(CMCTreeMapIter, units, tests);
+ cmc_run(CMCTreeSet, units, tests);
+ cmc_run(CMCTreeSetIter, units, tests);
+
+ cmc_run(ForEach, units, tests);
+
+ cmc_timer_stop(timer);
+
+ printf(" +---------------------------------------------------------------+\n");
+ printf(" | SUMMARY |\n");
+ printf(" +---------------------------------------------------------------+\n");
+ printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units);
+ printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests);
+ printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n", cmc_assert_failed);
+ printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result);
+ printf(" +---------------------------------------------------------------+\n");
+
+ return tests;
+}
diff --git a/tests/main/Makefile b/tests/main/Makefile
deleted file mode 100644
index 2cf7991..0000000
--- a/tests/main/Makefile
+++ /dev/null
@@ -1,107 +0,0 @@
-CC = gcc
-CFLAGS = -std=c11 -Wall -Wextra
-CFLAGS += -Wno-unused -Wno-missing-braces
-DBFLAGS = -g3
-CVFLAGS = --coverage -O0
-INCLUDE = ../../src/
-UNIT = ./unt
-
-main: FORCE
- $(CC) main.c -o main.exe $(CFLAGS) $(CVFLAGS) -I $(INCLUDE) -DCMC_TEST_COLOR
- ./main.exe
- gcov ./main.c
-
-nocov: FORCE
- $(CC) main.c -o main.exe $(CFLAGS) -I $(INCLUDE) -DCMC_TEST_COLOR
- ./main.exe
- rm *.exe
-
-bare: FORCE
- $(CC) main.c -o main.exe $(CFLAGS) -I $(INCLUDE)
- ./main.exe
- rm *.exe
-
-debug: FORCE
- $(CC) main.c -o main.exe $(CFLAGS) -I $(INCLUDE) -DCMC_TEST_COLOR $(DBFLAGS)
-
-valgrind: debug
- valgrind --leak-check=full ./main.exe
-
-all: bitset deque hashbidimap hashmap hashmultimap hashmultiset hashset heap intervalheap linkedlist list queue sortedlist stack treemap treeset foreach
- rm ./main.exe
-
-bitset: $(UNIT)/bitset.c $(INCLUDE)/cmc/bitset.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint8_t
- ./main.exe
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint16_t
- ./main.exe
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint32_t
- ./main.exe
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR -DCMC_BITSET_WORD_TYPE=uint64_t
- ./main.exe
-
-deque: $(UNIT)/deque.c $(INCLUDE)/cmc/deque.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-hashbidimap: $(UNIT)/hashbidimap.c $(INCLUDE)/cmc/hashbidimap.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-hashmap: $(UNIT)/hashmap.c $(INCLUDE)/cmc/hashmap.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-hashmultimap: $(UNIT)/hashmultimap.c $(INCLUDE)/cmc/hashmultimap.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-hashmultiset: $(UNIT)/hashmultiset.c $(INCLUDE)/cmc/hashmultiset.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-hashset: $(UNIT)/hashset.c $(INCLUDE)/cmc/hashset.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-heap: $(UNIT)/heap.c $(INCLUDE)/cmc/heap.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-intervalheap: $(UNIT)/intervalheap.c $(INCLUDE)/cmc/intervalheap.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-linkedlist: $(UNIT)/linkedlist.c $(INCLUDE)/cmc/linkedlist.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-list: $(UNIT)/list.c $(INCLUDE)/cmc/list.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-queue: $(UNIT)/queue.c $(INCLUDE)/cmc/queue.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-sortedlist: $(UNIT)/sortedlist.c $(INCLUDE)/cmc/sortedlist.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-stack: $(UNIT)/stack.c $(INCLUDE)/cmc/stack.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-treemap: $(UNIT)/treemap.c $(INCLUDE)/cmc/treemap.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-treeset: $(UNIT)/treeset.c $(INCLUDE)/cmc/treeset.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-foreach: $(UNIT)/foreach.c $(INCLUDE)/utl/foreach.h
- $(CC) $^ -o main.exe -I $(INCLUDE) -DCMC_TEST_MAIN -DCMC_TEST_COLOR
- ./main.exe
-
-FORCE:
diff --git a/tests/main/README.md b/tests/main/README.md
deleted file mode 100644
index 9d14b3e..0000000
--- a/tests/main/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# main
-
-This folder hosts the main tests for the C Macro Collections Library.
diff --git a/tests/main/main.c b/tests/main/main.c
deleted file mode 100644
index 076452d..0000000
--- a/tests/main/main.c
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "utl/timer.h"
-
-#include "unt/bitset.c"
-#include "unt/deque.c"
-#include "unt/hashbidimap.c"
-#include "unt/hashmap.c"
-#include "unt/hashmultimap.c"
-#include "unt/hashmultiset.c"
-#include "unt/hashset.c"
-#include "unt/heap.c"
-#include "unt/intervalheap.c"
-#include "unt/linkedlist.c"
-#include "unt/list.c"
-#include "unt/queue.c"
-#include "unt/sortedlist.c"
-#include "unt/stack.c"
-#include "unt/treemap.c"
-#include "unt/treeset.c"
-
-#include "unt/foreach.c"
-
-#define cmc_run(unit, unit_fails, test_fails) \
- do \
- { \
- uintmax_t f = unit(); \
- \
- if (f != 0) \
- unit_fails += 1; \
- \
- test_fails += f; \
- \
- } while (0)
-
-int main(void)
-{
- // clang-format off
- printf(" +---------------------------------------------------------------+\n");
- printf(" | C Macro Collections Library |\n");
- printf(" | |\n");
- printf(" | Test Suite |\n");
- printf(" | |\n");
- printf(" | https://github.com/LeoVen/C-Macro-Collections |\n");
- printf(" | Leonardo Vencovsky (leonardo.vencovsky@gmail.com) |\n");
- printf(" +---------------------------------------------------------------+\n\n");
- // clang-format on
-
- struct cmc_timer timer;
-
- cmc_timer_start(timer);
- uintmax_t tests = 0, units = 0;
-
- cmc_run(BitSet, units, tests);
- cmc_run(BitSetIter, units, tests);
- cmc_run(Deque, units, tests);
- cmc_run(DequeIter, units, tests);
- cmc_run(HashBidiMap, units, tests);
- cmc_run(HashBidiMapIter, units, tests);
- cmc_run(HashMap, units, tests);
- cmc_run(HashMapIter, units, tests);
- cmc_run(HashMultiMap, units, tests);
- cmc_run(HashMultiMapIter, units, tests);
- cmc_run(HashMultiSet, units, tests);
- cmc_run(HashMultiSetIter, units, tests);
- cmc_run(HashSet, units, tests);
- cmc_run(HashSetIter, units, tests);
- cmc_run(Heap, units, tests);
- cmc_run(HeapIter, units, tests);
- cmc_run(IntervalHeap, units, tests);
- cmc_run(IntervalHeapIter, units, tests);
- cmc_run(LinkedList, units, tests);
- cmc_run(LinkedListIter, units, tests);
- cmc_run(List, units, tests);
- cmc_run(ListIter, units, tests);
- cmc_run(Queue, units, tests);
- cmc_run(QueueIter, units, tests);
- cmc_run(SortedList, units, tests);
- cmc_run(SortedListIter, units, tests);
- cmc_run(Stack, units, tests);
- cmc_run(StackIter, units, tests);
- cmc_run(TreeMap, units, tests);
- cmc_run(TreeMapIter, units, tests);
- cmc_run(TreeSet, units, tests);
- cmc_run(TreeSetIter, units, tests);
-
- cmc_run(ForEach, units, tests);
-
- cmc_timer_stop(timer);
-
- printf(
- " +---------------------------------------------------------------+\n");
- printf(
- " | SUMMARY |\n");
- printf(
- " +---------------------------------------------------------------+\n");
- printf(" | Total Units Failed : %25" PRIuMAX " units |\n", units);
- printf(" | Total Tests Failed : %25" PRIuMAX " tests |\n", tests);
- printf(" | Total Asserts Failed : %25" PRIuMAX " asserts |\n",
- cmc_assert_failed);
- printf(" | Total Runtime : %25.0lf milliseconds |\n", timer.result);
- printf(
- " +---------------------------------------------------------------+\n");
-
- return tests;
-}
diff --git a/tests/sep/Makefile b/tests/sep/Makefile
deleted file mode 100644
index 089d7b8..0000000
--- a/tests/sep/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-CC = gcc
-CFLAGS = -std=c11 -Wall -Wextra
-CFLAGS += -Wno-unused -Wno-missing-braces
-
-main:
- $(CC) -c collections.c -o collections.o $(CFLAGS)
- $(CC) -c main.c -o main.o $(CFLAGS)
- $(CC) collections.o main.o -o sep.exe
- ./sep.exe
-
-clean:
- rm *.o
-
-clear:
- rm *.o *.exe
diff --git a/tests/sep/collections.c b/tests/sep/collections.c
deleted file mode 100644
index 0063216..0000000
--- a/tests/sep/collections.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "collections.h"
-
-CMC_COLLECTION_GENERATE_SOURCE( BIDIMAP, bm, bmap, int, int)
-CMC_COLLECTION_GENERATE_SOURCE( DEQUE, d, deque, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( HASHMAP, hm, hmap, int, int)
-CMC_COLLECTION_GENERATE_SOURCE( HASHSET, hs, hset, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( HEAP, h, heap, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE(INTERVALHEAP, ih, iheap, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( LINKEDLIST, ll, linked, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( LIST, l, list, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( MULTIMAP, mm, mmap, int, int)
-CMC_COLLECTION_GENERATE_SOURCE( MULTISET, ms, mset, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( QUEUE, q, queue, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( SORTEDLIST, sl, slist, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( STACK, s, stack, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( TREESET, ts, tset, /* K */, int)
-CMC_COLLECTION_GENERATE_SOURCE( TREEMAP, tm, tmap, int, int)
diff --git a/tests/sep/collections.h b/tests/sep/collections.h
deleted file mode 100644
index 966a307..0000000
--- a/tests/sep/collections.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "../../src/macro_collections.h"
-
-CMC_COLLECTION_GENERATE_HEADER( BIDIMAP, bm, bmap, int, int)
-CMC_COLLECTION_GENERATE_HEADER( DEQUE, d, deque, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( HASHMAP, hm, hmap, int, int)
-CMC_COLLECTION_GENERATE_HEADER( HASHSET, hs, hset, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( HEAP, h, heap, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER(INTERVALHEAP, ih, iheap, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( LINKEDLIST, ll, linked, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( LIST, l, list, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( MULTIMAP, mm, mmap, int, int)
-CMC_COLLECTION_GENERATE_HEADER( MULTISET, ms, mset, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( QUEUE, q, queue, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( SORTEDLIST, sl, slist, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( STACK, s, stack, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( TREESET, ts, tset, /* K */, int)
-CMC_COLLECTION_GENERATE_HEADER( TREEMAP, tm, tmap, int, int)
diff --git a/tests/sep/main.c b/tests/sep/main.c
deleted file mode 100644
index 350a863..0000000
--- a/tests/sep/main.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "collections.h"
-#include
-
-int intcmp(int a, int b)
-{
- return (a > b) - (a < b);
-}
-
-size_t inthash(int t)
-{
- size_t a = t;
- a += ~(a << 15);
- a ^= (a >> 10);
- a += (a << 3);
- a ^= (a >> 6);
- a += ~(a << 11);
- a ^= (a >> 16);
- return a;
-}
-
-int main(void)
-{
- struct bmap *bm =
- bm_new_custom(100, 0.7, &(struct bmap_ftab_key){ 0 },
- &(struct bmap_ftab_val){ 0 }, NULL, NULL);
- struct deque *d = d_new_custom(100, NULL, NULL);
- struct hmap *hm = hm_new_custom(100, 0.6, NULL, NULL, NULL, NULL);
- struct hset *hs = hs_new_custom(100, 0.6, NULL, NULL, NULL, NULL);
- struct heap *h = h_new_custom(100, cmc_max_heap, NULL, NULL, NULL);
- struct iheap *ih = ih_new_custom(100, NULL, NULL, NULL);
- struct linked *ll = ll_new_custom(NULL, NULL);
- struct list *l = l_new_custom(100, NULL, NULL);
- struct mmap *mm = mm_new_custom(100, 0.8, NULL, NULL, NULL, NULL);
- struct mset *ms = ms_new_custom(100, 0.6, NULL, NULL, NULL, NULL);
- struct queue *q = q_new_custom(100, NULL, NULL);
- struct slist *sl = sl_new_custom(100, NULL, NULL, NULL);
- struct stack *s = s_new_custom(100, NULL, NULL);
- struct tmap *tm = tm_new_custom(NULL, NULL, NULL);
- struct tset *ts = ts_new_custom(NULL, NULL, NULL);
-
- printf("+--------------------------------------------------+\n");
- printf("| Separate Header and Source is Working |\n");
- printf("+--------------------------------------------------+\n");
-
- bm_free(bm);
- d_free(d, NULL);
- hm_free(hm, NULL);
- hs_free(hs, NULL);
- h_free(h, NULL);
- ih_free(ih, NULL);
- ll_free(ll, NULL);
- l_free(l, NULL);
- mm_free(mm, NULL);
- ms_free(ms, NULL);
- q_free(q, NULL);
- sl_free(sl, NULL);
- s_free(s, NULL);
- tm_free(tm, NULL);
- ts_free(ts, NULL);
-
- return 0;
-}
diff --git a/tests/main/src/bitset.c b/tests/src/cmc/bitset.c
similarity index 57%
rename from tests/main/src/bitset.c
rename to tests/src/cmc/bitset.c
index fdd081c..39865ba 100644
--- a/tests/main/src/bitset.c
+++ b/tests/src/cmc/bitset.c
@@ -1,70 +1,19 @@
-#ifndef CMC_TEST_SRC_BITSET
-#define CMC_TEST_SRC_BITSET
#include "cmc/bitset.h"
-struct bitset
-{
- cmc_bitset_word *buffer;
- size_t capacity;
- int flag;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct bitset_iter
-{
- struct bitset *target;
- cmc_bitset_word cursor;
- _Bool start;
- _Bool end;
-};
-struct bitset *bs_new(size_t n_bits);
-struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-struct bitset bs_init(size_t n_bits);
-struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void bs_free(struct bitset *_bitset_);
-void bs_release(struct bitset _bitset_);
-void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool bs_set(struct bitset *_bitset_, size_t bit_index);
-_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to);
-_Bool bs_clear(struct bitset *_bitset_, size_t bit_index);
-_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to);
-_Bool bs_flip(struct bitset *_bitset_, size_t bit_index);
-_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to);
-_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state);
-_Bool bs_put_range(struct bitset *_bitset_, size_t from, size_t to,
- _Bool state);
-_Bool bs_set_all(struct bitset *_bitset_);
-_Bool bs_clear_all(struct bitset *_bitset_);
-_Bool bs_flip_all(struct bitset *_bitset_);
-_Bool bs_get(struct bitset *_bitset_, size_t bit_index);
-_Bool bs_resize(struct bitset *_bitset_, size_t n_bits);
-static inline size_t bs_bit_to_index(size_t idx)
-{
- static const size_t shift =
- ((sizeof(cmc_bitset_word) * 8) >> 6) > 0
- ? 6
- : ((sizeof(cmc_bitset_word) * 8) >> 5) > 0
- ? 5
- : ((sizeof(cmc_bitset_word) * 8) >> 4) > 0 ? 4 : 3;
- return idx >> shift;
-}
_Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize);
struct bitset *bs_new(size_t n_bits)
{
return bs_new_custom(n_bits, ((void *)0), ((void *)0));
}
-struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (n_bits < 1)
return ((void *)0);
if (!alloc)
alloc = &cmc_alloc_node_default;
- size_t capacity = bs_bit_to_index(n_bits - 1) + 1;
+ size_t capacity = cmc_bidx_to_widx(n_bits - 1) + 1;
struct bitset *_bitset_ = alloc->malloc(sizeof(struct bitset));
if (!_bitset_)
return ((void *)0);
@@ -75,9 +24,9 @@ struct bitset *bs_new_custom(size_t n_bits, struct cmc_alloc_node *alloc,
return ((void *)0);
}
_bitset_->capacity = capacity;
- _bitset_->flag = cmc_flags.OK;
+ _bitset_->flag = CMC_FLAG_OK;
_bitset_->alloc = alloc;
- _bitset_->callbacks = callbacks;
+ (_bitset_)->callbacks = callbacks;
return _bitset_;
}
struct bitset bs_init(size_t n_bits)
@@ -85,21 +34,22 @@ struct bitset bs_init(size_t n_bits)
return bs_init_custom(n_bits, ((void *)0), ((void *)0));
}
struct bitset bs_init_custom(size_t n_bits, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+ struct cmc_callbacks *__attribute__((__unused__)) (callbacks))
{
+ ;
struct bitset _bitset_ = { 0 };
if (n_bits < 1)
return _bitset_;
if (!alloc)
alloc = &cmc_alloc_node_default;
- size_t capacity = bs_bit_to_index(n_bits - 1) + 1;
+ 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_flags.OK;
+ _bitset_.flag = CMC_FLAG_OK;
_bitset_.alloc = alloc;
- _bitset_.callbacks = callbacks;
+ (&_bitset_)->callbacks = callbacks;
return _bitset_;
}
void bs_free(struct bitset *_bitset_)
@@ -111,39 +61,40 @@ void bs_release(struct bitset _bitset_)
{
free(_bitset_.buffer);
}
-void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void bs_customize(struct bitset *_bitset_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_bitset_->alloc = &cmc_alloc_node_default;
else
_bitset_->alloc = alloc;
- _bitset_->callbacks = callbacks;
- _bitset_->flag = cmc_flags.OK;
+ (_bitset_)->callbacks = callbacks;
+ _bitset_->flag = CMC_FLAG_OK;
}
_Bool bs_set(struct bitset *_bitset_, size_t bit_index)
{
if (!bs_impl_resize(_bitset_, bit_index + 1, 0))
return 0;
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
- size_t i = bs_bit_to_index(bit_index);
+ size_t i = cmc_bidx_to_widx(bit_index);
_bitset_->buffer[i] |= ((cmc_bitset_word)1) << (bit_index % bits);
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->create)
- _bitset_->callbacks->create();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
+ (_bitset_)->callbacks->create();
+ ;
return 1;
}
_Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to)
{
if (to < from)
{
- _bitset_->flag = cmc_flags.INVALID;
+ _bitset_->flag = CMC_FLAG_INVALID;
return 0;
}
if (!bs_impl_resize(_bitset_, to + 1, 0))
return 0;
- size_t start_index = bs_bit_to_index(from);
- size_t end_index = bs_bit_to_index(to);
+ size_t start_index = cmc_bidx_to_widx(from);
+ size_t end_index = cmc_bidx_to_widx(to);
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
cmc_bitset_word shift_start = from % bits;
@@ -161,9 +112,10 @@ _Bool bs_set_range(struct bitset *_bitset_, size_t from, size_t to)
_bitset_->buffer[i] |= ~((cmc_bitset_word)0);
_bitset_->buffer[end_index] |= end_mask;
}
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->create)
- _bitset_->callbacks->create();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
+ (_bitset_)->callbacks->create();
+ ;
return 1;
}
_Bool bs_clear(struct bitset *_bitset_, size_t bit_index)
@@ -171,24 +123,25 @@ _Bool bs_clear(struct bitset *_bitset_, size_t bit_index)
if (!bs_impl_resize(_bitset_, bit_index + 1, 0))
return 0;
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
- size_t i = bs_bit_to_index(bit_index);
+ size_t i = cmc_bidx_to_widx(bit_index);
_bitset_->buffer[i] &= ~(((cmc_bitset_word)1) << (bit_index % bits));
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->delete)
- _bitset_->callbacks->delete ();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete)
+ (_bitset_)->callbacks->delete ();
+ ;
return 1;
}
_Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
{
if (to < from)
{
- _bitset_->flag = cmc_flags.INVALID;
+ _bitset_->flag = CMC_FLAG_INVALID;
return 0;
}
if (!bs_impl_resize(_bitset_, to + 1, 0))
return 0;
- size_t start_index = bs_bit_to_index(from);
- size_t end_index = bs_bit_to_index(to);
+ size_t start_index = cmc_bidx_to_widx(from);
+ size_t end_index = cmc_bidx_to_widx(to);
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
cmc_bitset_word shift_start = from % bits;
@@ -206,9 +159,10 @@ _Bool bs_clear_range(struct bitset *_bitset_, size_t from, size_t to)
_bitset_->buffer[i] = 0;
_bitset_->buffer[end_index] &= ~end_mask;
}
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->delete)
- _bitset_->callbacks->delete ();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete)
+ (_bitset_)->callbacks->delete ();
+ ;
return 1;
}
_Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
@@ -216,24 +170,25 @@ _Bool bs_flip(struct bitset *_bitset_, size_t bit_index)
if (!bs_impl_resize(_bitset_, bit_index + 1, 0))
return 0;
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
- size_t i = bs_bit_to_index(bit_index);
+ size_t i = cmc_bidx_to_widx(bit_index);
_bitset_->buffer[i] ^= ((cmc_bitset_word)1) << (bit_index % bits);
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->update)
- _bitset_->callbacks->update();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->update)
+ (_bitset_)->callbacks->update();
+ ;
return 1;
}
_Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to)
{
if (to < from)
{
- _bitset_->flag = cmc_flags.INVALID;
+ _bitset_->flag = CMC_FLAG_INVALID;
return 0;
}
if (!bs_impl_resize(_bitset_, to + 1, 0))
return 0;
- size_t start_index = bs_bit_to_index(from);
- size_t end_index = bs_bit_to_index(to);
+ size_t start_index = cmc_bidx_to_widx(from);
+ size_t end_index = cmc_bidx_to_widx(to);
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
const cmc_bitset_word ones = ~((cmc_bitset_word)0);
cmc_bitset_word shift_start = from % bits;
@@ -251,9 +206,10 @@ _Bool bs_flip_range(struct bitset *_bitset_, size_t from, size_t to)
_bitset_->buffer[i] ^= ones;
_bitset_->buffer[end_index] ^= end_mask;
}
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->update)
- _bitset_->callbacks->update();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->update)
+ (_bitset_)->callbacks->update();
+ ;
return 1;
}
_Bool bs_put(struct bitset *_bitset_, size_t bit_index, _Bool state)
@@ -274,33 +230,36 @@ _Bool bs_set_all(struct bitset *_bitset_)
{
for (size_t i = 0; i < _bitset_->capacity; i++)
_bitset_->buffer[i] = ~((cmc_bitset_word)0);
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->create)
- _bitset_->callbacks->create();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
+ (_bitset_)->callbacks->create();
+ ;
return 1;
}
_Bool bs_clear_all(struct bitset *_bitset_)
{
for (size_t i = 0; i < _bitset_->capacity; i++)
_bitset_->buffer[i] = 0;
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->delete)
- _bitset_->callbacks->delete ();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->delete)
+ (_bitset_)->callbacks->delete ();
+ ;
return 1;
}
_Bool bs_flip_all(struct bitset *_bitset_)
{
for (size_t i = 0; i < _bitset_->capacity; i++)
_bitset_->buffer[i] ^= ~((cmc_bitset_word)0);
- _bitset_->flag = cmc_flags.OK;
- if (_bitset_->callbacks && _bitset_->callbacks->create)
- _bitset_->callbacks->create();
+ _bitset_->flag = CMC_FLAG_OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->create)
+ (_bitset_)->callbacks->create();
+ ;
return 1;
}
_Bool bs_get(struct bitset *_bitset_, size_t bit_index)
{
const cmc_bitset_word bits = sizeof(cmc_bitset_word) * 8;
- cmc_bitset_word w = _bitset_->buffer[bs_bit_to_index(bit_index)];
+ cmc_bitset_word w = _bitset_->buffer[cmc_bidx_to_widx(bit_index)];
return w & ((cmc_bitset_word)1 << (bit_index % bits));
}
_Bool bs_resize(struct bitset *_bitset_, size_t n_bits)
@@ -311,28 +270,25 @@ _Bool bs_impl_resize(struct bitset *_bitset_, size_t n_bits, _Bool do_resize)
{
if (n_bits == 0)
{
- _bitset_->flag = cmc_flags.INVALID;
+ _bitset_->flag = CMC_FLAG_INVALID;
return 0;
}
- size_t words = bs_bit_to_index(n_bits - 1) + 1;
+ size_t words = cmc_bidx_to_widx(n_bits - 1) + 1;
if (!do_resize && words <= _bitset_->capacity)
return 1;
- cmc_bitset_word *new_buffer =
- realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word));
+ cmc_bitset_word *new_buffer = realloc(_bitset_->buffer, words * sizeof(cmc_bitset_word));
if (!new_buffer)
{
- _bitset_->flag = cmc_flags.ALLOC;
+ _bitset_->flag = CMC_FLAG_ALLOC;
return 0;
}
_bitset_->buffer = new_buffer;
if (_bitset_->capacity < words)
- memset(_bitset_->buffer + _bitset_->capacity, 0,
- (words - _bitset_->capacity) * sizeof(cmc_bitset_word));
+ memset(_bitset_->buffer + _bitset_->capacity, 0, (words - _bitset_->capacity) * sizeof(cmc_bitset_word));
_bitset_->capacity = words;
- if (_bitset_->callbacks && _bitset_->callbacks->resize)
- _bitset_->callbacks->resize();
- _bitset_->flag = cmc_flags.OK;
+ if ((_bitset_)->callbacks && (_bitset_)->callbacks->resize)
+ (_bitset_)->callbacks->resize();
+ ;
+ _bitset_->flag = CMC_FLAG_OK;
return 1;
}
-
-#endif /* CMC_TEST_SRC_BITSET */
diff --git a/tests/main/src/deque.c b/tests/src/cmc/deque.c
similarity index 64%
rename from tests/main/src/deque.c
rename to tests/src/cmc/deque.c
index ba1e982..ede6e29 100644
--- a/tests/main/src/deque.c
+++ b/tests/src/cmc/deque.c
@@ -1,89 +1,14 @@
-#ifndef CMC_TEST_SRC_DEQUE
-#define CMC_TEST_SRC_DEQUE
#include "cmc/deque.h"
-struct deque
-{
- size_t *buffer;
- size_t capacity;
- size_t count;
- size_t front;
- size_t back;
- int flag;
- struct deque_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct deque_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct deque_iter
-{
- struct deque *target;
- size_t cursor;
- size_t index;
- _Bool start;
- _Bool end;
-};
-struct deque *d_new(size_t capacity, struct deque_fval *f_val);
-struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-struct deque d_init(size_t capacity, struct deque_fval *f_val);
-struct deque d_init_custom(size_t capacity, struct deque_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void d_clear(struct deque *_deque_);
-void d_free(struct deque *_deque_);
-void d_release(struct deque _deque_);
-void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool d_push_front(struct deque *_deque_, size_t value);
-_Bool d_push_back(struct deque *_deque_, size_t value);
-_Bool d_pop_front(struct deque *_deque_);
-_Bool d_pop_back(struct deque *_deque_);
-size_t d_front(struct deque *_deque_);
-size_t d_back(struct deque *_deque_);
-_Bool d_contains(struct deque *_deque_, size_t value);
-_Bool d_empty(struct deque *_deque_);
-_Bool d_full(struct deque *_deque_);
-size_t d_count(struct deque *_deque_);
-size_t d_capacity(struct deque *_deque_);
-int d_flag(struct deque *_deque_);
-_Bool d_resize(struct deque *_deque_, size_t capacity);
-struct deque *d_copy_of(struct deque *_deque_);
-_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_);
-struct cmc_string d_to_string(struct deque *_deque_);
-_Bool d_print(struct deque *_deque_, FILE *fptr);
-struct deque_iter d_iter_start(struct deque *target);
-struct deque_iter d_iter_end(struct deque *target);
-_Bool d_iter_at_start(struct deque_iter *iter);
-_Bool d_iter_at_end(struct deque_iter *iter);
-_Bool d_iter_to_start(struct deque_iter *iter);
-_Bool d_iter_to_end(struct deque_iter *iter);
-_Bool d_iter_next(struct deque_iter *iter);
-_Bool d_iter_prev(struct deque_iter *iter);
-_Bool d_iter_advance(struct deque_iter *iter, size_t steps);
-_Bool d_iter_rewind(struct deque_iter *iter, size_t steps);
-_Bool d_iter_go_to(struct deque_iter *iter, size_t index);
-size_t d_iter_value(struct deque_iter *iter);
-size_t *d_iter_rvalue(struct deque_iter *iter);
-size_t d_iter_index(struct deque_iter *iter);
struct deque *d_new(size_t capacity, struct deque_fval *f_val)
{
return d_new_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity < 1)
return ((void *)0);
if (!f_val)
@@ -103,38 +28,10 @@ struct deque *d_new_custom(size_t capacity, struct deque_fval *f_val,
_deque_->count = 0;
_deque_->front = 0;
_deque_->back = 0;
- _deque_->flag = cmc_flags.OK;
+ _deque_->flag = CMC_FLAG_OK;
_deque_->f_val = f_val;
_deque_->alloc = alloc;
- _deque_->callbacks = callbacks;
- return _deque_;
-}
-struct deque d_init(size_t capacity, struct deque_fval *f_val)
-{
- return d_init_custom(capacity, f_val, ((void *)0), ((void *)0));
-}
-struct deque d_init_custom(size_t capacity, struct deque_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
-{
- struct deque _deque_ = { 0 };
- if (capacity < 1)
- return _deque_;
- if (!f_val)
- return _deque_;
- if (!alloc)
- alloc = &cmc_alloc_node_default;
- _deque_.buffer = alloc->calloc(capacity, sizeof(size_t));
- if (!_deque_.buffer)
- return _deque_;
- _deque_.capacity = capacity;
- _deque_.count = 0;
- _deque_.front = 0;
- _deque_.back = 0;
- _deque_.flag = cmc_flags.OK;
- _deque_.f_val = f_val;
- _deque_.alloc = alloc;
- _deque_.callbacks = callbacks;
+ (_deque_)->callbacks = callbacks;
return _deque_;
}
void d_clear(struct deque *_deque_)
@@ -151,7 +48,7 @@ void d_clear(struct deque *_deque_)
_deque_->count = 0;
_deque_->front = 0;
_deque_->back = 0;
- _deque_->flag = cmc_flags.OK;
+ _deque_->flag = CMC_FLAG_OK;
}
void d_free(struct deque *_deque_)
{
@@ -166,27 +63,15 @@ void d_free(struct deque *_deque_)
_deque_->alloc->free(_deque_->buffer);
_deque_->alloc->free(_deque_);
}
-void d_release(struct deque _deque_)
-{
- if (_deque_.f_val->free)
- {
- for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++)
- {
- _deque_.f_val->free(_deque_.buffer[i]);
- i = (i + 1) % _deque_.capacity;
- }
- }
- _deque_.alloc->free(_deque_.buffer);
-}
-void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void d_customize(struct deque *_deque_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_deque_->alloc = &cmc_alloc_node_default;
else
_deque_->alloc = alloc;
- _deque_->callbacks = callbacks;
- _deque_->flag = cmc_flags.OK;
+ (_deque_)->callbacks = callbacks;
+ _deque_->flag = CMC_FLAG_OK;
}
_Bool d_push_front(struct deque *_deque_, size_t value)
{
@@ -195,13 +80,13 @@ _Bool d_push_front(struct deque *_deque_, size_t value)
if (!d_resize(_deque_, _deque_->capacity * 2))
return 0;
}
- _deque_->front =
- (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1;
+ _deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1;
_deque_->buffer[_deque_->front] = value;
_deque_->count++;
- _deque_->flag = cmc_flags.OK;
- if (_deque_->callbacks && _deque_->callbacks->create)
- _deque_->callbacks->create();
+ _deque_->flag = CMC_FLAG_OK;
+ if ((_deque_)->callbacks && (_deque_)->callbacks->create)
+ (_deque_)->callbacks->create();
+ ;
return 1;
}
_Bool d_push_back(struct deque *_deque_, size_t value)
@@ -212,74 +97,75 @@ _Bool d_push_back(struct deque *_deque_, size_t value)
return 0;
}
_deque_->buffer[_deque_->back] = value;
- _deque_->back =
- (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1;
+ _deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1;
_deque_->count++;
- _deque_->flag = cmc_flags.OK;
- if (_deque_->callbacks && _deque_->callbacks->create)
- _deque_->callbacks->create();
+ _deque_->flag = CMC_FLAG_OK;
+ if ((_deque_)->callbacks && (_deque_)->callbacks->create)
+ (_deque_)->callbacks->create();
+ ;
return 1;
}
_Bool d_pop_front(struct deque *_deque_)
{
if (d_empty(_deque_))
{
- _deque_->flag = cmc_flags.EMPTY;
+ _deque_->flag = CMC_FLAG_EMPTY;
return 0;
}
_deque_->buffer[_deque_->front] = (size_t){ 0 };
- _deque_->front =
- (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1;
+ _deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1;
_deque_->count--;
- _deque_->flag = cmc_flags.OK;
- if (_deque_->callbacks && _deque_->callbacks->delete)
- _deque_->callbacks->delete ();
+ _deque_->flag = CMC_FLAG_OK;
+ if ((_deque_)->callbacks && (_deque_)->callbacks->delete)
+ (_deque_)->callbacks->delete ();
+ ;
return 1;
}
_Bool d_pop_back(struct deque *_deque_)
{
if (d_empty(_deque_))
{
- _deque_->flag = cmc_flags.EMPTY;
+ _deque_->flag = CMC_FLAG_EMPTY;
return 0;
}
- _deque_->back =
- (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1;
+ _deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1;
_deque_->buffer[_deque_->back] = (size_t){ 0 };
_deque_->count--;
- _deque_->flag = cmc_flags.OK;
- if (_deque_->callbacks && _deque_->callbacks->delete)
- _deque_->callbacks->delete ();
+ _deque_->flag = CMC_FLAG_OK;
+ if ((_deque_)->callbacks && (_deque_)->callbacks->delete)
+ (_deque_)->callbacks->delete ();
+ ;
return 1;
}
size_t d_front(struct deque *_deque_)
{
if (d_empty(_deque_))
{
- _deque_->flag = cmc_flags.EMPTY;
+ _deque_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _deque_->flag = cmc_flags.OK;
- if (_deque_->callbacks && _deque_->callbacks->read)
- _deque_->callbacks->read();
+ _deque_->flag = CMC_FLAG_OK;
+ if ((_deque_)->callbacks && (_deque_)->callbacks->read)
+ (_deque_)->callbacks->read();
+ ;
return _deque_->buffer[_deque_->front];
}
size_t d_back(struct deque *_deque_)
{
if (d_empty(_deque_))
{
- _deque_->flag = cmc_flags.EMPTY;
+ _deque_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _deque_->flag = cmc_flags.OK;
- if (_deque_->callbacks && _deque_->callbacks->read)
- _deque_->callbacks->read();
- return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1
- : _deque_->back - 1];
+ _deque_->flag = CMC_FLAG_OK;
+ if ((_deque_)->callbacks && (_deque_)->callbacks->read)
+ (_deque_)->callbacks->read();
+ ;
+ return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1];
}
_Bool d_contains(struct deque *_deque_, size_t value)
{
- _deque_->flag = cmc_flags.OK;
+ _deque_->flag = CMC_FLAG_OK;
_Bool result = 0;
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
{
@@ -290,8 +176,9 @@ _Bool d_contains(struct deque *_deque_, size_t value)
}
i = (i + 1) % _deque_->capacity;
}
- if (_deque_->callbacks && _deque_->callbacks->read)
- _deque_->callbacks->read();
+ if ((_deque_)->callbacks && (_deque_)->callbacks->read)
+ (_deque_)->callbacks->read();
+ ;
return result;
}
_Bool d_empty(struct deque *_deque_)
@@ -316,18 +203,18 @@ int d_flag(struct deque *_deque_)
}
_Bool d_resize(struct deque *_deque_, size_t capacity)
{
- _deque_->flag = cmc_flags.OK;
+ _deque_->flag = CMC_FLAG_OK;
if (_deque_->capacity == capacity)
goto success;
if (capacity < _deque_->count)
{
- _deque_->flag = cmc_flags.INVALID;
+ _deque_->flag = CMC_FLAG_INVALID;
return 0;
}
size_t *new_buffer = _deque_->alloc->malloc(sizeof(size_t) * capacity);
if (!new_buffer)
{
- _deque_->flag = cmc_flags.ALLOC;
+ _deque_->flag = CMC_FLAG_ALLOC;
return 0;
}
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
@@ -341,19 +228,20 @@ _Bool d_resize(struct deque *_deque_, size_t capacity)
_deque_->front = 0;
_deque_->back = _deque_->count;
success:
- if (_deque_->callbacks && _deque_->callbacks->resize)
- _deque_->callbacks->resize();
+ if ((_deque_)->callbacks && (_deque_)->callbacks->resize)
+ (_deque_)->callbacks->resize();
+ ;
return 1;
}
struct deque *d_copy_of(struct deque *_deque_)
{
- struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val,
- _deque_->alloc, _deque_->callbacks);
+ struct deque *result = d_new_custom(_deque_->capacity, _deque_->f_val, _deque_->alloc, ((void *)0));
if (!result)
{
- _deque_->flag = cmc_flags.ERROR;
+ _deque_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _deque_->callbacks;
if (_deque_->f_val->cpy)
{
for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
@@ -373,18 +261,17 @@ struct deque *d_copy_of(struct deque *_deque_)
result->count = _deque_->count;
result->front = 0;
result->back = _deque_->count;
- _deque_->flag = cmc_flags.OK;
+ _deque_->flag = CMC_FLAG_OK;
return result;
}
_Bool d_equals(struct deque *_deque1_, struct deque *_deque2_)
{
- _deque1_->flag = cmc_flags.OK;
- _deque2_->flag = cmc_flags.OK;
+ _deque1_->flag = CMC_FLAG_OK;
+ _deque2_->flag = CMC_FLAG_OK;
if (_deque1_->count != _deque2_->count)
return 0;
size_t i, j, k;
- for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count;
- k++)
+ for (i = _deque1_->front, j = _deque2_->front, k = 0; k < _deque1_->count; k++)
{
if (_deque1_->f_val->cmp(_deque1_->buffer[i], _deque2_->buffer[j]) != 0)
return 0;
@@ -393,25 +280,45 @@ _Bool d_equals(struct deque *_deque1_, struct deque *_deque2_)
}
return 1;
}
-struct cmc_string d_to_string(struct deque *_deque_)
+struct deque d_init(size_t capacity, struct deque_fval *f_val)
{
- struct cmc_string str;
- struct deque *d_ = _deque_;
- int n =
- snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, "deque", "size_t",
- d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back,
- d_->flag, d_->f_val, d_->alloc, d_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
+ return d_init_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-_Bool d_print(struct deque *_deque_, FILE *fptr)
+struct deque d_init_custom(size_t capacity, struct deque_fval *f_val, struct cmc_alloc_node *alloc,
+ struct cmc_callbacks *callbacks)
{
- for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
+ ;
+ struct deque _deque_ = { 0 };
+ if (capacity < 1)
+ return _deque_;
+ if (!f_val)
+ return _deque_;
+ if (!alloc)
+ alloc = &cmc_alloc_node_default;
+ _deque_.buffer = alloc->calloc(capacity, sizeof(size_t));
+ if (!_deque_.buffer)
+ return _deque_;
+ _deque_.capacity = capacity;
+ _deque_.count = 0;
+ _deque_.front = 0;
+ _deque_.back = 0;
+ _deque_.flag = CMC_FLAG_OK;
+ _deque_.f_val = f_val;
+ _deque_.alloc = alloc;
+ (&_deque_)->callbacks = callbacks;
+ return _deque_;
+}
+void d_release(struct deque _deque_)
+{
+ if (_deque_.f_val->free)
{
- if (!_deque_->f_val->str(fptr, _deque_->buffer[i]))
- return 0;
- i = (i + 1) % _deque_->capacity;
+ for (size_t i = _deque_.front, j = 0; j < _deque_.count; j++)
+ {
+ _deque_.f_val->free(_deque_.buffer[i]);
+ i = (i + 1) % _deque_.capacity;
+ }
}
- return 1;
+ _deque_.alloc->free(_deque_.buffer);
}
struct deque_iter d_iter_start(struct deque *target)
{
@@ -503,8 +410,7 @@ _Bool d_iter_prev(struct deque_iter *iter)
return 0;
}
iter->end = d_empty(iter->target);
- iter->cursor =
- (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1;
+ iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1;
iter->index--;
return 1;
}
@@ -568,5 +474,43 @@ size_t d_iter_index(struct deque_iter *iter)
{
return iter->index;
}
-
-#endif /* CMC_TEST_SRC_DEQUE */
+_Bool d_to_string(struct deque *_deque_, FILE *fptr)
+{
+ struct deque *d_ = _deque_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "front:%"
+ "I64u"
+ ", "
+ "back:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "deque", "size_t", d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back, d_->flag,
+ d_->f_val, d_->alloc, (d_)->callbacks);
+}
+_Bool d_print(struct deque *_deque_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ for (size_t i = _deque_->front, j = 0; j < _deque_->count; j++)
+ {
+ if (!_deque_->f_val->str(fptr, _deque_->buffer[i]))
+ return 0;
+ i = (i + 1) % _deque_->capacity;
+ if (j + 1 < _deque_->count)
+ fprintf(fptr, "%s", separator);
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
+}
diff --git a/tests/main/src/hashbidimap.c b/tests/src/cmc/hashbidimap.c
similarity index 61%
rename from tests/main/src/hashbidimap.c
rename to tests/src/cmc/hashbidimap.c
index d8e98b8..c7a1b70 100644
--- a/tests/main/src/hashbidimap.c
+++ b/tests/src/cmc/hashbidimap.c
@@ -1,162 +1,24 @@
-#ifndef CMC_TEST_SRC_HASHBIDIMAP
-#define CMC_TEST_SRC_HASHBIDIMAP
#include "cmc/hashbidimap.h"
-struct hashbidimap
-{
- struct hashbidimap_entry *(*buffer)[2];
- size_t capacity;
- size_t count;
- double load;
- int flag;
- struct hashbidimap_fkey *f_key;
- struct hashbidimap_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
- struct hashbidimap_iter (*it_start)(struct hashbidimap *);
- struct hashbidimap_iter (*it_end)(struct hashbidimap *);
-};
-struct hashbidimap_entry
-{
- size_t key;
- size_t value;
- size_t dist[2];
- struct hashbidimap_entry **ref[2];
-};
-struct hashbidimap_fkey
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashbidimap_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashbidimap_iter
-{
- struct hashbidimap *target;
- size_t cursor;
- size_t index;
- size_t first;
- size_t last;
- _Bool start;
- _Bool end;
-};
-struct hashbidimap *hbm_new(size_t capacity, double load,
- struct hashbidimap_fkey *f_key,
- struct hashbidimap_fval *f_val);
-struct hashbidimap *hbm_new_custom(size_t capacity, double load,
- struct hashbidimap_fkey *f_key,
- struct hashbidimap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void hbm_clear(struct hashbidimap *_map_);
-void hbm_free(struct hashbidimap *_map_);
-void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value);
-_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key);
-_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val);
-_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key,
- size_t *out_val);
-_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key,
- size_t *out_val);
-size_t hbm_get_key(struct hashbidimap *_map_, size_t val);
-size_t hbm_get_val(struct hashbidimap *_map_, size_t key);
-_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key);
-_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val);
-_Bool hbm_empty(struct hashbidimap *_map_);
-_Bool hbm_full(struct hashbidimap *_map_);
-size_t hbm_count(struct hashbidimap *_map_);
-size_t hbm_capacity(struct hashbidimap *_map_);
-double hbm_load(struct hashbidimap *_map_);
-int hbm_flag(struct hashbidimap *_map_);
-_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity);
-struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_);
-_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_);
-struct cmc_string hbm_to_string(struct hashbidimap *_map_);
-_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr);
-struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target);
-void hbm_iter_free(struct hashbidimap_iter *iter);
-void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target);
-_Bool hbm_iter_start(struct hashbidimap_iter *iter);
-_Bool hbm_iter_end(struct hashbidimap_iter *iter);
-void hbm_iter_to_start(struct hashbidimap_iter *iter);
-void hbm_iter_to_end(struct hashbidimap_iter *iter);
-_Bool hbm_iter_next(struct hashbidimap_iter *iter);
-_Bool hbm_iter_prev(struct hashbidimap_iter *iter);
-_Bool hbm_iter_advance(struct hashbidimap_iter *iter, size_t steps);
-_Bool hbm_iter_rewind(struct hashbidimap_iter *iter, size_t steps);
-_Bool hbm_iter_go_to(struct hashbidimap_iter *iter, size_t index);
-size_t hbm_iter_key(struct hashbidimap_iter *iter);
-size_t hbm_iter_value(struct hashbidimap_iter *iter);
-size_t hbm_iter_index(struct hashbidimap_iter *iter);
-static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_,
- size_t key, size_t value);
-static struct hashbidimap_entry **
-hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key);
-static struct hashbidimap_entry **
-hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val);
-static struct hashbidimap_entry **
-hbm_impl_add_entry_to_key(struct hashbidimap *_map_,
- struct hashbidimap_entry *entry);
-static struct hashbidimap_entry **
-hbm_impl_add_entry_to_val(struct hashbidimap *_map_,
- struct hashbidimap_entry *entry);
+static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value);
+static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key);
+static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val);
+static struct hashbidimap_entry **hbm_impl_add_entry_to_key(struct hashbidimap *_map_, struct hashbidimap_entry *entry);
+static struct hashbidimap_entry **hbm_impl_add_entry_to_val(struct hashbidimap *_map_, struct hashbidimap_entry *entry);
static size_t hbm_impl_calculate_size(size_t required);
static struct hashbidimap_iter hbm_impl_it_start(struct hashbidimap *_map_);
static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_);
-struct hashbidimap *hbm_new(size_t capacity, double load,
- struct hashbidimap_fkey *f_key,
+struct hashbidimap *hbm_new(size_t capacity, double load, struct hashbidimap_fkey *f_key,
struct hashbidimap_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity == 0 || load <= 0 || load >= 1)
- return ((void *)0);
- if (capacity >= 0xffffffffffffffffULL * load)
- return ((void *)0);
- if (!f_key || !f_val)
- return ((void *)0);
- size_t real_capacity = hbm_impl_calculate_size(capacity / load);
- struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap));
- if (!_map_)
- return ((void *)0);
- _map_->buffer =
- alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2]));
- if (!_map_->buffer)
- {
- alloc->free(_map_->buffer);
- alloc->free(_map_);
- return ((void *)0);
- }
- _map_->count = 0;
- _map_->capacity = real_capacity;
- _map_->load = load;
- _map_->flag = cmc_flags.OK;
- _map_->f_key = f_key;
- _map_->f_val = f_val;
- _map_->alloc = alloc;
- _map_->callbacks = ((void *)0);
- _map_->it_start = hbm_impl_it_start;
- _map_->it_end = hbm_impl_it_end;
- return _map_;
+ return hbm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
}
-struct hashbidimap *hbm_new_custom(size_t capacity, double load,
- struct hashbidimap_fkey *f_key,
- struct hashbidimap_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct hashbidimap *hbm_new_custom(size_t capacity, double load, struct hashbidimap_fkey *f_key,
+ struct hashbidimap_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity == 0 || load <= 0 || load >= 1)
return ((void *)0);
if (capacity >= 0xffffffffffffffffULL * load)
@@ -169,8 +31,7 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load,
struct hashbidimap *_map_ = alloc->malloc(sizeof(struct hashbidimap));
if (!_map_)
return ((void *)0);
- _map_->buffer =
- alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2]));
+ _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashbidimap_entry *[2]));
if (!_map_->buffer)
{
alloc->free(_map_->buffer);
@@ -180,12 +41,12 @@ struct hashbidimap *hbm_new_custom(size_t capacity, double load,
_map_->count = 0;
_map_->capacity = real_capacity;
_map_->load = load;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_map_->f_key = f_key;
_map_->f_val = f_val;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
+ (_map_)->callbacks = callbacks;
_map_->it_start = hbm_impl_it_start;
_map_->it_end = hbm_impl_it_end;
return _map_;
@@ -207,7 +68,7 @@ void hbm_clear(struct hashbidimap *_map_)
_map_->buffer[i][1] = ((void *)0);
}
_map_->count = 0;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
}
void hbm_free(struct hashbidimap *_map_)
{
@@ -215,15 +76,15 @@ void hbm_free(struct hashbidimap *_map_)
_map_->alloc->free(_map_->buffer);
_map_->alloc->free(_map_);
}
-void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void hbm_customize(struct hashbidimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_map_->alloc = &cmc_alloc_node_default;
else
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
- _map_->flag = cmc_flags.OK;
+ (_map_)->callbacks = callbacks;
+ _map_->flag = CMC_FLAG_OK;
}
_Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value)
{
@@ -232,17 +93,14 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value)
if (!hbm_resize(_map_, _map_->capacity + 1))
return 0;
}
- if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) ||
- hbm_impl_get_entry_by_val(_map_, value) != ((void *)0))
+ if (hbm_impl_get_entry_by_key(_map_, key) != ((void *)0) || hbm_impl_get_entry_by_val(_map_, value) != ((void *)0))
{
- _map_->flag = cmc_flags.DUPLICATE;
+ _map_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
struct hashbidimap_entry *entry = hbm_impl_new_entry(_map_, key, value);
- struct hashbidimap_entry **key_entry =
- hbm_impl_add_entry_to_key(_map_, entry);
- struct hashbidimap_entry **val_entry =
- hbm_impl_add_entry_to_val(_map_, entry);
+ struct hashbidimap_entry **key_entry = hbm_impl_add_entry_to_key(_map_, entry);
+ struct hashbidimap_entry **val_entry = hbm_impl_add_entry_to_val(_map_, entry);
if (!key_entry || !val_entry)
{
if (key_entry)
@@ -250,40 +108,41 @@ _Bool hbm_insert(struct hashbidimap *_map_, size_t key, size_t value)
if (val_entry)
*val_entry = ((void *)1);
_map_->alloc->free(entry);
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
_map_->count++;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->create)
- _map_->callbacks->create();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->create)
+ (_map_)->callbacks->create();
+ ;
return 1;
}
_Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key)
{
if (hbm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashbidimap_entry **key_entry, **val_entry;
val_entry = hbm_impl_get_entry_by_val(_map_, val);
if (!val_entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (_map_->f_key->cmp(new_key, (*val_entry)->key) == 0)
goto success;
if (hbm_impl_get_entry_by_key(_map_, new_key) != ((void *)0))
{
- _map_->flag = cmc_flags.DUPLICATE;
+ _map_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
key_entry = (*val_entry)->ref[0];
if (!key_entry || *key_entry != *val_entry)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashbidimap_entry *to_add = *key_entry;
@@ -294,40 +153,41 @@ _Bool hbm_update_key(struct hashbidimap *_map_, size_t val, size_t new_key)
{
to_add->key = tmp_key;
*key_entry = to_add;
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
success:
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->update)
- _map_->callbacks->update();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->update)
+ (_map_)->callbacks->update();
+ ;
return 1;
}
_Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val)
{
if (hbm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashbidimap_entry **key_entry, **val_entry;
key_entry = hbm_impl_get_entry_by_key(_map_, key);
if (!key_entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (_map_->f_key->cmp(new_val, (*key_entry)->value) == 0)
goto success;
if (hbm_impl_get_entry_by_val(_map_, new_val) != ((void *)0))
{
- _map_->flag = cmc_flags.DUPLICATE;
+ _map_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
val_entry = (*key_entry)->ref[1];
if (!val_entry || *val_entry != *key_entry)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashbidimap_entry *to_add = *val_entry;
@@ -338,34 +198,34 @@ _Bool hbm_update_val(struct hashbidimap *_map_, size_t key, size_t new_val)
{
to_add->value = tmp_val;
*val_entry = to_add;
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
success:
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->update)
- _map_->callbacks->update();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->update)
+ (_map_)->callbacks->update();
+ ;
return 1;
}
-_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key,
- size_t *out_val)
+_Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key, size_t *out_val)
{
if (hbm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashbidimap_entry **key_entry, **val_entry;
key_entry = hbm_impl_get_entry_by_key(_map_, key);
if (!key_entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
val_entry = (*key_entry)->ref[1];
if (!val_entry || *val_entry != *key_entry)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
if (out_key)
@@ -376,30 +236,30 @@ _Bool hbm_remove_by_key(struct hashbidimap *_map_, size_t key, size_t *out_key,
*key_entry = ((void *)1);
*val_entry = ((void *)1);
_map_->count--;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->delete)
- _map_->callbacks->delete ();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->delete)
+ (_map_)->callbacks->delete ();
+ ;
return 1;
}
-_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key,
- size_t *out_val)
+_Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key, size_t *out_val)
{
if (hbm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashbidimap_entry **key_entry, **val_entry;
val_entry = hbm_impl_get_entry_by_val(_map_, val);
if (!val_entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
key_entry = (*val_entry)->ref[0];
if (!key_entry || *key_entry != *val_entry)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
if (out_key)
@@ -410,9 +270,10 @@ _Bool hbm_remove_by_val(struct hashbidimap *_map_, size_t val, size_t *out_key,
*key_entry = ((void *)1);
*val_entry = ((void *)1);
_map_->count--;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->delete)
- _map_->callbacks->delete ();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->delete)
+ (_map_)->callbacks->delete ();
+ ;
return 1;
}
size_t hbm_get_key(struct hashbidimap *_map_, size_t val)
@@ -420,12 +281,13 @@ size_t hbm_get_key(struct hashbidimap *_map_, size_t val)
struct hashbidimap_entry **entry = hbm_impl_get_entry_by_val(_map_, val);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return (size_t){ 0 };
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return (*entry)->key;
}
size_t hbm_get_val(struct hashbidimap *_map_, size_t key)
@@ -433,28 +295,31 @@ size_t hbm_get_val(struct hashbidimap *_map_, size_t key)
struct hashbidimap_entry **entry = hbm_impl_get_entry_by_key(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return (size_t){ 0 };
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return (*entry)->value;
}
_Bool hbm_contains_key(struct hashbidimap *_map_, size_t key)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_Bool result = hbm_impl_get_entry_by_key(_map_, key) != ((void *)0);
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return result;
}
_Bool hbm_contains_val(struct hashbidimap *_map_, size_t val)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_Bool result = hbm_impl_get_entry_by_val(_map_, val) != ((void *)0);
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return result;
}
_Bool hbm_empty(struct hashbidimap *_map_)
@@ -483,28 +348,27 @@ int hbm_flag(struct hashbidimap *_map_)
}
_Bool hbm_resize(struct hashbidimap *_map_, size_t capacity)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
if (_map_->capacity == capacity)
goto success;
if (_map_->capacity > capacity / _map_->load)
goto success;
if (capacity >= 0xffffffffffffffffULL * _map_->load)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
size_t new_cap = hbm_impl_calculate_size(capacity);
if (new_cap < _map_->count / _map_->load)
{
- _map_->flag = cmc_flags.INVALID;
+ _map_->flag = CMC_FLAG_INVALID;
return 0;
}
struct hashbidimap *_new_map_ =
- hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val,
- _map_->alloc, ((void *)0));
+ hbm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0));
if (!_new_map_)
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
for (size_t i = 0; i < _map_->capacity; i++)
@@ -512,17 +376,15 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity)
struct hashbidimap_entry *scan = _map_->buffer[i][0];
if (scan && scan != ((void *)1))
{
- struct hashbidimap_entry **e1 =
- hbm_impl_add_entry_to_key(_new_map_, scan);
- struct hashbidimap_entry **e2 =
- hbm_impl_add_entry_to_val(_new_map_, scan);
+ struct hashbidimap_entry **e1 = hbm_impl_add_entry_to_key(_new_map_, scan);
+ struct hashbidimap_entry **e2 = hbm_impl_add_entry_to_val(_new_map_, scan);
if (!e1 || !e2)
{
_new_map_->f_key = &(struct hashbidimap_fkey){ ((void *)0) };
_new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) };
_map_->alloc->free(_new_map_->buffer);
_map_->alloc->free(_new_map_);
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
_new_map_->count++;
@@ -534,7 +396,7 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity)
_new_map_->f_val = &(struct hashbidimap_fval){ ((void *)0) };
_map_->alloc->free(_new_map_->buffer);
_map_->alloc->free(_new_map_);
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashbidimap_entry *(*tmp_buff)[2] = _map_->buffer;
@@ -543,20 +405,21 @@ _Bool hbm_resize(struct hashbidimap *_map_, size_t capacity)
_map_->alloc->free(tmp_buff);
_map_->alloc->free(_new_map_);
success:
- if (_map_->callbacks && _map_->callbacks->resize)
- _map_->callbacks->resize();
+ if ((_map_)->callbacks && (_map_)->callbacks->resize)
+ (_map_)->callbacks->resize();
+ ;
return 1;
}
struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_)
{
- struct hashbidimap *result =
- hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key,
- _map_->f_val, _map_->alloc, _map_->callbacks);
+ struct hashbidimap *result = hbm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val,
+ _map_->alloc, ((void *)0));
if (!result)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _map_->callbacks;
for (size_t i = 0; i < _map_->capacity; i++)
{
struct hashbidimap_entry *scan = _map_->buffer[i][0];
@@ -572,20 +435,19 @@ struct hashbidimap *hbm_copy_of(struct hashbidimap *_map_)
tmp_val = _map_->f_val->cpy(scan->value);
else
tmp_val = scan->value;
- struct hashbidimap_entry *entry =
- hbm_impl_new_entry(result, tmp_key, tmp_val);
+ struct hashbidimap_entry *entry = hbm_impl_new_entry(result, tmp_key, tmp_val);
hbm_impl_add_entry_to_key(result, entry);
hbm_impl_add_entry_to_val(result, entry);
result->count++;
}
}
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
return result;
}
_Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_)
{
- _map1_->flag = cmc_flags.OK;
- _map2_->flag = cmc_flags.OK;
+ _map1_->flag = CMC_FLAG_OK;
+ _map2_->flag = CMC_FLAG_OK;
if (_map1_->count != _map2_->count)
return 0;
struct hashbidimap *_mapA_;
@@ -605,8 +467,7 @@ _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_)
struct hashbidimap_entry *scan = _mapA_->buffer[i][0];
if (scan && scan != ((void *)1))
{
- struct hashbidimap_entry **entry_B =
- hbm_impl_get_entry_by_key(_mapB_, scan->key);
+ struct hashbidimap_entry **entry_B = hbm_impl_get_entry_by_key(_mapB_, scan->key);
if (!entry_B)
return 0;
if (_mapA_->f_val->cmp((*entry_B)->value, scan->value) != 0)
@@ -615,34 +476,9 @@ _Bool hbm_equals(struct hashbidimap *_map1_, struct hashbidimap *_map2_)
}
return 1;
}
-struct cmc_string hbm_to_string(struct hashbidimap *_map_)
-{
- struct cmc_string str;
- struct hashbidimap *m_ = _map_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashbidimap,
- "hashbidimap", "size_t", "size_t", m_, m_->buffer,
- m_->capacity, m_->count, m_->load, m_->flag, m_->f_key,
- m_->f_val, m_->alloc, m_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr)
-{
- for (size_t i = 0; i < _map_->capacity; i++)
- {
- struct hashbidimap_entry *target = _map_->buffer[i][0];
- if (target && target != ((void *)1))
- {
- if (!_map_->f_key->str(fptr, target->key) ||
- !_map_->f_val->str(fptr, target->value))
- return 0;
- }
- }
- return 1;
-}
struct hashbidimap_iter *hbm_iter_new(struct hashbidimap *target)
{
- struct hashbidimap_iter *iter =
- target->alloc->malloc(sizeof(struct hashbidimap_iter));
+ struct hashbidimap_iter *iter = target->alloc->malloc(sizeof(struct hashbidimap_iter));
if (!iter)
return ((void *)0);
hbm_iter_init(iter, target);
@@ -662,8 +498,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target)
{
for (size_t i = 0; i < target->capacity; i++)
{
- struct hashbidimap_entry *tmp = target->buffer[i][0];
- if (tmp != ((void *)0) && tmp != ((void *)1))
+ struct hashbidimap_entry *entry = target->buffer[i][0];
+ if (entry && entry != ((void *)1))
{
iter->first = i;
break;
@@ -672,8 +508,8 @@ void hbm_iter_init(struct hashbidimap_iter *iter, struct hashbidimap *target)
iter->cursor = iter->first;
for (size_t i = target->capacity; i > 0; i--)
{
- struct hashbidimap_entry *tmp = target->buffer[i - 1][0];
- if (tmp != ((void *)0) && tmp != ((void *)1))
+ struct hashbidimap_entry *entry = target->buffer[i - 1][0];
+ if (entry && entry != ((void *)1))
{
iter->last = i - 1;
break;
@@ -795,7 +631,7 @@ size_t hbm_iter_key(struct hashbidimap_iter *iter)
{
if (hbm_empty(iter->target))
{
- iter->target->flag = cmc_flags.EMPTY;
+ iter->target->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
return iter->target->buffer[iter->cursor][0]->key;
@@ -804,7 +640,7 @@ size_t hbm_iter_value(struct hashbidimap_iter *iter)
{
if (hbm_empty(iter->target))
{
- iter->target->flag = cmc_flags.EMPTY;
+ iter->target->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
return iter->target->buffer[iter->cursor][0]->value;
@@ -813,11 +649,9 @@ size_t hbm_iter_index(struct hashbidimap_iter *iter)
{
return iter->index;
}
-static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_,
- size_t key, size_t value)
+static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_, size_t key, size_t value)
{
- struct hashbidimap_entry *entry =
- _map_->alloc->malloc(sizeof(struct hashbidimap_entry));
+ struct hashbidimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashbidimap_entry));
if (!entry)
return ((void *)0);
entry->key = key;
@@ -828,8 +662,7 @@ static struct hashbidimap_entry *hbm_impl_new_entry(struct hashbidimap *_map_,
entry->ref[1] = ((void *)0);
return entry;
}
-static struct hashbidimap_entry **
-hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key)
+static struct hashbidimap_entry **hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key)
{
size_t hash = _map_->f_key->hash(key);
size_t pos = hash % _map_->capacity;
@@ -843,8 +676,7 @@ hbm_impl_get_entry_by_key(struct hashbidimap *_map_, size_t key)
}
return ((void *)0);
}
-static struct hashbidimap_entry **
-hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val)
+static struct hashbidimap_entry **hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val)
{
size_t hash = _map_->f_val->hash(val);
size_t pos = hash % _map_->capacity;
@@ -858,16 +690,13 @@ hbm_impl_get_entry_by_val(struct hashbidimap *_map_, size_t val)
}
return ((void *)0);
}
-static struct hashbidimap_entry **
-hbm_impl_add_entry_to_key(struct hashbidimap *_map_,
- struct hashbidimap_entry *entry)
+static struct hashbidimap_entry **hbm_impl_add_entry_to_key(struct hashbidimap *_map_, struct hashbidimap_entry *entry)
{
struct hashbidimap_entry **to_return = ((void *)0);
size_t hash = _map_->f_key->hash(entry->key);
size_t original_pos = hash % _map_->capacity;
size_t pos = original_pos;
- struct hashbidimap_entry **scan =
- &(_map_->buffer[hash % _map_->capacity][0]);
+ struct hashbidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][0]);
if (*scan == ((void *)0))
{
*scan = entry;
@@ -905,16 +734,13 @@ hbm_impl_add_entry_to_key(struct hashbidimap *_map_,
}
return ((void *)0);
}
-static struct hashbidimap_entry **
-hbm_impl_add_entry_to_val(struct hashbidimap *_map_,
- struct hashbidimap_entry *entry)
+static struct hashbidimap_entry **hbm_impl_add_entry_to_val(struct hashbidimap *_map_, struct hashbidimap_entry *entry)
{
struct hashbidimap_entry **to_return = ((void *)0);
size_t hash = _map_->f_val->hash(entry->value);
size_t original_pos = hash % _map_->capacity;
size_t pos = original_pos;
- struct hashbidimap_entry **scan =
- &(_map_->buffer[hash % _map_->capacity][1]);
+ struct hashbidimap_entry **scan = &(_map_->buffer[hash % _map_->capacity][1]);
if (*scan == ((void *)0))
{
*scan = entry;
@@ -954,8 +780,7 @@ hbm_impl_add_entry_to_val(struct hashbidimap *_map_,
}
static size_t hbm_impl_calculate_size(size_t required)
{
- const size_t count =
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
if (cmc_hashtable_primes[count - 1] < required)
return required;
size_t i = 0;
@@ -976,5 +801,56 @@ static struct hashbidimap_iter hbm_impl_it_end(struct hashbidimap *_map_)
hbm_iter_to_end(&iter);
return iter;
}
-
-#endif /* CMC_TEST_SRC_HASHBIDIMAP */
+_Bool hbm_to_string(struct hashbidimap *_map_, FILE *fptr)
+{
+ struct hashbidimap *m_ = _map_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s, %s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "load:%lf, "
+ "flag:%d, "
+ "f_key:%p, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "hashbidimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag,
+ m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks);
+}
+_Bool hbm_print(struct hashbidimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep)
+{
+ fprintf(fptr, "%s", start);
+ size_t last = 0;
+ for (size_t i = _map_->capacity; i > 0; i--)
+ {
+ struct hashbidimap_entry *entry = _map_->buffer[i - 1][0];
+ if (entry && entry != ((void *)1))
+ {
+ last = i - 1;
+ break;
+ }
+ }
+ for (size_t i = 0; i < _map_->capacity; i++)
+ {
+ struct hashbidimap_entry *entry = _map_->buffer[i][0];
+ if (entry && entry != ((void *)1))
+ {
+ if (!_map_->f_key->str(fptr, entry->key))
+ return 0;
+ fprintf(fptr, "%s", key_val_sep);
+ if (!_map_->f_val->str(fptr, entry->value))
+ return 0;
+ if (i + 1 < last)
+ fprintf(fptr, "%s", separator);
+ }
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
+}
diff --git a/tests/main/src/hashmap.c b/tests/src/cmc/hashmap.c
similarity index 62%
rename from tests/main/src/hashmap.c
rename to tests/src/cmc/hashmap.c
index b771ab4..20f99e5 100644
--- a/tests/main/src/hashmap.c
+++ b/tests/src/cmc/hashmap.c
@@ -1,124 +1,16 @@
-#ifndef CMC_TEST_SRC_HASHMAP
-#define CMC_TEST_SRC_HASHMAP
#include "cmc/hashmap.h"
-struct hashmap
-{
- struct hashmap_entry *buffer;
- size_t capacity;
- size_t count;
- double load;
- int flag;
- struct hashmap_fkey *f_key;
- struct hashmap_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct hashmap_entry
-{
- size_t key;
- size_t value;
- size_t dist;
- enum cmc_entry_state state;
-};
-struct hashmap_fkey
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashmap_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashmap_iter
-{
- struct hashmap *target;
- size_t cursor;
- size_t index;
- size_t first;
- size_t last;
- _Bool start;
- _Bool end;
-};
-struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val);
-struct hashmap *hm_new_custom(size_t capacity, double load,
- struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val);
-struct hashmap hm_init_custom(size_t capacity, double load,
- struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void hm_clear(struct hashmap *_map_);
-void hm_free(struct hashmap *_map_);
-void hm_release(struct hashmap _map_);
-void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value);
-_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value,
- size_t *old_value);
-_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value);
-_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value);
-_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value);
-size_t hm_get(struct hashmap *_map_, size_t key);
-size_t *hm_get_ref(struct hashmap *_map_, size_t key);
-_Bool hm_contains(struct hashmap *_map_, size_t key);
-_Bool hm_empty(struct hashmap *_map_);
-_Bool hm_full(struct hashmap *_map_);
-size_t hm_count(struct hashmap *_map_);
-size_t hm_capacity(struct hashmap *_map_);
-double hm_load(struct hashmap *_map_);
-int hm_flag(struct hashmap *_map_);
-_Bool hm_resize(struct hashmap *_map_, size_t capacity);
-struct hashmap *hm_copy_of(struct hashmap *_map_);
-_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_);
-struct cmc_string hm_to_string(struct hashmap *_map_);
-_Bool hm_print(struct hashmap *_map_, FILE *fptr);
-struct hashmap_iter hm_iter_start(struct hashmap *target);
-struct hashmap_iter hm_iter_end(struct hashmap *target);
-_Bool hm_iter_at_start(struct hashmap_iter *iter);
-_Bool hm_iter_at_end(struct hashmap_iter *iter);
-_Bool hm_iter_to_start(struct hashmap_iter *iter);
-_Bool hm_iter_to_end(struct hashmap_iter *iter);
-_Bool hm_iter_next(struct hashmap_iter *iter);
-_Bool hm_iter_prev(struct hashmap_iter *iter);
-_Bool hm_iter_advance(struct hashmap_iter *iter, size_t steps);
-_Bool hm_iter_rewind(struct hashmap_iter *iter, size_t steps);
-_Bool hm_iter_go_to(struct hashmap_iter *iter, size_t index);
-size_t hm_iter_key(struct hashmap_iter *iter);
-size_t hm_iter_value(struct hashmap_iter *iter);
-size_t *hm_iter_rvalue(struct hashmap_iter *iter);
-size_t hm_iter_index(struct hashmap_iter *iter);
-static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_,
- size_t key);
+static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key);
static size_t hm_impl_calculate_size(size_t required);
-struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val)
+struct hashmap *hm_new(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val)
{
- return hm_new_custom(capacity, load, f_key, f_val, ((void *)0),
- ((void *)0));
+ return hm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
}
-struct hashmap *hm_new_custom(size_t capacity, double load,
- struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+struct hashmap *hm_new_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (capacity == 0 || load <= 0 || load >= 1)
return ((void *)0);
if (capacity >= 0xffffffffffffffffULL * load)
@@ -140,46 +32,11 @@ struct hashmap *hm_new_custom(size_t capacity, double load,
_map_->count = 0;
_map_->capacity = real_capacity;
_map_->load = load;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_map_->f_key = f_key;
_map_->f_val = f_val;
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
- return _map_;
-}
-struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val)
-{
- return hm_init_custom(capacity, load, f_key, f_val, ((void *)0),
- ((void *)0));
-}
-struct hashmap hm_init_custom(size_t capacity, double load,
- struct hashmap_fkey *f_key,
- struct hashmap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
-{
- struct hashmap _map_ = { 0 };
- if (capacity == 0 || load <= 0 || load >= 1)
- return _map_;
- if (capacity >= 0xffffffffffffffffULL * load)
- return _map_;
- if (!f_key || !f_val)
- return _map_;
- size_t real_capacity = hm_impl_calculate_size(capacity / load);
- if (!alloc)
- alloc = &cmc_alloc_node_default;
- _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry));
- if (!_map_.buffer)
- return _map_;
- _map_.count = 0;
- _map_.capacity = real_capacity;
- _map_.load = load;
- _map_.flag = cmc_flags.OK;
- _map_.f_key = f_key;
- _map_.f_val = f_val;
- _map_.alloc = alloc;
- _map_.callbacks = callbacks;
+ (_map_)->callbacks = callbacks;
return _map_;
}
void hm_clear(struct hashmap *_map_)
@@ -200,7 +57,7 @@ void hm_clear(struct hashmap *_map_)
}
memset(_map_->buffer, 0, sizeof(struct hashmap_entry) * _map_->capacity);
_map_->count = 0;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
}
void hm_free(struct hashmap *_map_)
{
@@ -221,33 +78,15 @@ void hm_free(struct hashmap *_map_)
_map_->alloc->free(_map_->buffer);
_map_->alloc->free(_map_);
}
-void hm_release(struct hashmap _map_)
-{
- if (_map_.f_key->free || _map_.f_val->free)
- {
- for (size_t i = 0; i < _map_.capacity; i++)
- {
- struct hashmap_entry *entry = &(_map_.buffer[i]);
- if (entry->state == CMC_ES_FILLED)
- {
- if (_map_.f_key->free)
- _map_.f_key->free(entry->key);
- if (_map_.f_val->free)
- _map_.f_val->free(entry->value);
- }
- }
- }
- _map_.alloc->free(_map_.buffer);
-}
-void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void hm_customize(struct hashmap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_map_->alloc = &cmc_alloc_node_default;
else
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
- _map_->flag = cmc_flags.OK;
+ (_map_)->callbacks = callbacks;
+ _map_->flag = CMC_FLAG_OK;
}
_Bool hm_insert(struct hashmap *_map_, size_t key, size_t value)
{
@@ -258,7 +97,7 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value)
}
if (hm_impl_get_entry(_map_, key) != ((void *)0))
{
- _map_->flag = cmc_flags.DUPLICATE;
+ _map_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
size_t hash = _map_->f_key->hash(key);
@@ -278,8 +117,7 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value)
{
pos++;
target = &(_map_->buffer[pos % _map_->capacity]);
- if (target->state == CMC_ES_EMPTY ||
- target->state == CMC_ES_DELETED)
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
{
target->key = key;
target->value = value;
@@ -302,44 +140,45 @@ _Bool hm_insert(struct hashmap *_map_, size_t key, size_t value)
}
}
_map_->count++;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->create)
- _map_->callbacks->create();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->create)
+ (_map_)->callbacks->create();
+ ;
return 1;
}
-_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value,
- size_t *old_value)
+_Bool hm_update(struct hashmap *_map_, size_t key, size_t new_value, size_t *old_value)
{
if (hm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashmap_entry *entry = hm_impl_get_entry(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (old_value)
*old_value = entry->value;
entry->value = new_value;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->update)
- _map_->callbacks->update();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->update)
+ (_map_)->callbacks->update();
+ ;
return 1;
}
_Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value)
{
if (hm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashmap_entry *result = hm_impl_get_entry(_map_, key);
if (result == ((void *)0))
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (out_value)
@@ -349,111 +188,135 @@ _Bool hm_remove(struct hashmap *_map_, size_t key, size_t *out_value)
result->dist = 0;
result->state = CMC_ES_DELETED;
_map_->count--;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->delete)
- _map_->callbacks->delete ();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->delete)
+ (_map_)->callbacks->delete ();
+ ;
return 1;
}
_Bool hm_max(struct hashmap *_map_, size_t *key, size_t *value)
{
if (hm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
- struct hashmap_iter iter = hm_iter_start(_map_);
- size_t max_key = hm_iter_key(&iter);
- size_t max_val = hm_iter_value(&iter);
- hm_iter_next(&iter);
- for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
+ size_t max_key = (size_t){ 0 };
+ size_t max_val = (size_t){ 0 };
+ size_t first = 0;
+ for (; first < _map_->capacity; first++)
{
- size_t iter_key = hm_iter_key(&iter);
- size_t iter_val = hm_iter_value(&iter);
- if (_map_->f_key->cmp(iter_key, max_key) > 0)
+ if (_map_->buffer[first].state == CMC_ES_FILLED)
{
- max_key = iter_key;
- max_val = iter_val;
+ max_key = _map_->buffer[first].key;
+ max_val = _map_->buffer[first].value;
+ break;
+ }
+ }
+ for (size_t i = first + 1; i < _map_->capacity; i++)
+ {
+ if (_map_->buffer[i].state == CMC_ES_FILLED)
+ {
+ if (_map_->f_key->cmp(_map_->buffer[i].key, max_key) > 0)
+ {
+ max_key = _map_->buffer[i].key;
+ max_val = _map_->buffer[i].value;
+ }
}
}
if (key)
*key = max_key;
if (value)
*value = max_val;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return 1;
}
_Bool hm_min(struct hashmap *_map_, size_t *key, size_t *value)
{
if (hm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
- struct hashmap_iter iter = hm_iter_start(_map_);
- size_t min_key = hm_iter_key(&iter);
- size_t min_val = hm_iter_value(&iter);
- hm_iter_next(&iter);
- for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
+ size_t min_key = (size_t){ 0 };
+ size_t min_val = (size_t){ 0 };
+ size_t first = 0;
+ for (; first < _map_->capacity; first++)
{
- size_t iter_key = hm_iter_key(&iter);
- size_t iter_val = hm_iter_value(&iter);
- if (_map_->f_key->cmp(iter_key, min_key) < 0)
+ if (_map_->buffer[first].state == CMC_ES_FILLED)
{
- min_key = iter_key;
- min_val = iter_val;
+ min_key = _map_->buffer[first].key;
+ min_val = _map_->buffer[first].value;
+ break;
+ }
+ }
+ for (size_t i = first + 1; i < _map_->capacity; i++)
+ {
+ if (_map_->buffer[i].state == CMC_ES_FILLED)
+ {
+ if (_map_->f_key->cmp(_map_->buffer[i].key, min_key) < 0)
+ {
+ min_key = _map_->buffer[i].key;
+ min_val = _map_->buffer[i].value;
+ }
}
}
if (key)
*key = min_key;
if (value)
*value = min_val;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return 1;
}
size_t hm_get(struct hashmap *_map_, size_t key)
{
if (hm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
- return 0;
+ _map_->flag = CMC_FLAG_EMPTY;
+ return (size_t){ 0 };
}
struct hashmap_entry *entry = hm_impl_get_entry(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return (size_t){ 0 };
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return entry->value;
}
size_t *hm_get_ref(struct hashmap *_map_, size_t key)
{
if (hm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
- return 0;
+ _map_->flag = CMC_FLAG_EMPTY;
+ return ((void *)0);
}
struct hashmap_entry *entry = hm_impl_get_entry(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return ((void *)0);
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return &(entry->value);
}
_Bool hm_contains(struct hashmap *_map_, size_t key)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_Bool result = hm_impl_get_entry(_map_, key) != ((void *)0);
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return result;
}
_Bool hm_empty(struct hashmap *_map_)
@@ -482,41 +345,42 @@ int hm_flag(struct hashmap *_map_)
}
_Bool hm_resize(struct hashmap *_map_, size_t capacity)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
if (_map_->capacity == capacity)
goto success;
if (_map_->capacity > capacity / _map_->load)
goto success;
if (capacity >= 0xffffffffffffffffULL * _map_->load)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
size_t theoretical_size = hm_impl_calculate_size(capacity);
if (theoretical_size < _map_->count / _map_->load)
{
- _map_->flag = cmc_flags.INVALID;
+ _map_->flag = CMC_FLAG_INVALID;
return 0;
}
struct hashmap *_new_map_ =
- hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val,
- _map_->alloc, ((void *)0));
+ hm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0));
if (!_new_map_)
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
- struct hashmap_iter iter = hm_iter_start(_map_);
- for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
+ for (size_t i = 0; i < _map_->capacity; i++)
{
- size_t key = hm_iter_key(&iter);
- size_t value = hm_iter_value(&iter);
- hm_insert(_new_map_, key, value);
+ if (_map_->buffer[i].state == CMC_ES_FILLED)
+ {
+ size_t key = _map_->buffer[i].key;
+ size_t value = _map_->buffer[i].value;
+ hm_insert(_new_map_, key, value);
+ }
}
if (_map_->count != _new_map_->count)
{
hm_free(_new_map_);
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashmap_entry *tmp_b = _map_->buffer;
@@ -529,20 +393,21 @@ _Bool hm_resize(struct hashmap *_map_, size_t capacity)
_new_map_->f_val = &(struct hashmap_fval){ ((void *)0) };
hm_free(_new_map_);
success:
- if (_map_->callbacks && _map_->callbacks->resize)
- _map_->callbacks->resize();
+ if ((_map_)->callbacks && (_map_)->callbacks->resize)
+ (_map_)->callbacks->resize();
+ ;
return 1;
}
struct hashmap *hm_copy_of(struct hashmap *_map_)
{
- struct hashmap *result =
- hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key,
- _map_->f_val, _map_->alloc, _map_->callbacks);
+ struct hashmap *result = hm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val,
+ _map_->alloc, ((void *)0));
if (!result)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _map_->callbacks;
if (_map_->f_key->cpy || _map_->f_val->cpy)
{
for (size_t i = 0; i < _map_->capacity; i++)
@@ -570,54 +435,108 @@ struct hashmap *hm_copy_of(struct hashmap *_map_)
}
}
else
- memcpy(result->buffer, _map_->buffer,
- sizeof(struct hashmap_entry) * _map_->capacity);
+ memcpy(result->buffer, _map_->buffer, sizeof(struct hashmap_entry) * _map_->capacity);
result->count = _map_->count;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
return result;
}
_Bool hm_equals(struct hashmap *_map1_, struct hashmap *_map2_)
{
- _map1_->flag = cmc_flags.OK;
- _map2_->flag = cmc_flags.OK;
+ _map1_->flag = CMC_FLAG_OK;
+ _map2_->flag = CMC_FLAG_OK;
if (_map1_->count != _map2_->count)
return 0;
- struct hashmap_iter iter = hm_iter_start(_map1_);
- for (; !hm_iter_at_end(&iter); hm_iter_next(&iter))
+ struct hashmap *_map_a_;
+ struct hashmap *_map_b_;
+ _map_a_ = _map1_->capacity < _map2_->capacity ? _map1_ : _map2_;
+ _map_b_ = _map_a_ == _map1_ ? _map2_ : _map1_;
+ for (size_t i = 0; i < _map_a_->capacity; i++)
{
- struct hashmap_entry *entry =
- hm_impl_get_entry(_map2_, hm_iter_key(&iter));
- if (entry == ((void *)0))
- return 0;
- if (_map1_->f_val->cmp(entry->value, hm_iter_value(&iter)) != 0)
- return 0;
- }
- return 1;
-}
-struct cmc_string hm_to_string(struct hashmap *_map_)
-{
- struct cmc_string str;
- struct hashmap *m_ = _map_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmap, "hashmap",
- "size_t", "size_t", m_, m_->buffer, m_->capacity,
- m_->count, m_->load, m_->flag, m_->f_key, m_->f_val,
- m_->alloc, m_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool hm_print(struct hashmap *_map_, FILE *fptr)
-{
- for (size_t i = 0; i < _map_->capacity; i++)
- {
- struct hashmap_entry *entry = &(_map_->buffer[i]);
- if (entry->state == CMC_ES_FILLED)
+ if (_map_a_->buffer[i].state == CMC_ES_FILLED)
{
- if (!_map_->f_key->str(fptr, entry->key) ||
- !_map_->f_val->str(fptr, entry->value))
+ struct hashmap_entry *entry_a = &(_map_a_->buffer[i]);
+ struct hashmap_entry *entry_b = hm_impl_get_entry(_map_b_, entry_a->key);
+ if (!entry_b)
+ return 0;
+ if (_map_a_->f_val->cmp(entry_a->value, entry_b->value) != 0)
return 0;
}
}
return 1;
}
+static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_, size_t key)
+{
+ size_t hash = _map_->f_key->hash(key);
+ size_t pos = hash % _map_->capacity;
+ struct hashmap_entry *target = &(_map_->buffer[pos]);
+ while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
+ {
+ if (_map_->f_key->cmp(target->key, key) == 0)
+ return target;
+ pos++;
+ target = &(_map_->buffer[pos % _map_->capacity]);
+ }
+ return ((void *)0);
+}
+static size_t hm_impl_calculate_size(size_t required)
+{
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
+ if (cmc_hashtable_primes[count - 1] < required)
+ return required;
+ size_t i = 0;
+ while (cmc_hashtable_primes[i] < required)
+ i++;
+ return cmc_hashtable_primes[i];
+}
+struct hashmap hm_init(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val)
+{
+ return hm_init_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
+}
+struct hashmap hm_init_custom(size_t capacity, double load, struct hashmap_fkey *f_key, struct hashmap_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
+{
+ ;
+ struct hashmap _map_ = { 0 };
+ if (capacity == 0 || load <= 0 || load >= 1)
+ return _map_;
+ if (capacity >= 0xffffffffffffffffULL * load)
+ return _map_;
+ if (!f_key || !f_val)
+ return _map_;
+ size_t real_capacity = hm_impl_calculate_size(capacity / load);
+ if (!alloc)
+ alloc = &cmc_alloc_node_default;
+ _map_.buffer = alloc->calloc(real_capacity, sizeof(struct hashmap_entry));
+ if (!_map_.buffer)
+ return _map_;
+ _map_.count = 0;
+ _map_.capacity = real_capacity;
+ _map_.load = load;
+ _map_.flag = CMC_FLAG_OK;
+ _map_.f_key = f_key;
+ _map_.f_val = f_val;
+ _map_.alloc = alloc;
+ (&_map_)->callbacks = callbacks;
+ return _map_;
+}
+void hm_release(struct hashmap _map_)
+{
+ if (_map_.f_key->free || _map_.f_val->free)
+ {
+ for (size_t i = 0; i < _map_.capacity; i++)
+ {
+ struct hashmap_entry *entry = &(_map_.buffer[i]);
+ if (entry->state == CMC_ES_FILLED)
+ {
+ if (_map_.f_key->free)
+ _map_.f_key->free(entry->key);
+ if (_map_.f_val->free)
+ _map_.f_val->free(entry->value);
+ }
+ }
+ }
+ _map_.alloc->free(_map_.buffer);
+}
struct hashmap_iter hm_iter_start(struct hashmap *target)
{
struct hashmap_iter iter;
@@ -819,31 +738,55 @@ size_t hm_iter_index(struct hashmap_iter *iter)
{
return iter->index;
}
-static struct hashmap_entry *hm_impl_get_entry(struct hashmap *_map_,
- size_t key)
+_Bool hm_to_string(struct hashmap *_map_, FILE *fptr)
{
- size_t hash = _map_->f_key->hash(key);
- size_t pos = hash % _map_->capacity;
- struct hashmap_entry *target = &(_map_->buffer[pos]);
- while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
+ struct hashmap *m_ = _map_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s, %s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "load:%lf, "
+ "flag:%d, "
+ "f_key:%p, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "hashmap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag,
+ m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks);
+}
+_Bool hm_print(struct hashmap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep)
+{
+ fprintf(fptr, "%s", start);
+ size_t last = 0;
+ for (size_t i = _map_->capacity; i > 0; i--)
{
- if (_map_->f_key->cmp(target->key, key) == 0)
- return target;
- pos++;
- target = &(_map_->buffer[pos % _map_->capacity]);
+ if ((_map_->buffer[i - 1]).state == CMC_ES_FILLED)
+ {
+ last = i - 1;
+ break;
+ }
}
- return ((void *)0);
+ for (size_t i = 0; i < _map_->capacity; i++)
+ {
+ struct hashmap_entry *entry = &(_map_->buffer[i]);
+ if (entry->state == CMC_ES_FILLED)
+ {
+ if (!_map_->f_key->str(fptr, entry->key))
+ return 0;
+ fprintf(fptr, "%s", key_val_sep);
+ if (!_map_->f_val->str(fptr, entry->value))
+ return 0;
+ if (i + 1 < last)
+ fprintf(fptr, "%s", separator);
+ }
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
}
-static size_t hm_impl_calculate_size(size_t required)
-{
- const size_t count =
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
- if (cmc_hashtable_primes[count - 1] < required)
- return required;
- size_t i = 0;
- while (cmc_hashtable_primes[i] < required)
- i++;
- return cmc_hashtable_primes[i];
-}
-
-#endif /* CMC_TEST_SRC_HASHMAP */
diff --git a/tests/main/src/hashmultimap.c b/tests/src/cmc/hashmultimap.c
similarity index 65%
rename from tests/main/src/hashmultimap.c
rename to tests/src/cmc/hashmultimap.c
index ac1471e..41d0817 100644
--- a/tests/main/src/hashmultimap.c
+++ b/tests/src/cmc/hashmultimap.c
@@ -1,152 +1,20 @@
-#ifndef CMC_TEST_SRC_HASHMULTIMAP
-#define CMC_TEST_SRC_HASHMULTIMAP
#include "cmc/hashmultimap.h"
-struct hashmultimap
-{
- struct hashmultimap_entry *(*buffer)[2];
- size_t capacity;
- size_t count;
- double load;
- int flag;
- struct hashmultimap_fkey *f_key;
- struct hashmultimap_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct hashmultimap_entry
-{
- size_t key;
- size_t value;
- struct hashmultimap_entry *next;
- struct hashmultimap_entry *prev;
-};
-struct hashmultimap_fkey
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashmultimap_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashmultimap_iter
-{
- struct hashmultimap *target;
- struct hashmultimap_entry *curr_entry;
- size_t cursor;
- size_t index;
- size_t first;
- size_t last;
- _Bool start;
- _Bool end;
-};
-struct hashmultimap *hmm_new(size_t capacity, double load,
- struct hashmultimap_fkey *f_key,
- struct hashmultimap_fval *f_val);
-struct hashmultimap *hmm_new_custom(size_t capacity, double load,
- struct hashmultimap_fkey *f_key,
- struct hashmultimap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void hmm_clear(struct hashmultimap *_map_);
-void hmm_free(struct hashmultimap *_map_);
-void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value);
-_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value,
- size_t *old_value);
-size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value,
- size_t **old_values);
-_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value);
-size_t hmm_remove_all(struct hashmultimap *_map_, size_t key,
- size_t **out_values);
-_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value);
-_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value);
-size_t hmm_get(struct hashmultimap *_map_, size_t key);
-size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key);
-_Bool hmm_contains(struct hashmultimap *_map_, size_t key);
-_Bool hmm_empty(struct hashmultimap *_map_);
-_Bool hmm_full(struct hashmultimap *_map_);
-size_t hmm_count(struct hashmultimap *_map_);
-size_t hmm_key_count(struct hashmultimap *_map_, size_t key);
-size_t hmm_capacity(struct hashmultimap *_map_);
-double hmm_load(struct hashmultimap *_map_);
-int hmm_flag(struct hashmultimap *_map_);
-_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity);
-struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_);
-_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_);
-struct cmc_string hmm_to_string(struct hashmultimap *_map_);
-_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr);
-struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target);
-struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target);
-_Bool hmm_iter_at_start(struct hashmultimap_iter *iter);
-_Bool hmm_iter_at_end(struct hashmultimap_iter *iter);
-_Bool hmm_iter_to_start(struct hashmultimap_iter *iter);
-_Bool hmm_iter_to_end(struct hashmultimap_iter *iter);
-_Bool hmm_iter_next(struct hashmultimap_iter *iter);
-_Bool hmm_iter_prev(struct hashmultimap_iter *iter);
-_Bool hmm_iter_advance(struct hashmultimap_iter *iter, size_t steps);
-_Bool hmm_iter_rewind(struct hashmultimap_iter *iter, size_t steps);
-_Bool hmm_iter_go_to(struct hashmultimap_iter *iter, size_t index);
-size_t hmm_iter_key(struct hashmultimap_iter *iter);
-size_t hmm_iter_value(struct hashmultimap_iter *iter);
-size_t *hmm_iter_rvalue(struct hashmultimap_iter *iter);
-size_t hmm_iter_index(struct hashmultimap_iter *iter);
-struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_,
- size_t key, size_t value);
-struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_,
- size_t key);
+struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value);
+struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key);
size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key);
size_t hmm_impl_calculate_size(size_t required);
-struct hashmultimap *hmm_new(size_t capacity, double load,
- struct hashmultimap_fkey *f_key,
+struct hashmultimap *hmm_new(size_t capacity, double load, struct hashmultimap_fkey *f_key,
struct hashmultimap_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity == 0 || load <= 0)
- return ((void *)0);
- if (capacity >= 0xffffffffffffffffULL * load)
- return ((void *)0);
- if (!f_key || !f_val)
- return ((void *)0);
- size_t real_capacity = hmm_impl_calculate_size(capacity / load);
- struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap));
- if (!_map_)
- return ((void *)0);
- _map_->buffer =
- alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2]));
- if (!_map_->buffer)
- {
- alloc->free(_map_);
- return ((void *)0);
- }
- _map_->count = 0;
- _map_->capacity = real_capacity;
- _map_->load = load;
- _map_->flag = cmc_flags.OK;
- _map_->f_key = f_key;
- _map_->f_val = f_val;
- _map_->alloc = alloc;
- _map_->callbacks = ((void *)0);
- return _map_;
+ return hmm_new_custom(capacity, load, f_key, f_val, ((void *)0), ((void *)0));
}
-struct hashmultimap *hmm_new_custom(size_t capacity, double load,
- struct hashmultimap_fkey *f_key,
- struct hashmultimap_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct hashmultimap *hmm_new_custom(size_t capacity, double load, struct hashmultimap_fkey *f_key,
+ struct hashmultimap_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity == 0 || load <= 0)
return ((void *)0);
if (capacity >= 0xffffffffffffffffULL * load)
@@ -159,8 +27,7 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load,
struct hashmultimap *_map_ = alloc->malloc(sizeof(struct hashmultimap));
if (!_map_)
return ((void *)0);
- _map_->buffer =
- alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2]));
+ _map_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultimap_entry *[2]));
if (!_map_->buffer)
{
alloc->free(_map_);
@@ -169,11 +36,11 @@ struct hashmultimap *hmm_new_custom(size_t capacity, double load,
_map_->count = 0;
_map_->capacity = real_capacity;
_map_->load = load;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_map_->f_key = f_key;
_map_->f_val = f_val;
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
+ (_map_)->callbacks = callbacks;
return _map_;
}
void hmm_clear(struct hashmultimap *_map_)
@@ -192,10 +59,9 @@ void hmm_clear(struct hashmultimap *_map_)
scan = next;
}
}
- memset(_map_->buffer, 0,
- sizeof(struct hashmultimap_entry *[2]) * _map_->capacity);
+ memset(_map_->buffer, 0, sizeof(struct hashmultimap_entry *[2]) * _map_->capacity);
_map_->count = 0;
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
}
void hmm_free(struct hashmultimap *_map_)
{
@@ -232,15 +98,15 @@ void hmm_free(struct hashmultimap *_map_)
_map_->alloc->free(_map_->buffer);
_map_->alloc->free(_map_);
}
-void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void hmm_customize(struct hashmultimap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_map_->alloc = &cmc_alloc_node_default;
else
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
- _map_->flag = cmc_flags.OK;
+ (_map_)->callbacks = callbacks;
+ _map_->flag = CMC_FLAG_OK;
}
_Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value)
{
@@ -264,46 +130,46 @@ _Bool hmm_insert(struct hashmultimap *_map_, size_t key, size_t value)
_map_->buffer[pos][1] = entry;
}
_map_->count++;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->create)
- _map_->callbacks->create();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->create)
+ (_map_)->callbacks->create();
+ ;
return 1;
}
-_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value,
- size_t *old_value)
+_Bool hmm_update(struct hashmultimap *_map_, size_t key, size_t new_value, size_t *old_value)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (old_value)
*old_value = entry->value;
entry->value = new_value;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->update)
- _map_->callbacks->update();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->update)
+ (_map_)->callbacks->update();
+ ;
return 1;
}
-size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value,
- size_t **old_values)
+size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value, size_t **old_values)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
size_t hash = _map_->f_key->hash(key);
struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
if (entry == ((void *)0))
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (old_values)
@@ -311,13 +177,13 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value,
size_t total = hmm_impl_key_count(_map_, key);
if (total == 0)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
*old_values = _map_->alloc->malloc(sizeof(size_t) * total);
if (!(*old_values))
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
}
@@ -333,26 +199,25 @@ size_t hmm_update_all(struct hashmultimap *_map_, size_t key, size_t new_value,
}
entry = entry->next;
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->update)
- _map_->callbacks->update();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->update)
+ (_map_)->callbacks->update();
+ ;
return index;
}
_Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
size_t hash = _map_->f_key->hash(key);
- struct hashmultimap_entry **head =
- &(_map_->buffer[hash % _map_->capacity][0]);
- struct hashmultimap_entry **tail =
- &(_map_->buffer[hash % _map_->capacity][1]);
+ struct hashmultimap_entry **head = &(_map_->buffer[hash % _map_->capacity][0]);
+ struct hashmultimap_entry **tail = &(_map_->buffer[hash % _map_->capacity][1]);
if (*head == ((void *)0))
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
struct hashmultimap_entry *entry = *head;
@@ -367,7 +232,7 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value)
}
else
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
}
@@ -396,33 +261,31 @@ _Bool hmm_remove(struct hashmultimap *_map_, size_t key, size_t *out_value)
}
if (!found)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
}
_map_->alloc->free(entry);
_map_->count--;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->delete)
- _map_->callbacks->delete ();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->delete)
+ (_map_)->callbacks->delete ();
+ ;
return 1;
}
-size_t hmm_remove_all(struct hashmultimap *_map_, size_t key,
- size_t **out_values)
+size_t hmm_remove_all(struct hashmultimap *_map_, size_t key, size_t **out_values)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
size_t hash = _map_->f_key->hash(key);
- struct hashmultimap_entry **head =
- &(_map_->buffer[hash % _map_->capacity][0]);
- struct hashmultimap_entry **tail =
- &(_map_->buffer[hash % _map_->capacity][1]);
+ struct hashmultimap_entry **head = &(_map_->buffer[hash % _map_->capacity][0]);
+ struct hashmultimap_entry **tail = &(_map_->buffer[hash % _map_->capacity][1]);
if (*head == ((void *)0))
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (out_values)
@@ -430,13 +293,13 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key,
size_t total = hmm_impl_key_count(_map_, key);
if (total == 0)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
*out_values = _map_->alloc->malloc(sizeof(size_t) * total);
if (!(*out_values))
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
}
@@ -477,20 +340,21 @@ size_t hmm_remove_all(struct hashmultimap *_map_, size_t key,
}
}
_map_->count -= index;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->delete)
- _map_->callbacks->delete ();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->delete)
+ (_map_)->callbacks->delete ();
+ ;
return index;
}
_Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
- size_t max_key;
- size_t max_val;
+ size_t max_key = (size_t){ 0 };
+ size_t max_val = (size_t){ 0 };
struct hashmultimap_iter iter = hmm_iter_start(_map_);
for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter))
{
@@ -512,20 +376,21 @@ _Bool hmm_max(struct hashmultimap *_map_, size_t *key, size_t *value)
*key = max_key;
if (value)
*value = max_val;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return 1;
}
_Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
- size_t min_key;
- size_t min_val;
+ size_t min_key = (size_t){ 0 };
+ size_t min_val = (size_t){ 0 };
struct hashmultimap_iter iter = hmm_iter_start(_map_);
for (; !hmm_iter_at_end(&iter); hmm_iter_next(&iter))
{
@@ -547,53 +412,57 @@ _Bool hmm_min(struct hashmultimap *_map_, size_t *key, size_t *value)
*key = min_key;
if (value)
*value = min_val;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return 1;
}
size_t hmm_get(struct hashmultimap *_map_, size_t key)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
- return 0;
+ _map_->flag = CMC_FLAG_EMPTY;
+ return (size_t){ 0 };
}
struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return (size_t){ 0 };
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return entry->value;
}
size_t *hmm_get_ref(struct hashmultimap *_map_, size_t key)
{
if (hmm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
- return 0;
+ _map_->flag = CMC_FLAG_EMPTY;
+ return ((void *)0);
}
struct hashmultimap_entry *entry = hmm_impl_get_entry(_map_, key);
if (!entry)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return ((void *)0);
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return &(entry->value);
}
_Bool hmm_contains(struct hashmultimap *_map_, size_t key)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_Bool result = hmm_impl_get_entry(_map_, key) != ((void *)0);
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return result;
}
_Bool hmm_empty(struct hashmultimap *_map_)
@@ -626,28 +495,27 @@ int hmm_flag(struct hashmultimap *_map_)
}
_Bool hmm_resize(struct hashmultimap *_map_, size_t capacity)
{
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
if (_map_->capacity == capacity)
goto success;
if (_map_->capacity > capacity / _map_->load)
goto success;
if (capacity >= 0xffffffffffffffffULL * _map_->load)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
size_t theoretical_size = hmm_impl_calculate_size(capacity);
if (theoretical_size < _map_->count / _map_->load)
{
- _map_->flag = cmc_flags.INVALID;
+ _map_->flag = CMC_FLAG_INVALID;
return 0;
}
struct hashmultimap *_new_map_ =
- hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val,
- _map_->alloc, ((void *)0));
+ hmm_new_custom(capacity, _map_->load, _map_->f_key, _map_->f_val, _map_->alloc, ((void *)0));
if (!_new_map_)
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
struct hashmultimap_iter iter = hmm_iter_start(_map_);
@@ -660,7 +528,7 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity)
if (_map_->count != _new_map_->count)
{
hmm_free(_new_map_);
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashmultimap_entry *(*tmp_b)[2] = _map_->buffer;
@@ -673,18 +541,18 @@ _Bool hmm_resize(struct hashmultimap *_map_, size_t capacity)
_new_map_->f_val = &(struct hashmultimap_fval){ ((void *)0) };
hmm_free(_new_map_);
success:
- if (_map_->callbacks && _map_->callbacks->resize)
- _map_->callbacks->resize();
+ if ((_map_)->callbacks && (_map_)->callbacks->resize)
+ (_map_)->callbacks->resize();
+ ;
return 1;
}
struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_)
{
- struct hashmultimap *result =
- hmm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key,
- _map_->f_val, _map_->alloc, ((void *)0));
+ struct hashmultimap *result = hmm_new_custom(_map_->capacity * _map_->load, _map_->load, _map_->f_key, _map_->f_val,
+ _map_->alloc, ((void *)0));
if (!result)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
struct hashmultimap_iter iter = hmm_iter_start(_map_);
@@ -701,14 +569,14 @@ struct hashmultimap *hmm_copy_of(struct hashmultimap *_map_)
hmm_insert(result, key, value);
}
}
- result->callbacks = _map_->callbacks;
- _map_->flag = cmc_flags.OK;
+ (result)->callbacks = _map_->callbacks;
+ _map_->flag = CMC_FLAG_OK;
return result;
}
_Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_)
{
- _map1_->flag = cmc_flags.OK;
- _map2_->flag = cmc_flags.OK;
+ _map1_->flag = CMC_FLAG_OK;
+ _map2_->flag = CMC_FLAG_OK;
if (_map1_->count != _map2_->count)
return 0;
struct hashmultimap_iter iter = hmm_iter_start(_map1_);
@@ -720,30 +588,53 @@ _Bool hmm_equals(struct hashmultimap *_map1_, struct hashmultimap *_map2_)
}
return 1;
}
-struct cmc_string hmm_to_string(struct hashmultimap *_map_)
+struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_, size_t key, size_t value)
{
- struct cmc_string str;
- struct hashmultimap *m_ = _map_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultimap,
- "hashmultimap", "size_t", "size_t", m_, m_->buffer,
- m_->capacity, m_->count, m_->load, m_->flag, m_->f_key,
- m_->f_val, m_->alloc, m_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
+ struct hashmultimap_entry *entry = _map_->alloc->malloc(sizeof(struct hashmultimap_entry));
+ if (!entry)
+ return ((void *)0);
+ entry->key = key;
+ entry->value = value;
+ entry->next = ((void *)0);
+ entry->prev = ((void *)0);
+ return entry;
}
-_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr)
+struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_, size_t key)
{
- for (size_t i = 0; i < _map_->capacity; i++)
+ size_t hash = _map_->f_key->hash(key);
+ struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
+ while (entry != ((void *)0))
{
- struct hashmultimap_entry *scan = _map_->buffer[i][0];
- while (scan != ((void *)0))
- {
- if (!_map_->f_key->str(fptr, scan->key) ||
- !_map_->f_val->str(fptr, scan->value))
- return 0;
- scan = scan->next;
- }
+ if (_map_->f_key->cmp(entry->key, key) == 0)
+ return entry;
+ entry = entry->next;
}
- return 1;
+ return ((void *)0);
+}
+size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key)
+{
+ size_t hash = _map_->f_key->hash(key);
+ struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
+ size_t total_count = 0;
+ if (!entry)
+ return total_count;
+ while (entry != ((void *)0))
+ {
+ if (_map_->f_key->cmp(entry->key, key) == 0)
+ total_count++;
+ entry = entry->next;
+ }
+ return total_count;
+}
+size_t hmm_impl_calculate_size(size_t required)
+{
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
+ if (cmc_hashtable_primes[count - 1] < required)
+ return required;
+ size_t i = 0;
+ while (cmc_hashtable_primes[i] < required)
+ i++;
+ return cmc_hashtable_primes[i];
}
struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target)
{
@@ -760,7 +651,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target)
{
for (size_t i = 0; i < target->capacity; i++)
{
- if (target->buffer[i][0] != ((void *)0))
+ struct hashmultimap_entry *entry = target->buffer[i][0];
+ if (entry && entry != ((void *)1))
{
iter.curr_entry = target->buffer[i][0];
iter.first = i;
@@ -770,7 +662,8 @@ struct hashmultimap_iter hmm_iter_start(struct hashmultimap *target)
iter.cursor = iter.first;
for (size_t i = target->capacity; i > 0; i--)
{
- if (target->buffer[i - 1][1] != ((void *)0))
+ struct hashmultimap_entry *entry = target->buffer[i - 1][1];
+ if (entry && entry != ((void *)1))
{
iter.last = i - 1;
break;
@@ -794,7 +687,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target)
{
for (size_t i = 0; i < target->capacity; i++)
{
- if (target->buffer[i][0] != ((void *)0))
+ struct hashmultimap_entry *entry = target->buffer[i][0];
+ if (entry && entry != ((void *)1))
{
iter.first = i;
break;
@@ -802,7 +696,8 @@ struct hashmultimap_iter hmm_iter_end(struct hashmultimap *target)
}
for (size_t i = target->capacity; i > 0; i--)
{
- if (target->buffer[i - 1][1] != ((void *)0))
+ struct hashmultimap_entry *entry = target->buffer[i - 1][1];
+ if (entry && entry != ((void *)1))
{
iter.curr_entry = target->buffer[i - 1][1];
iter.last = i - 1;
@@ -960,57 +855,57 @@ size_t hmm_iter_index(struct hashmultimap_iter *iter)
{
return iter->index;
}
-struct hashmultimap_entry *hmm_impl_new_entry(struct hashmultimap *_map_,
- size_t key, size_t value)
+_Bool hmm_to_string(struct hashmultimap *_map_, FILE *fptr)
{
- struct hashmultimap_entry *entry =
- _map_->alloc->malloc(sizeof(struct hashmultimap_entry));
- if (!entry)
- return ((void *)0);
- entry->key = key;
- entry->value = value;
- entry->next = ((void *)0);
- entry->prev = ((void *)0);
- return entry;
+ struct hashmultimap *m_ = _map_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s, %s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "load:%lf, "
+ "flag:%d, "
+ "f_key:%p, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "hashmultimap", "size_t", "size_t", m_, m_->buffer, m_->capacity, m_->count, m_->load, m_->flag,
+ m_->f_key, m_->f_val, m_->alloc, (m_)->callbacks);
}
-struct hashmultimap_entry *hmm_impl_get_entry(struct hashmultimap *_map_,
- size_t key)
+_Bool hmm_print(struct hashmultimap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep)
{
- size_t hash = _map_->f_key->hash(key);
- struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
- while (entry != ((void *)0))
+ fprintf(fptr, "%s", start);
+ size_t last = 0;
+ for (size_t i = _map_->capacity; i > 0; i--)
{
- if (_map_->f_key->cmp(entry->key, key) == 0)
- return entry;
- entry = entry->next;
+ struct hashmultimap_entry *entry = _map_->buffer[i - 1][1];
+ if (entry && entry != ((void *)1))
+ {
+ last = i - 1;
+ break;
+ }
}
- return ((void *)0);
-}
-size_t hmm_impl_key_count(struct hashmultimap *_map_, size_t key)
-{
- size_t hash = _map_->f_key->hash(key);
- struct hashmultimap_entry *entry = _map_->buffer[hash % _map_->capacity][0];
- size_t total_count = 0;
- if (!entry)
- return total_count;
- while (entry != ((void *)0))
+ for (size_t i = 0; i < _map_->capacity; i++)
{
- if (_map_->f_key->cmp(entry->key, key) == 0)
- total_count++;
- entry = entry->next;
+ struct hashmultimap_entry *scan = _map_->buffer[i][0];
+ while (scan != ((void *)0))
+ {
+ if (!_map_->f_key->str(fptr, scan->key))
+ return 0;
+ fprintf(fptr, "%s", key_val_sep);
+ if (!_map_->f_val->str(fptr, scan->value))
+ return 0;
+ scan = scan->next;
+ if (i + 1 < last)
+ fprintf(fptr, "%s", separator);
+ }
}
- return total_count;
+ fprintf(fptr, "%s", end);
+ return 1;
}
-size_t hmm_impl_calculate_size(size_t required)
-{
- const size_t count =
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
- if (cmc_hashtable_primes[count - 1] < required)
- return required;
- size_t i = 0;
- while (cmc_hashtable_primes[i] < required)
- i++;
- return cmc_hashtable_primes[i];
-}
-
-#endif /* CMC_TEST_SRC_HASHMULTIMAP */
diff --git a/tests/main/src/hashmultiset.c b/tests/src/cmc/hashmultiset.c
similarity index 65%
rename from tests/main/src/hashmultiset.c
rename to tests/src/cmc/hashmultiset.c
index f51a4d0..6aa25a2 100644
--- a/tests/main/src/hashmultiset.c
+++ b/tests/src/cmc/hashmultiset.c
@@ -1,153 +1,18 @@
-#ifndef CMC_TEST_SRC_HASHMULTISET
-#define CMC_TEST_SRC_HASHMULTISET
#include "cmc/hashmultiset.h"
-struct hashmultiset
-{
- struct hashmultiset_entry *buffer;
- size_t capacity;
- size_t count;
- size_t cardinality;
- double load;
- int flag;
- struct hashmultiset_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct hashmultiset_entry
-{
- size_t value;
- size_t multiplicity;
- size_t dist;
- enum cmc_entry_state state;
-};
-struct hashmultiset_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashmultiset_iter
-{
- struct hashmultiset *target;
- size_t cursor;
- size_t index;
- size_t first;
- size_t last;
- _Bool start;
- _Bool end;
-};
-struct hashmultiset *hms_new(size_t capacity, double load,
- struct hashmultiset_fval *f_val);
-struct hashmultiset *hms_new_custom(size_t capacity, double load,
- struct hashmultiset_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void hms_clear(struct hashmultiset *_set_);
-void hms_free(struct hashmultiset *_set_);
-void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool hms_insert(struct hashmultiset *_set_, size_t value);
-_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count);
-_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity);
-_Bool hms_remove(struct hashmultiset *_set_, size_t value);
-size_t hms_remove_all(struct hashmultiset *_set_, size_t value);
-_Bool hms_max(struct hashmultiset *_set_, size_t *value);
-_Bool hms_min(struct hashmultiset *_set_, size_t *value);
-size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value);
-_Bool hms_contains(struct hashmultiset *_set_, size_t value);
-_Bool hms_empty(struct hashmultiset *_set_);
-_Bool hms_full(struct hashmultiset *_set_);
-size_t hms_count(struct hashmultiset *_set_);
-size_t hms_cardinality(struct hashmultiset *_set_);
-size_t hms_capacity(struct hashmultiset *_set_);
-double hms_load(struct hashmultiset *_set_);
-int hms_flag(struct hashmultiset *_set_);
-_Bool hms_resize(struct hashmultiset *_set_, size_t capacity);
-struct hashmultiset *hms_copy_of(struct hashmultiset *_set_);
-_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
-struct cmc_string hms_to_string(struct hashmultiset *_set_);
-_Bool hms_print(struct hashmultiset *_set_, FILE *fptr);
-struct hashmultiset *hms_union(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-struct hashmultiset *hms_intersection(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-struct hashmultiset *hms_difference(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-struct hashmultiset *hms_summation(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
-_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_);
-_Bool hms_is_proper_subset(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-_Bool hms_is_proper_superset(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-_Bool hms_is_disjointset(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_);
-struct hashmultiset_iter hms_iter_start(struct hashmultiset *target);
-struct hashmultiset_iter hms_iter_end(struct hashmultiset *target);
-_Bool hms_iter_at_start(struct hashmultiset_iter *iter);
-_Bool hms_iter_at_end(struct hashmultiset_iter *iter);
-_Bool hms_iter_to_start(struct hashmultiset_iter *iter);
-_Bool hms_iter_to_end(struct hashmultiset_iter *iter);
-_Bool hms_iter_next(struct hashmultiset_iter *iter);
-_Bool hms_iter_prev(struct hashmultiset_iter *iter);
-_Bool hms_iter_advance(struct hashmultiset_iter *iter, size_t steps);
-_Bool hms_iter_rewind(struct hashmultiset_iter *iter, size_t steps);
-_Bool hms_iter_go_to(struct hashmultiset_iter *iter, size_t index);
-size_t hms_iter_value(struct hashmultiset_iter *iter);
-size_t hms_iter_multiplicity(struct hashmultiset_iter *iter);
-size_t hms_iter_index(struct hashmultiset_iter *iter);
-static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_,
- size_t value);
-static struct hashmultiset_entry *
-hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value,
- _Bool *new_node);
-static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_,
- size_t value);
+static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value);
+static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node);
+static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value);
static size_t hms_impl_calculate_size(size_t required);
-struct hashmultiset *hms_new(size_t capacity, double load,
- struct hashmultiset_fval *f_val)
+struct hashmultiset *hms_new(size_t capacity, double load, struct hashmultiset_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity == 0 || load <= 0 || load >= 1)
- return ((void *)0);
- if (capacity >= 0xffffffffffffffffULL * load)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- size_t real_capacity = hms_impl_calculate_size(capacity / load);
- struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset));
- if (!_set_)
- return ((void *)0);
- _set_->buffer =
- alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry));
- if (!_set_->buffer)
- {
- alloc->free(_set_);
- return ((void *)0);
- }
- _set_->count = 0;
- _set_->cardinality = 0;
- _set_->capacity = real_capacity;
- _set_->load = load;
- _set_->flag = cmc_flags.OK;
- _set_->f_val = f_val;
- _set_->alloc = alloc;
- _set_->callbacks = ((void *)0);
- return _set_;
+ return hms_new_custom(capacity, load, f_val, ((void *)0), ((void *)0));
}
-struct hashmultiset *hms_new_custom(size_t capacity, double load,
- struct hashmultiset_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+struct hashmultiset *hms_new_custom(size_t capacity, double load, struct hashmultiset_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (capacity == 0 || load <= 0 || load >= 1)
return ((void *)0);
if (capacity >= 0xffffffffffffffffULL * load)
@@ -160,8 +25,7 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load,
struct hashmultiset *_set_ = alloc->malloc(sizeof(struct hashmultiset));
if (!_set_)
return ((void *)0);
- _set_->buffer =
- alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry));
+ _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashmultiset_entry));
if (!_set_->buffer)
{
alloc->free(_set_);
@@ -171,10 +35,10 @@ struct hashmultiset *hms_new_custom(size_t capacity, double load,
_set_->cardinality = 0;
_set_->capacity = real_capacity;
_set_->load = load;
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
_set_->f_val = f_val;
_set_->alloc = alloc;
- _set_->callbacks = callbacks;
+ (_set_)->callbacks = callbacks;
return _set_;
}
void hms_clear(struct hashmultiset *_set_)
@@ -190,10 +54,9 @@ void hms_clear(struct hashmultiset *_set_)
}
}
}
- memset(_set_->buffer, 0,
- sizeof(struct hashmultiset_entry) * _set_->capacity);
+ memset(_set_->buffer, 0, sizeof(struct hashmultiset_entry) * _set_->capacity);
_set_->count = 0;
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
}
void hms_free(struct hashmultiset *_set_)
{
@@ -211,32 +74,32 @@ void hms_free(struct hashmultiset *_set_)
_set_->alloc->free(_set_->buffer);
_set_->alloc->free(_set_);
}
-void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void hms_customize(struct hashmultiset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_set_->alloc = &cmc_alloc_node_default;
else
_set_->alloc = alloc;
- _set_->callbacks = callbacks;
- _set_->flag = cmc_flags.OK;
+ (_set_)->callbacks = callbacks;
+ _set_->flag = CMC_FLAG_OK;
}
_Bool hms_insert(struct hashmultiset *_set_, size_t value)
{
_Bool new_node;
- struct hashmultiset_entry *entry =
- hms_impl_insert_and_return(_set_, value, &new_node);
+ struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node);
if (!entry)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
if (!new_node)
entry->multiplicity++;
_set_->cardinality++;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->create)
- _set_->callbacks->create();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->create)
+ (_set_)->callbacks->create();
+ ;
return 1;
}
_Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count)
@@ -244,11 +107,10 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count)
if (count == 0)
goto success;
_Bool new_node;
- struct hashmultiset_entry *entry =
- hms_impl_insert_and_return(_set_, value, &new_node);
+ struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node);
if (!entry)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
if (new_node)
@@ -257,9 +119,10 @@ _Bool hms_insert_many(struct hashmultiset *_set_, size_t value, size_t count)
entry->multiplicity += count;
_set_->cardinality += count;
success:
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->create)
- _set_->callbacks->create();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->create)
+ (_set_)->callbacks->create();
+ ;
return 1;
}
_Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity)
@@ -278,32 +141,31 @@ _Bool hms_update(struct hashmultiset *_set_, size_t value, size_t multiplicity)
goto success;
}
_Bool new_node;
- struct hashmultiset_entry *entry =
- hms_impl_insert_and_return(_set_, value, &new_node);
+ struct hashmultiset_entry *entry = hms_impl_insert_and_return(_set_, value, &new_node);
if (!entry)
return 0;
if (new_node)
_set_->cardinality++;
- _set_->cardinality =
- (_set_->cardinality - entry->multiplicity) + multiplicity;
+ _set_->cardinality = (_set_->cardinality - entry->multiplicity) + multiplicity;
entry->multiplicity = multiplicity;
success:
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->update)
- _set_->callbacks->update();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->update)
+ (_set_)->callbacks->update();
+ ;
return 1;
}
_Bool hms_remove(struct hashmultiset *_set_, size_t value)
{
if (hms_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value);
if (!result)
{
- _set_->flag = cmc_flags.NOT_FOUND;
+ _set_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (result->multiplicity > 1)
@@ -317,22 +179,23 @@ _Bool hms_remove(struct hashmultiset *_set_, size_t value)
_set_->count--;
}
_set_->cardinality--;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->delete)
- _set_->callbacks->delete ();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->delete)
+ (_set_)->callbacks->delete ();
+ ;
return 1;
}
size_t hms_remove_all(struct hashmultiset *_set_, size_t value)
{
if (hms_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashmultiset_entry *result = hms_impl_get_entry(_set_, value);
if (!result)
{
- _set_->flag = cmc_flags.NOT_FOUND;
+ _set_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
size_t removed = result->multiplicity;
@@ -342,19 +205,20 @@ size_t hms_remove_all(struct hashmultiset *_set_, size_t value)
result->state = CMC_ES_DELETED;
_set_->count--;
_set_->cardinality -= removed;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->delete)
- _set_->callbacks->delete ();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->delete)
+ (_set_)->callbacks->delete ();
+ ;
return removed;
}
_Bool hms_max(struct hashmultiset *_set_, size_t *value)
{
if (hms_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
- size_t max_val;
+ size_t max_val = (size_t){ 0 };
struct hashmultiset_iter iter = hms_iter_start(_set_);
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
{
@@ -367,19 +231,20 @@ _Bool hms_max(struct hashmultiset *_set_, size_t *value)
}
if (value)
*value = max_val;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return 1;
}
_Bool hms_min(struct hashmultiset *_set_, size_t *value)
{
if (hms_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
- size_t min_val;
+ size_t min_val = (size_t){ 0 };
struct hashmultiset_iter iter = hms_iter_start(_set_);
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
{
@@ -392,27 +257,30 @@ _Bool hms_min(struct hashmultiset *_set_, size_t *value)
}
if (value)
*value = min_val;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return 1;
}
size_t hms_multiplicity_of(struct hashmultiset *_set_, size_t value)
{
struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
if (!entry)
return 0;
return entry->multiplicity;
}
_Bool hms_contains(struct hashmultiset *_set_, size_t value)
{
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
_Bool result = hms_impl_get_entry(_set_, value) != ((void *)0);
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return result;
}
_Bool hms_empty(struct hashmultiset *_set_)
@@ -445,39 +313,37 @@ int hms_flag(struct hashmultiset *_set_)
}
_Bool hms_resize(struct hashmultiset *_set_, size_t capacity)
{
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
if (_set_->capacity == capacity)
goto success;
if (_set_->capacity > capacity / _set_->load)
goto success;
if (capacity >= 0xffffffffffffffffULL * _set_->load)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
size_t theoretical_size = hms_impl_calculate_size(capacity);
if (theoretical_size < _set_->count / _set_->load)
{
- _set_->flag = cmc_flags.INVALID;
+ _set_->flag = CMC_FLAG_INVALID;
return 0;
}
- struct hashmultiset *_new_set_ = hms_new_custom(
- capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
+ struct hashmultiset *_new_set_ = hms_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
if (!_new_set_)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashmultiset_iter iter = hms_iter_start(_set_);
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
{
- hms_insert_many(_new_set_, hms_iter_value(&iter),
- hms_iter_multiplicity(&iter));
+ hms_insert_many(_new_set_, hms_iter_value(&iter), hms_iter_multiplicity(&iter));
}
if (_set_->count != _new_set_->count)
{
hms_free(_new_set_);
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashmultiset_entry *tmp_b = _set_->buffer;
@@ -489,20 +355,21 @@ _Bool hms_resize(struct hashmultiset *_set_, size_t capacity)
_new_set_->f_val = &(struct hashmultiset_fval){ ((void *)0) };
hms_free(_new_set_);
success:
- if (_set_->callbacks && _set_->callbacks->resize)
- _set_->callbacks->resize();
+ if ((_set_)->callbacks && (_set_)->callbacks->resize)
+ (_set_)->callbacks->resize();
+ ;
return 1;
}
struct hashmultiset *hms_copy_of(struct hashmultiset *_set_)
{
struct hashmultiset *result =
- hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val,
- _set_->alloc, _set_->callbacks);
+ hms_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
if (!result)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _set_->callbacks;
if (_set_->f_val->cpy)
{
for (size_t i = 0; i < _set_->capacity; i++)
@@ -524,17 +391,16 @@ struct hashmultiset *hms_copy_of(struct hashmultiset *_set_)
}
}
else
- memcpy(result->buffer, _set_->buffer,
- sizeof(struct hashmultiset_entry) * _set_->capacity);
+ memcpy(result->buffer, _set_->buffer, sizeof(struct hashmultiset_entry) * _set_->capacity);
result->count = _set_->count;
result->cardinality = _set_->cardinality;
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
return result;
}
_Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
{
- _set1_->flag = cmc_flags.OK;
- _set2_->flag = cmc_flags.OK;
+ _set1_->flag = CMC_FLAG_OK;
+ _set2_->flag = CMC_FLAG_OK;
if (_set1_->count != _set2_->count)
return 0;
if (_set1_->cardinality != _set2_->cardinality)
@@ -544,8 +410,7 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
struct hashmultiset_iter iter = hms_iter_start(_set1_);
for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
{
- struct hashmultiset_entry *entry =
- hms_impl_get_entry(_set2_, hms_iter_value(&iter));
+ struct hashmultiset_entry *entry = hms_impl_get_entry(_set2_, hms_iter_value(&iter));
if (!entry)
return 0;
if (entry->multiplicity != hms_iter_multiplicity(&iter))
@@ -553,225 +418,97 @@ _Bool hms_equals(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
}
return 1;
}
-struct cmc_string hms_to_string(struct hashmultiset *_set_)
+static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value)
{
- struct cmc_string str;
- struct hashmultiset *s_ = _set_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashmultiset,
- "hashmultiset", "size_t", s_, s_->buffer, s_->capacity,
- s_->count, s_->cardinality, s_->load, s_->flag, s_->f_val,
- s_->alloc, s_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool hms_print(struct hashmultiset *_set_, FILE *fptr)
-{
- for (size_t i = 0; i < _set_->capacity; i++)
- {
- struct hashmultiset_entry *entry = &(_set_->buffer[i]);
- if (entry->state == CMC_ES_FILLED)
- {
- if (!_set_->f_val->str(fptr, entry->value))
- return 0;
- }
- }
- return 1;
-}
-struct hashmultiset *hms_union(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- struct hashmultiset *_set_r_ =
- hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- return ((void *)0);
- struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
- struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
- for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
- {
- size_t value = hms_iter_value(&iter1);
- size_t m1 = hms_iter_multiplicity(&iter1);
- size_t m2 = hms_impl_multiplicity_of(_set2_, value);
- size_t max_ = m1 > m2 ? m1 : m2;
- hms_update(_set_r_, value, max_);
- }
- for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
- {
- size_t value = hms_iter_value(&iter2);
- size_t m1 = hms_impl_multiplicity_of(_set1_, value);
- size_t m2 = hms_iter_multiplicity(&iter2);
- size_t max_ = m1 > m2 ? m1 : m2;
- hms_update(_set_r_, value, max_);
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashmultiset *hms_intersection(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- struct hashmultiset *_set_r_ =
- hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- return ((void *)0);
- struct hashmultiset *_set_A_ =
- _set1_->count < _set2_->count ? _set1_ : _set2_;
- struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
- struct hashmultiset_iter iter = hms_iter_start(_set_A_);
- for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
- {
- size_t value = hms_iter_value(&iter);
- size_t m1 = hms_iter_multiplicity(&iter);
- size_t m2 = hms_impl_multiplicity_of(_set_B_, value);
- size_t max_ = m1 < m2 ? m1 : m2;
- hms_update(_set_r_, value, max_);
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashmultiset *hms_difference(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- struct hashmultiset *_set_r_ =
- hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- return ((void *)0);
- struct hashmultiset_iter iter = hms_iter_start(_set1_);
- for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
- {
- size_t value = hms_iter_value(&iter);
- size_t m1 = hms_iter_multiplicity(&iter);
- size_t m2 = hms_impl_multiplicity_of(_set2_, value);
- if (m1 > m2)
- hms_update(_set_r_, value, m1 - m2);
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashmultiset *hms_summation(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- struct hashmultiset *_set_r_ =
- hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- return ((void *)0);
- struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
- struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
- for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
- {
- hms_insert_many(_set_r_, hms_iter_value(&iter1),
- hms_iter_multiplicity(&iter1));
- }
- for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
- {
- hms_insert_many(_set_r_, hms_iter_value(&iter2),
- hms_iter_multiplicity(&iter2));
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- struct hashmultiset *_set_r_ =
- hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- return ((void *)0);
- struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
- struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
- for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
- {
- size_t value = hms_iter_value(&iter1);
- size_t m1 = hms_iter_multiplicity(&iter1);
- size_t m2 = hms_impl_multiplicity_of(_set2_, value);
- if (m1 != m2)
- {
- if (m1 > m2)
- hms_update(_set_r_, value, m1 - m2);
- else
- hms_update(_set_r_, value, m2 - m1);
- }
- }
- for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
- {
- size_t value = hms_iter_value(&iter2);
- size_t m1 = hms_impl_multiplicity_of(_set1_, value);
- size_t m2 = hms_iter_multiplicity(&iter2);
- if (m1 != m2)
- {
- if (m1 > m2)
- hms_update(_set_r_, value, m1 - m2);
- else
- hms_update(_set_r_, value, m2 - m1);
- }
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
-{
- if (_set1_->count > _set2_->count)
+ struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
+ if (!entry)
return 0;
- if (hms_empty(_set1_))
- return 1;
- struct hashmultiset_iter iter = hms_iter_start(_set1_);
- for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
- {
- size_t value = hms_iter_value(&iter);
- size_t m1 = hms_iter_multiplicity(&iter);
- size_t m2 = hms_impl_multiplicity_of(_set2_, value);
- if (m1 > m2)
- return 0;
- }
- return 1;
+ return entry->multiplicity;
}
-_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+static struct hashmultiset_entry *hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value, _Bool *new_node)
{
- return hms_is_subset(_set2_, _set1_);
-}
-_Bool hms_is_proper_subset(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- if (_set1_->count >= _set2_->count)
- return 0;
- if (hms_empty(_set1_))
+ *new_node = 0;
+ struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
+ if (entry != ((void *)0))
+ return entry;
+ *new_node = 1;
+ if (hms_full(_set_))
{
- if (!hms_empty(_set2_))
- return 1;
- else
- return 0;
+ if (!hms_resize(_set_, _set_->capacity + 1))
+ return ((void *)0);
}
- struct hashmultiset_iter iter = hms_iter_start(_set1_);
- for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
+ size_t hash = _set_->f_val->hash(value);
+ size_t original_pos = hash % _set_->capacity;
+ size_t pos = original_pos;
+ size_t curr_mul = 1;
+ struct hashmultiset_entry *target = &(_set_->buffer[pos]);
+ struct hashmultiset_entry *to_return = ((void *)0);
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
{
- size_t value = hms_iter_value(&iter);
- size_t m1 = hms_iter_multiplicity(&iter);
- size_t m2 = hms_impl_multiplicity_of(_set2_, value);
- if (m1 >= m2)
- return 0;
+ target->value = value;
+ target->multiplicity = curr_mul;
+ target->dist = pos - original_pos;
+ target->state = CMC_ES_FILLED;
+ to_return = target;
}
- return 1;
-}
-_Bool hms_is_proper_superset(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- return hms_is_proper_subset(_set2_, _set1_);
-}
-_Bool hms_is_disjointset(struct hashmultiset *_set1_,
- struct hashmultiset *_set2_)
-{
- if (hms_empty(_set1_))
- return 1;
- struct hashmultiset_iter iter = hms_iter_start(_set1_);
- for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
+ else
{
- size_t value = hms_iter_value(&iter);
- if (hms_impl_get_entry(_set2_, value) != ((void *)0))
- return 0;
+ while (1)
+ {
+ pos++;
+ target = &(_set_->buffer[pos % _set_->capacity]);
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
+ {
+ target->value = value;
+ target->multiplicity = curr_mul;
+ target->dist = pos - original_pos;
+ target->state = CMC_ES_FILLED;
+ if (!to_return)
+ to_return = target;
+ break;
+ }
+ else if (target->dist < pos - original_pos)
+ {
+ size_t tmp = target->value;
+ size_t tmp_dist = target->dist;
+ size_t tmp_mul = target->multiplicity;
+ target->value = value;
+ target->dist = pos - original_pos;
+ target->multiplicity = curr_mul;
+ value = tmp;
+ original_pos = pos - tmp_dist;
+ curr_mul = tmp_mul;
+ if (!to_return)
+ to_return = target;
+ }
+ }
}
- return 1;
+ _set_->count++;
+ return to_return;
+}
+static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_, size_t value)
+{
+ size_t hash = _set_->f_val->hash(value);
+ size_t pos = hash % _set_->capacity;
+ struct hashmultiset_entry *target = &(_set_->buffer[pos]);
+ while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
+ {
+ if (_set_->f_val->cmp(target->value, value) == 0)
+ return target;
+ pos++;
+ target = &(_set_->buffer[pos % _set_->capacity]);
+ }
+ return ((void *)0);
+}
+static size_t hms_impl_calculate_size(size_t required)
+{
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
+ if (cmc_hashtable_primes[count - 1] < required)
+ return required;
+ size_t i = 0;
+ while (cmc_hashtable_primes[i] < required)
+ i++;
+ return cmc_hashtable_primes[i];
}
struct hashmultiset_iter hms_iter_start(struct hashmultiset *target)
{
@@ -968,102 +705,242 @@ size_t hms_iter_index(struct hashmultiset_iter *iter)
{
return iter->index;
}
-static size_t hms_impl_multiplicity_of(struct hashmultiset *_set_, size_t value)
+struct hashmultiset *hms_union(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
{
- struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
- if (!entry)
- return 0;
- return entry->multiplicity;
+ struct hashmultiset *_set_r_ =
+ hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
+ struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
+ for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
+ {
+ size_t value = hms_iter_value(&iter1);
+ size_t m1 = hms_iter_multiplicity(&iter1);
+ size_t m2 = hms_impl_multiplicity_of(_set2_, value);
+ size_t max_ = m1 > m2 ? m1 : m2;
+ hms_update(_set_r_, value, max_);
+ }
+ for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
+ {
+ size_t value = hms_iter_value(&iter2);
+ size_t m1 = hms_impl_multiplicity_of(_set1_, value);
+ size_t m2 = hms_iter_multiplicity(&iter2);
+ size_t max_ = m1 > m2 ? m1 : m2;
+ hms_update(_set_r_, value, max_);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
}
-static struct hashmultiset_entry *
-hms_impl_insert_and_return(struct hashmultiset *_set_, size_t value,
- _Bool *new_node)
+struct hashmultiset *hms_intersection(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
{
- *new_node = 0;
- struct hashmultiset_entry *entry = hms_impl_get_entry(_set_, value);
- if (entry != ((void *)0))
- return entry;
- *new_node = 1;
- if (hms_full(_set_))
+ struct hashmultiset *_set_r_ =
+ hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct hashmultiset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
+ struct hashmultiset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
+ struct hashmultiset_iter iter = hms_iter_start(_set_A_);
+ for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
{
- if (!hms_resize(_set_, _set_->capacity + 1))
- return ((void *)0);
+ size_t value = hms_iter_value(&iter);
+ size_t m1 = hms_iter_multiplicity(&iter);
+ size_t m2 = hms_impl_multiplicity_of(_set_B_, value);
+ size_t max_ = m1 < m2 ? m1 : m2;
+ hms_update(_set_r_, value, max_);
}
- size_t hash = _set_->f_val->hash(value);
- size_t original_pos = hash % _set_->capacity;
- size_t pos = original_pos;
- size_t curr_mul = 1;
- struct hashmultiset_entry *target = &(_set_->buffer[pos]);
- struct hashmultiset_entry *to_return = ((void *)0);
- if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct hashmultiset *hms_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ struct hashmultiset *_set_r_ =
+ hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct hashmultiset_iter iter = hms_iter_start(_set1_);
+ for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
{
- target->value = value;
- target->multiplicity = curr_mul;
- target->dist = pos - original_pos;
- target->state = CMC_ES_FILLED;
- to_return = target;
+ size_t value = hms_iter_value(&iter);
+ size_t m1 = hms_iter_multiplicity(&iter);
+ size_t m2 = hms_impl_multiplicity_of(_set2_, value);
+ if (m1 > m2)
+ hms_update(_set_r_, value, m1 - m2);
}
- else
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct hashmultiset *hms_summation(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ struct hashmultiset *_set_r_ =
+ hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
+ struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
+ for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
{
- while (1)
+ hms_insert_many(_set_r_, hms_iter_value(&iter1), hms_iter_multiplicity(&iter1));
+ }
+ for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
+ {
+ hms_insert_many(_set_r_, hms_iter_value(&iter2), hms_iter_multiplicity(&iter2));
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct hashmultiset *hms_symmetric_difference(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ struct hashmultiset *_set_r_ =
+ hms_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct hashmultiset_iter iter1 = hms_iter_start(_set1_);
+ struct hashmultiset_iter iter2 = hms_iter_start(_set2_);
+ for (; !hms_iter_at_end(&iter1); hms_iter_next(&iter1))
+ {
+ size_t value = hms_iter_value(&iter1);
+ size_t m1 = hms_iter_multiplicity(&iter1);
+ size_t m2 = hms_impl_multiplicity_of(_set2_, value);
+ if (m1 != m2)
{
- pos++;
- target = &(_set_->buffer[pos % _set_->capacity]);
- if (target->state == CMC_ES_EMPTY ||
- target->state == CMC_ES_DELETED)
- {
- target->value = value;
- target->multiplicity = curr_mul;
- target->dist = pos - original_pos;
- target->state = CMC_ES_FILLED;
- if (!to_return)
- to_return = target;
- break;
- }
- else if (target->dist < pos - original_pos)
- {
- size_t tmp = target->value;
- size_t tmp_dist = target->dist;
- size_t tmp_mul = target->multiplicity;
- target->value = value;
- target->dist = pos - original_pos;
- target->multiplicity = curr_mul;
- value = tmp;
- original_pos = pos - tmp_dist;
- curr_mul = tmp_mul;
- if (!to_return)
- to_return = target;
- }
+ if (m1 > m2)
+ hms_update(_set_r_, value, m1 - m2);
+ else
+ hms_update(_set_r_, value, m2 - m1);
}
}
- _set_->count++;
- return to_return;
-}
-static struct hashmultiset_entry *hms_impl_get_entry(struct hashmultiset *_set_,
- size_t value)
-{
- size_t hash = _set_->f_val->hash(value);
- size_t pos = hash % _set_->capacity;
- struct hashmultiset_entry *target = &(_set_->buffer[pos]);
- while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
+ for (; !hms_iter_at_end(&iter2); hms_iter_next(&iter2))
{
- if (_set_->f_val->cmp(target->value, value) == 0)
- return target;
- pos++;
- target = &(_set_->buffer[pos % _set_->capacity]);
+ size_t value = hms_iter_value(&iter2);
+ size_t m1 = hms_impl_multiplicity_of(_set1_, value);
+ size_t m2 = hms_iter_multiplicity(&iter2);
+ if (m1 != m2)
+ {
+ if (m1 > m2)
+ hms_update(_set_r_, value, m1 - m2);
+ else
+ hms_update(_set_r_, value, m2 - m1);
+ }
}
- return ((void *)0);
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
}
-static size_t hms_impl_calculate_size(size_t required)
+_Bool hms_is_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
{
- const size_t count =
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
- if (cmc_hashtable_primes[count - 1] < required)
- return required;
- size_t i = 0;
- while (cmc_hashtable_primes[i] < required)
- i++;
- return cmc_hashtable_primes[i];
+ if (_set1_->count > _set2_->count)
+ return 0;
+ if (hms_empty(_set1_))
+ return 1;
+ struct hashmultiset_iter iter = hms_iter_start(_set1_);
+ for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
+ {
+ size_t value = hms_iter_value(&iter);
+ size_t m1 = hms_iter_multiplicity(&iter);
+ size_t m2 = hms_impl_multiplicity_of(_set2_, value);
+ if (m1 > m2)
+ return 0;
+ }
+ return 1;
+}
+_Bool hms_is_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ return hms_is_subset(_set2_, _set1_);
+}
+_Bool hms_is_proper_subset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ if (_set1_->count >= _set2_->count)
+ return 0;
+ if (hms_empty(_set1_))
+ {
+ if (!hms_empty(_set2_))
+ return 1;
+ else
+ return 0;
+ }
+ struct hashmultiset_iter iter = hms_iter_start(_set1_);
+ for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
+ {
+ size_t value = hms_iter_value(&iter);
+ size_t m1 = hms_iter_multiplicity(&iter);
+ size_t m2 = hms_impl_multiplicity_of(_set2_, value);
+ if (m1 >= m2)
+ return 0;
+ }
+ return 1;
+}
+_Bool hms_is_proper_superset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ return hms_is_proper_subset(_set2_, _set1_);
+}
+_Bool hms_is_disjointset(struct hashmultiset *_set1_, struct hashmultiset *_set2_)
+{
+ if (hms_empty(_set1_))
+ return 1;
+ struct hashmultiset_iter iter = hms_iter_start(_set1_);
+ for (; !hms_iter_at_end(&iter); hms_iter_next(&iter))
+ {
+ size_t value = hms_iter_value(&iter);
+ if (hms_impl_get_entry(_set2_, value) != ((void *)0))
+ return 0;
+ }
+ return 1;
+}
+_Bool hms_to_string(struct hashmultiset *_set_, FILE *fptr)
+{
+ struct hashmultiset *s_ = _set_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "cardinality:%"
+ "I64u"
+ ", "
+ "load:%lf, "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "hashmultiset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->cardinality, s_->load,
+ s_->flag, s_->f_val, s_->alloc, (s_)->callbacks);
+}
+_Bool hms_print(struct hashmultiset *_set_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *val_mul_sep)
+{
+ fprintf(fptr, "%s", start);
+ size_t last = 0;
+ for (size_t i = _set_->capacity; i > 0; i--)
+ {
+ if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED)
+ {
+ last = i - 1;
+ break;
+ }
+ }
+ for (size_t i = 0; i < _set_->capacity; i++)
+ {
+ struct hashmultiset_entry *entry = &(_set_->buffer[i]);
+ if (entry->state == CMC_ES_FILLED)
+ {
+ if (!_set_->f_val->str(fptr, entry->value))
+ return 0;
+ fprintf(fptr, "%s", val_mul_sep);
+ if (fprintf(fptr,
+ "%"
+ "I64u"
+ "",
+ entry->multiplicity) < 0)
+ return 0;
+ if (i + 1 < last)
+ fprintf(fptr, "%s", separator);
+ }
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
}
-
-#endif /* CMC_TEST_SRC_HASHMULTISET */
diff --git a/tests/main/src/hashset.c b/tests/src/cmc/hashset.c
similarity index 65%
rename from tests/main/src/hashset.c
rename to tests/src/cmc/hashset.c
index 856920d..e0605f1 100644
--- a/tests/main/src/hashset.c
+++ b/tests/src/cmc/hashset.c
@@ -1,131 +1,16 @@
-#ifndef CMC_TEST_SRC_HASHSET
-#define CMC_TEST_SRC_HASHSET
#include "cmc/hashset.h"
-struct hashset
-{
- struct hashset_entry *buffer;
- size_t capacity;
- size_t count;
- double load;
- int flag;
- struct hashset_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct hashset_entry
-{
- size_t value;
- size_t dist;
- enum cmc_entry_state state;
-};
-struct hashset_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct hashset_iter
-{
- struct hashset *target;
- size_t cursor;
- size_t index;
- size_t first;
- size_t last;
- _Bool start;
- _Bool end;
-};
-struct hashset *hs_new(size_t capacity, double load,
- struct hashset_fval *f_val);
-struct hashset *hs_new_custom(size_t capacity, double load,
- struct hashset_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void hs_clear(struct hashset *_set_);
-void hs_free(struct hashset *_set_);
-void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool hs_insert(struct hashset *_set_, size_t value);
-_Bool hs_remove(struct hashset *_set_, size_t value);
-_Bool hs_max(struct hashset *_set_, size_t *value);
-_Bool hs_min(struct hashset *_set_, size_t *value);
-_Bool hs_contains(struct hashset *_set_, size_t value);
-_Bool hs_empty(struct hashset *_set_);
-_Bool hs_full(struct hashset *_set_);
-size_t hs_count(struct hashset *_set_);
-size_t hs_capacity(struct hashset *_set_);
-double hs_load(struct hashset *_set_);
-int hs_flag(struct hashset *_set_);
-_Bool hs_resize(struct hashset *_set_, size_t capacity);
-struct hashset *hs_copy_of(struct hashset *_set_);
-_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_);
-struct cmc_string hs_to_string(struct hashset *_set_);
-_Bool hs_print(struct hashset *_set_, FILE *fptr);
-struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_);
-struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_);
-struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_);
-struct hashset *hs_symmetric_difference(struct hashset *_set1_,
- struct hashset *_set2_);
-_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_);
-_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_);
-_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_);
-_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_);
-_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_);
-struct hashset_iter hs_iter_start(struct hashset *target);
-struct hashset_iter hs_iter_end(struct hashset *target);
-_Bool hs_iter_at_start(struct hashset_iter *iter);
-_Bool hs_iter_at_end(struct hashset_iter *iter);
-_Bool hs_iter_to_start(struct hashset_iter *iter);
-_Bool hs_iter_to_end(struct hashset_iter *iter);
-_Bool hs_iter_next(struct hashset_iter *iter);
-_Bool hs_iter_prev(struct hashset_iter *iter);
-_Bool hs_iter_advance(struct hashset_iter *iter, size_t steps);
-_Bool hs_iter_rewind(struct hashset_iter *iter, size_t steps);
-_Bool hs_iter_go_to(struct hashset_iter *iter, size_t index);
-size_t hs_iter_value(struct hashset_iter *iter);
-size_t hs_iter_index(struct hashset_iter *iter);
-static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_,
- size_t value);
+static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value);
static size_t hs_impl_calculate_size(size_t required);
-static struct hashset_iter hs_impl_it_start(struct hashset *_set_);
-static struct hashset_iter hs_impl_it_end(struct hashset *_set_);
struct hashset *hs_new(size_t capacity, double load, struct hashset_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity == 0 || load <= 0 || load >= 1)
- return ((void *)0);
- if (capacity >= 0xffffffffffffffffULL * load)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- size_t real_capacity = hs_impl_calculate_size(capacity / load);
- struct hashset *_set_ = alloc->malloc(sizeof(struct hashset));
- if (!_set_)
- return ((void *)0);
- _set_->buffer = alloc->calloc(real_capacity, sizeof(struct hashset_entry));
- if (!_set_->buffer)
- {
- alloc->free(_set_);
- return ((void *)0);
- }
- _set_->count = 0;
- _set_->capacity = real_capacity;
- _set_->load = load;
- _set_->flag = cmc_flags.OK;
- _set_->f_val = f_val;
- _set_->alloc = alloc;
- _set_->callbacks = ((void *)0);
- return _set_;
+ return hs_new_custom(capacity, load, f_val, ((void *)0), ((void *)0));
}
-struct hashset *hs_new_custom(size_t capacity, double load,
- struct hashset_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct hashset *hs_new_custom(size_t capacity, double load, struct hashset_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity == 0 || load <= 0 || load >= 1)
return ((void *)0);
if (capacity >= 0xffffffffffffffffULL * load)
@@ -147,10 +32,10 @@ struct hashset *hs_new_custom(size_t capacity, double load,
_set_->count = 0;
_set_->capacity = real_capacity;
_set_->load = load;
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
_set_->f_val = f_val;
_set_->alloc = alloc;
- _set_->callbacks = callbacks;
+ (_set_)->callbacks = callbacks;
return _set_;
}
void hs_clear(struct hashset *_set_)
@@ -168,7 +53,7 @@ void hs_clear(struct hashset *_set_)
}
memset(_set_->buffer, 0, sizeof(struct hashset_entry) * _set_->capacity);
_set_->count = 0;
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
}
void hs_free(struct hashset *_set_)
{
@@ -186,15 +71,15 @@ void hs_free(struct hashset *_set_)
_set_->alloc->free(_set_->buffer);
_set_->alloc->free(_set_);
}
-void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void hs_customize(struct hashset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_set_->alloc = &cmc_alloc_node_default;
else
_set_->alloc = alloc;
- _set_->callbacks = callbacks;
- _set_->flag = cmc_flags.OK;
+ (_set_)->callbacks = callbacks;
+ _set_->flag = CMC_FLAG_OK;
}
_Bool hs_insert(struct hashset *_set_, size_t value)
{
@@ -205,7 +90,7 @@ _Bool hs_insert(struct hashset *_set_, size_t value)
}
if (hs_impl_get_entry(_set_, value) != ((void *)0))
{
- _set_->flag = cmc_flags.DUPLICATE;
+ _set_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
size_t hash = _set_->f_val->hash(value);
@@ -224,8 +109,7 @@ _Bool hs_insert(struct hashset *_set_, size_t value)
{
pos++;
target = &(_set_->buffer[pos % _set_->capacity]);
- if (target->state == CMC_ES_EMPTY ||
- target->state == CMC_ES_DELETED)
+ if (target->state == CMC_ES_EMPTY || target->state == CMC_ES_DELETED)
{
target->value = value;
target->dist = pos - original_pos;
@@ -244,89 +128,94 @@ _Bool hs_insert(struct hashset *_set_, size_t value)
}
}
_set_->count++;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->create)
- _set_->callbacks->create();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->create)
+ (_set_)->callbacks->create();
+ ;
return 1;
}
_Bool hs_remove(struct hashset *_set_, size_t value)
{
if (hs_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct hashset_entry *result = hs_impl_get_entry(_set_, value);
if (result == ((void *)0))
{
- _set_->flag = cmc_flags.NOT_FOUND;
+ _set_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
result->value = (size_t){ 0 };
result->dist = 0;
result->state = CMC_ES_DELETED;
_set_->count--;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->delete)
- _set_->callbacks->delete ();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->delete)
+ (_set_)->callbacks->delete ();
+ ;
return 1;
}
_Bool hs_max(struct hashset *_set_, size_t *value)
{
if (hs_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
- size_t max_value;
+ size_t max_val = (size_t){ 0 };
struct hashset_iter iter = hs_iter_start(_set_);
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
{
size_t result = hs_iter_value(&iter);
size_t index = hs_iter_index(&iter);
if (index == 0)
- max_value = result;
- else if (_set_->f_val->cmp(result, max_value) > 0)
- max_value = result;
+ max_val = result;
+ else if (_set_->f_val->cmp(result, max_val) > 0)
+ max_val = result;
}
if (value)
- *value = max_value;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ *value = max_val;
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return 1;
}
_Bool hs_min(struct hashset *_set_, size_t *value)
{
if (hs_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
- size_t min_value;
+ size_t min_val = (size_t){ 0 };
struct hashset_iter iter = hs_iter_start(_set_);
for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
{
size_t result = hs_iter_value(&iter);
size_t index = hs_iter_index(&iter);
if (index == 0)
- min_value = result;
- else if (_set_->f_val->cmp(result, min_value) < 0)
- min_value = result;
+ min_val = result;
+ else if (_set_->f_val->cmp(result, min_val) < 0)
+ min_val = result;
}
if (value)
- *value = min_value;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ *value = min_val;
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return 1;
}
_Bool hs_contains(struct hashset *_set_, size_t value)
{
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
_Bool result = hs_impl_get_entry(_set_, value) != ((void *)0);
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return result;
}
_Bool hs_empty(struct hashset *_set_)
@@ -355,27 +244,26 @@ int hs_flag(struct hashset *_set_)
}
_Bool hs_resize(struct hashset *_set_, size_t capacity)
{
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
if (_set_->capacity == capacity)
goto success;
if (_set_->capacity > capacity / _set_->load)
goto success;
if (capacity >= 0xffffffffffffffffULL * _set_->load)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
size_t theoretical_size = hs_impl_calculate_size(capacity);
if (theoretical_size < _set_->count / _set_->load)
{
- _set_->flag = cmc_flags.INVALID;
+ _set_->flag = CMC_FLAG_INVALID;
return 0;
}
- struct hashset *_new_set_ = hs_new_custom(
- capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
+ struct hashset *_new_set_ = hs_new_custom(capacity, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
if (!_new_set_)
{
- _set_->flag = cmc_flags.ALLOC;
+ _set_->flag = CMC_FLAG_ALLOC;
return 0;
}
struct hashset_iter iter = hs_iter_start(_set_);
@@ -387,7 +275,7 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity)
if (_set_->count != _new_set_->count)
{
hs_free(_new_set_);
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return 0;
}
struct hashset_entry *tmp_b = _set_->buffer;
@@ -399,20 +287,21 @@ _Bool hs_resize(struct hashset *_set_, size_t capacity)
_new_set_->f_val = &(struct hashset_fval){ ((void *)0) };
hs_free(_new_set_);
success:
- if (_set_->callbacks && _set_->callbacks->resize)
- _set_->callbacks->resize();
+ if ((_set_)->callbacks && (_set_)->callbacks->resize)
+ (_set_)->callbacks->resize();
+ ;
return 1;
}
struct hashset *hs_copy_of(struct hashset *_set_)
{
struct hashset *result =
- hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val,
- _set_->alloc, _set_->callbacks);
+ hs_new_custom(_set_->capacity * _set_->load, _set_->load, _set_->f_val, _set_->alloc, ((void *)0));
if (!result)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _set_->callbacks;
if (_set_->f_val->cpy)
{
for (size_t i = 0; i < _set_->capacity; i++)
@@ -433,16 +322,15 @@ struct hashset *hs_copy_of(struct hashset *_set_)
}
}
else
- memcpy(result->buffer, _set_->buffer,
- sizeof(struct hashset_entry) * _set_->capacity);
+ memcpy(result->buffer, _set_->buffer, sizeof(struct hashset_entry) * _set_->capacity);
result->count = _set_->count;
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
return result;
}
_Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_)
{
- _set1_->flag = cmc_flags.OK;
- _set2_->flag = cmc_flags.OK;
+ _set1_->flag = CMC_FLAG_OK;
+ _set2_->flag = CMC_FLAG_OK;
if (_set1_->count != _set2_->count)
return 0;
if (_set1_->count == 0)
@@ -455,186 +343,29 @@ _Bool hs_equals(struct hashset *_set1_, struct hashset *_set2_)
}
return 1;
}
-struct cmc_string hs_to_string(struct hashset *_set_)
+static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_, size_t value)
{
- struct cmc_string str;
- struct hashset *s_ = _set_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_hashset, "hashset",
- "size_t", s_, s_->buffer, s_->capacity, s_->count,
- s_->load, s_->flag, s_->f_val, s_->alloc, s_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
+ size_t hash = _set_->f_val->hash(value);
+ size_t pos = hash % _set_->capacity;
+ struct hashset_entry *target = &(_set_->buffer[pos]);
+ while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
+ {
+ if (_set_->f_val->cmp(target->value, value) == 0)
+ return target;
+ pos++;
+ target = &(_set_->buffer[pos % _set_->capacity]);
+ }
+ return ((void *)0);
}
-_Bool hs_print(struct hashset *_set_, FILE *fptr)
+static size_t hs_impl_calculate_size(size_t required)
{
- for (size_t i = 0; i < _set_->capacity; i++)
- {
- struct hashset_entry *entry = &(_set_->buffer[i]);
- if (entry->state == CMC_ES_FILLED)
- {
- if (!_set_->f_val->str(fptr, entry->value))
- return 0;
- }
- }
- return 1;
-}
-struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_)
-{
- struct hashset *_set_r_ =
- hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- {
- _set1_->flag = cmc_flags.ALLOC;
- _set2_->flag = cmc_flags.ALLOC;
- return ((void *)0);
- }
- struct hashset_iter iter1 = hs_iter_start(_set1_);
- struct hashset_iter iter2 = hs_iter_start(_set2_);
- for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
- {
- hs_insert(_set_r_, hs_iter_value(&iter1));
- }
- for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
- {
- hs_insert(_set_r_, hs_iter_value(&iter2));
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_)
-{
- struct hashset *_set_r_ =
- hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- {
- _set1_->flag = cmc_flags.ALLOC;
- _set2_->flag = cmc_flags.ALLOC;
- return ((void *)0);
- }
- struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
- struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
- struct hashset_iter iter = hs_iter_start(_set_A_);
- for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
- {
- size_t value = hs_iter_value(&iter);
- if (hs_impl_get_entry(_set_B_, value) != ((void *)0))
- hs_insert(_set_r_, value);
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_)
-{
- struct hashset *_set_r_ =
- hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- {
- _set1_->flag = cmc_flags.ALLOC;
- _set2_->flag = cmc_flags.ALLOC;
- return ((void *)0);
- }
- struct hashset_iter iter = hs_iter_start(_set1_);
- for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
- {
- size_t value = hs_iter_value(&iter);
- if (hs_impl_get_entry(_set2_, value) == ((void *)0))
- hs_insert(_set_r_, value);
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-struct hashset *hs_symmetric_difference(struct hashset *_set1_,
- struct hashset *_set2_)
-{
- struct hashset *_set_r_ =
- hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val,
- _set1_->alloc, ((void *)0));
- if (!_set_r_)
- {
- _set1_->flag = cmc_flags.ALLOC;
- _set2_->flag = cmc_flags.ALLOC;
- return ((void *)0);
- }
- struct hashset_iter iter1 = hs_iter_start(_set1_);
- struct hashset_iter iter2 = hs_iter_start(_set2_);
- for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
- {
- size_t value = hs_iter_value(&iter1);
- if (hs_impl_get_entry(_set2_, value) == ((void *)0))
- hs_insert(_set_r_, value);
- }
- for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
- {
- size_t value = hs_iter_value(&iter2);
- if (hs_impl_get_entry(_set1_, value) == ((void *)0))
- hs_insert(_set_r_, value);
- }
- _set_r_->callbacks = _set1_->callbacks;
- return _set_r_;
-}
-_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_)
-{
- _set1_->flag = cmc_flags.OK;
- _set2_->flag = cmc_flags.OK;
- if (_set1_->count > _set2_->count)
- return 0;
- if (hs_empty(_set1_))
- return 1;
- struct hashset_iter iter = hs_iter_start(_set1_);
- for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
- {
- size_t value = hs_iter_value(&iter);
- if (hs_impl_get_entry(_set2_, value) == ((void *)0))
- return 0;
- }
- return 1;
-}
-_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_)
-{
- return hs_is_subset(_set2_, _set1_);
-}
-_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_)
-{
- _set1_->flag = cmc_flags.OK;
- _set2_->flag = cmc_flags.OK;
- if (_set1_->count >= _set2_->count)
- return 0;
- if (hs_empty(_set1_))
- {
- if (!hs_empty(_set2_))
- return 1;
- else
- return 0;
- }
- struct hashset_iter iter = hs_iter_start(_set1_);
- for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
- {
- size_t value = hs_iter_value(&iter);
- if (hs_impl_get_entry(_set2_, value) == ((void *)0))
- return 0;
- }
- return 1;
-}
-_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_)
-{
- return hs_is_proper_subset(_set2_, _set1_);
-}
-_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_)
-{
- _set1_->flag = cmc_flags.OK;
- _set2_->flag = cmc_flags.OK;
- if (hs_empty(_set1_))
- return 1;
- struct hashset_iter iter = hs_iter_start(_set1_);
- for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
- {
- size_t value = hs_iter_value(&iter);
- if (hs_impl_get_entry(_set2_, value) != ((void *)0))
- return 0;
- }
- return 1;
+ const size_t count = sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
+ if (cmc_hashtable_primes[count - 1] < required)
+ return required;
+ size_t i = 0;
+ while (cmc_hashtable_primes[i] < required)
+ i++;
+ return cmc_hashtable_primes[i];
}
struct hashset_iter hs_iter_start(struct hashset *target)
{
@@ -825,31 +556,200 @@ size_t hs_iter_index(struct hashset_iter *iter)
{
return iter->index;
}
-static struct hashset_entry *hs_impl_get_entry(struct hashset *_set_,
- size_t value)
+struct hashset *hs_union(struct hashset *_set1_, struct hashset *_set2_)
{
- size_t hash = _set_->f_val->hash(value);
- size_t pos = hash % _set_->capacity;
- struct hashset_entry *target = &(_set_->buffer[pos]);
- while (target->state == CMC_ES_FILLED || target->state == CMC_ES_DELETED)
+ struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
{
- if (_set_->f_val->cmp(target->value, value) == 0)
- return target;
- pos++;
- target = &(_set_->buffer[pos % _set_->capacity]);
+ _set1_->flag = CMC_FLAG_ALLOC;
+ _set2_->flag = CMC_FLAG_ALLOC;
+ return ((void *)0);
}
- return ((void *)0);
+ struct hashset_iter iter1 = hs_iter_start(_set1_);
+ struct hashset_iter iter2 = hs_iter_start(_set2_);
+ for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
+ {
+ hs_insert(_set_r_, hs_iter_value(&iter1));
+ }
+ for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
+ {
+ hs_insert(_set_r_, hs_iter_value(&iter2));
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
}
-static size_t hs_impl_calculate_size(size_t required)
+struct hashset *hs_intersection(struct hashset *_set1_, struct hashset *_set2_)
{
- const size_t count =
- sizeof(cmc_hashtable_primes) / sizeof(cmc_hashtable_primes[0]);
- if (cmc_hashtable_primes[count - 1] < required)
- return required;
- size_t i = 0;
- while (cmc_hashtable_primes[i] < required)
- i++;
- return cmc_hashtable_primes[i];
+ struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ {
+ _set1_->flag = CMC_FLAG_ALLOC;
+ _set2_->flag = CMC_FLAG_ALLOC;
+ return ((void *)0);
+ }
+ struct hashset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
+ struct hashset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
+ struct hashset_iter iter = hs_iter_start(_set_A_);
+ for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
+ {
+ size_t value = hs_iter_value(&iter);
+ if (hs_impl_get_entry(_set_B_, value) != ((void *)0))
+ hs_insert(_set_r_, value);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct hashset *hs_difference(struct hashset *_set1_, struct hashset *_set2_)
+{
+ struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ {
+ _set1_->flag = CMC_FLAG_ALLOC;
+ _set2_->flag = CMC_FLAG_ALLOC;
+ return ((void *)0);
+ }
+ struct hashset_iter iter = hs_iter_start(_set1_);
+ for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
+ {
+ size_t value = hs_iter_value(&iter);
+ if (hs_impl_get_entry(_set2_, value) == ((void *)0))
+ hs_insert(_set_r_, value);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct hashset *hs_symmetric_difference(struct hashset *_set1_, struct hashset *_set2_)
+{
+ struct hashset *_set_r_ = hs_new_custom(_set1_->capacity, _set1_->load, _set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ {
+ _set1_->flag = CMC_FLAG_ALLOC;
+ _set2_->flag = CMC_FLAG_ALLOC;
+ return ((void *)0);
+ }
+ struct hashset_iter iter1 = hs_iter_start(_set1_);
+ struct hashset_iter iter2 = hs_iter_start(_set2_);
+ for (; !hs_iter_at_end(&iter1); hs_iter_next(&iter1))
+ {
+ size_t value = hs_iter_value(&iter1);
+ if (hs_impl_get_entry(_set2_, value) == ((void *)0))
+ hs_insert(_set_r_, value);
+ }
+ for (; !hs_iter_at_end(&iter2); hs_iter_next(&iter2))
+ {
+ size_t value = hs_iter_value(&iter2);
+ if (hs_impl_get_entry(_set1_, value) == ((void *)0))
+ hs_insert(_set_r_, value);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+_Bool hs_is_subset(struct hashset *_set1_, struct hashset *_set2_)
+{
+ _set1_->flag = CMC_FLAG_OK;
+ _set2_->flag = CMC_FLAG_OK;
+ if (_set1_->count > _set2_->count)
+ return 0;
+ if (hs_empty(_set1_))
+ return 1;
+ struct hashset_iter iter = hs_iter_start(_set1_);
+ for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
+ {
+ size_t value = hs_iter_value(&iter);
+ if (hs_impl_get_entry(_set2_, value) == ((void *)0))
+ return 0;
+ }
+ return 1;
+}
+_Bool hs_is_superset(struct hashset *_set1_, struct hashset *_set2_)
+{
+ return hs_is_subset(_set2_, _set1_);
+}
+_Bool hs_is_proper_subset(struct hashset *_set1_, struct hashset *_set2_)
+{
+ _set1_->flag = CMC_FLAG_OK;
+ _set2_->flag = CMC_FLAG_OK;
+ if (_set1_->count >= _set2_->count)
+ return 0;
+ if (hs_empty(_set1_))
+ {
+ if (!hs_empty(_set2_))
+ return 1;
+ else
+ return 0;
+ }
+ struct hashset_iter iter = hs_iter_start(_set1_);
+ for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
+ {
+ size_t value = hs_iter_value(&iter);
+ if (hs_impl_get_entry(_set2_, value) == ((void *)0))
+ return 0;
+ }
+ return 1;
+}
+_Bool hs_is_proper_superset(struct hashset *_set1_, struct hashset *_set2_)
+{
+ return hs_is_proper_subset(_set2_, _set1_);
+}
+_Bool hs_is_disjointset(struct hashset *_set1_, struct hashset *_set2_)
+{
+ _set1_->flag = CMC_FLAG_OK;
+ _set2_->flag = CMC_FLAG_OK;
+ if (hs_empty(_set1_))
+ return 1;
+ struct hashset_iter iter = hs_iter_start(_set1_);
+ for (; !hs_iter_at_end(&iter); hs_iter_next(&iter))
+ {
+ size_t value = hs_iter_value(&iter);
+ if (hs_impl_get_entry(_set2_, value) != ((void *)0))
+ return 0;
+ }
+ return 1;
+}
+_Bool hs_to_string(struct hashset *_set_, FILE *fptr)
+{
+ struct hashset *s_ = _set_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "load:%lf, "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks: %p }",
+ "hashset", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->load, s_->flag, s_->f_val,
+ s_->alloc, (s_)->callbacks);
+}
+_Bool hs_print(struct hashset *_set_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ size_t last = 0;
+ for (size_t i = _set_->capacity; i > 0; i--)
+ {
+ if ((_set_->buffer[i - 1]).state == CMC_ES_FILLED)
+ {
+ last = i - 1;
+ break;
+ }
+ }
+ for (size_t i = 0; i < _set_->capacity; i++)
+ {
+ struct hashset_entry *entry = &(_set_->buffer[i]);
+ if (entry->state == CMC_ES_FILLED)
+ {
+ if (!_set_->f_val->str(fptr, entry->value))
+ return 0;
+ if (i + 1 < last)
+ fprintf(fptr, "%s", separator);
+ }
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
}
-
-#endif /* CMC_TEST_SRC_HASHSET */
diff --git a/tests/main/src/heap.c b/tests/src/cmc/heap.c
similarity index 60%
rename from tests/main/src/heap.c
rename to tests/src/cmc/heap.c
index 972af1d..11cd537 100644
--- a/tests/main/src/heap.c
+++ b/tests/src/cmc/heap.c
@@ -1,108 +1,19 @@
-#ifndef CMC_TEST_SRC_HEAP
-#define CMC_TEST_SRC_HEAP
#include "cmc/heap.h"
-struct heap
-{
- size_t *buffer;
- size_t capacity;
- size_t count;
- enum cmc_heap_order HO;
- int flag;
- struct heap_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct heap_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct heap_iter
-{
- struct heap *target;
- size_t cursor;
- _Bool start;
- _Bool end;
-};
-struct heap *h_new(size_t capacity, enum cmc_heap_order HO,
- struct heap_fval *f_val);
-struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO,
- struct heap_fval *f_val, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void h_clear(struct heap *_heap_);
-void h_free(struct heap *_heap_);
-void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool h_insert(struct heap *_heap_, size_t value);
-_Bool h_remove(struct heap *_heap_);
-size_t h_peek(struct heap *_heap_);
-_Bool h_contains(struct heap *_heap_, size_t value);
-_Bool h_empty(struct heap *_heap_);
-_Bool h_full(struct heap *_heap_);
-size_t h_count(struct heap *_heap_);
-size_t h_capacity(struct heap *_heap_);
-int h_flag(struct heap *_heap_);
-_Bool h_resize(struct heap *_heap_, size_t capacity);
-struct heap *h_copy_of(struct heap *_heap_);
-_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_);
-struct cmc_string h_to_string(struct heap *_heap_);
-_Bool h_print(struct heap *_heap_, FILE *fptr);
-struct heap_iter h_iter_start(struct heap *target);
-struct heap_iter h_iter_end(struct heap *target);
-_Bool h_iter_at_start(struct heap_iter *iter);
-_Bool h_iter_at_end(struct heap_iter *iter);
-_Bool h_iter_to_start(struct heap_iter *iter);
-_Bool h_iter_to_end(struct heap_iter *iter);
-_Bool h_iter_next(struct heap_iter *iter);
-_Bool h_iter_prev(struct heap_iter *iter);
-_Bool h_iter_advance(struct heap_iter *iter, size_t steps);
-_Bool h_iter_rewind(struct heap_iter *iter, size_t steps);
-_Bool h_iter_go_to(struct heap_iter *iter, size_t index);
-size_t h_iter_value(struct heap_iter *iter);
-size_t h_iter_index(struct heap_iter *iter);
static void h_impl_float_up(struct heap *_heap_, size_t index);
static void h_impl_float_down(struct heap *_heap_, size_t index);
-struct heap *h_new(size_t capacity, enum cmc_heap_order HO,
- struct heap_fval *f_val)
+struct heap *h_new(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity < 1)
- return ((void *)0);
- if (HO != cmc_min_heap && HO != cmc_max_heap)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- struct heap *_heap_ = alloc->malloc(sizeof(struct heap));
- if (!_heap_)
- return ((void *)0);
- _heap_->buffer = alloc->calloc(capacity, sizeof(size_t));
- if (!_heap_->buffer)
- {
- alloc->free(_heap_);
- return ((void *)0);
- }
- _heap_->capacity = capacity;
- _heap_->count = 0;
- _heap_->HO = HO;
- _heap_->flag = cmc_flags.OK;
- _heap_->f_val = f_val;
- _heap_->alloc = alloc;
- _heap_->callbacks = ((void *)0);
- return _heap_;
+ return h_new_custom(capacity, HO, f_val, ((void *)0), ((void *)0));
}
-struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO,
- struct heap_fval *f_val, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO, struct heap_fval *f_val,
+ struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (capacity < 1)
return ((void *)0);
- if (HO != cmc_min_heap && HO != cmc_max_heap)
+ if (HO != CMC_MIN_HEAP && HO != CMC_MAX_HEAP)
return ((void *)0);
if (!f_val)
return ((void *)0);
@@ -120,10 +31,10 @@ struct heap *h_new_custom(size_t capacity, enum cmc_heap_order HO,
_heap_->capacity = capacity;
_heap_->count = 0;
_heap_->HO = HO;
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
_heap_->f_val = f_val;
_heap_->alloc = alloc;
- _heap_->callbacks = callbacks;
+ (_heap_)->callbacks = callbacks;
return _heap_;
}
void h_clear(struct heap *_heap_)
@@ -137,7 +48,7 @@ void h_clear(struct heap *_heap_)
}
memset(_heap_->buffer, 0, sizeof(size_t) * _heap_->capacity);
_heap_->count = 0;
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
}
void h_free(struct heap *_heap_)
{
@@ -151,15 +62,15 @@ void h_free(struct heap *_heap_)
_heap_->alloc->free(_heap_->buffer);
_heap_->alloc->free(_heap_);
}
-void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void h_customize(struct heap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_heap_->alloc = &cmc_alloc_node_default;
else
_heap_->alloc = alloc;
- _heap_->callbacks = callbacks;
- _heap_->flag = cmc_flags.OK;
+ (_heap_)->callbacks = callbacks;
+ _heap_->flag = CMC_FLAG_OK;
}
_Bool h_insert(struct heap *_heap_, size_t value)
{
@@ -173,42 +84,45 @@ _Bool h_insert(struct heap *_heap_, size_t value)
{
h_impl_float_up(_heap_, _heap_->count - 1);
}
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->create)
- _heap_->callbacks->create();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->create)
+ (_heap_)->callbacks->create();
+ ;
return 1;
}
_Bool h_remove(struct heap *_heap_)
{
if (h_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return 0;
}
_heap_->buffer[0] = _heap_->buffer[_heap_->count - 1];
_heap_->buffer[_heap_->count - 1] = (size_t){ 0 };
_heap_->count--;
h_impl_float_down(_heap_, 0);
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->delete)
- _heap_->callbacks->delete ();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->delete)
+ (_heap_)->callbacks->delete ();
+ ;
return 1;
}
size_t h_peek(struct heap *_heap_)
{
if (h_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->read)
- _heap_->callbacks->read();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->read)
+ (_heap_)->callbacks->read();
+ ;
return _heap_->buffer[0];
}
_Bool h_contains(struct heap *_heap_, size_t value)
{
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
_Bool result = 0;
for (size_t i = 0; i < _heap_->count; i++)
{
@@ -218,8 +132,9 @@ _Bool h_contains(struct heap *_heap_, size_t value)
break;
}
}
- if (_heap_->callbacks && _heap_->callbacks->read)
- _heap_->callbacks->read();
+ if ((_heap_)->callbacks && (_heap_)->callbacks->read)
+ (_heap_)->callbacks->read();
+ ;
return result;
}
_Bool h_empty(struct heap *_heap_)
@@ -244,38 +159,37 @@ int h_flag(struct heap *_heap_)
}
_Bool h_resize(struct heap *_heap_, size_t capacity)
{
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
if (_heap_->capacity == capacity)
goto success;
if (capacity < _heap_->count)
{
- _heap_->flag = cmc_flags.INVALID;
+ _heap_->flag = CMC_FLAG_INVALID;
return 0;
}
- size_t *new_buffer =
- _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity);
+ size_t *new_buffer = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t) * capacity);
if (!new_buffer)
{
- _heap_->flag = cmc_flags.ALLOC;
+ _heap_->flag = CMC_FLAG_ALLOC;
return 0;
}
_heap_->buffer = new_buffer;
_heap_->capacity = capacity;
success:
- if (_heap_->callbacks && _heap_->callbacks->resize)
- _heap_->callbacks->resize();
+ if ((_heap_)->callbacks && (_heap_)->callbacks->resize)
+ (_heap_)->callbacks->resize();
+ ;
return 1;
}
struct heap *h_copy_of(struct heap *_heap_)
{
- struct heap *result =
- h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc,
- _heap_->callbacks);
+ struct heap *result = h_new_custom(_heap_->capacity, _heap_->HO, _heap_->f_val, _heap_->alloc, ((void *)0));
if (!result)
{
- _heap_->flag = cmc_flags.ERROR;
+ _heap_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _heap_->callbacks;
if (_heap_->f_val->cpy)
{
for (size_t i = 0; i < _heap_->count; i++)
@@ -284,13 +198,13 @@ struct heap *h_copy_of(struct heap *_heap_)
else
memcpy(result->buffer, _heap_->buffer, sizeof(size_t) * _heap_->count);
result->count = _heap_->count;
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
return result;
}
_Bool h_equals(struct heap *_heap1_, struct heap *_heap2_)
{
- _heap1_->flag = cmc_flags.OK;
- _heap2_->flag = cmc_flags.OK;
+ _heap1_->flag = CMC_FLAG_OK;
+ _heap2_->flag = CMC_FLAG_OK;
if (_heap1_->count != _heap2_->count)
return 0;
for (size_t i = 0; i < _heap1_->count; i++)
@@ -300,24 +214,50 @@ _Bool h_equals(struct heap *_heap1_, struct heap *_heap2_)
}
return 1;
}
-struct cmc_string h_to_string(struct heap *_heap_)
+static void h_impl_float_up(struct heap *_heap_, size_t index)
{
- struct cmc_string str;
- struct heap *h_ = _heap_;
- const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap";
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_heap, "heap",
- "size_t", h_, h_->buffer, h_->capacity, h_->count, t,
- h_->flag, h_->f_val, h_->alloc, h_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool h_print(struct heap *_heap_, FILE *fptr)
-{
- for (size_t i = 0; i < _heap_->count; i++)
+ size_t C = index;
+ size_t child = _heap_->buffer[C];
+ size_t parent = _heap_->buffer[(index - 1) / 2];
+ int mod = _heap_->HO;
+ while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0)
{
- if (!_heap_->f_val->str(fptr, _heap_->buffer[i]))
- return 0;
+ size_t tmp = _heap_->buffer[C];
+ _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2];
+ _heap_->buffer[(C - 1) / 2] = tmp;
+ C = (C - 1) / 2;
+ if (C == 0)
+ break;
+ child = _heap_->buffer[C];
+ parent = _heap_->buffer[(C - 1) / 2];
+ }
+}
+static void h_impl_float_down(struct heap *_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;
+ 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;
+ }
+ if (C != index)
+ {
+ size_t tmp = _heap_->buffer[index];
+ _heap_->buffer[index] = _heap_->buffer[C];
+ _heap_->buffer[C] = tmp;
+ index = C;
+ }
+ else
+ break;
}
- return 1;
}
struct heap_iter h_iter_start(struct heap *target)
{
@@ -447,52 +387,38 @@ size_t h_iter_index(struct heap_iter *iter)
{
return iter->cursor;
}
-static void h_impl_float_up(struct heap *_heap_, size_t index)
+_Bool h_to_string(struct heap *_heap_, FILE *fptr)
{
- size_t C = index;
- size_t child = _heap_->buffer[C];
- size_t parent = _heap_->buffer[(index - 1) / 2];
- int mod = _heap_->HO;
- while (C > 0 && _heap_->f_val->cmp(child, parent) * mod > 0)
- {
- size_t tmp = _heap_->buffer[C];
- _heap_->buffer[C] = _heap_->buffer[(C - 1) / 2];
- _heap_->buffer[(C - 1) / 2] = tmp;
- C = (C - 1) / 2;
- if (C == 0)
- break;
- child = _heap_->buffer[C];
- parent = _heap_->buffer[(C - 1) / 2];
- }
+ struct heap *h_ = _heap_;
+ const char *t = h_->HO == 1 ? "MaxHeap" : "MinHeap";
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "type:%s, "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks: %p}",
+ "heap", "size_t", h_, h_->buffer, h_->capacity, h_->count, t, h_->flag, h_->f_val, h_->alloc,
+ (h_)->callbacks);
}
-static void h_impl_float_down(struct heap *_heap_, size_t index)
+_Bool h_print(struct heap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end)
{
- int mod = _heap_->HO;
- while (index < _heap_->count)
+ fprintf(fptr, "%s", start);
+ for (size_t i = 0; i < _heap_->count; i++)
{
- size_t L = 2 * index + 1;
- size_t R = 2 * index + 2;
- size_t C = index;
- 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;
- }
- if (C != index)
- {
- size_t tmp = _heap_->buffer[index];
- _heap_->buffer[index] = _heap_->buffer[C];
- _heap_->buffer[C] = tmp;
- index = C;
- }
- else
- break;
+ if (!_heap_->f_val->str(fptr, _heap_->buffer[i]))
+ return 0;
+ if (i + 1 < _heap_->count)
+ fprintf(fptr, "%s", separator);
}
+ fprintf(fptr, "%s", end);
+ return 1;
}
-
-#endif /* CMC_TEST_SRC_HEAP */
diff --git a/tests/main/src/intervalheap.c b/tests/src/cmc/intervalheap.c
similarity index 68%
rename from tests/main/src/intervalheap.c
rename to tests/src/cmc/intervalheap.c
index 568ac19..56ac313 100644
--- a/tests/main/src/intervalheap.c
+++ b/tests/src/cmc/intervalheap.c
@@ -1,110 +1,18 @@
-#ifndef CMC_TEST_SRC_INTERVALHEAP
-#define CMC_TEST_SRC_INTERVALHEAP
#include "cmc/intervalheap.h"
-struct intervalheap
-{
- size_t (*buffer)[2];
- size_t capacity;
- size_t size;
- size_t count;
- int flag;
- struct intervalheap_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct intervalheap_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct intervalheap_iter
-{
- struct intervalheap *target;
- size_t cursor;
- _Bool start;
- _Bool end;
-};
-struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val);
-struct intervalheap *ih_new_custom(size_t capacity,
- struct intervalheap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void ih_clear(struct intervalheap *_heap_);
-void ih_free(struct intervalheap *_heap_);
-void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool ih_insert(struct intervalheap *_heap_, size_t value);
-_Bool ih_remove_max(struct intervalheap *_heap_);
-_Bool ih_remove_min(struct intervalheap *_heap_);
-_Bool ih_update_max(struct intervalheap *_heap_, size_t value);
-_Bool ih_update_min(struct intervalheap *_heap_, size_t value);
-size_t ih_max(struct intervalheap *_heap_);
-size_t ih_min(struct intervalheap *_heap_);
-_Bool ih_contains(struct intervalheap *_heap_, size_t value);
-_Bool ih_empty(struct intervalheap *_heap_);
-_Bool ih_full(struct intervalheap *_heap_);
-size_t ih_count(struct intervalheap *_heap_);
-size_t ih_capacity(struct intervalheap *_heap_);
-int ih_flag(struct intervalheap *_heap_);
-_Bool ih_resize(struct intervalheap *_heap_, size_t capacity);
-struct intervalheap *ih_copy_of(struct intervalheap *_set_);
-_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_);
-struct cmc_string ih_to_string(struct intervalheap *_heap_);
-_Bool ih_print(struct intervalheap *_heap_, FILE *fptr);
-struct intervalheap_iter ih_iter_start(struct intervalheap *target);
-struct intervalheap_iter ih_iter_end(struct intervalheap *target);
-_Bool ih_iter_at_start(struct intervalheap_iter *iter);
-_Bool ih_iter_at_end(struct intervalheap_iter *iter);
-_Bool ih_iter_to_start(struct intervalheap_iter *iter);
-_Bool ih_iter_to_end(struct intervalheap_iter *iter);
-_Bool ih_iter_next(struct intervalheap_iter *iter);
-_Bool ih_iter_prev(struct intervalheap_iter *iter);
-_Bool ih_iter_advance(struct intervalheap_iter *iter, size_t steps);
-_Bool ih_iter_rewind(struct intervalheap_iter *iter, size_t steps);
-_Bool ih_iter_go_to(struct intervalheap_iter *iter, size_t index);
-size_t ih_iter_value(struct intervalheap_iter *iter);
-size_t ih_iter_index(struct intervalheap_iter *iter);
static void ih_impl_float_up_max(struct intervalheap *_heap_);
static void ih_impl_float_up_min(struct intervalheap *_heap_);
static void ih_impl_float_down_max(struct intervalheap *_heap_);
static void ih_impl_float_down_min(struct intervalheap *_heap_);
struct intervalheap *ih_new(size_t capacity, struct intervalheap_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity == 0 || capacity == 0xffffffffffffffffULL)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- struct intervalheap *_heap_ = alloc->malloc(sizeof(struct intervalheap));
- if (!_heap_)
- return ((void *)0);
- capacity = (capacity + capacity % 2) / 2;
- _heap_->buffer = alloc->calloc(capacity, sizeof(size_t[2]));
- if (!_heap_->buffer)
- {
- alloc->free(_heap_);
- return ((void *)0);
- }
- _heap_->capacity = capacity;
- _heap_->size = 0;
- _heap_->count = 0;
- _heap_->flag = cmc_flags.OK;
- _heap_->f_val = f_val;
- _heap_->alloc = alloc;
- _heap_->callbacks = ((void *)0);
- return _heap_;
+ return ih_new_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-struct intervalheap *ih_new_custom(size_t capacity,
- struct intervalheap_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct intervalheap *ih_new_custom(size_t capacity, struct intervalheap_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity == 0 || capacity == 0xffffffffffffffffULL)
return ((void *)0);
if (!f_val)
@@ -124,10 +32,10 @@ struct intervalheap *ih_new_custom(size_t capacity,
_heap_->capacity = capacity;
_heap_->size = 0;
_heap_->count = 0;
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
_heap_->f_val = f_val;
_heap_->alloc = alloc;
- _heap_->callbacks = callbacks;
+ (_heap_)->callbacks = callbacks;
return _heap_;
}
void ih_clear(struct intervalheap *_heap_)
@@ -142,7 +50,7 @@ void ih_clear(struct intervalheap *_heap_)
memset(_heap_->buffer, 0, sizeof(size_t[2]) * _heap_->capacity);
_heap_->size = 0;
_heap_->count = 0;
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
}
void ih_free(struct intervalheap *_heap_)
{
@@ -156,15 +64,15 @@ void ih_free(struct intervalheap *_heap_)
_heap_->alloc->free(_heap_->buffer);
_heap_->alloc->free(_heap_);
}
-void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void ih_customize(struct intervalheap *_heap_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_heap_->alloc = &cmc_alloc_node_default;
else
_heap_->alloc = alloc;
- _heap_->callbacks = callbacks;
- _heap_->flag = cmc_flags.OK;
+ (_heap_)->callbacks = callbacks;
+ _heap_->flag = CMC_FLAG_OK;
}
_Bool ih_insert(struct intervalheap *_heap_, size_t value)
{
@@ -193,7 +101,7 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value)
}
}
_heap_->count++;
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
if (_heap_->count > 2)
{
size_t(*parent)[2] = &(_heap_->buffer[(_heap_->size - 2) / 2]);
@@ -202,15 +110,16 @@ _Bool ih_insert(struct intervalheap *_heap_, size_t value)
else if (_heap_->f_val->cmp((*parent)[1], value) < 0)
ih_impl_float_up_max(_heap_);
}
- if (_heap_->callbacks && _heap_->callbacks->create)
- _heap_->callbacks->create();
+ if ((_heap_)->callbacks && (_heap_)->callbacks->create)
+ (_heap_)->callbacks->create();
+ ;
return 1;
}
_Bool ih_remove_max(struct intervalheap *_heap_)
{
if (ih_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (_heap_->count == 1)
@@ -235,16 +144,17 @@ _Bool ih_remove_max(struct intervalheap *_heap_)
_heap_->count--;
ih_impl_float_down_max(_heap_);
success:
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->delete)
- _heap_->callbacks->delete ();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->delete)
+ (_heap_)->callbacks->delete ();
+ ;
return 1;
}
_Bool ih_remove_min(struct intervalheap *_heap_)
{
if (ih_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (_heap_->count == 1)
@@ -269,16 +179,17 @@ _Bool ih_remove_min(struct intervalheap *_heap_)
_heap_->count--;
ih_impl_float_down_min(_heap_);
success:
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->delete)
- _heap_->callbacks->delete ();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->delete)
+ (_heap_)->callbacks->delete ();
+ ;
return 1;
}
_Bool ih_update_max(struct intervalheap *_heap_, size_t value)
{
if (ih_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (_heap_->count == 1)
@@ -296,16 +207,17 @@ _Bool ih_update_max(struct intervalheap *_heap_, size_t value)
_heap_->buffer[0][1] = value;
ih_impl_float_down_max(_heap_);
}
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->update)
- _heap_->callbacks->update();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->update)
+ (_heap_)->callbacks->update();
+ ;
return 1;
}
_Bool ih_update_min(struct intervalheap *_heap_, size_t value)
{
if (ih_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (_heap_->count == 1)
@@ -323,21 +235,23 @@ _Bool ih_update_min(struct intervalheap *_heap_, size_t value)
_heap_->buffer[0][0] = value;
ih_impl_float_down_min(_heap_);
}
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->update)
- _heap_->callbacks->update();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->update)
+ (_heap_)->callbacks->update();
+ ;
return 1;
}
size_t ih_max(struct intervalheap *_heap_)
{
if (ih_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->read)
- _heap_->callbacks->read();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->read)
+ (_heap_)->callbacks->read();
+ ;
if (_heap_->count == 1)
return _heap_->buffer[0][0];
return _heap_->buffer[0][1];
@@ -346,17 +260,18 @@ size_t ih_min(struct intervalheap *_heap_)
{
if (ih_empty(_heap_))
{
- _heap_->flag = cmc_flags.EMPTY;
+ _heap_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->read)
- _heap_->callbacks->read();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->read)
+ (_heap_)->callbacks->read();
+ ;
return _heap_->buffer[0][0];
}
_Bool ih_contains(struct intervalheap *_heap_, size_t value)
{
- _heap_->flag = cmc_flags.OK;
+ _heap_->flag = CMC_FLAG_OK;
_Bool result = 0;
for (size_t i = 0; i < _heap_->count; i++)
{
@@ -366,8 +281,9 @@ _Bool ih_contains(struct intervalheap *_heap_, size_t value)
break;
}
}
- if (_heap_->callbacks && _heap_->callbacks->read)
- _heap_->callbacks->read();
+ if ((_heap_)->callbacks && (_heap_)->callbacks->read)
+ (_heap_)->callbacks->read();
+ ;
return result;
}
_Bool ih_empty(struct intervalheap *_heap_)
@@ -396,76 +312,71 @@ _Bool ih_resize(struct intervalheap *_heap_, size_t capacity)
goto success;
if (capacity < _heap_->count)
{
- _heap_->flag = cmc_flags.INVALID;
+ _heap_->flag = CMC_FLAG_INVALID;
return 0;
}
if (capacity == 0xffffffffffffffffULL)
{
- _heap_->flag = cmc_flags.ERROR;
+ _heap_->flag = CMC_FLAG_ERROR;
return 0;
}
capacity += capacity % 2;
- size_t(*new_buffer)[2] =
- _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity);
+ size_t(*new_buffer)[2] = _heap_->alloc->realloc(_heap_->buffer, sizeof(size_t[2]) * capacity);
if (!new_buffer)
{
- _heap_->flag = cmc_flags.ALLOC;
+ _heap_->flag = CMC_FLAG_ALLOC;
return 0;
}
if (capacity > _heap_->capacity)
{
- memset(new_buffer + _heap_->capacity, 0,
- sizeof(size_t[2]) * (capacity - _heap_->capacity));
+ memset(new_buffer + _heap_->capacity, 0, sizeof(size_t[2]) * (capacity - _heap_->capacity));
}
_heap_->buffer = new_buffer;
_heap_->capacity = capacity;
success:
- _heap_->flag = cmc_flags.OK;
- if (_heap_->callbacks && _heap_->callbacks->resize)
- _heap_->callbacks->resize();
+ _heap_->flag = CMC_FLAG_OK;
+ if ((_heap_)->callbacks && (_heap_)->callbacks->resize)
+ (_heap_)->callbacks->resize();
+ ;
return 1;
}
struct intervalheap *ih_copy_of(struct intervalheap *_heap_)
{
- struct intervalheap *result =
- _heap_->alloc->malloc(sizeof(struct intervalheap));
+ struct intervalheap *result = _heap_->alloc->malloc(sizeof(struct intervalheap));
if (!result)
{
- _heap_->flag = cmc_flags.ALLOC;
+ _heap_->flag = CMC_FLAG_ALLOC;
return ((void *)0);
}
memcpy(result, _heap_, sizeof(struct intervalheap));
- result->buffer =
- _heap_->alloc->malloc(sizeof(size_t[2]) * _heap_->capacity);
+ result->buffer = _heap_->alloc->malloc(sizeof(size_t[2]) * _heap_->capacity);
if (!result->buffer)
{
_heap_->alloc->free(result);
- _heap_->flag = cmc_flags.ALLOC;
+ _heap_->flag = CMC_FLAG_ALLOC;
return ((void *)0);
}
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]);
+ result->buffer[i / 2][i % 2] = _heap_->f_val->cpy(_heap_->buffer[i / 2][i % 2]);
}
else
- memcpy(result->buffer, _heap_->buffer,
- sizeof(size_t[2]) * _heap_->capacity);
+ memcpy(result->buffer, _heap_->buffer, sizeof(size_t[2]) * _heap_->capacity);
result->capacity = _heap_->capacity;
result->size = _heap_->size;
result->count = _heap_->count;
- result->flag = cmc_flags.OK;
+ result->flag = CMC_FLAG_OK;
result->f_val = _heap_->f_val;
result->alloc = _heap_->alloc;
- result->callbacks = _heap_->callbacks;
- _heap_->flag = cmc_flags.OK;
+ (result)->callbacks = _heap_->callbacks;
+ _heap_->flag = CMC_FLAG_OK;
return result;
}
_Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_)
{
- _heap1_->flag = cmc_flags.OK;
- _heap2_->flag = cmc_flags.OK;
+ _heap1_->flag = CMC_FLAG_OK;
+ _heap2_->flag = CMC_FLAG_OK;
if (_heap1_->count != _heap2_->count)
return 0;
for (size_t i = 0; i < _heap1_->count; i++)
@@ -477,24 +388,137 @@ _Bool ih_equals(struct intervalheap *_heap1_, struct intervalheap *_heap2_)
}
return 1;
}
-struct cmc_string ih_to_string(struct intervalheap *_heap_)
+static void ih_impl_float_up_max(struct intervalheap *_heap_)
{
- struct cmc_string str;
- struct intervalheap *h_ = _heap_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_intervalheap,
- "intervalheap", "size_t", h_, h_->buffer, h_->capacity,
- h_->size, h_->count, h_->flag, h_->f_val, h_->alloc,
- h_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool ih_print(struct intervalheap *_heap_, FILE *fptr)
-{
- for (size_t i = 0; i < _heap_->count; i++)
+ size_t index = _heap_->size - 1;
+ size_t(*curr_node)[2] = &(_heap_->buffer[index]);
+ while (index > 0)
{
- if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2]))
- return 0;
+ size_t P_index = (index - 1) / 2;
+ size_t(*parent)[2] = &(_heap_->buffer[P_index]);
+ if (index == _heap_->size - 1 && _heap_->count % 2 != 0)
+ {
+ if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0)
+ break;
+ size_t tmp = (*curr_node)[0];
+ (*curr_node)[0] = (*parent)[1];
+ (*parent)[1] = tmp;
+ }
+ else
+ {
+ if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0)
+ break;
+ size_t tmp = (*curr_node)[1];
+ (*curr_node)[1] = (*parent)[1];
+ (*parent)[1] = tmp;
+ }
+ index = P_index;
+ curr_node = parent;
+ }
+}
+static void ih_impl_float_up_min(struct intervalheap *_heap_)
+{
+ size_t index = _heap_->size - 1;
+ size_t(*curr_node)[2] = &(_heap_->buffer[index]);
+ while (index > 0)
+ {
+ size_t P_index = (index - 1) / 2;
+ size_t(*parent)[2] = &(_heap_->buffer[P_index]);
+ if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0)
+ break;
+ size_t tmp = (*curr_node)[0];
+ (*curr_node)[0] = (*parent)[0];
+ (*parent)[0] = tmp;
+ index = P_index;
+ curr_node = parent;
+ }
+}
+static void ih_impl_float_down_max(struct intervalheap *_heap_)
+{
+ size_t index = 0;
+ size_t(*curr_node)[2] = &(_heap_->buffer[index]);
+ while (1)
+ {
+ if (2 * index + 1 >= _heap_->size)
+ break;
+ size_t child;
+ size_t L_index = index * 2 + 1;
+ size_t R_index = index * 2 + 2;
+ if (R_index < _heap_->size)
+ {
+ size_t(*L)[2] = &(_heap_->buffer[L_index]);
+ size_t(*R)[2] = &(_heap_->buffer[R_index]);
+ 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;
+ }
+ else
+ child = L_index;
+ size_t(*child_node)[2] = &(_heap_->buffer[child]);
+ if (child == _heap_->size - 1 && _heap_->count % 2 != 0)
+ {
+ if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0)
+ break;
+ size_t tmp = (*child_node)[0];
+ (*child_node)[0] = (*curr_node)[1];
+ (*curr_node)[1] = tmp;
+ }
+ else
+ {
+ if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0)
+ break;
+ size_t tmp = (*child_node)[1];
+ (*child_node)[1] = (*curr_node)[1];
+ (*curr_node)[1] = tmp;
+ if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
+ {
+ tmp = (*child_node)[0];
+ (*child_node)[0] = (*child_node)[1];
+ (*child_node)[1] = tmp;
+ }
+ }
+ index = child;
+ curr_node = child_node;
+ }
+}
+static void ih_impl_float_down_min(struct intervalheap *_heap_)
+{
+ size_t index = 0;
+ size_t(*curr_node)[2] = &(_heap_->buffer[index]);
+ while (1)
+ {
+ if (2 * index + 1 >= _heap_->size)
+ break;
+ size_t child;
+ size_t L_index = index * 2 + 1;
+ size_t R_index = index * 2 + 2;
+ if (R_index < _heap_->size)
+ {
+ size_t(*L)[2] = &(_heap_->buffer[L_index]);
+ size_t(*R)[2] = &(_heap_->buffer[R_index]);
+ child = _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index;
+ }
+ else
+ child = L_index;
+ size_t(*child_node)[2] = &(_heap_->buffer[child]);
+ if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0)
+ break;
+ size_t tmp = (*child_node)[0];
+ (*child_node)[0] = (*curr_node)[0];
+ (*curr_node)[0] = tmp;
+ if (child != _heap_->size - 1 || _heap_->count % 2 == 0)
+ {
+ if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
+ {
+ tmp = (*child_node)[0];
+ (*child_node)[0] = (*child_node)[1];
+ (*child_node)[1] = tmp;
+ }
+ }
+ index = child;
+ curr_node = child_node;
}
- return 1;
}
struct intervalheap_iter ih_iter_start(struct intervalheap *target)
{
@@ -624,140 +648,39 @@ size_t ih_iter_index(struct intervalheap_iter *iter)
{
return iter->cursor;
}
-static void ih_impl_float_up_max(struct intervalheap *_heap_)
+_Bool ih_to_string(struct intervalheap *_heap_, FILE *fptr)
{
- size_t index = _heap_->size - 1;
- size_t(*curr_node)[2] = &(_heap_->buffer[index]);
- while (index > 0)
- {
- size_t P_index = (index - 1) / 2;
- size_t(*parent)[2] = &(_heap_->buffer[P_index]);
- if (index == _heap_->size - 1 && _heap_->count % 2 != 0)
- {
- if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[1]) < 0)
- break;
- size_t tmp = (*curr_node)[0];
- (*curr_node)[0] = (*parent)[1];
- (*parent)[1] = tmp;
- }
- else
- {
- if (_heap_->f_val->cmp((*curr_node)[1], (*parent)[1]) < 0)
- break;
- size_t tmp = (*curr_node)[1];
- (*curr_node)[1] = (*parent)[1];
- (*parent)[1] = tmp;
- }
- index = P_index;
- curr_node = parent;
- }
+ struct intervalheap *h_ = _heap_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "size:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "intervalheap", "size_t", h_, h_->buffer, h_->capacity, h_->size, h_->count, h_->flag,
+ h_->f_val, h_->alloc, (h_)->callbacks);
}
-static void ih_impl_float_up_min(struct intervalheap *_heap_)
+_Bool ih_print(struct intervalheap *_heap_, FILE *fptr, const char *start, const char *separator, const char *end)
{
- size_t index = _heap_->size - 1;
- size_t(*curr_node)[2] = &(_heap_->buffer[index]);
- while (index > 0)
+ fprintf(fptr, "%s", start);
+ for (size_t i = 0; i < _heap_->count; i++)
{
- size_t P_index = (index - 1) / 2;
- size_t(*parent)[2] = &(_heap_->buffer[P_index]);
- if (_heap_->f_val->cmp((*curr_node)[0], (*parent)[0]) >= 0)
- break;
- size_t tmp = (*curr_node)[0];
- (*curr_node)[0] = (*parent)[0];
- (*parent)[0] = tmp;
- index = P_index;
- curr_node = parent;
+ if (!_heap_->f_val->str(fptr, _heap_->buffer[i / 2][i % 2]))
+ return 0;
+ if (i + 1 < _heap_->count)
+ fprintf(fptr, "%s", separator);
}
+ fprintf(fptr, "%s", end);
+ return 1;
}
-static void ih_impl_float_down_max(struct intervalheap *_heap_)
-{
- size_t index = 0;
- size_t(*curr_node)[2] = &(_heap_->buffer[index]);
- while (1)
- {
- if (2 * index + 1 >= _heap_->size)
- break;
- size_t child;
- size_t L_index = index * 2 + 1;
- size_t R_index = index * 2 + 2;
- if (R_index < _heap_->size)
- {
- size_t(*L)[2] = &(_heap_->buffer[L_index]);
- size_t(*R)[2] = &(_heap_->buffer[R_index]);
- 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;
- }
- else
- child = L_index;
- size_t(*child_node)[2] = &(_heap_->buffer[child]);
- if (child == _heap_->size - 1 && _heap_->count % 2 != 0)
- {
- if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[0]) >= 0)
- break;
- size_t tmp = (*child_node)[0];
- (*child_node)[0] = (*curr_node)[1];
- (*curr_node)[1] = tmp;
- }
- else
- {
- if (_heap_->f_val->cmp((*curr_node)[1], (*child_node)[1]) >= 0)
- break;
- size_t tmp = (*child_node)[1];
- (*child_node)[1] = (*curr_node)[1];
- (*curr_node)[1] = tmp;
- if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
- {
- tmp = (*child_node)[0];
- (*child_node)[0] = (*child_node)[1];
- (*child_node)[1] = tmp;
- }
- }
- index = child;
- curr_node = child_node;
- }
-}
-static void ih_impl_float_down_min(struct intervalheap *_heap_)
-{
- size_t index = 0;
- size_t(*curr_node)[2] = &(_heap_->buffer[index]);
- while (1)
- {
- if (2 * index + 1 >= _heap_->size)
- break;
- size_t child;
- size_t L_index = index * 2 + 1;
- size_t R_index = index * 2 + 2;
- if (R_index < _heap_->size)
- {
- size_t(*L)[2] = &(_heap_->buffer[L_index]);
- size_t(*R)[2] = &(_heap_->buffer[R_index]);
- child =
- _heap_->f_val->cmp((*L)[0], (*R)[0]) < 0 ? L_index : R_index;
- }
- else
- child = L_index;
- size_t(*child_node)[2] = &(_heap_->buffer[child]);
- if (_heap_->f_val->cmp((*curr_node)[0], (*child_node)[0]) < 0)
- break;
- size_t tmp = (*child_node)[0];
- (*child_node)[0] = (*curr_node)[0];
- (*curr_node)[0] = tmp;
- if (child != _heap_->size - 1 || _heap_->count % 2 == 0)
- {
- if (_heap_->f_val->cmp((*child_node)[0], (*child_node)[1]) > 0)
- {
- tmp = (*child_node)[0];
- (*child_node)[0] = (*child_node)[1];
- (*child_node)[1] = tmp;
- }
- }
- index = child;
- curr_node = child_node;
- }
-}
-
-#endif /* CMC_TEST_SRC_INTERVALHEAP */
diff --git a/tests/main/src/linkedlist.c b/tests/src/cmc/linkedlist.c
similarity index 64%
rename from tests/main/src/linkedlist.c
rename to tests/src/cmc/linkedlist.c
index f5d3d6a..32dbae8 100644
--- a/tests/main/src/linkedlist.c
+++ b/tests/src/cmc/linkedlist.c
@@ -1,117 +1,14 @@
-#ifndef CMC_TEST_SRC_LINKEDLIST
-#define CMC_TEST_SRC_LINKEDLIST
#include "cmc/linkedlist.h"
-struct linkedlist
-{
- struct linkedlist_node *head;
- struct linkedlist_node *tail;
- size_t count;
- int flag;
- struct linkedlist_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct linkedlist_node
-{
- size_t value;
- struct linkedlist_node *next;
- struct linkedlist_node *prev;
-};
-struct linkedlist_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct linkedlist_iter
-{
- struct linkedlist *target;
- struct linkedlist_node *cursor;
- size_t index;
- _Bool start;
- _Bool end;
-};
-struct linkedlist *ll_new(struct linkedlist_fval *f_val);
-struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void ll_clear(struct linkedlist *_list_);
-void ll_free(struct linkedlist *_list_);
-void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool ll_push_front(struct linkedlist *_list_, size_t value);
-_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index);
-_Bool ll_push_back(struct linkedlist *_list_, size_t value);
-_Bool ll_pop_front(struct linkedlist *_list_);
-_Bool ll_pop_at(struct linkedlist *_list_, size_t index);
-_Bool ll_pop_back(struct linkedlist *_list_);
-size_t ll_front(struct linkedlist *_list_);
-size_t ll_get(struct linkedlist *_list_, size_t index);
-size_t *ll_get_ref(struct linkedlist *_list_, size_t index);
-size_t ll_back(struct linkedlist *_list_);
-_Bool ll_contains(struct linkedlist *_list_, size_t value);
-_Bool ll_empty(struct linkedlist *_list_);
-size_t ll_count(struct linkedlist *_list_);
-int ll_flag(struct linkedlist *_list_);
-struct linkedlist *ll_copy_of(struct linkedlist *_list_);
-_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_);
-struct cmc_string ll_to_string(struct linkedlist *_list_);
-_Bool ll_print(struct linkedlist *_list_, FILE *fptr);
-struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value);
-void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_);
-struct linkedlist_node *ll_head(struct linkedlist *_list_);
-struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index);
-struct linkedlist_node *ll_tail(struct linkedlist *_list_);
-_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_,
- size_t value);
-_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_,
- size_t value);
-_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_);
-_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_);
-_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_);
-struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_);
-struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_);
-struct linkedlist_iter ll_iter_start(struct linkedlist *target);
-struct linkedlist_iter ll_iter_end(struct linkedlist *target);
-_Bool ll_iter_at_start(struct linkedlist_iter *iter);
-_Bool ll_iter_at_end(struct linkedlist_iter *iter);
-_Bool ll_iter_to_start(struct linkedlist_iter *iter);
-_Bool ll_iter_to_end(struct linkedlist_iter *iter);
-_Bool ll_iter_next(struct linkedlist_iter *iter);
-_Bool ll_iter_prev(struct linkedlist_iter *iter);
-_Bool ll_iter_advance(struct linkedlist_iter *iter, size_t steps);
-_Bool ll_iter_rewind(struct linkedlist_iter *iter, size_t steps);
-_Bool ll_iter_go_to(struct linkedlist_iter *iter, size_t index);
-size_t ll_iter_value(struct linkedlist_iter *iter);
-size_t *ll_iter_rvalue(struct linkedlist_iter *iter);
-size_t ll_iter_index(struct linkedlist_iter *iter);
-struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter);
struct linkedlist *ll_new(struct linkedlist_fval *f_val)
{
- if (!f_val)
- return ((void *)0);
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- struct linkedlist *_list_ = alloc->malloc(sizeof(struct linkedlist));
- if (!_list_)
- return ((void *)0);
- _list_->count = 0;
- _list_->head = ((void *)0);
- _list_->tail = ((void *)0);
- _list_->flag = cmc_flags.OK;
- _list_->f_val = f_val;
- _list_->alloc = alloc;
- _list_->callbacks = ((void *)0);
- return _list_;
+ return ll_new_custom(f_val, ((void *)0), ((void *)0));
}
-struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (!f_val)
return ((void *)0);
if (!alloc)
@@ -122,10 +19,10 @@ struct linkedlist *ll_new_custom(struct linkedlist_fval *f_val,
_list_->count = 0;
_list_->head = ((void *)0);
_list_->tail = ((void *)0);
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
_list_->f_val = f_val;
_list_->alloc = alloc;
- _list_->callbacks = callbacks;
+ (_list_)->callbacks = callbacks;
return _list_;
}
void ll_clear(struct linkedlist *_list_)
@@ -144,22 +41,22 @@ void ll_clear(struct linkedlist *_list_)
_list_->count = 0;
_list_->head = ((void *)0);
_list_->tail = ((void *)0);
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
}
void ll_free(struct linkedlist *_list_)
{
ll_clear(_list_);
_list_->alloc->free(_list_);
}
-void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void ll_customize(struct linkedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_list_->alloc = &cmc_alloc_node_default;
else
_list_->alloc = alloc;
- _list_->callbacks = callbacks;
- _list_->flag = cmc_flags.OK;
+ (_list_)->callbacks = callbacks;
+ _list_->flag = CMC_FLAG_OK;
}
_Bool ll_push_front(struct linkedlist *_list_, size_t value)
{
@@ -178,16 +75,17 @@ _Bool ll_push_front(struct linkedlist *_list_, size_t value)
_list_->head = _node_;
}
_list_->count++;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index)
{
if (index > _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return 0;
}
if (index == 0)
@@ -207,9 +105,10 @@ _Bool ll_push_at(struct linkedlist *_list_, size_t value, size_t index)
_node_->next->prev = _node_;
_node_->prev->next = _node_;
_list_->count++;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool ll_push_back(struct linkedlist *_list_, size_t value)
@@ -229,16 +128,17 @@ _Bool ll_push_back(struct linkedlist *_list_, size_t value)
_list_->tail = _node_;
}
_list_->count++;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool ll_pop_front(struct linkedlist *_list_)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct linkedlist_node *_node_ = _list_->head;
@@ -249,21 +149,22 @@ _Bool ll_pop_front(struct linkedlist *_list_)
else
_list_->head->prev = ((void *)0);
_list_->count--;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
_Bool ll_pop_at(struct linkedlist *_list_, size_t index)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return 0;
}
if (index == 0)
@@ -281,16 +182,17 @@ _Bool ll_pop_at(struct linkedlist *_list_, size_t index)
_node_->prev->next = _node_->next;
_list_->alloc->free(_node_);
_list_->count--;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
_Bool ll_pop_back(struct linkedlist *_list_)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct linkedlist_node *_node_ = _list_->tail;
@@ -301,76 +203,81 @@ _Bool ll_pop_back(struct linkedlist *_list_)
else
_list_->tail->next = ((void *)0);
_list_->count--;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
size_t ll_front(struct linkedlist *_list_)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->head->value;
}
size_t ll_get(struct linkedlist *_list_, size_t index)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return (size_t){ 0 };
}
struct linkedlist_node *scan = ll_get_node(_list_, index);
if (scan == ((void *)0))
return (size_t){ 0 };
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return scan->value;
}
size_t *ll_get_ref(struct linkedlist *_list_, size_t index)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return ((void *)0);
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return ((void *)0);
}
struct linkedlist_node *scan = ll_get_node(_list_, index);
if (scan == ((void *)0))
return ((void *)0);
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return &(scan->value);
}
size_t ll_back(struct linkedlist *_list_)
{
if (ll_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->tail->value;
}
_Bool ll_contains(struct linkedlist *_list_, size_t value)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
_Bool result = 0;
struct linkedlist_node *scan = _list_->head;
while (scan != ((void *)0))
@@ -382,8 +289,9 @@ _Bool ll_contains(struct linkedlist *_list_, size_t value)
}
scan = scan->next;
}
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return result;
}
_Bool ll_empty(struct linkedlist *_list_)
@@ -400,10 +308,10 @@ int ll_flag(struct linkedlist *_list_)
}
struct linkedlist *ll_copy_of(struct linkedlist *_list_)
{
- struct linkedlist *result =
- ll_new_custom(_list_->f_val, _list_->alloc, _list_->callbacks);
+ struct linkedlist *result = ll_new_custom(_list_->f_val, _list_->alloc, ((void *)0));
if (!result)
return ((void *)0);
+ (result)->callbacks = _list_->callbacks;
struct linkedlist_node *scan = _list_->head;
while (scan != ((void *)0))
{
@@ -426,13 +334,13 @@ struct linkedlist *ll_copy_of(struct linkedlist *_list_)
scan = scan->next;
}
result->count = _list_->count;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
return result;
}
_Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_)
{
- _list1_->flag = cmc_flags.OK;
- _list2_->flag = cmc_flags.OK;
+ _list1_->flag = CMC_FLAG_OK;
+ _list2_->flag = CMC_FLAG_OK;
if (_list1_->count != _list2_->count)
return 0;
struct linkedlist_node *scan1 = _list1_->head;
@@ -446,177 +354,6 @@ _Bool ll_equals(struct linkedlist *_list1_, struct linkedlist *_list2_)
}
return 1;
}
-struct cmc_string ll_to_string(struct linkedlist *_list_)
-{
- struct cmc_string str;
- struct linkedlist *l_ = _list_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_linkedlist,
- "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail,
- l_->flag, l_->f_val, l_->alloc, l_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool ll_print(struct linkedlist *_list_, FILE *fptr)
-{
- struct linkedlist_node *scan = _list_->head;
- while (scan != ((void *)0))
- {
- if (!_list_->f_val->str(fptr, scan->value))
- return 0;
- scan = scan->next;
- }
- return 1;
-}
-struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value)
-{
- struct linkedlist_node *_node_ =
- _list_->alloc->malloc(sizeof(struct linkedlist_node));
- if (!_node_)
- {
- _list_->flag = cmc_flags.ALLOC;
- return ((void *)0);
- }
- _node_->value = value;
- _node_->next = ((void *)0);
- _node_->prev = ((void *)0);
- return _node_;
-}
-void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_)
-{
- _list_->alloc->free(_node_);
-}
-struct linkedlist_node *ll_head(struct linkedlist *_list_)
-{
- return _list_->head;
-}
-struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index)
-{
- if (ll_empty(_list_))
- {
- _list_->flag = cmc_flags.EMPTY;
- return ((void *)0);
- }
- if (index >= _list_->count)
- {
- _list_->flag = cmc_flags.RANGE;
- return ((void *)0);
- }
- struct linkedlist_node *_node_ = ((void *)0);
- if (index <= _list_->count / 2)
- {
- _node_ = _list_->head;
- for (size_t i = 0; i < index; i++)
- {
- _node_ = _node_->next;
- }
- }
- else
- {
- _node_ = _list_->tail;
- for (size_t i = _list_->count - 1; i > index; i--)
- {
- _node_ = _node_->prev;
- }
- }
- _list_->flag = cmc_flags.OK;
- return _node_;
-}
-struct linkedlist_node *ll_tail(struct linkedlist *_list_)
-{
- return _list_->tail;
-}
-_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_,
- size_t value)
-{
- struct linkedlist_node *new_node = ll_new_node(_owner_, value);
- if (!new_node)
- return 0;
- new_node->next = _node_->next;
- if (_node_->next != ((void *)0))
- _node_->next->prev = new_node;
- else
- _owner_->tail = new_node;
- new_node->prev = _node_;
- _node_->next = new_node;
- _owner_->count++;
- _owner_->flag = cmc_flags.OK;
- return 1;
-}
-_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_,
- size_t value)
-{
- struct linkedlist_node *new_node = ll_new_node(_owner_, value);
- if (!new_node)
- return 0;
- new_node->prev = _node_->prev;
- if (_node_->prev != ((void *)0))
- _node_->prev->next = new_node;
- else
- _owner_->head = new_node;
- new_node->next = _node_;
- _node_->prev = new_node;
- _owner_->count++;
- _owner_->flag = cmc_flags.OK;
- return 1;
-}
-_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_)
-{
- if (_node_->next == ((void *)0))
- {
- _owner_->flag = cmc_flags.INVALID;
- return 0;
- }
- struct linkedlist_node *tmp = _node_->next;
- _node_->next = _node_->next->next;
- if (tmp->next != ((void *)0))
- tmp->next->prev = _node_;
- else
- _owner_->tail = _node_;
- _owner_->alloc->free(tmp);
- _owner_->count--;
- _owner_->flag = cmc_flags.OK;
- return 1;
-}
-_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_)
-{
- if (_node_->prev != ((void *)0))
- _node_->prev->next = _node_->next;
- else
- _owner_->head = _node_->next;
- if (_node_->next != ((void *)0))
- _node_->next->prev = _node_->prev;
- else
- _owner_->tail = _node_->prev;
- _owner_->alloc->free(_node_);
- _owner_->count--;
- _owner_->flag = cmc_flags.OK;
- return 1;
-}
-_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_)
-{
- if (_node_->prev == ((void *)0))
- {
- _owner_->flag = cmc_flags.INVALID;
- return 0;
- }
- struct linkedlist_node *tmp = _node_->prev;
- _node_->prev = _node_->prev->prev;
- if (tmp->prev != ((void *)0))
- tmp->prev->next = _node_;
- else
- _owner_->head = _node_;
- _owner_->alloc->free(tmp);
- _owner_->count--;
- _owner_->flag = cmc_flags.OK;
- return 1;
-}
-struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_)
-{
- return _node_->next;
-}
-struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_)
-{
- return _node_->prev;
-}
struct linkedlist_iter ll_iter_start(struct linkedlist *target)
{
struct linkedlist_iter iter;
@@ -763,5 +500,184 @@ struct linkedlist_node *ll_iter_node(struct linkedlist_iter *iter)
{
return iter->cursor;
}
-
-#endif /* CMC_TEST_SRC_LINKEDLIST */
+struct linkedlist_node *ll_new_node(struct linkedlist *_list_, size_t value)
+{
+ struct linkedlist_node *_node_ = _list_->alloc->malloc(sizeof(struct linkedlist_node));
+ if (!_node_)
+ {
+ _list_->flag = CMC_FLAG_ALLOC;
+ return ((void *)0);
+ }
+ _node_->value = value;
+ _node_->next = ((void *)0);
+ _node_->prev = ((void *)0);
+ return _node_;
+}
+void ll_free_node(struct linkedlist *_list_, struct linkedlist_node *_node_)
+{
+ _list_->alloc->free(_node_);
+}
+struct linkedlist_node *ll_head(struct linkedlist *_list_)
+{
+ return _list_->head;
+}
+struct linkedlist_node *ll_get_node(struct linkedlist *_list_, size_t index)
+{
+ if (ll_empty(_list_))
+ {
+ _list_->flag = CMC_FLAG_EMPTY;
+ return ((void *)0);
+ }
+ if (index >= _list_->count)
+ {
+ _list_->flag = CMC_FLAG_RANGE;
+ return ((void *)0);
+ }
+ struct linkedlist_node *_node_ = ((void *)0);
+ if (index <= _list_->count / 2)
+ {
+ _node_ = _list_->head;
+ for (size_t i = 0; i < index; i++)
+ {
+ _node_ = _node_->next;
+ }
+ }
+ else
+ {
+ _node_ = _list_->tail;
+ for (size_t i = _list_->count - 1; i > index; i--)
+ {
+ _node_ = _node_->prev;
+ }
+ }
+ _list_->flag = CMC_FLAG_OK;
+ return _node_;
+}
+struct linkedlist_node *ll_tail(struct linkedlist *_list_)
+{
+ return _list_->tail;
+}
+_Bool ll_add_next(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value)
+{
+ struct linkedlist_node *new_node = ll_new_node(_owner_, value);
+ if (!new_node)
+ return 0;
+ new_node->next = _node_->next;
+ if (_node_->next != ((void *)0))
+ _node_->next->prev = new_node;
+ else
+ _owner_->tail = new_node;
+ new_node->prev = _node_;
+ _node_->next = new_node;
+ _owner_->count++;
+ _owner_->flag = CMC_FLAG_OK;
+ return 1;
+}
+_Bool ll_add_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_, size_t value)
+{
+ struct linkedlist_node *new_node = ll_new_node(_owner_, value);
+ if (!new_node)
+ return 0;
+ new_node->prev = _node_->prev;
+ if (_node_->prev != ((void *)0))
+ _node_->prev->next = new_node;
+ else
+ _owner_->head = new_node;
+ new_node->next = _node_;
+ _node_->prev = new_node;
+ _owner_->count++;
+ _owner_->flag = CMC_FLAG_OK;
+ return 1;
+}
+_Bool ll_del_next(struct linkedlist *_owner_, struct linkedlist_node *_node_)
+{
+ if (_node_->next == ((void *)0))
+ {
+ _owner_->flag = CMC_FLAG_INVALID;
+ return 0;
+ }
+ struct linkedlist_node *tmp = _node_->next;
+ _node_->next = _node_->next->next;
+ if (tmp->next != ((void *)0))
+ tmp->next->prev = _node_;
+ else
+ _owner_->tail = _node_;
+ _owner_->alloc->free(tmp);
+ _owner_->count--;
+ _owner_->flag = CMC_FLAG_OK;
+ return 1;
+}
+_Bool ll_del_curr(struct linkedlist *_owner_, struct linkedlist_node *_node_)
+{
+ if (_node_->prev != ((void *)0))
+ _node_->prev->next = _node_->next;
+ else
+ _owner_->head = _node_->next;
+ if (_node_->next != ((void *)0))
+ _node_->next->prev = _node_->prev;
+ else
+ _owner_->tail = _node_->prev;
+ _owner_->alloc->free(_node_);
+ _owner_->count--;
+ _owner_->flag = CMC_FLAG_OK;
+ return 1;
+}
+_Bool ll_del_prev(struct linkedlist *_owner_, struct linkedlist_node *_node_)
+{
+ if (_node_->prev == ((void *)0))
+ {
+ _owner_->flag = CMC_FLAG_INVALID;
+ return 0;
+ }
+ struct linkedlist_node *tmp = _node_->prev;
+ _node_->prev = _node_->prev->prev;
+ if (tmp->prev != ((void *)0))
+ tmp->prev->next = _node_;
+ else
+ _owner_->head = _node_;
+ _owner_->alloc->free(tmp);
+ _owner_->count--;
+ _owner_->flag = CMC_FLAG_OK;
+ return 1;
+}
+struct linkedlist_node *ll_next_node(struct linkedlist_node *_node_)
+{
+ return _node_->next;
+}
+struct linkedlist_node *ll_prev_node(struct linkedlist_node *_node_)
+{
+ return _node_->prev;
+}
+_Bool ll_to_string(struct linkedlist *_list_, FILE *fptr)
+{
+ struct linkedlist *l_ = _list_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "count:%"
+ "I64u"
+ ", "
+ "head:%p, "
+ "tail:%p, "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "linkedlist", "size_t", l_, l_->count, l_->head, l_->tail, l_->flag, l_->f_val, l_->alloc,
+ (l_)->callbacks);
+}
+_Bool ll_print(struct linkedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ struct linkedlist_node *scan = _list_->head;
+ while (scan != ((void *)0))
+ {
+ if (!_list_->f_val->str(fptr, scan->value))
+ return 0;
+ scan = scan->next;
+ if (scan)
+ fprintf(fptr, "%s", separator);
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
+}
diff --git a/tests/main/src/list.c b/tests/src/cmc/list.c
similarity index 56%
rename from tests/main/src/list.c
rename to tests/src/cmc/list.c
index 221171c..6d65763 100644
--- a/tests/main/src/list.c
+++ b/tests/src/cmc/list.c
@@ -1,111 +1,14 @@
-#ifndef CMC_TEST_SRC_LIST
-#define CMC_TEST_SRC_LIST
#include "cmc/list.h"
-struct list
-{
- size_t *buffer;
- size_t capacity;
- size_t count;
- int flag;
- struct list_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct list_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct list_iter
-{
- struct list *target;
- size_t cursor;
- _Bool start;
- _Bool end;
-};
-struct list *l_new(size_t capacity, struct list_fval *f_val);
-struct list *l_new_custom(size_t capacity, struct list_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void l_clear(struct list *_list_);
-void l_free(struct list *_list_);
-void l_customize(struct list *_list_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool l_push_front(struct list *_list_, size_t value);
-_Bool l_push_at(struct list *_list_, size_t value, size_t index);
-_Bool l_push_back(struct list *_list_, size_t value);
-_Bool l_pop_front(struct list *_list_);
-_Bool l_pop_at(struct list *_list_, size_t index);
-_Bool l_pop_back(struct list *_list_);
-_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size);
-_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size,
- size_t index);
-_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size);
-_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to);
-struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to);
-size_t l_front(struct list *_list_);
-size_t l_get(struct list *_list_, size_t index);
-size_t *l_get_ref(struct list *_list_, size_t index);
-size_t l_back(struct list *_list_);
-size_t l_index_of(struct list *_list_, size_t value, _Bool from_start);
-_Bool l_contains(struct list *_list_, size_t value);
-_Bool l_empty(struct list *_list_);
-_Bool l_full(struct list *_list_);
-size_t l_count(struct list *_list_);
-_Bool l_fits(struct list *_list_, size_t size);
-size_t l_capacity(struct list *_list_);
-int l_flag(struct list *_list_);
-_Bool l_resize(struct list *_list_, size_t capacity);
-struct list *l_copy_of(struct list *_list_);
-_Bool l_equals(struct list *_list1_, struct list *_list2_);
-struct cmc_string l_to_string(struct list *_list_);
-_Bool l_print(struct list *_list_, FILE *fptr);
-struct list_iter l_iter_start(struct list *target);
-struct list_iter l_iter_end(struct list *target);
-_Bool l_iter_at_start(struct list_iter *iter);
-_Bool l_iter_at_end(struct list_iter *iter);
-_Bool l_iter_to_start(struct list_iter *iter);
-_Bool l_iter_to_end(struct list_iter *iter);
-_Bool l_iter_next(struct list_iter *iter);
-_Bool l_iter_prev(struct list_iter *iter);
-_Bool l_iter_advance(struct list_iter *iter, size_t steps);
-_Bool l_iter_rewind(struct list_iter *iter, size_t steps);
-_Bool l_iter_go_to(struct list_iter *iter, size_t index);
-size_t l_iter_value(struct list_iter *iter);
-size_t *l_iter_rvalue(struct list_iter *iter);
-size_t l_iter_index(struct list_iter *iter);
struct list *l_new(size_t capacity, struct list_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity < 1)
- return ((void *)0);
- struct list *_list_ = alloc->malloc(sizeof(struct list));
- if (!_list_)
- return ((void *)0);
- _list_->buffer = alloc->calloc(capacity, sizeof(size_t));
- if (!_list_->buffer)
- {
- alloc->free(_list_);
- return ((void *)0);
- }
- _list_->capacity = capacity;
- _list_->count = 0;
- _list_->flag = cmc_flags.OK;
- _list_->f_val = f_val;
- _list_->alloc = alloc;
- _list_->callbacks = ((void *)0);
- return _list_;
+ return l_new_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-struct list *l_new_custom(size_t capacity, struct list_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct list *l_new_custom(size_t capacity, struct list_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity < 1)
return ((void *)0);
if (!f_val)
@@ -123,10 +26,10 @@ struct list *l_new_custom(size_t capacity, struct list_fval *f_val,
}
_list_->capacity = capacity;
_list_->count = 0;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
_list_->f_val = f_val;
_list_->alloc = alloc;
- _list_->callbacks = callbacks;
+ (_list_)->callbacks = callbacks;
return _list_;
}
void l_clear(struct list *_list_)
@@ -138,7 +41,7 @@ void l_clear(struct list *_list_)
}
memset(_list_->buffer, 0, sizeof(size_t) * _list_->capacity);
_list_->count = 0;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
}
void l_free(struct list *_list_)
{
@@ -150,15 +53,15 @@ void l_free(struct list *_list_)
_list_->alloc->free(_list_->buffer);
_list_->alloc->free(_list_);
}
-void l_customize(struct list *_list_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void l_customize(struct list *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_list_->alloc = &cmc_alloc_node_default;
else
_list_->alloc = alloc;
- _list_->callbacks = callbacks;
- _list_->flag = cmc_flags.OK;
+ (_list_)->callbacks = callbacks;
+ _list_->flag = CMC_FLAG_OK;
}
_Bool l_push_front(struct list *_list_, size_t value)
{
@@ -169,21 +72,21 @@ _Bool l_push_front(struct list *_list_, size_t value)
}
if (!l_empty(_list_))
{
- memmove(_list_->buffer + 1, _list_->buffer,
- _list_->count * sizeof(size_t));
+ memmove(_list_->buffer + 1, _list_->buffer, _list_->count * sizeof(size_t));
}
_list_->buffer[0] = value;
_list_->count++;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool l_push_at(struct list *_list_, size_t value, size_t index)
{
if (index > _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return 0;
}
if (l_full(_list_))
@@ -191,13 +94,13 @@ _Bool l_push_at(struct list *_list_, size_t value, size_t index)
if (!l_resize(_list_, _list_->count * 2))
return 0;
}
- memmove(_list_->buffer + index + 1, _list_->buffer + index,
- (_list_->count - index) * sizeof(size_t));
+ memmove(_list_->buffer + index + 1, _list_->buffer + index, (_list_->count - index) * sizeof(size_t));
_list_->buffer[index] = value;
_list_->count++;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool l_push_back(struct list *_list_, size_t value)
@@ -208,44 +111,45 @@ _Bool l_push_back(struct list *_list_, size_t value)
return 0;
}
_list_->buffer[_list_->count++] = value;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool l_pop_front(struct list *_list_)
{
if (l_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return 0;
}
- memmove(_list_->buffer, _list_->buffer + 1,
- (_list_->count - 1) * sizeof(size_t));
+ memmove(_list_->buffer, _list_->buffer + 1, (_list_->count - 1) * sizeof(size_t));
_list_->buffer[--_list_->count] = (size_t){ 0 };
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
_Bool l_pop_at(struct list *_list_, size_t index)
{
if (l_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return 0;
}
- memmove(_list_->buffer + index, _list_->buffer + index + 1,
- (_list_->count - index - 1) * sizeof(size_t));
+ memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index - 1) * sizeof(size_t));
_list_->buffer[--_list_->count] = (size_t){ 0 };
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
_Bool l_pop_back(struct list *_list_)
@@ -253,196 +157,77 @@ _Bool l_pop_back(struct list *_list_)
if (l_empty(_list_))
return 0;
_list_->buffer[--_list_->count] = (size_t){ 0 };
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
-_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size)
-{
- if (size == 0)
- {
- _list_->flag = cmc_flags.INVALID;
- return 0;
- }
- if (!l_fits(_list_, size))
- {
- if (!l_resize(_list_, _list_->count + size))
- return 0;
- }
- memmove(_list_->buffer + size, _list_->buffer,
- _list_->count * sizeof(size_t));
- memcpy(_list_->buffer, values, size * sizeof(size_t));
- _list_->count += size;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
- return 1;
-}
-_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size,
- size_t index)
-{
- if (size == 0)
- {
- _list_->flag = cmc_flags.INVALID;
- return 0;
- }
- if (index > _list_->count)
- {
- _list_->flag = cmc_flags.RANGE;
- return 0;
- }
- if (index == 0)
- return l_seq_push_front(_list_, values, size);
- else if (index == _list_->count)
- return l_seq_push_back(_list_, values, size);
- if (!l_fits(_list_, size))
- {
- if (!l_resize(_list_, _list_->count + size))
- return 0;
- }
- memmove(_list_->buffer + index + size, _list_->buffer + index,
- (_list_->count - index) * sizeof(size_t));
- memcpy(_list_->buffer + index, values, size * sizeof(size_t));
- _list_->count += size;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
- return 1;
-}
-_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size)
-{
- if (size == 0)
- {
- _list_->flag = cmc_flags.INVALID;
- return 0;
- }
- if (!l_fits(_list_, size))
- {
- if (!l_resize(_list_, _list_->count + size))
- return 0;
- }
- memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t));
- _list_->count += size;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
- return 1;
-}
-_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to)
-{
- if (from > to)
- {
- _list_->flag = cmc_flags.INVALID;
- return 0;
- }
- if (to >= _list_->count)
- {
- _list_->flag = cmc_flags.RANGE;
- return 0;
- }
- size_t length = (to - from + 1);
- memmove(_list_->buffer + from, _list_->buffer + to + 1,
- (_list_->count - to - 1) * sizeof(size_t));
- memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
- _list_->count -= to - from + 1;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
- return 1;
-}
-struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to)
-{
- if (from > to)
- {
- _list_->flag = cmc_flags.INVALID;
- return ((void *)0);
- }
- if (to >= _list_->count)
- {
- _list_->flag = cmc_flags.RANGE;
- return ((void *)0);
- }
- size_t length = to - from + 1;
- struct list *result =
- l_new_custom(length, _list_->f_val, _list_->alloc, _list_->callbacks);
- if (!result)
- {
- _list_->flag = cmc_flags.ALLOC;
- return ((void *)0);
- }
- memcpy(result->buffer, _list_->buffer, length * sizeof(size_t));
- memmove(_list_->buffer + from, _list_->buffer + to + 1,
- (_list_->count - to - 1) * sizeof(size_t));
- memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
- _list_->count -= length;
- result->count = length;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
- return result;
-}
size_t l_front(struct list *_list_)
{
if (l_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->buffer[0];
}
size_t l_get(struct list *_list_, size_t index)
{
if (l_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return (size_t){ 0 };
}
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->buffer[index];
}
size_t *l_get_ref(struct list *_list_, size_t index)
{
if (l_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return ((void *)0);
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return ((void *)0);
}
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return &(_list_->buffer[index]);
}
size_t l_back(struct list *_list_)
{
if (l_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->buffer[_list_->count - 1];
}
size_t l_index_of(struct list *_list_, size_t value, _Bool from_start)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
size_t result = _list_->count;
if (from_start)
{
@@ -466,13 +251,14 @@ size_t l_index_of(struct list *_list_, size_t value, _Bool from_start)
}
}
}
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return result;
}
_Bool l_contains(struct list *_list_, size_t value)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
_Bool result = 0;
for (size_t i = 0; i < _list_->count; i++)
{
@@ -482,8 +268,9 @@ _Bool l_contains(struct list *_list_, size_t value)
break;
}
}
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return result;
}
_Bool l_empty(struct list *_list_)
@@ -512,36 +299,36 @@ int l_flag(struct list *_list_)
}
_Bool l_resize(struct list *_list_, size_t capacity)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
if (_list_->capacity == capacity)
return 1;
if (capacity < _list_->count)
{
- _list_->flag = cmc_flags.INVALID;
+ _list_->flag = CMC_FLAG_INVALID;
return 0;
}
- size_t *new_buffer =
- _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity);
+ size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity);
if (!new_buffer)
{
- _list_->flag = cmc_flags.ALLOC;
+ _list_->flag = CMC_FLAG_ALLOC;
return 0;
}
_list_->buffer = new_buffer;
_list_->capacity = capacity;
- if (_list_->callbacks && _list_->callbacks->resize)
- _list_->callbacks->resize();
+ if ((_list_)->callbacks && (_list_)->callbacks->resize)
+ (_list_)->callbacks->resize();
+ ;
return 1;
}
struct list *l_copy_of(struct list *_list_)
{
- struct list *result = l_new_custom(_list_->capacity, _list_->f_val,
- _list_->alloc, _list_->callbacks);
+ struct list *result = l_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0));
if (!result)
{
- _list_->flag = cmc_flags.ALLOC;
+ _list_->flag = CMC_FLAG_ALLOC;
return ((void *)0);
}
+ (result)->callbacks = _list_->callbacks;
if (_list_->f_val->cpy)
{
for (size_t i = 0; i < _list_->count; i++)
@@ -550,36 +337,18 @@ struct list *l_copy_of(struct list *_list_)
else
memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count);
result->count = _list_->count;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
return result;
}
_Bool l_equals(struct list *_list1_, struct list *_list2_)
{
- _list1_->flag = cmc_flags.OK;
- _list2_->flag = cmc_flags.OK;
+ _list1_->flag = CMC_FLAG_OK;
+ _list2_->flag = CMC_FLAG_OK;
if (_list1_->count != _list2_->count)
return 0;
for (size_t i = 0; i < _list1_->count; i++)
{
- if (_list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]) != 0)
- return 0;
- }
- return 1;
-}
-struct cmc_string l_to_string(struct list *_list_)
-{
- struct cmc_string str;
- struct list *l_ = _list_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_list, "list",
- "size_t", l_, l_->buffer, l_->capacity, l_->count,
- l_->flag, l_->f_val, l_->alloc, l_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool l_print(struct list *_list_, FILE *fptr)
-{
- for (size_t i = 0; i < _list_->count; i++)
- {
- if (!_list_->f_val->str(fptr, _list_->buffer[i]))
+ if (0 != _list1_->f_val->cmp(_list1_->buffer[i], _list2_->buffer[i]))
return 0;
}
return 1;
@@ -716,5 +485,159 @@ size_t l_iter_index(struct list_iter *iter)
{
return iter->cursor;
}
-
-#endif /* CMC_TEST_SRC_LIST */
+_Bool l_seq_push_front(struct list *_list_, size_t *values, size_t size)
+{
+ if (size == 0)
+ {
+ _list_->flag = CMC_FLAG_INVALID;
+ return 0;
+ }
+ if (!l_fits(_list_, size))
+ {
+ if (!l_resize(_list_, _list_->count + size))
+ return 0;
+ }
+ memmove(_list_->buffer + size, _list_->buffer, _list_->count * sizeof(size_t));
+ memcpy(_list_->buffer, values, size * sizeof(size_t));
+ _list_->count += size;
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
+ return 1;
+}
+_Bool l_seq_push_at(struct list *_list_, size_t *values, size_t size, size_t index)
+{
+ if (size == 0)
+ {
+ _list_->flag = CMC_FLAG_INVALID;
+ return 0;
+ }
+ if (index > _list_->count)
+ {
+ _list_->flag = CMC_FLAG_RANGE;
+ return 0;
+ }
+ if (index == 0)
+ return l_seq_push_front(_list_, values, size);
+ else if (index == _list_->count)
+ return l_seq_push_back(_list_, values, size);
+ if (!l_fits(_list_, size))
+ {
+ if (!l_resize(_list_, _list_->count + size))
+ return 0;
+ }
+ memmove(_list_->buffer + index + size, _list_->buffer + index, (_list_->count - index) * sizeof(size_t));
+ memcpy(_list_->buffer + index, values, size * sizeof(size_t));
+ _list_->count += size;
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
+ return 1;
+}
+_Bool l_seq_push_back(struct list *_list_, size_t *values, size_t size)
+{
+ if (size == 0)
+ {
+ _list_->flag = CMC_FLAG_INVALID;
+ return 0;
+ }
+ if (!l_fits(_list_, size))
+ {
+ if (!l_resize(_list_, _list_->count + size))
+ return 0;
+ }
+ memcpy(_list_->buffer + _list_->count, values, size * sizeof(size_t));
+ _list_->count += size;
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
+ return 1;
+}
+_Bool l_seq_pop_at(struct list *_list_, size_t from, size_t to)
+{
+ if (from > to)
+ {
+ _list_->flag = CMC_FLAG_INVALID;
+ return 0;
+ }
+ if (to >= _list_->count)
+ {
+ _list_->flag = CMC_FLAG_RANGE;
+ return 0;
+ }
+ size_t length = (to - from + 1);
+ memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t));
+ memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
+ _list_->count -= to - from + 1;
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
+ return 1;
+}
+struct list *l_seq_sublist(struct list *_list_, size_t from, size_t to)
+{
+ if (from > to)
+ {
+ _list_->flag = CMC_FLAG_INVALID;
+ return ((void *)0);
+ }
+ if (to >= _list_->count)
+ {
+ _list_->flag = CMC_FLAG_RANGE;
+ return ((void *)0);
+ }
+ size_t length = to - from + 1;
+ struct list *result = l_new_custom(length, _list_->f_val, _list_->alloc, (_list_)->callbacks);
+ if (!result)
+ {
+ _list_->flag = CMC_FLAG_ALLOC;
+ return ((void *)0);
+ }
+ memcpy(result->buffer, _list_->buffer, length * sizeof(size_t));
+ memmove(_list_->buffer + from, _list_->buffer + to + 1, (_list_->count - to - 1) * sizeof(size_t));
+ memset(_list_->buffer + _list_->count - length, 0, length * sizeof(size_t));
+ _list_->count -= length;
+ result->count = length;
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
+ return result;
+}
+_Bool l_to_string(struct list *_list_, FILE *fptr)
+{
+ struct list *l_ = _list_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "list", "size_t", l_, l_->buffer, l_->capacity, l_->count, l_->flag, l_->f_val, l_->alloc,
+ (l_)->callbacks);
+}
+_Bool l_print(struct list *_list_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ for (size_t i = 0; i < _list_->count; i++)
+ {
+ if (!_list_->f_val->str(fptr, _list_->buffer[i]))
+ return 0;
+ if (i + 1 < _list_->count)
+ fprintf(fptr, "%s", separator);
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
+}
diff --git a/tests/main/src/queue.c b/tests/src/cmc/queue.c
similarity index 63%
rename from tests/main/src/queue.c
rename to tests/src/cmc/queue.c
index f749065..de55581 100644
--- a/tests/main/src/queue.c
+++ b/tests/src/cmc/queue.c
@@ -1,103 +1,14 @@
-#ifndef CMC_TEST_SRC_QUEUE
-#define CMC_TEST_SRC_QUEUE
#include "cmc/queue.h"
-struct queue
-{
- size_t *buffer;
- size_t capacity;
- size_t count;
- size_t front;
- size_t back;
- int flag;
- struct queue_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct queue_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct queue_iter
-{
- struct queue *target;
- size_t cursor;
- size_t index;
- _Bool start;
- _Bool end;
-};
-struct queue *q_new(size_t capacity, struct queue_fval *f_val);
-struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void q_clear(struct queue *_queue_);
-void q_free(struct queue *_queue_);
-void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool q_enqueue(struct queue *_queue_, size_t value);
-_Bool q_dequeue(struct queue *_queue_);
-size_t q_peek(struct queue *_queue_);
-_Bool q_contains(struct queue *_queue_, size_t value);
-_Bool q_empty(struct queue *_queue_);
-_Bool q_full(struct queue *_queue_);
-size_t q_count(struct queue *_queue_);
-size_t q_capacity(struct queue *_queue_);
-int q_flag(struct queue *_queue_);
-_Bool q_resize(struct queue *_queue_, size_t capacity);
-struct queue *q_copy_of(struct queue *_queue_);
-_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_);
-struct cmc_string q_to_string(struct queue *_queue_);
-_Bool q_print(struct queue *_queue_, FILE *fptr);
-struct queue_iter q_iter_start(struct queue *target);
-struct queue_iter q_iter_end(struct queue *target);
-_Bool q_iter_at_start(struct queue_iter *iter);
-_Bool q_iter_at_end(struct queue_iter *iter);
-_Bool q_iter_to_start(struct queue_iter *iter);
-_Bool q_iter_to_end(struct queue_iter *iter);
-_Bool q_iter_next(struct queue_iter *iter);
-_Bool q_iter_prev(struct queue_iter *iter);
-_Bool q_iter_advance(struct queue_iter *iter, size_t steps);
-_Bool q_iter_rewind(struct queue_iter *iter, size_t steps);
-_Bool q_iter_go_to(struct queue_iter *iter, size_t index);
-size_t q_iter_value(struct queue_iter *iter);
-size_t *q_iter_rvalue(struct queue_iter *iter);
-size_t q_iter_index(struct queue_iter *iter);
struct queue *q_new(size_t capacity, struct queue_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity < 1)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- struct queue *_queue_ = alloc->malloc(sizeof(struct queue));
- if (!_queue_)
- return ((void *)0);
- _queue_->buffer = alloc->calloc(capacity, sizeof(size_t));
- if (!_queue_->buffer)
- {
- alloc->free(_queue_);
- return ((void *)0);
- }
- _queue_->capacity = capacity;
- _queue_->count = 0;
- _queue_->front = 0;
- _queue_->back = 0;
- _queue_->flag = cmc_flags.OK;
- _queue_->f_val = f_val;
- _queue_->alloc = alloc;
- _queue_->callbacks = ((void *)0);
- return _queue_;
+ return q_new_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity < 1)
return ((void *)0);
if (!f_val)
@@ -117,10 +28,10 @@ struct queue *q_new_custom(size_t capacity, struct queue_fval *f_val,
_queue_->count = 0;
_queue_->front = 0;
_queue_->back = 0;
- _queue_->flag = cmc_flags.OK;
+ _queue_->flag = CMC_FLAG_OK;
_queue_->f_val = f_val;
_queue_->alloc = alloc;
- _queue_->callbacks = callbacks;
+ (_queue_)->callbacks = callbacks;
return _queue_;
}
void q_clear(struct queue *_queue_)
@@ -137,7 +48,7 @@ void q_clear(struct queue *_queue_)
_queue_->count = 0;
_queue_->front = 0;
_queue_->back = 0;
- _queue_->flag = cmc_flags.OK;
+ _queue_->flag = CMC_FLAG_OK;
}
void q_free(struct queue *_queue_)
{
@@ -152,15 +63,15 @@ void q_free(struct queue *_queue_)
_queue_->alloc->free(_queue_->buffer);
_queue_->alloc->free(_queue_);
}
-void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void q_customize(struct queue *_queue_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_queue_->alloc = &cmc_alloc_node_default;
else
_queue_->alloc = alloc;
- _queue_->callbacks = callbacks;
- _queue_->flag = cmc_flags.OK;
+ (_queue_)->callbacks = callbacks;
+ _queue_->flag = CMC_FLAG_OK;
}
_Bool q_enqueue(struct queue *_queue_, size_t value)
{
@@ -170,45 +81,46 @@ _Bool q_enqueue(struct queue *_queue_, size_t value)
return 0;
}
_queue_->buffer[_queue_->back] = value;
- _queue_->back =
- (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1;
+ _queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1;
_queue_->count++;
- _queue_->flag = cmc_flags.OK;
- if (_queue_->callbacks && _queue_->callbacks->create)
- _queue_->callbacks->create();
+ _queue_->flag = CMC_FLAG_OK;
+ if ((_queue_)->callbacks && (_queue_)->callbacks->create)
+ (_queue_)->callbacks->create();
+ ;
return 1;
}
_Bool q_dequeue(struct queue *_queue_)
{
if (q_empty(_queue_))
{
- _queue_->flag = cmc_flags.EMPTY;
+ _queue_->flag = CMC_FLAG_EMPTY;
return 0;
}
_queue_->buffer[_queue_->front] = (size_t){ 0 };
- _queue_->front =
- (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1;
+ _queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1;
_queue_->count--;
- _queue_->flag = cmc_flags.OK;
- if (_queue_->callbacks && _queue_->callbacks->delete)
- _queue_->callbacks->delete ();
+ _queue_->flag = CMC_FLAG_OK;
+ if ((_queue_)->callbacks && (_queue_)->callbacks->delete)
+ (_queue_)->callbacks->delete ();
+ ;
return 1;
}
size_t q_peek(struct queue *_queue_)
{
if (q_empty(_queue_))
{
- _queue_->flag = cmc_flags.EMPTY;
+ _queue_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _queue_->flag = cmc_flags.OK;
- if (_queue_->callbacks && _queue_->callbacks->read)
- _queue_->callbacks->read();
+ _queue_->flag = CMC_FLAG_OK;
+ if ((_queue_)->callbacks && (_queue_)->callbacks->read)
+ (_queue_)->callbacks->read();
+ ;
return _queue_->buffer[_queue_->front];
}
_Bool q_contains(struct queue *_queue_, size_t value)
{
- _queue_->flag = cmc_flags.OK;
+ _queue_->flag = CMC_FLAG_OK;
_Bool result = 0;
for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
{
@@ -219,8 +131,9 @@ _Bool q_contains(struct queue *_queue_, size_t value)
}
i = (i + 1) % _queue_->capacity;
}
- if (_queue_->callbacks && _queue_->callbacks->read)
- _queue_->callbacks->read();
+ if ((_queue_)->callbacks && (_queue_)->callbacks->read)
+ (_queue_)->callbacks->read();
+ ;
return result;
}
_Bool q_empty(struct queue *_queue_)
@@ -249,13 +162,13 @@ _Bool q_resize(struct queue *_queue_, size_t capacity)
goto success;
if (capacity < _queue_->count)
{
- _queue_->flag = cmc_flags.INVALID;
+ _queue_->flag = CMC_FLAG_INVALID;
return 0;
}
size_t *new_buffer = _queue_->alloc->malloc(sizeof(size_t) * capacity);
if (!new_buffer)
{
- _queue_->flag = cmc_flags.ALLOC;
+ _queue_->flag = CMC_FLAG_ALLOC;
return 0;
}
for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
@@ -269,20 +182,21 @@ _Bool q_resize(struct queue *_queue_, size_t capacity)
_queue_->front = 0;
_queue_->back = _queue_->count;
success:
- _queue_->flag = cmc_flags.OK;
- if (_queue_->callbacks && _queue_->callbacks->resize)
- _queue_->callbacks->resize();
+ _queue_->flag = CMC_FLAG_OK;
+ if ((_queue_)->callbacks && (_queue_)->callbacks->resize)
+ (_queue_)->callbacks->resize();
+ ;
return 1;
}
struct queue *q_copy_of(struct queue *_queue_)
{
- struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val,
- _queue_->alloc, _queue_->callbacks);
+ struct queue *result = q_new_custom(_queue_->capacity, _queue_->f_val, _queue_->alloc, ((void *)0));
if (!result)
{
- _queue_->flag = cmc_flags.ERROR;
+ _queue_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _queue_->callbacks;
if (_queue_->f_val->cpy)
{
for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
@@ -302,18 +216,17 @@ struct queue *q_copy_of(struct queue *_queue_)
result->count = _queue_->count;
result->front = 0;
result->back = _queue_->count;
- _queue_->flag = cmc_flags.OK;
+ _queue_->flag = CMC_FLAG_OK;
return result;
}
_Bool q_equals(struct queue *_queue1_, struct queue *_queue2_)
{
- _queue1_->flag = cmc_flags.OK;
- _queue2_->flag = cmc_flags.OK;
+ _queue1_->flag = CMC_FLAG_OK;
+ _queue2_->flag = CMC_FLAG_OK;
if (_queue1_->count != _queue2_->count)
return 0;
size_t i, j, k;
- for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count;
- k++)
+ for (i = _queue1_->front, j = _queue2_->front, k = 0; k < _queue1_->count; k++)
{
if (_queue1_->f_val->cmp(_queue1_->buffer[i], _queue2_->buffer[j]) != 0)
return 0;
@@ -322,26 +235,6 @@ _Bool q_equals(struct queue *_queue1_, struct queue *_queue2_)
}
return 1;
}
-struct cmc_string q_to_string(struct queue *_queue_)
-{
- struct cmc_string str;
- struct queue *q_ = _queue_;
- int n =
- snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, "queue", "size_t",
- q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back,
- q_->flag, q_->f_val, q_->alloc, q_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool q_print(struct queue *_queue_, FILE *fptr)
-{
- for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
- {
- if (!_queue_->f_val->str(fptr, _queue_->buffer[i]))
- return 0;
- i = (i + 1) % _queue_->capacity;
- }
- return 1;
-}
struct queue_iter q_iter_start(struct queue *target)
{
struct queue_iter iter;
@@ -432,8 +325,7 @@ _Bool q_iter_prev(struct queue_iter *iter)
return 0;
}
iter->end = q_empty(iter->target);
- iter->cursor =
- (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1;
+ iter->cursor = (iter->cursor == 0) ? iter->target->capacity - 1 : iter->cursor - 1;
iter->index--;
return 1;
}
@@ -497,5 +389,43 @@ size_t q_iter_index(struct queue_iter *iter)
{
return iter->index;
}
-
-#endif /* CMC_TEST_SRC_QUEUE */
+_Bool q_to_string(struct queue *_queue_, FILE *fptr)
+{
+ struct queue *q_ = _queue_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "front:%"
+ "I64u"
+ ", "
+ "back:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "queue", "size_t", q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back, q_->flag,
+ q_->f_val, q_->alloc, (q_)->callbacks);
+}
+_Bool q_print(struct queue *_queue_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ for (size_t i = _queue_->front, j = 0; j < _queue_->count; j++)
+ {
+ if (!_queue_->f_val->str(fptr, _queue_->buffer[i]))
+ return 0;
+ i = (i + 1) % _queue_->capacity;
+ if (j + 1 < _queue_->count)
+ fprintf(fptr, "%s", separator);
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
+}
diff --git a/tests/main/src/sortedlist.c b/tests/src/cmc/sortedlist.c
similarity index 61%
rename from tests/main/src/sortedlist.c
rename to tests/src/cmc/sortedlist.c
index efa0d92..d130322 100644
--- a/tests/main/src/sortedlist.c
+++ b/tests/src/cmc/sortedlist.c
@@ -1,111 +1,18 @@
-#ifndef CMC_TEST_SRC_SORTEDLIST
-#define CMC_TEST_SRC_SORTEDLIST
#include "cmc/sortedlist.h"
-struct sortedlist
-{
- size_t *buffer;
- size_t capacity;
- size_t count;
- _Bool is_sorted;
- int flag;
- struct sortedlist_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct sortedlist_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct sortedlist_iter
-{
- struct sortedlist *target;
- size_t cursor;
- _Bool start;
- _Bool end;
-};
-struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val);
-struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void sl_clear(struct sortedlist *_list_);
-void sl_free(struct sortedlist *_list_);
-void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool sl_insert(struct sortedlist *_list_, size_t value);
-_Bool sl_remove(struct sortedlist *_list_, size_t index);
-size_t sl_max(struct sortedlist *_list_);
-size_t sl_min(struct sortedlist *_list_);
-size_t sl_get(struct sortedlist *_list_, size_t index);
-size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start);
-_Bool sl_contains(struct sortedlist *_list_, size_t value);
-_Bool sl_empty(struct sortedlist *_list_);
-_Bool sl_full(struct sortedlist *_list_);
-size_t sl_count(struct sortedlist *_list_);
-size_t sl_capacity(struct sortedlist *_list_);
-int sl_flag(struct sortedlist *_list_);
-_Bool sl_resize(struct sortedlist *_list_, size_t capacity);
-void sl_sort(struct sortedlist *_list_);
-struct sortedlist *sl_copy_of(struct sortedlist *_list_);
-_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_);
-struct cmc_string sl_to_string(struct sortedlist *_list_);
-_Bool sl_print(struct sortedlist *_list_, FILE *fptr);
-struct sortedlist_iter sl_iter_start(struct sortedlist *target);
-struct sortedlist_iter sl_iter_end(struct sortedlist *target);
-_Bool sl_iter_at_start(struct sortedlist_iter *iter);
-_Bool sl_iter_at_end(struct sortedlist_iter *iter);
-_Bool sl_iter_to_start(struct sortedlist_iter *iter);
-_Bool sl_iter_to_end(struct sortedlist_iter *iter);
-_Bool sl_iter_next(struct sortedlist_iter *iter);
-_Bool sl_iter_prev(struct sortedlist_iter *iter);
-_Bool sl_iter_advance(struct sortedlist_iter *iter, size_t steps);
-_Bool sl_iter_rewind(struct sortedlist_iter *iter, size_t steps);
-_Bool sl_iter_go_to(struct sortedlist_iter *iter, size_t index);
-size_t sl_iter_value(struct sortedlist_iter *iter);
-size_t sl_iter_index(struct sortedlist_iter *iter);
-static size_t sl_impl_binary_search_first(struct sortedlist *_list_,
- size_t value);
-static size_t sl_impl_binary_search_last(struct sortedlist *_list_,
- size_t value);
-void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t),
- size_t low, size_t high);
-void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t),
- size_t low, size_t high);
+static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value);
+static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value);
+void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high);
+void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high);
struct sortedlist *sl_new(size_t capacity, struct sortedlist_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity < 1)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- struct sortedlist *_list_ = alloc->malloc(sizeof(struct sortedlist));
- if (!_list_)
- return ((void *)0);
- _list_->buffer = alloc->calloc(capacity, sizeof(size_t));
- if (!_list_->buffer)
- {
- alloc->free(_list_);
- return ((void *)0);
- }
- _list_->capacity = capacity;
- _list_->count = 0;
- _list_->is_sorted = 0;
- _list_->flag = cmc_flags.OK;
- _list_->f_val = f_val;
- _list_->alloc = alloc;
- _list_->callbacks = ((void *)0);
- return _list_;
+ return sl_new_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity < 1)
return ((void *)0);
if (!alloc)
@@ -122,10 +29,10 @@ struct sortedlist *sl_new_custom(size_t capacity, struct sortedlist_fval *f_val,
_list_->capacity = capacity;
_list_->count = 0;
_list_->is_sorted = 0;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
_list_->f_val = f_val;
_list_->alloc = alloc;
- _list_->callbacks = callbacks;
+ (_list_)->callbacks = callbacks;
return _list_;
}
void sl_clear(struct sortedlist *_list_)
@@ -137,7 +44,7 @@ void sl_clear(struct sortedlist *_list_)
}
memset(_list_->buffer, 0, sizeof(size_t) * _list_->capacity);
_list_->count = 0;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
}
void sl_free(struct sortedlist *_list_)
{
@@ -149,15 +56,15 @@ void sl_free(struct sortedlist *_list_)
_list_->alloc->free(_list_->buffer);
_list_->alloc->free(_list_);
}
-void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void sl_customize(struct sortedlist *_list_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_list_->alloc = &cmc_alloc_node_default;
else
_list_->alloc = alloc;
- _list_->callbacks = callbacks;
- _list_->flag = cmc_flags.OK;
+ (_list_)->callbacks = callbacks;
+ _list_->flag = CMC_FLAG_OK;
}
_Bool sl_insert(struct sortedlist *_list_, size_t value)
{
@@ -168,81 +75,86 @@ _Bool sl_insert(struct sortedlist *_list_, size_t value)
}
_list_->buffer[_list_->count++] = value;
_list_->is_sorted = 0;
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->create)
- _list_->callbacks->create();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->create)
+ (_list_)->callbacks->create();
+ ;
return 1;
}
_Bool sl_remove(struct sortedlist *_list_, size_t index)
{
if (sl_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return 0;
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return 0;
}
- memmove(_list_->buffer + index, _list_->buffer + index + 1,
- (_list_->count - index) * sizeof(size_t));
+ memmove(_list_->buffer + index, _list_->buffer + index + 1, (_list_->count - index) * sizeof(size_t));
_list_->buffer[--_list_->count] = (size_t){ 0 };
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->delete)
- _list_->callbacks->delete ();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->delete)
+ (_list_)->callbacks->delete ();
+ ;
return 1;
}
size_t sl_max(struct sortedlist *_list_)
{
if (sl_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
sl_sort(_list_);
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->buffer[_list_->count - 1];
}
size_t sl_min(struct sortedlist *_list_)
{
if (sl_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
sl_sort(_list_);
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->buffer[0];
}
size_t sl_get(struct sortedlist *_list_, size_t index)
{
if (sl_empty(_list_))
{
- _list_->flag = cmc_flags.EMPTY;
+ _list_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
if (index >= _list_->count)
{
- _list_->flag = cmc_flags.RANGE;
+ _list_->flag = CMC_FLAG_RANGE;
return (size_t){ 0 };
}
sl_sort(_list_);
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return _list_->buffer[index];
}
size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
sl_sort(_list_);
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
if (from_start)
{
return sl_impl_binary_search_first(_list_, value);
@@ -251,12 +163,13 @@ size_t sl_index_of(struct sortedlist *_list_, size_t value, _Bool from_start)
}
_Bool sl_contains(struct sortedlist *_list_, size_t value)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
if (sl_empty(_list_))
return 0;
sl_sort(_list_);
- if (_list_->callbacks && _list_->callbacks->read)
- _list_->callbacks->read();
+ if ((_list_)->callbacks && (_list_)->callbacks->read)
+ (_list_)->callbacks->read();
+ ;
return sl_impl_binary_search_first(_list_, value) < _list_->count;
}
_Bool sl_empty(struct sortedlist *_list_)
@@ -285,43 +198,42 @@ _Bool sl_resize(struct sortedlist *_list_, size_t capacity)
goto success;
if (capacity < _list_->count)
{
- _list_->flag = cmc_flags.INVALID;
+ _list_->flag = CMC_FLAG_INVALID;
return 0;
}
- size_t *new_buffer =
- _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity);
+ size_t *new_buffer = _list_->alloc->realloc(_list_->buffer, sizeof(size_t) * capacity);
if (!new_buffer)
{
- _list_->flag = cmc_flags.ALLOC;
+ _list_->flag = CMC_FLAG_ALLOC;
return 0;
}
_list_->buffer = new_buffer;
_list_->capacity = capacity;
success:
- _list_->flag = cmc_flags.OK;
- if (_list_->callbacks && _list_->callbacks->resize)
- _list_->callbacks->resize();
+ _list_->flag = CMC_FLAG_OK;
+ if ((_list_)->callbacks && (_list_)->callbacks->resize)
+ (_list_)->callbacks->resize();
+ ;
return 1;
}
void sl_sort(struct sortedlist *_list_)
{
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
if (!_list_->is_sorted && _list_->count > 1)
{
- sl_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0,
- _list_->count - 1);
+ sl_impl_sort_quicksort(_list_->buffer, _list_->f_val->cmp, 0, _list_->count - 1);
_list_->is_sorted = 1;
}
}
struct sortedlist *sl_copy_of(struct sortedlist *_list_)
{
- struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val,
- _list_->alloc, _list_->callbacks);
+ struct sortedlist *result = sl_new_custom(_list_->capacity, _list_->f_val, _list_->alloc, ((void *)0));
if (!result)
{
- _list_->flag = cmc_flags.ERROR;
+ _list_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _list_->callbacks;
if (_list_->f_val->cpy)
{
for (size_t i = 0; i < _list_->count; i++)
@@ -330,7 +242,7 @@ struct sortedlist *sl_copy_of(struct sortedlist *_list_)
else
memcpy(result->buffer, _list_->buffer, sizeof(size_t) * _list_->count);
result->count = _list_->count;
- _list_->flag = cmc_flags.OK;
+ _list_->flag = CMC_FLAG_OK;
return result;
}
_Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_)
@@ -346,25 +258,94 @@ _Bool sl_equals(struct sortedlist *_list1_, struct sortedlist *_list2_)
}
return 1;
}
-struct cmc_string sl_to_string(struct sortedlist *_list_)
+static size_t sl_impl_binary_search_first(struct sortedlist *_list_, size_t value)
{
- struct cmc_string str;
- struct sortedlist *l_ = _list_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_sortedlist,
- "sortedlist", "size_t", l_, l_->buffer, l_->capacity,
- l_->count, l_->is_sorted ? "true" : "false", l_->flag,
- l_->f_val, l_->alloc, l_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool sl_print(struct sortedlist *_list_, FILE *fptr)
-{
- sl_sort(_list_);
- for (size_t i = 0; i < _list_->count; i++)
+ if (sl_empty(_list_))
+ return 1;
+ size_t L = 0;
+ size_t R = _list_->count;
+ while (L < R)
{
- if (!_list_->f_val->str(fptr, _list_->buffer[i]))
- return 0;
+ size_t M = L + (R - L) / 2;
+ if (_list_->f_val->cmp(_list_->buffer[M], value) < 0)
+ L = M + 1;
+ else
+ R = M;
+ }
+ if (_list_->f_val->cmp(_list_->buffer[L], value) == 0)
+ return L;
+ return _list_->count;
+}
+static size_t sl_impl_binary_search_last(struct sortedlist *_list_, size_t value)
+{
+ if (sl_empty(_list_))
+ return 1;
+ size_t L = 0;
+ size_t R = _list_->count;
+ while (L < R)
+ {
+ size_t M = L + (R - L) / 2;
+ if (_list_->f_val->cmp(_list_->buffer[M], value) > 0)
+ R = M;
+ else
+ L = M + 1;
+ }
+ if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0)
+ return L - 1;
+ return _list_->count;
+}
+void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high)
+{
+ while (low < high)
+ {
+ if (high - low < 10)
+ {
+ sl_impl_sort_insertion(array, cmp, low, high);
+ break;
+ }
+ else
+ {
+ size_t pivot = array[high];
+ size_t pindex = low;
+ for (size_t i = low; i < high; i++)
+ {
+ if (cmp(array[i], pivot) <= 0)
+ {
+ size_t _tmp_ = array[i];
+ array[i] = array[pindex];
+ array[pindex] = _tmp_;
+ pindex++;
+ }
+ }
+ size_t _tmp_ = array[pindex];
+ array[pindex] = array[high];
+ array[high] = _tmp_;
+ if (pindex - low < high - pindex)
+ {
+ sl_impl_sort_quicksort(array, cmp, low, pindex - 1);
+ low = pindex + 1;
+ }
+ else
+ {
+ sl_impl_sort_quicksort(array, cmp, pindex + 1, high);
+ high = pindex - 1;
+ }
+ }
+ }
+}
+void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t), size_t low, size_t high)
+{
+ for (size_t i = low + 1; i <= high; i++)
+ {
+ size_t _tmp_ = array[i];
+ size_t j = i;
+ while (j > low && cmp(array[j - 1], _tmp_) > 0)
+ {
+ array[j] = array[j - 1];
+ j--;
+ }
+ array[j] = _tmp_;
}
- return 1;
}
struct sortedlist_iter sl_iter_start(struct sortedlist *target)
{
@@ -494,98 +475,38 @@ size_t sl_iter_index(struct sortedlist_iter *iter)
{
return iter->cursor;
}
-static size_t sl_impl_binary_search_first(struct sortedlist *_list_,
- size_t value)
+_Bool sl_to_string(struct sortedlist *_list_, FILE *fptr)
{
- if (sl_empty(_list_))
- return 1;
- size_t L = 0;
- size_t R = _list_->count;
- while (L < R)
- {
- size_t M = L + (R - L) / 2;
- if (_list_->f_val->cmp(_list_->buffer[M], value) < 0)
- L = M + 1;
- else
- R = M;
- }
- if (_list_->f_val->cmp(_list_->buffer[L], value) == 0)
- return L;
- return _list_->count;
+ struct sortedlist *l_ = _list_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "is_sorted:%s, "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "sortedlist", "size_t", l_, l_->buffer, l_->capacity, l_->count,
+ l_->is_sorted ? "true" : "false", l_->flag, l_->f_val, l_->alloc, (l_)->callbacks);
}
-static size_t sl_impl_binary_search_last(struct sortedlist *_list_,
- size_t value)
+_Bool sl_print(struct sortedlist *_list_, FILE *fptr, const char *start, const char *separator, const char *end)
{
- if (sl_empty(_list_))
- return 1;
- size_t L = 0;
- size_t R = _list_->count;
- while (L < R)
+ sl_sort(_list_);
+ fprintf(fptr, "%s", start);
+ for (size_t i = 0; i < _list_->count; i++)
{
- size_t M = L + (R - L) / 2;
- if (_list_->f_val->cmp(_list_->buffer[M], value) > 0)
- R = M;
- else
- L = M + 1;
+ if (!_list_->f_val->str(fptr, _list_->buffer[i]))
+ return 0;
+ if (i + 1 < _list_->count)
+ fprintf(fptr, "%s", separator);
}
- if (L > 0 && _list_->f_val->cmp(_list_->buffer[L - 1], value) == 0)
- return L - 1;
- return _list_->count;
+ fprintf(fptr, "%s", end);
+ return 1;
}
-void sl_impl_sort_quicksort(size_t *array, int (*cmp)(size_t, size_t),
- size_t low, size_t high)
-{
- while (low < high)
- {
- if (high - low < 10)
- {
- sl_impl_sort_insertion(array, cmp, low, high);
- break;
- }
- else
- {
- size_t pivot = array[high];
- size_t pindex = low;
- for (size_t i = low; i < high; i++)
- {
- if (cmp(array[i], pivot) <= 0)
- {
- size_t _tmp_ = array[i];
- array[i] = array[pindex];
- array[pindex] = _tmp_;
- pindex++;
- }
- }
- size_t _tmp_ = array[pindex];
- array[pindex] = array[high];
- array[high] = _tmp_;
- if (pindex - low < high - pindex)
- {
- sl_impl_sort_quicksort(array, cmp, low, pindex - 1);
- low = pindex + 1;
- }
- else
- {
- sl_impl_sort_quicksort(array, cmp, pindex + 1, high);
- high = pindex - 1;
- }
- }
- }
-}
-void sl_impl_sort_insertion(size_t *array, int (*cmp)(size_t, size_t),
- size_t low, size_t high)
-{
- for (size_t i = low + 1; i <= high; i++)
- {
- size_t _tmp_ = array[i];
- size_t j = i;
- while (j > low && cmp(array[j - 1], _tmp_) > 0)
- {
- array[j] = array[j - 1];
- j--;
- }
- array[j] = _tmp_;
- }
-}
-
-#endif /* CMC_TEST_SRC_SORTEDLIST */
diff --git a/tests/main/src/stack.c b/tests/src/cmc/stack.c
similarity index 57%
rename from tests/main/src/stack.c
rename to tests/src/cmc/stack.c
index a0be8dd..46cf798 100644
--- a/tests/main/src/stack.c
+++ b/tests/src/cmc/stack.c
@@ -1,98 +1,14 @@
-#ifndef CMC_TEST_SRC_STACK
-#define CMC_TEST_SRC_STACK
#include "cmc/stack.h"
-struct stack
-{
- size_t *buffer;
- size_t capacity;
- size_t count;
- int flag;
- struct stack_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct stack_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct stack_iter
-{
- struct stack *target;
- size_t cursor;
- _Bool start;
- _Bool end;
-};
-struct stack *s_new(size_t capacity, struct stack_fval *f_val);
-struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void s_clear(struct stack *_stack_);
-void s_free(struct stack *_stack_);
-void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool s_push(struct stack *_stack_, size_t value);
-_Bool s_pop(struct stack *_stack_);
-size_t s_top(struct stack *_stack_);
-_Bool s_contains(struct stack *_stack_, size_t value);
-_Bool s_empty(struct stack *_stack_);
-_Bool s_full(struct stack *_stack_);
-size_t s_count(struct stack *_stack_);
-size_t s_capacity(struct stack *_stack_);
-int s_flag(struct stack *_stack_);
-_Bool s_resize(struct stack *_stack_, size_t capacity);
-struct stack *s_copy_of(struct stack *_stack_);
-_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_);
-struct cmc_string s_to_string(struct stack *_stack_);
-_Bool s_print(struct stack *_stack_, FILE *fptr);
-struct stack_iter s_iter_start(struct stack *target);
-struct stack_iter s_iter_end(struct stack *target);
-_Bool s_iter_at_start(struct stack_iter *iter);
-_Bool s_iter_at_end(struct stack_iter *iter);
-_Bool s_iter_to_start(struct stack_iter *iter);
-_Bool s_iter_to_end(struct stack_iter *iter);
-_Bool s_iter_next(struct stack_iter *iter);
-_Bool s_iter_prev(struct stack_iter *iter);
-_Bool s_iter_advance(struct stack_iter *iter, size_t steps);
-_Bool s_iter_rewind(struct stack_iter *iter, size_t steps);
-_Bool s_iter_go_to(struct stack_iter *iter, size_t index);
-size_t s_iter_value(struct stack_iter *iter);
-size_t *s_iter_rvalue(struct stack_iter *iter);
-size_t s_iter_index(struct stack_iter *iter);
struct stack *s_new(size_t capacity, struct stack_fval *f_val)
{
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- if (capacity < 1)
- return ((void *)0);
- if (!f_val)
- return ((void *)0);
- struct stack *_stack_ = alloc->malloc(sizeof(struct stack));
- if (!_stack_)
- return ((void *)0);
- _stack_->buffer = alloc->calloc(capacity, sizeof(size_t));
- if (!_stack_->buffer)
- {
- alloc->free(_stack_);
- return ((void *)0);
- }
- _stack_->capacity = capacity;
- _stack_->count = 0;
- _stack_->flag = cmc_flags.OK;
- _stack_->f_val = f_val;
- _stack_->alloc = alloc;
- _stack_->callbacks = ((void *)0);
- return _stack_;
+ return s_new_custom(capacity, f_val, ((void *)0), ((void *)0));
}
-struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (capacity < 1)
return ((void *)0);
if (!f_val)
@@ -110,10 +26,10 @@ struct stack *s_new_custom(size_t capacity, struct stack_fval *f_val,
}
_stack_->capacity = capacity;
_stack_->count = 0;
- _stack_->flag = cmc_flags.OK;
+ _stack_->flag = CMC_FLAG_OK;
_stack_->f_val = f_val;
_stack_->alloc = alloc;
- _stack_->callbacks = callbacks;
+ (_stack_)->callbacks = callbacks;
return _stack_;
}
void s_clear(struct stack *_stack_)
@@ -125,7 +41,7 @@ void s_clear(struct stack *_stack_)
}
memset(_stack_->buffer, 0, sizeof(size_t) * _stack_->capacity);
_stack_->count = 0;
- _stack_->flag = cmc_flags.OK;
+ _stack_->flag = CMC_FLAG_OK;
}
void s_free(struct stack *_stack_)
{
@@ -137,15 +53,15 @@ void s_free(struct stack *_stack_)
_stack_->alloc->free(_stack_->buffer);
_stack_->alloc->free(_stack_);
}
-void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void s_customize(struct stack *_stack_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_stack_->alloc = &cmc_alloc_node_default;
else
_stack_->alloc = alloc;
- _stack_->callbacks = callbacks;
- _stack_->flag = cmc_flags.OK;
+ (_stack_)->callbacks = callbacks;
+ _stack_->flag = CMC_FLAG_OK;
}
_Bool s_push(struct stack *_stack_, size_t value)
{
@@ -155,39 +71,42 @@ _Bool s_push(struct stack *_stack_, size_t value)
return 0;
}
_stack_->buffer[_stack_->count++] = value;
- _stack_->flag = cmc_flags.OK;
- if (_stack_->callbacks && _stack_->callbacks->create)
- _stack_->callbacks->create();
+ _stack_->flag = CMC_FLAG_OK;
+ if ((_stack_)->callbacks && (_stack_)->callbacks->create)
+ (_stack_)->callbacks->create();
+ ;
return 1;
}
_Bool s_pop(struct stack *_stack_)
{
if (s_empty(_stack_))
{
- _stack_->flag = cmc_flags.EMPTY;
+ _stack_->flag = CMC_FLAG_EMPTY;
return 0;
}
_stack_->buffer[--_stack_->count] = (size_t){ 0 };
- _stack_->flag = cmc_flags.OK;
- if (_stack_->callbacks && _stack_->callbacks->delete)
- _stack_->callbacks->delete ();
+ _stack_->flag = CMC_FLAG_OK;
+ if ((_stack_)->callbacks && (_stack_)->callbacks->delete)
+ (_stack_)->callbacks->delete ();
+ ;
return 1;
}
size_t s_top(struct stack *_stack_)
{
if (s_empty(_stack_))
{
- _stack_->flag = cmc_flags.EMPTY;
+ _stack_->flag = CMC_FLAG_EMPTY;
return (size_t){ 0 };
}
- _stack_->flag = cmc_flags.OK;
- if (_stack_->callbacks && _stack_->callbacks->read)
- _stack_->callbacks->read();
+ _stack_->flag = CMC_FLAG_OK;
+ if ((_stack_)->callbacks && (_stack_)->callbacks->read)
+ (_stack_)->callbacks->read();
+ ;
return _stack_->buffer[_stack_->count - 1];
}
_Bool s_contains(struct stack *_stack_, size_t value)
{
- _stack_->flag = cmc_flags.OK;
+ _stack_->flag = CMC_FLAG_OK;
_Bool result = 0;
for (size_t i = 0; i < _stack_->count; i++)
{
@@ -197,8 +116,9 @@ _Bool s_contains(struct stack *_stack_, size_t value)
break;
}
}
- if (_stack_->callbacks && _stack_->callbacks->read)
- _stack_->callbacks->read();
+ if ((_stack_)->callbacks && (_stack_)->callbacks->read)
+ (_stack_)->callbacks->read();
+ ;
return result;
}
_Bool s_empty(struct stack *_stack_)
@@ -227,49 +147,48 @@ _Bool s_resize(struct stack *_stack_, size_t capacity)
goto success;
if (capacity < _stack_->count)
{
- _stack_->flag = cmc_flags.INVALID;
+ _stack_->flag = CMC_FLAG_INVALID;
return 0;
}
- size_t *new_buffer =
- _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity);
+ size_t *new_buffer = _stack_->alloc->realloc(_stack_->buffer, sizeof(size_t) * capacity);
if (!new_buffer)
{
- _stack_->flag = cmc_flags.ALLOC;
+ _stack_->flag = CMC_FLAG_ALLOC;
return 0;
}
_stack_->buffer = new_buffer;
_stack_->capacity = capacity;
success:
- _stack_->flag = cmc_flags.OK;
- if (_stack_->callbacks && _stack_->callbacks->resize)
- _stack_->callbacks->resize();
+ _stack_->flag = CMC_FLAG_OK;
+ if ((_stack_)->callbacks && (_stack_)->callbacks->resize)
+ (_stack_)->callbacks->resize();
+ ;
return 1;
}
struct stack *s_copy_of(struct stack *_stack_)
{
- struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val,
- _stack_->alloc, _stack_->callbacks);
+ struct stack *result = s_new_custom(_stack_->capacity, _stack_->f_val, _stack_->alloc, ((void *)0));
if (!result)
{
- _stack_->flag = cmc_flags.ERROR;
+ _stack_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _stack_->callbacks;
if (_stack_->f_val->cpy)
{
for (size_t i = 0; i < _stack_->count; i++)
result->buffer[i] = _stack_->f_val->cpy(_stack_->buffer[i]);
}
else
- memcpy(result->buffer, _stack_->buffer,
- sizeof(size_t) * _stack_->count);
+ memcpy(result->buffer, _stack_->buffer, sizeof(size_t) * _stack_->count);
result->count = _stack_->count;
- _stack_->flag = cmc_flags.OK;
+ _stack_->flag = CMC_FLAG_OK;
return result;
}
_Bool s_equals(struct stack *_stack1_, struct stack *_stack2_)
{
- _stack1_->flag = cmc_flags.OK;
- _stack2_->flag = cmc_flags.OK;
+ _stack1_->flag = CMC_FLAG_OK;
+ _stack2_->flag = CMC_FLAG_OK;
if (_stack1_->count != _stack2_->count)
return 0;
for (size_t i = 0; i < _stack1_->count; i++)
@@ -279,24 +198,6 @@ _Bool s_equals(struct stack *_stack1_, struct stack *_stack2_)
}
return 1;
}
-struct cmc_string s_to_string(struct stack *_stack_)
-{
- struct cmc_string str;
- struct stack *s_ = _stack_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, "stack",
- "size_t", s_, s_->buffer, s_->capacity, s_->count,
- s_->flag, s_->f_val, s_->alloc, s_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
-}
-_Bool s_print(struct stack *_stack_, FILE *fptr)
-{
- for (size_t i = 0; i < _stack_->count; i++)
- {
- if (!_stack_->f_val->str(fptr, _stack_->buffer[i]))
- return 0;
- }
- return 1;
-}
struct stack_iter s_iter_start(struct stack *target)
{
struct stack_iter iter;
@@ -431,5 +332,36 @@ size_t s_iter_index(struct stack_iter *iter)
return 0;
return iter->target->count - 1 - iter->cursor;
}
-
-#endif /* CMC_TEST_SRC_STACK */
+_Bool s_to_string(struct stack *_stack_, FILE *fptr)
+{
+ struct stack *s_ = _stack_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "buffer:%p, "
+ "capacity:%"
+ "I64u"
+ ", "
+ "count:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "stack", "size_t", s_, s_->buffer, s_->capacity, s_->count, s_->flag, s_->f_val, s_->alloc,
+ (s_)->callbacks);
+}
+_Bool s_print(struct stack *_stack_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ for (size_t i = _stack_->count; i > 0; i--)
+ {
+ if (!_stack_->f_val->str(fptr, _stack_->buffer[i - 1]))
+ return 0;
+ if (i - 1 != 0)
+ fprintf(fptr, "%s", separator);
+ }
+ fprintf(fptr, "%s", end);
+ return 1;
+}
diff --git a/tests/main/src/treemap.c b/tests/src/cmc/treemap.c
similarity index 73%
rename from tests/main/src/treemap.c
rename to tests/src/cmc/treemap.c
index f30a722..6c495e7 100644
--- a/tests/main/src/treemap.c
+++ b/tests/src/cmc/treemap.c
@@ -1,97 +1,7 @@
-#ifndef CMC_TEST_SRC_TREEMAP
-#define CMC_TEST_SRC_TREEMAP
#include "cmc/treemap.h"
-struct treemap
-{
- struct treemap_node *root;
- size_t count;
- int flag;
- struct treemap_fkey *f_key;
- struct treemap_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct treemap_node
-{
- size_t key;
- size_t value;
- unsigned char height;
- struct treemap_node *right;
- struct treemap_node *left;
- struct treemap_node *parent;
-};
-struct treemap_fkey
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct treemap_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct treemap_iter
-{
- struct treemap *target;
- struct treemap_node *cursor;
- struct treemap_node *first;
- struct treemap_node *last;
- size_t index;
- _Bool start;
- _Bool end;
-};
-struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val);
-struct treemap *tm_new_custom(struct treemap_fkey *f_key,
- struct treemap_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void tm_clear(struct treemap *_map_);
-void tm_free(struct treemap *_map_);
-void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool tm_insert(struct treemap *_map_, size_t key, size_t value);
-_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value,
- size_t *old_value);
-_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value);
-_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value);
-_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value);
-size_t tm_get(struct treemap *_map_, size_t key);
-size_t *tm_get_ref(struct treemap *_map_, size_t key);
-_Bool tm_contains(struct treemap *_map_, size_t key);
-_Bool tm_empty(struct treemap *_map_);
-size_t tm_count(struct treemap *_map_);
-int tm_flag(struct treemap *_map_);
-struct treemap *tm_copy_of(struct treemap *_map_);
-_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_);
-struct cmc_string tm_to_string(struct treemap *_map_);
-_Bool tm_print(struct treemap *_map_, FILE *fptr);
-struct treemap_iter tm_iter_start(struct treemap *target);
-struct treemap_iter tm_iter_end(struct treemap *target);
-_Bool tm_iter_at_start(struct treemap_iter *iter);
-_Bool tm_iter_at_end(struct treemap_iter *iter);
-_Bool tm_iter_to_start(struct treemap_iter *iter);
-_Bool tm_iter_to_end(struct treemap_iter *iter);
-_Bool tm_iter_next(struct treemap_iter *iter);
-_Bool tm_iter_prev(struct treemap_iter *iter);
-_Bool tm_iter_advance(struct treemap_iter *iter, size_t steps);
-_Bool tm_iter_rewind(struct treemap_iter *iter, size_t steps);
-_Bool tm_iter_go_to(struct treemap_iter *iter, size_t index);
-size_t tm_iter_key(struct treemap_iter *iter);
-size_t tm_iter_value(struct treemap_iter *iter);
-size_t *tm_iter_rvalue(struct treemap_iter *iter);
-size_t tm_iter_index(struct treemap_iter *iter);
-static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key,
- size_t value);
+static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value);
static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key);
static unsigned char tm_impl_h(struct treemap_node *node);
static unsigned char tm_impl_hupdate(struct treemap_node *node);
@@ -100,26 +10,12 @@ static void tm_impl_rotate_left(struct treemap_node **Z);
static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node);
struct treemap *tm_new(struct treemap_fkey *f_key, struct treemap_fval *f_val)
{
- if (!f_key || !f_val)
- return ((void *)0);
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- struct treemap *_map_ = alloc->malloc(sizeof(struct treemap));
- if (!_map_)
- return ((void *)0);
- _map_->count = 0;
- _map_->root = ((void *)0);
- _map_->flag = cmc_flags.OK;
- _map_->f_key = f_key;
- _map_->f_val = f_val;
- _map_->alloc = alloc;
- _map_->callbacks = ((void *)0);
- return _map_;
+ return tm_new_custom(f_key, f_val, ((void *)0), ((void *)0));
}
-struct treemap *tm_new_custom(struct treemap_fkey *f_key,
- struct treemap_fval *f_val,
- struct cmc_alloc_node *alloc,
+struct treemap *tm_new_custom(struct treemap_fkey *f_key, struct treemap_fval *f_val, struct cmc_alloc_node *alloc,
struct cmc_callbacks *callbacks)
{
+ ;
if (!f_key || !f_val)
return ((void *)0);
if (!alloc)
@@ -129,11 +25,11 @@ struct treemap *tm_new_custom(struct treemap_fkey *f_key,
return ((void *)0);
_map_->count = 0;
_map_->root = ((void *)0);
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
_map_->f_key = f_key;
_map_->f_val = f_val;
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
+ (_map_)->callbacks = callbacks;
return _map_;
}
void tm_clear(struct treemap *_map_)
@@ -191,22 +87,22 @@ void tm_clear(struct treemap *_map_)
}
_map_->count = 0;
_map_->root = ((void *)0);
- _map_->flag = cmc_flags.OK;
+ _map_->flag = CMC_FLAG_OK;
}
void tm_free(struct treemap *_map_)
{
tm_clear(_map_);
_map_->alloc->free(_map_);
}
-void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void tm_customize(struct treemap *_map_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_map_->alloc = &cmc_alloc_node_default;
else
_map_->alloc = alloc;
- _map_->callbacks = callbacks;
- _map_->flag = cmc_flags.OK;
+ (_map_)->callbacks = callbacks;
+ _map_->flag = CMC_FLAG_OK;
}
_Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
{
@@ -215,7 +111,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
_map_->root = tm_impl_new_node(_map_, key, value);
if (!_map_->root)
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
}
@@ -232,7 +128,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
scan = scan->right;
else
{
- _map_->flag = cmc_flags.DUPLICATE;
+ _map_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
}
@@ -242,7 +138,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
parent->left = tm_impl_new_node(_map_, key, value);
if (!parent->left)
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
parent->left->parent = parent;
@@ -253,7 +149,7 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
parent->right = tm_impl_new_node(_map_, key, value);
if (!parent->right)
{
- _map_->flag = cmc_flags.ALLOC;
+ _map_->flag = CMC_FLAG_ALLOC;
return 0;
}
parent->right->parent = parent;
@@ -262,39 +158,40 @@ _Bool tm_insert(struct treemap *_map_, size_t key, size_t value)
tm_impl_rebalance(_map_, node);
}
_map_->count++;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->create)
- _map_->callbacks->create();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->create)
+ (_map_)->callbacks->create();
+ ;
return 1;
}
-_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value,
- size_t *old_value)
+_Bool tm_update(struct treemap *_map_, size_t key, size_t new_value, size_t *old_value)
{
struct treemap_node *node = tm_impl_get_node(_map_, key);
if (!node)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (old_value)
*old_value = node->value;
node->value = new_value;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->update)
- _map_->callbacks->update();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->update)
+ (_map_)->callbacks->update();
+ ;
return 1;
}
_Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value)
{
if (tm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct treemap_node *node = tm_impl_get_node(_map_, key);
if (!node)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
if (out_value)
@@ -391,16 +288,17 @@ _Bool tm_remove(struct treemap *_map_, size_t key, size_t *out_value)
if (_map_->count == 0)
_map_->root = ((void *)0);
_map_->count--;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->delete)
- _map_->callbacks->delete ();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->delete)
+ (_map_)->callbacks->delete ();
+ ;
return 1;
}
_Bool tm_max(struct treemap *_map_, size_t *key, size_t *value)
{
if (tm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct treemap_node *scan = _map_->root;
@@ -410,16 +308,17 @@ _Bool tm_max(struct treemap *_map_, size_t *key, size_t *value)
*key = scan->key;
if (value)
*value = scan->value;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return 1;
}
_Bool tm_min(struct treemap *_map_, size_t *key, size_t *value)
{
if (tm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
+ _map_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct treemap_node *scan = _map_->root;
@@ -429,52 +328,56 @@ _Bool tm_min(struct treemap *_map_, size_t *key, size_t *value)
*key = scan->key;
if (value)
*value = scan->value;
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return 1;
}
size_t tm_get(struct treemap *_map_, size_t key)
{
if (tm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
- return 0;
+ _map_->flag = CMC_FLAG_EMPTY;
+ return (size_t){ 0 };
}
struct treemap_node *node = tm_impl_get_node(_map_, key);
if (!node)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return (size_t){ 0 };
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return node->value;
}
size_t *tm_get_ref(struct treemap *_map_, size_t key)
{
if (tm_empty(_map_))
{
- _map_->flag = cmc_flags.EMPTY;
- return 0;
+ _map_->flag = CMC_FLAG_EMPTY;
+ return ((void *)0);
}
struct treemap_node *node = tm_impl_get_node(_map_, key);
if (!node)
{
- _map_->flag = cmc_flags.NOT_FOUND;
+ _map_->flag = CMC_FLAG_NOT_FOUND;
return ((void *)0);
}
- _map_->flag = cmc_flags.OK;
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ _map_->flag = CMC_FLAG_OK;
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return &(node->value);
}
_Bool tm_contains(struct treemap *_map_, size_t key)
{
_Bool result = tm_impl_get_node(_map_, key) != ((void *)0);
- if (_map_->callbacks && _map_->callbacks->read)
- _map_->callbacks->read();
+ if ((_map_)->callbacks && (_map_)->callbacks->read)
+ (_map_)->callbacks->read();
+ ;
return result;
}
_Bool tm_empty(struct treemap *_map_)
@@ -491,11 +394,10 @@ int tm_flag(struct treemap *_map_)
}
struct treemap *tm_copy_of(struct treemap *_map_)
{
- struct treemap *result =
- tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0));
+ struct treemap *result = tm_new_custom(_map_->f_key, _map_->f_val, _map_->alloc, ((void *)0));
if (!result)
{
- _map_->flag = cmc_flags.ERROR;
+ _map_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
struct treemap_iter iter = tm_iter_start(_map_);
@@ -509,21 +411,20 @@ struct treemap *tm_copy_of(struct treemap *_map_)
value = _map_->f_val->cpy(value);
tm_insert(result, key, value);
}
- result->callbacks = _map_->callbacks;
- _map_->flag = cmc_flags.OK;
+ (result)->callbacks = _map_->callbacks;
+ _map_->flag = CMC_FLAG_OK;
return result;
}
_Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_)
{
- _map1_->flag = cmc_flags.OK;
- _map2_->flag = cmc_flags.OK;
+ _map1_->flag = CMC_FLAG_OK;
+ _map2_->flag = CMC_FLAG_OK;
if (_map1_->count != _map2_->count)
return 0;
struct treemap_iter iter = tm_iter_start(_map1_);
for (; !tm_iter_at_end(&iter); tm_iter_next(&iter))
{
- struct treemap_node *node =
- tm_impl_get_node(_map2_, tm_iter_key(&iter));
+ struct treemap_node *node = tm_impl_get_node(_map2_, tm_iter_key(&iter));
if (node == ((void *)0))
return 0;
if (_map1_->f_val->cmp(node->value, tm_iter_value(&iter)) != 0)
@@ -531,47 +432,121 @@ _Bool tm_equals(struct treemap *_map1_, struct treemap *_map2_)
}
return 1;
}
-struct cmc_string tm_to_string(struct treemap *_map_)
+static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key, size_t value)
{
- struct cmc_string str;
- struct treemap *m_ = _map_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treemap, "treemap",
- "size_t", "size_t", m_, m_->root, m_->count, m_->flag,
- m_->f_key, m_->f_val, m_->alloc, m_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
+ struct treemap_node *node = _map_->alloc->malloc(sizeof(struct treemap_node));
+ if (!node)
+ return ((void *)0);
+ node->key = key;
+ node->value = value;
+ node->right = ((void *)0);
+ node->left = ((void *)0);
+ node->parent = ((void *)0);
+ node->height = 0;
+ return node;
}
-_Bool tm_print(struct treemap *_map_, FILE *fptr)
+static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key)
{
- struct treemap_node *root = _map_->root;
- _Bool left_done = 0;
- while (root)
+ struct treemap_node *scan = _map_->root;
+ while (scan != ((void *)0))
{
- if (!left_done)
- {
- while (root->left)
- root = root->left;
- }
- if (!_map_->f_key->str(fptr, root->key) &&
- !_map_->f_val->str(fptr, root->value))
- return 0;
- left_done = 1;
- if (root->right)
- {
- left_done = 0;
- root = root->right;
- }
- else if (root->parent)
- {
- while (root->parent && root == root->parent->right)
- root = root->parent;
- if (!root->parent)
- break;
- root = root->parent;
- }
+ if (_map_->f_key->cmp(scan->key, key) > 0)
+ scan = scan->left;
+ else if (_map_->f_key->cmp(scan->key, key) < 0)
+ scan = scan->right;
else
- break;
+ return scan;
+ }
+ return ((void *)0);
+}
+static unsigned char tm_impl_h(struct treemap_node *node)
+{
+ if (node == ((void *)0))
+ return 0;
+ return node->height;
+}
+static unsigned char tm_impl_hupdate(struct treemap_node *node)
+{
+ if (node == ((void *)0))
+ return 0;
+ unsigned char h_l = tm_impl_h(node->left);
+ unsigned char h_r = tm_impl_h(node->right);
+ return 1 + (h_l > h_r ? h_l : h_r);
+}
+static void tm_impl_rotate_right(struct treemap_node **Z)
+{
+ struct treemap_node *root = *Z;
+ struct treemap_node *new_root = root->left;
+ if (root->parent != ((void *)0))
+ {
+ if (root->parent->left == root)
+ root->parent->left = new_root;
+ else
+ root->parent->right = new_root;
+ }
+ new_root->parent = root->parent;
+ root->parent = new_root;
+ root->left = new_root->right;
+ if (root->left)
+ root->left->parent = root;
+ new_root->right = root;
+ root->height = tm_impl_hupdate(root);
+ new_root->height = tm_impl_hupdate(new_root);
+ *Z = new_root;
+}
+static void tm_impl_rotate_left(struct treemap_node **Z)
+{
+ struct treemap_node *root = *Z;
+ struct treemap_node *new_root = root->right;
+ if (root->parent != ((void *)0))
+ {
+ if (root->parent->right == root)
+ root->parent->right = new_root;
+ else
+ root->parent->left = new_root;
+ }
+ new_root->parent = root->parent;
+ root->parent = new_root;
+ root->right = new_root->left;
+ if (root->right)
+ root->right->parent = root;
+ new_root->left = root;
+ root->height = tm_impl_hupdate(root);
+ new_root->height = tm_impl_hupdate(new_root);
+ *Z = new_root;
+}
+static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node)
+{
+ struct treemap_node *scan = node, *child = ((void *)0);
+ int balance;
+ _Bool is_root = 0;
+ while (scan != ((void *)0))
+ {
+ if (scan->parent == ((void *)0))
+ is_root = 1;
+ scan->height = tm_impl_hupdate(scan);
+ balance = tm_impl_h(scan->right) - tm_impl_h(scan->left);
+ if (balance >= 2)
+ {
+ child = scan->right;
+ if (tm_impl_h(child->right) < tm_impl_h(child->left))
+ tm_impl_rotate_right(&(scan->right));
+ tm_impl_rotate_left(&scan);
+ }
+ else if (balance <= -2)
+ {
+ child = scan->left;
+ if (tm_impl_h(child->left) < tm_impl_h(child->right))
+ tm_impl_rotate_left(&(scan->left));
+ tm_impl_rotate_right(&scan);
+ }
+ if (is_root)
+ {
+ _map_->root = scan;
+ is_root = 0;
+ }
+ scan = scan->parent;
}
- return 1;
}
struct treemap_iter tm_iter_start(struct treemap *target)
{
@@ -768,123 +743,62 @@ size_t tm_iter_index(struct treemap_iter *iter)
{
return iter->index;
}
-static struct treemap_node *tm_impl_new_node(struct treemap *_map_, size_t key,
- size_t value)
+_Bool tm_to_string(struct treemap *_map_, FILE *fptr)
{
- struct treemap_node *node =
- _map_->alloc->malloc(sizeof(struct treemap_node));
- if (!node)
- return ((void *)0);
- node->key = key;
- node->value = value;
- node->right = ((void *)0);
- node->left = ((void *)0);
- node->parent = ((void *)0);
- node->height = 0;
- return node;
+ struct treemap *m_ = _map_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s, %s> "
+ "at %p { "
+ "root:%p, "
+ "count:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "f_key:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "treemap", "size_t", "size_t", m_, m_->root, m_->count, m_->flag, m_->f_key, m_->f_val,
+ m_->alloc, (m_)->callbacks);
}
-static struct treemap_node *tm_impl_get_node(struct treemap *_map_, size_t key)
+_Bool tm_print(struct treemap *_map_, FILE *fptr, const char *start, const char *separator, const char *end,
+ const char *key_val_sep)
{
- struct treemap_node *scan = _map_->root;
- while (scan != ((void *)0))
+ fprintf(fptr, "%s", start);
+ struct treemap_node *root = _map_->root;
+ _Bool left_done = 0;
+ size_t i = 0;
+ while (root)
{
- if (_map_->f_key->cmp(scan->key, key) > 0)
- scan = scan->left;
- else if (_map_->f_key->cmp(scan->key, key) < 0)
- scan = scan->right;
- else
- return scan;
- }
- return ((void *)0);
-}
-static unsigned char tm_impl_h(struct treemap_node *node)
-{
- if (node == ((void *)0))
- return 0;
- return node->height;
-}
-static unsigned char tm_impl_hupdate(struct treemap_node *node)
-{
- if (node == ((void *)0))
- return 0;
- unsigned char h_l = tm_impl_h(node->left);
- unsigned char h_r = tm_impl_h(node->right);
- return 1 + (h_l > h_r ? h_l : h_r);
-}
-static void tm_impl_rotate_right(struct treemap_node **Z)
-{
- struct treemap_node *root = *Z;
- struct treemap_node *new_root = root->left;
- if (root->parent != ((void *)0))
- {
- if (root->parent->left == root)
- root->parent->left = new_root;
- else
- root->parent->right = new_root;
- }
- new_root->parent = root->parent;
- root->parent = new_root;
- root->left = new_root->right;
- if (root->left)
- root->left->parent = root;
- new_root->right = root;
- root->height = tm_impl_hupdate(root);
- new_root->height = tm_impl_hupdate(new_root);
- *Z = new_root;
-}
-static void tm_impl_rotate_left(struct treemap_node **Z)
-{
- struct treemap_node *root = *Z;
- struct treemap_node *new_root = root->right;
- if (root->parent != ((void *)0))
- {
- if (root->parent->right == root)
- root->parent->right = new_root;
- else
- root->parent->left = new_root;
- }
- new_root->parent = root->parent;
- root->parent = new_root;
- root->right = new_root->left;
- if (root->right)
- root->right->parent = root;
- new_root->left = root;
- root->height = tm_impl_hupdate(root);
- new_root->height = tm_impl_hupdate(new_root);
- *Z = new_root;
-}
-static void tm_impl_rebalance(struct treemap *_map_, struct treemap_node *node)
-{
- struct treemap_node *scan = node, *child = ((void *)0);
- int balance;
- _Bool is_root = 0;
- while (scan != ((void *)0))
- {
- if (scan->parent == ((void *)0))
- is_root = 1;
- scan->height = tm_impl_hupdate(scan);
- balance = tm_impl_h(scan->right) - tm_impl_h(scan->left);
- if (balance >= 2)
+ if (!left_done)
{
- child = scan->right;
- if (tm_impl_h(child->right) < tm_impl_h(child->left))
- tm_impl_rotate_right(&(scan->right));
- tm_impl_rotate_left(&scan);
+ while (root->left)
+ root = root->left;
}
- else if (balance <= -2)
+ if (!_map_->f_key->str(fptr, root->key))
+ return 0;
+ fprintf(fptr, "%s", key_val_sep);
+ if (!_map_->f_val->str(fptr, root->value))
+ return 0;
+ if (++i < _map_->count)
+ fprintf(fptr, "%s", separator);
+ left_done = 1;
+ if (root->right)
{
- child = scan->left;
- if (tm_impl_h(child->left) < tm_impl_h(child->right))
- tm_impl_rotate_left(&(scan->left));
- tm_impl_rotate_right(&scan);
+ left_done = 0;
+ root = root->right;
}
- if (is_root)
+ else if (root->parent)
{
- _map_->root = scan;
- is_root = 0;
+ while (root->parent && root == root->parent->right)
+ root = root->parent;
+ if (!root->parent)
+ break;
+ root = root->parent;
}
- scan = scan->parent;
+ else
+ break;
}
+ fprintf(fptr, "%s", end);
+ return 1;
}
-
-#endif /* CMC_TEST_SRC_TREEMAP */
diff --git a/tests/main/src/treeset.c b/tests/src/cmc/treeset.c
similarity index 75%
rename from tests/main/src/treeset.c
rename to tests/src/cmc/treeset.c
index 517b40a..5216b54 100644
--- a/tests/main/src/treeset.c
+++ b/tests/src/cmc/treeset.c
@@ -1,97 +1,8 @@
-#ifndef CMC_TEST_SRC_TREESET
-#define CMC_TEST_SRC_TREESET
#include "cmc/treeset.h"
-struct treeset
-{
- struct treeset_node *root;
- size_t count;
- int flag;
- struct treeset_fval *f_val;
- struct cmc_alloc_node *alloc;
- struct cmc_callbacks *callbacks;
-};
-struct treeset_node
-{
- size_t value;
- unsigned char height;
- struct treeset_node *right;
- struct treeset_node *left;
- struct treeset_node *parent;
-};
-struct treeset_fval
-{
- int (*cmp)(size_t, size_t);
- size_t (*cpy)(size_t);
- _Bool (*str)(FILE *, size_t);
- void (*free)(size_t);
- size_t (*hash)(size_t);
- int (*pri)(size_t, size_t);
-};
-struct treeset_iter
-{
- struct treeset *target;
- struct treeset_node *cursor;
- struct treeset_node *first;
- struct treeset_node *last;
- size_t index;
- _Bool start;
- _Bool end;
-};
-struct treeset *ts_new(struct treeset_fval *f_val);
-struct treeset *ts_new_custom(struct treeset_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-void ts_clear(struct treeset *_set_);
-void ts_free(struct treeset *_set_);
-void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks);
-_Bool ts_insert(struct treeset *_set_, size_t value);
-_Bool ts_remove(struct treeset *_set_, size_t value);
-_Bool ts_max(struct treeset *_set_, size_t *value);
-_Bool ts_min(struct treeset *_set_, size_t *value);
-_Bool ts_contains(struct treeset *_set_, size_t value);
-_Bool ts_empty(struct treeset *_set_);
-size_t ts_count(struct treeset *_set_);
-int ts_flag(struct treeset *_set_);
-struct treeset *ts_copy_of(struct treeset *_set_);
-_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_);
-struct cmc_string ts_to_string(struct treeset *_set_);
-_Bool ts_print(struct treeset *_set_, FILE *fptr);
-struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_);
-struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_);
-struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_);
-struct treeset *ts_symmetric_difference(struct treeset *_set1_,
- struct treeset *_set2_);
-_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_);
-_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_);
-_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_);
-_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_);
-_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_);
-struct treeset_iter ts_iter_start(struct treeset *target);
-struct treeset_iter ts_iter_end(struct treeset *target);
-_Bool ts_iter_at_start(struct treeset_iter *iter);
-_Bool ts_iter_at_end(struct treeset_iter *iter);
-_Bool ts_iter_to_start(struct treeset_iter *iter);
-_Bool ts_iter_to_end(struct treeset_iter *iter);
-_Bool ts_iter_next(struct treeset_iter *iter);
-_Bool ts_iter_prev(struct treeset_iter *iter);
-_Bool ts_iter_advance(struct treeset_iter *iter, size_t steps);
-_Bool ts_iter_rewind(struct treeset_iter *iter, size_t steps);
-_Bool ts_iter_go_to(struct treeset_iter *iter, size_t index);
-size_t ts_iter_value(struct treeset_iter *iter);
-size_t ts_iter_index(struct treeset_iter *iter);
-static inline size_t ts_impl_default_value(void)
-{
- size_t _empty_value_;
- memset(&_empty_value_, 0, sizeof(size_t));
- return _empty_value_;
-}
-static struct treeset_node *ts_impl_new_node(struct treeset *_set_,
- size_t value);
-static struct treeset_node *ts_impl_get_node(struct treeset *_set_,
- size_t value);
+static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value);
+static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value);
static unsigned char ts_impl_h(struct treeset_node *node);
static unsigned char ts_impl_hupdate(struct treeset_node *node);
static void ts_impl_rotate_right(struct treeset_node **Z);
@@ -99,24 +10,11 @@ static void ts_impl_rotate_left(struct treeset_node **Z);
static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node);
struct treeset *ts_new(struct treeset_fval *f_val)
{
- if (!f_val)
- return ((void *)0);
- struct cmc_alloc_node *alloc = &cmc_alloc_node_default;
- struct treeset *_set_ = alloc->malloc(sizeof(struct treeset));
- if (!_set_)
- return ((void *)0);
- _set_->count = 0;
- _set_->root = ((void *)0);
- _set_->flag = cmc_flags.OK;
- _set_->f_val = f_val;
- _set_->alloc = alloc;
- _set_->callbacks = ((void *)0);
- return _set_;
+ return ts_new_custom(f_val, ((void *)0), ((void *)0));
}
-struct treeset *ts_new_custom(struct treeset_fval *f_val,
- struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+struct treeset *ts_new_custom(struct treeset_fval *f_val, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!f_val)
return ((void *)0);
if (!alloc)
@@ -126,10 +24,10 @@ struct treeset *ts_new_custom(struct treeset_fval *f_val,
return ((void *)0);
_set_->count = 0;
_set_->root = ((void *)0);
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
_set_->f_val = f_val;
_set_->alloc = alloc;
- _set_->callbacks = callbacks;
+ (_set_)->callbacks = callbacks;
return _set_;
}
void ts_clear(struct treeset *_set_)
@@ -183,22 +81,22 @@ void ts_clear(struct treeset *_set_)
}
_set_->count = 0;
_set_->root = ((void *)0);
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
}
void ts_free(struct treeset *_set_)
{
ts_clear(_set_);
_set_->alloc->free(_set_);
}
-void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc,
- struct cmc_callbacks *callbacks)
+void ts_customize(struct treeset *_set_, struct cmc_alloc_node *alloc, struct cmc_callbacks *callbacks)
{
+ ;
if (!alloc)
_set_->alloc = &cmc_alloc_node_default;
else
_set_->alloc = alloc;
- _set_->callbacks = callbacks;
- _set_->flag = cmc_flags.OK;
+ (_set_)->callbacks = callbacks;
+ _set_->flag = CMC_FLAG_OK;
}
_Bool ts_insert(struct treeset *_set_, size_t value)
{
@@ -207,7 +105,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value)
_set_->root = ts_impl_new_node(_set_, value);
if (!_set_->root)
{
- _set_->flag = cmc_flags.ALLOC;
+ _set_->flag = CMC_FLAG_ALLOC;
return 0;
}
}
@@ -224,7 +122,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value)
scan = scan->right;
else
{
- _set_->flag = cmc_flags.DUPLICATE;
+ _set_->flag = CMC_FLAG_DUPLICATE;
return 0;
}
}
@@ -234,7 +132,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value)
parent->left = ts_impl_new_node(_set_, value);
if (!parent->left)
{
- _set_->flag = cmc_flags.ALLOC;
+ _set_->flag = CMC_FLAG_ALLOC;
return 0;
}
parent->left->parent = parent;
@@ -245,7 +143,7 @@ _Bool ts_insert(struct treeset *_set_, size_t value)
parent->right = ts_impl_new_node(_set_, value);
if (!parent->right)
{
- _set_->flag = cmc_flags.ALLOC;
+ _set_->flag = CMC_FLAG_ALLOC;
return 0;
}
parent->right->parent = parent;
@@ -254,22 +152,23 @@ _Bool ts_insert(struct treeset *_set_, size_t value)
ts_impl_rebalance(_set_, node);
}
_set_->count++;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->create)
- _set_->callbacks->create();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->create)
+ (_set_)->callbacks->create();
+ ;
return 1;
}
_Bool ts_remove(struct treeset *_set_, size_t value)
{
if (ts_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct treeset_node *node = ts_impl_get_node(_set_, value);
if (!node)
{
- _set_->flag = cmc_flags.NOT_FOUND;
+ _set_->flag = CMC_FLAG_NOT_FOUND;
return 0;
}
struct treeset_node *temp = ((void *)0), *unbalanced = ((void *)0);
@@ -362,16 +261,17 @@ _Bool ts_remove(struct treeset *_set_, size_t value)
if (_set_->count == 0)
_set_->root = ((void *)0);
_set_->count--;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->delete)
- _set_->callbacks->delete ();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->delete)
+ (_set_)->callbacks->delete ();
+ ;
return 1;
}
_Bool ts_max(struct treeset *_set_, size_t *value)
{
if (ts_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct treeset_node *scan = _set_->root;
@@ -379,16 +279,17 @@ _Bool ts_max(struct treeset *_set_, size_t *value)
scan = scan->right;
if (value)
*value = scan->value;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return 1;
}
_Bool ts_min(struct treeset *_set_, size_t *value)
{
if (ts_empty(_set_))
{
- _set_->flag = cmc_flags.EMPTY;
+ _set_->flag = CMC_FLAG_EMPTY;
return 0;
}
struct treeset_node *scan = _set_->root;
@@ -396,16 +297,18 @@ _Bool ts_min(struct treeset *_set_, size_t *value)
scan = scan->left;
if (value)
*value = scan->value;
- _set_->flag = cmc_flags.OK;
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ _set_->flag = CMC_FLAG_OK;
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return 1;
}
_Bool ts_contains(struct treeset *_set_, size_t value)
{
_Bool result = ts_impl_get_node(_set_, value) != ((void *)0);
- if (_set_->callbacks && _set_->callbacks->read)
- _set_->callbacks->read();
+ if ((_set_)->callbacks && (_set_)->callbacks->read)
+ (_set_)->callbacks->read();
+ ;
return result;
}
_Bool ts_empty(struct treeset *_set_)
@@ -422,13 +325,13 @@ int ts_flag(struct treeset *_set_)
}
struct treeset *ts_copy_of(struct treeset *_set_)
{
- struct treeset *result =
- ts_new_custom(_set_->f_val, _set_->alloc, _set_->callbacks);
+ struct treeset *result = ts_new_custom(_set_->f_val, _set_->alloc, ((void *)0));
if (!result)
{
- _set_->flag = cmc_flags.ERROR;
+ _set_->flag = CMC_FLAG_ERROR;
return ((void *)0);
}
+ (result)->callbacks = _set_->callbacks;
if (!ts_empty(_set_))
{
struct treeset_iter iter = ts_iter_start(_set_);
@@ -440,13 +343,13 @@ struct treeset *ts_copy_of(struct treeset *_set_)
ts_insert(result, ts_iter_value(&iter));
}
}
- _set_->flag = cmc_flags.OK;
+ _set_->flag = CMC_FLAG_OK;
return result;
}
_Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_)
{
- _set1_->flag = cmc_flags.OK;
- _set2_->flag = cmc_flags.OK;
+ _set1_->flag = CMC_FLAG_OK;
+ _set2_->flag = CMC_FLAG_OK;
if (_set1_->count != _set2_->count)
return 0;
struct treeset_iter iter = ts_iter_start(_set1_);
@@ -457,175 +360,120 @@ _Bool ts_equals(struct treeset *_set1_, struct treeset *_set2_)
}
return 1;
}
-struct cmc_string ts_to_string(struct treeset *_set_)
+static struct treeset_node *ts_impl_new_node(struct treeset *_set_, size_t value)
{
- struct cmc_string str;
- struct treeset *s_ = _set_;
- int n = snprintf(str.s, cmc_string_len, cmc_string_fmt_treeset, "treeset",
- "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val,
- s_->alloc, s_->callbacks);
- return n >= 0 ? str : (struct cmc_string){ 0 };
+ struct treeset_node *node = _set_->alloc->malloc(sizeof(struct treeset_node));
+ if (!node)
+ return ((void *)0);
+ node->value = value;
+ node->right = ((void *)0);
+ node->left = ((void *)0);
+ node->parent = ((void *)0);
+ node->height = 0;
+ return node;
}
-_Bool ts_print(struct treeset *_set_, FILE *fptr)
+static struct treeset_node *ts_impl_get_node(struct treeset *_set_, size_t value)
{
- struct treeset_node *root = _set_->root;
- _Bool left_done = 0;
- while (root)
+ struct treeset_node *scan = _set_->root;
+ while (scan != ((void *)0))
{
- if (!left_done)
- {
- while (root->left)
- root = root->left;
- }
- if (!_set_->f_val->str(fptr, root->value))
- return 0;
- left_done = 1;
- if (root->right)
- {
- left_done = 0;
- root = root->right;
- }
- else if (root->parent)
- {
- while (root->parent && root == root->parent->right)
- root = root->parent;
- if (!root->parent)
- break;
- root = root->parent;
- }
+ if (_set_->f_val->cmp(scan->value, value) > 0)
+ scan = scan->left;
+ else if (_set_->f_val->cmp(scan->value, value) < 0)
+ scan = scan->right;
else
- break;
+ return scan;
}
- return 1;
+ return ((void *)0);
}
-struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_)
+static unsigned char ts_impl_h(struct treeset_node *node)
{
- struct treeset *_set_r_ =
- ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
- if (!_set_r_)
- return ((void *)0);
- struct treeset_iter iter1 = ts_iter_start(_set1_);
- struct treeset_iter iter2 = ts_iter_start(_set2_);
- for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1))
- {
- ts_insert(_set_r_, ts_iter_value(&iter1));
- }
- for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2))
- {
- ts_insert(_set_r_, ts_iter_value(&iter2));
- }
- return _set_r_;
-}
-struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_)
-{
- struct treeset *_set_r_ =
- ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
- if (!_set_r_)
- return ((void *)0);
- struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
- struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
- struct treeset_iter iter = ts_iter_start(_set_A_);
- for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
- {
- size_t value = ts_iter_value(&iter);
- if (ts_impl_get_node(_set_B_, value) != ((void *)0))
- ts_insert(_set_r_, value);
- }
- return _set_r_;
-}
-struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_)
-{
- struct treeset *_set_r_ =
- ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
- if (!_set_r_)
- return ((void *)0);
- struct treeset_iter iter = ts_iter_start(_set1_);
- for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
- {
- size_t value = ts_iter_value(&iter);
- if (ts_impl_get_node(_set2_, value) == ((void *)0))
- ts_insert(_set_r_, value);
- }
- return _set_r_;
-}
-struct treeset *ts_symmetric_difference(struct treeset *_set1_,
- struct treeset *_set2_)
-{
- struct treeset *_set_r_ =
- ts_new_custom(_set1_->f_val, _set1_->alloc, _set1_->callbacks);
- if (!_set_r_)
- return ((void *)0);
- struct treeset_iter iter1 = ts_iter_start(_set1_);
- struct treeset_iter iter2 = ts_iter_start(_set2_);
- for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1))
- {
- size_t value = ts_iter_value(&iter1);
- if (ts_impl_get_node(_set2_, value) == ((void *)0))
- ts_insert(_set_r_, value);
- }
- for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2))
- {
- size_t value = ts_iter_value(&iter2);
- if (ts_impl_get_node(_set1_, value) == ((void *)0))
- ts_insert(_set_r_, value);
- }
- return _set_r_;
-}
-_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_)
-{
- if (_set1_->count > _set2_->count)
+ if (node == ((void *)0))
return 0;
- if (ts_empty(_set1_))
- return 1;
- struct treeset_iter iter = ts_iter_start(_set1_);
- for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
- {
- size_t value = ts_iter_value(&iter);
- if (ts_impl_get_node(_set2_, value) == ((void *)0))
- return 0;
- }
- return 1;
+ return node->height;
}
-_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_)
+static unsigned char ts_impl_hupdate(struct treeset_node *node)
{
- return ts_is_subset(_set2_, _set1_);
-}
-_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_)
-{
- if (_set1_->count >= _set2_->count)
+ if (node == ((void *)0))
return 0;
- if (ts_empty(_set1_))
+ unsigned char h_l = ts_impl_h(node->left);
+ unsigned char h_r = ts_impl_h(node->right);
+ return 1 + (h_l > h_r ? h_l : h_r);
+}
+static void ts_impl_rotate_right(struct treeset_node **Z)
+{
+ struct treeset_node *root = *Z;
+ struct treeset_node *new_root = root->left;
+ if (root->parent != ((void *)0))
{
- if (!ts_empty(_set2_))
- return 1;
+ if (root->parent->left == root)
+ root->parent->left = new_root;
else
- return 0;
+ root->parent->right = new_root;
}
- struct treeset_iter iter = ts_iter_start(_set1_);
- for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
- {
- size_t value = ts_iter_value(&iter);
- if (ts_impl_get_node(_set2_, value) == ((void *)0))
- return 0;
- }
- return 1;
+ new_root->parent = root->parent;
+ root->parent = new_root;
+ root->left = new_root->right;
+ if (root->left)
+ root->left->parent = root;
+ new_root->right = root;
+ root->height = ts_impl_hupdate(root);
+ new_root->height = ts_impl_hupdate(new_root);
+ *Z = new_root;
}
-_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_)
+static void ts_impl_rotate_left(struct treeset_node **Z)
{
- return ts_is_proper_subset(_set2_, _set1_);
-}
-_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_)
-{
- if (ts_empty(_set1_))
- return 1;
- struct treeset_iter iter = ts_iter_start(_set1_);
- for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
+ struct treeset_node *root = *Z;
+ struct treeset_node *new_root = root->right;
+ if (root->parent != ((void *)0))
{
- size_t value = ts_iter_value(&iter);
- if (ts_impl_get_node(_set2_, value) != ((void *)0))
- return 0;
+ if (root->parent->right == root)
+ root->parent->right = new_root;
+ else
+ root->parent->left = new_root;
+ }
+ new_root->parent = root->parent;
+ root->parent = new_root;
+ root->right = new_root->left;
+ if (root->right)
+ root->right->parent = root;
+ new_root->left = root;
+ root->height = ts_impl_hupdate(root);
+ new_root->height = ts_impl_hupdate(new_root);
+ *Z = new_root;
+}
+static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node)
+{
+ struct treeset_node *scan = node, *child = ((void *)0);
+ int balance;
+ _Bool is_root = 0;
+ while (scan != ((void *)0))
+ {
+ if (scan->parent == ((void *)0))
+ is_root = 1;
+ scan->height = ts_impl_hupdate(scan);
+ balance = ts_impl_h(scan->right) - ts_impl_h(scan->left);
+ if (balance >= 2)
+ {
+ child = scan->right;
+ if (ts_impl_h(child->right) < ts_impl_h(child->left))
+ ts_impl_rotate_right(&(scan->right));
+ ts_impl_rotate_left(&scan);
+ }
+ else if (balance <= -2)
+ {
+ child = scan->left;
+ if (ts_impl_h(child->left) < ts_impl_h(child->right))
+ ts_impl_rotate_left(&(scan->left));
+ ts_impl_rotate_right(&scan);
+ }
+ if (is_root)
+ {
+ _set_->root = scan;
+ is_root = 0;
+ }
+ scan = scan->parent;
}
- return 1;
}
struct treeset_iter ts_iter_start(struct treeset *target)
{
@@ -810,123 +658,184 @@ size_t ts_iter_index(struct treeset_iter *iter)
{
return iter->index;
}
-static struct treeset_node *ts_impl_new_node(struct treeset *_set_,
- size_t value)
+struct treeset *ts_union(struct treeset *_set1_, struct treeset *_set2_)
{
- struct treeset_node *node =
- _set_->alloc->malloc(sizeof(struct treeset_node));
- if (!node)
+ struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
return ((void *)0);
- node->value = value;
- node->right = ((void *)0);
- node->left = ((void *)0);
- node->parent = ((void *)0);
- node->height = 0;
- return node;
-}
-static struct treeset_node *ts_impl_get_node(struct treeset *_set_,
- size_t value)
-{
- struct treeset_node *scan = _set_->root;
- while (scan != ((void *)0))
+ struct treeset_iter iter1 = ts_iter_start(_set1_);
+ struct treeset_iter iter2 = ts_iter_start(_set2_);
+ for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1))
{
- if (_set_->f_val->cmp(scan->value, value) > 0)
- scan = scan->left;
- else if (_set_->f_val->cmp(scan->value, value) < 0)
- scan = scan->right;
- else
- return scan;
+ ts_insert(_set_r_, ts_iter_value(&iter1));
}
- return ((void *)0);
+ for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2))
+ {
+ ts_insert(_set_r_, ts_iter_value(&iter2));
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
}
-static unsigned char ts_impl_h(struct treeset_node *node)
+struct treeset *ts_intersection(struct treeset *_set1_, struct treeset *_set2_)
{
- if (node == ((void *)0))
+ struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct treeset *_set_A_ = _set1_->count < _set2_->count ? _set1_ : _set2_;
+ struct treeset *_set_B_ = _set_A_ == _set1_ ? _set2_ : _set1_;
+ struct treeset_iter iter = ts_iter_start(_set_A_);
+ for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
+ {
+ size_t value = ts_iter_value(&iter);
+ if (ts_impl_get_node(_set_B_, value) != ((void *)0))
+ ts_insert(_set_r_, value);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct treeset *ts_difference(struct treeset *_set1_, struct treeset *_set2_)
+{
+ struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct treeset_iter iter = ts_iter_start(_set1_);
+ for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
+ {
+ size_t value = ts_iter_value(&iter);
+ if (ts_impl_get_node(_set2_, value) == ((void *)0))
+ ts_insert(_set_r_, value);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+struct treeset *ts_symmetric_difference(struct treeset *_set1_, struct treeset *_set2_)
+{
+ struct treeset *_set_r_ = ts_new_custom(_set1_->f_val, _set1_->alloc, ((void *)0));
+ if (!_set_r_)
+ return ((void *)0);
+ struct treeset_iter iter1 = ts_iter_start(_set1_);
+ struct treeset_iter iter2 = ts_iter_start(_set2_);
+ for (; !ts_iter_at_end(&iter1); ts_iter_next(&iter1))
+ {
+ size_t value = ts_iter_value(&iter1);
+ if (ts_impl_get_node(_set2_, value) == ((void *)0))
+ ts_insert(_set_r_, value);
+ }
+ for (; !ts_iter_at_end(&iter2); ts_iter_next(&iter2))
+ {
+ size_t value = ts_iter_value(&iter2);
+ if (ts_impl_get_node(_set1_, value) == ((void *)0))
+ ts_insert(_set_r_, value);
+ }
+ (_set_r_)->callbacks = _set1_->callbacks;
+ return _set_r_;
+}
+_Bool ts_is_subset(struct treeset *_set1_, struct treeset *_set2_)
+{
+ if (_set1_->count > _set2_->count)
return 0;
- return node->height;
+ if (ts_empty(_set1_))
+ return 1;
+ struct treeset_iter iter = ts_iter_start(_set1_);
+ for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
+ {
+ size_t value = ts_iter_value(&iter);
+ if (ts_impl_get_node(_set2_, value) == ((void *)0))
+ return 0;
+ }
+ return 1;
}
-static unsigned char ts_impl_hupdate(struct treeset_node *node)
+_Bool ts_is_superset(struct treeset *_set1_, struct treeset *_set2_)
{
- if (node == ((void *)0))
+ return ts_is_subset(_set2_, _set1_);
+}
+_Bool ts_is_proper_subset(struct treeset *_set1_, struct treeset *_set2_)
+{
+ if (_set1_->count >= _set2_->count)
return 0;
- unsigned char h_l = ts_impl_h(node->left);
- unsigned char h_r = ts_impl_h(node->right);
- return 1 + (h_l > h_r ? h_l : h_r);
-}
-static void ts_impl_rotate_right(struct treeset_node **Z)
-{
- struct treeset_node *root = *Z;
- struct treeset_node *new_root = root->left;
- if (root->parent != ((void *)0))
+ if (ts_empty(_set1_))
{
- if (root->parent->left == root)
- root->parent->left = new_root;
+ if (!ts_empty(_set2_))
+ return 1;
else
- root->parent->right = new_root;
+ return 0;
}
- new_root->parent = root->parent;
- root->parent = new_root;
- root->left = new_root->right;
- if (root->left)
- root->left->parent = root;
- new_root->right = root;
- root->height = ts_impl_hupdate(root);
- new_root->height = ts_impl_hupdate(new_root);
- *Z = new_root;
-}
-static void ts_impl_rotate_left(struct treeset_node **Z)
-{
- struct treeset_node *root = *Z;
- struct treeset_node *new_root = root->right;
- if (root->parent != ((void *)0))
+ struct treeset_iter iter = ts_iter_start(_set1_);
+ for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
{
- if (root->parent->right == root)
- root->parent->right = new_root;
+ size_t value = ts_iter_value(&iter);
+ if (ts_impl_get_node(_set2_, value) == ((void *)0))
+ return 0;
+ }
+ return 1;
+}
+_Bool ts_is_proper_superset(struct treeset *_set1_, struct treeset *_set2_)
+{
+ return ts_is_proper_subset(_set2_, _set1_);
+}
+_Bool ts_is_disjointset(struct treeset *_set1_, struct treeset *_set2_)
+{
+ if (ts_empty(_set1_))
+ return 1;
+ struct treeset_iter iter = ts_iter_start(_set1_);
+ for (; !ts_iter_at_end(&iter); ts_iter_next(&iter))
+ {
+ size_t value = ts_iter_value(&iter);
+ if (ts_impl_get_node(_set2_, value) != ((void *)0))
+ return 0;
+ }
+ return 1;
+}
+_Bool ts_to_string(struct treeset *_set_, FILE *fptr)
+{
+ struct treeset *s_ = _set_;
+ return 0 <= fprintf(fptr,
+ "struct %s<%s> "
+ "at %p { "
+ "root:%p, "
+ "count:%"
+ "I64u"
+ ", "
+ "flag:%d, "
+ "f_val:%p, "
+ "alloc:%p, "
+ "callbacks:%p }",
+ "treeset", "size_t", s_, s_->root, s_->count, s_->flag, s_->f_val, s_->alloc, (s_)->callbacks);
+}
+_Bool ts_print(struct treeset *_set_, FILE *fptr, const char *start, const char *separator, const char *end)
+{
+ fprintf(fptr, "%s", start);
+ struct treeset_node *root = _set_->root;
+ _Bool left_done = 0;
+ size_t i = 0;
+ while (root)
+ {
+ if (!left_done)
+ {
+ while (root->left)
+ root = root->left;
+ }
+ if (!_set_->f_val->str(fptr, root->value))
+ return 0;
+ if (++i < _set_->count)
+ fprintf(fptr, "%s", separator);
+ left_done = 1;
+ if (root->right)
+ {
+ left_done = 0;
+ root = root->right;
+ }
+ else if (root->parent)
+ {
+ while (root->parent && root == root->parent->right)
+ root = root->parent;
+ if (!root->parent)
+ break;
+ root = root->parent;
+ }
else
- root->parent->left = new_root;
+ break;
}
- new_root->parent = root->parent;
- root->parent = new_root;
- root->right = new_root->left;
- if (root->right)
- root->right->parent = root;
- new_root->left = root;
- root->height = ts_impl_hupdate(root);
- new_root->height = ts_impl_hupdate(new_root);
- *Z = new_root;
+ fprintf(fptr, "%s", end);
+ return 1;
}
-static void ts_impl_rebalance(struct treeset *_set_, struct treeset_node *node)
-{
- struct treeset_node *scan = node, *child = ((void *)0);
- int balance;
- _Bool is_root = 0;
- while (scan != ((void *)0))
- {
- if (scan->parent == ((void *)0))
- is_root = 1;
- scan->height = ts_impl_hupdate(scan);
- balance = ts_impl_h(scan->right) - ts_impl_h(scan->left);
- if (balance >= 2)
- {
- child = scan->right;
- if (ts_impl_h(child->right) < ts_impl_h(child->left))
- ts_impl_rotate_right(&(scan->right));
- ts_impl_rotate_left(&scan);
- }
- else if (balance <= -2)
- {
- child = scan->left;
- if (ts_impl_h(child->left) < ts_impl_h(child->right))
- ts_impl_rotate_left(&(scan->left));
- ts_impl_rotate_right(&scan);
- }
- if (is_root)
- {
- _set_->root = scan;
- is_root = 0;
- }
- scan = scan->parent;
- }
-}
-
-#endif /* CMC_TEST_SRC_TREESET */
diff --git a/tests/to_string.c b/tests/to_string.c
index 42aae05..df8b926 100644
--- a/tests/to_string.c
+++ b/tests/to_string.c
@@ -1,84 +1,208 @@
// A visual check for to_string methods
-#include "../src/macro_collections.h"
+#include "macro_collections.h"
-CMC_COLLECTION_GENERATE(BIDIMAP, bm, bmap, int, int)
-CMC_COLLECTION_GENERATE(DEQUE, d, deque, /* K */, int)
-CMC_COLLECTION_GENERATE(HASHMAP, hm, hmap, int, int)
-CMC_COLLECTION_GENERATE(HASHSET, hs, hset, /* K */, int)
-CMC_COLLECTION_GENERATE(HEAP, h, heap, /* K */, int)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih, iheap, /* K */, int)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* K */, int)
-CMC_COLLECTION_GENERATE(LIST, l, list, /* K */, int)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm, mmap, int, int)
-CMC_COLLECTION_GENERATE(MULTISET, ms, mset, /* K */, int)
-CMC_COLLECTION_GENERATE(QUEUE, q, queue, /* K */, int)
-CMC_COLLECTION_GENERATE(SORTEDLIST, sl, slist, /* K */, int)
-CMC_COLLECTION_GENERATE(STACK, s, stack, /* K */, int)
-CMC_COLLECTION_GENERATE(TREESET, ts, tset, /* K */, int)
-CMC_COLLECTION_GENERATE(TREEMAP, tm, tmap, int, int)
+// clang-format off
+C_MACRO_COLLECTIONS_ALL(CMC, BITSET, ( bs, bitset, , , ))
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d, deque, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm, hashbidimap, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm, hashmap, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm, hashmultimap, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms, hashmultiset, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs, hashset, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h, heap, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih, intervalheap, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll, linkedlist, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l, list, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q, queue, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl, sortedlist, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s, stack, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm, treemap, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts, treeset, , , int))
+
+struct
+{
+ CMC_DEF_FTAB_CMP(int);
+ CMC_DEF_FTAB_CPY(int);
+ CMC_DEF_FTAB_STR(int);
+ CMC_DEF_FTAB_FREE(int);
+ CMC_DEF_FTAB_HASH(int);
+ CMC_DEF_FTAB_PRI(int);
+} int_ftab = {cmc_i32_cmp, NULL, cmc_i32_str, NULL, cmc_i32_hash, cmc_i32_cmp};
int main(void)
{
- struct bmap *bm = bm_new_custom(100, 0.7, &(struct bmap_ftab_key){ 0 },
- &(struct bmap_ftab_val){ 0 }, NULL, NULL);
- struct deque *d =
- d_new_custom(100, &(struct deque_ftab_val){ 0 }, NULL, NULL);
- struct hmap *hm = hm_new_custom(100, 0.6, &(struct hmap_ftab_key){ 0 },
- &(struct hmap_ftab_val){ 0 }, NULL, NULL);
- struct hset *hs =
- hs_new_custom(100, 0.6, &(struct hset_ftab_val){ 0 }, NULL, NULL);
- struct heap *h = h_new_custom(100, cmc_max_heap,
- &(struct heap_ftab_val){ 0 }, NULL, NULL);
- struct iheap *ih =
- ih_new_custom(100, &(struct iheap_ftab_val){ 0 }, NULL, NULL);
- struct linked *ll =
- ll_new_custom(&(struct linked_ftab_val){ 0 }, NULL, NULL);
- struct list *l =
- l_new_custom(100, &(struct list_ftab_val){ 0 }, NULL, NULL);
- struct mmap *mm = mm_new_custom(100, 0.8, &(struct mmap_ftab_key){ 0 },
- &(struct mmap_ftab_val){ 0 }, NULL, NULL);
- struct mset *ms =
- ms_new_custom(100, 0.6, &(struct mset_ftab_val){ 0 }, NULL, NULL);
- struct queue *q =
- q_new_custom(100, &(struct queue_ftab_val){ 0 }, NULL, NULL);
- struct slist *sl =
- sl_new_custom(100, &(struct slist_ftab_val){ 0 }, NULL, NULL);
- struct stack *s =
- s_new_custom(100, &(struct stack_ftab_val){ 0 }, NULL, NULL);
- struct tmap *tm = tm_new_custom(&(struct tmap_ftab_key){ 0 },
- &(struct tmap_ftab_val){ 0 }, NULL, NULL);
- struct tset *ts = ts_new_custom(&(struct tset_ftab_val){ 0 }, NULL, NULL);
+ struct deque *d = d_new(100, (struct deque_fval *)&int_ftab);
+ struct hashbidimap *hbm = hbm_new(100, 0.8,
+ (struct hashbidimap_fkey *)&int_ftab,
+ (struct hashbidimap_fval *)&int_ftab);
+ struct hashmap *hm = hm_new(100, 0.6, (struct hashmap_fkey *)&int_ftab,
+ (struct hashmap_fval *)&int_ftab);
+ struct hashmultimap *hmm = hmm_new(100, 0.8,
+ (struct hashmultimap_fkey *)&int_ftab,
+ (struct hashmultimap_fval *)&int_ftab);
+ struct hashmultiset *hms = hms_new(100, 0.6,
+ (struct hashmultiset_fval *)&int_ftab);
+ struct hashset *hs = hs_new(100, 0.6,
+ (struct hashset_fval *)&int_ftab);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, (struct heap_fval *)&int_ftab);
+ struct intervalheap *ih = ih_new(100, (struct intervalheap_fval *)&int_ftab);
+ struct linkedlist *ll = ll_new((struct linkedlist_fval *)&int_ftab);
+ struct list *l = l_new(100, (struct list_fval *)&int_ftab);
+ struct queue *q = q_new(100, (struct queue_fval *)&int_ftab);
+ struct sortedlist *sl = sl_new(100, (struct sortedlist_fval *)&int_ftab);
+ struct stack *s = s_new(100, (struct stack_fval *)&int_ftab);
+ struct treemap *tm = tm_new((struct treemap_fkey *)&int_ftab,
+ (struct treemap_fval *)&int_ftab);
+ struct treeset *ts = ts_new((struct treeset_fval *)&int_ftab);
- printf("%s\n", bm_to_string(bm).s);
- printf("%s\n", d_to_string(d).s);
- printf("%s\n", hm_to_string(hm).s);
- printf("%s\n", hs_to_string(hs).s);
- printf("%s\n", h_to_string(h).s);
- printf("%s\n", ih_to_string(ih).s);
- printf("%s\n", ll_to_string(ll).s);
- printf("%s\n", l_to_string(l).s);
- printf("%s\n", mm_to_string(mm).s);
- printf("%s\n", ms_to_string(ms).s);
- printf("%s\n", q_to_string(q).s);
- printf("%s\n", sl_to_string(sl).s);
- printf("%s\n", s_to_string(s).s);
- printf("%s\n", tm_to_string(tm).s);
- printf("%s\n", ts_to_string(ts).s);
+ d_to_string(d, stdout);
+ d_print(d, stdout, "\n[ ", ", ", " ]\n");
+ hbm_to_string(hbm, stdout);
+ hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hm_to_string(hm, stdout);
+ hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hmm_to_string(hmm, stdout);
+ hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hms_to_string(hms, stdout);
+ hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hs_to_string(hs, stdout);
+ hs_print(hs, stdout, "\n[ ", ", ", " ]\n");
+ h_to_string(h, stdout);
+ h_print(h, stdout, "\n[ ", ", ", " ]\n");
+ ih_to_string(ih, stdout);
+ ih_print(ih, stdout, "\n[ ", ", ", " ]\n");
+ ll_to_string(ll, stdout);
+ ll_print(ll, stdout, "\n[ ", ", ", " ]\n");
+ l_to_string(l, stdout);
+ l_print(l, stdout, "\n[ ", ", ", " ]\n");
+ q_to_string(q, stdout);
+ q_print(q, stdout, "\n[ ", ", ", " ]\n");
+ sl_to_string(sl, stdout);
+ sl_print(sl, stdout, "\n[ ", ", ", " ]\n");
+ s_to_string(s, stdout);
+ s_print(s, stdout, "\n[ ", ", ", " ]\n");
+ tm_to_string(tm, stdout);
+ tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ ts_to_string(ts, stdout);
+ ts_print(ts, stdout, "\n[ ", ", ", " ]\n");
+
+ fprintf(stdout, "\n");
+
+ d_push_back(d, 0);
+ hbm_insert(hbm, 0, 0);
+ hm_insert(hm, 0, 0);
+ hmm_insert(hmm, 0, 0);
+ hms_insert(hms, 0);
+ hs_insert(hs, 0);
+ h_insert(h, 0);
+ ih_insert(ih, 0);
+ ll_push_back(ll, 0);
+ l_push_back(l, 0);
+ q_enqueue(q, 0);
+ sl_insert(sl, 0);
+ s_push(s, 0);
+ tm_insert(tm, 0, 0);
+ ts_insert(ts, 0);
+
+ d_to_string(d, stdout);
+ d_print(d, stdout, "\n[ ", ", ", " ]\n");
+ hbm_to_string(hbm, stdout);
+ hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hm_to_string(hm, stdout);
+ hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hmm_to_string(hmm, stdout);
+ hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hms_to_string(hms, stdout);
+ hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hs_to_string(hs, stdout);
+ hs_print(hs, stdout, "\n[ ", ", ", " ]\n");
+ h_to_string(h, stdout);
+ h_print(h, stdout, "\n[ ", ", ", " ]\n");
+ ih_to_string(ih, stdout);
+ ih_print(ih, stdout, "\n[ ", ", ", " ]\n");
+ ll_to_string(ll, stdout);
+ ll_print(ll, stdout, "\n[ ", ", ", " ]\n");
+ l_to_string(l, stdout);
+ l_print(l, stdout, "\n[ ", ", ", " ]\n");
+ q_to_string(q, stdout);
+ q_print(q, stdout, "\n[ ", ", ", " ]\n");
+ sl_to_string(sl, stdout);
+ sl_print(sl, stdout, "\n[ ", ", ", " ]\n");
+ s_to_string(s, stdout);
+ s_print(s, stdout, "\n[ ", ", ", " ]\n");
+ tm_to_string(tm, stdout);
+ tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ ts_to_string(ts, stdout);
+ ts_print(ts, stdout, "\n[ ", ", ", " ]\n");
+
+ for (int i = 1; i < 20; i++)
+ {
+ d_push_back(d, i);
+ hbm_insert(hbm, i, i);
+ hm_insert(hm, i, i);
+ hmm_insert(hmm, i, i);
+ hms_insert(hms, i);
+ hs_insert(hs, i);
+ h_insert(h, i);
+ ih_insert(ih, i);
+ ll_push_back(ll, i);
+ l_push_back(l, i);
+ q_enqueue(q, i);
+ sl_insert(sl, i);
+ s_push(s, i);
+ tm_insert(tm, i, i);
+ ts_insert(ts, i);
+ }
+
+ fprintf(stdout, "\n");
+
+ d_to_string(d, stdout);
+ d_print(d, stdout, "\n[ ", ", ", " ]\n");
+ hbm_to_string(hbm, stdout);
+ hbm_print(hbm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hm_to_string(hm, stdout);
+ hm_print(hm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hmm_to_string(hmm, stdout);
+ hmm_print(hmm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hms_to_string(hms, stdout);
+ hms_print(hms, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ hs_to_string(hs, stdout);
+ hs_print(hs, stdout, "\n[ ", ", ", " ]\n");
+ h_to_string(h, stdout);
+ h_print(h, stdout, "\n[ ", ", ", " ]\n");
+ ih_to_string(ih, stdout);
+ ih_print(ih, stdout, "\n[ ", ", ", " ]\n");
+ ll_to_string(ll, stdout);
+ ll_print(ll, stdout, "\n[ ", ", ", " ]\n");
+ l_to_string(l, stdout);
+ l_print(l, stdout, "\n[ ", ", ", " ]\n");
+ q_to_string(q, stdout);
+ q_print(q, stdout, "\n[ ", ", ", " ]\n");
+ sl_to_string(sl, stdout);
+ sl_print(sl, stdout, "\n[ ", ", ", " ]\n");
+ s_to_string(s, stdout);
+ s_print(s, stdout, "\n[ ", ", ", " ]\n");
+ tm_to_string(tm, stdout);
+ tm_print(tm, stdout, "\n[ {", "}, {", "} ]\n", " : ");
+ ts_to_string(ts, stdout);
+ ts_print(ts, stdout, "\n[ ", ", ", " ]\n");
- bm_free(bm);
d_free(d);
+ hbm_free(hbm);
hm_free(hm);
+ hmm_free(hmm);
+ hms_free(hms);
hs_free(hs);
h_free(h);
ih_free(ih);
ll_free(ll);
l_free(l);
- mm_free(mm);
- ms_free(ms);
q_free(q);
sl_free(sl);
s_free(s);
tm_free(tm);
ts_free(ts);
}
+
+// clang-format on
diff --git a/tests/types.c b/tests/types.c
index 9ee6797..ec6678f 100644
--- a/tests/types.c
+++ b/tests/types.c
@@ -17,151 +17,175 @@ typedef enum enum_e
NONE = 0
} enum_t;
-typedef union union_u {
+typedef union union_u
+{
enum enum_e a;
struct struct_s b;
double c;
char *d;
} union_t;
-typedef int (*func_t)(int, double, char *);
+typedef int(func_t)(int, double, char *);
-CMC_COLLECTION_GENERATE(LIST, l0, list0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(STACK, s0, stack0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(QUEUE, q0, queue0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(DEQUE, d0, deque0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(HEAP, h0, heap0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(TREESET, ts0, tset0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(TREEMAP, tm0, tmap0, struct_t *, struct_t *)
-CMC_COLLECTION_GENERATE(HASHSET, hs0, hset0, /* K */, struct_t *)
-CMC_COLLECTION_GENERATE(HASHMAP, hm0, hmap0, struct_t *, struct_t *)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih0, iheap0, struct_t *, struct_t *)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm0, mmap0, struct_t *, struct_t *)
-CMC_COLLECTION_GENERATE(MULTISET, ms0, mset0, struct_t *, struct_t *)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d0, deque0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm0, hashbidimap0, , struct_t *, struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm0, hashmap0, , struct_t *, struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm0, hashmultimap0, , struct_t *, struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms0, hashmultiset0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs0, hashset0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h0, heap0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih0, intervalheap0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll0, linkedlist0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l0, list0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q0, queue0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl0, sortedlist0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s0, stack0, , , struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm0, treemap0, , struct_t *, struct_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts0, treeset0, , , struct_t *))
-CMC_COLLECTION_GENERATE(LIST, l1, list1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(STACK, s1, stack1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(QUEUE, q1, queue1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(DEQUE, d1, deque1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(HEAP, h1, heap1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(TREESET, ts1, tset1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(TREEMAP, tm1, tmap1, struct_t, struct_t)
-CMC_COLLECTION_GENERATE(HASHSET, hs1, hset1, /* K */, struct_t)
-CMC_COLLECTION_GENERATE(HASHMAP, hm1, hmap1, struct_t, struct_t)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih1, iheap1, struct_t, struct_t)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm1, mmap1, struct_t, struct_t)
-CMC_COLLECTION_GENERATE(MULTISET, ms1, mset1, struct_t, struct_t)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d1, deque1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm1, hashbidimap1, , struct_t, struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm1, hashmap1, , struct_t, struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm1, hashmultimap1, , struct_t, struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms1, hashmultiset1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs1, hashset1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h1, heap1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih1, intervalheap1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll1, linkedlist1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l1, list1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q1, queue1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl1, sortedlist1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s1, stack1, , , struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm1, treemap1, , struct_t, struct_t))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts1, treeset1, , , struct_t))
-CMC_COLLECTION_GENERATE(LIST, l2, list2, /* K */, int)
-CMC_COLLECTION_GENERATE(STACK, s2, stack2, /* K */, int)
-CMC_COLLECTION_GENERATE(QUEUE, q2, queue2, /* K */, int)
-CMC_COLLECTION_GENERATE(DEQUE, d2, deque2, /* K */, int)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, /* K */, int)
-CMC_COLLECTION_GENERATE(HEAP, h2, heap2, /* K */, int)
-CMC_COLLECTION_GENERATE(TREESET, ts2, tset2, /* K */, int)
-CMC_COLLECTION_GENERATE(TREEMAP, tm2, tmap2, int, int)
-CMC_COLLECTION_GENERATE(HASHSET, hs2, hset2, /* K */, int)
-CMC_COLLECTION_GENERATE(HASHMAP, hm2, hmap2, int, int)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih2, iheap2, /* K */, int)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm2, mmap2, int, int)
-CMC_COLLECTION_GENERATE(MULTISET, ms2, mset2, /* K */, int)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d2, deque2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm2, hashbidimap2, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm2, hashmap2, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm2, hashmultimap2, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms2, hashmultiset2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs2, hashset2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h2, heap2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih2, intervalheap2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll2, linkedlist2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l2, list2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q2, queue2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl2, sortedlist2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s2, stack2, , , int))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm2, treemap2, , int, int))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts2, treeset2, , , int))
-CMC_COLLECTION_GENERATE(LIST, l3, list3, /* K */, int *)
-CMC_COLLECTION_GENERATE(STACK, s3, stack3, /* K */, int *)
-CMC_COLLECTION_GENERATE(QUEUE, q3, queue3, /* K */, int *)
-CMC_COLLECTION_GENERATE(DEQUE, d3, deque3, /* K */, int *)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, /* K */, int *)
-CMC_COLLECTION_GENERATE(HEAP, h3, heap3, /* K */, int *)
-CMC_COLLECTION_GENERATE(TREESET, ts3, tset3, /* K */, int *)
-CMC_COLLECTION_GENERATE(TREEMAP, tm3, tmap3, int *, int *)
-CMC_COLLECTION_GENERATE(HASHSET, hs3, hset3, /* K */, int *)
-CMC_COLLECTION_GENERATE(HASHMAP, hm3, hmap3, int *, int *)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih3, iheap3, /* K */, int *)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm3, mmap3, int *, int *)
-CMC_COLLECTION_GENERATE(MULTISET, ms3, mset3, /* K */, int *)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d3, deque3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm3, hashbidimap3, , int *, int *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm3, hashmap3, , int *, int *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm3, hashmultimap3, , int *, int *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms3, hashmultiset3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs3, hashset3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h3, heap3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih3, intervalheap3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll3, linkedlist3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l3, list3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q3, queue3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl3, sortedlist3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s3, stack3, , , int *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm3, treemap3, , int *, int *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts3, treeset3, , , int *))
-CMC_COLLECTION_GENERATE(LIST, l4, list4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(STACK, s4, stack4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(QUEUE, q4, queue4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(DEQUE, d4, deque4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(HEAP, h4, heap4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(TREESET, ts4, tset4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(TREEMAP, tm4, tmap4, enum_t *, enum_t *)
-CMC_COLLECTION_GENERATE(HASHSET, hs4, hset4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(HASHMAP, hm4, hmap4, enum_t *, enum_t *)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih4, iheap4, /* K */, enum_t *)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm4, mmap4, enum_t *, enum_t *)
-CMC_COLLECTION_GENERATE(MULTISET, ms4, mset4, /* K */, enum_t *)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d4, deque4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm4, hashbidimap4, , enum_t, enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm4, hashmap4, , enum_t, enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm4, hashmultimap4, , enum_t, enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms4, hashmultiset4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs4, hashset4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h4, heap4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih4, intervalheap4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll4, linkedlist4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l4, list4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q4, queue4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl4, sortedlist4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s4, stack4, , , enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm4, treemap4, , enum_t, enum_t))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts4, treeset4, , , enum_t))
-CMC_COLLECTION_GENERATE(LIST, l5, list5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(STACK, s5, stack5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(QUEUE, q5, queue5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(DEQUE, d5, deque5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(HEAP, h5, heap5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(TREESET, ts5, tset5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(TREEMAP, tm5, tmap5, enum_t, enum_t)
-CMC_COLLECTION_GENERATE(HASHSET, hs5, hset5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(HASHMAP, hm5, hmap5, enum_t, enum_t)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih5, iheap5, /* K */, enum_t)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm5, mmap5, enum_t, enum_t)
-CMC_COLLECTION_GENERATE(MULTISET, ms5, mset5, /* K */, enum_t)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d5, deque5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm5, hashbidimap5, , enum_t *, enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm5, hashmap5, , enum_t *, enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm5, hashmultimap5, , enum_t *, enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms5, hashmultiset5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs5, hashset5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h5, heap5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih5, intervalheap5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll5, linkedlist5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l5, list5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q5, queue5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl5, sortedlist5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s5, stack5, , , enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm5, treemap5, , enum_t *, enum_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts5, treeset5, , , enum_t *))
-CMC_COLLECTION_GENERATE(LIST, l6, list6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(STACK, s6, stack6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(QUEUE, q6, queue6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(DEQUE, d6, deque6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(HEAP, h6, heap6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(TREESET, ts6, tset6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(TREEMAP, tm6, tmap6, union_t *, union_t *)
-CMC_COLLECTION_GENERATE(HASHSET, hs6, hset6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(HASHMAP, hm6, hmap6, union_t *, union_t *)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih6, iheap6, /* K */, union_t *)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm6, mmap6, union_t *, union_t *)
-CMC_COLLECTION_GENERATE(MULTISET, ms6, mset6, /* K */, union_t *)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d6, deque6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm6, hashbidimap6, , union_t, union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm6, hashmap6, , union_t, union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm6, hashmultimap6, , union_t, union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms6, hashmultiset6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs6, hashset6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h6, heap6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih6, intervalheap6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll6, linkedlist6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l6, list6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q6, queue6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl6, sortedlist6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s6, stack6, , , union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm6, treemap6, , union_t, union_t))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts6, treeset6, , , union_t))
-CMC_COLLECTION_GENERATE(LIST, l7, list7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(STACK, s7, stack7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(QUEUE, q7, queue7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(DEQUE, d7, deque7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(HEAP, h7, heap7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(TREESET, ts7, tset7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(TREEMAP, tm7, tmap7, union_t, union_t)
-CMC_COLLECTION_GENERATE(HASHSET, hs7, hset7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(HASHMAP, hm7, hmap7, union_t, union_t)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih7, iheap7, /* K */, union_t)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm7, mmap7, union_t, union_t)
-CMC_COLLECTION_GENERATE(MULTISET, ms7, mset7, /* K */, union_t)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d7, deque7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm7, hashbidimap7, , union_t *, union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm7, hashmap7, , union_t *, union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm7, hashmultimap7, , union_t *, union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms7, hashmultiset7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs7, hashset7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h7, heap7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih7, intervalheap7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll7, linkedlist7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l7, list7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q7, queue7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl7, sortedlist7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s7, stack7, , , union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm7, treemap7, , union_t *, union_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts7, treeset7, , , union_t *))
-CMC_COLLECTION_GENERATE(LIST, l8, list8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(STACK, s8, stack8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(QUEUE, q8, queue8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(DEQUE, d8, deque8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(HEAP, h8, heap8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(TREESET, ts8, tset8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(TREEMAP, tm8, tmap8, func_t, func_t)
-CMC_COLLECTION_GENERATE(HASHSET, hs8, hset8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(HASHMAP, hm8, hmap8, func_t, func_t)
-CMC_COLLECTION_GENERATE(INTERVALHEAP, ih8, iheap8, /* K */, func_t)
-CMC_COLLECTION_GENERATE(MULTIMAP, mm8, mmap8, func_t, func_t)
-CMC_COLLECTION_GENERATE(MULTISET, ms8, mset8, /* K */, func_t)
+// C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, ( d8, deque8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm8, hashbidimap8, , func_t, func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, ( hm8, hashmap8, , func_t, func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm8, hashmultimap8, , func_t, func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms8, hashmultiset8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, ( hs8, hashset8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, HEAP, ( h8, heap8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, ( ih8, intervalheap8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, ( ll8, linkedlist8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, LIST, ( l8, list8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, ( q8, queue8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, ( sl8, sortedlist8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, STACK, ( s8, stack8, , , func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, ( tm8, treemap8, , func_t, func_t))
+// C_MACRO_COLLECTIONS_ALL(CMC, TREESET, ( ts8, treeset8, , , func_t))
-CMC_COLLECTION_GENERATE(LIST, l9, list9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(STACK, s9, stack9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(QUEUE, q9, queue9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(DEQUE, d9, deque9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(HEAP, h9, heap9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(TREESET, ts9, tset9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(TREEMAP, tm9, tmap9, func_t, func_t)
-CMC_COLLECTION_GENERATE(HASHSET, hs9, hset9, /* K */, func_t)
-CMC_COLLECTION_GENERATE(HASHMAP, hm9, hmap9, func_t, func_t)
+C_MACRO_COLLECTIONS_ALL(CMC, DEQUE, (d9, deque9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHBIDIMAP, (hbm9, hashbidimap9, , func_t *, func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMAP, (hm9, hashmap9, , func_t *, func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTIMAP, (hmm9, hashmultimap9, , func_t *, func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHMULTISET, (hms9, hashmultiset9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HASHSET, (hs9, hashset9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, HEAP, (h9, heap9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, INTERVALHEAP, (ih9, intervalheap9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LINKEDLIST, (ll9, linkedlist9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, LIST, (l9, list9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, QUEUE, (q9, queue9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, SORTEDLIST, (sl9, sortedlist9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, STACK, (s9, stack9, , , func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREEMAP, (tm9, treemap9, , func_t *, func_t *))
+C_MACRO_COLLECTIONS_ALL(CMC, TREESET, (ts9, treeset9, , , func_t *))
int main(void)
{
diff --git a/tests/main/unt/bitset.c b/tests/unt/cmc/bitset.h
similarity index 75%
rename from tests/main/unt/bitset.c
rename to tests/unt/cmc/bitset.h
index 85c61b9..daf9757 100644
--- a/tests/main/unt/bitset.c
+++ b/tests/unt/cmc/bitset.h
@@ -1,15 +1,14 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_ITSET_H
+#define CMC_TESTS_UNT_CMC_ITSET_H
-#include "../src/bitset.c"
+#include "../utl.h"
-struct cmc_alloc_node *bs_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
-};
+#include "cmc/bitset.h"
-CMC_CREATE_UNIT(BitSet, true, {
- const size_t word_bytes = sizeof(cmc_bitset_word);
+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));
@@ -21,15 +20,18 @@ CMC_CREATE_UNIT(BitSet, true, {
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_not_equals(ptr, NULL, bs->buffer);
- cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, bs->alloc);
+ 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, bs_bit_to_index(128) + 1, bs->capacity);
+ cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs->capacity);
bs_free(bs);
@@ -43,7 +45,7 @@ CMC_CREATE_UNIT(BitSet, true, {
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_not_equals(ptr, NULL, bs->buffer);
- cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs->capacity);
+ 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);
@@ -51,7 +53,7 @@ CMC_CREATE_UNIT(BitSet, true, {
bs = bs_new_custom(129, NULL, NULL);
- cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs->capacity);
+ 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);
@@ -63,15 +65,18 @@ CMC_CREATE_UNIT(BitSet, true, {
struct bitset bs = bs_init(64);
cmc_assert_not_equals(ptr, NULL, bs.buffer);
- cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, bs.alloc);
+ 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, bs_bit_to_index(128) + 1, bs.capacity);
+ cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity);
bs_release(bs);
@@ -84,7 +89,7 @@ CMC_CREATE_UNIT(BitSet, true, {
struct bitset bs = bs_init_custom(64, bs_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, bs.buffer);
- cmc_assert_equals(size_t, bs_bit_to_index(63) + 1, bs.capacity);
+ 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);
@@ -92,7 +97,7 @@ CMC_CREATE_UNIT(BitSet, true, {
bs = bs_init_custom(129, NULL, NULL);
- cmc_assert_equals(size_t, bs_bit_to_index(128) + 1, bs.capacity);
+ cmc_assert_equals(size_t, cmc_bidx_to_widx(128) + 1, bs.capacity);
bs_release(bs);
@@ -106,19 +111,22 @@ CMC_CREATE_UNIT(BitSet, true, {
cmc_assert_not_equals(ptr, NULL, bs);
- bs->flag = cmc_flags.ERROR;
+ 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_flags.OK, bs->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
- bs->flag = cmc_flags.ERROR;
+ bs->flag = CMC_FLAG_ERROR;
bs_customize(bs, NULL, NULL);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, bs->alloc);
+ 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_flags.OK, bs->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
bs_free(bs);
});
@@ -129,27 +137,23 @@ CMC_CREATE_UNIT(BitSet, true, {
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
- bs->flag = cmc_flags.ERROR;
+ 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_flags.OK, bs->flag);
+ 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_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[bs_bit_to_index(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[bs_bit_to_index(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);
});
@@ -160,13 +164,13 @@ CMC_CREATE_UNIT(BitSet, true, {
cmc_assert_not_equals(ptr, NULL, bs);
cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0, bs->buffer[0]);
- bs->flag = cmc_flags.ERROR;
+ 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_flags.OK, bs->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, bs->flag);
cmc_assert(!bs_set_range(bs, 1, 0));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, bs->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, bs->flag);
bs->buffer[0] = 0;
@@ -177,28 +181,23 @@ CMC_CREATE_UNIT(BitSet, true, {
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[bs_bit_to_index(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[bs_bit_to_index(word_bits * 20)]);
+ 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[bs_bit_to_index(word_bits * 20 - 1)]);
- cmc_assert_equals(CMC_BITSET_WORD_TYPE, 0,
- bs->buffer[bs_bit_to_index(word_bits * 21 + 1)]);
+ 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]);
+ cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
bs_free(bs);
});
@@ -231,7 +230,7 @@ CMC_CREATE_UNIT(BitSet, true, {
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_flags.INVALID, bs->flag);
+ 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);
@@ -239,8 +238,7 @@ CMC_CREATE_UNIT(BitSet, true, {
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[bs_bit_to_index(word_bits * 20)]);
+ 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);
@@ -309,8 +307,7 @@ CMC_CREATE_UNIT(BitSet, 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_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
bs_free(bs);
});
@@ -359,8 +356,7 @@ CMC_CREATE_UNIT(BitSet, 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_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++)
@@ -377,8 +373,7 @@ CMC_CREATE_UNIT(BitSet, true, {
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]);
+ cmc_assert_equals(CMC_BITSET_WORD_TYPE, ~((cmc_bitset_word)0), bs->buffer[i]);
bs_free(bs);
});
@@ -404,8 +399,7 @@ CMC_CREATE_UNIT(BitSet, true, {
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_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++)
@@ -435,9 +429,9 @@ CMC_CREATE_UNIT(BitSet, true, {
});
});
-CMC_CREATE_UNIT(BitSetIter, true, {
- const size_t word_bytes = sizeof(cmc_bitset_word);
- const size_t word_bits = sizeof(cmc_bitset_word) * CHAR_BIT;
+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");
@@ -455,16 +449,16 @@ CMC_CREATE_UNIT(BitSetIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = BitSet() + BitSetIter();
+ int result = CMCBitSet() + CMCBitSetIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | BitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCBitSet Suit : %-47s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_ITSET_H */
diff --git a/tests/main/unt/deque.c b/tests/unt/cmc/deque.h
similarity index 86%
rename from tests/main/unt/deque.c
rename to tests/unt/cmc/deque.h
index c46374d..a072906 100644
--- a/tests/main/unt/deque.c
+++ b/tests/unt/cmc/deque.h
@@ -1,28 +1,22 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_EQUE_H
+#define CMC_TESTS_UNT_CMC_EQUE_H
-#include "../src/deque.c"
+#include "../utl.h"
-struct deque_fval *d_fval = &(struct deque_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/deque.h"
-struct deque_fval *d_fval_counter = &(struct deque_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *d_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct deque_fval *d_fval = &(struct deque_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(Deque, true, {
+struct deque_fval *d_fval_counter = &(struct deque_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *d_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCDeque, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct deque *d = d_new(1000000, d_fval);
@@ -32,9 +26,12 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 0, d->count);
cmc_assert_equals(size_t, 0, d->front);
cmc_assert_equals(size_t, 0, d->back);
- cmc_assert_equals(int32_t, cmc_flags.OK, d->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag);
cmc_assert_equals(ptr, d_fval, d->f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, d->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free);
cmc_assert_equals(ptr, NULL, d->callbacks);
d_free(d);
@@ -50,8 +47,7 @@ CMC_CREATE_UNIT(Deque, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct deque *d =
- d_new_custom(1000000, d_fval, d_alloc_node, callbacks);
+ struct deque *d = d_new_custom(1000000, d_fval, d_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, d);
cmc_assert_not_equals(ptr, NULL, d->buffer);
@@ -59,7 +55,7 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 0, d->count);
cmc_assert_equals(size_t, 0, d->front);
cmc_assert_equals(size_t, 0, d->back);
- cmc_assert_equals(int32_t, cmc_flags.OK, d->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d->flag);
cmc_assert_equals(ptr, d_fval, d->f_val);
cmc_assert_equals(ptr, d_alloc_node, d->alloc);
cmc_assert_equals(ptr, callbacks, d->callbacks);
@@ -84,9 +80,12 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 0, d.count);
cmc_assert_equals(size_t, 0, d.front);
cmc_assert_equals(size_t, 0, d.back);
- cmc_assert_equals(int32_t, cmc_flags.OK, d.flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag);
cmc_assert_equals(ptr, d_fval, d.f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, d.alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d.alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d.alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d.alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, d.alloc->free);
cmc_assert_equals(ptr, NULL, d.callbacks);
d_release(d);
@@ -111,15 +110,14 @@ CMC_CREATE_UNIT(Deque, true, {
});
CMC_CREATE_TEST(PFX##_init_custom(), {
- struct deque d =
- d_init_custom(1000000, d_fval, d_alloc_node, callbacks);
+ struct deque d = d_init_custom(1000000, d_fval, d_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, d.buffer);
cmc_assert_equals(size_t, 1000000, d.capacity);
cmc_assert_equals(size_t, 0, d.count);
cmc_assert_equals(size_t, 0, d.front);
cmc_assert_equals(size_t, 0, d.back);
- cmc_assert_equals(int32_t, cmc_flags.OK, d.flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d.flag);
cmc_assert_equals(ptr, d_fval, d.f_val);
cmc_assert_equals(ptr, d_alloc_node, d.alloc);
cmc_assert_equals(ptr, callbacks, d.callbacks);
@@ -156,11 +154,11 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 50, d_count(d));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
d_clear(d);
cmc_assert_equals(size_t, 50, v_total_free);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert_equals(size_t, 0, d_count(d));
cmc_assert_equals(size_t, 100, d_capacity(d));
@@ -176,17 +174,16 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 1000, d_count(d));
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
sum += d->buffer[i];
cmc_assert_equals(size_t, 500500, sum);
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
d_clear(d);
cmc_assert_equals(size_t, 1050, v_total_free);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
sum = 0;
for (size_t i = 0; i < d->capacity; i++)
@@ -219,8 +216,7 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 1000, d_count(d));
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
sum += d->buffer[i];
cmc_assert_equals(size_t, 500500, sum);
@@ -250,8 +246,7 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 1000, d_count(&d));
size_t sum = 0;
- for (size_t i = d.front, j = 0; j < d.count;
- i = (i + 1) % d.capacity, j++)
+ for (size_t i = d.front, j = 0; j < d.count; i = (i + 1) % d.capacity, j++)
sum += d.buffer[i];
cmc_assert_equals(size_t, 500500, sum);
@@ -268,19 +263,22 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_not_equals(ptr, NULL, d);
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
d_customize(d, d_alloc_node, callbacks);
cmc_assert_equals(ptr, d_alloc_node, d->alloc);
cmc_assert_equals(ptr, callbacks, d->callbacks);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
d_customize(d, NULL, NULL);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, d->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, d->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, d->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, d->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, d->alloc->free);
cmc_assert_equals(ptr, NULL, d->callbacks);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
d_free(d);
});
@@ -291,12 +289,12 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_not_equals(ptr, NULL, d);
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_push_front(d, 10));
cmc_assert_equals(size_t, 1, d_count(d));
cmc_assert_equals(int32_t, 1, total_create);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
d_customize(d, NULL, NULL);
@@ -319,8 +317,7 @@ CMC_CREATE_UNIT(Deque, true, {
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -339,12 +336,12 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_not_equals(ptr, NULL, d);
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_push_front(d, 10));
cmc_assert_equals(size_t, 1, d_count(d));
cmc_assert_equals(int32_t, 1, total_create);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
d_customize(d, NULL, NULL);
@@ -367,8 +364,7 @@ CMC_CREATE_UNIT(Deque, true, {
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -387,14 +383,14 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_not_equals(ptr, NULL, d);
cmc_assert(!d_pop_front(d));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
cmc_assert(d_push_front(d, 10));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_pop_front(d));
cmc_assert_equals(size_t, 0, d_count(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert(d_push_back(d, 10));
cmc_assert(d_pop_front(d));
@@ -417,8 +413,7 @@ CMC_CREATE_UNIT(Deque, true, {
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -437,8 +432,7 @@ CMC_CREATE_UNIT(Deque, true, {
sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -454,14 +448,14 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_not_equals(ptr, NULL, d);
cmc_assert(!d_pop_back(d));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
cmc_assert(d_push_front(d, 10));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_pop_back(d));
cmc_assert_equals(size_t, 0, d_count(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert(d_push_back(d, 10));
cmc_assert(d_pop_back(d));
@@ -482,8 +476,7 @@ CMC_CREATE_UNIT(Deque, true, {
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -502,8 +495,7 @@ CMC_CREATE_UNIT(Deque, true, {
sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -520,13 +512,13 @@ CMC_CREATE_UNIT(Deque, true, {
d_front(d);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
cmc_assert(d_push_front(d, 99));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 99, d_front(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert(d_push_back(d, 98));
cmc_assert_equals(size_t, 99, d_front(d));
@@ -573,13 +565,13 @@ CMC_CREATE_UNIT(Deque, true, {
d_back(d);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
cmc_assert(d_push_back(d, 99));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 99, d_back(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert(d_push_front(d, 98));
cmc_assert_equals(size_t, 99, d_back(d));
@@ -754,7 +746,7 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_not_equals(ptr, NULL, d);
cmc_assert_equals(size_t, 100, d_capacity(d));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_resize(d, 100));
cmc_assert_equals(size_t, 100, d_capacity(d));
@@ -781,7 +773,7 @@ CMC_CREATE_UNIT(Deque, true, {
cmc_assert_equals(size_t, 150, d_capacity(d));
cmc_assert(!d_resize(d, d_count(d) - 10));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, d_flag(d));
d_free(d);
@@ -802,8 +794,7 @@ CMC_CREATE_UNIT(Deque, true, {
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
{
sum += d->buffer[i];
}
@@ -1093,8 +1084,7 @@ CMC_CREATE_UNIT(Deque, true, {
}
size_t sum = 0;
- for (size_t i = d->front, j = 0; j < d->count;
- i = (i + 1) % d->capacity, j++)
+ for (size_t i = d->front, j = 0; j < d->count; i = (i + 1) % d->capacity, j++)
sum += d->buffer[i];
cmc_assert_equals(size_t, 1200, d_count(d));
@@ -1107,82 +1097,82 @@ CMC_CREATE_UNIT(Deque, true, {
struct deque *d = d_new(100, d_fval);
cmc_assert_not_equals(ptr, NULL, d);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// customize
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
d_customize(d, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 });
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// push_front
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_push_front(d, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// pop_front
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_pop_front(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert(!d_pop_front(d));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
// push_back
cmc_assert(d_push_back(d, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// pop_back
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_pop_back(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
cmc_assert(!d_pop_back(d));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
// front
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_front(d) == 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
cmc_assert(d_push_back(d, 1));
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_front(d) == 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// clear
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
d_clear(d);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// back
cmc_assert(d_back(d) == 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
cmc_assert(d_push_front(d, 1));
cmc_assert(d_back(d) == 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// contains
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
cmc_assert(d_contains(d, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
// copy_of
- d->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
struct deque *d2 = d_copy_of(d);
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2));
// equals
cmc_assert(d_pop_back(d));
cmc_assert(d_pop_back(d2));
- d->flag = cmc_flags.ERROR;
- d2->flag = cmc_flags.ERROR;
+ d->flag = CMC_FLAG_ERROR;
+ d2->flag = CMC_FLAG_ERROR;
d_front(d);
d_front(d2);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, d_flag(d2));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, d_flag(d2));
cmc_assert(d_equals(d, d2));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d));
- cmc_assert_equals(int32_t, cmc_flags.OK, d_flag(d2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, d_flag(d2));
d_free(d);
d_free(d2);
@@ -1271,7 +1261,7 @@ CMC_CREATE_UNIT(Deque, true, {
});
});
-CMC_CREATE_UNIT(DequeIter, true, {
+CMC_CREATE_UNIT(CMCDequeIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct deque *d = d_new(100, d_fval);
@@ -1730,16 +1720,16 @@ CMC_CREATE_UNIT(DequeIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = Deque() + DequeIter();
+ int result = CMCDeque() + CMCDequeIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | Deque Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCDeque Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_EQUE_H */
diff --git a/tests/main/unt/hashbidimap.c b/tests/unt/cmc/hashbidimap.h
similarity index 72%
rename from tests/main/unt/hashbidimap.c
rename to tests/unt/cmc/hashbidimap.h
index d9342a1..9c6c411 100644
--- a/tests/main/unt/hashbidimap.c
+++ b/tests/unt/cmc/hashbidimap.h
@@ -1,46 +1,30 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_ASHBIDIMAP_H
+#define CMC_TESTS_UNT_CMC_ASHBIDIMAP_H
-#include "../src/hashbidimap.c"
+#include "../utl.h"
-struct hashbidimap_fkey *hbm_fkey =
- &(struct hashbidimap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/hashbidimap.h"
-struct hashbidimap_fval *hbm_fval =
- &(struct hashbidimap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
-
-struct hashbidimap_fkey *hbm_fkey_counter =
- &(struct hashbidimap_fkey){ .cmp = k_c_cmp,
- .cpy = k_c_cpy,
- .str = k_c_str,
- .free = k_c_free,
- .hash = k_c_hash,
- .pri = k_c_pri };
-
-struct hashbidimap_fval *hbm_fval_counter =
- &(struct hashbidimap_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *hbm_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct hashbidimap_fkey *hbm_fkey = &(struct hashbidimap_fkey){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(HashBidiMap, true, {
+struct hashbidimap_fval *hbm_fval = &(struct hashbidimap_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+struct hashbidimap_fkey *hbm_fkey_counter = &(struct hashbidimap_fkey){
+ .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri
+};
+
+struct hashbidimap_fval *hbm_fval_counter = &(struct hashbidimap_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *hbm_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCHashBidiMap, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct hashbidimap *map = hbm_new(943722, 0.6, hbm_fkey, hbm_fval);
@@ -48,10 +32,13 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
cmc_assert_not_equals(ptr, NULL, map->buffer);
cmc_assert_equals(size_t, 0, map->count);
cmc_assert_equals(double, 0.6, map->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(ptr, hbm_fkey, map->f_key);
cmc_assert_equals(ptr, hbm_fval, map->f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free);
cmc_assert_equals(ptr, NULL, map->callbacks);
cmc_assert_greater_equals(size_t, (943722 / 0.6), hbm_capacity(map));
@@ -87,14 +74,13 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct hashbidimap *map = hbm_new_custom(
- 943722, 0.6, hbm_fkey, hbm_fval, hbm_alloc_node, callbacks);
+ struct hashbidimap *map = hbm_new_custom(943722, 0.6, hbm_fkey, hbm_fval, hbm_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_not_equals(ptr, NULL, map->buffer);
cmc_assert_equals(size_t, 0, map->count);
cmc_assert_equals(double, 0.6, map->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(ptr, hbm_fkey, map->f_key);
cmc_assert_equals(ptr, hbm_fval, map->f_val);
cmc_assert_equals(ptr, hbm_alloc_node, map->alloc);
@@ -123,8 +109,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
CMC_CREATE_TEST(PFX##_clear(), {
k_total_free = 0;
v_total_free = 0;
- struct hashbidimap *map =
- hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter);
+ struct hashbidimap *map = hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -133,11 +118,11 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
cmc_assert_equals(size_t, 1000, map->count);
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hbm_clear(map);
cmc_assert_equals(size_t, 0, map->count);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(int32_t, 1000, k_total_free);
cmc_assert_equals(int32_t, 1000, v_total_free);
@@ -149,8 +134,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
CMC_CREATE_TEST(PFX##_free(), {
k_total_free = 0;
v_total_free = 0;
- struct hashbidimap *map =
- hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter);
+ struct hashbidimap *map = hbm_new(100, 0.6, hbm_fkey_counter, hbm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -178,12 +162,14 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
});
CMC_CREATE_TEST(customize, {
- struct hashbidimap *map =
- hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, NULL, NULL);
+ struct hashbidimap *map = hbm_new_custom(100, 0.6, hbm_fkey, hbm_fval, NULL, NULL);
cmc_assert_not_equals(ptr, NULL, map);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free);
cmc_assert_equals(ptr, NULL, map->callbacks);
hbm_free(map);
@@ -313,8 +299,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
});
CMC_CREATE_TEST(insert[ftab hash calls], {
- struct hashbidimap *map =
- hbm_new(100, 0.7, hbm_fkey_counter, hbm_fval_counter);
+ struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey_counter, hbm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -365,7 +350,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
cmc_assert(!hbm_update_key(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map));
hbm_free(map);
});
@@ -379,21 +364,21 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
cmc_assert_equals(size_t, 1, hbm_count(map));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hbm_update_key(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
cmc_assert(!hbm_update_key(map, 2, 2));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
cmc_assert(hbm_insert(map, 2, 2));
cmc_assert(!hbm_update_key(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
cmc_assert(!hbm_update_key(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
cmc_assert(hbm_update_key(map, 2, 2));
@@ -432,7 +417,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
cmc_assert(!hbm_update_val(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map));
hbm_free(map);
});
@@ -446,21 +431,21 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
cmc_assert_equals(size_t, 1, hbm_count(map));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hbm_update_val(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
cmc_assert(!hbm_update_val(map, 2, 2));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
cmc_assert(hbm_insert(map, 2, 2));
cmc_assert(!hbm_update_val(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
cmc_assert(!hbm_update_val(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
cmc_assert(hbm_update_val(map, 2, 2));
@@ -468,13 +453,10 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
});
CMC_CREATE_TEST(remove_by_key[cleanup custom], {
- struct hashbidimap *map =
- hbm_new_custom(10000, 0.6, hbm_fkey, hbm_fval,
- &(struct cmc_alloc_node){ .malloc = malloc,
- .calloc = calloc,
- .realloc = realloc,
- .free = free },
- &(struct cmc_callbacks){ 0 });
+ struct hashbidimap *map = hbm_new_custom(
+ 10000, 0.6, hbm_fkey, hbm_fval,
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free },
+ &(struct cmc_callbacks){ 0 });
cmc_assert_not_equals(ptr, NULL, map);
@@ -493,21 +475,17 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
struct hashbidimap_entry *k = map->buffer[i][0];
struct hashbidimap_entry *v = map->buffer[i][1];
- cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) &&
- (v == NULL || v == CMC_ENTRY_DELETED));
+ cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED));
}
hbm_free(map);
});
CMC_CREATE_TEST(remove_by_val[cleanup custom], {
- struct hashbidimap *map =
- hbm_new_custom(10000, 0.6, hbm_fkey, hbm_fval,
- &(struct cmc_alloc_node){ .malloc = malloc,
- .calloc = calloc,
- .realloc = realloc,
- .free = free },
- &(struct cmc_callbacks){ 0 });
+ struct hashbidimap *map = hbm_new_custom(
+ 10000, 0.6, hbm_fkey, hbm_fval,
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free },
+ &(struct cmc_callbacks){ 0 });
cmc_assert_not_equals(ptr, NULL, map);
@@ -526,8 +504,7 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
struct hashbidimap_entry *k = map->buffer[i][0];
struct hashbidimap_entry *v = map->buffer[i][1];
- cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) &&
- (v == NULL || v == CMC_ENTRY_DELETED));
+ cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) && (v == NULL || v == CMC_ENTRY_DELETED));
}
hbm_free(map);
@@ -598,141 +575,139 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
struct hashbidimap *map = hbm_new(100, 0.7, hbm_fkey, hbm_fval);
cmc_assert_not_equals(ptr, NULL, map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
// customize
- hbm_customize(map, &cmc_alloc_node_default,
- &(struct cmc_callbacks){ 0 });
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ hbm_customize(map, &cmc_alloc_node_default, &(struct cmc_callbacks){ 0 });
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
// Insert
cmc_assert(hbm_insert(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
cmc_assert(!hbm_insert(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!hbm_insert(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
// clear
hbm_clear(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
// hbm_update_key
cmc_assert(!hbm_update_key(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map));
cmc_assert(hbm_insert(map, 1, 1));
cmc_assert(!hbm_update_key(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
cmc_assert(hbm_insert(map, 2, 2));
cmc_assert(!hbm_update_key(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!hbm_update_key(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
// clear
hbm_clear(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
// hbm_update_val
cmc_assert(!hbm_update_val(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map));
cmc_assert(hbm_insert(map, 1, 1));
cmc_assert(!hbm_update_val(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
cmc_assert(hbm_insert(map, 2, 2));
cmc_assert(!hbm_update_val(map, 2, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!hbm_update_val(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hbm_flag(map));
// remove_by_key
cmc_assert(hbm_remove_by_key(map, 1, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
cmc_assert(!hbm_remove_by_key(map, 1, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
cmc_assert(hbm_remove_by_key(map, 2, NULL, NULL));
cmc_assert(!hbm_remove_by_key(map, 2, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map));
// remove_by_val
cmc_assert(hbm_insert(map, 1, 1) && hbm_insert(map, 2, 2));
cmc_assert(hbm_remove_by_val(map, 1, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
cmc_assert(!hbm_remove_by_val(map, 1, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
cmc_assert(hbm_remove_by_val(map, 2, NULL, NULL));
cmc_assert(!hbm_remove_by_val(map, 2, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hbm_flag(map));
// get_key and get_val
cmc_assert(hbm_insert(map, 2, 1));
cmc_assert_equals(size_t, 2, hbm_get_key(map, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 1, hbm_get_val(map, 2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
cmc_assert_equals(size_t, 0, hbm_get_key(map, 2));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 0, hbm_get_val(map, 1));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
// contains_key
cmc_assert(hbm_contains_key(map, 2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
// contains_val
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hbm_contains_val(map, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
// copy_of
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
struct hashbidimap *map2 = hbm_copy_of(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map2));
size_t tmp = map->capacity;
map->capacity = 0;
struct hashbidimap *map3 = hbm_copy_of(map);
cmc_assert_equals(ptr, NULL, map3);
- cmc_assert_equals(int32_t, cmc_flags.ERROR, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hbm_flag(map));
map->capacity = tmp;
// equals
hbm_get_key(map, 100);
hbm_get_key(map2, 100);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hbm_flag(map2));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hbm_flag(map2));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hbm_equals(map, map2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, hbm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hbm_flag(map2));
hbm_free(map);
hbm_free(map2);
});
CMC_CREATE_TEST(callbacks, {
- struct hashbidimap *map =
- hbm_new_custom(100, 0.7, hbm_fkey, hbm_fval, NULL, callbacks);
+ struct hashbidimap *map = hbm_new_custom(100, 0.7, hbm_fkey, hbm_fval, NULL, callbacks);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_equals(ptr, callbacks, map->callbacks);
@@ -825,25 +800,27 @@ CMC_CREATE_UNIT(HashBidiMap, true, {
});
});
-CMC_CREATE_UNIT(HashBidiMapIter, true,
- {
-
- });
+CMC_CREATE_UNIT(CMCHashBidiMapIter, true, {
+ CMC_CREATE_TEST(PFX##_iter_start, {
+ // WIP
+ cmc_assert(true);
+ cmc_assert(true);
+ });
+});
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = HashBidiMap() + HashBidiMapIter();
+ int result = CMCHashBidiMap() + CMCHashBidiMapIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | HashBidiMap Suit : %-42s |\n",
- result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCHashBidiMap Suit : %-42s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_ASHBIDIMAP_H */
diff --git a/tests/main/unt/hashmap.c b/tests/unt/cmc/hashmap.h
similarity index 83%
rename from tests/main/unt/hashmap.c
rename to tests/unt/cmc/hashmap.h
index f43e576..c255fa8 100644
--- a/tests/main/unt/hashmap.c
+++ b/tests/unt/cmc/hashmap.h
@@ -1,42 +1,30 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_ASHMAP_H
+#define CMC_TESTS_UNT_CMC_ASHMAP_H
-#include "../src/hashmap.c"
+#include "../utl.h"
-struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/hashmap.h"
-struct hashmap_fval *hm_fval = &(struct hashmap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
-
-struct hashmap_fkey *hm_fkey_counter = &(struct hashmap_fkey){ .cmp = k_c_cmp,
- .cpy = k_c_cpy,
- .str = k_c_str,
- .free = k_c_free,
- .hash = k_c_hash,
- .pri = k_c_pri };
-
-struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *hm_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct hashmap_fkey *hm_fkey = &(struct hashmap_fkey){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(HashMap, true, {
+struct hashmap_fval *hm_fval = &(struct hashmap_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+struct hashmap_fkey *hm_fkey_counter = &(struct hashmap_fkey){
+ .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri
+};
+
+struct hashmap_fval *hm_fval_counter = &(struct hashmap_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *hm_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCHashMap, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct hashmap *map = hm_new(943722, 0.6, hm_fkey, hm_fval);
@@ -44,10 +32,13 @@ CMC_CREATE_UNIT(HashMap, true, {
cmc_assert_not_equals(ptr, NULL, map->buffer);
cmc_assert_equals(size_t, 0, map->count);
cmc_assert_equals(double, 0.6, map->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(ptr, hm_fkey, map->f_key);
cmc_assert_equals(ptr, hm_fval, map->f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free);
cmc_assert_equals(ptr, NULL, map->callbacks);
cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map));
@@ -71,14 +62,13 @@ CMC_CREATE_UNIT(HashMap, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct hashmap *map = hm_new_custom(943722, 0.6, hm_fkey, hm_fval,
- hm_alloc_node, callbacks);
+ struct hashmap *map = hm_new_custom(943722, 0.6, hm_fkey, hm_fval, hm_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_not_equals(ptr, NULL, map->buffer);
cmc_assert_equals(size_t, 0, map->count);
cmc_assert_equals(double, 0.6, map->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(ptr, hm_fkey, map->f_key);
cmc_assert_equals(ptr, hm_fval, map->f_val);
cmc_assert_equals(ptr, hm_alloc_node, map->alloc);
@@ -110,10 +100,13 @@ CMC_CREATE_UNIT(HashMap, true, {
cmc_assert_not_equals(ptr, NULL, map.buffer);
cmc_assert_equals(size_t, 0, map.count);
cmc_assert_equals(double, 0.6, map.load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map.flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag);
cmc_assert_equals(ptr, hm_fkey, map.f_key);
cmc_assert_equals(ptr, hm_fval, map.f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, map.alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map.alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map.alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map.alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, map.alloc->free);
cmc_assert_equals(ptr, NULL, map.callbacks);
cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(&map));
@@ -137,13 +130,12 @@ CMC_CREATE_UNIT(HashMap, true, {
});
CMC_CREATE_TEST(PFX##_init_custom(), {
- struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval,
- hm_alloc_node, callbacks);
+ struct hashmap map = hm_init_custom(943722, 0.6, hm_fkey, hm_fval, hm_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, map.buffer);
cmc_assert_equals(size_t, 0, map.count);
cmc_assert_equals(double, 0.6, map.load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map.flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map.flag);
cmc_assert_equals(ptr, hm_fkey, map.f_key);
cmc_assert_equals(ptr, hm_fval, map.f_val);
cmc_assert_equals(ptr, hm_alloc_node, map.alloc);
@@ -172,8 +164,7 @@ CMC_CREATE_UNIT(HashMap, true, {
CMC_CREATE_TEST(PFX##_clear(), {
k_total_free = 0;
v_total_free = 0;
- struct hashmap *map =
- hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter);
+ struct hashmap *map = hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -186,11 +177,11 @@ CMC_CREATE_UNIT(HashMap, true, {
cmc_assert_equals(size_t, 100, *r);
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hm_clear(map);
cmc_assert_equals(size_t, 0, map->count);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(int32_t, 1000, k_total_free);
cmc_assert_equals(int32_t, 1000, v_total_free);
@@ -205,8 +196,7 @@ CMC_CREATE_UNIT(HashMap, true, {
CMC_CREATE_TEST(PFX##_free(), {
k_total_free = 0;
v_total_free = 0;
- struct hashmap *map =
- hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter);
+ struct hashmap *map = hm_new(100, 0.6, hm_fkey_counter, hm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -236,8 +226,7 @@ CMC_CREATE_UNIT(HashMap, true, {
CMC_CREATE_TEST(PFX##_release(), {
k_total_free = 0;
v_total_free = 0;
- struct hashmap map =
- hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter);
+ struct hashmap map = hm_init(100, 0.6, hm_fkey_counter, hm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map.buffer);
@@ -268,19 +257,22 @@ CMC_CREATE_UNIT(HashMap, true, {
cmc_assert_not_equals(ptr, NULL, map);
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hm_customize(map, hm_alloc_node, callbacks);
cmc_assert_equals(ptr, hm_alloc_node, map->alloc);
cmc_assert_equals(ptr, callbacks, map->callbacks);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hm_customize(map, NULL, NULL);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free);
cmc_assert_equals(ptr, NULL, map->callbacks);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
hm_free(map);
});
@@ -290,9 +282,9 @@ CMC_CREATE_UNIT(HashMap, true, {
cmc_assert_not_equals(ptr, NULL, map);
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hm_insert(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(size_t, 1, hm_count(map));
hm_free(map);
@@ -360,8 +352,7 @@ CMC_CREATE_UNIT(HashMap, true, {
capacity = hm_capacity(map);
// Just to be sure, not part of the test
- cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1,
- hashcapminus1(0));
+ cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, hashcapminus1(0));
cmc_assert_equals(size_t, capacity - 1, hashcapminus1(0));
cmc_assert(hm_insert(map, 0, 0));
@@ -387,8 +378,8 @@ CMC_CREATE_UNIT(HashMap, true, {
for (size_t i = 0; i < 6; i++)
cmc_assert(hm_insert(map, i, i));
- for (size_t i = 0; i < 6; i++)
- cmc_assert_equals(size_t, i, hm_impl_get_entry(map, i)->dist);
+ // for (size_t i = 0; i < 6; i++)
+ // cmc_assert_equals(size_t, i, hm_impl_get_entry(map, i)->dist);
hm_fkey->hash = cmc_size_hash;
@@ -636,8 +627,7 @@ CMC_CREATE_UNIT(HashMap, true, {
});
CMC_CREATE_TEST(PFX##_full(), {
- struct hashmap *map =
- hm_new(cmc_hashtable_primes[0], 0.99999, hm_fkey, hm_fval);
+ struct hashmap *map = hm_new(cmc_hashtable_primes[0], 0.99999, hm_fkey, hm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -676,8 +666,7 @@ CMC_CREATE_UNIT(HashMap, true, {
cmc_assert_not_equals(ptr, NULL, map);
- cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6),
- hm_capacity(map));
+ cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), hm_capacity(map));
hm_free(map);
@@ -705,92 +694,92 @@ CMC_CREATE_UNIT(HashMap, true, {
struct hashmap *map = hm_new(100, 0.6, hm_fkey, hm_fval);
cmc_assert_not_equals(ptr, NULL, map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
// insert
cmc_assert(hm_insert(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
cmc_assert(!hm_insert(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hm_flag(map));
// clear
hm_clear(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
// update
cmc_assert(!hm_update(map, 1, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map));
cmc_assert(hm_insert(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
cmc_assert(!hm_update(map, 2, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map));
cmc_assert(hm_update(map, 1, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
// remove
cmc_assert(!hm_remove(map, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map));
cmc_assert(hm_remove(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
cmc_assert(!hm_remove(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map));
// max
cmc_assert(hm_insert(map, 1, 1));
cmc_assert(hm_max(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
cmc_assert(hm_remove(map, 1, NULL));
cmc_assert(!hm_max(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map));
// min
cmc_assert(hm_insert(map, 1, 1));
cmc_assert(hm_min(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
cmc_assert(hm_remove(map, 1, NULL));
cmc_assert(!hm_min(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map));
// get
hm_get(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map));
cmc_assert(hm_insert(map, 1, 1));
hm_get(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
hm_get(map, 2);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map));
hm_clear(map);
// get_ref
hm_get_ref(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hm_flag(map));
cmc_assert(hm_insert(map, 1, 1));
hm_get_ref(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
hm_get_ref(map, 2);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hm_flag(map));
// contains
hm_contains(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
// copy
struct hashmap *map2 = hm_copy_of(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map2));
size_t tmp = map->capacity;
map->capacity = 0;
@@ -798,21 +787,20 @@ CMC_CREATE_UNIT(HashMap, true, {
struct hashmap *map3 = hm_copy_of(map);
cmc_assert_equals(ptr, NULL, map3);
- cmc_assert_equals(int32_t, cmc_flags.ERROR, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hm_flag(map));
map->capacity = tmp;
cmc_assert(hm_equals(map, map2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, hm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hm_flag(map2));
hm_free(map);
hm_free(map2);
});
CMC_CREATE_TEST(callbacks, {
- struct hashmap *map =
- hm_new_custom(100, 0.6, hm_fkey, hm_fval, NULL, callbacks);
+ struct hashmap *map = hm_new_custom(100, 0.6, hm_fkey, hm_fval, NULL, callbacks);
cmc_assert_not_equals(ptr, NULL, map);
@@ -890,15 +878,11 @@ CMC_CREATE_UNIT(HashMap, true, {
});
});
-struct hashmap_fkey *hm_fkey_numhash =
- &(struct hashmap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = numhash,
- .pri = cmc_size_cmp };
+struct hashmap_fkey *hm_fkey_numhash = &(struct hashmap_fkey){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp
+};
-CMC_CREATE_UNIT(HashMapIter, true, {
+CMC_CREATE_UNIT(CMCHashMapIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct hashmap *map = hm_new(100, 0.6, hm_fkey_numhash, hm_fval);
@@ -1342,16 +1326,16 @@ CMC_CREATE_UNIT(HashMapIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = HashMap() + HashMapIter();
+ int result = CMCHashMap() + CMCHashMapIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | HashMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCHashMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_ASHMAP_H */
diff --git a/tests/main/unt/hashmultimap.c b/tests/unt/cmc/hashmultimap.h
similarity index 77%
rename from tests/main/unt/hashmultimap.c
rename to tests/unt/cmc/hashmultimap.h
index dfacb6a..343ff93 100644
--- a/tests/main/unt/hashmultimap.c
+++ b/tests/unt/cmc/hashmultimap.h
@@ -1,46 +1,30 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_ASHMULTIMAP_H
+#define CMC_TESTS_UNT_CMC_ASHMULTIMAP_H
-#include "../src/hashmultimap.c"
+#include "../utl.h"
-struct hashmultimap_fkey *hmm_fkey =
- &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/hashmultimap.h"
-struct hashmultimap_fval *hmm_fval =
- &(struct hashmultimap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
-
-struct hashmultimap_fkey *hmm_fkey_counter =
- &(struct hashmultimap_fkey){ .cmp = k_c_cmp,
- .cpy = k_c_cpy,
- .str = k_c_str,
- .free = k_c_free,
- .hash = k_c_hash,
- .pri = k_c_pri };
-
-struct hashmultimap_fval *hmm_fval_counter =
- &(struct hashmultimap_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *hmm_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct hashmultimap_fkey *hmm_fkey = &(struct hashmultimap_fkey){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(HashMultiMap, true, {
+struct hashmultimap_fval *hmm_fval = &(struct hashmultimap_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+struct hashmultimap_fkey *hmm_fkey_counter = &(struct hashmultimap_fkey){
+ .cmp = k_c_cmp, .cpy = k_c_cpy, .str = k_c_str, .free = k_c_free, .hash = k_c_hash, .pri = k_c_pri
+};
+
+struct hashmultimap_fval *hmm_fval_counter = &(struct hashmultimap_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *hmm_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCHashMultiMap, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct hashmultimap *map = hmm_new(943722, 0.6, hmm_fkey, hmm_fval);
@@ -48,10 +32,13 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
cmc_assert_not_equals(ptr, NULL, map->buffer);
cmc_assert_equals(size_t, 0, map->count);
cmc_assert_equals(double, 0.6, map->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(ptr, hmm_fkey, map->f_key);
cmc_assert_equals(ptr, hmm_fval, map->f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, map->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, map->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, map->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, map->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, map->alloc->free);
cmc_assert_equals(ptr, NULL, map->callbacks);
cmc_assert_greater_equals(size_t, (943722 / 0.6), hmm_capacity(map));
@@ -87,14 +74,13 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct hashmultimap *map = hmm_new_custom(
- 943722, 0.6, hmm_fkey, hmm_fval, hmm_alloc_node, callbacks);
+ struct hashmultimap *map = hmm_new_custom(943722, 0.6, hmm_fkey, hmm_fval, hmm_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_not_equals(ptr, NULL, map->buffer);
cmc_assert_equals(size_t, 0, map->count);
cmc_assert_equals(double, 0.6, map->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(ptr, hmm_fkey, map->f_key);
cmc_assert_equals(ptr, hmm_fval, map->f_val);
cmc_assert_equals(ptr, hmm_alloc_node, map->alloc);
@@ -123,8 +109,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
CMC_CREATE_TEST(PFX##_clear(), {
k_total_free = 0;
v_total_free = 0;
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -133,11 +118,11 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
cmc_assert_equals(size_t, 1000, map->count);
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hmm_clear(map);
cmc_assert_equals(size_t, 0, map->count);
- cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, map->flag);
cmc_assert_equals(int32_t, 1000, k_total_free);
cmc_assert_equals(int32_t, 1000, v_total_free);
@@ -149,8 +134,7 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
CMC_CREATE_TEST(PFX##_free(), {
k_total_free = 0;
v_total_free = 0;
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_counter, hmm_fval_counter);
cmc_assert_not_equals(ptr, NULL, map);
@@ -263,125 +247,124 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
struct hashmultimap *map = hmm_new(100, 0.8, hmm_fkey, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// clear
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hmm_clear(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// customize
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
hmm_customize(map, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// insert
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hmm_insert(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// update
cmc_assert(!hmm_update(map, 9, 10, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map));
cmc_assert(hmm_update(map, 1, 20, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// update_all
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 1, hmm_update_all(map, 1, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 0, hmm_update_all(map, 2, 4, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map));
hmm_clear(map);
cmc_assert_equals(size_t, 0, hmm_update_all(map, 1, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
// remove
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!hmm_remove(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
cmc_assert(hmm_insert(map, 1, 1));
cmc_assert(!hmm_remove(map, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map));
cmc_assert(hmm_remove(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// remove_all
cmc_assert(!hmm_remove_all(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
cmc_assert(hmm_insert(map, 1, 1) && hmm_insert(map, 1, 1));
cmc_assert_equals(size_t, 0, hmm_remove_all(map, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map));
cmc_assert_equals(size_t, 2, hmm_remove_all(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// max min
cmc_assert(!hmm_max(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!hmm_min(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
cmc_assert(hmm_insert(map, 1, 1));
cmc_assert(hmm_max(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(hmm_min(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// get get_ref
hmm_get(map, 2);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
hmm_get_ref(map, 2);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hmm_flag(map));
hmm_get(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
hmm_get_ref(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
hmm_clear(map);
hmm_get(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
- map->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
+ map->flag = CMC_FLAG_ERROR;
hmm_get_ref(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hmm_flag(map));
// contains
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!hmm_contains(map, 1000));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
// copy_of
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
struct hashmultimap *map2 = hmm_copy_of(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map2));
// equals
- map->flag = cmc_flags.ERROR;
- map2->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
+ map2->flag = CMC_FLAG_ERROR;
cmc_assert(hmm_equals(map, map2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, hmm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hmm_flag(map2));
hmm_free(map);
hmm_free(map2);
});
CMC_CREATE_TEST(callbacks, {
- struct hashmultimap *map =
- hmm_new_custom(100, 0.8, hmm_fkey, hmm_fval, NULL, callbacks);
+ struct hashmultimap *map = hmm_new_custom(100, 0.8, hmm_fkey, hmm_fval, NULL, callbacks);
cmc_assert_not_equals(ptr, NULL, map);
@@ -481,18 +464,13 @@ CMC_CREATE_UNIT(HashMultiMap, true, {
});
});
-struct hashmultimap_fkey *hmm_fkey_numhash =
- &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = numhash,
- .pri = cmc_size_cmp };
+struct hashmultimap_fkey *hmm_fkey_numhash = &(struct hashmultimap_fkey){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp
+};
-CMC_CREATE_UNIT(HashMultiMapIter, true, {
+CMC_CREATE_UNIT(CMCHashMultiMapIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -526,8 +504,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_end(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -607,8 +584,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_to_start(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -639,8 +615,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_to_end(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -681,8 +656,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
hmm_insert(map, i, i);
size_t sum = 0;
- for (it = hmm_iter_start(map); !hmm_iter_at_end(&it);
- hmm_iter_next(&it))
+ for (it = hmm_iter_start(map); !hmm_iter_at_end(&it); hmm_iter_next(&it))
{
sum += hmm_iter_value(&it);
}
@@ -715,8 +689,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
hmm_insert(map, i, i);
size_t sum = 0;
- for (it = hmm_iter_end(map); !hmm_iter_at_start(&it);
- hmm_iter_prev(&it))
+ for (it = hmm_iter_end(map); !hmm_iter_at_start(&it); hmm_iter_prev(&it))
{
sum += hmm_iter_value(&it);
}
@@ -737,8 +710,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_advance(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -772,8 +744,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_rewind(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -807,8 +778,7 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_go_to(), {
- struct hashmultimap *map =
- hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
+ struct hashmultimap *map = hmm_new(100, 0.6, hmm_fkey_numhash, hmm_fval);
cmc_assert_not_equals(ptr, NULL, map);
@@ -942,17 +912,16 @@ CMC_CREATE_UNIT(HashMultiMapIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = HashMultiMap() + HashMultiMapIter();
+ int result = CMCHashMultiMap() + CMCHashMultiMapIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | HashMultiMap Suit : %-41s |\n",
- result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCHashMultiMap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_ASHMULTIMAP_H */
diff --git a/tests/main/unt/hashmultiset.c b/tests/unt/cmc/hashmultiset.h
similarity index 82%
rename from tests/main/unt/hashmultiset.c
rename to tests/unt/cmc/hashmultiset.h
index 2c2bf74..bb70897 100644
--- a/tests/main/unt/hashmultiset.c
+++ b/tests/unt/cmc/hashmultiset.h
@@ -1,30 +1,22 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_ASHMULTISET_H
+#define CMC_TESTS_UNT_CMC_ASHMULTISET_H
-#include "../src/hashmultiset.c"
+#include "../utl.h"
-struct hashmultiset_fval *hms_fval =
- &(struct hashmultiset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/hashmultiset.h"
-struct hashmultiset_fval *hms_fval_counter =
- &(struct hashmultiset_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *hms_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct hashmultiset_fval *hms_fval = &(struct hashmultiset_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(HashMultiSet, true, {
+struct hashmultiset_fval *hms_fval_counter = &(struct hashmultiset_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *hms_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCHashMultiSet, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct hashmultiset *set = hms_new(943722, 0.6, hms_fval);
@@ -32,9 +24,12 @@ CMC_CREATE_UNIT(HashMultiSet, true, {
cmc_assert_not_equals(ptr, NULL, set->buffer);
cmc_assert_equals(size_t, 0, set->count);
cmc_assert_equals(double, 0.6, set->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, set->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag);
cmc_assert_equals(ptr, hms_fval, set->f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, set->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, set->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, set->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, set->alloc->free);
cmc_assert_equals(ptr, NULL, set->callbacks);
cmc_assert_greater_equals(size_t, (943722 / 0.6), hms_capacity(set));
@@ -55,14 +50,13 @@ CMC_CREATE_UNIT(HashMultiSet, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct hashmultiset *set =
- hms_new_custom(943722, 0.6, hms_fval, hms_alloc_node, callbacks);
+ struct hashmultiset *set = hms_new_custom(943722, 0.6, hms_fval, hms_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, set);
cmc_assert_not_equals(ptr, NULL, set->buffer);
cmc_assert_equals(size_t, 0, set->count);
cmc_assert_equals(double, 0.6, set->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, set->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag);
cmc_assert_equals(ptr, hms_fval, set->f_val);
cmc_assert_equals(ptr, hms_alloc_node, set->alloc);
cmc_assert_equals(ptr, callbacks, set->callbacks);
@@ -92,11 +86,11 @@ CMC_CREATE_UNIT(HashMultiSet, true, {
cmc_assert_equals(size_t, 1000, set->count);
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
hms_clear(set);
cmc_assert_equals(size_t, 0, set->count);
- cmc_assert_equals(int32_t, cmc_flags.OK, set->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag);
cmc_assert_equals(int32_t, 1000, v_total_free);
hms_free(set);
@@ -236,108 +230,107 @@ CMC_CREATE_UNIT(HashMultiSet, true, {
struct hashmultiset *set = hms_new(100, 0.6, hms_fval);
cmc_assert_not_equals(ptr, NULL, set);
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// clear
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
hms_clear(set);
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// customize
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
hms_customize(set, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// insert
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_insert(set, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_insert(set, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// insert_many
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_insert_many(set, 1, 0));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_insert_many(set, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// update
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_update(set, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_update(set, 10, 0));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// remove
cmc_assert(!hms_remove(set, 10));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hms_flag(set));
cmc_assert(hms_remove(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// remove_all
cmc_assert_equals(size_t, 0, hms_remove_all(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set));
cmc_assert(hms_insert_many(set, 1, 10));
cmc_assert_equals(size_t, 0, hms_remove_all(set, 10));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hms_flag(set));
cmc_assert_equals(size_t, 10, hms_remove_all(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// max min
cmc_assert(!hms_max(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hms_flag(set));
- set->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set));
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(!hms_min(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hms_flag(set));
cmc_assert(hms_insert(set, 1));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_max(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
- set->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(hms_min(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// multiplicity_of
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 0, hms_multiplicity_of(set, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// contains
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(!hms_contains(set, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
// copy_of
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
struct hashmultiset *set2 = hms_copy_of(set);
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set2));
// equals
- set->flag = cmc_flags.ERROR;
- set2->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
+ set2->flag = CMC_FLAG_ERROR;
cmc_assert(hms_equals(set, set2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set));
- cmc_assert_equals(int32_t, cmc_flags.OK, hms_flag(set2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hms_flag(set2));
hms_free(set);
hms_free(set2);
});
CMC_CREATE_TEST(callbacks, {
- struct hashmultiset *set =
- hms_new_custom(100, 0.8, hms_fval, NULL, callbacks);
+ struct hashmultiset *set = hms_new_custom(100, 0.8, hms_fval, NULL, callbacks);
cmc_assert_not_equals(ptr, NULL, set);
@@ -425,15 +418,11 @@ CMC_CREATE_UNIT(HashMultiSet, true, {
});
});
-struct hashmultiset_fval *hms_fval_numhash =
- &(struct hashmultiset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = numhash,
- .pri = cmc_size_cmp };
+struct hashmultiset_fval *hms_fval_numhash = &(struct hashmultiset_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp
+};
-CMC_CREATE_UNIT(HashMultiSetIter, true, {
+CMC_CREATE_UNIT(CMCHashMultiSetIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct hashmultiset *set = hms_new(100, 0.6, hms_fval_numhash);
@@ -621,8 +610,7 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, {
hms_insert(set, i);
size_t sum = 0;
- for (it = hms_iter_start(set); !hms_iter_at_end(&it);
- hms_iter_next(&it))
+ for (it = hms_iter_start(set); !hms_iter_at_end(&it); hms_iter_next(&it))
{
sum += hms_iter_value(&it);
}
@@ -655,8 +643,7 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, {
hms_insert(set, i);
size_t sum = 0;
- for (it = hms_iter_end(set); !hms_iter_at_start(&it);
- hms_iter_prev(&it))
+ for (it = hms_iter_end(set); !hms_iter_at_start(&it); hms_iter_prev(&it))
{
sum += hms_iter_value(&it);
}
@@ -862,17 +849,16 @@ CMC_CREATE_UNIT(HashMultiSetIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = HashMultiSet() + HashMultiSetIter();
+ int result = CMCHashMultiSet() + CMCHashMultiSetIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | HashMultiSet Suit : %-41s |\n",
- result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCHashMultiSet Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_ASHMULTISET_H */
diff --git a/tests/main/unt/hashset.c b/tests/unt/cmc/hashset.h
similarity index 86%
rename from tests/main/unt/hashset.c
rename to tests/unt/cmc/hashset.h
index 22bdd0e..38e2933 100644
--- a/tests/main/unt/hashset.c
+++ b/tests/unt/cmc/hashset.h
@@ -1,28 +1,22 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_ASHSET_H
+#define CMC_TESTS_UNT_CMC_ASHSET_H
-#include "../src/hashset.c"
+#include "../utl.h"
-struct hashset_fval *hs_fval = &(struct hashset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/hashset.h"
-struct hashset_fval *hs_fval_counter = &(struct hashset_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *hs_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct hashset_fval *hs_fval = &(struct hashset_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(HashSet, true, {
+struct hashset_fval *hs_fval_counter = &(struct hashset_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *hs_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCHashSet, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct hashset *set = hs_new(943722, 0.6, hs_fval);
@@ -30,9 +24,12 @@ CMC_CREATE_UNIT(HashSet, true, {
cmc_assert_not_equals(ptr, NULL, set->buffer);
cmc_assert_equals(size_t, 0, set->count);
cmc_assert_equals(double, 0.6, set->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, set->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag);
cmc_assert_equals(ptr, hs_fval, set->f_val);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, set->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, set->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, set->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, set->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, set->alloc->free);
cmc_assert_equals(ptr, NULL, set->callbacks);
cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set));
@@ -53,14 +50,13 @@ CMC_CREATE_UNIT(HashSet, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct hashset *set =
- hs_new_custom(943722, 0.6, hs_fval, hs_alloc_node, callbacks);
+ struct hashset *set = hs_new_custom(943722, 0.6, hs_fval, hs_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, set);
cmc_assert_not_equals(ptr, NULL, set->buffer);
cmc_assert_equals(size_t, 0, set->count);
cmc_assert_equals(double, 0.6, set->load);
- cmc_assert_equals(int32_t, cmc_flags.OK, set->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag);
cmc_assert_equals(ptr, hs_fval, set->f_val);
cmc_assert_equals(ptr, hs_alloc_node, set->alloc);
cmc_assert_equals(ptr, callbacks, set->callbacks);
@@ -90,11 +86,11 @@ CMC_CREATE_UNIT(HashSet, true, {
cmc_assert_equals(size_t, 1000, set->count);
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
hs_clear(set);
cmc_assert_equals(size_t, 0, set->count);
- cmc_assert_equals(int32_t, cmc_flags.OK, set->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, set->flag);
cmc_assert_equals(int32_t, 1000, v_total_free);
hs_free(set);
@@ -165,8 +161,7 @@ CMC_CREATE_UNIT(HashSet, true, {
cmc_assert(hs_insert(set, capacity - 1));
cmc_assert(hs_insert(set, capacity));
- cmc_assert_equals(size_t, capacity - 1,
- set->buffer[capacity - 1].value);
+ cmc_assert_equals(size_t, capacity - 1, set->buffer[capacity - 1].value);
cmc_assert_equals(size_t, capacity, set->buffer[0].value);
hs_fval->hash = cmc_size_hash;
@@ -206,8 +201,7 @@ CMC_CREATE_UNIT(HashSet, true, {
size_t capacity = hs_capacity(set);
// Just to be sure, not part of the test
- cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1,
- hashcapminus1(0));
+ cmc_assert_equals(size_t, cmc_hashtable_primes[0] - 1, hashcapminus1(0));
cmc_assert_equals(size_t, capacity - 1, hashcapminus1(0));
cmc_assert(hs_insert(set, 0));
@@ -234,8 +228,8 @@ CMC_CREATE_UNIT(HashSet, true, {
for (size_t i = 0; i < 6; i++)
cmc_assert(hs_insert(set, i));
- for (size_t i = 0; i < 6; i++)
- cmc_assert_equals(size_t, i, hs_impl_get_entry(set, i)->dist);
+ // for (size_t i = 0; i < 6; i++)
+ // cmc_assert_equals(size_t, i, hs_impl_get_entry(set, i)->dist);
hs_fval->hash = cmc_size_hash;
@@ -451,8 +445,7 @@ CMC_CREATE_UNIT(HashSet, true, {
cmc_assert_not_equals(ptr, NULL, set);
- cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6),
- hs_capacity(set));
+ cmc_assert_greater_equals(size_t, (size_t)(2500 / 0.6), hs_capacity(set));
hs_free(set);
});
@@ -481,58 +474,58 @@ CMC_CREATE_UNIT(HashSet, true, {
struct hashset *set = hs_new(1, 0.99, hs_fval);
cmc_assert_not_equals(ptr, NULL, set);
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
// insert
cmc_assert(hs_insert(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
cmc_assert(!hs_insert(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, hs_flag(set));
// clear
hs_clear(set);
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
cmc_assert(hs_insert(set, 1));
// remove
cmc_assert(!hs_remove(set, 2));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, hs_flag(set));
cmc_assert(hs_remove(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
cmc_assert(!hs_remove(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set));
// max
cmc_assert(hs_insert(set, 1));
cmc_assert(hs_max(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
cmc_assert(hs_remove(set, 1));
cmc_assert(!hs_max(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set));
// min
cmc_assert(hs_insert(set, 1));
cmc_assert(hs_min(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
cmc_assert(hs_remove(set, 1));
cmc_assert(!hs_min(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, hs_flag(set));
// contains
hs_contains(set, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
// copy
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
struct hashset *set2 = hs_copy_of(set);
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set2));
size_t tmp = set->capacity;
set->capacity = 0;
@@ -540,13 +533,13 @@ CMC_CREATE_UNIT(HashSet, true, {
struct hashset *set3 = hs_copy_of(set);
cmc_assert_equals(ptr, NULL, set3);
- cmc_assert_equals(int32_t, cmc_flags.ERROR, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_ERROR, hs_flag(set));
set->capacity = tmp;
cmc_assert(hs_equals(set, set2));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set));
- cmc_assert_equals(int32_t, cmc_flags.OK, hs_flag(set2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, hs_flag(set2));
hs_free(set);
hs_free(set2);
@@ -625,15 +618,11 @@ CMC_CREATE_UNIT(HashSet, true, {
});
});
-struct hashset_fval *hs_fval_numhash =
- &(struct hashset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = numhash,
- .pri = cmc_size_cmp };
+struct hashset_fval *hs_fval_numhash = &(struct hashset_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = numhash, .pri = cmc_size_cmp
+};
-CMC_CREATE_UNIT(HashSetIter, true, {
+CMC_CREATE_UNIT(CMCHashSetIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct hashset *set = hs_new(100, 0.6, hs_fval_numhash);
@@ -1040,16 +1029,16 @@ CMC_CREATE_UNIT(HashSetIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = HashSet() + HashSetIter();
+ int result = CMCHashSet() + CMCHashSetIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | HashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCHashSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_ASHSET_H */
diff --git a/tests/main/unt/heap.c b/tests/unt/cmc/heap.h
similarity index 81%
rename from tests/main/unt/heap.c
rename to tests/unt/cmc/heap.h
index 2a3fe60..ca320ef 100644
--- a/tests/main/unt/heap.c
+++ b/tests/unt/cmc/heap.h
@@ -1,19 +1,17 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_EAP_H
+#define CMC_TESTS_UNT_CMC_EAP_H
-#include "../src/heap.c"
+#include "../utl.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 };
+#include "cmc/heap.h"
-CMC_CREATE_UNIT(Heap, true, {
+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);
+ 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);
@@ -24,19 +22,19 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(new[edge_case capacity = 0], {
- struct heap *h = h_new(0, cmc_max_heap, h_fval);
+ 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);
+ 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);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -54,7 +52,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(buffer_growth[edge_case capacity = 1], {
- struct heap *h = h_new(1, cmc_max_heap, h_fval);
+ struct heap *h = h_new(1, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -67,7 +65,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(insert, {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -77,7 +75,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(insert[item preservation], {
- struct heap *h = h_new(50, cmc_max_heap, h_fval);
+ struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -94,7 +92,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(remove, {
- struct heap *h = h_new(50, cmc_max_heap, h_fval);
+ struct heap *h = h_new(50, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -109,7 +107,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(remove[count = 0], {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -119,14 +117,13 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(remove[sorted], {
- struct heap *h = h_new(100, cmc_min_heap, h_fval);
+ 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 r;
size_t i = 0;
size_t arr[100];
while (!h_empty(h))
@@ -141,7 +138,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(peek, {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -154,7 +151,7 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(peek[count = 0], {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -164,66 +161,65 @@ CMC_CREATE_UNIT(Heap, true, {
});
CMC_CREATE_TEST(flags, {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
- h->flag = cmc_flags.ERROR;
+ h->flag = CMC_FLAG_ERROR;
// insert
cmc_assert(h_insert(h, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
- h->flag = cmc_flags.ERROR;
+ h->flag = CMC_FLAG_ERROR;
// remove
cmc_assert(h_remove(h));
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
cmc_assert(!h_remove(h));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, h_flag(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_flags.OK, h_flag(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_flags.EMPTY, h_flag(h));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, h_flag(h));
// clear
h_clear(h);
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
- h->flag = cmc_flags.ERROR;
+ h->flag = CMC_FLAG_ERROR;
// contains
h_contains(h, 10);
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, h_flag(h));
- h->flag = cmc_flags.ERROR;
+ h->flag = CMC_FLAG_ERROR;
// copy of
struct heap *h2 = h_copy_of(h);
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h2));
+ 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_flags.ERROR;
- h2->flag = cmc_flags.ERROR;
+ h->flag = CMC_FLAG_ERROR;
+ h2->flag = CMC_FLAG_ERROR;
// equals
cmc_assert(h_equals(h, h2));
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(h));
- cmc_assert_equals(int32_t, cmc_flags.OK, h_flag(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);
+ struct heap *h = h_new_custom(100, CMC_MAX_HEAP, h_fval, NULL, callbacks);
cmc_assert_not_equals(ptr, NULL, h);
@@ -291,9 +287,9 @@ CMC_CREATE_UNIT(Heap, true, {
});
});
-CMC_CREATE_UNIT(HeapIter, true, {
+CMC_CREATE_UNIT(CMCHeapIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -319,7 +315,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_end(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -346,7 +342,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_at_start(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -368,7 +364,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_at_end(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -390,7 +386,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_to_start(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -422,7 +418,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_to_end(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -450,7 +446,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_next(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -488,7 +484,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_prev(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -526,7 +522,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_advance(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -577,7 +573,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_rewind(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -628,7 +624,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_go_to(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -669,7 +665,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_value(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -689,7 +685,7 @@ CMC_CREATE_UNIT(HeapIter, true, {
});
CMC_CREATE_TEST(PFX##_iter_index(), {
- struct heap *h = h_new(100, cmc_max_heap, h_fval);
+ struct heap *h = h_new(100, CMC_MAX_HEAP, h_fval);
cmc_assert_not_equals(ptr, NULL, h);
@@ -718,16 +714,16 @@ CMC_CREATE_UNIT(HeapIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = Heap() + HeapIter();
+ int result = CMCHeap() + CMCHeapIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | Heap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCHeap Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_EAP_H */
diff --git a/tests/main/unt/intervalheap.c b/tests/unt/cmc/intervalheap.h
similarity index 85%
rename from tests/main/unt/intervalheap.c
rename to tests/unt/cmc/intervalheap.h
index 88dea15..6b28430 100644
--- a/tests/main/unt/intervalheap.c
+++ b/tests/unt/cmc/intervalheap.h
@@ -1,30 +1,22 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_NTERVALHEAP_H
+#define CMC_TESTS_UNT_CMC_NTERVALHEAP_H
-#include "../src/intervalheap.c"
+#include "../utl.h"
-struct intervalheap_fval *ih_fval =
- &(struct intervalheap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/intervalheap.h"
-struct intervalheap_fval *ih_fval_counter =
- &(struct intervalheap_fval){ .cmp = v_c_cmp,
- .cpy = v_c_cpy,
- .str = v_c_str,
- .free = v_c_free,
- .hash = v_c_hash,
- .pri = v_c_pri };
-
-struct cmc_alloc_node *ih_alloc_node = &(struct cmc_alloc_node){
- .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free
+struct intervalheap_fval *ih_fval = &(struct intervalheap_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
};
-CMC_CREATE_UNIT(IntervalHeap, true, {
+struct intervalheap_fval *ih_fval_counter = &(struct intervalheap_fval){
+ .cmp = v_c_cmp, .cpy = v_c_cpy, .str = v_c_str, .free = v_c_free, .hash = v_c_hash, .pri = v_c_pri
+};
+
+struct cmc_alloc_node *ih_alloc_node =
+ &(struct cmc_alloc_node){ .malloc = malloc, .calloc = calloc, .realloc = realloc, .free = free };
+
+CMC_CREATE_UNIT(CMCIntervalHeap, true, {
CMC_CREATE_TEST(PFX##_new(), {
struct intervalheap *ih = ih_new(1000000, ih_fval);
@@ -72,8 +64,7 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
});
CMC_CREATE_TEST(PFX##_new_custom(), {
- struct intervalheap *ih =
- ih_new_custom(1000000, ih_fval, ih_alloc_node, callbacks);
+ struct intervalheap *ih = ih_new_custom(1000000, ih_fval, ih_alloc_node, callbacks);
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert_not_equals(ptr, NULL, ih->buffer);
@@ -96,7 +87,10 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
cmc_assert_not_equals(ptr, NULL, ih);
cmc_assert_equals(size_t, 1, ih_capacity(ih));
- cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, ih->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, ih->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, ih->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, ih->alloc->free);
cmc_assert_equals(ptr, NULL, ih->callbacks);
ih_free(ih);
@@ -196,19 +190,22 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
CMC_CREATE_TEST(PFX##_customize(), {
struct intervalheap *ih = ih_new(100, ih_fval);
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
ih_customize(ih, ih_alloc_node, callbacks);
cmc_assert_equals(ptr, ih_alloc_node, ih->alloc);
cmc_assert_equals(ptr, callbacks, ih->callbacks);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag);
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
ih_customize(ih, NULL, NULL);
- cmc_assert_equals(ptr, &cmc_alloc_node_default, ih->alloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.malloc, ih->alloc->malloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.calloc, ih->alloc->calloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.realloc, ih->alloc->realloc);
+ cmc_assert_equals(ptr, cmc_alloc_node_default.free, ih->alloc->free);
cmc_assert_equals(ptr, NULL, ih->callbacks);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag);
ih_free(ih);
});
@@ -299,15 +296,15 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
// count == 0
cmc_assert(!ih_remove_max(ih));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih->flag);
// count == 1
cmc_assert(ih_insert(ih, 10));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(ih_remove_max(ih));
cmc_assert_equals(int32_t, 1, total_delete);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag);
for (size_t i = 1; i <= 1000; i++)
ih_insert(ih, i);
@@ -347,15 +344,15 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
// count == 0
cmc_assert(!ih_remove_min(ih));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih->flag);
// count == 1
cmc_assert(ih_insert(ih, 10));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(ih_remove_min(ih));
cmc_assert_equals(int32_t, 1, total_delete);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih->flag);
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih->flag);
for (size_t i = 1000; i >= 1; i--)
ih_insert(ih, i);
@@ -434,89 +431,89 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
struct intervalheap *ih = ih_new(100, ih_fval);
cmc_assert_not_equals(ptr, NULL, ih);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
// clear
ih_clear(ih);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
// customize
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
ih_customize(ih, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
// insert
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(ih_insert(ih, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
// remove_max
cmc_assert(ih_remove_max(ih));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
cmc_assert(!ih_remove_max(ih));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih));
// remove min
cmc_assert(ih_insert(ih, 10));
cmc_assert(ih_remove_min(ih));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
cmc_assert(!ih_remove_min(ih));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih));
// update_max
cmc_assert(!ih_update_max(ih, 20));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih));
cmc_assert(ih_insert(ih, 10));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(ih_update_max(ih, 20));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
// update_min
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(ih_update_min(ih, 20));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
cmc_assert(ih_remove_min(ih));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(!ih_update_max(ih, 20));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih));
// max min
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, (size_t){ 0 }, ih_max(ih));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, (size_t){ 0 }, ih_min(ih));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ih_flag(ih));
cmc_assert(ih_insert(ih, 10));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 10, ih_max(ih));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 10, ih_min(ih));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
// contains
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
cmc_assert(ih_contains(ih, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
// copy_of
- ih->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
struct intervalheap *ih2 = ih_copy_of(ih);
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih2));
// equals
- ih->flag = cmc_flags.ERROR;
- ih2->flag = cmc_flags.ERROR;
+ ih->flag = CMC_FLAG_ERROR;
+ ih2->flag = CMC_FLAG_ERROR;
cmc_assert(ih_equals(ih, ih2));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih));
- cmc_assert_equals(int32_t, cmc_flags.OK, ih_flag(ih2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ih_flag(ih2));
ih_free(ih);
ih_free(ih2);
@@ -613,7 +610,7 @@ CMC_CREATE_UNIT(IntervalHeap, true, {
});
});
-CMC_CREATE_UNIT(IntervalHeapIter, true, {
+CMC_CREATE_UNIT(CMCIntervalHeapIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct intervalheap *ih = ih_new(100, ih_fval);
@@ -1042,17 +1039,16 @@ CMC_CREATE_UNIT(IntervalHeapIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = IntervalHeap() + IntervalHeapIter();
+ int result = CMCIntervalHeap() + CMCIntervalHeapIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | IntervalHeap Suit : %-41s |\n",
- result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCIntervalHeap Suit : %-41s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_NTERVALHEAP_H */
diff --git a/tests/main/unt/linkedlist.c b/tests/unt/cmc/linkedlist.h
similarity index 82%
rename from tests/main/unt/linkedlist.c
rename to tests/unt/cmc/linkedlist.h
index 7e5113a..cb78499 100644
--- a/tests/main/unt/linkedlist.c
+++ b/tests/unt/cmc/linkedlist.h
@@ -1,18 +1,15 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_INKEDLIST_H
+#define CMC_TESTS_UNT_CMC_INKEDLIST_H
-#include "../src/linkedlist.c"
+#include "../utl.h"
-struct linkedlist_fval *ll_fval =
- &(struct linkedlist_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/linkedlist.h"
-CMC_CREATE_UNIT(LinkedList, true, {
+struct linkedlist_fval *ll_fval = &(struct linkedlist_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCLinkedList, true, {
CMC_CREATE_TEST(new, {
struct linkedlist *ll = ll_new(ll_fval);
@@ -85,133 +82,133 @@ CMC_CREATE_UNIT(LinkedList, true, {
struct linkedlist *ll = ll_new(ll_fval);
cmc_assert_not_equals(ptr, NULL, ll);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// clear
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
ll_clear(ll);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// customize
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
ll_customize(ll, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// push_front
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(ll_push_front(ll, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// push_at
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(ll_push_at(ll, 10, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
cmc_assert(!ll_push_at(ll, 10, 300));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll));
// push_back
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(ll_push_back(ll, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_clear(ll);
// pop_front
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(!ll_pop_front(ll));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_back(ll, 10));
cmc_assert(ll_pop_front(ll));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// pop_at
cmc_assert(!ll_pop_at(ll, 0));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_front(ll, 10));
cmc_assert(!ll_pop_at(ll, 1));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll));
cmc_assert(ll_pop_at(ll, 0));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// pop_back
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(!ll_pop_front(ll));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_back(ll, 10));
cmc_assert(ll_pop_front(ll));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_clear(ll);
// front
ll_front(ll);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_front(ll, 10));
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
ll_front(ll);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_clear(ll);
// back
ll_back(ll);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_front(ll, 10));
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
ll_back(ll);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_clear(ll);
// get get_ref
ll_get(ll, 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
- ll->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
+ ll->flag = CMC_FLAG_ERROR;
ll_get_ref(ll, 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_at(ll, 10, 0));
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
ll_get(ll, 0);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_get(ll, 1);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll));
ll_get_ref(ll, 0);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_get_ref(ll, 1);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll));
// contains
cmc_assert(ll_contains(ll, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// copy_of
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
struct linkedlist *ll2 = ll_copy_of(ll);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll2));
// equals
- ll->flag = cmc_flags.ERROR;
- ll2->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
+ ll2->flag = CMC_FLAG_ERROR;
cmc_assert(ll_equals(ll, ll2));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll2));
ll_clear(ll);
// get_node
struct linkedlist_node *n = ll_get_node(ll, 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ll_flag(ll));
cmc_assert(ll_push_at(ll, 10, 0));
n = ll_get_node(ll, 0);
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
n = ll_get_node(ll, 1);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, ll_flag(ll));
// functions relative to node
ll_clear(ll);
@@ -220,35 +217,35 @@ CMC_CREATE_UNIT(LinkedList, true, {
cmc_assert_not_equals(ptr, NULL, n);
// add_next
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(ll_add_next(ll, n, 11));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// add_prev
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(ll_add_prev(ll, n, 9));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// del_next
n = ll_next_node(n);
cmc_assert(!ll_del_next(ll, n));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, ll_flag(ll));
n = ll_prev_node(n);
cmc_assert(ll_del_next(ll, n));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// del_prev
n = ll_prev_node(n);
cmc_assert(!ll_del_prev(ll, n));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, ll_flag(ll));
n = ll_next_node(n);
cmc_assert(ll_del_prev(ll, n));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
// del_curr
- ll->flag = cmc_flags.ERROR;
+ ll->flag = CMC_FLAG_ERROR;
cmc_assert(ll_del_curr(ll, n));
- cmc_assert_equals(int32_t, cmc_flags.OK, ll_flag(ll));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ll_flag(ll));
ll_free(ll);
ll_free(ll2);
@@ -343,7 +340,7 @@ CMC_CREATE_UNIT(LinkedList, true, {
});
});
-CMC_CREATE_UNIT(LinkedListIter, true, {
+CMC_CREATE_UNIT(CMCLinkedListIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct linkedlist *ll = ll_new(ll_fval);
@@ -802,16 +799,16 @@ CMC_CREATE_UNIT(LinkedListIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = LinkedList() + LinkedListIter();
+ int result = CMCLinkedList() + CMCLinkedListIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | LinkedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCLinkedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_INKEDLIST_H */
diff --git a/tests/main/unt/list.c b/tests/unt/cmc/list.h
similarity index 85%
rename from tests/main/unt/list.c
rename to tests/unt/cmc/list.h
index c98d0d2..8bda4ac 100644
--- a/tests/main/unt/list.c
+++ b/tests/unt/cmc/list.h
@@ -1,17 +1,15 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_LIST_H
+#define CMC_TESTS_UNT_CMC_LIST_H
-#include "../src/list.c"
+#include "../utl.h"
-struct list_fval *l_fval = &(struct list_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/list.h"
-CMC_CREATE_UNIT(List, true, {
+struct list_fval *l_fval = &(struct list_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCList, true, {
CMC_CREATE_TEST(new, {
struct list *l = l_new(1000000, l_fval);
@@ -316,178 +314,178 @@ CMC_CREATE_UNIT(List, true, {
struct list *l = l_new(100, l_fval);
cmc_assert_not_equals(ptr, NULL, l);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// clear
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
l_clear(l);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// customize
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
l_customize(l, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// push_front
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
cmc_assert(l_push_front(l, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// push_at
cmc_assert(!l_push_at(l, 5, 2));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
cmc_assert(l_push_at(l, 5, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// push_back
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
cmc_assert(l_push_back(l, 0));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// pop_front
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
cmc_assert(l_pop_front(l));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
l_clear(l);
cmc_assert(!l_pop_front(l));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
// pop_back
cmc_assert(l_push_front(l, 10));
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
cmc_assert(l_pop_back(l));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
cmc_assert(!l_pop_front(l));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
// pop_at
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
cmc_assert(!l_pop_at(l, 0));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
cmc_assert(l_push_back(l, 10));
cmc_assert(!l_pop_at(l, 1));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
cmc_assert(l_pop_at(l, 0));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// seq_push_front
cmc_assert(!l_seq_push_front(l, NULL, 0));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l));
cmc_assert(l_seq_push_front(l, (size_t[2]){ 1, 2 }, 2));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// seq_push_at
cmc_assert(!l_seq_push_at(l, NULL, 0, 0));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l));
cmc_assert(!l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, 10));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
cmc_assert(l_seq_push_at(l, (size_t[2]){ 1, 2 }, 2, l_count(l) - 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// seq_push_back
cmc_assert(!l_seq_push_back(l, NULL, 0));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l));
cmc_assert(l_seq_push_back(l, (size_t[2]){ 1, 2 }, 2));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// seq_pop_at
cmc_assert(!l_seq_pop_at(l, 10, 1));
- cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l));
cmc_assert(!l_seq_pop_at(l, 100, 200));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
cmc_assert(l_seq_pop_at(l, 1, l_count(l) - 2));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// seq_sublist
struct list *l2 = l_seq_sublist(l, 10, 1);
cmc_assert_equals(ptr, NULL, l2);
- cmc_assert_equals(int32_t, cmc_flags.INVALID, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_INVALID, l_flag(l));
l2 = l_seq_sublist(l, 100, 200);
cmc_assert_equals(ptr, NULL, l2);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
l2 = l_seq_sublist(l, 0, l_count(l) - 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l2));
l_clear(l);
// l_front
l_front(l);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
cmc_assert(l_push_back(l, 10));
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
l_front(l);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
l_clear(l);
// l_back
l_back(l);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
cmc_assert(l_push_back(l, 10));
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
l_back(l);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
l_clear(l);
// get, get_ref
l_get(l, 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
- l->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
+ l->flag = CMC_FLAG_ERROR;
l_get_ref(l, 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, l_flag(l));
cmc_assert(l_push_back(l, 10));
l_get(l, 1);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
- l->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
+ l->flag = CMC_FLAG_ERROR;
l_get_ref(l, 1);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, l_flag(l));
l_get(l, 0);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
- l->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
+ l->flag = CMC_FLAG_ERROR;
l_get_ref(l, 0);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// index_of
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
l_index_of(l, 10, false);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// contains
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
cmc_assert(l_contains(l, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
// copy_of
- l->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
struct list *l3 = l_copy_of(l);
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l3));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3));
// equals
- l->flag = cmc_flags.ERROR;
- l3->flag = cmc_flags.ERROR;
+ l->flag = CMC_FLAG_ERROR;
+ l3->flag = CMC_FLAG_ERROR;
cmc_assert(l_equals(l, l3));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l));
- cmc_assert_equals(int32_t, cmc_flags.OK, l_flag(l3));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, l_flag(l3));
l_free(l);
l_free(l2);
@@ -613,7 +611,7 @@ CMC_CREATE_UNIT(List, true, {
});
})
-CMC_CREATE_UNIT(ListIter, true, {
+CMC_CREATE_UNIT(CMCListIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct list *l = l_new(100, l_fval);
@@ -1068,16 +1066,16 @@ CMC_CREATE_UNIT(ListIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = List() + ListIter();
+ int result = CMCList() + CMCListIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | List Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCList Suit : %-49s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_LIST_H */
diff --git a/tests/main/unt/queue.c b/tests/unt/cmc/queue.h
similarity index 90%
rename from tests/main/unt/queue.c
rename to tests/unt/cmc/queue.h
index f988730..b9a67b3 100644
--- a/tests/main/unt/queue.c
+++ b/tests/unt/cmc/queue.h
@@ -1,17 +1,15 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_QUEUE_H
+#define CMC_TESTS_UNT_CMC_QUEUE_H
-#include "../src/queue.c"
+#include "../utl.h"
-struct queue_fval *q_fval = &(struct queue_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/queue.h"
-CMC_CREATE_UNIT(Queue, true, {
+struct queue_fval *q_fval = &(struct queue_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCQueue, true, {
CMC_CREATE_TEST(new, {
struct queue *q = q_new(1000000, q_fval);
@@ -78,8 +76,7 @@ CMC_CREATE_UNIT(Queue, true, {
}
size_t sum = 0;
- for (size_t i = q->front, j = 0; j < q->count;
- i = (i + 1) % q->capacity, j++)
+ for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++)
sum += q->buffer[i];
cmc_assert_equals(size_t, 1200, q_count(q));
@@ -112,8 +109,7 @@ CMC_CREATE_UNIT(Queue, true, {
size_t sum = 0;
- for (size_t i = q->front, j = 0; j < q->count;
- i = (i + 1) % q->capacity, j++)
+ for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++)
{
sum += q->buffer[i];
}
@@ -154,8 +150,7 @@ CMC_CREATE_UNIT(Queue, true, {
size_t sum = 0;
- for (size_t i = q->front, j = 0; j < q->count;
- i = (i + 1) % q->capacity, j++)
+ for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++)
{
sum += q->buffer[i];
}
@@ -326,8 +321,7 @@ CMC_CREATE_UNIT(Queue, true, {
size_t sum = 0;
- for (size_t i = q->front, j = 0; j < q->count;
- i = (i + 1) % q->capacity, j++)
+ for (size_t i = q->front, j = 0; j < q->count; i = (i + 1) % q->capacity, j++)
{
sum += q->buffer[i];
}
@@ -420,57 +414,57 @@ CMC_CREATE_UNIT(Queue, true, {
struct queue *q = q_new(100, q_fval);
cmc_assert_not_equals(ptr, NULL, q);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
// clear
- q->flag = cmc_flags.ERROR;
+ q->flag = CMC_FLAG_ERROR;
q_clear(q);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
// customize
- q->flag = cmc_flags.ERROR;
+ q->flag = CMC_FLAG_ERROR;
q_customize(q, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
// enqueue
- q->flag = cmc_flags.ERROR;
+ q->flag = CMC_FLAG_ERROR;
q_enqueue(q, 10);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
// dequeue
- q->flag = cmc_flags.ERROR;
+ q->flag = CMC_FLAG_ERROR;
q_dequeue(q);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
q_dequeue(q);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, q_flag(q));
// peek
- q->flag = cmc_flags.ERROR;
+ q->flag = CMC_FLAG_ERROR;
q_peek(q);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, q_flag(q));
cmc_assert(q_enqueue(q, 10));
q_peek(q);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
// contains
- q->flag = cmc_flags.ERROR;
+ q->flag = CMC_FLAG_ERROR;
cmc_assert(q_contains(q, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
// copy_of
- q->flag = cmc_flags.OK;
+ q->flag = CMC_FLAG_OK;
struct queue *q2 = q_copy_of(q);
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q2));
// equals
- q->flag = cmc_flags.OK;
- q2->flag = cmc_flags.OK;
+ q->flag = CMC_FLAG_OK;
+ q2->flag = CMC_FLAG_OK;
cmc_assert(q_equals(q, q2));
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q));
- cmc_assert_equals(int32_t, cmc_flags.OK, q_flag(q2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, q_flag(q2));
q_free(q);
q_free(q2);
@@ -545,7 +539,7 @@ CMC_CREATE_UNIT(Queue, true, {
});
});
-CMC_CREATE_UNIT(QueueIter, true, {
+CMC_CREATE_UNIT(CMCQueueIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct queue *q = q_new(100, q_fval);
@@ -958,16 +952,16 @@ CMC_CREATE_UNIT(QueueIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = Queue() + QueueIter();
+ int result = CMCQueue() + CMCQueueIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | Queue Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCQueue Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_QUEUE_H */
diff --git a/tests/main/unt/sortedlist.c b/tests/unt/cmc/sortedlist.h
similarity index 86%
rename from tests/main/unt/sortedlist.c
rename to tests/unt/cmc/sortedlist.h
index 68e23dc..edb1b8c 100644
--- a/tests/main/unt/sortedlist.c
+++ b/tests/unt/cmc/sortedlist.h
@@ -1,18 +1,15 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_SORTEDLIST_H
+#define CMC_TESTS_UNT_CMC_SORTEDLIST_H
-#include "../src/sortedlist.c"
+#include "../utl.h"
-struct sortedlist_fval *sl_fval =
- &(struct sortedlist_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/sortedlist.h"
-CMC_CREATE_UNIT(SortedList, true, {
+struct sortedlist_fval *sl_fval = &(struct sortedlist_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCSortedList, true, {
CMC_CREATE_TEST(new, {
struct sortedlist *sl = sl_new(1000000, sl_fval);
@@ -66,8 +63,7 @@ CMC_CREATE_UNIT(SortedList, true, {
sl_sort(sl);
cmc_assert_equals(size_t, 50, sl_count(sl));
- cmc_assert_array_sorted_any(size_t, sl->buffer, cmc_size_cmp, 0,
- sl->count - 1);
+ cmc_assert_array_sorted_any(size_t, sl->buffer, cmc_size_cmp, 0, sl->count - 1);
sl_free(sl);
});
@@ -148,87 +144,87 @@ CMC_CREATE_UNIT(SortedList, true, {
struct sortedlist *sl = sl_new(100, sl_fval);
cmc_assert_not_equals(ptr, NULL, sl);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// clear
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
sl_clear(sl);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// customize
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
sl_customize(sl, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// insert
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
cmc_assert(sl_insert(sl, 10));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// remove
cmc_assert(!sl_remove(sl, 2));
- cmc_assert_equals(int32_t, cmc_flags.RANGE, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, sl_flag(sl));
cmc_assert(sl_remove(sl, 0));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
cmc_assert(!sl_remove(sl, 0));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl));
// max min
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, (size_t){ 0 }, sl_max(sl));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
- sl->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl));
+ sl->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, (size_t){ 0 }, sl_min(sl));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl));
cmc_assert(sl_insert(sl, 1));
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 1, sl_max(sl));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
- sl->flag = cmc_flags.ERROR;
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
+ sl->flag = CMC_FLAG_ERROR;
cmc_assert_equals(size_t, 1, sl_min(sl));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// get
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
sl_get(sl, 1);
- cmc_assert_equals(int32_t, cmc_flags.RANGE, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_RANGE, sl_flag(sl));
sl_get(sl, 0);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
cmc_assert(sl_remove(sl, 0));
sl_get(sl, 0);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, sl_flag(sl));
// index_of
cmc_assert(sl_insert(sl, 1));
sl_index_of(sl, 1, false);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// contains
cmc_assert(sl_contains(sl, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// sort
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
sl_sort(sl);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
// copy_of
- sl->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
struct sortedlist *sl2 = sl_copy_of(sl);
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl2));
// equals
- sl->flag = cmc_flags.ERROR;
- sl2->flag = cmc_flags.ERROR;
+ sl->flag = CMC_FLAG_ERROR;
+ sl2->flag = CMC_FLAG_ERROR;
cmc_assert(sl_equals(sl, sl2));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl));
- cmc_assert_equals(int32_t, cmc_flags.OK, sl_flag(sl2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, sl_flag(sl2));
sl_free(sl);
sl_free(sl2);
@@ -313,7 +309,7 @@ CMC_CREATE_UNIT(SortedList, true, {
});
});
-CMC_CREATE_UNIT(SortedListIter, true, {
+CMC_CREATE_UNIT(CMCSortedListIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct sortedlist *sl = sl_new(100, sl_fval);
@@ -703,16 +699,16 @@ CMC_CREATE_UNIT(SortedListIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = SortedList() + SortedListIter();
+ int result = CMCSortedList() + CMCSortedListIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | SortedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCSortedList Suit : %-43s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_SORTEDLIST_H */
diff --git a/tests/main/unt/stack.c b/tests/unt/cmc/stack.h
similarity index 90%
rename from tests/main/unt/stack.c
rename to tests/unt/cmc/stack.h
index 8537d58..4efb1f4 100644
--- a/tests/main/unt/stack.c
+++ b/tests/unt/cmc/stack.h
@@ -1,17 +1,15 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_STACK_H
+#define CMC_TESTS_UNT_CMC_STACK_H
-#include "../src/stack.c"
+#include "../utl.h"
-struct stack_fval *s_fval = &(struct stack_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/stack.h"
-CMC_CREATE_UNIT(Stack, true, {
+struct stack_fval *s_fval = &(struct stack_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCStack, true, {
CMC_CREATE_TEST(new, {
struct stack *s = s_new(1000000, s_fval);
@@ -282,57 +280,57 @@ CMC_CREATE_UNIT(Stack, true, {
struct stack *s = s_new(100, s_fval);
cmc_assert_not_equals(ptr, NULL, s);
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
// clear
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
s_clear(s);
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
// customize
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
s_customize(s, NULL, NULL);
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
// push
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
cmc_assert(s_push(s, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
// pop
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
cmc_assert(s_pop(s));
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
cmc_assert(!s_pop(s));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s));
// top
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
s_top(s);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, s_flag(s));
cmc_assert(s_push(s, 1));
s_top(s);
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
// contains
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
cmc_assert(s_contains(s, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
// copy_of
- s->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
struct stack *s2 = s_copy_of(s);
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2));
// equals
- s->flag = cmc_flags.ERROR;
- s2->flag = cmc_flags.ERROR;
+ s->flag = CMC_FLAG_ERROR;
+ s2->flag = CMC_FLAG_ERROR;
cmc_assert(s_equals(s, s2));
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s));
- cmc_assert_equals(int32_t, cmc_flags.OK, s_flag(s2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, s_flag(s2));
s_free(s);
s_free(s2);
@@ -405,7 +403,7 @@ CMC_CREATE_UNIT(Stack, true, {
});
});
-CMC_CREATE_UNIT(StackIter, true, {
+CMC_CREATE_UNIT(CMCStackIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct stack *s = s_new(100, s_fval);
@@ -836,16 +834,16 @@ CMC_CREATE_UNIT(StackIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = Stack() + StackIter();
+ int result = CMCStack() + CMCStackIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | Stack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCStack Suit : %-48s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_STACK_H */
diff --git a/tests/main/unt/treemap.c b/tests/unt/cmc/treemap.h
similarity index 82%
rename from tests/main/unt/treemap.c
rename to tests/unt/cmc/treemap.h
index 909224b..014ac02 100644
--- a/tests/main/unt/treemap.c
+++ b/tests/unt/cmc/treemap.h
@@ -1,24 +1,19 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_TREEMAP_H
+#define CMC_TESTS_UNT_CMC_TREEMAP_H
-#include "../src/treemap.c"
+#include "../utl.h"
-struct treemap_fkey *tm_fkey = &(struct treemap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/treemap.h"
-struct treemap_fval *tm_fval = &(struct treemap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+struct treemap_fkey *tm_fkey = &(struct treemap_fkey){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
-CMC_CREATE_UNIT(TreeMap, true, {
+struct treemap_fval *tm_fval = &(struct treemap_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCTreeMap, true, {
CMC_CREATE_TEST(new, {
struct treemap *map = tm_new(tm_fkey, tm_fval);
@@ -49,90 +44,90 @@ CMC_CREATE_UNIT(TreeMap, true, {
struct treemap *map = tm_new(tm_fkey, tm_fval);
cmc_assert_not_equals(ptr, NULL, map);
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
// clear
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
tm_clear(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
// insert
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(tm_insert(map, 1, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
cmc_assert(!tm_insert(map, 1, 2));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, tm_flag(map));
// update
cmc_assert(!tm_update(map, 2, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map));
cmc_assert(tm_update(map, 1, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
// remove
cmc_assert(!tm_remove(map, 2, NULL));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map));
cmc_assert(tm_remove(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
cmc_assert(!tm_remove(map, 1, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map));
// max min
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!tm_max(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(!tm_min(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map));
cmc_assert(tm_insert(map, 1, 1));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(tm_max(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
cmc_assert(tm_min(map, NULL, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
// get get_ref
tm_get(map, 2);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map));
tm_get(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
tm_get_ref(map, 2);
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, tm_flag(map));
tm_get_ref(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
cmc_assert(tm_remove(map, 1, NULL));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
tm_get(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map));
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
tm_get_ref(map, 1);
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, tm_flag(map));
// copy_of
- map->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
struct treemap *map2 = tm_copy_of(map);
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map2));
// equals
- map->flag = cmc_flags.ERROR;
- map2->flag = cmc_flags.ERROR;
+ map->flag = CMC_FLAG_ERROR;
+ map2->flag = CMC_FLAG_ERROR;
cmc_assert(tm_equals(map, map2));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map));
- cmc_assert_equals(int32_t, cmc_flags.OK, tm_flag(map2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, tm_flag(map2));
tm_free(map);
tm_free(map2);
@@ -213,7 +208,7 @@ CMC_CREATE_UNIT(TreeMap, true, {
});
});
-CMC_CREATE_UNIT(TreeMapIter, true, {
+CMC_CREATE_UNIT(CMCTreeMapIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct treemap *map = tm_new(tm_fkey, tm_fval);
@@ -657,16 +652,16 @@ CMC_CREATE_UNIT(TreeMapIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = TreeMap() + TreeMapIter();
+ int result = CMCTreeMap() + CMCTreeMapIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | TreeMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCTreeMap Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_TREEMAP_H */
diff --git a/tests/main/unt/treeset.c b/tests/unt/cmc/treeset.h
similarity index 85%
rename from tests/main/unt/treeset.c
rename to tests/unt/cmc/treeset.h
index 46bc04e..46dddf6 100644
--- a/tests/main/unt/treeset.c
+++ b/tests/unt/cmc/treeset.h
@@ -1,17 +1,15 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_CMC_TREESET_H
+#define CMC_TESTS_UNT_CMC_TREESET_H
-#include "../src/treeset.c"
+#include "../utl.h"
-struct treeset_fval *ts_fval = &(struct treeset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp };
+#include "cmc/treeset.h"
-CMC_CREATE_UNIT(TreeSet, true, {
+struct treeset_fval *ts_fval = &(struct treeset_fval){
+ .cmp = cmc_size_cmp, .cpy = NULL, .str = cmc_size_str, .free = NULL, .hash = cmc_size_hash, .pri = cmc_size_cmp
+};
+
+CMC_CREATE_UNIT(CMCTreeSet, true, {
CMC_CREATE_TEST(new, {
struct treeset *set = ts_new(ts_fval);
@@ -42,61 +40,61 @@ CMC_CREATE_UNIT(TreeSet, true, {
struct treeset *set = ts_new(ts_fval);
cmc_assert_not_equals(ptr, NULL, set);
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
// clear
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
ts_clear(set);
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
// insert
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(ts_insert(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
cmc_assert(!ts_insert(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_DUPLICATE, ts_flag(set));
// remove
cmc_assert(!ts_remove(set, 2));
- cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_NOT_FOUND, ts_flag(set));
cmc_assert(ts_remove(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
cmc_assert(!ts_remove(set, 1));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set));
// max min
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(!ts_max(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(!ts_min(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.EMPTY, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_EMPTY, ts_flag(set));
cmc_assert(ts_insert(set, 1));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(ts_max(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
cmc_assert(ts_min(set, NULL));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
// copy_of
- set->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
struct treeset *set2 = ts_copy_of(set);
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set2));
// equals
- set->flag = cmc_flags.ERROR;
- set2->flag = cmc_flags.ERROR;
+ set->flag = CMC_FLAG_ERROR;
+ set2->flag = CMC_FLAG_ERROR;
cmc_assert(ts_equals(set, set2));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set));
- cmc_assert_equals(int32_t, cmc_flags.OK, ts_flag(set2));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set));
+ cmc_assert_equals(int32_t, CMC_FLAG_OK, ts_flag(set2));
ts_free(set);
ts_free(set2);
@@ -165,7 +163,7 @@ CMC_CREATE_UNIT(TreeSet, true, {
});
});
-CMC_CREATE_UNIT(TreeSetIter, true, {
+CMC_CREATE_UNIT(CMCTreeSetIter, true, {
CMC_CREATE_TEST(PFX##_iter_start(), {
struct treeset *set = ts_new(ts_fval);
@@ -572,16 +570,16 @@ CMC_CREATE_UNIT(TreeSetIter, true, {
#ifdef CMC_TEST_MAIN
int main(void)
{
- int result = TreeSet() + TreeSetIter();
+ int result = CMCTreeSet() + CMCTreeSetIter();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
- printf(" | TreeSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" | CMCTreeSet Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_CMC_TREESET_H */
diff --git a/tests/main/unt/utl.c b/tests/unt/utl.h
similarity index 77%
rename from tests/main/unt/utl.c
rename to tests/unt/utl.h
index 84cc860..9835ae9 100644
--- a/tests/main/unt/utl.c
+++ b/tests/unt/utl.h
@@ -1,13 +1,16 @@
/* Utility file to be included in the unit tests */
-#ifndef CMC_UNIT_TEST_UTL__
-#define CMC_UNIT_TEST_UTL__
+#ifndef CMC_TESTS_UTL
+#define CMC_TESTS_UTL
#include
#include
#include
#include "cor/hashtable.h"
+#include "utl/assert.h"
+#include "utl/foreach.h"
#include "utl/futils.h"
+#include "utl/test.h"
size_t numhash(size_t a)
{
@@ -16,16 +19,19 @@ size_t numhash(size_t a)
size_t hashcapminus1(size_t a)
{
+ (void)a;
return cmc_hashtable_primes[0] - 1;
}
size_t hashcapminus4(size_t a)
{
+ (void)a;
return cmc_hashtable_primes[0] - 1;
}
size_t hash0(size_t a)
{
+ (void)a;
return 0;
}
@@ -65,6 +71,7 @@ bool k_c_str(FILE *fptr, size_t a)
void k_c_free(size_t a)
{
+ (void)a;
k_total_free++;
}
@@ -103,6 +110,7 @@ bool v_c_str(FILE *fptr, size_t a)
void v_c_free(size_t a)
{
+ (void)a;
v_total_free++;
}
@@ -154,11 +162,10 @@ void callback_resize(void)
total_resize++;
}
-struct cmc_callbacks *callbacks =
- &(struct cmc_callbacks){ .create = callback_create,
- .read = callback_read,
- .update = callback_update,
- .delete = callback_delete,
- .resize = callback_resize };
+struct cmc_callbacks *callbacks = &(struct cmc_callbacks){ .create = callback_create,
+ .read = callback_read,
+ .update = callback_update,
+ .delete = callback_delete,
+ .resize = callback_resize };
-#endif /* CMC_UNIT_TEST_UTL__ */
+#endif /* CMC_TESTS_UTL */
diff --git a/tests/main/unt/foreach.c b/tests/unt/utl/foreach.h
similarity index 51%
rename from tests/main/unt/foreach.c
rename to tests/unt/utl/foreach.h
index de2d7f7..2336f99 100644
--- a/tests/main/unt/foreach.c
+++ b/tests/unt/utl/foreach.h
@@ -1,25 +1,24 @@
-#include "utl.c"
-#include "utl/assert.h"
-#include "utl/test.h"
+#ifndef CMC_TESTS_UNT_UTL_FOREACH_H
+#define CMC_TESTS_UNT_UTL_FOREACH_H
-#include "utl/foreach.h"
+#include "../utl.h"
-#include "../src/bitset.c"
-#include "../src/deque.c"
-#include "../src/hashbidimap.c"
-#include "../src/hashmap.c"
-#include "../src/hashmultimap.c"
-#include "../src/hashmultiset.c"
-#include "../src/hashset.c"
-#include "../src/heap.c"
-#include "../src/intervalheap.c"
-#include "../src/linkedlist.c"
-#include "../src/list.c"
-#include "../src/queue.c"
-#include "../src/sortedlist.c"
-#include "../src/stack.c"
-#include "../src/treemap.c"
-#include "../src/treeset.c"
+#include "cmc/bitset.h"
+#include "cmc/deque.h"
+#include "cmc/hashbidimap.h"
+#include "cmc/hashmap.h"
+#include "cmc/hashmultimap.h"
+#include "cmc/hashmultiset.h"
+#include "cmc/hashset.h"
+#include "cmc/heap.h"
+#include "cmc/intervalheap.h"
+#include "cmc/linkedlist.h"
+#include "cmc/list.h"
+#include "cmc/queue.h"
+#include "cmc/sortedlist.h"
+#include "cmc/stack.h"
+#include "cmc/treemap.h"
+#include "cmc/treeset.h"
CMC_CREATE_UNIT(ForEach, true, {
// CMC_CREATE_TEST(CMC, {
@@ -31,13 +30,12 @@ CMC_CREATE_UNIT(ForEach, true, {
// });
CMC_CREATE_TEST(CMC, {
- struct deque *d =
- d_new(10000, &(struct deque_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct deque *d = d_new(10000, &(struct deque_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
d_push_back(d, i);
@@ -81,20 +79,19 @@ CMC_CREATE_UNIT(ForEach, true, {
// });
CMC_CREATE_TEST(CMC, {
- struct hashmap *hm =
- hm_new(10000, 0.6,
- &(struct hashmap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp },
- &(struct hashmap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct hashmap *hm = hm_new(10000, 0.6,
+ &(struct hashmap_fkey){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp },
+ &(struct hashmap_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
hm_insert(hm, i, i);
@@ -123,20 +120,19 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct hashmultimap *hmm =
- hmm_new(10000, 0.6,
- &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp },
- &(struct hashmultimap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct hashmultimap *hmm = hmm_new(10000, 0.6,
+ &(struct hashmultimap_fkey){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp },
+ &(struct hashmultimap_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
hmm_insert(hmm, i, i);
@@ -165,14 +161,13 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct hashmultiset *hms =
- hms_new(10000, 0.6,
- &(struct hashmultiset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct hashmultiset *hms = hms_new(10000, 0.6,
+ &(struct hashmultiset_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
hms_insert_many(hms, i, i);
@@ -201,14 +196,13 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct hashset *hs =
- hs_new(10000, 0.6,
- &(struct hashset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct hashset *hs = hs_new(10000, 0.6,
+ &(struct hashset_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
hs_insert(hs, i);
@@ -231,7 +225,7 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct heap *h = h_new(10000, cmc_max_heap,
+ struct heap *h = h_new(10000, CMC_MAX_HEAP,
&(struct heap_fval){ .cmp = cmc_size_cmp,
.cpy = NULL,
.str = cmc_size_str,
@@ -260,13 +254,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct intervalheap *ih =
- ih_new(10000, &(struct intervalheap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct intervalheap *ih = ih_new(10000, &(struct intervalheap_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
ih_insert(ih, i);
@@ -289,13 +282,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct linkedlist *ll =
- ll_new(&(struct linkedlist_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct linkedlist *ll = ll_new(&(struct linkedlist_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
ll_push_back(ll, i);
@@ -318,13 +310,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct list *l =
- l_new(10000, &(struct list_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct list *l = l_new(10000, &(struct list_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
l_push_back(l, i);
@@ -347,13 +338,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct queue *q =
- q_new(10000, &(struct queue_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct queue *q = q_new(10000, &(struct queue_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
q_enqueue(q, i);
@@ -376,13 +366,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct sortedlist *sl =
- sl_new(10000, &(struct sortedlist_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct sortedlist *sl = sl_new(10000, &(struct sortedlist_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
sl_insert(sl, i);
@@ -405,13 +394,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct stack *s =
- s_new(10000, &(struct stack_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct stack *s = s_new(10000, &(struct stack_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
s_push(s, i);
@@ -434,19 +422,18 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct treemap *tm =
- tm_new(&(struct treemap_fkey){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp },
- &(struct treemap_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct treemap *tm = tm_new(&(struct treemap_fkey){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp },
+ &(struct treemap_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
tm_insert(tm, i, i);
@@ -475,13 +462,12 @@ CMC_CREATE_UNIT(ForEach, true, {
});
CMC_CREATE_TEST(CMC, {
- struct treeset *ts =
- ts_new(&(struct treeset_fval){ .cmp = cmc_size_cmp,
- .cpy = NULL,
- .str = cmc_size_str,
- .free = NULL,
- .hash = cmc_size_hash,
- .pri = cmc_size_cmp });
+ struct treeset *ts = ts_new(&(struct treeset_fval){ .cmp = cmc_size_cmp,
+ .cpy = NULL,
+ .str = cmc_size_str,
+ .free = NULL,
+ .hash = cmc_size_hash,
+ .pri = cmc_size_cmp });
for (size_t i = 1; i <= 10000; i++)
ts_insert(ts, i);
@@ -509,14 +495,14 @@ int main(void)
{
int result = ForEach();
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n");
printf(" | ForEach Suit : %-46s |\n", result == 0 ? "PASSED" : "FAILED");
- printf(
- " +---------------------------------------------------------------+");
+ printf(" +---------------------------------------------------------------+");
printf("\n\n\n");
return result;
}
#endif
+
+#endif /* CMC_TESTS_UNT_UTL_FOREACH_H */