Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
191c47fc7c | ||
|
|
f2f806612f | ||
|
|
5e2e001265 | ||
|
|
2ca2210a77 | ||
|
|
747aa8cb4e | ||
|
|
4fe4e96811 | ||
|
|
0df0ebbdeb | ||
|
|
e834aaee81 | ||
|
|
1928fdd6d5 | ||
|
|
abdbfa2018 | ||
|
|
a1a940399a | ||
|
|
855e085996 | ||
|
|
e95379bdd7 | ||
|
|
762b95db26 | ||
|
|
396066f289 | ||
|
|
f070d274f4 | ||
|
|
1f50add1bb | ||
|
|
e68b8a8e0e | ||
|
|
5ee7bfa23a | ||
|
|
8ec768d30e | ||
|
|
35d27ffb39 | ||
|
|
613392ae76 |
No files matched your search
+2
-2
@@ -13,8 +13,8 @@ script:
|
||||
- sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc
|
||||
- export CC=gcc-7
|
||||
- cd ./tests
|
||||
- make --always-make
|
||||
- make
|
||||
- cd ./main
|
||||
- make --always-make
|
||||
- make
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
@@ -1,5 +1,29 @@
|
||||
# RELEASE.MAJOR.MINOR
|
||||
|
||||
1.7.0
|
||||
- Removed FMOD (function modifier)
|
||||
- Added CMC prefix to all macros defined within the library
|
||||
|
||||
1.6.3
|
||||
- Added iterator functions to all collections:
|
||||
- iter_advance
|
||||
- iter_rewind
|
||||
- iter_go_to
|
||||
- Added cmc prefix to the logging utility
|
||||
- Integrated the assert utility with the test utility. Now any assertion that fails inside the unit test will trigger failure and is no longer needed to manually pass or fail tests.
|
||||
|
||||
1.6.2
|
||||
Added new functions to all collections:
|
||||
- copy_of
|
||||
- equals
|
||||
Added the new collections to the tests
|
||||
Fixed some collections and some improvements to the hashtables
|
||||
Unified the functions set and update from the map implementations
|
||||
|
||||
1.6.1
|
||||
Removed ./ext/linkedqueue.h
|
||||
Added a deallocator parameter to all _free and _clear functions
|
||||
|
||||
1.6.0
|
||||
Added ./ext/intervalheap.h
|
||||
Added ./ext/multimap.h
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
# C-Macro-Collections
|
||||
|
||||
Generate Simple Data Structures of any type in C for you to use in your projects.
|
||||
Header only, macro generated, generic and type-safe Collections in C.
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://travis-ci.org/LeoVen/C-Macro-Collections)
|
||||
[](https://codecov.io/gh/LeoVen/C-Macro-Collections)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* Project Structure
|
||||
* Available Collections
|
||||
* Overall To-Do
|
||||
* Design Decisions
|
||||
* What to Use
|
||||
* How to Use
|
||||
|
||||
## Project Structure
|
||||
|
||||
* __benchmarks__ - Where all benchmarks are hosted
|
||||
@@ -15,13 +24,11 @@ Generate Simple Data Structures of any type in C for you to use in your projects
|
||||
* __cmc__ - The main C Macro Collections Library
|
||||
* __dev__ - The main C Macro Collections Library for development (containing logging)
|
||||
* __ext__ - Extra collections
|
||||
* __sac__ - Stack Allocated Collections
|
||||
* __sac__ - Statically Allocated Collections
|
||||
* __utl__ - Utility like ForEach macros, logging, etc
|
||||
* __macro\_collections.h__ - Master header containing all collections and utilities
|
||||
* __tests__ - Where all tests are hosted
|
||||
|
||||
Only Collections located in __cmc__ are to be documented at *Documentation.md*.
|
||||
|
||||
## Available Collections
|
||||
|
||||
* Main C Macro Collections Library
|
||||
@@ -37,16 +44,25 @@ Only Collections located in __cmc__ are to be documented at *Documentation.md*.
|
||||
* TreeSet
|
||||
* Extra Collections Library
|
||||
* IntervalHeap
|
||||
* LinkedQueue
|
||||
* MultiMap
|
||||
* MultiSet
|
||||
* Stack Allocated Collections Library
|
||||
* Statically Allocated Collections Library
|
||||
* Queue
|
||||
* Stack
|
||||
* Development Collections Library
|
||||
* Deque
|
||||
|
||||
Check out **Documentation.md** for more information about each collection.
|
||||
Check out **Documentation.md** for more information about each collection. The documentation is still being written.
|
||||
|
||||
## 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 (all those included in `cmc` and `ext`);
|
||||
* Reorganize and complete all tests for `cmc` and `ext`;
|
||||
* 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`.
|
||||
|
||||
## Design Decisions
|
||||
|
||||
@@ -124,7 +140,6 @@ When including `macro_collections.h` in your source code you gain access to a ma
|
||||
* __C__ - Container name in uppercase (*LIST*, *LINKEDLIST*, *STACK*, *QUEUE*, *DEQUE*, *HEAP*, *TREESET*, *TREEMAP*, *HASHSET*, *HASHMAP*).
|
||||
* __PFX__ - Functions prefix or namespace.
|
||||
* __SNAME__ - Structure name (`typedef struct SNAME##_s SNAME`).
|
||||
* __FMOD__ - Function modifier (`static` or empty).
|
||||
* \*__K__ - Key type. Only used in *HASHMAP* and *TREEMAP*; ignored by others.
|
||||
* __V__ - Value type. Primary type for most collections, or value to be mapped by *HASHMAP* and *TREEMAP*.
|
||||
|
||||
|
||||
@@ -4,43 +4,37 @@ TODO
|
||||
[X] - Finished
|
||||
[~] - Needs to be reviewed
|
||||
|
||||
[ ] Future possible Collections
|
||||
[ ] Add TreeHashMap
|
||||
[ ] Add SortedList
|
||||
[ ] Add BiDiMap
|
||||
[ ] Add Trie (or any variant)
|
||||
|
||||
[/] Documentation
|
||||
[X] Remove PUBLIC and PRIVATE
|
||||
[ ] Extra Collections
|
||||
[X] Extra Collections
|
||||
[X] Add MultiSet
|
||||
[X] Add MultiMap
|
||||
[X] Add IntervalHeap
|
||||
[ ] Add TreeHashMap
|
||||
[ ] Add functions
|
||||
[X] update {hashmap, treemap, multimap}
|
||||
[/] to_string {all}
|
||||
[ ] iter_advance {all} (iterators)
|
||||
[ ] iter_rewind {all} (iterators)
|
||||
[ ] iter_go_to {all} (iterators)
|
||||
[X] set {hashmap, treemap, multimap}
|
||||
[X] to_string {all}
|
||||
[X] iter_advance {all} (iterators)
|
||||
[X] iter_rewind {all} (iterators)
|
||||
[X] iter_go_to {all} (iterators)
|
||||
[ ] from_array {all}
|
||||
[ ] to_array {all}
|
||||
[ ] equals {all}
|
||||
[X] equals {all}
|
||||
[X] copy_of {all}
|
||||
[ ] resize {dynamic arrays and circular buffers}
|
||||
[ ] dispose {all}
|
||||
[ ] copy_of {all}
|
||||
[ ] save {all} (serialization)
|
||||
[ ] load {all} (serialization)
|
||||
[ ] read {all} (serialization)
|
||||
[ ] write {all} (serialization)
|
||||
[ ] Range IO
|
||||
[ ] Sequences
|
||||
[ ] seq_push_front
|
||||
[ ] seq_push_at
|
||||
[ ] seq_push_back
|
||||
[ ] seq_remove
|
||||
[ ] seq_extract
|
||||
[ ] Others
|
||||
[ ] seq_insert
|
||||
[ ] seq_remove (attention on how to treat this)
|
||||
[ ] seq_extract (attention on how to treat this)
|
||||
[ ] Iterator IO
|
||||
[ ] range_insert
|
||||
[ ] range_remove
|
||||
[ ] Serialization
|
||||
[ ] save {all}
|
||||
[ ] load {all}
|
||||
[ ] serialize {all}
|
||||
[ ] deserialize {all}
|
||||
[ ] Add callback utility
|
||||
[ ] Zip Iterators
|
||||
[ ] Stack Allocated Collections
|
||||
[ ] Deque
|
||||
[ ] HashMap
|
||||
@@ -63,9 +57,9 @@ TODO
|
||||
[ ] Stack
|
||||
[ ] TreeMap
|
||||
[ ] TreeSet
|
||||
[X] Utility
|
||||
[X] assert.h
|
||||
[~] Utility
|
||||
[~] assert.h
|
||||
[X] foreach.h
|
||||
[X] log.h
|
||||
[X] test.h
|
||||
[~] log.h
|
||||
[~] test.h
|
||||
[X] timer.h
|
||||
@@ -154,7 +154,7 @@ COLLECTION_GENERATE(MULTISET, ms, mset, /* FMOD */, /* K */, int)
|
||||
timer_stop(total); \
|
||||
timer_calc(total); \
|
||||
\
|
||||
PFX##_free(coll); \
|
||||
PFX##_free(coll, NULL); \
|
||||
\
|
||||
double adj_search_time = (total.result - search_time) + (search_time * (double)NTOTAL) / (double)s; \
|
||||
double no_search = input_time + iter_time + output_time; \
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
__Check out the new documentation at__ https://leoven.github.io/C-Macro-Collections/
|
||||
|
||||
<span id="collections_index"> Collections Documentation </span>
|
||||
|
||||
* [Deque](#Deque)
|
||||
@@ -0,0 +1,247 @@
|
||||
THIS IS A SAFE COPY OF THE MARKDOWN FOR THE DOCUMENTATION LOCATED AT https://leoven.github.io/C-Macro-Collections/
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
title: CMC Documentation
|
||||
|
||||
toc_footers:
|
||||
- <a href='https://github.com/lord/slate'>Documentation Powered by Slate</a>
|
||||
|
||||
language_tabs:
|
||||
- C
|
||||
|
||||
search: true
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
[](https://github.com/LeoVen/C-Macro-Collections)
|
||||
|
||||

|
||||

|
||||
[](https://travis-ci.org/LeoVen/C-Macro-Collections)
|
||||
[](https://codecov.io/gh/LeoVen/C-Macro-Collections)
|
||||
|
||||
The C Macro Collections Library is a compilation of macros that can be used to generate common data structures for any desired type. These data structures are [type safe](https://en.wikipedia.org/wiki/Type_safety).
|
||||
|
||||
The documentation is currently being written in hopes that in the future it can be used to help you get to know better this amazing C library.
|
||||
|
||||
## Why this library
|
||||
|
||||
C is a low level language and lacks all the data structures that we commonly use. Many high level languages already come with these collections so that we don't have to implement everything ourselves. This is why the C Macro Collections Library was created.
|
||||
|
||||
The library currently provides many data structures, such as:
|
||||
|
||||
* Linear Collections
|
||||
* List, LinkedList, Deque, Stack, Queue
|
||||
* Sets
|
||||
* HashSet, TreeSet, MultiSet
|
||||
* Maps
|
||||
* HashMap, TreeMap, MultiMap
|
||||
* Heaps
|
||||
* Heap, IntervalHeap
|
||||
|
||||
All with the following features:
|
||||
|
||||
* __Type-safe__ - No `void *` pointers are used. A collection of type `int` will only accept integers;
|
||||
* __Customization__ - Custom struct name and function namespace;
|
||||
* __Bidirectional Iterators__ - Full support for iterators;
|
||||
* __Nesting__ - Collections can be nested (List of Lists, HashSet of Stacks, etc).
|
||||
|
||||
## Library Structure
|
||||
|
||||
The `src` folder is subdivided in 5 other folders and one file:
|
||||
|
||||
> The `dev` folder is an exact copy of `cmc` but it is filled with logging information regarding the code execution and debugging.
|
||||
|
||||
> The `sac` library contains fixed-length collections with an internal C array.
|
||||
|
||||
* __cmc__ - The main C Macro Collections Library
|
||||
* __dev__ - The main C Macro Collections Library for development
|
||||
* __ext__ - Extra collections
|
||||
* __sac__ - Statically Allocated Collections
|
||||
* __utl__ - Utility like ForEach macros, logging, etc
|
||||
* __macro\_collections.h__ - Master header containing all collections and utilities
|
||||
|
||||
## How to install
|
||||
|
||||
> Include header files like this
|
||||
|
||||
```c
|
||||
#include <cmc/list.h>
|
||||
#include <dev/deque.h>
|
||||
#include <utl/assert.h>
|
||||
```
|
||||
> Not like this
|
||||
|
||||
```c
|
||||
#include <list.h>
|
||||
#include <deque.h> // dev or cmc?
|
||||
#include <assert.h> // this will import from the standard library
|
||||
```
|
||||
|
||||
No installation is required. All you have to do is include the appropriate header files, generate any collections that you desire and then compile your program. It is recommended that you include the headers relative to the `src` folder and include it with `-I path/to/library/src` as shown in the following example.
|
||||
|
||||
The library has no external dependencies other than the C standard library.
|
||||
|
||||
## Minimal Example
|
||||
|
||||
Lets create a list of type `int`, add some elements to it and get the sum of all the elements printed on the screen.
|
||||
|
||||
### Include headers
|
||||
|
||||
```c
|
||||
#include <cmc/list.h>
|
||||
```
|
||||
|
||||
First you need to include only the necessary headers. It is not recommended that you include everything with `macro_collections.h`, only in cases where you might be using almost all features from the library.
|
||||
|
||||
### Generating a list
|
||||
|
||||
```c
|
||||
// CMC_GENERATE_LIST(PFX, SNAME, V)
|
||||
CMC_GENERATE_LIST(il, int_list, int)
|
||||
```
|
||||
|
||||
The List is also known as `vector`, `ArrayList` and dynamic array. In fact the latter is the best description for this collection. It is a dynamic array that can grow and shrink as needed. To generate it we can simply call the macro `CMC_GENERATE_LIST` after our includes. It has three parameters:
|
||||
|
||||
| Parameter name | Purpose |
|
||||
| :------------: | ------- |
|
||||
| __PFX__ | Functions prefix (namespace) |
|
||||
| __SNAME__ | Struct name |
|
||||
| __V__ | The list value type (can be any valid data type) |
|
||||
|
||||
<aside class="notice">
|
||||
All collections can be generated by using the macro CMC_GENERATE_ and then the name of the include (in this case list.h) but in uppercase without the `.h`.
|
||||
</aside>
|
||||
|
||||
### Initializing and adding elements
|
||||
|
||||
```c
|
||||
// Allocate an int_list with an initial capacity of 100
|
||||
int_list *list = il_new(100);
|
||||
|
||||
// Adding elements to the back of the list
|
||||
for (int i = 0; i <= 1000; i++)
|
||||
{
|
||||
if (!il_push_back(list, i))
|
||||
{
|
||||
// Something went wrong (check out documentation)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To initialize any collection we call a function `_new`. Since the `PFX` parameter is set to `il` all functions related to our list of integer will be prefixed by `il`, so `_new` becomes `il_new`.
|
||||
|
||||
The list name is `int_list` as defined by `SNAME`. This type is a typedef like:
|
||||
|
||||
`typedef struct SNAME##_s SNAME;`
|
||||
|
||||
Which expands to:
|
||||
|
||||
`typedef struct int_list_s int_list`
|
||||
|
||||
To add elements to the back of a list we can use `il_push_back`. This function will first check if the list has enough space for a new element. If not, reallocate the internal buffer with doubled size and then add the new element.
|
||||
|
||||
### Iteration
|
||||
|
||||
> It is recommended that the iterator is allocated on the stack
|
||||
|
||||
```c
|
||||
// Resulting sum will be stored here
|
||||
int sum = 0;
|
||||
|
||||
// Declare our iterator (allocating it on the stack)
|
||||
int_list_iter it;
|
||||
|
||||
// Loop for each element
|
||||
for (il_iter_init(&it, list); !il_iter_end(&it); il_iter_next(&it))
|
||||
{
|
||||
// Accessing the value
|
||||
int elem = il_iter_value(&it);
|
||||
|
||||
sum += elem;
|
||||
}
|
||||
|
||||
printf("%d\n", sum);
|
||||
```
|
||||
|
||||
There are 6 (2 optional) steps to iterate over the elements of any collection:
|
||||
|
||||
| Step | Description | Function |
|
||||
| :--: | ----------- | -------- |
|
||||
| 1 | Allocate the iterator (optional) | `il_iter_new` |
|
||||
| 2 | Initialize the iterator given a target list | `il_iter_init` |
|
||||
| 3 | Access the iterator's elements (value, index, etc) | `il_iter_value` |
|
||||
| 4 | Go to the next element | `il_iter_next` |
|
||||
| 5 | Check if we haven't reached the end of the list | `il_iter_end` |
|
||||
| 6 | Free the iterator if it was allocated on the heap | `il_iter_free` |
|
||||
|
||||
Note that all iterator functions are prefixed by the user defined prefix and then by `iter` (`il + iter = il_iter`). Also, the steps __1__ and __6__ are optional so `il_iter_new` and `il_iter_free` are not used in the example.
|
||||
|
||||
By the end of the example we have the variable `sum` with the sum of all integers inside our list. We can then print it and this example is almost done.
|
||||
|
||||
### Freeing resources
|
||||
|
||||
```c
|
||||
// void il_free(int_list *_list_, void(*deallocator)(int))
|
||||
il_free(list, NULL);
|
||||
```
|
||||
|
||||
The list is currently allocated in memory. To deallocate it we call `il_free`. This function takes a pointer to the allocated list and a pointer to a `deallocator` function that will be responsible for deallocating each element in the list. This last parameter is optional and we won't be using it since our data type `int` is not allocated in the heap. This optional parameter can be set to `NULL` to be ignored by the `il_free` function.
|
||||
|
||||
### Compile and run
|
||||
|
||||
> source.c
|
||||
|
||||
```c
|
||||
#include <cmc/list.h>
|
||||
|
||||
CMC_GENERATE_LIST(il, int_list, int)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int_list *list = il_new(100);
|
||||
|
||||
for (int i = 0; i <= 1000; i++)
|
||||
{
|
||||
if (!il_push_back(list, i))
|
||||
{
|
||||
// Something went wrong (check out documentation)
|
||||
}
|
||||
}
|
||||
|
||||
int sum = 0;
|
||||
|
||||
int_list_iter it;
|
||||
|
||||
for (il_iter_init(&it, list); !il_iter_end(&it); il_iter_next(&it))
|
||||
{
|
||||
int elem = il_iter_value(&it);
|
||||
sum += elem;
|
||||
}
|
||||
|
||||
printf("%d\n", sum);
|
||||
|
||||
il_free(list, NULL);
|
||||
}
|
||||
```
|
||||
|
||||
If the source file is `source.c`, all you have to do is to include the `src` folder to the include path and compile. The following example uses `gcc`:
|
||||
|
||||
`gcc source.c -I path/to/library/src`
|
||||
|
||||
### Conclusion
|
||||
|
||||
The C Macro Collections Library is prepared to accept any data type and is highly customizable. It is also very easy to integrate and no previous compilation is required. The library also comes with many utilities in the `utl` folder that are designed to work well with all collections.
|
||||
|
||||
# Upcoming
|
||||
|
||||
This documentation is still being written. Here is some of the things you will be able to find here:
|
||||
|
||||
* Full explanation about data structures
|
||||
* Full documentation about all current collections and others to come
|
||||
* Fully explained examples
|
||||
* Benchmark examples
|
||||
+537
-399
@@ -37,18 +37,18 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define DEQUE_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_DEQUE(PFX, SNAME, V) \
|
||||
CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define DEQUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_DEQUE_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define DEQUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
DEQUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_DEQUE_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define DEQUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_DEQUE_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Deque Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
@@ -98,49 +98,54 @@
|
||||
\
|
||||
/* 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_); \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_deque_, void (*deallocator)(V)); \
|
||||
/* 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_); \
|
||||
bool PFX##_push_front(SNAME *_deque_, V element); \
|
||||
bool PFX##_push_back(SNAME *_deque_, V element); \
|
||||
bool PFX##_pop_front(SNAME *_deque_); \
|
||||
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); \
|
||||
bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition); \
|
||||
bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition); \
|
||||
bool PFX##_pop_front_if(SNAME *_deque_, bool condition); \
|
||||
bool PFX##_pop_back_if(SNAME *_deque_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_front(SNAME *_deque_); \
|
||||
FMOD V PFX##_back(SNAME *_deque_); \
|
||||
V PFX##_front(SNAME *_deque_); \
|
||||
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_); \
|
||||
bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_deque_); \
|
||||
bool PFX##_full(SNAME *_deque_); \
|
||||
size_t PFX##_count(SNAME *_deque_); \
|
||||
size_t PFX##_capacity(SNAME *_deque_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_deque_); \
|
||||
SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_deque_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
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); \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
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); \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* 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); \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
@@ -153,366 +158,499 @@
|
||||
} \
|
||||
\
|
||||
/* 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) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_deque_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
\
|
||||
_deque_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_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; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_deque_) \
|
||||
{ \
|
||||
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
|
||||
\
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_deque_) \
|
||||
{ \
|
||||
free(_deque_->buffer); \
|
||||
free(_deque_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = element; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = element; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_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 (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
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_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *d_ = _deque_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, \
|
||||
name, d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
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->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; \
|
||||
} \
|
||||
\
|
||||
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) % (iter->target->capacity); \
|
||||
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) ? iter->target->capacity - 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 bool PFX##_impl_grow(SNAME *_deque_) \
|
||||
{ \
|
||||
size_t new_capacity = _deque_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_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; \
|
||||
#define CMC_GENERATE_DEQUE_SOURCE(PFX, SNAME, 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_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_deque_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_deque_) \
|
||||
return NULL; \
|
||||
\
|
||||
_deque_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_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; \
|
||||
\
|
||||
return _deque_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_deque_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_deque_->buffer, 0, sizeof(V) * _deque_->capacity); \
|
||||
\
|
||||
_deque_->count = 0; \
|
||||
_deque_->front = 0; \
|
||||
_deque_->back = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_deque_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_deque_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_deque_->buffer); \
|
||||
free(_deque_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_front(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->front = (_deque_->front == 0) ? _deque_->capacity - 1 : _deque_->front - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = element; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_back(SNAME *_deque_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_deque_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_deque_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = element; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == _deque_->capacity - 1) ? 0 : _deque_->back + 1; \
|
||||
\
|
||||
_deque_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->buffer[_deque_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->front = (_deque_->front == _deque_->capacity - 1) ? 0 : _deque_->front + 1; \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return false; \
|
||||
\
|
||||
_deque_->back = (_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1; \
|
||||
\
|
||||
_deque_->buffer[_deque_->back] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_deque_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_front_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_front(_deque_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_back_if(SNAME *_deque_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push_back(_deque_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_front_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_front(_deque_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_back_if(SNAME *_deque_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop_back(_deque_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V PFX##_front(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[_deque_->front]; \
|
||||
} \
|
||||
\
|
||||
V PFX##_back(SNAME *_deque_) \
|
||||
{ \
|
||||
if (PFX##_empty(_deque_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _deque_->buffer[(_deque_->back == 0) ? _deque_->capacity - 1 : _deque_->back - 1]; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_contains(SNAME *_deque_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count >= _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_deque_) \
|
||||
{ \
|
||||
return _deque_->capacity; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_deque_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_deque_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
result->buffer[j] = copy_func(_deque_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for (size_t i = _deque_->front, j = 0; j < _deque_->count; i = (i + 1) % _deque_->capacity, j++) \
|
||||
{ \
|
||||
result->buffer[j] = _deque_->buffer[i]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
result->count = _deque_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_deque1_, SNAME *_deque2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_deque1_) != PFX##_count(_deque2_)) \
|
||||
return false; \
|
||||
\
|
||||
size_t i, j, k; \
|
||||
for (i = _deque1_->front, j = _deque2_->front, k = 0; k < PFX##_count(_deque1_); k++) \
|
||||
{ \
|
||||
if (comparator(_deque1_->buffer[i], _deque2_->buffer[j]) == 0) \
|
||||
return false; \
|
||||
\
|
||||
i = (i + 1) % _deque1_->capacity; \
|
||||
j = (j + 1) % _deque2_->capacity; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_deque_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *d_ = _deque_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_deque, \
|
||||
name, d_, d_->buffer, d_->capacity, d_->count, d_->front, d_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
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); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
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); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->index = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = (iter->target->back == 0) ? iter->target->capacity - 1 : iter->target->back - 1; \
|
||||
iter->index = PFX##_count(iter->target) - 1; \
|
||||
} \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
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(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(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \
|
||||
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(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 += PFX##_capacity(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(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *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) \
|
||||
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 */
|
||||
+842
-673
File diff suppressed because it is too large.
Load diff
+947
-793
File diff suppressed because it is too large.
Load diff
+273
-145
@@ -42,115 +42,120 @@ typedef enum cmc_heap_order_e
|
||||
cmc_min_heap = -1
|
||||
} cmc_heap_order;
|
||||
|
||||
#define HEAP_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_HEAP(PFX, SNAME, V) \
|
||||
CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define HEAP_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_HEAP_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define HEAP_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_HEAP_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define HEAP_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* 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_e HO; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the heap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the heap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
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(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
FMOD void PFX##_clear(SNAME *_heap_); \
|
||||
FMOD void PFX##_free(SNAME *_heap_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_heap_); \
|
||||
FMOD V *PFX##_peek_ref(SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_heap_); \
|
||||
FMOD bool PFX##_full(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_count(SNAME *_heap_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_heap_); \
|
||||
\
|
||||
/* 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 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_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_HEAP_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Heap Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* 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_e HO; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the heap */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the heap */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Heap Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target heap */ \
|
||||
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 */ \
|
||||
SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)); \
|
||||
void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_heap_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_heap_, V element); \
|
||||
bool PFX##_remove(SNAME *_heap_, V *result); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_insert_if(SNAME *_heap_, V element, bool condition); \
|
||||
bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition); \
|
||||
/* Element Access */ \
|
||||
V PFX##_peek(SNAME *_heap_); \
|
||||
V *PFX##_peek_ref(SNAME *_heap_); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_heap_, V element); \
|
||||
bool PFX##_empty(SNAME *_heap_); \
|
||||
bool PFX##_full(SNAME *_heap_); \
|
||||
size_t PFX##_count(SNAME *_heap_); \
|
||||
size_t PFX##_capacity(SNAME *_heap_); \
|
||||
/* Collection Utility */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_); \
|
||||
cmc_string PFX##_to_string(SNAME *_heap_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
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 HEAP_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_HEAP_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_heap_); \
|
||||
@@ -159,7 +164,7 @@ typedef enum cmc_heap_order_e
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_heap_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_heap_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
SNAME *PFX##_new(size_t capacity, cmc_heap_order HO, int (*compare)(V, V)) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -193,20 +198,36 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_heap_) \
|
||||
void PFX##_clear(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
deallocator(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_heap_->buffer, 0, sizeof(V) * _heap_->capacity); \
|
||||
\
|
||||
_heap_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_heap_) \
|
||||
void PFX##_free(SNAME *_heap_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
deallocator(_heap_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_heap_->buffer); \
|
||||
free(_heap_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
bool PFX##_insert(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_heap_)) \
|
||||
{ \
|
||||
@@ -228,7 +249,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_heap_, V *result) \
|
||||
bool PFX##_remove(SNAME *_heap_, V *result) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return false; \
|
||||
@@ -245,7 +266,7 @@ typedef enum cmc_heap_order_e
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_heap_, V element, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_heap_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_heap_, element); \
|
||||
@@ -253,7 +274,7 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition) \
|
||||
bool PFX##_remove_if(SNAME *_heap_, V *result, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove(_heap_, result); \
|
||||
@@ -261,7 +282,7 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_heap_) \
|
||||
V PFX##_peek(SNAME *_heap_) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -269,7 +290,7 @@ typedef enum cmc_heap_order_e
|
||||
return _heap_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_peek_ref(SNAME *_heap_) \
|
||||
V *PFX##_peek_ref(SNAME *_heap_) \
|
||||
{ \
|
||||
if (PFX##_empty(_heap_)) \
|
||||
return NULL; \
|
||||
@@ -277,7 +298,7 @@ typedef enum cmc_heap_order_e
|
||||
return &(_heap_->buffer[0]); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
bool PFX##_contains(SNAME *_heap_, V element) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
{ \
|
||||
@@ -288,27 +309,61 @@ typedef enum cmc_heap_order_e
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_heap_) \
|
||||
bool PFX##_empty(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_heap_) \
|
||||
bool PFX##_full(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count >= _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_heap_) \
|
||||
size_t PFX##_count(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_heap_) \
|
||||
size_t PFX##_capacity(SNAME *_heap_) \
|
||||
{ \
|
||||
return _heap_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
SNAME *PFX##_copy_of(SNAME *_heap_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_heap_->capacity, _heap_->HO, _heap_->cmp); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _heap_->count; i++) \
|
||||
result->buffer[i] = copy_func(_heap_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _heap_->buffer, sizeof(V) * _heap_->count); \
|
||||
\
|
||||
result->count = _heap_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_heap1_, SNAME *_heap2_) \
|
||||
{ \
|
||||
if (PFX##_count(_heap1_) != PFX##_count(_heap2_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < PFX##_count(_heap1_); i++) \
|
||||
{ \
|
||||
if (_heap1_->cmp(_heap1_->buffer[i], _heap2_->buffer[i]) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_heap_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *h_ = _heap_; \
|
||||
@@ -321,7 +376,7 @@ typedef enum cmc_heap_order_e
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -333,12 +388,12 @@ typedef enum cmc_heap_order_e
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -346,61 +401,134 @@ typedef enum cmc_heap_order_e
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = PFX##_count(iter->target) - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = false; \
|
||||
\
|
||||
if (iter->cursor == iter->target->count - 1) \
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
else \
|
||||
iter->cursor++; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
iter->end = false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
else \
|
||||
iter->cursor--; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
iter->cursor += steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(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(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -408,7 +536,7 @@ typedef enum cmc_heap_order_e
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
|
||||
+886
-741
File diff suppressed because it is too large.
Load diff
+290
-169
@@ -49,132 +49,137 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define LIST_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
LIST_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_LIST(PFX, SNAME, V) \
|
||||
CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define LIST_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
LIST_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_LIST_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_LIST_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define LIST_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_LIST_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define LIST_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* List Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target list */ \
|
||||
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(size_t capacity); \
|
||||
FMOD SNAME *PFX##_new_from(V *elements, size_t size); \
|
||||
FMOD void PFX##_clear(SNAME *_list_); \
|
||||
FMOD void PFX##_free(SNAME *_list_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
FMOD bool PFX##_push(SNAME *_list_, V element, size_t index); \
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, V element); \
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_); \
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition); \
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \
|
||||
/* Collection Range Input and Output */ \
|
||||
FMOD bool PFX##_prepend(SNAME *_list_, V *elements, size_t size); \
|
||||
FMOD bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index); \
|
||||
FMOD bool PFX##_append(SNAME *_list_, V *elements, size_t size); \
|
||||
FMOD bool PFX##_remove(SNAME *_list_, size_t from, size_t to); \
|
||||
FMOD SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_front(SNAME *_list_); \
|
||||
FMOD V PFX##_get(SNAME *_list_, size_t index); \
|
||||
FMOD V *PFX##_get_ref(SNAME *_list_, size_t index); \
|
||||
FMOD V PFX##_back(SNAME *_list_); \
|
||||
FMOD size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_list_); \
|
||||
FMOD bool PFX##_full(SNAME *_list_); \
|
||||
FMOD size_t PFX##_count(SNAME *_list_); \
|
||||
FMOD bool PFX##_fits(SNAME *_list_, size_t size); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_list_); \
|
||||
\
|
||||
/* 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_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_LIST_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* List Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Dynamic array of elements */ \
|
||||
V *buffer; \
|
||||
\
|
||||
/* Current array capacity */ \
|
||||
size_t capacity; \
|
||||
\
|
||||
/* Current amount of elements */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the list */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* List Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target list */ \
|
||||
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 */ \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
SNAME *PFX##_new_from(V *elements, size_t size); \
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_push_front(SNAME *_list_, V element); \
|
||||
bool PFX##_push(SNAME *_list_, V element, size_t index); \
|
||||
bool PFX##_push_back(SNAME *_list_, V element); \
|
||||
bool PFX##_pop_front(SNAME *_list_); \
|
||||
bool PFX##_pop(SNAME *_list_, size_t index); \
|
||||
bool PFX##_pop_back(SNAME *_list_); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition); \
|
||||
bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition); \
|
||||
/* Collection Range Input and Output */ \
|
||||
bool PFX##_prepend(SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index); \
|
||||
bool PFX##_append(SNAME *_list_, V *elements, size_t size); \
|
||||
bool PFX##_remove(SNAME *_list_, size_t from, size_t to); \
|
||||
SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to); \
|
||||
/* Element Access */ \
|
||||
V PFX##_front(SNAME *_list_); \
|
||||
V PFX##_get(SNAME *_list_, size_t index); \
|
||||
V *PFX##_get_ref(SNAME *_list_, size_t index); \
|
||||
V PFX##_back(SNAME *_list_); \
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_list_); \
|
||||
bool PFX##_full(SNAME *_list_); \
|
||||
size_t PFX##_count(SNAME *_list_); \
|
||||
bool PFX##_fits(SNAME *_list_, size_t size); \
|
||||
size_t PFX##_capacity(SNAME *_list_); \
|
||||
/* Collection Utility */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_list_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
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 LIST_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_LIST_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_list_, size_t required); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_list_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_list_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
@@ -203,7 +208,7 @@
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_new_from(V *elements, size_t size) \
|
||||
SNAME *PFX##_new_from(V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return NULL; \
|
||||
@@ -220,20 +225,32 @@
|
||||
return _list_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_list_) \
|
||||
void PFX##_clear(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
deallocator(_list_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
memset(_list_->buffer, 0, sizeof(V) * _list_->capacity); \
|
||||
\
|
||||
_list_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_list_) \
|
||||
void PFX##_free(SNAME *_list_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
deallocator(_list_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
free(_list_->buffer); \
|
||||
free(_list_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_front(SNAME *_list_, V element) \
|
||||
bool PFX##_push_front(SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -253,7 +270,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_list_, V element, size_t index) \
|
||||
bool PFX##_push(SNAME *_list_, V element, size_t index) \
|
||||
{ \
|
||||
if (index > _list_->count) \
|
||||
return false; \
|
||||
@@ -282,7 +299,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_back(SNAME *_list_, V element) \
|
||||
bool PFX##_push_back(SNAME *_list_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_list_)) \
|
||||
{ \
|
||||
@@ -295,7 +312,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_front(SNAME *_list_) \
|
||||
bool PFX##_pop_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -307,7 +324,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
bool PFX##_pop(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -331,7 +348,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_back(SNAME *_list_) \
|
||||
bool PFX##_pop_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return false; \
|
||||
@@ -341,7 +358,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition) \
|
||||
bool PFX##_push_if(SNAME *_list_, V element, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_list_, element, index); \
|
||||
@@ -349,7 +366,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition) \
|
||||
bool PFX##_pop_if(SNAME *_list_, size_t index, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_list_, index); \
|
||||
@@ -357,7 +374,7 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_prepend(SNAME *_list_, V *elements, size_t size) \
|
||||
bool PFX##_prepend(SNAME *_list_, V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return false; \
|
||||
@@ -377,7 +394,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index) \
|
||||
bool PFX##_insert(SNAME *_list_, V *elements, size_t size, size_t index) \
|
||||
{ \
|
||||
if (size == 0 || index > _list_->count) \
|
||||
return false; \
|
||||
@@ -404,7 +421,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_append(SNAME *_list_, V *elements, size_t size) \
|
||||
bool PFX##_append(SNAME *_list_, V *elements, size_t size) \
|
||||
{ \
|
||||
if (size == 0) \
|
||||
return false; \
|
||||
@@ -422,7 +439,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_list_, size_t from, size_t to) \
|
||||
bool PFX##_remove(SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
@@ -438,7 +455,7 @@
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to) \
|
||||
SNAME *PFX##_extract(SNAME *_list_, size_t from, size_t to) \
|
||||
{ \
|
||||
if (from > to || to >= _list_->count) \
|
||||
return false; \
|
||||
@@ -459,7 +476,7 @@
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_front(SNAME *_list_) \
|
||||
V PFX##_front(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -467,7 +484,7 @@
|
||||
return _list_->buffer[0]; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_get(SNAME *_list_, size_t index) \
|
||||
V PFX##_get(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count || PFX##_empty(_list_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -475,7 +492,7 @@
|
||||
return _list_->buffer[index]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_get_ref(SNAME *_list_, size_t index) \
|
||||
V *PFX##_get_ref(SNAME *_list_, size_t index) \
|
||||
{ \
|
||||
if (index >= _list_->count) \
|
||||
return NULL; \
|
||||
@@ -486,7 +503,7 @@
|
||||
return &(_list_->buffer[index]); \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_back(SNAME *_list_) \
|
||||
V PFX##_back(SNAME *_list_) \
|
||||
{ \
|
||||
if (PFX##_empty(_list_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -494,7 +511,7 @@
|
||||
return _list_->buffer[_list_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \
|
||||
size_t PFX##_indexof(SNAME *_list_, V element, int (*comparator)(V, V), bool from_start) \
|
||||
{ \
|
||||
if (from_start) \
|
||||
{ \
|
||||
@@ -516,7 +533,7 @@
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
bool PFX##_contains(SNAME *_list_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
{ \
|
||||
@@ -527,32 +544,66 @@
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_list_) \
|
||||
bool PFX##_empty(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_full(SNAME *_list_) \
|
||||
bool PFX##_full(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count >= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_list_) \
|
||||
size_t PFX##_count(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_fits(SNAME *_list_, size_t size) \
|
||||
bool PFX##_fits(SNAME *_list_, size_t size) \
|
||||
{ \
|
||||
return _list_->count + size <= _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_list_) \
|
||||
size_t PFX##_capacity(SNAME *_list_) \
|
||||
{ \
|
||||
return _list_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_list_) \
|
||||
SNAME *PFX##_copy_of(SNAME *_list_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_list_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _list_->count; i++) \
|
||||
result->buffer[i] = copy_func(_list_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _list_->buffer, sizeof(V) * _list_->count); \
|
||||
\
|
||||
result->count = _list_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_list1_, SNAME *_list2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_list1_) != PFX##_count(_list2_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < PFX##_count(_list1_); i++) \
|
||||
{ \
|
||||
if (comparator(_list1_->buffer[i], _list2_->buffer[i]) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_list_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *l_ = _list_; \
|
||||
@@ -564,7 +615,7 @@
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -576,12 +627,12 @@
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
@@ -589,61 +640,131 @@
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->cursor = PFX##_empty(iter->target) ? 0 : iter->target->count - 1; \
|
||||
iter->end = true; \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->cursor = PFX##_empty(iter->target) ? 0 : iter->target->count - 1; \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->cursor == iter->target->count - 1) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
iter->cursor++; \
|
||||
iter->cursor++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
if (iter->cursor == 0) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
iter->cursor--; \
|
||||
iter->cursor--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(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 >= PFX##_count(iter->target)) \
|
||||
return false; \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
iter->cursor += steps; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_rewind(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(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -651,7 +772,7 @@
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
@@ -659,7 +780,7 @@
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->cursor; \
|
||||
} \
|
||||
|
||||
+472
-339
@@ -49,18 +49,18 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define QUEUE_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_QUEUE(PFX, SNAME, V) \
|
||||
CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define QUEUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_QUEUE_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define QUEUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_QUEUE_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define QUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_QUEUE_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Queue Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
@@ -110,44 +110,49 @@
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_queue_); \
|
||||
FMOD void PFX##_free(SNAME *_queue_); \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_queue_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_queue_); \
|
||||
bool PFX##_enqueue(SNAME *_queue_, V element); \
|
||||
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); \
|
||||
bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition); \
|
||||
bool PFX##_dequeue_if(SNAME *_queue_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_queue_); \
|
||||
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(SNAME *_queue_); \
|
||||
bool PFX##_contains(SNAME *_queue_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_queue_); \
|
||||
bool PFX##_full(SNAME *_queue_); \
|
||||
size_t PFX##_count(SNAME *_queue_); \
|
||||
size_t PFX##_capacity(SNAME *_queue_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_queue_); \
|
||||
SNAME *PFX##_copy_of(SNAME *_queue_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_queue1_, SNAME *_queue2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_queue_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
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); \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
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); \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* 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); \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
@@ -160,311 +165,439 @@
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define QUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_queue_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_queue_) \
|
||||
return NULL; \
|
||||
\
|
||||
_queue_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_queue_->buffer) \
|
||||
{ \
|
||||
free(_queue_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_queue_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_queue_->capacity = capacity; \
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
\
|
||||
_queue_->it_start = PFX##_impl_it_start; \
|
||||
_queue_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _queue_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_queue_) \
|
||||
{ \
|
||||
memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
|
||||
\
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_queue_) \
|
||||
{ \
|
||||
free(_queue_->buffer); \
|
||||
free(_queue_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue(SNAME *_queue_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_queue_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_queue_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_queue_->buffer[_queue_->back] = element; \
|
||||
\
|
||||
_queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 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 == _queue_->capacity - 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 >= _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_queue_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *q_ = _queue_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, \
|
||||
name, q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
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->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; \
|
||||
} \
|
||||
\
|
||||
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) % (iter->target->capacity); \
|
||||
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) ? iter->target->capacity - 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 bool PFX##_impl_grow(SNAME *_queue_) \
|
||||
{ \
|
||||
\
|
||||
size_t new_capacity = _queue_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
new_buffer[j] = _queue_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
free(_queue_->buffer); \
|
||||
\
|
||||
_queue_->buffer = new_buffer; \
|
||||
_queue_->capacity = new_capacity; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = _queue_->count; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
#define CMC_GENERATE_QUEUE_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_queue_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_queue_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_queue_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_queue_) \
|
||||
return NULL; \
|
||||
\
|
||||
_queue_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_queue_->buffer) \
|
||||
{ \
|
||||
free(_queue_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_queue_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_queue_->capacity = capacity; \
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
\
|
||||
_queue_->it_start = PFX##_impl_it_start; \
|
||||
_queue_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _queue_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_queue_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_queue_->buffer, 0, sizeof(V) * _queue_->capacity); \
|
||||
\
|
||||
_queue_->count = 0; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_queue_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
deallocator(_queue_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_queue_->buffer); \
|
||||
free(_queue_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_enqueue(SNAME *_queue_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_queue_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_queue_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_queue_->buffer[_queue_->back] = element; \
|
||||
\
|
||||
_queue_->back = (_queue_->back == _queue_->capacity - 1) ? 0 : _queue_->back + 1; \
|
||||
_queue_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_dequeue(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return false; \
|
||||
\
|
||||
_queue_->buffer[_queue_->front] = PFX##_impl_default_value(); \
|
||||
\
|
||||
_queue_->front = (_queue_->front == _queue_->capacity - 1) ? 0 : _queue_->front + 1; \
|
||||
_queue_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_enqueue_if(SNAME *_queue_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_enqueue(_queue_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_dequeue_if(SNAME *_queue_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_dequeue(_queue_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V PFX##_peek(SNAME *_queue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_queue_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _queue_->buffer[_queue_->front]; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count >= _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_queue_) \
|
||||
{ \
|
||||
return _queue_->capacity; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_queue_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_queue_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
result->buffer[j] = copy_func(_queue_->buffer[i]); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
result->buffer[j] = _queue_->buffer[i]; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
result->count = _queue_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_queue1_, SNAME *_queue2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_queue1_) != PFX##_count(_queue2_)) \
|
||||
return false; \
|
||||
\
|
||||
size_t i, j, k; \
|
||||
for (i = _queue1_->front, j = _queue2_->front, k = 0; k < PFX##_count(_queue1_); k++) \
|
||||
{ \
|
||||
if (comparator(_queue1_->buffer[i], _queue2_->buffer[j]) == 0) \
|
||||
return false; \
|
||||
\
|
||||
i = (i + 1) % _queue1_->capacity; \
|
||||
j = (j + 1) % _queue2_->capacity; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_queue_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *q_ = _queue_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_queue, \
|
||||
name, q_, q_->buffer, q_->capacity, q_->count, q_->front, q_->back); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
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); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
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); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *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; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
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(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(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \
|
||||
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(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 += PFX##_capacity(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(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_queue_) \
|
||||
{ \
|
||||
\
|
||||
size_t new_capacity = _queue_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = malloc(sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = _queue_->front, j = 0; j < _queue_->count; i = (i + 1) % _queue_->capacity, j++) \
|
||||
{ \
|
||||
new_buffer[j] = _queue_->buffer[i]; \
|
||||
} \
|
||||
\
|
||||
free(_queue_->buffer); \
|
||||
\
|
||||
_queue_->buffer = new_buffer; \
|
||||
_queue_->capacity = new_capacity; \
|
||||
_queue_->front = 0; \
|
||||
_queue_->back = _queue_->count; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
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_QUEUE_H */
|
||||
+431
-322
@@ -34,18 +34,18 @@
|
||||
#include <string.h>
|
||||
#include "../utl/cmc_string.h"
|
||||
|
||||
#define STACK_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_STACK(PFX, SNAME, V) \
|
||||
CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define STACK_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_STACK_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_STACK_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define STACK_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_STACK_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define STACK_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_STACK_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Stack Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
@@ -86,44 +86,49 @@
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity); \
|
||||
FMOD void PFX##_clear(SNAME *_stack_); \
|
||||
FMOD void PFX##_free(SNAME *_stack_); \
|
||||
SNAME *PFX##_new(size_t capacity); \
|
||||
void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_stack_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element); \
|
||||
FMOD bool PFX##_pop(SNAME *_stack_); \
|
||||
bool PFX##_push(SNAME *_stack_, V element); \
|
||||
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); \
|
||||
bool PFX##_push_if(SNAME *_stack_, V element, bool condition); \
|
||||
bool PFX##_pop_if(SNAME *_stack_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_top(SNAME *_stack_); \
|
||||
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(SNAME *_stack_); \
|
||||
bool PFX##_contains(SNAME *_stack_, V element, int (*comparator)(V, V)); \
|
||||
bool PFX##_empty(SNAME *_stack_); \
|
||||
bool PFX##_full(SNAME *_stack_); \
|
||||
size_t PFX##_count(SNAME *_stack_); \
|
||||
size_t PFX##_capacity(SNAME *_stack_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_stack_); \
|
||||
SNAME *PFX##_copy_of(SNAME *_stack_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_stack1_, SNAME *_stack2_, int (*comparator)(V, V)); \
|
||||
cmc_string PFX##_to_string(SNAME *_stack_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
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); \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
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); \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* 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); \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter); \
|
||||
\
|
||||
/* Default Value */ \
|
||||
static inline V PFX##_impl_default_value(void) \
|
||||
@@ -136,294 +141,398 @@
|
||||
} \
|
||||
\
|
||||
/* SOURCE ********************************************************************/
|
||||
#define STACK_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_stack_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_stack_->capacity = capacity; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
_stack_->it_start = PFX##_impl_it_start; \
|
||||
_stack_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_stack_) \
|
||||
{ \
|
||||
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
|
||||
\
|
||||
_stack_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_stack_) \
|
||||
{ \
|
||||
free(_stack_->buffer); \
|
||||
free(_stack_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_push(SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_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 >= _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_stack_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _stack_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, \
|
||||
name, s_, s_->buffer, s_->capacity, s_->count); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
\
|
||||
if (PFX##_empty(target)) \
|
||||
iter->cursor = 0; \
|
||||
else \
|
||||
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; \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
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; \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
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) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
\
|
||||
return iter->target->count - 1 - iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_stack_) \
|
||||
{ \
|
||||
size_t new_capacity = _stack_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = realloc(_stack_->buffer, sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer = new_buffer; \
|
||||
_stack_->capacity = new_capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
#define CMC_GENERATE_STACK_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static bool PFX##_impl_grow(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_stack_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_stack_); \
|
||||
\
|
||||
SNAME *PFX##_new(size_t capacity) \
|
||||
{ \
|
||||
if (capacity < 1) \
|
||||
return NULL; \
|
||||
\
|
||||
SNAME *_stack_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_stack_) \
|
||||
return NULL; \
|
||||
\
|
||||
_stack_->buffer = malloc(sizeof(V) * capacity); \
|
||||
\
|
||||
if (!_stack_->buffer) \
|
||||
{ \
|
||||
free(_stack_); \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * capacity); \
|
||||
\
|
||||
_stack_->capacity = capacity; \
|
||||
_stack_->count = 0; \
|
||||
\
|
||||
_stack_->it_start = PFX##_impl_it_start; \
|
||||
_stack_->it_end = PFX##_impl_it_end; \
|
||||
\
|
||||
return _stack_; \
|
||||
} \
|
||||
\
|
||||
void PFX##_clear(SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
deallocator(_stack_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
memset(_stack_->buffer, 0, sizeof(V) * _stack_->capacity); \
|
||||
\
|
||||
_stack_->count = 0; \
|
||||
} \
|
||||
\
|
||||
void PFX##_free(SNAME *_stack_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
free(_stack_->buffer); \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
deallocator(_stack_->buffer[i]); \
|
||||
} \
|
||||
\
|
||||
free(_stack_); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push(SNAME *_stack_, V element) \
|
||||
{ \
|
||||
if (PFX##_full(_stack_)) \
|
||||
{ \
|
||||
if (!PFX##_impl_grow(_stack_)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
_stack_->buffer[_stack_->count++] = element; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer[--_stack_->count] = PFX##_impl_default_value(); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_push_if(SNAME *_stack_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_push(_stack_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_pop_if(SNAME *_stack_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_pop(_stack_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
V PFX##_top(SNAME *_stack_) \
|
||||
{ \
|
||||
if (PFX##_empty(_stack_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _stack_->buffer[_stack_->count - 1]; \
|
||||
} \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_empty(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count == 0; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_full(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count >= _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_count(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->count; \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_capacity(SNAME *_stack_) \
|
||||
{ \
|
||||
return _stack_->capacity; \
|
||||
} \
|
||||
\
|
||||
SNAME *PFX##_copy_of(SNAME *_stack_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_stack_->capacity); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _stack_->count; i++) \
|
||||
result->buffer[i] = copy_func(_stack_->buffer[i]); \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _stack_->buffer, sizeof(V) * _stack_->count); \
|
||||
\
|
||||
result->count = _stack_->count; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_stack1_, SNAME *_stack2_, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
if (PFX##_count(_stack1_) != PFX##_count(_stack2_)) \
|
||||
return false; \
|
||||
\
|
||||
for (size_t i = 0; i < PFX##_count(_stack1_); i++) \
|
||||
{ \
|
||||
if (comparator(_stack1_->buffer[i], _stack2_->buffer[i]) != 0) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_stack_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _stack_; \
|
||||
const char *name = #SNAME; \
|
||||
\
|
||||
snprintf(str.s, cmc_string_len, cmc_string_fmt_stack, \
|
||||
name, s_, s_->buffer, s_->capacity, s_->count); \
|
||||
\
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = PFX##_empty(target) ? 0 : iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->target->count - 1; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = 0; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
bool PFX##_iter_next(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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
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(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(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->cursor + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->cursor + steps >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->target->buffer[iter->cursor]; \
|
||||
} \
|
||||
\
|
||||
V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->target->buffer[iter->cursor]); \
|
||||
} \
|
||||
\
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
\
|
||||
return iter->target->count - 1 - iter->cursor; \
|
||||
} \
|
||||
\
|
||||
static bool PFX##_impl_grow(SNAME *_stack_) \
|
||||
{ \
|
||||
size_t new_capacity = _stack_->capacity * 2; \
|
||||
\
|
||||
V *new_buffer = realloc(_stack_->buffer, sizeof(V) * new_capacity); \
|
||||
\
|
||||
if (!new_buffer) \
|
||||
return false; \
|
||||
\
|
||||
_stack_->buffer = new_buffer; \
|
||||
_stack_->capacity = new_capacity; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
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_STACK_H */
|
||||
+1020
-881
File diff suppressed because it is too large.
Load diff
+1052
-928
File diff suppressed because it is too large.
Load diff
+940
-804
File diff suppressed because it is too large.
Load diff
@@ -1,384 +0,0 @@
|
||||
/**
|
||||
* linkedqueue.h
|
||||
*
|
||||
* Creation Date: 21/06/2019
|
||||
*
|
||||
* Authors:
|
||||
* Leonardo Vencovsky (https://github.com/LeoVen)
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* A node-based Queue using a Singly Linked List
|
||||
*
|
||||
* enqueue : is equivalent to a push_back from a LinkedList
|
||||
* dequeue : is equivalent to a pop_front from a LinkedList
|
||||
*
|
||||
* This Queue has a one-way iterator
|
||||
*/
|
||||
|
||||
#ifndef CMC_LINKEDQUEUE_H
|
||||
#define CMC_LINKEDQUEUE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LINKEDQUEUE_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
LINKEDQUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
LINKEDQUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
|
||||
#define LINKEDQUEUE_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
LINKEDQUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
|
||||
#define LINKEDQUEUE_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
LINKEDQUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define LINKEDQUEUE_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Linked Queue Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* First node in the list */ \
|
||||
struct SNAME##_node_s *head; \
|
||||
\
|
||||
/* Last node in the list */ \
|
||||
struct SNAME##_node_s *tail; \
|
||||
\
|
||||
/* Current amount of elements in the list */ \
|
||||
size_t count; \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the list */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
/* Singly-linked list node */ \
|
||||
typedef struct SNAME##_node_s \
|
||||
{ \
|
||||
/* Node's data */ \
|
||||
V data; \
|
||||
\
|
||||
/* Pointer to the next node on the linked list */ \
|
||||
struct SNAME##_node_s *next; \
|
||||
\
|
||||
} SNAME##_node, *SNAME##_node_ptr; \
|
||||
\
|
||||
/* Linked Queue Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target Linked Queue */ \
|
||||
struct SNAME##_s *target; \
|
||||
\
|
||||
/* Cursor's current node */ \
|
||||
struct SNAME##_node_s *cursor; \
|
||||
\
|
||||
/* Keeps track of relative index to the iteration of elements */ \
|
||||
size_t index; \
|
||||
\
|
||||
/* If the iterator is at 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 *_lqueue_); \
|
||||
FMOD void PFX##_free(SNAME *_lqueue_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_enqueue(SNAME *_lqueue_, V element); \
|
||||
FMOD bool PFX##_dequeue(SNAME *_lqueue_); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_lqueue_, V element, bool condition); \
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_lqueue_, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD V PFX##_peek(SNAME *_lqueue_); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_lqueue_, V element, int (*comparator)(V, V)); \
|
||||
FMOD bool PFX##_empty(SNAME *_lqueue_); \
|
||||
FMOD size_t PFX##_count(SNAME *_lqueue_); \
|
||||
\
|
||||
/* 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); \
|
||||
/* 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 LINKEDQUEUE_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
FMOD SNAME##_node *PFX##_impl_new_node(V element); \
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_lqueue_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(void) \
|
||||
{ \
|
||||
SNAME *_lqueue_ = malloc(sizeof(SNAME)); \
|
||||
\
|
||||
if (!_lqueue_) \
|
||||
return NULL; \
|
||||
\
|
||||
_lqueue_->count = 0; \
|
||||
_lqueue_->head = NULL; \
|
||||
_lqueue_->tail = NULL; \
|
||||
\
|
||||
_lqueue_->it_start = PFX##_impl_it_start; \
|
||||
\
|
||||
return _lqueue_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_lqueue_) \
|
||||
{ \
|
||||
SNAME##_node *scan = _lqueue_->head; \
|
||||
\
|
||||
while (_lqueue_->head != NULL) \
|
||||
{ \
|
||||
_lqueue_->head = _lqueue_->head->next; \
|
||||
free(scan); \
|
||||
scan = _lqueue_->head; \
|
||||
} \
|
||||
\
|
||||
_lqueue_->count = 0; \
|
||||
_lqueue_->head = NULL; \
|
||||
_lqueue_->tail = NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_lqueue_) \
|
||||
{ \
|
||||
PFX##_clear(_lqueue_); \
|
||||
\
|
||||
free(_lqueue_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue(SNAME *_lqueue_, V element) \
|
||||
{ \
|
||||
SNAME##_node *_node_ = PFX##_impl_new_node(element); \
|
||||
\
|
||||
if (!_node_) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_empty(_lqueue_)) \
|
||||
{ \
|
||||
_lqueue_->head = _node_; \
|
||||
_lqueue_->tail = _node_; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_lqueue_->tail->next = _node_; \
|
||||
_lqueue_->tail = _node_; \
|
||||
} \
|
||||
\
|
||||
_lqueue_->count++; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue(SNAME *_lqueue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_lqueue_)) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_node *_node_ = _lqueue_->head; \
|
||||
_lqueue_->head = _lqueue_->head->next; \
|
||||
\
|
||||
free(_node_); \
|
||||
\
|
||||
if (_lqueue_->head == NULL) \
|
||||
_lqueue_->tail = NULL; \
|
||||
\
|
||||
_lqueue_->count--; \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_enqueue_if(SNAME *_lqueue_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_enqueue(_lqueue_, element); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_dequeue_if(SNAME *_lqueue_, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_dequeue(_lqueue_); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_peek(SNAME *_lqueue_) \
|
||||
{ \
|
||||
if (PFX##_empty(_lqueue_)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return _lqueue_->head->data; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_lqueue_, V element, int (*comparator)(V, V)) \
|
||||
{ \
|
||||
SNAME##_node *scan = _lqueue_->head; \
|
||||
\
|
||||
while (scan != NULL) \
|
||||
{ \
|
||||
if (comparator(scan->data, element) == 0) \
|
||||
return true; \
|
||||
\
|
||||
scan = scan->next; \
|
||||
} \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_lqueue_) \
|
||||
{ \
|
||||
return _lqueue_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_lqueue_) \
|
||||
{ \
|
||||
return _lqueue_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
if (!iter) \
|
||||
return NULL; \
|
||||
\
|
||||
PFX##_iter_init(iter, target); \
|
||||
\
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
iter->target = target; \
|
||||
iter->cursor = target->head; \
|
||||
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->head; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->target->tail; \
|
||||
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->cursor->next == NULL) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
{ \
|
||||
iter->cursor = iter->cursor->next; \
|
||||
iter->index++; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
\
|
||||
return iter->cursor->data; \
|
||||
} \
|
||||
\
|
||||
FMOD V *PFX##_iter_rvalue(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return NULL; \
|
||||
\
|
||||
return &(iter->cursor->data); \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_node *PFX##_impl_new_node(V element) \
|
||||
{ \
|
||||
SNAME##_node *_node_ = malloc(sizeof(SNAME##_node)); \
|
||||
\
|
||||
if (!_node_) \
|
||||
return NULL; \
|
||||
\
|
||||
_node_->data = element; \
|
||||
_node_->next = NULL; \
|
||||
\
|
||||
return _node_; \
|
||||
} \
|
||||
\
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_lqueue_) \
|
||||
{ \
|
||||
SNAME##_iter iter; \
|
||||
\
|
||||
PFX##_iter_init(&iter, _lqueue_); \
|
||||
PFX##_iter_to_start(&iter); \
|
||||
\
|
||||
return iter; \
|
||||
}
|
||||
|
||||
#endif /* CMC_LINKEDQUEUE_H */
|
||||
+1044
-826
File diff suppressed because it is too large.
Load diff
+397
-235
@@ -71,163 +71,168 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
|
||||
#endif /* CMC_HASH_TABLE_SETUP */
|
||||
|
||||
#define MULTISET_GENERATE(PFX, SNAME, FMOD, V) \
|
||||
MULTISET_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
MULTISET_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_GENERATE_MULTISET(PFX, SNAME, V) \
|
||||
CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V) \
|
||||
CMC_GENERATE_MULTISET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
#define MULTISET_WRAPGEN_HEADER(PFX, SNAME, FMOD, K, V) \
|
||||
MULTISET_GENERATE_HEADER(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_MULTISET_HEADER(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V)
|
||||
|
||||
#define MULTISET_WRAPGEN_SOURCE(PFX, SNAME, FMOD, K, V) \
|
||||
MULTISET_GENERATE_SOURCE(PFX, SNAME, FMOD, V)
|
||||
#define CMC_WRAPGEN_MULTISET_SOURCE(PFX, SNAME, K, V) \
|
||||
CMC_GENERATE_MULTISET_SOURCE(PFX, SNAME, V)
|
||||
|
||||
/* HEADER ********************************************************************/
|
||||
#define MULTISET_GENERATE_HEADER(PFX, SNAME, FMOD, V) \
|
||||
\
|
||||
/* Hashset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Array of Entries */ \
|
||||
struct SNAME##_entry_s *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; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Element hash function */ \
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
typedef struct SNAME##_entry_s \
|
||||
{ \
|
||||
/* 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_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
\
|
||||
/* Hashset Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target Hashset */ \
|
||||
struct SNAME##_s *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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)); \
|
||||
FMOD void PFX##_clear(SNAME *_set_); \
|
||||
FMOD void PFX##_free(SNAME *_set_); \
|
||||
/* Collection Input and Output */ \
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_insert_many(SNAME *_set_, V element, size_t count); \
|
||||
FMOD bool PFX##_update(SNAME *_set_, V element, size_t multiplicity); \
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element); \
|
||||
FMOD size_t PFX##_remove_all(SNAME *_set_, V element); \
|
||||
/* Conditional Input and Output */ \
|
||||
FMOD bool PFX##_insert_if(SNAME *_set_, V element, bool condition); \
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
/* Element Access */ \
|
||||
FMOD bool PFX##_max(SNAME *_set_, V *value); \
|
||||
FMOD bool PFX##_min(SNAME *_set_, V *value); \
|
||||
FMOD size_t PFX##_multiplicity_of(SNAME *_set_, V element); \
|
||||
/* Collection State */ \
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element); \
|
||||
FMOD bool PFX##_empty(SNAME *_set_); \
|
||||
FMOD size_t PFX##_count(SNAME *_set_); \
|
||||
FMOD size_t PFX##_cardinality(SNAME *_set_); \
|
||||
FMOD size_t PFX##_capacity(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
FMOD bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_); \
|
||||
\
|
||||
/* 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 size_t PFX##_iter_multiplicity(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_; \
|
||||
} \
|
||||
\
|
||||
#define CMC_GENERATE_MULTISET_HEADER(PFX, SNAME, V) \
|
||||
\
|
||||
/* Hashset Structure */ \
|
||||
typedef struct SNAME##_s \
|
||||
{ \
|
||||
/* Array of Entries */ \
|
||||
struct SNAME##_entry_s *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; \
|
||||
\
|
||||
/* Element comparison function */ \
|
||||
int (*cmp)(V, V); \
|
||||
\
|
||||
/* Element hash function */ \
|
||||
size_t (*hash)(V); \
|
||||
\
|
||||
/* Function that returns an iterator to the start of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_start)(struct SNAME##_s *); \
|
||||
\
|
||||
/* Function that returns an iterator to the end of the hashset */ \
|
||||
struct SNAME##_iter_s (*it_end)(struct SNAME##_s *); \
|
||||
\
|
||||
} SNAME, *SNAME##_ptr; \
|
||||
\
|
||||
typedef struct SNAME##_entry_s \
|
||||
{ \
|
||||
/* 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_e state; \
|
||||
\
|
||||
} SNAME##_entry, *SNAME##_entry_ptr; \
|
||||
\
|
||||
/* Hashset Iterator */ \
|
||||
typedef struct SNAME##_iter_s \
|
||||
{ \
|
||||
/* Target Hashset */ \
|
||||
struct SNAME##_s *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; \
|
||||
\
|
||||
} SNAME##_iter, *SNAME##_iter_ptr; \
|
||||
\
|
||||
/* Collection Functions */ \
|
||||
/* Collection Allocation and Deallocation */ \
|
||||
SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)); \
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)); \
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)); \
|
||||
/* Collection Input and Output */ \
|
||||
bool PFX##_insert(SNAME *_set_, V element); \
|
||||
bool PFX##_insert_many(SNAME *_set_, V element, size_t count); \
|
||||
bool PFX##_update(SNAME *_set_, V element, size_t multiplicity); \
|
||||
bool PFX##_remove(SNAME *_set_, V element); \
|
||||
size_t PFX##_remove_all(SNAME *_set_, V element); \
|
||||
/* Conditional Input and Output */ \
|
||||
bool PFX##_insert_if(SNAME *_set_, V element, bool condition); \
|
||||
bool PFX##_remove_if(SNAME *_set_, V element, bool condition); \
|
||||
/* Element Access */ \
|
||||
bool PFX##_max(SNAME *_set_, V *value); \
|
||||
bool PFX##_min(SNAME *_set_, V *value); \
|
||||
size_t PFX##_multiplicity_of(SNAME *_set_, V element); \
|
||||
/* Collection State */ \
|
||||
bool PFX##_contains(SNAME *_set_, V element); \
|
||||
bool PFX##_empty(SNAME *_set_); \
|
||||
size_t PFX##_count(SNAME *_set_); \
|
||||
size_t PFX##_cardinality(SNAME *_set_); \
|
||||
size_t PFX##_capacity(SNAME *_set_); \
|
||||
/* Collection Utility */ \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)); \
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity); \
|
||||
cmc_string PFX##_to_string(SNAME *_set_); \
|
||||
\
|
||||
/* Set Operations */ \
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_); \
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_); \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_); \
|
||||
\
|
||||
/* Iterator Functions */ \
|
||||
/* Iterator Allocation and Deallocation */ \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target); \
|
||||
void PFX##_iter_free(SNAME##_iter *iter); \
|
||||
/* Iterator Initialization */ \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target); \
|
||||
/* Iterator State */ \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter); \
|
||||
/* Iterator Movement */ \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter); \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter); \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_rewind(SNAME##_iter *iter, size_t steps); \
|
||||
bool PFX##_iter_go_to(SNAME##_iter *iter, size_t index); \
|
||||
/* Iterator Access */ \
|
||||
V PFX##_iter_value(SNAME##_iter *iter); \
|
||||
size_t PFX##_iter_multiplicity(SNAME##_iter *iter); \
|
||||
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 MULTISET_GENERATE_SOURCE(PFX, SNAME, FMOD, V) \
|
||||
#define CMC_GENERATE_MULTISET_SOURCE(PFX, SNAME, V) \
|
||||
\
|
||||
/* Implementation Detail Functions */ \
|
||||
static SNAME##_entry *PFX##_impl_insert_and_return(SNAME *_set_, V element, bool *new_node); \
|
||||
@@ -237,7 +242,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
static SNAME##_iter PFX##_impl_it_start(SNAME *_set_); \
|
||||
static SNAME##_iter PFX##_impl_it_end(SNAME *_set_); \
|
||||
\
|
||||
FMOD SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)) \
|
||||
SNAME *PFX##_new(size_t capacity, double load, int (*compare)(V, V), size_t (*hash)(V)) \
|
||||
{ \
|
||||
if (capacity == 0 || load <= 0 || load >= 1) \
|
||||
return NULL; \
|
||||
@@ -276,20 +281,46 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_clear(SNAME *_set_) \
|
||||
void PFX##_clear(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
memset(_set_->buffer, 0, sizeof(SNAME##_entry) * _set_->capacity); \
|
||||
\
|
||||
_set_->count = 0; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_free(SNAME *_set_) \
|
||||
void PFX##_free(SNAME *_set_, void (*deallocator)(V)) \
|
||||
{ \
|
||||
if (deallocator) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *entry = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (entry->state == CMC_ES_FILLED) \
|
||||
{ \
|
||||
deallocator(entry->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
free(_set_->buffer); \
|
||||
free(_set_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert(SNAME *_set_, V element) \
|
||||
bool PFX##_insert(SNAME *_set_, V element) \
|
||||
{ \
|
||||
bool new_node; \
|
||||
\
|
||||
@@ -306,7 +337,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_many(SNAME *_set_, V element, size_t count) \
|
||||
bool PFX##_insert_many(SNAME *_set_, V element, size_t count) \
|
||||
{ \
|
||||
if (count == 0) \
|
||||
return true; \
|
||||
@@ -328,7 +359,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_update(SNAME *_set_, V element, size_t multiplicity) \
|
||||
bool PFX##_update(SNAME *_set_, V element, size_t multiplicity) \
|
||||
{ \
|
||||
if (multiplicity == 0) \
|
||||
return PFX##_remove_all(_set_, element); \
|
||||
@@ -350,7 +381,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove(SNAME *_set_, V element) \
|
||||
bool PFX##_remove(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
@@ -374,7 +405,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_remove_all(SNAME *_set_, V element) \
|
||||
size_t PFX##_remove_all(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *result = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
@@ -394,7 +425,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return removed; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_insert_if(SNAME *_set_, V element, bool condition) \
|
||||
bool PFX##_insert_if(SNAME *_set_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_insert(_set_, element); \
|
||||
@@ -402,7 +433,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_remove_if(SNAME *_set_, V element, bool condition) \
|
||||
bool PFX##_remove_if(SNAME *_set_, V element, bool condition) \
|
||||
{ \
|
||||
if (condition) \
|
||||
return PFX##_remove(_set_, element); \
|
||||
@@ -410,7 +441,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_max(SNAME *_set_, V *value) \
|
||||
bool PFX##_max(SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
@@ -431,7 +462,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_min(SNAME *_set_, V *value) \
|
||||
bool PFX##_min(SNAME *_set_, V *value) \
|
||||
{ \
|
||||
if (PFX##_empty(_set_)) \
|
||||
return false; \
|
||||
@@ -452,7 +483,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_multiplicity_of(SNAME *_set_, V element) \
|
||||
size_t PFX##_multiplicity_of(SNAME *_set_, V element) \
|
||||
{ \
|
||||
SNAME##_entry *entry = PFX##_impl_get_entry(_set_, element); \
|
||||
\
|
||||
@@ -462,32 +493,99 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return entry->multiplicity; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_contains(SNAME *_set_, V element) \
|
||||
bool PFX##_contains(SNAME *_set_, V element) \
|
||||
{ \
|
||||
return PFX##_impl_get_entry(_set_, element) != NULL; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_empty(SNAME *_set_) \
|
||||
bool PFX##_empty(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count == 0; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_count(SNAME *_set_) \
|
||||
size_t PFX##_count(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->count; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_cardinality(SNAME *_set_) \
|
||||
size_t PFX##_cardinality(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->cardinality; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_capacity(SNAME *_set_) \
|
||||
size_t PFX##_capacity(SNAME *_set_) \
|
||||
{ \
|
||||
return _set_->capacity; \
|
||||
} \
|
||||
\
|
||||
FMOD cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
SNAME *PFX##_copy_of(SNAME *_set_, V (*copy_func)(V)) \
|
||||
{ \
|
||||
SNAME *result = PFX##_new(_set_->capacity, _set_->load, _set_->cmp, _set_->hash); \
|
||||
\
|
||||
if (!result) \
|
||||
return NULL; \
|
||||
\
|
||||
if (copy_func) \
|
||||
{ \
|
||||
for (size_t i = 0; i < _set_->capacity; i++) \
|
||||
{ \
|
||||
SNAME##_entry *scan = &(_set_->buffer[i]); \
|
||||
\
|
||||
if (scan->state != CMC_ES_EMPTY) \
|
||||
{ \
|
||||
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 = copy_func(scan->value); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
memcpy(result->buffer, _set_->buffer, sizeof(SNAME##_entry) * _set_->capacity); \
|
||||
\
|
||||
result->count = _set_->count; \
|
||||
result->cardinality = _set_->cardinality; \
|
||||
\
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool PFX##_equals(SNAME *_set1_, SNAME *_set2_, bool ignore_multiplicity) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) != PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
\
|
||||
if (!ignore_multiplicity && PFX##_cardinality(_set1_) != PFX##_cardinality(_set2_)) \
|
||||
return false; \
|
||||
\
|
||||
if (PFX##_count(_set1_) == 0) \
|
||||
return true; \
|
||||
\
|
||||
SNAME##_iter iter; \
|
||||
PFX##_iter_init(&iter, _set1_); \
|
||||
\
|
||||
for (PFX##_iter_to_start(&iter); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
SNAME##_entry *entry = PFX##_impl_get_entry(_set2_, PFX##_iter_value(&iter)); \
|
||||
\
|
||||
if (entry == NULL) \
|
||||
return false; \
|
||||
\
|
||||
if (!ignore_multiplicity && entry->multiplicity != PFX##_iter_multiplicity(&iter)) \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
cmc_string PFX##_to_string(SNAME *_set_) \
|
||||
{ \
|
||||
cmc_string str; \
|
||||
SNAME *s_ = _set_; \
|
||||
@@ -499,7 +597,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return str; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_union(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -535,7 +633,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_intersection(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -562,7 +660,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -586,7 +684,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_summation(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME *_set_r_ = PFX##_new(_set1_->capacity, _set1_->load, _set1_->cmp, _set1_->hash); \
|
||||
\
|
||||
@@ -610,7 +708,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
SNAME *PFX##_symmetric_difference(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
SNAME##_iter iter1, iter2; \
|
||||
\
|
||||
@@ -657,7 +755,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return _set_r_; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) > PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -683,12 +781,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_subset(_set2_, _set1_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_subset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_count(_set1_) >= PFX##_count(_set2_)) \
|
||||
return false; \
|
||||
@@ -719,12 +817,12 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_proper_superset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
return PFX##_is_proper_subset(_set2_, _set1_); \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
bool PFX##_is_disjointset(SNAME *_set1_, SNAME *_set2_) \
|
||||
{ \
|
||||
if (PFX##_empty(_set1_)) \
|
||||
return true; \
|
||||
@@ -744,7 +842,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
FMOD SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
SNAME##_iter *PFX##_iter_new(SNAME *target) \
|
||||
{ \
|
||||
SNAME##_iter *iter = malloc(sizeof(SNAME##_iter)); \
|
||||
\
|
||||
@@ -756,16 +854,16 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
void PFX##_iter_free(SNAME##_iter *iter) \
|
||||
{ \
|
||||
free(iter); \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
void PFX##_iter_init(SNAME##_iter *iter, SNAME *target) \
|
||||
{ \
|
||||
memset(iter, 0, sizeof(SNAME##_iter)); \
|
||||
\
|
||||
iter->target = target; \
|
||||
iter->cursor = 0; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(target); \
|
||||
\
|
||||
@@ -793,89 +891,153 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->start; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return PFX##_empty(iter->target) || iter->end; \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_start(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->first; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->first; \
|
||||
iter->index = 0; \
|
||||
iter->start = true; \
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
void PFX##_iter_to_end(SNAME##_iter *iter) \
|
||||
{ \
|
||||
iter->cursor = iter->last; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
if (!PFX##_empty(iter->target)) \
|
||||
{ \
|
||||
iter->cursor = iter->last; \
|
||||
iter->index = iter->target->count - 1; \
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
iter->end = true; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_next(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (iter->cursor == iter->last) \
|
||||
iter->end = true; \
|
||||
else \
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->index++; \
|
||||
\
|
||||
while (1) \
|
||||
{ \
|
||||
iter->cursor++; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->start = PFX##_empty(iter->target); \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
FMOD bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
bool PFX##_iter_prev(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (iter->start) \
|
||||
return false; \
|
||||
\
|
||||
SNAME##_entry *scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (iter->cursor == iter->first) \
|
||||
iter->start = true; \
|
||||
else \
|
||||
if (iter->index == 0) \
|
||||
{ \
|
||||
iter->index--; \
|
||||
\
|
||||
while (1) \
|
||||
{ \
|
||||
iter->cursor--; \
|
||||
scan = &(iter->target->buffer[iter->cursor]); \
|
||||
\
|
||||
if (scan->state == CMC_ES_FILLED) \
|
||||
break; \
|
||||
} \
|
||||
iter->start = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
iter->end = PFX##_empty(iter->target); \
|
||||
\
|
||||
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; \
|
||||
} \
|
||||
\
|
||||
FMOD V PFX##_iter_value(SNAME##_iter *iter) \
|
||||
/* Returns true only if the iterator moved */ \
|
||||
bool PFX##_iter_advance(SNAME##_iter *iter, size_t steps) \
|
||||
{ \
|
||||
if (iter->end) \
|
||||
return false; \
|
||||
\
|
||||
if (iter->index + 1 == PFX##_count(iter->target)) \
|
||||
{ \
|
||||
iter->end = true; \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
if (steps == 0 || iter->index + steps >= PFX##_count(iter->target)) \
|
||||
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(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(SNAME##_iter *iter, size_t index) \
|
||||
{ \
|
||||
if (index >= PFX##_count(iter->target)) \
|
||||
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(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return PFX##_impl_default_value(); \
|
||||
@@ -883,7 +1045,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter->target->buffer[iter->cursor].value; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_multiplicity(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_multiplicity(SNAME##_iter *iter) \
|
||||
{ \
|
||||
if (PFX##_empty(iter->target)) \
|
||||
return 0; \
|
||||
@@ -891,7 +1053,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
return iter->target->buffer[iter->cursor].multiplicity; \
|
||||
} \
|
||||
\
|
||||
FMOD size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
size_t PFX##_iter_index(SNAME##_iter *iter) \
|
||||
{ \
|
||||
return iter->index; \
|
||||
} \
|
||||
@@ -988,7 +1150,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
if (_set_->count != _new_set_->count) \
|
||||
{ \
|
||||
PFX##_free(_new_set_); \
|
||||
PFX##_free(_new_set_, NULL); \
|
||||
\
|
||||
return false; \
|
||||
} \
|
||||
@@ -999,7 +1161,7 @@ static const size_t cmc_hashtable_primes[] = {53, 97, 191, 383, 769, 1531,
|
||||
\
|
||||
_set_->capacity = _new_set_->capacity; \
|
||||
\
|
||||
PFX##_free(_new_set_); \
|
||||
PFX##_free(_new_set_, NULL); \
|
||||
\
|
||||
return true; \
|
||||
} \
|
||||
|
||||
+12
-15
@@ -8,26 +8,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CMC_MACRO_COLLECTIONS
|
||||
#define CMC_MACRO_COLLECTIONS
|
||||
#ifndef CMC_MACRO_COLLECTIONS_H
|
||||
#define CMC_MACRO_COLLECTIONS_H
|
||||
|
||||
#define CMC_CONCATH_(C) C##_WRAPGEN_HEADER
|
||||
#define CMC_CONCATC_(C) C##_WRAPGEN_SOURCE
|
||||
#define CMC_CONCATH_(C) CMC_WRAPGEN_##C##_HEADER
|
||||
#define CMC_CONCATC_(C) CMC_WRAPGEN_##C##_SOURCE
|
||||
|
||||
#define CMC_CONCATH(C) CMC_CONCATH_(C)
|
||||
#define CMC_CONCATC(C) CMC_CONCATC_(C)
|
||||
|
||||
#define COLLECTION_GENERATE(C, PFX, SNAME, FMOD, K, V) \
|
||||
COLLECTION_GENERATE_HEADER(C, PFX, SNAME, FMOD, K, V) \
|
||||
COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, FMOD, K, V)
|
||||
#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)
|
||||
|
||||
#define COLLECTION_GENERATE_HEADER(C, PFX, SNAME, FMOD, K, V) \
|
||||
CMC_CONCATH(C) \
|
||||
(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_COLLECTION_GENERATE_HEADER(C, PFX, SNAME, K, V) \
|
||||
CMC_CONCATH(C)(PFX, SNAME, K, V)
|
||||
|
||||
#define COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, FMOD, K, V) \
|
||||
CMC_CONCATC(C) \
|
||||
(PFX, SNAME, FMOD, K, V)
|
||||
#define CMC_COLLECTION_GENERATE_SOURCE(C, PFX, SNAME, K, V) \
|
||||
CMC_CONCATC(C)(PFX, SNAME, K, V)
|
||||
|
||||
#include "cmc/deque.h"
|
||||
#include "cmc/hashmap.h"
|
||||
@@ -41,7 +39,6 @@
|
||||
#include "cmc/treeset.h"
|
||||
|
||||
#include "ext/intervalheap.h"
|
||||
#include "ext/linkedqueue.h"
|
||||
#include "ext/multimap.h"
|
||||
#include "ext/multiset.h"
|
||||
|
||||
@@ -54,4 +51,4 @@
|
||||
#include "utl/test.h"
|
||||
#include "utl/timer.h"
|
||||
|
||||
#endif /* CMC_MACRO_COLLECTIONS */
|
||||
#endif /* CMC_MACRO_COLLECTIONS_H */
|
||||
+231
-3
@@ -11,7 +11,7 @@
|
||||
/**
|
||||
* Definition of many typed non-abortive assertions. Every assertion that fails
|
||||
* will print a message to stderr but will not abort the program execution.
|
||||
* There are 4 main macros:
|
||||
* There are 9 main macros:
|
||||
*
|
||||
* - cmc_assert
|
||||
* - cmc_assert_equals
|
||||
@@ -46,6 +46,7 @@
|
||||
#define CMC_ASSERT_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -53,6 +54,15 @@
|
||||
#define CMC_ASSERT_GLUE_(dtype, assertion) cmc_assert_##assertion##_##dtype
|
||||
#define CMC_ASSERT_GLUE(dtype, assertion) CMC_ASSERT_GLUE_(dtype, assertion)
|
||||
|
||||
/**
|
||||
* This is a global variable that can be used to test if all assertions passed.
|
||||
* If a single assertion fails, this variable will be set to false.
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* expression : An expression that is expected to be evaluated to true.
|
||||
*/
|
||||
@@ -62,6 +72,8 @@
|
||||
const char *str = #expression; \
|
||||
if (!(expression)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }\n", \
|
||||
__FILE__, __func__, __LINE__, str); \
|
||||
@@ -155,6 +167,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId8 " Actual: %" PRId8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -171,6 +185,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId16 " Actual: %" PRId16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -187,6 +203,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId32 " Actual: %" PRId32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -203,6 +221,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRId64 " Actual: %" PRId64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -219,6 +239,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu8 " Actual: %" PRIu8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -235,6 +257,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu16 " Actual: %" PRIu16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -251,6 +275,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu32 " Actual: %" PRIu32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -267,6 +293,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIu64 " Actual: %" PRIu64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -283,6 +311,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIdMAX " Actual: %" PRIdMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -299,6 +329,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -315,6 +347,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -331,6 +365,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %f Actual: %f\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -347,6 +383,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %lf Actual: %lf\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -363,6 +401,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %p Actual: %p\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -370,7 +410,7 @@
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define cmc_assert_equals__Bool(expected, actual) \
|
||||
#define cmc_assert_equals__Bool(expected, actual) \
|
||||
do \
|
||||
{ \
|
||||
const char *str = #actual; \
|
||||
@@ -379,6 +419,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected: %d Actual: %d\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -395,6 +437,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId8 " Actual: %" PRId8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -411,6 +455,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId16 " Actual: %" PRId16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -427,6 +473,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId32 " Actual: %" PRId32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -443,6 +491,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRId64 " Actual: %" PRId64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -459,6 +509,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu8 " Actual: %" PRIu8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -475,6 +527,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu16 " Actual: %" PRIu16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -491,6 +545,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIu32 " Actual: %" PRIu32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -507,6 +563,8 @@
|
||||
\
|
||||
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_); \
|
||||
@@ -523,6 +581,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIdMAX " Actual: %" PRIdMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -539,6 +599,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -555,6 +617,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -571,6 +635,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %f Actual: %f\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -587,6 +653,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %lf Actual: %lf\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -603,6 +671,8 @@
|
||||
\
|
||||
if ((not_expected_) == (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %p Actual: %p\n", \
|
||||
__FILE__, __func__, __LINE__, str, not_expected_, actual_); \
|
||||
@@ -610,7 +680,7 @@
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define cmc_assert_not_equals__Bool(expected, actual) \
|
||||
#define cmc_assert_not_equals__Bool(expected, actual) \
|
||||
do \
|
||||
{ \
|
||||
const char *str = #actual; \
|
||||
@@ -619,6 +689,8 @@
|
||||
\
|
||||
if ((expected_) != (actual_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Not Expected: %d Actual: %d\n", \
|
||||
__FILE__, __func__, __LINE__, str, expected_, actual_); \
|
||||
@@ -635,6 +707,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRId8 " Actual: %" PRId8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -651,6 +725,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRId16 " Actual: %" PRId16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -667,6 +743,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRId32 " Actual: %" PRId32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -683,6 +761,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRId64 " Actual: %" PRId64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -699,6 +779,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIu8 " Actual: %" PRIu8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -715,6 +797,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIu16 " Actual: %" PRIu16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -731,6 +815,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIu32 " Actual: %" PRIu32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -747,6 +833,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIu64 " Actual: %" PRIu64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -763,6 +851,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIdMAX " Actual: %" PRIdMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -779,6 +869,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -795,6 +887,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -811,6 +905,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %f Actual: %f\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -827,6 +923,8 @@
|
||||
\
|
||||
if ((actual_) <= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (excluded): %lf Actual: %lf\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -843,6 +941,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRId8 " Actual: %" PRId8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -859,6 +959,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRId16 " Actual: %" PRId16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -875,6 +977,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRId32 " Actual: %" PRId32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -891,6 +995,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRId64 " Actual: %" PRId64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -907,6 +1013,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIu8 " Actual: %" PRIu8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -923,6 +1031,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIu16 " Actual: %" PRIu16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -939,6 +1049,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIu32 " Actual: %" PRIu32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -955,6 +1067,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIu64 " Actual: %" PRIu64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -971,6 +1085,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIdMAX " Actual: %" PRIdMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -987,6 +1103,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1003,6 +1121,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1019,6 +1139,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %f Actual: %f\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1035,6 +1157,8 @@
|
||||
\
|
||||
if ((actual_) < (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Greater (included): %lf Actual: %lf\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1051,6 +1175,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRId8 " Actual: %" PRId8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1067,6 +1193,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRId16 " Actual: %" PRId16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1083,6 +1211,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRId32 " Actual: %" PRId32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1099,6 +1229,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRId64 " Actual: %" PRId64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1115,6 +1247,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIu8 " Actual: %" PRIu8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1131,6 +1265,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIu16 " Actual: %" PRIu16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1147,6 +1283,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIu32 " Actual: %" PRIu32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1163,6 +1301,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIu64 " Actual: %" PRIu64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1179,6 +1319,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIdMAX " Actual: %" PRIdMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1195,6 +1337,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1211,6 +1355,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1227,6 +1373,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %f Actual: %f\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1243,6 +1391,8 @@
|
||||
\
|
||||
if ((actual_) >= (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (excluded): %lf Actual: %lf\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1259,6 +1409,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRId8 " Actual: %" PRId8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1275,6 +1427,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRId16 " Actual: %" PRId16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1291,6 +1445,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRId32 " Actual: %" PRId32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1307,6 +1463,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRId64 " Actual: %" PRId64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1323,6 +1481,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIu8 " Actual: %" PRIu8 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1339,6 +1499,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIu16 " Actual: %" PRIu16 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1355,6 +1517,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIu32 " Actual: %" PRIu32 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1371,6 +1535,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIu64 " Actual: %" PRIu64 "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1387,6 +1553,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIdMAX " Actual: %" PRIdMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1403,6 +1571,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1419,6 +1589,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %" PRIuMAX " Actual: %" PRIuMAX "\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1435,6 +1607,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %f Actual: %f\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1451,6 +1625,8 @@
|
||||
\
|
||||
if ((actual_) > (boundary_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
fprintf(stderr, \
|
||||
"Assertion Failed at %s:%s:%u for { %s }: Expected Lesser (included): %lf Actual: %lf\n", \
|
||||
__FILE__, __func__, __LINE__, str, boundary_, actual_); \
|
||||
@@ -1468,6 +1644,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1485,6 +1663,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1502,6 +1682,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1519,6 +1701,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1536,6 +1720,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1553,6 +1739,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1570,6 +1758,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1587,6 +1777,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1604,6 +1796,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1621,6 +1815,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1638,6 +1834,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1655,6 +1853,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1672,6 +1872,8 @@
|
||||
\
|
||||
if ((actual_) < (lower_bound_) || (actual_) > (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1689,6 +1891,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1706,6 +1910,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1723,6 +1929,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1740,6 +1948,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1757,6 +1967,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1774,6 +1986,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1791,6 +2005,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1808,6 +2024,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1825,6 +2043,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1842,6 +2062,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1859,6 +2081,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1876,6 +2100,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
@@ -1893,6 +2119,8 @@
|
||||
\
|
||||
if ((actual_) >= (lower_bound_) && (actual_) <= (upper_bound_)) \
|
||||
{ \
|
||||
cmc_assert_state = false; \
|
||||
\
|
||||
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_); \
|
||||
|
||||
+17
-23
@@ -8,31 +8,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ForEach utility
|
||||
*
|
||||
* Read Documentation.md for more information
|
||||
*/
|
||||
#ifndef CMC_FOR_EACH_H
|
||||
#define CMC_FOR_EACH_H
|
||||
|
||||
#ifndef CMC_FOR_EACH
|
||||
#define CMC_FOR_EACH
|
||||
|
||||
#define FOR_EACH(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (SNAME##_iter iter = TARGET->it_start(TARGET); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
#define CMC_FOR_EACH(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (SNAME##_iter iter = (TARGET)->it_start(TARGET); !PFX##_iter_end(&iter); PFX##_iter_next(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FOR_EACH_REV(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (SNAME##_iter iter = TARGET->it_end(TARGET); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
#define CMC_FOR_EACH_REV(PFX, SNAME, TARGET, BODY) \
|
||||
do \
|
||||
{ \
|
||||
for (SNAME##_iter iter = (TARGET)->it_end(TARGET); !PFX##_iter_start(&iter); PFX##_iter_prev(&iter)) \
|
||||
{ \
|
||||
BODY; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* CMC_FOR_EACH */
|
||||
#endif /* CMC_FOR_EACH_H */
|
||||
+12
-12
@@ -85,21 +85,21 @@ static struct
|
||||
|
||||
typedef enum cmc_log_type_e
|
||||
{
|
||||
LOG_TRACE = 1,
|
||||
LOG_DEBUG = 2,
|
||||
LOG_INFO = 3,
|
||||
LOG_WARN = 4,
|
||||
LOG_ERROR = 5,
|
||||
LOG_FATAL = 6
|
||||
CMC_LOG_TRACE = 1,
|
||||
CMC_LOG_DEBUG = 2,
|
||||
CMC_LOG_INFO = 3,
|
||||
CMC_LOG_WARN = 4,
|
||||
CMC_LOG_ERROR = 5,
|
||||
CMC_LOG_FATAL = 6
|
||||
|
||||
} cmc_log_type;
|
||||
|
||||
#define log_trace(fmt, ...) cmc_log(LOG_TRACE, __FILE__, __func__, __LINE__, fmt, __VA_ARGS__)
|
||||
#define log_debug(fmt, ...) cmc_log(LOG_DEBUG, __FILE__, __func__, __LINE__, fmt, __VA_ARGS__)
|
||||
#define log_info(fmt, ...) cmc_log(LOG_INFO, __FILE__, __func__, __LINE__, fmt, __VA_ARGS__)
|
||||
#define log_warn(fmt, ...) cmc_log(LOG_WARN, __FILE__, __func__, __LINE__, fmt, __VA_ARGS__)
|
||||
#define log_error(fmt, ...) cmc_log(LOG_ERROR, __FILE__, __func__, __LINE__, fmt, __VA_ARGS__)
|
||||
#define log_fatal(fmt, ...) cmc_log(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(cmc_log_type log, const char *filename, const char *funcname, int line, const char *fmt, ...)
|
||||
{
|
||||
|
||||
+30
-36
@@ -11,6 +11,10 @@
|
||||
/**
|
||||
* Simple Unit Test Utility
|
||||
*
|
||||
* Required imports:
|
||||
* - assert.h (to integrate with the cmc_assert_state variable)
|
||||
* - timer.h (to calculate the execution time for the unit test)
|
||||
*
|
||||
* CMC_CREATE_UNIT
|
||||
* Create a UnitTest
|
||||
* Parameters:
|
||||
@@ -42,6 +46,7 @@
|
||||
#ifndef CMC_TEST_H
|
||||
#define CMC_TEST_H
|
||||
|
||||
#include "assert.h"
|
||||
#include "timer.h"
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
@@ -92,7 +97,7 @@ static void cmc_test_log(const char *unit_name, const char *current_test, bool a
|
||||
}
|
||||
|
||||
#define CMC_CREATE_UNIT(UNAME, VERBOSE, BODY) \
|
||||
void UNAME(void) \
|
||||
uintmax_t UNAME(void) \
|
||||
{ \
|
||||
const char *unit_name = #UNAME; \
|
||||
const char *current_test = NULL; \
|
||||
@@ -104,11 +109,13 @@ static void cmc_test_log(const char *unit_name, const char *current_test, bool a
|
||||
\
|
||||
/* Tests */ \
|
||||
timer_start(timer); \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
timer_stop(timer); \
|
||||
timer_calc(timer); \
|
||||
\
|
||||
unittest_abort: \
|
||||
unittest_abort: \
|
||||
if (tinfo.aborted) \
|
||||
{ \
|
||||
cmc_test_log(unit_name, current_test, true, false); \
|
||||
@@ -122,51 +129,38 @@ static void cmc_test_log(const char *unit_name, const char *current_test, bool a
|
||||
printf("| |\n"); \
|
||||
printf("| Total Unit Test Runtime : %9.0f milliseconds |\n", timer.result); \
|
||||
printf("+--------------------------------------------------+\n"); \
|
||||
\
|
||||
return tinfo.failed; \
|
||||
}
|
||||
|
||||
#define CMC_CREATE_TEST(TNAME, BODY) \
|
||||
do \
|
||||
{ \
|
||||
current_test = #TNAME; \
|
||||
\
|
||||
tinfo.total += 1; \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define CMC_TEST_PASS() \
|
||||
do \
|
||||
{ \
|
||||
tinfo.passed += 1; \
|
||||
if (tinfo.verbose) \
|
||||
cmc_test_log(unit_name, current_test, false, true); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define CMC_TEST_FAIL() \
|
||||
#define CMC_CREATE_TEST(TNAME, BODY) \
|
||||
do \
|
||||
{ \
|
||||
tinfo.failed += 1; \
|
||||
if (tinfo.verbose) \
|
||||
current_test = #TNAME; \
|
||||
\
|
||||
tinfo.total += 1; \
|
||||
\
|
||||
/* Provided by assert.h */ \
|
||||
cmc_assert_state = true; \
|
||||
\
|
||||
BODY; \
|
||||
\
|
||||
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); \
|
||||
} \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define CMC_TEST_PASS_ELSE_FAIL(EXPRESSION) \
|
||||
do \
|
||||
{ \
|
||||
if (EXPRESSION) \
|
||||
CMC_TEST_PASS(); \
|
||||
else \
|
||||
CMC_TEST_FAIL(); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
#define CMC_TEST_ABORT() \
|
||||
do \
|
||||
{ \
|
||||
\
|
||||
tinfo.aborted = true; \
|
||||
tinfo.total -= 1; \
|
||||
goto unittest_abort; \
|
||||
|
||||
+20
-12
@@ -1,17 +1,25 @@
|
||||
CC = gcc
|
||||
CFLAGS = -std=c11 -Wall -Wextra
|
||||
CFLAGS += -Wno-unused-function -Wno-unused-paramter -Wno-unused-variable -Wno-unused-label
|
||||
CFLAGS += -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-unused-label
|
||||
|
||||
main:
|
||||
$(CC) foreach.c -o foreach $(CFLAGS)
|
||||
./foreach
|
||||
$(CC) iterators.c -o iterators $(CFLAGS)
|
||||
./iterators
|
||||
$(CC) contains.c -o contains $(CFLAGS)
|
||||
./contains
|
||||
$(CC) types.c -o types $(CFLAGS)
|
||||
./types
|
||||
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
|
||||
$(CC) -c ./sep/sep.c -o ./sep/sep.o $(CFLAGS)
|
||||
$(CC) -c ./sep/main.c -o ./sep/main.o $(CFLAGS)
|
||||
$(CC) ./sep/sep.o ./sep/main.o -o ./sep/sep
|
||||
./sep/sep
|
||||
$(CC) ./sep/sep.o ./sep/main.o -o ./sep/sep.exe
|
||||
./sep/sep.exe
|
||||
|
||||
dev: main
|
||||
rm *.exe ./sep/*.o ./sep/*.exe
|
||||
|
||||
windev: main
|
||||
del *.exe .\\sep\\*.o .\\sep\\*.exe
|
||||
|
||||
FORCE:
|
||||
+109
-55
@@ -20,16 +20,20 @@ size_t inthash(int t)
|
||||
return a;
|
||||
}
|
||||
|
||||
COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
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)
|
||||
{
|
||||
@@ -41,12 +45,16 @@ int main(void)
|
||||
heap *h = h_new(1000, cmc_max_heap, intcmp);
|
||||
tset *ts = ts_new(intcmp);
|
||||
tmap *tm = tm_new(intcmp);
|
||||
hset *hs = hs_new(1000, 0.9, intcmp, inthash);
|
||||
hmap *hm = hm_new(1000, 0.9, intcmp, inthash);
|
||||
hset *hs = hs_new(1000, 0.6, intcmp, inthash);
|
||||
hmap *hm = hm_new(1000, 0.6, intcmp, inthash);
|
||||
|
||||
bool a[10] = {false, false, false, false, false, false, false, false, false, false},
|
||||
b[10] = {false, false, false, false, false, false, false, false, false, false},
|
||||
c[10] = {true, true, true, true, true, true, true, true, true, true};
|
||||
iheap *ih = ih_new(1000, intcmp);
|
||||
mmap *mm = mm_new(1000, 0.8, intcmp, inthash);
|
||||
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);
|
||||
@@ -59,6 +67,10 @@ int main(void)
|
||||
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)
|
||||
@@ -81,6 +93,10 @@ int main(void)
|
||||
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++)
|
||||
@@ -95,6 +111,10 @@ int main(void)
|
||||
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++)
|
||||
@@ -109,6 +129,10 @@ int main(void)
|
||||
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++)
|
||||
@@ -123,18 +147,26 @@ int main(void)
|
||||
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);
|
||||
hm_clear(hm);
|
||||
hs_clear(hs);
|
||||
h_clear(h);
|
||||
ll_clear(ll);
|
||||
l_clear(l);
|
||||
q_clear(q);
|
||||
s_clear(s);
|
||||
tm_clear(tm);
|
||||
ts_clear(ts);
|
||||
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);
|
||||
@@ -147,58 +179,80 @@ int main(void)
|
||||
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("%10s PASSED\n", "DEQUE");
|
||||
printf("%12s PASSED\n", "DEQUE");
|
||||
else
|
||||
printf("%10s FAILED\n", "DEQUE");
|
||||
printf("%12s FAILED\n", "DEQUE");
|
||||
if (c[1] && !a[1] && !b[1])
|
||||
printf("%10s PASSED\n", "HASHMAP");
|
||||
printf("%12s PASSED\n", "HASHMAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "HASHMAP");
|
||||
printf("%12s FAILED\n", "HASHMAP");
|
||||
if (c[2] && !a[2] && !b[2])
|
||||
printf("%10s PASSED\n", "HASHSET");
|
||||
printf("%12s PASSED\n", "HASHSET");
|
||||
else
|
||||
printf("%10s FAILED\n", "HASHSET");
|
||||
printf("%12s FAILED\n", "HASHSET");
|
||||
if (c[3] && !a[3] && !b[3])
|
||||
printf("%10s PASSED\n", "HEAP");
|
||||
printf("%12s PASSED\n", "HEAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "HEAP");
|
||||
printf("%12s FAILED\n", "HEAP");
|
||||
if (c[4] && !a[4] && !b[4])
|
||||
printf("%10s PASSED\n", "LINKEDLIST");
|
||||
printf("%12s PASSED\n", "LINKEDLIST");
|
||||
else
|
||||
printf("%10s FAILED\n", "LINKEDLIST");
|
||||
printf("%12s FAILED\n", "LINKEDLIST");
|
||||
if (c[5] && !a[5] && !b[5])
|
||||
printf("%10s PASSED\n", "LIST");
|
||||
printf("%12s PASSED\n", "LIST");
|
||||
else
|
||||
printf("%10s FAILED\n", "LIST");
|
||||
printf("%12s FAILED\n", "LIST");
|
||||
if (c[6] && !a[6] && !b[6])
|
||||
printf("%10s PASSED\n", "QUEUE");
|
||||
printf("%12s PASSED\n", "QUEUE");
|
||||
else
|
||||
printf("%10s FAILED\n", "QUEUE");
|
||||
printf("%12s FAILED\n", "QUEUE");
|
||||
if (c[7] && !a[7] && !b[7])
|
||||
printf("%10s PASSED\n", "STACK");
|
||||
printf("%12s PASSED\n", "STACK");
|
||||
else
|
||||
printf("%10s FAILED\n", "STACK");
|
||||
printf("%12s FAILED\n", "STACK");
|
||||
if (c[8] && !a[8] && !b[8])
|
||||
printf("%10s PASSED\n", "TREEMAP");
|
||||
printf("%12s PASSED\n", "TREEMAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "TREEMAP");
|
||||
printf("%12s FAILED\n", "TREEMAP");
|
||||
if (c[9] && !a[9] && !b[9])
|
||||
printf("%10s PASSED\n", "TREESET");
|
||||
printf("%12s PASSED\n", "TREESET");
|
||||
else
|
||||
printf("%10s FAILED\n", "TREESET");
|
||||
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");
|
||||
|
||||
l_free(l);
|
||||
ll_free(ll);
|
||||
s_free(s);
|
||||
q_free(q);
|
||||
d_free(d);
|
||||
h_free(h);
|
||||
ts_free(ts);
|
||||
tm_free(tm);
|
||||
hs_free(hs);
|
||||
hm_free(hm);
|
||||
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;
|
||||
}
|
||||
+224
-155
@@ -1,5 +1,6 @@
|
||||
#include "../src/macro_collections.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
int intcmp(int a, int b)
|
||||
@@ -19,16 +20,20 @@ size_t inthash(int t)
|
||||
return a;
|
||||
}
|
||||
|
||||
COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
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)
|
||||
{
|
||||
@@ -40,219 +45,283 @@ int main(void)
|
||||
heap *h = h_new(1000, cmc_max_heap, intcmp);
|
||||
tset *ts = ts_new(intcmp);
|
||||
tmap *tm = tm_new(intcmp);
|
||||
hset *hs = hs_new(1000, 0.9, intcmp, inthash);
|
||||
hmap *hm = hm_new(1000, 0.9, intcmp, inthash);
|
||||
hset *hs = hs_new(1000, 0.6, intcmp, inthash);
|
||||
hmap *hm = hm_new(1000, 0.6, intcmp, inthash);
|
||||
|
||||
iheap *ih = ih_new(1000, intcmp);
|
||||
mmap *mm = mm_new(1000, 0.8, intcmp, inthash);
|
||||
mset *ms = ms_new(1000, 0.6, intcmp, inthash);
|
||||
|
||||
bool p = true;
|
||||
|
||||
for (int i = 1; i < 10001; i++)
|
||||
{
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
d_push_front(d, i);
|
||||
l_push_front(l, i);
|
||||
ll_push_front(ll, i);
|
||||
assert(d_push_front(d, i));
|
||||
assert(l_push_front(l, i));
|
||||
assert(ll_push_front(ll, i));
|
||||
}
|
||||
else
|
||||
{
|
||||
d_push_back(d, i);
|
||||
l_push_back(l, i);
|
||||
ll_push_back(ll, i);
|
||||
assert(d_push_back(d, i));
|
||||
assert(l_push_back(l, i));
|
||||
assert(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);
|
||||
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 sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0,
|
||||
sum7 = 0, sum8 = 0, sum9 = 0, sum10 = 0, sum11 = 0;
|
||||
int sums[16] = {0};
|
||||
|
||||
FOR_EACH(d, deque, d, {
|
||||
sum3 += d_iter_value(&iter);
|
||||
CMC_FOR_EACH(d, deque, d, {
|
||||
sums[0] += d_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(hm, hmap, hm, {
|
||||
sum10 += hm_iter_key(&iter);
|
||||
sum11 += hm_iter_value(&iter);
|
||||
CMC_FOR_EACH(hm, hmap, hm, {
|
||||
sums[1] += hm_iter_key(&iter);
|
||||
sums[2] += hm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(hs, hset, hs, {
|
||||
sum9 += hs_iter_value(&iter);
|
||||
CMC_FOR_EACH(hs, hset, hs, {
|
||||
sums[3] += hs_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(h, heap, h, {
|
||||
sum5 += h_iter_value(&iter);
|
||||
CMC_FOR_EACH(h, heap, h, {
|
||||
sums[4] += h_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(ll, linked, ll, {
|
||||
sum4 += ll_iter_value(&iter);
|
||||
CMC_FOR_EACH(ll, linked, ll, {
|
||||
sums[5] += ll_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(l, list, l, {
|
||||
sum0 += l_iter_value(&iter);
|
||||
CMC_FOR_EACH(l, list, l, {
|
||||
sums[6] += l_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(q, queue, q, {
|
||||
sum2 += q_iter_value(&iter);
|
||||
CMC_FOR_EACH(q, queue, q, {
|
||||
sums[7] += q_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(s, stack, s, {
|
||||
sum1 += s_iter_value(&iter);
|
||||
CMC_FOR_EACH(s, stack, s, {
|
||||
sums[8] += s_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(tm, tmap, tm, {
|
||||
sum7 += tm_iter_key(&iter);
|
||||
sum8 += tm_iter_value(&iter);
|
||||
CMC_FOR_EACH(tm, tmap, tm, {
|
||||
sums[9] += tm_iter_key(&iter);
|
||||
sums[10] += tm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH(ts, tset, ts, {
|
||||
sum6 += ts_iter_value(&iter);
|
||||
CMC_FOR_EACH(ts, tset, ts, {
|
||||
sums[11] += ts_iter_value(&iter);
|
||||
});
|
||||
|
||||
printf("\n-------------------- FOR_EACH --------------------\n");
|
||||
if (sum3 == 50005000)
|
||||
printf("%10s PASSED\n", "DEQUE");
|
||||
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("%10s FAILED\n", "DEQUE");
|
||||
if (sum9 == 50005000)
|
||||
printf("%10s PASSED\n", "HASHSET");
|
||||
printf("%12s FAILED\n", "DEQUE");
|
||||
if (sums[1] == 50005000 && sums[2] == 50005000)
|
||||
printf("%12s PASSED\n", "HASHMAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "HASHSET");
|
||||
if (sum10 == 50005000 && sum11 == 50005000)
|
||||
printf("%10s PASSED\n", "HASHMAP");
|
||||
printf("%12s FAILED\n", "HASHMAP");
|
||||
if (sums[3] == 50005000)
|
||||
printf("%12s PASSED\n", "HASHSET");
|
||||
else
|
||||
printf("%10s FAILED\n", "HASHMAP");
|
||||
if (sum5 == 50005000)
|
||||
printf("%10s PASSED\n", "HEAP");
|
||||
printf("%12s FAILED\n", "HASHSET");
|
||||
if (sums[4] == 50005000)
|
||||
printf("%12s PASSED\n", "HEAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "HEAP");
|
||||
if (sum4 == 50005000)
|
||||
printf("%10s PASSED\n", "LINKEDLIST");
|
||||
printf("%12s FAILED\n", "HEAP");
|
||||
if (sums[5] == 50005000)
|
||||
printf("%12s PASSED\n", "LINKEDLIST");
|
||||
else
|
||||
printf("%10s FAILED\n", "LINKEDLIST");
|
||||
if (sum0 == 50005000)
|
||||
printf("%10s PASSED\n", "LIST");
|
||||
printf("%12s FAILED\n", "LINKEDLIST");
|
||||
if (sums[6] == 50005000)
|
||||
printf("%12s PASSED\n", "LIST");
|
||||
else
|
||||
printf("%10s FAILED\n", "LIST");
|
||||
if (sum2 == 50005000)
|
||||
printf("%10s PASSED\n", "QUEUE");
|
||||
printf("%12s FAILED\n", "LIST");
|
||||
if (sums[7] == 50005000)
|
||||
printf("%12s PASSED\n", "QUEUE");
|
||||
else
|
||||
printf("%10s FAILED\n", "QUEUE");
|
||||
if (sum1 == 50005000)
|
||||
printf("%10s PASSED\n", "STACK");
|
||||
printf("%12s FAILED\n", "QUEUE");
|
||||
if (sums[8] == 50005000)
|
||||
printf("%12s PASSED\n", "STACK");
|
||||
else
|
||||
printf("%10s FAILED\n", "STACK");
|
||||
if (sum7 == 50005000 && sum8 == 50005000)
|
||||
printf("%10s PASSED\n", "TREEMAP");
|
||||
printf("%12s FAILED\n", "STACK");
|
||||
if (sums[9] == 50005000 && sums[10] == 50005000)
|
||||
printf("%12s PASSED\n", "TREEMAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "TREEMAP");
|
||||
if (sum6 == 50005000)
|
||||
printf("%10s PASSED\n", "TREESET");
|
||||
printf("%12s FAILED\n", "TREEMAP");
|
||||
if (sums[11] == 50005000)
|
||||
printf("%12s PASSED\n", "TREESET");
|
||||
else
|
||||
printf("%10s FAILED\n", "TREESET");
|
||||
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");
|
||||
|
||||
sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, sum6 = 0,
|
||||
sum7 = 0, sum8 = 0, sum9 = 0, sum10 = 0, sum11 = 0;
|
||||
memset(sums, 0, sizeof sums);
|
||||
|
||||
FOR_EACH_REV(d, deque, d, {
|
||||
sum3 += d_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(d, deque, d, {
|
||||
sums[0] += d_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(hm, hmap, hm, {
|
||||
sum10 += hm_iter_key(&iter);
|
||||
sum11 += hm_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(hm, hmap, hm, {
|
||||
sums[1] += hm_iter_key(&iter);
|
||||
sums[2] += hm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(hs, hset, hs, {
|
||||
sum9 += hs_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(hs, hset, hs, {
|
||||
sums[3] += hs_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(h, heap, h, {
|
||||
sum5 += h_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(h, heap, h, {
|
||||
sums[4] += h_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(ll, linked, ll, {
|
||||
sum4 += ll_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(ll, linked, ll, {
|
||||
sums[5] += ll_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(l, list, l, {
|
||||
sum0 += l_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(l, list, l, {
|
||||
sums[6] += l_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(q, queue, q, {
|
||||
sum2 += q_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(q, queue, q, {
|
||||
sums[7] += q_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(s, stack, s, {
|
||||
sum1 += s_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(s, stack, s, {
|
||||
sums[8] += s_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(tm, tmap, tm, {
|
||||
sum7 += tm_iter_key(&iter);
|
||||
sum8 += tm_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(tm, tmap, tm, {
|
||||
sums[9] += tm_iter_key(&iter);
|
||||
sums[10] += tm_iter_value(&iter);
|
||||
});
|
||||
|
||||
FOR_EACH_REV(ts, tset, ts, {
|
||||
sum6 += ts_iter_value(&iter);
|
||||
CMC_FOR_EACH_REV(ts, tset, ts, {
|
||||
sums[11] += ts_iter_value(&iter);
|
||||
});
|
||||
|
||||
printf("-------------------- FOR_EACH_REV --------------------\n");
|
||||
if (sum3 == 50005000)
|
||||
printf("%10s PASSED\n", "DEQUE");
|
||||
else
|
||||
printf("%10s FAILED\n", "DEQUE");
|
||||
if (sum10 == 50005000 && sum11 == 50005000)
|
||||
printf("%10s PASSED\n", "HASHMAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "HASHMAP");
|
||||
if (sum9 == 50005000)
|
||||
printf("%10s PASSED\n", "HASHSET");
|
||||
else
|
||||
printf("%10s FAILED\n", "HASHSET");
|
||||
if (sum5 == 50005000)
|
||||
printf("%10s PASSED\n", "HEAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "HEAP");
|
||||
if (sum4 == 50005000)
|
||||
printf("%10s PASSED\n", "LINKEDLIST");
|
||||
else
|
||||
printf("%10s FAILED\n", "LINKEDLIST");
|
||||
if (sum0 == 50005000)
|
||||
printf("%10s PASSED\n", "LIST");
|
||||
else
|
||||
printf("%10s FAILED\n", "LIST");
|
||||
if (sum2 == 50005000)
|
||||
printf("%10s PASSED\n", "QUEUE");
|
||||
else
|
||||
printf("%10s FAILED\n", "QUEUE");
|
||||
if (sum1 == 50005000)
|
||||
printf("%10s PASSED\n", "STACK");
|
||||
else
|
||||
printf("%10s FAILED\n", "STACK");
|
||||
if (sum7 == 50005000 && sum8 == 50005000)
|
||||
printf("%10s PASSED\n", "TREEMAP");
|
||||
else
|
||||
printf("%10s FAILED\n", "TREEMAP");
|
||||
if (sum6 == 50005000)
|
||||
printf("%10s PASSED\n", "TREESET");
|
||||
else
|
||||
printf("%10s FAILED\n", "TREESET");
|
||||
CMC_FOR_EACH_REV(ih, iheap, ih, {
|
||||
sums[12] += ih_iter_value(&iter);
|
||||
});
|
||||
|
||||
l_free(l);
|
||||
ll_free(ll);
|
||||
s_free(s);
|
||||
q_free(q);
|
||||
d_free(d);
|
||||
h_free(h);
|
||||
ts_free(ts);
|
||||
tm_free(tm);
|
||||
hs_free(hs);
|
||||
hm_free(hm);
|
||||
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;
|
||||
}
|
||||
+29
-17
@@ -1,6 +1,5 @@
|
||||
#include "../src/macro_collections.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
int intcmp(int a, int b)
|
||||
{
|
||||
@@ -19,16 +18,20 @@ size_t inthash(int t)
|
||||
return a;
|
||||
}
|
||||
|
||||
COLLECTION_GENERATE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm, tmap, /* FMOD */, int, double)
|
||||
COLLECTION_GENERATE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, double)
|
||||
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) \
|
||||
@@ -69,24 +72,27 @@ COLLECTION_GENERATE(HASHMAP, hm, hmap, /* FMOD */, int, double)
|
||||
sumbody; \
|
||||
} \
|
||||
\
|
||||
PFX##_free(coll); \
|
||||
PFX##_free(coll, NULL); \
|
||||
\
|
||||
if (validation1 && validation2) \
|
||||
printf("%10s PASSED\n", #NAME); \
|
||||
if ((validation1) && (validation2)) \
|
||||
printf("%12s PASSED\n", #NAME); \
|
||||
else \
|
||||
printf("%10s FAILED\n", #NAME); \
|
||||
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, sum2 == 45.0)
|
||||
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, sum2 == 45.0)
|
||||
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)
|
||||
{
|
||||
@@ -102,5 +108,11 @@ int main(void)
|
||||
TREEMAP_iterator_test();
|
||||
TREESET_iterator_test();
|
||||
|
||||
INTERVALHEAP_iterator_test();
|
||||
MULTIMAP_iterator_test();
|
||||
MULTISET_iterator_test();
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
+10
-2
@@ -4,13 +4,21 @@ CFLAGS += -Wno-unused-function -Wno-unused-parameter -Wno-unused-variable -Wno-u
|
||||
CVFLAGS = --coverage -O0
|
||||
INCLUDE = ../../src/
|
||||
|
||||
main:
|
||||
main: FORCE
|
||||
$(CC) main.c -o main $(CFLAGS) $(CVFLAGS) -I $(INCLUDE)
|
||||
./main
|
||||
gcov ./main.c
|
||||
|
||||
dev:
|
||||
dev: FORCE
|
||||
$(CC) main.c -o main $(CFLAGS) $(CVFLAGS) -I $(INCLUDE)
|
||||
./main
|
||||
gcov ./main.c -n
|
||||
rm *.gcda *.gcno *.exe
|
||||
|
||||
windev: FORCE
|
||||
$(CC) main.c -o main $(CFLAGS) $(CVFLAGS) -I $(INCLUDE)
|
||||
./main
|
||||
gcov ./main.c -n
|
||||
del *.gcda *.gcno *.exe
|
||||
|
||||
FORCE:
|
||||
+15
-15
@@ -9,27 +9,27 @@
|
||||
#include "unt/treemap.c"
|
||||
#include "unt/treeset.c"
|
||||
|
||||
#include "unt/linkedqueue.c"
|
||||
#include "unt/multimap.c"
|
||||
#include "unt/multiset.c"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
deque_test();
|
||||
hashmap_test();
|
||||
hashset_test();
|
||||
heap_test();
|
||||
linkedlist_test();
|
||||
list_test();
|
||||
queue_test();
|
||||
stack_test();
|
||||
treemap_test();
|
||||
treeset_test();
|
||||
uintmax_t failed = 0;
|
||||
|
||||
failed += deque_test();
|
||||
failed += hashmap_test();
|
||||
failed += hashset_test();
|
||||
failed += heap_test();
|
||||
failed += linkedlist_test();
|
||||
failed += list_test();
|
||||
failed += queue_test();
|
||||
failed += stack_test();
|
||||
failed += treemap_test();
|
||||
failed += treeset_test();
|
||||
|
||||
/* ext */
|
||||
linkedqueue_test();
|
||||
multimap_test();
|
||||
multiset_test();
|
||||
failed += multimap_test();
|
||||
failed += multiset_test();
|
||||
|
||||
return 0;
|
||||
return failed;
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
#include "ext/linkedqueue.h"
|
||||
|
||||
//LINKEDQUEUE_GENERATE(lq, linkedqueue, , size_t)
|
||||
|
||||
typedef struct linkedqueue_s
|
||||
{
|
||||
struct linkedqueue_node_s *head;
|
||||
struct linkedqueue_node_s *tail;
|
||||
size_t count;
|
||||
struct linkedqueue_iter_s (*it_start)(struct linkedqueue_s *);
|
||||
} linkedqueue, *linkedqueue_ptr;
|
||||
typedef struct linkedqueue_node_s
|
||||
{
|
||||
size_t data;
|
||||
struct linkedqueue_node_s *next;
|
||||
} linkedqueue_node, *linkedqueue_node_ptr;
|
||||
typedef struct linkedqueue_iter_s
|
||||
{
|
||||
struct linkedqueue_s *target;
|
||||
struct linkedqueue_node_s *cursor;
|
||||
size_t index;
|
||||
bool start;
|
||||
bool end;
|
||||
} linkedqueue_iter, *linkedqueue_iter_ptr;
|
||||
linkedqueue *lq_new(void);
|
||||
void lq_clear(linkedqueue *_lqueue_);
|
||||
void lq_free(linkedqueue *_lqueue_);
|
||||
bool lq_enqueue(linkedqueue *_lqueue_, size_t element);
|
||||
bool lq_dequeue(linkedqueue *_lqueue_);
|
||||
bool lq_enqueue_if(linkedqueue *_lqueue_, size_t element, bool condition);
|
||||
bool lq_dequeue_if(linkedqueue *_lqueue_, bool condition);
|
||||
size_t lq_peek(linkedqueue *_lqueue_);
|
||||
bool lq_contains(linkedqueue *_lqueue_, size_t element, int (*comparator)(size_t, size_t));
|
||||
bool lq_empty(linkedqueue *_lqueue_);
|
||||
size_t lq_count(linkedqueue *_lqueue_);
|
||||
linkedqueue_iter *lq_iter_new(linkedqueue *target);
|
||||
void lq_iter_free(linkedqueue_iter *iter);
|
||||
void lq_iter_init(linkedqueue_iter *iter, linkedqueue *target);
|
||||
bool lq_iter_start(linkedqueue_iter *iter);
|
||||
bool lq_iter_end(linkedqueue_iter *iter);
|
||||
void lq_iter_to_start(linkedqueue_iter *iter);
|
||||
void lq_iter_to_end(linkedqueue_iter *iter);
|
||||
bool lq_iter_next(linkedqueue_iter *iter);
|
||||
size_t lq_iter_value(linkedqueue_iter *iter);
|
||||
size_t *lq_iter_rvalue(linkedqueue_iter *iter);
|
||||
size_t lq_iter_index(linkedqueue_iter *iter);
|
||||
static inline size_t lq_impl_default_value(void)
|
||||
{
|
||||
size_t _empty_value_;
|
||||
memset(&_empty_value_, 0, sizeof(size_t));
|
||||
return _empty_value_;
|
||||
}
|
||||
linkedqueue_node *lq_impl_new_node(size_t element);
|
||||
static linkedqueue_iter lq_impl_it_start(linkedqueue *_lqueue_);
|
||||
linkedqueue *lq_new(void)
|
||||
{
|
||||
linkedqueue *_lqueue_ = malloc(sizeof(linkedqueue));
|
||||
if (!_lqueue_)
|
||||
return NULL;
|
||||
_lqueue_->count = 0;
|
||||
_lqueue_->head = NULL;
|
||||
_lqueue_->tail = NULL;
|
||||
_lqueue_->it_start = lq_impl_it_start;
|
||||
return _lqueue_;
|
||||
}
|
||||
void lq_clear(linkedqueue *_lqueue_)
|
||||
{
|
||||
linkedqueue_node *scan = _lqueue_->head;
|
||||
while (_lqueue_->head != NULL)
|
||||
{
|
||||
_lqueue_->head = _lqueue_->head->next;
|
||||
free(scan);
|
||||
scan = _lqueue_->head;
|
||||
}
|
||||
_lqueue_->count = 0;
|
||||
_lqueue_->head = NULL;
|
||||
_lqueue_->tail = NULL;
|
||||
}
|
||||
void lq_free(linkedqueue *_lqueue_)
|
||||
{
|
||||
lq_clear(_lqueue_);
|
||||
free(_lqueue_);
|
||||
}
|
||||
bool lq_enqueue(linkedqueue *_lqueue_, size_t element)
|
||||
{
|
||||
linkedqueue_node *_node_ = lq_impl_new_node(element);
|
||||
if (!_node_)
|
||||
return false;
|
||||
if (lq_empty(_lqueue_))
|
||||
{
|
||||
_lqueue_->head = _node_;
|
||||
_lqueue_->tail = _node_;
|
||||
}
|
||||
else
|
||||
{
|
||||
_lqueue_->tail->next = _node_;
|
||||
_lqueue_->tail = _node_;
|
||||
}
|
||||
_lqueue_->count++;
|
||||
return true;
|
||||
}
|
||||
bool lq_dequeue(linkedqueue *_lqueue_)
|
||||
{
|
||||
if (lq_empty(_lqueue_))
|
||||
return false;
|
||||
linkedqueue_node *_node_ = _lqueue_->head;
|
||||
_lqueue_->head = _lqueue_->head->next;
|
||||
free(_node_);
|
||||
if (_lqueue_->head == NULL)
|
||||
_lqueue_->tail = NULL;
|
||||
_lqueue_->count--;
|
||||
return true;
|
||||
}
|
||||
bool lq_enqueue_if(linkedqueue *_lqueue_, size_t element, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return lq_enqueue(_lqueue_, element);
|
||||
return false;
|
||||
}
|
||||
bool lq_dequeue_if(linkedqueue *_lqueue_, bool condition)
|
||||
{
|
||||
if (condition)
|
||||
return lq_dequeue(_lqueue_);
|
||||
return false;
|
||||
}
|
||||
size_t lq_peek(linkedqueue *_lqueue_)
|
||||
{
|
||||
if (lq_empty(_lqueue_))
|
||||
return lq_impl_default_value();
|
||||
return _lqueue_->head->data;
|
||||
}
|
||||
bool lq_contains(linkedqueue *_lqueue_, size_t element, int (*comparator)(size_t, size_t))
|
||||
{
|
||||
linkedqueue_node *scan = _lqueue_->head;
|
||||
while (scan != NULL)
|
||||
{
|
||||
if (comparator(scan->data, element) == 0)
|
||||
return true;
|
||||
scan = scan->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool lq_empty(linkedqueue *_lqueue_) { return _lqueue_->count == 0; }
|
||||
size_t lq_count(linkedqueue *_lqueue_) { return _lqueue_->count; }
|
||||
linkedqueue_iter *lq_iter_new(linkedqueue *target)
|
||||
{
|
||||
linkedqueue_iter *iter = malloc(sizeof(linkedqueue_iter));
|
||||
if (!iter)
|
||||
return NULL;
|
||||
lq_iter_init(iter, target);
|
||||
return iter;
|
||||
}
|
||||
void lq_iter_free(linkedqueue_iter *iter) { free(iter); }
|
||||
void lq_iter_init(linkedqueue_iter *iter, linkedqueue *target)
|
||||
{
|
||||
iter->target = target;
|
||||
iter->cursor = target->head;
|
||||
iter->index = 0;
|
||||
iter->start = true;
|
||||
iter->end = lq_empty(target);
|
||||
}
|
||||
bool lq_iter_start(linkedqueue_iter *iter) { return lq_empty(iter->target) || iter->start; }
|
||||
bool lq_iter_end(linkedqueue_iter *iter) { return lq_empty(iter->target) || iter->end; }
|
||||
void lq_iter_to_start(linkedqueue_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->head;
|
||||
iter->index = 0;
|
||||
iter->start = true;
|
||||
iter->end = lq_empty(iter->target);
|
||||
}
|
||||
void lq_iter_to_end(linkedqueue_iter *iter)
|
||||
{
|
||||
iter->cursor = iter->target->tail;
|
||||
iter->index = iter->target->count - 1;
|
||||
iter->start = lq_empty(iter->target);
|
||||
iter->end = true;
|
||||
}
|
||||
bool lq_iter_next(linkedqueue_iter *iter)
|
||||
{
|
||||
if (iter->end)
|
||||
return false;
|
||||
iter->start = lq_empty(iter->target);
|
||||
if (iter->cursor->next == NULL)
|
||||
iter->end = true;
|
||||
else
|
||||
{
|
||||
iter->cursor = iter->cursor->next;
|
||||
iter->index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
size_t lq_iter_value(linkedqueue_iter *iter)
|
||||
{
|
||||
if (lq_empty(iter->target))
|
||||
return lq_impl_default_value();
|
||||
return iter->cursor->data;
|
||||
}
|
||||
size_t *lq_iter_rvalue(linkedqueue_iter *iter)
|
||||
{
|
||||
if (lq_empty(iter->target))
|
||||
return NULL;
|
||||
return &(iter->cursor->data);
|
||||
}
|
||||
size_t lq_iter_index(linkedqueue_iter *iter) { return iter->index; }
|
||||
linkedqueue_node *lq_impl_new_node(size_t element)
|
||||
{
|
||||
linkedqueue_node *_node_ = malloc(sizeof(linkedqueue_node));
|
||||
if (!_node_)
|
||||
return NULL;
|
||||
_node_->data = element;
|
||||
_node_->next = NULL;
|
||||
return _node_;
|
||||
}
|
||||
static linkedqueue_iter lq_impl_it_start(linkedqueue *_lqueue_)
|
||||
{
|
||||
linkedqueue_iter iter;
|
||||
lq_iter_init(&iter, _lqueue_);
|
||||
lq_iter_to_start(&iter);
|
||||
return iter;
|
||||
}
|
||||
+1
-14
@@ -7,14 +7,9 @@ CMC_CREATE_UNIT(deque_test, true, {
|
||||
deque *d = d_new(1000000);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, d);
|
||||
|
||||
bool passed = d->capacity == 1000000 && d->count == 0 && d->buffer;
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, d->buffer);
|
||||
cmc_assert_equals(size_t, 1000000, d->capacity);
|
||||
cmc_assert_equals(size_t, 0, d_count(d));
|
||||
cmc_assert_not_equals(ptr, NULL, d->buffer);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
d_free(d);
|
||||
});
|
||||
@@ -23,16 +18,12 @@ CMC_CREATE_UNIT(deque_test, true, {
|
||||
deque *d = d_new(0);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, d);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(d == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
deque *d = d_new(UINT64_MAX);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, d);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(d == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -50,8 +41,6 @@ CMC_CREATE_UNIT(deque_test, true, {
|
||||
cmc_assert_equals(size_t, 0, d_count(d));
|
||||
cmc_assert_equals(size_t, 100, d_capacity(d));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(d_count(d) == 0 && d_capacity(d) == 100);
|
||||
|
||||
d_free(d);
|
||||
});
|
||||
|
||||
@@ -66,8 +55,6 @@ CMC_CREATE_UNIT(deque_test, true, {
|
||||
cmc_assert_equals(size_t, 50, d_count(d));
|
||||
cmc_assert_lesser_equals(size_t, d_capacity(d), d_count(d));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(d_count(d) == 50 && d_count(d) <= d_capacity(d));
|
||||
|
||||
d_free(d);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,13 +8,11 @@ CMC_CREATE_UNIT(hashmap_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
hashmap *map = hm_new(943722, 0.6, cmp, hash);
|
||||
|
||||
bool passed = (map->capacity >= (943722 / 0.6)) && map->count == 0 && map->buffer;
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, map);
|
||||
cmc_assert_not_equals(ptr, NULL, map->buffer);
|
||||
cmc_assert_equals(size_t, 0, hm_count(map));
|
||||
cmc_assert_greater_equals(size_t, (943722 / 0.6), hm_capacity(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
hm_free(map);
|
||||
});
|
||||
|
||||
@@ -22,16 +20,12 @@ CMC_CREATE_UNIT(hashmap_test, true, {
|
||||
hashmap *map = hm_new(0, 0.6, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, map);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(map == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
hashmap *map = hm_new(UINT64_MAX, 0.6, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, map);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(map == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -48,8 +42,6 @@ CMC_CREATE_UNIT(hashmap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, hm_count(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(hm_count(map) == 0);
|
||||
|
||||
hm_free(map);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,12 +8,10 @@ CMC_CREATE_UNIT(hashset_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
hashset *set = hs_new(943722, 0.6, cmp, hash);
|
||||
|
||||
bool passed = (set->capacity >= (943722 / 0.6)) && set->count == 0 && set->buffer;
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, set);
|
||||
cmc_assert(hs_capacity(set) > (943722 / 0.6));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_not_equals(ptr, NULL, set->buffer);
|
||||
cmc_assert_equals(size_t, 0, hs_count(set));
|
||||
cmc_assert_greater_equals(size_t, (943722 / 0.6), hs_capacity(set));
|
||||
|
||||
hs_free(set);
|
||||
});
|
||||
@@ -22,16 +20,12 @@ CMC_CREATE_UNIT(hashset_test, true, {
|
||||
hashset *set = hs_new(0, 0.6, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, set);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(set == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
hashset *set = hs_new(UINT64_MAX, 0.6, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, set);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(set == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -48,8 +42,6 @@ CMC_CREATE_UNIT(hashset_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, hs_count(set));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(hs_count(set) == 0);
|
||||
|
||||
hs_free(set);
|
||||
});
|
||||
|
||||
|
||||
+2
-15
@@ -9,14 +9,9 @@ CMC_CREATE_UNIT(heap_test, true, {
|
||||
heap *h = h_new(1000000, cmc_max_heap, cmp);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, h);
|
||||
|
||||
bool passed = h->capacity == 1000000 && h->count == 0 && h->buffer;
|
||||
|
||||
cmc_assert_equals(size_t, 1000000, h->capacity);
|
||||
cmc_assert_equals(size_t, 0, h_count(h));
|
||||
cmc_assert_not_equals(ptr, NULL, h->buffer);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_equals(size_t, 1000000, h_capacity(h));
|
||||
cmc_assert_equals(size_t, 0, h_count(h));
|
||||
|
||||
h_free(h);
|
||||
});
|
||||
@@ -25,16 +20,12 @@ CMC_CREATE_UNIT(heap_test, true, {
|
||||
heap *h = h_new(0, cmc_max_heap, cmp);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, h);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
heap *h = h_new(UINT64_MAX, cmc_max_heap, cmp);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, h);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -52,8 +43,6 @@ CMC_CREATE_UNIT(heap_test, true, {
|
||||
cmc_assert_equals(size_t, 0, h_count(h));
|
||||
cmc_assert_equals(size_t, 100, h_capacity(h));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h_count(h) == 0 && h_capacity(h) == 100);
|
||||
|
||||
h_free(h);
|
||||
});
|
||||
|
||||
@@ -67,8 +56,6 @@ CMC_CREATE_UNIT(heap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 50, h_count(h));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(h_count(h) == 50);
|
||||
|
||||
h_free(h);
|
||||
});
|
||||
|
||||
|
||||
@@ -7,15 +7,10 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
linkedlist *ll = ll_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, ll);
|
||||
|
||||
bool passed = ll->count == 0 && ll->head == NULL && ll->tail == NULL;
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
cmc_assert_equals(ptr, NULL, ll->head);
|
||||
cmc_assert_equals(ptr, NULL, ll->tail);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
@@ -33,8 +28,6 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ll_count(ll) == 0);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
@@ -47,8 +40,6 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, ll_count(ll));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ll_count(ll) == 0);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
@@ -63,8 +54,6 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
cmc_assert_not_equals(ptr, NULL, ll->tail);
|
||||
cmc_assert_equals(size_t, 1, ll_count(ll));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ll->head && ll->tail && ll_count(ll) == 1);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
@@ -76,16 +65,8 @@ CMC_CREATE_UNIT(linkedlist_test, true, {
|
||||
for (size_t i = 0; i < 200; i++)
|
||||
ll_push_front(ll, i);
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < ll_count(ll); i++)
|
||||
{
|
||||
passed = passed && ll_get(ll, i) == (ll_count(ll) - i - 1);
|
||||
|
||||
cmc_assert_equals(size_t, ll_get(ll, i), ll_count(ll) - i - 1);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && ll_count(ll) == 200);
|
||||
|
||||
ll_free(ll);
|
||||
});
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#include "utl/assert.h"
|
||||
#include "utl/test.h"
|
||||
#include "../src/linkedqueue.c"
|
||||
|
||||
CMC_CREATE_UNIT(linkedqueue_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
linkedqueue *q = lq_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
bool passed = q->count == 0 && !q->head && !q->tail;
|
||||
|
||||
cmc_assert_equals(size_t, 0, lq_count(q));
|
||||
cmc_assert_equals(ptr, NULL, q->head);
|
||||
cmc_assert_equals(ptr, NULL, q->tail);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
lq_free(q);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count], {
|
||||
linkedqueue *q = lq_new();
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
lq_enqueue(q, i);
|
||||
|
||||
cmc_assert_equals(size_t, 50, lq_count(q));
|
||||
|
||||
lq_clear(q);
|
||||
|
||||
cmc_assert_equals(size_t, 0, lq_count(q));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(lq_count(q) == 0);
|
||||
|
||||
lq_free(q);
|
||||
});
|
||||
|
||||
});
|
||||
+5
-90
@@ -7,14 +7,9 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
list *l = l_new(1000000);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
bool passed = l->capacity == 1000000 && l->count == 0 && l->buffer;
|
||||
|
||||
cmc_assert_equals(size_t, 1000000, l->capacity);
|
||||
cmc_assert_equals(size_t, 0, l_count(l));
|
||||
cmc_assert_not_equals(ptr, NULL, l->buffer);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_equals(size_t, 1000000, l_capacity(l));
|
||||
cmc_assert_equals(size_t, 0, l_count(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -23,16 +18,12 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
list *l = l_new(0);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, l);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
list *l = l_new(UINT64_MAX);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, l);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new_from[count item_preservation], {
|
||||
@@ -47,17 +38,9 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < 5; i++)
|
||||
{
|
||||
cmc_assert_equals(size_t, i, l_get(l, i));
|
||||
|
||||
passed = passed && l_get(l, i) == i;
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && l_count(l) == 5);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -70,8 +53,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 1);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -90,8 +71,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert_equals(size_t, 0, l_count(l));
|
||||
cmc_assert_equals(size_t, 100, l_capacity(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 0 && l_capacity(l) == 100);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -105,15 +84,8 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 100, l_count(l));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < 100; i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == i;
|
||||
cmc_assert_equals(size_t, i, l_get(l, i));
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -128,8 +100,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -143,8 +113,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) <= l_capacity(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -156,16 +124,8 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_front(l, i));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == (l_count(l) - i - 1);
|
||||
|
||||
cmc_assert_equals(size_t, l_get(l, i), l_count(l) - i - 1);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -183,8 +143,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -201,8 +159,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) <= l_capacity(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -217,16 +173,8 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 1; i < 249; i++)
|
||||
cmc_assert(l_push(l, i, l_count(l) - 1));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == i;
|
||||
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -241,8 +189,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -256,8 +202,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, l_capacity(l), l_count(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) <= l_capacity(l));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -269,16 +213,8 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(l_push_back(l, i));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == i;
|
||||
|
||||
cmc_assert_equals(size_t, l_get(l, i), i);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -293,8 +229,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 250 - 1);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -306,16 +240,10 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
l_push_back(l, i);
|
||||
|
||||
bool passed = l_pop_front(l);
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
for (size_t i = 0; i < l_count(l); i++)
|
||||
{
|
||||
passed = passed && l_get(l, i) == i + 1;
|
||||
|
||||
cmc_assert_equals(size_t, l_get(l, i), i + 1);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -325,7 +253,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(!l_pop_front(l));
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 0);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -337,8 +264,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert(l_push_back(l, 10));
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 0);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -349,12 +274,10 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert(l_push_back(l, 1));
|
||||
cmc_assert(l_push_front(l, 2));
|
||||
|
||||
bool passed = l_pop_front(l) && l->buffer[1] == 0;
|
||||
cmc_assert(l_pop_front(l));
|
||||
|
||||
cmc_assert_equals(size_t, 0, l->buffer[1]);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && l_count(l) == 1);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -364,8 +287,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(!l_pop(l, 1));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(!l_pop(l, 1));
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -374,8 +295,7 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(l_push_back(l, 1));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_pop(l, 0));
|
||||
cmc_assert(l_pop(l, 0));
|
||||
|
||||
cmc_assert_equals(size_t, 0, l->buffer[0]);
|
||||
|
||||
@@ -391,8 +311,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert(l_push_back(l, 3));
|
||||
cmc_assert(l_pop(l, 1));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(0 == l->buffer[2]);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
|
||||
@@ -401,7 +319,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, l);
|
||||
cmc_assert(!l_pop_back(l));
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 0);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
@@ -413,8 +330,6 @@ CMC_CREATE_UNIT(list_test, true, {
|
||||
cmc_assert(l_push_back(l, 10));
|
||||
cmc_assert(l_pop_back(l));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(l_count(l) == 0);
|
||||
|
||||
l_free(l);
|
||||
});
|
||||
})
|
||||
@@ -8,13 +8,11 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
multimap *map = mm_new(943722, 0.8, cmp, hash);
|
||||
|
||||
bool passed = (map->capacity >= (943722 / 0.8)) && map->count == 0 && map->buffer;
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, map);
|
||||
cmc_assert_not_equals(ptr, NULL, map->buffer);
|
||||
cmc_assert_equals(size_t, 0, mm_count(map));
|
||||
cmc_assert_greater_equals(size_t, (943722 / 0.8), mm_capacity(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -22,16 +20,12 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
multimap *map = mm_new(0, 0.8, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, map);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(map == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
multimap *map = mm_new(UINT64_MAX, 0.8, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, map);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(map == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -48,8 +42,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, mm_count(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_count(map) == 0);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -63,8 +55,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 200, mm_count(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_count(map) == 200);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -83,8 +73,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 140, mm_count(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_count(map) == 140);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -97,8 +85,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert(!mm_remove(map, 10, &r));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(!mm_remove(map, 10, &r));
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -112,8 +98,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
cmc_assert(mm_insert(map, 10, 11));
|
||||
cmc_assert(mm_remove(map, 10, &r));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_count(map) == 0);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -127,8 +111,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 50, mm_count(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_count(map) == 50);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -147,8 +129,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 50, mm_count(map));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_count(map) == 50);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
@@ -165,8 +145,6 @@ CMC_CREATE_UNIT(multimap_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 100, mm_get(map, 10));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(mm_get(map, 10) == 100);
|
||||
|
||||
mm_free(map);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,12 +8,10 @@ CMC_CREATE_UNIT(multiset_test, true, {
|
||||
CMC_CREATE_TEST(new, {
|
||||
multiset *set = ms_new(943722, 0.6, cmp, hash);
|
||||
|
||||
bool passed = (set->capacity >= (943722 / 0.6)) && set->count == 0 && set->buffer;
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, set);
|
||||
cmc_assert(ms_capacity(set) > (943722 / 0.6));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_not_equals(ptr, NULL, set->buffer);
|
||||
cmc_assert_equals(size_t, 0, ms_count(set));
|
||||
cmc_assert_greater_equals(size_t, ((size_t)(943722 / 0.6)), ms_capacity(set));
|
||||
|
||||
ms_free(set);
|
||||
});
|
||||
@@ -22,16 +20,12 @@ CMC_CREATE_UNIT(multiset_test, true, {
|
||||
multiset *set = ms_new(0, 0.6, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, set);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(set == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINTMAX_MAX], {
|
||||
multiset *set = ms_new(UINTMAX_MAX, 0.99, cmp, hash);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, set);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(set == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -48,8 +42,6 @@ CMC_CREATE_UNIT(multiset_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, ms_count(set));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ms_count(set) == 0);
|
||||
|
||||
ms_free(set);
|
||||
});
|
||||
|
||||
@@ -68,12 +60,8 @@ CMC_CREATE_UNIT(multiset_test, true, {
|
||||
cmc_assert_equals(size_t, 3, ms_count(set));
|
||||
cmc_assert_equals(size_t, 6, ms_cardinality(set));
|
||||
|
||||
bool passed = ms_count(set) == 3 && ms_cardinality(set) == 6;
|
||||
|
||||
for (size_t i = 0; i <= 3; i++)
|
||||
passed = passed && ms_multiplicity_of(set, i) == i;
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_equals(size_t, i, ms_multiplicity_of(set, i));
|
||||
|
||||
ms_free(set);
|
||||
});
|
||||
@@ -89,12 +77,8 @@ CMC_CREATE_UNIT(multiset_test, true, {
|
||||
cmc_assert_equals(size_t, 20, ms_count(set));
|
||||
cmc_assert_equals(size_t, 100, ms_cardinality(set));
|
||||
|
||||
bool passed = ms_count(set) == 20 && ms_cardinality(set) == 100;
|
||||
|
||||
for (size_t i = 0; i < 20; i++)
|
||||
passed = passed && ms_multiplicity_of(set, i) == 5;
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_equals(size_t, 5, ms_multiplicity_of(set, i));
|
||||
|
||||
ms_free(set);
|
||||
});
|
||||
|
||||
+4
-16
@@ -7,15 +7,11 @@ CMC_CREATE_UNIT(queue_test, true, {
|
||||
queue *q = q_new(1000000);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
bool passed = q->capacity == 1000000 && q->count == 0 && q->buffer;
|
||||
|
||||
cmc_assert_equals(size_t, 1000000, q->capacity);
|
||||
cmc_assert_not_equals(ptr, NULL, q->buffer);
|
||||
cmc_assert_equals(size_t, 1000000, q_capacity(q));
|
||||
cmc_assert_equals(size_t, 0, q_count(q));
|
||||
cmc_assert_not_equals(ptr, NULL, q->buffer);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
@@ -23,16 +19,12 @@ CMC_CREATE_UNIT(queue_test, true, {
|
||||
queue *q = q_new(0);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, q);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(q == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
queue *q = q_new(UINT64_MAX);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, q);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(q == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -41,7 +33,7 @@ CMC_CREATE_UNIT(queue_test, true, {
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
q_enqueue(q, i);
|
||||
cmc_assert(q_enqueue(q, i));
|
||||
|
||||
cmc_assert_equals(size_t, 50, q_count(q));
|
||||
|
||||
@@ -50,8 +42,6 @@ CMC_CREATE_UNIT(queue_test, true, {
|
||||
cmc_assert_equals(size_t, 0, q_count(q));
|
||||
cmc_assert_equals(size_t, 100, q_capacity(q));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(q_count(q) == 0 && q_capacity(q) == 100);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
@@ -61,12 +51,10 @@ CMC_CREATE_UNIT(queue_test, true, {
|
||||
cmc_assert_not_equals(ptr, NULL, q);
|
||||
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
q_enqueue(q, i);
|
||||
cmc_assert(q_enqueue(q, i));
|
||||
|
||||
cmc_assert_equals(size_t, 50, q_count(q));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(q_count(q) == 50);
|
||||
|
||||
q_free(q);
|
||||
});
|
||||
|
||||
|
||||
+6
-118
@@ -9,15 +9,11 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
stack *s = s_new(1000000);
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, s);
|
||||
|
||||
bool passed = s->capacity == 1000000 && s->count == 0 && s->buffer;
|
||||
|
||||
cmc_assert_equals(size_t, 1000000, s->capacity);
|
||||
cmc_assert_not_equals(ptr, NULL, s->buffer);
|
||||
cmc_assert_equals(size_t, 1000000, s_capacity(s));
|
||||
cmc_assert_equals(size_t, 0, s_count(s));
|
||||
cmc_assert_not_equals(ptr, NULL, s->buffer);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -25,16 +21,12 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
stack *s = s_new(0);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, s);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(new[edge_case:capacity = UINT64_MAX], {
|
||||
stack *s = s_new(UINT64_MAX);
|
||||
|
||||
cmc_assert_equals(ptr, NULL, s);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s == NULL);
|
||||
});
|
||||
|
||||
CMC_CREATE_TEST(clear[count capacity], {
|
||||
@@ -52,8 +44,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert_equals(size_t, 0, s_count(s));
|
||||
cmc_assert_equals(size_t, 100, s_capacity(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_count(s) == 0 && s_capacity(s) == 100);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -68,8 +58,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert_equals(size_t, 50, s_count(s));
|
||||
cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_count(s) == 50 && s_count(s) <= s_capacity(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -83,8 +71,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 250, s_count(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_count(s) == 250);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -98,8 +84,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_count(s) <= s_capacity(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -111,16 +95,8 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
cmc_assert(s_push(s, i));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < s_count(s); i++)
|
||||
{
|
||||
passed = s->buffer[i] == i;
|
||||
|
||||
cmc_assert_equals(size_t, i, s->buffer[i]);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -137,8 +113,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 249, s_count(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_count(s) == 249);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -154,8 +128,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_lesser_equals(size_t, s_capacity(s), s_count(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_count(s) <= s_capacity(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -170,16 +142,8 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert(s_pop(s));
|
||||
cmc_assert(s_pop(s));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < s_count(s); i++)
|
||||
{
|
||||
passed = s->buffer[i] == i;
|
||||
|
||||
cmc_assert_equals(size_t, i, s->buffer[i]);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -191,8 +155,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(bool, false, s_pop(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(!s_pop(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -204,16 +166,8 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
for (size_t i = 0; i < 250; i++)
|
||||
s_push_if(s, i, i % 2 == 0);
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < s_count(s); i++)
|
||||
{
|
||||
passed = passed && s->buffer[i] % 2 == 0;
|
||||
|
||||
cmc_assert(s->buffer[i] % 2 == 0);
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -229,16 +183,8 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
s_pop_if(s, s_top(s) % 2 == 0);
|
||||
}
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < s_count(s); i++)
|
||||
{
|
||||
passed = passed && !(s->buffer[i] % 2 == 0);
|
||||
|
||||
cmc_assert(!(s->buffer[i] % 2 == 0));
|
||||
}
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert_not_equals(uint32_t, 0, s->buffer[i] % 2);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -256,8 +202,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 247, s_top(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(247 == s_top(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -272,8 +216,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, s_impl_default_value(), s_top(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_impl_default_value() == s_top(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -286,8 +228,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert_equals(size_t, 1, s_count(s));
|
||||
cmc_assert_equals(size_t, 10, s_top(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(10 == s_top(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -299,12 +239,8 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
for (size_t i = 0; i < 150; i++)
|
||||
cmc_assert(s_push(s, i));
|
||||
|
||||
bool passed = true;
|
||||
|
||||
for (size_t i = 0; i < 150; i++)
|
||||
passed = passed && s_contains(s, i, cmp);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
cmc_assert(s_contains(s, i, cmp));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -316,8 +252,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(bool, false, s_contains(s, 10, cmp));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(!s_contains(s, 10, cmp));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -328,8 +262,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert(s_empty(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_empty(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -342,8 +274,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert(s_pop(s));
|
||||
cmc_assert(s_empty(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_empty(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -357,8 +287,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert(s_full(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_full(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -371,8 +299,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert(s_full(s));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_full(s));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -385,8 +311,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, iter);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s && iter);
|
||||
|
||||
s_iter_free(iter);
|
||||
s_free(s);
|
||||
});
|
||||
@@ -405,10 +329,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert(iter.start);
|
||||
cmc_assert(iter.end);
|
||||
|
||||
bool passed = iter.target == s && iter.cursor == 0 && iter.start && iter.end;
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -421,7 +341,7 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
s_iter_init(&iter, s);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_iter_start(&iter));
|
||||
cmc_assert(s_iter_start(&iter));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -435,7 +355,7 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
s_iter_init(&iter, s);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_iter_end(&iter));
|
||||
cmc_assert(s_iter_end(&iter));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -464,8 +384,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 40200, total);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(total == 40200);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -496,8 +414,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 40200, total);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(total == 40200);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -521,8 +437,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 20, total);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(total == 20);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -552,8 +466,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 2000, total);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(total == 2000);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -565,7 +477,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
for (size_t i = 0; i < 50; i++)
|
||||
cmc_assert(s_push(s, i));
|
||||
|
||||
bool passed = true;
|
||||
stack_iter it1;
|
||||
stack_iter it2;
|
||||
|
||||
@@ -581,7 +492,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert_equals(size_t, it1.cursor, it2.cursor);
|
||||
cmc_assert_equals(bool, it1.start, it2.start);
|
||||
cmc_assert_equals(bool, it1.end, it2.end);
|
||||
passed = passed && it1.target == it2.target && it1.cursor == it2.cursor && it1.start == it2.start && it1.end == it2.end;
|
||||
|
||||
it1 = s->it_end(s);
|
||||
s_iter_to_end(&it2);
|
||||
@@ -590,9 +500,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
cmc_assert_equals(size_t, it1.cursor, it2.cursor);
|
||||
cmc_assert_equals(bool, it1.start, it2.start);
|
||||
cmc_assert_equals(bool, it1.end, it2.end);
|
||||
passed = passed && it1.target == it2.target && it1.cursor == it2.cursor && it1.start == it2.start && it1.end == it2.end;
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -608,14 +515,10 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
s_iter_to_end(&iter);
|
||||
|
||||
cmc_assert_equals(bool, false, s_iter_next(&iter));
|
||||
bool passed = !s_iter_next(&iter);
|
||||
|
||||
s_iter_to_start(&iter);
|
||||
|
||||
cmc_assert_equals(bool, false, s_iter_prev(&iter));
|
||||
passed = !s_iter_prev(&iter);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -634,14 +537,10 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
s_iter_to_end(&iter);
|
||||
|
||||
cmc_assert_equals(bool, false, s_iter_next(&iter));
|
||||
bool passed = !s_iter_next(&iter);
|
||||
|
||||
s_iter_to_start(&iter);
|
||||
|
||||
cmc_assert_equals(bool, false, s_iter_prev(&iter));
|
||||
passed = !s_iter_prev(&iter);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
@@ -657,8 +556,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, s_impl_default_value(), s_iter_value(&iter));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(s_impl_default_value() == s_iter_value(&iter));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -673,8 +570,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(ptr, NULL, s_iter_rvalue(&iter));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(NULL == s_iter_rvalue(&iter));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -688,18 +583,15 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 10, s_count(s));
|
||||
|
||||
bool passed = true;
|
||||
size_t total = 0;
|
||||
|
||||
for (stack_iter it = s->it_start(s); false; )
|
||||
{
|
||||
passed = passed && s_iter_index(&it) == 0;
|
||||
cmc_assert_equals(size_t, 0, s_iter_index(&it));
|
||||
}
|
||||
|
||||
for (stack_iter it = s->it_start(s); false; )
|
||||
{
|
||||
passed = passed && s_iter_index(&it) == s_count(s) - 1;
|
||||
cmc_assert_equals(size_t, s_count(s) - 1, s_iter_index(&it));
|
||||
}
|
||||
|
||||
@@ -717,8 +609,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 90, total);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(passed && total == 90);
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
@@ -732,8 +622,6 @@ CMC_CREATE_UNIT(stack_test, true, {
|
||||
|
||||
cmc_assert_equals(size_t, 0, s_iter_index(&iter));
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(0 == s_iter_index(&iter));
|
||||
|
||||
s_free(s);
|
||||
});
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ CMC_CREATE_UNIT(treemap_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, map);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(map);
|
||||
|
||||
tm_free(map);
|
||||
});
|
||||
|
||||
@@ -30,8 +28,6 @@ CMC_CREATE_UNIT(treemap_test, true, {
|
||||
cmc_assert_equals(size_t, 0, tm_count(map));
|
||||
cmc_assert_equals(ptr, NULL, map->root);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(tm_count(map) == 0);
|
||||
|
||||
tm_free(map);
|
||||
});
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ CMC_CREATE_UNIT(treeset_test, true, {
|
||||
|
||||
cmc_assert_not_equals(ptr, NULL, set);
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(set);
|
||||
|
||||
ts_free(set);
|
||||
});
|
||||
|
||||
@@ -30,9 +28,6 @@ CMC_CREATE_UNIT(treeset_test, true, {
|
||||
cmc_assert_equals(size_t, 0, ts_count(set));
|
||||
cmc_assert_equals(ptr, NULL, set->root);
|
||||
|
||||
|
||||
CMC_TEST_PASS_ELSE_FAIL(ts_count(set) == 0);
|
||||
|
||||
ts_free(set);
|
||||
});
|
||||
|
||||
|
||||
+21
-13
@@ -28,23 +28,31 @@ int main(void)
|
||||
heap *h = h_new(1000, cmc_max_heap, intcmp);
|
||||
tset *ts = ts_new(intcmp);
|
||||
tmap *tm = tm_new(intcmp);
|
||||
hset *hs = hs_new(1000, 0.9, intcmp, inthash);
|
||||
hmap *hm = hm_new(1000, 0.9, intcmp, inthash);
|
||||
hset *hs = hs_new(1000, 0.6, intcmp, inthash);
|
||||
hmap *hm = hm_new(1000, 0.6, intcmp, inthash);
|
||||
|
||||
iheap *ih = ih_new(1000, intcmp);
|
||||
mmap *mm = mm_new(1000, 0.8, intcmp, inthash);
|
||||
mset *ms = ms_new(1000, 0.6, intcmp, inthash);
|
||||
|
||||
printf("+--------------------------------------------------+\n");
|
||||
printf("| Separate Header and Source is Working |\n");
|
||||
printf("+--------------------------------------------------+\n");
|
||||
|
||||
l_free(l);
|
||||
ll_free(ll);
|
||||
s_free(s);
|
||||
q_free(q);
|
||||
d_free(d);
|
||||
h_free(h);
|
||||
ts_free(ts);
|
||||
tm_free(tm);
|
||||
hs_free(hs);
|
||||
hm_free(hm);
|
||||
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;
|
||||
}
|
||||
}
|
||||
+14
-10
@@ -1,12 +1,16 @@
|
||||
#include "sep.h"
|
||||
|
||||
COLLECTION_GENERATE_SOURCE(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE_SOURCE(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_SOURCE(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(TREEMAP, tm, tmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(HASHMAP, hm, hmap, int, int)
|
||||
|
||||
CMC_COLLECTION_GENERATE_SOURCE(INTERVALHEAP, ih, iheap, , int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(MULTIMAP, mm, mmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_SOURCE(MULTISET, ms, mset, , int)
|
||||
+14
-10
@@ -1,12 +1,16 @@
|
||||
#include "../../src/macro_collections.h"
|
||||
|
||||
COLLECTION_GENERATE_HEADER(LIST, l, list, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(STACK, s, stack, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(QUEUE, q, queue, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(DEQUE, d, deque, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(LINKEDLIST, ll, linked, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(HEAP, h, heap, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(TREESET, ts, tset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(TREEMAP, tm, tmap, /* FMOD */, int, int)
|
||||
COLLECTION_GENERATE_HEADER(HASHSET, hs, hset, /* FMOD */, /* K */, int)
|
||||
COLLECTION_GENERATE_HEADER(HASHMAP, hm, hmap, /* FMOD */, int, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(LIST, l, list, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(STACK, s, stack, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(QUEUE, q, queue, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(DEQUE, d, deque, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(LINKEDLIST, ll, linked, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(HEAP, h, heap, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(TREESET, ts, tset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(TREEMAP, tm, tmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(HASHSET, hs, hset, /* K */, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(HASHMAP, hm, hmap, int, int)
|
||||
|
||||
CMC_COLLECTION_GENERATE_HEADER(INTERVALHEAP, ih, iheap, , int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(MULTIMAP, mm, mmap, int, int)
|
||||
CMC_COLLECTION_GENERATE_HEADER(MULTISET, ms, mset, , int)
|
||||
+127
-100
@@ -26,115 +26,142 @@ typedef union union_u {
|
||||
|
||||
typedef int (*func_t)(int, double, char *);
|
||||
|
||||
COLLECTION_GENERATE(LIST, l0, list0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(STACK, s0, stack0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(QUEUE, q0, queue0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(DEQUE, d0, deque0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll0, linked0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(HEAP, h0, heap0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(TREESET, ts0, tset0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm0, tmap0, static, struct_t *, struct_t *)
|
||||
COLLECTION_GENERATE(HASHSET, hs0, hset0, static, /* K */, struct_t *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm0, hmap0, static, struct_t *, struct_t *)
|
||||
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 *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l1, list1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(STACK, s1, stack1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(QUEUE, q1, queue1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(DEQUE, d1, deque1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll1, linked1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(HEAP, h1, heap1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(TREESET, ts1, tset1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm1, tmap1, static, struct_t, struct_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs1, hset1, static, /* K */, struct_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm1, hmap1, static, struct_t, 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)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l2, list2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(STACK, s2, stack2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(QUEUE, q2, queue2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(DEQUE, d2, deque2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll2, linked2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(HEAP, h2, heap2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(TREESET, ts2, tset2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(TREEMAP, tm2, tmap2, static, int, int)
|
||||
COLLECTION_GENERATE(HASHSET, hs2, hset2, static, /* K */, int)
|
||||
COLLECTION_GENERATE(HASHMAP, hm2, hmap2, static, int, int)
|
||||
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)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l3, list3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(STACK, s3, stack3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(QUEUE, q3, queue3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(DEQUE, d3, deque3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll3, linked3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(HEAP, h3, heap3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(TREESET, ts3, tset3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm3, tmap3, static, int *, int *)
|
||||
COLLECTION_GENERATE(HASHSET, hs3, hset3, static, /* K */, int *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm3, hmap3, static, int *, 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 *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l4, list4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(STACK, s4, stack4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(QUEUE, q4, queue4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(DEQUE, d4, deque4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll4, linked4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(HEAP, h4, heap4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(TREESET, ts4, tset4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm4, tmap4, static, enum_t *, enum_t *)
|
||||
COLLECTION_GENERATE(HASHSET, hs4, hset4, static, /* K */, enum_t *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm4, hmap4, static, enum_t *, enum_t *)
|
||||
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 *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l5, list5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(STACK, s5, stack5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(QUEUE, q5, queue5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(DEQUE, d5, deque5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll5, linked5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(HEAP, h5, heap5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(TREESET, ts5, tset5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm5, tmap5, static, enum_t, enum_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs5, hset5, static, /* K */, enum_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm5, hmap5, static, enum_t, 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)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l6, list6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(STACK, s6, stack6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(QUEUE, q6, queue6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(DEQUE, d6, deque6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll6, linked6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(HEAP, h6, heap6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(TREESET, ts6, tset6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(TREEMAP, tm6, tmap6, static, union_t *, union_t *)
|
||||
COLLECTION_GENERATE(HASHSET, hs6, hset6, static, /* K */, union_t *)
|
||||
COLLECTION_GENERATE(HASHMAP, hm6, hmap6, static, union_t *, union_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 *)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l7, list7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(STACK, s7, stack7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(QUEUE, q7, queue7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(DEQUE, d7, deque7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll7, linked7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(HEAP, h7, heap7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(TREESET, ts7, tset7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm7, tmap7, static, union_t, union_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs7, hset7, static, /* K */, union_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm7, hmap7, static, union_t, 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)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l8, list8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(STACK, s8, stack8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(QUEUE, q8, queue8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(DEQUE, d8, deque8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll8, linked8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HEAP, h8, heap8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREESET, ts8, tset8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm8, tmap8, static, func_t, func_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs8, hset8, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm8, hmap8, static, func_t, func_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)
|
||||
|
||||
COLLECTION_GENERATE(LIST, l9, list9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(STACK, s9, stack9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(QUEUE, q9, queue9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(DEQUE, d9, deque9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(LINKEDLIST, ll9, linked9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HEAP, h9, heap9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREESET, ts9, tset9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(TREEMAP, tm9, tmap9, static, func_t, func_t)
|
||||
COLLECTION_GENERATE(HASHSET, hs9, hset9, static, /* K */, func_t)
|
||||
COLLECTION_GENERATE(HASHMAP, hm9, hmap9, static, func_t, 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)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user